Giter VIP home page Giter VIP logo

parson's Introduction

About

Parson is a lightweight json library written in C.

Features

  • Lightweight (only 2 files)
  • Simple API
  • Addressing json values with dot notation (similar to C structs or objects in most OO languages, e.g. "objectA.objectB.value")
  • C89 compatible
  • Test suites

Installation

Run:

git clone https://github.com/kgabis/parson.git

and copy parson.h and parson.c to you source code tree.

Run make test to compile and run tests.

Examples

Parsing JSON

Here is a function, which prints basic commit info (date, sha and author) from a github repository.

void print_commits_info(const char *username, const char *repo) {
    JSON_Value *root_value;
    JSON_Array *commits;
    JSON_Object *commit;
    size_t i;
    
    char curl_command[512];
    char cleanup_command[256];
    char output_filename[] = "commits.json";
    
    /* it ain't pretty, but it's not a libcurl tutorial */
    sprintf(curl_command, 
        "curl -s \"https://api.github.com/repos/%s/%s/commits\" > %s",
        username, repo, output_filename);
    sprintf(cleanup_command, "rm -f %s", output_filename);
    system(curl_command);
    
    /* parsing json and validating output */
    root_value = json_parse_file(output_filename);
    if (json_value_get_type(root_value) != JSONArray) {
        system(cleanup_command);
        return;
    }
    
    /* getting array from root value and printing commit info */
    commits = json_value_get_array(root_value);
    printf("%-10.10s %-10.10s %s\n", "Date", "SHA", "Author");
    for (i = 0; i < json_array_get_count(commits); i++) {
        commit = json_array_get_object(commits, i);
        printf("%.10s %.10s %s\n",
               json_object_dotget_string(commit, "commit.author.date"),
               json_object_get_string(commit, "sha"),
               json_object_dotget_string(commit, "commit.author.name"));
    }
    
    /* cleanup code */
    json_value_free(root_value);
    system(cleanup_command);
}

Calling print_commits_info("torvalds", "linux"); prints:

Date       SHA        Author
2012-10-15 dd8e8c4a2c David Rientjes
2012-10-15 3ce9e53e78 Michal Marek
2012-10-14 29bb4cc5e0 Randy Dunlap
2012-10-15 325adeb55e Ralf Baechle
2012-10-14 68687c842c Russell King
2012-10-14 ddffeb8c4d Linus Torvalds
...

Persistence

In this example I'm using parson to save user information to a file and then load it and validate later.

void persistence_example(void) {
    JSON_Value *schema = json_parse_string("{\"name\":\"\"}");
    JSON_Value *user_data = json_parse_file("user_data.json");
    char buf[256];
    const char *name = NULL;
    if (user_data == NULL || json_validate(schema, user_data) != JSONSuccess) {
        puts("Enter your name:");
        scanf("%s", buf);
        user_data = json_value_init_object();
        json_object_set_string(json_object(user_data), "name", buf);
        json_serialize_to_file(user_data, "user_data.json");
    }
    name = json_object_get_string(json_object(user_data), "name");
    printf("Hello, %s.", name);
    json_value_free(schema);
    json_value_free(user_data);
    return;
}

Serialization

Creating JSON values is very simple thanks to the dot notation. Object hierarchy is automatically created when addressing specific fields. In the following example I create a simple JSON value containing basic information about a person.

void serialization_example(void) {
    JSON_Value *root_value = json_value_init_object();
    JSON_Object *root_object = json_value_get_object(root_value);
    char *serialized_string = NULL;
    json_object_set_string(root_object, "name", "John Smith");
    json_object_set_number(root_object, "age", 25);
    json_object_dotset_string(root_object, "address.city", "Cupertino");
    json_object_dotset_value(root_object, "contact.emails", json_parse_string("[\"[email protected]\",\"[email protected]\"]"));
    serialized_string = json_serialize_to_string_pretty(root_value);
    puts(serialized_string);
    json_free_serialized_string(serialized_string);
    json_value_free(root_value);
}

Output:

