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);