fix memory leak in json reader when handling incomplete tokens

Sun, 20 Oct 2024 12:30:30 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 20 Oct 2024 12:30:30 +0200
changeset 940
bbf41b9c2658
parent 939
0bb7258366a0
child 941
9077724b75a0

fix memory leak in json reader when handling incomplete tokens

src/json.c file | annotate | diff | comparison | revisions
--- a/src/json.c	Sun Oct 20 11:39:54 2024 +0200
+++ b/src/json.c	Sun Oct 20 12:30:30 2024 +0200
@@ -427,15 +427,13 @@
         switch (token.tokentype) {
             case CX_JSON_TOKEN_BEGIN_ARRAY: {
                 p->reader_type = CX_JSON_READER_ARRAY_BEGIN;
-                if (add_state(p, JP_STATE_VALUE_BEGIN_AR)) return -1;
-                return 1;
-                //return json_read(p);
+                ret = add_state(p, JP_STATE_VALUE_BEGIN_AR) ? -1 : 1;
+                break;
             }
             case CX_JSON_TOKEN_BEGIN_OBJECT: {
                 p->reader_type = CX_JSON_READER_OBJECT_BEGIN;
-                if (add_state(p, JP_STATE_OBJ_NAME_OR_CLOSE)) return -1;
-                return 1;
-                //return json_read(p);
+                ret = add_state(p, JP_STATE_OBJ_NAME_OR_CLOSE) ? -1 : 1;
+                break;
             }
             case CX_JSON_TOKEN_END_ARRAY: {
                 p->value_ready = 0;
@@ -454,7 +452,7 @@
                     p->value_str = str.ptr;
                     p->value_str_len = str.length;
                 } else {
-                    return -1;
+                    ret = -1;
                 }
                 break;
             }
@@ -462,38 +460,39 @@
                 p->reader_type = CX_JSON_READER_INTEGER;
                 int64_t value;
                 if (parse_integer(token.content, token.length, &value)) {
-                    return -1;
+                    ret = -1;
+                } else {
+                    p->value_int = value;
+                    p->value_double = (double) value;
                 }
-                p->value_int = value;
-                p->value_double = (double) value;
                 break;
             }
             case CX_JSON_TOKEN_NUMBER: {
                 p->reader_type = CX_JSON_READER_NUMBER;
                 double value;
                 if (parse_number(token.content, token.length, &value)) {
-                    return -1;
+                    ret = -1;
+                } else {
+                    p->value_double = value;
+                    p->value_int = (int64_t) value;
                 }
-                p->value_double = value;
-                p->value_int = (int64_t) value;
                 break;
             }
             case CX_JSON_TOKEN_LITERAL: {
                 p->reader_type = CX_JSON_READER_LITERAL;
                 break;
             }
-            default:
-                return -1;
+            default: ret = -1;  
         }
     } else if (state == JP_STATE_ARRAY_SEP_OR_CLOSE) {
         // expect ',' or ']'
         if (token.tokentype == CX_JSON_TOKEN_VALUE_SEPARATOR) {
             p->states[p->nstates] = JP_STATE_VALUE_BEGIN_AR;
-            return json_read(p);
+            ret = json_read(p);
         } else if (token.tokentype == CX_JSON_TOKEN_END_ARRAY) {
             end_elm(p, CX_JSON_READER_ARRAY_END);
         } else {
-            return -1;
+            ret = -1;
         }
     } else if (state == JP_STATE_OBJ_NAME_OR_CLOSE || state == JP_STATE_OBJ_NAME) {
         if (state == JP_STATE_OBJ_NAME_OR_CLOSE && token.tokentype == CX_JSON_TOKEN_END_OBJECT) {
@@ -510,25 +509,29 @@
 
             // next state
             p->states[p->nstates] = JP_STATE_OBJ_COLON;
-            return json_read(p);
+            ret = json_read(p);
         }
     } else if (state == JP_STATE_OBJ_COLON) {
         // expect ':'
         if (token.tokentype != CX_JSON_TOKEN_NAME_SEPARATOR) return -1;
         // next state
         p->states[p->nstates] = 1;
-        return json_read(p);
+        ret = json_read(p);
     } else if (state == 7) {
         // expect ',' or '}]'
         if (token.tokentype == CX_JSON_TOKEN_VALUE_SEPARATOR) {
             p->states[p->nstates] = JP_STATE_OBJ_NAME;
-            return json_read(p);
+            ret = json_read(p);
         } else if (token.tokentype == CX_JSON_TOKEN_END_OBJECT) {
             end_elm(p, CX_JSON_READER_OBJECT_END);
         } else {
-            return -1;
+            ret = -1;
         }
     }
+    
+    if (token.alloc > 0) {
+        free((char*)token.content);
+    }
 
     return ret;
 }

mercurial