{
    "name": "John Smith",
    "age": 25,
    "address": {
        "city": "Cupertino"
    },
    "contact": {
        "emails": [
            "[email protected]",
            "[email protected]"
        ]
    }
}

Contributing

I will always merge working bug fixes. However, if you want to add something new to the API, please create an "issue" on github for this first so we can discuss if it should end up in the library before you start implementing it. Remember to follow parson's code style and write appropriate tests.

My other projects

  • ape - simple programming language implemented in C library
  • kgflags - easy to use command-line flag parsing library
  • agnes - header-only NES emulation library

License

The MIT License (MIT)

parson's People

Contributors

9re avatar akihirosuda avatar benswick avatar cipop avatar commodo avatar dan-so avatar disconnect3d avatar erikdubbelboer avatar ewertons avatar i-rinat avatar iggyvolz avatar indutny avatar jacobenget avatar jetstreamroysprowl avatar jmlemetayer avatar kgabis avatar lunixoid avatar michaelsproul avatar reubeno avatar tbeu avatar timgates42 avatar uni-dos avatar vaavva avatar vovanec avatar w32zhong avatar yesmar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

parson's Issues

Issue in replace exising object

Hello.
I try to replace exising json object with another, but fail.
I use json_object_set_value. Return 0, but JSON invalid.
Code:

        JSON_Value *root_value = json_parse_string(pcBuffer);
        if (!root_value)
            return 1;

        JSON_Object *root_object = json_value_get_object(root_value);
        if (!root_object)
            return 1;

        JSON_Object *protection = json_object_get_object(root_object, "protection");
        if (!protection)
            return 1;

        status = json_object_set_value(protection, "macs", json_parse_string(pchAddedJSON));
        if (status != 0)
            return 1;

        char* result = json_serialize_to_string(root_value);

pchAddedJSON file content:
http://pastebin.com/W2YnuXsj

Exiting JSON file content (before any operations, valid):
http://pastebin.com/X5tjG9hd

After insert JSON file content (invalid file):
http://pastebin.com/90P251D4

Wrapping objects/arrays/etc. into values

How can we wrap a JSON_Object *, JSON_Array *, const char*, or double around a JSON_Value? Or is there such a feature that I've missed?

This could also be useful if e.g. you have a JSON_Object but you want to use json_value_deep_copy or json_serialize_to_string—both receive JSON_Value * arguments. Situations where you have an object but not a value include when it has been passed as a function argument.

Then we could do something like:

void a(const char *s) {
    JSON_Value *v = json_parse_string(s);
    JSON_Object *o = json_value_get_object(v);
    // do lots of processing with o
    b(o);
    json_value_free(v);
}

void b(JSON_Object *o) {
    // do lots of processing with o
    printSomewhere(json_serialize_to_string(json_object_to_value(o)));
}

NULL string values when escaped backslashes are present

This seems related to the fixes put in place for issue #24, but I'm now seeing NULL values returned for any string which contains an escaped backslash.

Given the following code I'd expect name to contain the value John\ Smith. Instead, it's returned as NULL.

JSON_Value *v = json_parse_string("{\"name\":\"John\\ Smith\"}");
JSON_Object *o = json_value_get_object(v);

const char *name = json_object_get_string(o, "name");
printf("name: %s\n", name);

Number max size in serialization

Just a question about max size in json_serialization_size and json_serialization_size_pretty functions, there's 1100 character long buffer for pre-parsing numbers, where's this number coming from? Wouldn't it be better to use parson_malloc + parson_free if there's need for such a long buffer for just a number, or is it misclicked 100? More than 1000 characters seems like an overkill?

1 byte buffer overflow in json serialize

The json_serialize_to_buffer_pretty() uses macro APPEND_STRING(str) to calculate how much data has been written to the ourput buffer. This macro uses append_string() then sprintf(). While in Std C lib, the return value of sprintf will not include the null terminator char.

As a result, the returned value of json_serialization_size_pretty() is always lack of 1 bytes, and json_serialize_to_string_pretty() will also always over write 1 byte of the allocated memory buffer.

