forkachild / C-Simple-JSON-Parser

Extremely lightweight, easy-to-use & blazing fast JSON parsing library written in pure C
https://forkachild.github.io/C-Simple-JSON-Parser/
MIT License
45 stars 16 forks source link

After recursively parsing of a child object, the string is not incremented correctly #1

Closed jongilm closed 4 years ago

jongilm commented 4 years ago

Problem:

The code can enter an infinite loop after parsing a complex string that requires recursion.

Cause:

After recursively parsing of a child object, the string pointer is not incremented correctly. It is increased by the current _offset, rather than only the size of the child/recursed object(s).

e.g.

{"name":{"first":"John", "last":"Doe"}, "age":"21"}
0----+----1----+----2----+----3----+----4----+----
        0----+----1----+----2----+----

After parsing {"first":"John", "last":"Doe"}, the string pointer is incorrectly advanced to the "2", instead of the ",".

Solution:

Increment the string pointer by the size of the recursed child objects, rather than the current (already incremented) _offset.

diff --git a/json.c b/json.c
index eb00265..331a902 100644
--- a/json.c
+++ b/json.c
@@ -86,6 +86,9 @@ static JSONObject * _parseJSON(string str, int * offset) {
             removeWhitespaceCalcOffset(str, _offset);

             if(*str == '{') {
+                int _offsetBeforeParsingChildObject = _offset;
+                int _sizeOfChildObject;
+
                 tempPtr.value = new(JSONValue);
                 tempPtr.type = JSON_OBJECT;
                 tempPtr.value->jsonObject = _parseJSON(str, &_offset);
@@ -93,7 +96,9 @@ static JSONObject * _parseJSON(string str, int * offset) {
                     freeJSONFromMemory(obj);
                     return NULL;
                 }
-                str += _offset;
+                // Advance the string pointer by the size of the processed child object
+                _sizeOfChildObject = _offset - _offsetBeforeParsingChildObject;
+                str += _sizeOfChildObject;
             } else if(*str == '"') {
                 i = strNextOccurence(++str, '"');
                 if(i == -1) {

@forkachild: I don't have permission to push a branch or raise a pull request, so please feel free to apply the change yourself, assuming you like it. Also, great solution, thanks. It was exactly what I was looking for. I will indeed buy you that beer. Rgds Jonathan

forkachild commented 4 years ago

@jongilm Thanks a lot for pointing out the issue, and I'm really glad it could help you. It will be really good if you can PR the change, but the weird thing is I don't know how to give the permission for PR, so if you can guide me, I will give you the permission.

jongilm commented 4 years ago

I figured it out. On github the process is to:

I hope this helps

forkachild commented 4 years ago

Merged #2