1

I am trying to read json string and print, it is producing segmentation fault(core dumped). I think the error is beacuse of the input string but not really sure.

here is the code

CODE:

 #include <json/json.h>
 #include <stdio.h>

 void json_parse(json_object * jobj);

int main(){

char * string = "{"
              "\"coooooool\": { "
                                    "\"name\" : \"coooooooooool\","
                                    "\"name\" : 1"
                                    "\"}"
               "\"}";

printf ("JSON string: %sn", string);
json_object * jobj = json_tokener_parse(string);
json_parse(jobj);


return 0;
}

void json_parse(json_object * jobj) {
 enum json_type type;
 json_object_object_foreach(jobj, key, val) {
     type = json_object_get_type(val);
     switch (type)
     {
         case json_type_int: printf("type: json_type_int, ");
         printf("value: %dn", json_object_get_int(val));
         break;
     }
  }
}

I ran the output binary file with valgrind to check the error properly

I am getting this error while running with valgrind

==14573== Memcheck, a memory error detector
==14573== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==14573== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==14573== Command: ./a.out
==14573== 
==14573== Invalid read of size 4
==14573==    at 0x40491F8: json_object_get_object (in /usr/lib/i386-linux-gnu/libjson.so.0.0.1)
==14573==    by 0x80485E5: main (in /var/www/json/a.out)
==14573==  Address 0xfffffff5 is not stack'd, malloc'd or (recently) free'd
==14573== 
==14573== 
==14573== Process terminating with default action of signal 11 (SIGSEGV)
==14573==  Access not within mapped region at address 0xFFFFFFF5
==14573==    at 0x40491F8: json_object_get_object (in /usr/lib/i386-linux-gnu/libjson.so.0.0.1)
==14573==    by 0x80485E5: main (in /var/www/json/a.out)
==14573==  If you believe this happened as a result of a stack
==14573==  overflow in your program's main thread (unlikely but
==14573==  possible), you can try to increase the size of the
==14573==  main thread stack using the --main-stacksize= flag.
==14573==  The main thread stack size used in this run was 8388608.
JSON string: {"coooooool": { "name" : "coooooooooool","name" : 1"}"}n==14573== 
==14573== HEAP SUMMARY:
==14573==     in use at exit: 0 bytes in 0 blocks
==14573==   total heap usage: 17 allocs, 17 frees, 1,511 bytes allocated
==14573== 
==14573== All heap blocks were freed -- no leaks are possible
==14573== 
==14573== For counts of detected and suppressed errors, rerun with: -v
==14573== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
sandesh
  • 390
  • 6
  • 20
  • 1
    why the quotes before the closing parenthesis? – Assaf Levy May 23 '16 at 15:53
  • Where is memory allocated for `json_object * jobj`? Does the json lib do that or are you responsible? It would appear you are, but I haven't used the library before, so double-check. `Address 0xfffffff5 is not stack'd, malloc'd or (recently) free'd`?? – David C. Rankin May 23 '16 at 16:00

2 Answers2

1

Your json is invalid. Try with a properly formatted json string and it works:

#include <stdio.h>
#include <json/json.h>

void json_parse(json_object * jobj);

int main(){

    char * string2 = "{"
            "\"coooooool\": { "
            "\"name\" : \"coooooooooool\","
            "\"name\" : 1"
            "\"}"
            "\"}";
    char * string = "{\"name\" : \"joys of programming\"}";
    printf ("JSON string: %sn", string);
   // json_object * jobj = malloc(sizeof(json_object));
    json_object *  jobj = json_tokener_parse(string);
    json_parse(jobj);


    return 0;
}

void json_parse(json_object * jobj) {
    enum json_type type;
    json_object_object_foreach(jobj, key, val) {
        type = json_object_get_type(val);
        switch (type)
        {
            case json_type_int: printf("type: json_type_int, ");
                printf("value: %dn", json_object_get_int(val));
                break;
        }
    }
}

You can lint your json to check how you want it.

Output

./test1 
JSON string: {"name" : "joys of programming"}

I compiled it like this

gcc -g -v -Wall -std=gnu99 -static -L/path/to/json-c-0.9/lib main.c -o test1 -ljson

Niklas Rosencrantz
  • 25,640
  • 75
  • 229
  • 424
  • yeah. segfault is because of invalid json. but the code is not able to print values in json_parse(). I mean the json_type_int. please check my code. – sandesh May 23 '16 at 16:41
1

Your problem is simple: you have errors in your json string.
your json string is the following (without escaping the quotes):

{"coooooool": { "name" : "coooooooooool","name" : 1"}"}

Two keys have the same name, and the two last double quotes characters of the string are totally out of place.
This string is not a valid json, and therefore json_tokener_parse returns NULL.
You should perform error checking to catch the failure to parse the string, ie add a check like this:

if(jobj == NULL) {
    // recover from the error or quit the program
}

With your code, json_object_object_foreach receives a NULL pointer, causing the Segmentation Fault.

Nicolas Jean
  • 775
  • 6
  • 19
  • yeah. segfault is because of invalid json. but the code is not able to print values in json_parse(). I mean the json_type_int. please check my code – sandesh May 23 '16 at 16:42
  • that's right. This is because the code loops on all the keys contained in the root object, and there is only one : "coooooool", which is not an int but a json object. – Nicolas Jean May 23 '16 at 17:00