problem with number field in json object

if there is a number field in json, and call json_object_get_number to get the number, it will return 0 in case of failed, and if it is a real 0, it returns 0. but get not existed field also returns 0, It can't be decide the call is failed or a real 0 or not existed.

Custom allocators with context.

Hi,

Use of some custom allocators requires passing a context object with (mutable) allocator state. Currently parson doesn't really support such allocators and trying to get a saved state would require for example playing with static variables.

I forked the project and made an implementation that allows that, which you can check at my repo: https://github.com/Matthew-Jemielity/parson . It doesn't change the existing API, but adds some new types and a function. I'm creating this issue as per readme to discuss it. If you think the change is useful, I'll make a pull request.

Regards,
Matt.

Microsoft's _CRT_SECURE_NO_WARNINGS

Hello kgabis,

I would like to propose the following (small) improvement:

#ifdef _MSC_VER
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif /*_CRT_SECURE_NO_WARNINGS*/
#endif

Thank you.

Best Regards,
Andrei Porumb
PS: this helps in the cases where the build system blindly defines _CRT_SECURE_NO_WARNINGS for all files.

Add array notation to dotget/dotset functions

Example:

/* Initialising object with an array of strings */
JSON_Value *val = json_value_init_object();
JSON_Object *obj = json_object(val);
json_object_dotset_string(obj, "array[0]", "item0");
json_object_dotset_string(obj, "array[1]", "item1");

json_object_dotset_string(obj, "array[3]", "item3"); /* error, index 2 is missing */

json_object_dotset_string(obj, "array[2]", "item2");
json_object_dotset_string(obj, "array[3]", "item3"); /* ok */

/* Result:
{ "array": ["item0", "item1", "item2", item3"] }
*/

/* Getting a string at index */
const char *str = json_object_dotget_string(obj, "array[0]");

Return value in get_number functions

Maybe settable in config value for return of get_number function would be good idea. Currently return if it's wrong is 0, so if you expect 0 in some of numbers, without validation using schema before-hand it's impossible to easily check if returned value is caused by failure.

Mix of tabs and spaces leads to warning about indentation

Around parson.c:276 tabs are used for indentation rather than spaces like everywhere else. This leads to a compiler warning. The warning is unfounded, IMHO.

    gcc -std=gnu99 -g -fpic -Wall -c -o parson/parson.o parson/parson.c
    parson/parson.c: In function ‘remove_comments’:
    parson/parson.c:282:13: warning: this ‘for’ clause does not guard... [-Wmisleading-indentation]
                             for (i = 0; i < (ptr - string) + end_token_len; i++)
                             ^~~
    parson/parson.c:284:12: note: ...this statement, but the latter is misleadingly indented as if it is guarded by the ‘for’
                            string = ptr + end_token_len - 1;
                            ^~~~~~

parson does not compile with c++ compiler

Changed compiler from gcc to g++ in Makefile.
Get error
parson.c: In function ‘JSON_Status json_array_resize(JSON_Array_, size_t)’:
parson.c:407:65: error: invalid conversion from ‘void_’ to ‘JSON_Value** {aka json_value_t*}’ [-fpermissive]
new_items = parson_malloc(new_capacity * sizeof(JSON_Value
));

It seems to be as easy as adding a simple cast, changing line 407 to
new_items = (JSON_Value*)parson_malloc(new_capacity * sizeof(JSON_Value));

Crash

I have crashs when run test_suite_3:
json_parse_string("{,"); and json_parse_string("["\0"]");
Maybe you should validate in function skip_quotes()

return value from json_object_dotget_number

Hi,
I have been using parson for a while and I love it!
However, I have a problem with the json_object_dotget_number() function.
json_object_dotget_number() returns '0' on fail as shown below so there is no way to distinguish between an error and value '0'.

double json_object_dotget_number (const JSON_Object object, const char *name); / returns 0 on fail */

I suggest returning the value as a function argument and use the return value for error only.
I also suggest using 0 for success and -1 for failure.

