Mercurial > nxg > jason
changeset 2:27a0f5a39536
Fix lexer; fixes crashing bug
author | Norman Gray <norman@astro.gla.ac.uk> |
---|---|
date | Thu, 05 Sep 2013 20:34:52 +0100 |
parents | 8834a6154573 |
children | e6626e8d6433 |
files | src/jason.c src/json_lex.lex |
diffstat | 2 files changed, 56 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/src/jason.c Wed Sep 04 22:34:58 2013 +0100 +++ b/src/jason.c Thu Sep 05 20:34:52 2013 +0100 @@ -17,17 +17,25 @@ #define DEBUG 0 static jmp_buf unsupported_jmp; +// The flag in_jmp_code is true when we're in an extent protected by +// unsupported_jmp. This doesn't have any effect other than letting +// us check that we've nested calls to setjmp/longjmp appropriately. +// +// Of course, this setup makes this whole thing completely non-thread-safe. +static int in_jmp_code = 0; #define UNSUPPORTED_MSG_LENGTH 128 static char unsupported_msg[UNSUPPORTED_MSG_LENGTH]; static void unsupported_operation(const char *msg, ...) { va_list ap; + assert(in_jmp_code); va_start(ap, msg); vsnprintf(unsupported_msg, UNSUPPORTED_MSG_LENGTH, msg, ap); va_end(ap); longjmp(unsupported_jmp, 1); } + // If get_der_encoding fails because of unsupported behaviour, // then it returns NULL and sets a message which can be retrieved // here. The message will be NULL unless this is the cause of the failure. @@ -417,18 +425,28 @@ byte* get_der_encoding(JsonObject obj, size_t *len) { + byte* rval; + if (obj == NULL) { return NULL; } + assert(! in_jmp_code); + if (setjmp(unsupported_jmp) != 0) { // something has called unsupported_operation() - return NULL; + rval = NULL; + } else { + // normal behaviour + in_jmp_code = 1; + unsupported_msg[0] = '\0'; + + rval = get_der_encoding_internal(obj, len); } - // normal behaviour - unsupported_msg[0] = '\0'; - return get_der_encoding_internal(obj, len); + in_jmp_code = 0; + + return rval; } char* bytes_to_string(byte* b, size_t blen) @@ -978,14 +996,27 @@ { JsonObject rval; - lex_setup(json_string); - if (yyparse() == 0) { - rval = get_parsed_value(); + assert(! in_jmp_code); + + if (setjmp(unsupported_jmp) != 0) { + // something called unsupported_operation() (yyerror) + rval = NULL; } else { - rval = NULL; + // normal behaviour + in_jmp_code = 1; + unsupported_msg[0] = '\0'; + + lex_setup(json_string); + if (yyparse() == 0) { + rval = get_parsed_value(); + } else { + rval = NULL; + } + lex_release(); } - lex_release(); + in_jmp_code = 0; + return rval; } @@ -1273,13 +1304,24 @@ JsonObject parse_der_bytes(byte* b, size_t blen, size_t* actuallen) { + JsonObject rval = NULL; + + assert(! in_jmp_code); + if (setjmp(unsupported_jmp) != 0) { // something has called unsupported_operation() - return NULL; + rval = NULL; + } else { + // normal behaviour + in_jmp_code = 1; + unsupported_msg[0] = '\0'; + + rval = parse_der_bytes_internal(b, blen, actuallen); } - // normal behaviour - unsupported_msg[0] = '\0'; - return parse_der_bytes_internal(b, blen, actuallen); + + in_jmp_code = 0; + + return rval; } /**
--- a/src/json_lex.lex Wed Sep 04 22:34:58 2013 +0100 +++ b/src/json_lex.lex Thu Sep 05 20:34:52 2013 +0100 @@ -84,7 +84,7 @@ <string>\\u snprintf(err_msg, ERR_MSG_LEN, "don't support unicode yet\n"); return 0; <string>\\. snprintf(err_msg, ERR_MSG_LEN, "bogus escape '%s' in string\n", yytext); return 0; <string>\n snprintf(err_msg, ERR_MSG_LEN, "newline in string\n"); return 0; -<string>\" { +<string>\"{WS} { append_to_buffer_c(stringbuilder, '\0'); yylval.str = (char*)stringbuilder->buf; free(stringbuilder);