Very low footprint JSON parser written in portable ANSI C

Very low footprint JSON parser written in portable ANSI C.

  • BSD licensed with no dependencies (i.e. just drop the C file into your project)
  • Never recurses or allocates more memory than it needs
  • Very simple API with operator sugar for C++

Build Status

Want to serialize? Check out json-builder!

Installing

There is now a makefile which will produce a libjsonparser static and dynamic library. However, this is not required to build json-parser, and the source files (json.c and json.h) should be happy in any build system you already have in place.

API

json_value * json_parse (const json_char * json,
                         size_t length);

json_value * json_parse_ex (json_settings * settings,
                            const json_char * json,
                            size_t length,
                            char * error);

void json_value_free (json_value *);

The type field of json_value is one of:

  • json_object (see u.object.length, u.object.values[x].name, u.object.values[x].value)
  • json_array (see u.array.length, u.array.values)
  • json_integer (see u.integer)
  • json_double (see u.dbl)
  • json_string (see u.string.ptr, u.string.length)
  • json_boolean (see u.boolean)
  • json_null

Compile-Time Options

-DJSON_TRACK_SOURCE

Stores the source location (line and column number) inside each json_value.

This is useful for application-level error reporting.

Runtime Options

settings |= json_enable_comments;

Enables C-style // line and /* block */ comments.

size_t value_extra

The amount of space (if any) to allocate at the end of each json_value, in order to give the application space to add metadata.

void * (* mem_alloc) (size_t, int zero, void * user_data);
void (* mem_free) (void *, void * user_data);

Custom allocator routines. If NULL, the default malloc and free will be used.

The user_data pointer will be forwarded from json_settings to allow application context to be passed.

Changes in version 1.1.0

  • UTF-8 byte order marks are now skipped if present

  • Allows cross-compilation by honoring --host if given (@wkz)

  • Maximum size for error buffer is now exposed in header (@LB--)

  • GCC warning for static after const fixed (@batrick)

  • Optional support for C-style line and block comments added (@Jin-W-FS)

  • name_length field added to object values

  • It is now possible to retrieve the source line/column number of a parsed json_value when JSON_TRACK_SOURCE is enabled

  • The application may now extend json_value using the value_extra setting

  • Un-ambiguate pow call in the case of C++ overloaded pow (@fcartegnie)

  • Fix null pointer de-reference when a non-existing array is closed and no root value is present