int json_object_dotget_number (const JSON_Object object, const char *name, double *number);
/
returns 0 on success, -1 on fail */

dotset*() to understand printf-style names?

Hi,

I've found in trying to programatically generate a JSON structure that I'm having to make a lot of snprintf() calls to form the key name for a dotset*() operation when iterating over various pieces of data.

I was wondering if parson would benefit from understanding a printf-style string, and to interpolate that appropriately? I'm happy to do the work on the basis that it might be accepted.

Parson fails to parse a large JSON file

[TestParson.json was here]

Repro code:

#include "parson.h"
#include <assert.h>

int main() {
  JSON_Value * root_value = json_parse_file("TestParson.json");
  assert(json_value_get_type(root_value) == JSONArray);
  json_value_free(root_value);
}

Assert is triggered despite that JSON file is correct

Support file encodings other than ANSI

Currently parson opens files using a call to FILE *fp = fopen(filename, "r");. This will assume the file is encoded as ANSI which is not always the case. fopen can take an optional ccs=<encoding> argument, and values of <encoding> can be "UNICODE", "UTF-8", and "UTF-16LE". Please consider changing the call to fopen passing the ccs=UNICODE argument.

I played around with this and ended up changing a lot of parson internals such as allowing the switch between wchar_t* and char*, and modifying the file open calls to FILE *fp = fopen(filename, "r, ccs=UNICODE"); however there ended up being quite a bit of changes and more that I would have needed to do to make it complete, there was a simpler way to go about it which as just changing the functions which open files to read into a wchar_t* and then put that into a char*. I decided to table my work as it was starting to get extensive, and instead suggest the change here just in case you are already working on this or don't plan on supporting unicode.

Escaping "/"

Just a suggestion, but many json parsers escape "/" because in script tags "</" is not allowed, so there's a slight chance having some json in a script tag can lead to invalid html. I think it's just a matter of adding a case in json_serialize_string:

case '/': APPEND_STRING("\/"); break;

Feature request: support for comments

Would it be possible for parson to support at least one of the comment styles bellow ?

  • suspend parsing from /* to */
  • suspend parsing from // to newline
  • suspend parsing from # to newline

Comment are not part of the JSON specification but they are an invaluable tool when using JSON for configuration files, on when providing an example JSON data structure to another developer.

Object with duplicate keys doesn't parse

This fails to parse:

{"x":1,"x":2}

It's not clear to me from the JSON grammar whether it should parse or not. Most other JSON libraries (e.g. the validator at http://jsonlint.com/) appear to simply overwrite the value of a redefined key with the new value (i.e. the above is decoded to {"x":2}).

Buffer overrun

Hi, i tried using your lib to generate logs, which works fine for simple cases. I'm currently using VS2008 and will also use gcc.

But as soon as I add a longer message containing backslashes I do get a crash calling json_serialize_to_string():

const char* msg = "Environment: \npid=13232\nhostname=con-js\nALLUSERSPROFILE=C:\ProgramData\nAPPDATA=C:\Users\js\AppData\Roaming";
JSON_Value *root_value = json_value_init_object();
JSON_Object *root_object = json_value_get_object(root_value);
char *serialized_string = NULL;
json_object_set_string(root_object, "message", msg);
serialized_string = json_serialize_to_string(root_value);
json_free_serialized_string(serialized_string);
json_value_free(root_value);

It looks like json_serialize_string writes over the bounds of buf, which causes to stop.

The call stack:

msvcr90.dll!_crt_debugger_hook(int _Reserved=12770140)  Zeile 65    C
msvcr90.dll!_invalid_parameter(const wchar_t * pszExpression=0x00000000, const wchar_t * pszFunction=0x00000000, const wchar_t * pszFile=0x00000000, unsigned int nLine=0, unsigned int pReserved=0)  Zeile 112 + 0x7 Bytes C++
msvcr90.dll!sprintf(char * string=0x00000000, const char * format=0x040baff0, ...)  Zeile 105 + 0x1c Bytes  C
_cdbwrapc.pyd!json_serialize_to_buffer_r(const json_value_t * value=0x0490c068, char * buf=0x00000000)  Zeile 698 + 0xf Bytes   C
_cdbwrapc.pyd!json_serialize_to_buffer(const json_value_t * value=0x0490c068, char * buf=0x0496a380, unsigned int buf_size_in_bytes=97)  Zeile 1075 + 0xd Bytes C
_cdbwrapc.pyd!json_serialize_to_string(const json_value_t * value=0x0490c068)  Zeile 1107 + 0x11 Bytes  C

Am I guessing right, or did you watch similar behaviour before?

memory allocation

In the implementation, I see multiple instances where NULL is used to check the sanity of the array. If pointer pointing to NULL while a pointer to an JSON_Value is expected, the function returns JSONFailure. This design is OK if allocated space is properly zerorized. However, in current implementation, json_malloc is a simple wrapper over the system malloc, and does not provide all zero memory block. I recommend us change the implementation into a standard malloc followed by a memset.

On the other hand, in memory extension, is there any specific reason why malloc and manual copy over is preferred over realloc?

I recive null on socket response parsing

Please, take a little look to this SOpt post, i have an inssue with parsing response data.
http://pt.stackoverflow.com/q/148202/8984?problema-com-a-library-parson-ao-utilizar-json-object-get-string-com-resposta-do

JSON_Value const *user_data = json_parse_string(response);
const char *msgs = json_object_get_string(json_object(user_data), "message");
__android_log_print(ANDROID_LOG_INFO, "-----from--jni-1-----", "Json Message  1. [%s] \n", msgs);

example I/-----from--jni-1-----: Json Message 1. [(null)]

response: {"name":"qualquer um", "message":"ano 2016"}

What is going on with this code? @kgabis

Removing dependency on sscanf

I am suggesting to remove dependency on sscanf. It was only used twice for parsing hex numbers "%4x" and could be easily replaced.

Primarily, it is because of this issue in Azure IoT SDK for C. The SDK relies on parson. But since some Arduino devices did not implement sscanf, thus, they cannot use Azure IoT SDK.

As I dig further, I found that parson only used sscanf twice for parsing UTF-16 in hex. So I am suggesting if it could be replaced. Apart from Azure IoT SDK, the change could also benefit other Arduino users by using parson for their project.

I have forked parson and replaced sscanf with this commit.

Thanks!

Memory leak when parsing failed

Here's the input that will trigger the issue:
leak.txt
Feed it into the json_parse_string() function on master(e410fc7) built with AddressSanitizer will crash the program:

> ./parse leak.txt
=================================================================
==9905==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 2 byte(s) in 1 object(s) allocated from:
    #0 0x4d6250 in __interceptor_malloc /home/grieve/LLVM/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:88
    #1 0x521788 in process_string (/home/grieve/scratch/parson/main+0x521788)
    #2 0x51f29e in get_quoted_string (/home/grieve/scratch/parson/main+0x51f29e)
    #3 0x51ba2d in parse_object_value (/home/grieve/scratch/parson/main+0x51ba2d)
    #4 0x50e8d5 in parse_value (/home/grieve/scratch/parson/main+0x50e8d5)
    #5 0x50e137 in json_parse_string (/home/grieve/scratch/parson/main+0x50e137)
    #6 0x50d993 in main (/home/grieve/scratch/parson/main+0x50d993)
    #7 0x7f80f45784c9 in __libc_start_main (/usr/lib/libc.so.6+0x204c9)

SUMMARY: AddressSanitizer: 2 byte(s) leaked in 1 allocation(s).

Here's the full source code of parse.c I used in testing:

#include "parson.h"
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
  if (argc > 1) {
    const char* filename = argv[1];
    FILE* file = fopen(filename, "rb");
    if (file != NULL) {
      fseek(file, 0, SEEK_END);
      long file_size = ftell(file);
      rewind(file);

      char* buf = (char*)malloc(file_size + 1);
      if (buf != NULL) {
        fread(buf, file_size, 1, file);
        buf[file_size] = 0;

        JSON_Value* val = json_parse_string(buf);
        if (val != NULL) {
          json_value_free(val);
        }

        free(buf);
      }
      fclose(file);
    }
  }
}