Owner
Comments
  • json fails on double value

    json fails on double value

    Fails with 1:104: Unexpected . in object

    { "status": "ok", "results": [ { "recordings": [ { "id": "889ec8e0-b8a6-4ff1-a104-5512ea49fe87" } ], "score": 0.879051, "id": "45047cb1-3d3f-477e-a3dc-f14e8254e78d" } ] }

  • Testing flags may not be correct.

    Testing flags may not be correct.

    VS2013 flagged a couple of possible issues and I'm not sure it it's right or not. Line 411:

    else if (!state.settings.settings & json_relaxed_commas)
    

    parses as ((!state.settings.settings) & json_relaxed_commas) and I think maybe it should be (!(state.settings.settings & json_relaxed_commas))

    And likewise line 572:

    if (flags & flag_need_comma && (!state.settings.settings & json_relaxed_commas))
    
  • Fix strict-aliasing warning

    Fix strict-aliasing warning

    A couple of lines trigger strict-aliasing warnings on gcc (Ubuntu)

    error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
    

    Output of gcc --version

    gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
    

    This PR addresses those two warnings

    Commit d7b67db02aaa17fcc9bfbc8b60f41c3b677bd5a8 also simplifies the pointer notation by removing a reference and a dereference that seem to cancel each other out. Let's say that value->u.object.values is a pointer in memory location A and points to location B. Then | expression | type | pointer location | pointed location | |---|---|---|---| | value->u.object.values | json_object_entry * | A | B | | &value->u.object.values | json_object_entry ** | | A | | (char **) &value->u.object.values | char ** | | A | | *(char **) &value->u.object.values | char * | | B |

    The last expression can be simplified in (char *) value->u.object.values

  • Improve calculation of JSON_INT_MAX

    Improve calculation of JSON_INT_MAX

    From https://github.com/udp/json-parser/blob/e6426ae/json.c#L49-L55. That value can be calculated mathematically using 2**((n * 8) - 1) - 1. Which can also be done using the following bit shift:

    static const json_int_t JSON_INT_MAX = (1L << ((8 * sizeof(json_int_t) - 1))) - 1
    
  • Parse error when arrays are empty

    Parse error when arrays are empty

    Hi,

    The parser fails when the following JSON is provided: {"myArray": [] }

    In code: static char str[] = "{ "myArray": [] }"; json_value * root = json_parse(str, strlen(str));

    This is because malloc is called with a size of 0, due to the empty array. However some implementations of malloc will return NULL when asked to allocate 0 bytes and in this case the parser stops. I think this is wrong. In my opinion the parser should not try to allocate 0 bytes. A simple check in the newValue method for the json_array case can prevent this:

    In code: if (value->u.array.length == 0) { break; }

    With these three lines of code the parser can also handle the above input.

    Regards, Matthijs

  • Portability issue: cast from pointer to unsigned long

    Portability issue: cast from pointer to unsigned long

    The compiler on my system is 64 bit and sizeof(void *) is 8.

    json-parser\json.c: In function 'new_value':
    json-parser\json.c:135:42: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
                       (state, values_size + ((unsigned long) value->u.object.values), 0)) )
                                              ^
    

    https://github.com/udp/json-parser/blob/master/json.c#L141 In context, I'm not sure what this is supposed to be doing, so I don't have a proposed solution.

  • Compile error using clang

    Compile error using clang

    [100%] Building C object AudioAgent/external/CMakeFiles/JsonParser.dir/json-parser/json.c.o cc: warning: argument unused during compilation: '-no-cpp-precomp' /Users/johank/safe/audio/trunk/AudioAgent/external/json-parser/json.c:42:51: error: missing field 'type' initializer [-Werror,-Wmissing-field-initializers] const struct _json_value json_value_none = { 0 }; ^ I would suggest changing to

    const struct _json_value json_value_none;

    since static variables should anyway be zero initialized by default.

  • Raisonance RC51 error

    Raisonance RC51 error

    Hey

    I just tried compiling this with Raisonance's RC51 compiler, and it threw this error:

    *** ERROR C203 IN LINE 638 OF json.c : '(XDATA  CODE)': pointer: different mspace
    

    on the first lines of e_failed.

    With those lines commented out it worked fine.

  • Use size_t for memory size

    Use size_t for memory size

    The C standard library consistently uses size_t for variables related to memory size. See for example malloc(), memset(), sizeof().

    The maximum value of an object of size_t type is:

    Note that we cannot change unsigned longto size_t everywhere without modifying the API, so we will probably have to live with this exception:

    typedef struct
    {
       unsigned long max_memory;
       [...]
    } json_settings;
    
  • Copyright dates and web site updates

    Copyright dates and web site updates

    Perhaps it's time we change:

     * Copyright (C) 2012, 2013, 2014, 2016, 2018, 2019, 2021 James McLaughlin et al.  All rights reserved.
    

    to:

     * Copyright (C) 2012-2021 James McLaughlin et al.  All rights reserved.
    
  • Fix header files

    Fix header files

    json.h: <inttypes.h><stdint.h> int64_t is defined in <stdint.h>, no need for the full <inttypes.h>

    json.h: <stdlib.h><stddef.h> <stddef.h> is enough to define size_t

    json.c: <stdlib.h> Now that <stdlib.h> has been removed from json.h, add it to json.c for malloc()/calloc() and free()

  • New bversion?

    New bversion?

    Looking on https://github.com/json-parser/json-parser/compare/v1.1.0...master I think that it would be good to flush all those commits and make new release.

  • Install pkgconfig file to $(libdir)

    Install pkgconfig file to $(libdir)

    Pkgconfig file needs to be installed in $(libdir) rather than $(datadir), otherwise it is not possible to support multilib systems properly, e.g. 32 and 64 bits library on one system, where location must differ /usr/lib/pkgconfig for 32bit and /usr/lib64/pkgconfig for 64bit, for example.

  • Add ASan and UBSan to CI

    Add ASan and UBSan to CI

    When built with UndefinedBehaviorSanitizer and AddressSanitizer the tests throw this UndefinedBehaviorSanitizer error

     json.c:437:34: runtime error: applying non-zero offset 8 to null pointer
        #0 0x4caab2 in json_parse_ex /home/runner/work/json-parser/json-parser/json.c:437:34
        #1 0x4daf8c in json_test /home/runner/work/json-parser/json-parser/tests/test.c:79:18
        #2 0x4da892 in json_verify /home/runner/work/json-parser/json-parser/tests/test.c:153:14
        #3 0x4d9fe2 in main /home/runner/work/json-parser/json-parser/tests/test.c:229:12
        #4 0x7f148b3dc0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x240b2)
        #5 0x41c2fd in _start (/home/runner/work/json-parser/json-parser/json-test+0x41c2fd)
    

    Should be fixed first then this CI could help making sure it wont happen again :slightly_smiling_face:

Related tags
https://github.com/json-c/json-c is the official code repository for json-c. See the wiki for release tarballs for download. API docs at http://json-c.github.io/json-c/

\mainpage json-c Overview and Build Status Building on Unix Prerequisites Build commands CMake options Testing Building with vcpkg Linking to libjson-

Aug 13, 2022
A C++, header-only library for constructing JSON and JSON-like data formats, with JSON Pointer, JSON Patch, JSON Schema, JSONPath, JMESPath, CSV, MessagePack, CBOR, BSON, UBJSON

JSONCONS jsoncons is a C++, header-only library for constructing JSON and JSON-like data formats such as CBOR. For each supported data format, it enab

Aug 15, 2022
Ultralightweight JSON parser in ANSI C

cJSON Ultralightweight JSON parser in ANSI C. Table of contents License Usage Welcome to cJSON Building Copying the source CMake Makefile Vcpkg Includ

Aug 15, 2022
Very simple C++ JSON Parser

Very simple JSON parser for c++ data.json: { "examples": [ { "tag_name": "a", "attr": [ { "key":

Jul 25, 2022
A very sane (header only) C++14 JSON library

JeayeSON - a very sane C++14 JSON library JeayeSON was designed out of frustration that there aren't many template-based approaches to handling JSON i

Jun 7, 2022
Very fast Python JSON parsing library

cysimdjson Fast JSON parsing library for Python, 7-12 times faster than standard Python JSON parser. It is Python bindings for the simdjson using Cyth

Aug 5, 2022
JSON parser and generator for C/C++ with scanf/printf like interface. Targeting embedded systems.

JSON parser and emitter for C/C++ Features ISO C and ISO C++ compliant portable code Very small footprint No dependencies json_scanf() scans a string

Aug 15, 2022
JSON & BSON parser/writer

jbson is a library for building & iterating BSON data, and JSON documents in C++14. \tableofcontents Features # {#features} Header only. Boost license

May 12, 2022
Jsmn is a world fastest JSON parser/tokenizer. This is the official repo replacing the old one at Bitbucket

JSMN jsmn (pronounced like 'jasmine') is a minimalistic JSON parser in C. It can be easily integrated into resource-limited or embedded projects. You

Aug 8, 2022
A JSON parser in C++

JSON++ Introduction JSON++ is a light-weight JSON parser, writer and reader written in C++. JSON++ can also convert JSON documents into lossless XML d

Jul 23, 2022
🗄️ single header json parser for C and C++

??️ json.h A simple single header solution to parsing JSON in C and C++. JSON is parsed into a read-only, single allocation buffer. The current suppor

Aug 2, 2022
a JSON parser and printer library in C. easy to integrate with any model.

libjson - simple and efficient json parser and printer in C Introduction libjson is a simple library without any dependancies to parse and pretty prin

Aug 9, 2022
a header-file-only, JSON parser serializer in C++

PicoJSON - a C++ JSON parser / serializer Copyright © 2009-2010 Cybozu Labs, Inc. Copyright © 2011-2015 Kazuho Oku Licensed under 2-clause BSD license

Aug 5, 2022
A fast JSON parser/generator for C++ with both SAX/DOM style API
A fast JSON parser/generator for C++ with both SAX/DOM style API

A fast JSON parser/generator for C++ with both SAX/DOM style API Tencent is pleased to support the open source community by making RapidJSON available

Aug 16, 2022
Lightweight, extremely high-performance JSON parser for C++11

sajson sajson is an extremely high-performance, in-place, DOM-style JSON parser written in C++. Originally, sajson meant Single Allocation JSON, but i

Aug 13, 2022
🔋 In-place lightweight JSON parser

?? JSON parser for C This is very simple and very powerful JSON parser. It creates DOM-like data structure and allows to iterate and process JSON obje

Jun 7, 2022
RapidJSON is a JSON parser and generator for C++.
RapidJSON is a JSON parser and generator for C++.

A fast JSON parser/generator for C++ with both SAX/DOM style API

Aug 7, 2022
single-header json parser for c99 and c++

ghh_json.h a single-header ISO-C99 (and C++ compatible) json loader. why? obviously this isn't the first json library written for C, so why would I wr

May 26, 2022
Buggy JSON parser

Fuzzgoat: A minimal libFuzzer integration This repository contains a basic C project that includes an (intentionally insecure) JSON parser. It is an e

Apr 11, 2022