Logic problem for `json_array_remove()`

According to JSON standard, objects in array is supposed to be order sensitive (https://www.tutorialspoint.com/json/json_data_types.htm). However, according to the source code, when an object in the array is removed, last object in the array is to be used to replace the index it occupies.

This logic could potentially disrupt some functions that take advantage of the ordered nature of array. Do you think this logic should be adjusted to shifting all indices larger than ix left by 1?

UTF-8 symbols

Can't process some UTF-8 symbols.
JSON example: http://pastebin.com/3ZzNPup5
Fail to serialize "\u0001" in end of file.
My simple code:

        JSON_Value *root_value = json_parse_file(jsonfile1);
        assert(root_value);
        json_serialize_to_file(root_value, jsonfile2);
        JSON_Value * second_root_value = json_parse_file(jsonfile2);
        assert(second_root_value);

jsonfile2 is incorrect JSON file.
second_root_value NULL.

null parsing

Hello kgabis,

As per json.org, null is a valid JSON value.

I would expect the following code to print "parsing null success!". Instead it prints "cannot json_parse_string null".

#include <stdio.h>

#include "parson.h"

int main(int argc, char** argv)
{

    JSON_Value* v = json_parse_string("null");
    if (v == NULL)
    {
        printf("cannot json_parse_string null\n");
    }
    else
    {
        printf("parsing null is success!\n");
        json_value_free(v);
    }

    return 0;
}

Thank you.

Best Regards,
Andrei Porumb

Add link to parent object

Would it be possible to add a parent field to objects, in order to allow back-navigation in the hierarchy?

valgrind complain on strlen

Since the pointer of the output is known and you control the end pointer, why not do a simple subtraction. It will be even faster than scanning the string for \0 with strlen.

Here the 1 line fix.

--- parson/parson.c
+++ parson/parson.c
@@ -435,11 +435,11 @@
         }
         output_ptr++;
         input_ptr++;
     }
     *output_ptr = '\0';
-    if (try_realloc((void**)&output, strlen(output) + 1) == JSONFailure)
+    if (try_realloc((void**)&output, (output_ptr-output) + 1) == JSONFailure)
         goto error;
     return output;
 error:
     free(output);
     return NULL;

JSON objects inside JSON Array

Hello,

Is there any way to insert JSON objects in to JSON Array?
Eg:-
"employees":[
{"firstName":"John", "lastName":"Doe"},
{"firstName":"Anna", "lastName":"Smith"},
{"firstName":"Peter","lastName":"Jones"}
]
I tried to parse the string in the above format and put it in to an array using json_parse_string(). Which I couldn't succeed.

Could you give some pointers to this?

Thanks,
Sajeesh.

Code-quality scan (Version d7726760e0532eaa65e439c3f9403312d819be52)

Currently used version of the library (Clone-Version 08.02.2016)
We have couple of findings from Code-quality tool:

File ID Severity Method Message
parson.c 142 Critical json_serialize_to_buffer_r Pointer 'key' returned from call to function 'json_object_get_name' at line 768 may be NULL and may be dereferenced at line 771.
parson.c 148 Critical json_value_equals Pointer 'a_string' returned from call to function 'json_value_get_string' at line 1722 may be NULL and will be dereferenced at line 1724.
parson.c 150 Critical json_serialize_to_buffer_r Pointer 'string' returned from call to function 'json_value_get_string' at line 797 may be NULL and will be dereferenced at line 798.
parson.c 152 Critical json_value_equals Pointer 'b_string' returned from call to function 'json_value_get_string' at line 1723 may be NULL and will be dereferenced at line 1724.
parson.c 155 Critical json_value_deep_copy Pointer 'temp_string' returned from call to function 'json_value_get_string' at line 1197 may be NULL and will be dereferenced at line 1198.

json_serialize_to_string: unnecessary escaping of "/"

json_serialize_to_string() escapes "/", though it doesn't need to:

int main(void) {
  JSON_Value *object = NULL;
  JSON_Status ret;
  char *json = NULL;

  object = json_value_init_object();
  ret = json_object_set_string(json_object(object), "foo/bar", "1.2.3");
  if (JSONSuccess != ret) {
    fprintf(stderr, "OH NO!!\n");
    json_value_free(object);
    return 1;
  }

  json = json_serialize_to_string(object);
  printf("%s\n", json);
  free(json);
  json_value_free(object);

  return 0;
}

yields:

./example
{"foo\/bar":"1.2.3"}

though {"foo/bar":"1.2.3"} is perfectly valid.

Undefined behavoiur sanitizer runtime errors

Hi there,

I'm switched on the undefined behaviour sanitizer on clang. That gives me two runtime errors according to parson.c.

parson.c:420:24: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'size_t' (aka 'unsigned long')
#0 0x42bc0c in json_object_free c/parson/parson.c:388

parson.c:477:24: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'size_t' (aka 'unsigned long')
#0 0x42c209 in json_array_free /c/parson/parson.c:443

Both issues came from this statement: while (array->count--) and count is an unsigned long. Please fix it by adding an additional check, maybe in this way: while (array->count && array->count--) so that you only decrement if not zero.

Best Regards,

Ingo

Move Type definitions from parson.c to parson.h

When debugging applications, without access to the type definitions, attempting to access JSON Object names or values causes an "dereferencing pointer to incomplete type" compiler error.

names:
ubp.c: In function ‘json_to_response_two’: ubp.c:59:41: error: dereferencing pointer to incomplete type printf("name: %s, value: %s\n",object->names[j], json_value_get_string(object->values[j]));
and for values:
ubp.c:59:58: error: dereferencing pointer to incomplete type printf("name: %s, value: %s\n",object->names[j], json_value_get_string(object->values[j]));

Moving these to the header file resolves this issue, and allows for better debugging.

Error message if parsing fails

Currently, when parsing fails a NULL value is returned and my software can only log a "something went wrong" message. It would be great to be able to log the line number and line contents that caused the failure.

I apologize for not reading the bottom of the readme about creating issues before a pull request. Pull request #78 shows a minimally invasive way to implement this. It returns a JSONError value with an error message in the string field.

handling of DEL (0x7F) char in string parsing

As of RFC 4627 point 2.5, the unescaped allowed characters are 0x20-0x21 / 0x23-0x5B / 0x5D-0x10FFFF so 0x7F (DEL) is an allowed unescaped char.

In strings parsing, parson use iscntrl() to verify control characters. iscntrl() returns true even for 0x7F, yet it is an allowed character and should be accepted in unescaped form.

I posted a patch at https://gist.github.com/4270061

missing object key existance function

Hi there,
I noticed that is missing a function such int json_object_string_exists( JSON_Object *object, const char *name ) that checks (and return like an int) if a key (or string) in a Object exists. If I use json_object_get_string over an unexisting string, program gives Segmentation Fault (code dump).
Could you add it? Thank you.

Error with several same keys.

We have JSON:
http://pastebin.com/CRxepHVa
This JSON have 2 same keys: "size".
JSON_Value *root_value = json_parse_file(jsonFile1);
We recieve NULL. Library can't process JSON files with several same keys.
Maybe add support? For example, we parse to struct only last key.
On example, skip size:0 and insert size:1 in struct.
Thanks.

Needs well defined behavior surrounding memory allocation/ownership

Documentation is not crisp about when I need to free resources versus when the library will free resources on my behalf.

There are comments in the header file in some places that indicate how memory should be handled...

/* Works like dotget functions, but creates whole hierarchy if necessary.`
* json_object_dotset_value does not copy passed value so it shouldn't be freed afterwards. */ 

However, the header offers no advice for the management of the string returned by const char * json_object_get_string (const JSON_Object *object, const char *name);

The README ("Persistence" section) shows, json_object_get_string being used without a call to free, but this is uncommon behavior for c libraries and it would be nice if it were well defined.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.