Very low footprint JSON parser written in portable ANSI C

Related tags

JSON json-parser
Overview

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

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" } ] }

    opened by fcartegnie 9
  • 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))
    
    opened by ghost 7
  • 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

    opened by ChromaticIsobar 5
  • 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
    
    opened by trevnorris 5
  • 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

    opened by mboelstra 5
  • 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.

    opened by LB-- 5
  • 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.

    opened by jkotlinski 5
  • 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.

    opened by fbstj 5
  • 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;
    
    opened by DimitriPapadopoulos 4
  • 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.
    
    opened by DimitriPapadopoulos 4
  • 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()

    opened by DimitriPapadopoulos 4
  • Potential buffer overflow

    Potential buffer overflow

    I came across your library while investigating security of a widely deployed product using it. I found the overflow checks to be very lacking.

    The calculations performed under https://github.com/json-parser/json-parser/blob/94f66d8f83c1d84ccccd7540ec2f51cf8325d272/json.c#L154 and https://github.com/json-parser/json-parser/blob/94f66d8f83c1d84ccccd7540ec2f51cf8325d272/json.c#L167 can overflow even if length stays below UINT_MAX. For 32 bit applications both size_t and unsigned int are 32 bit values. As a result, this code can handle at most 0x40000000 array entries and at most 0x13B13B13 object entries before the allocation size overflows resulting in far too little memory being allocated. Once array/object data is written into this buffer, it overflows which could result in code execution.

    Luckily, this allocation only happens in the second pass. Your code will allocate all the json_value instances in the first pass however, resulting in an out of memory error before this allocation can be reached. So with the current logic this buffer overflow vulnerability doesn’t seem exploitable. It might turn exploitable however if you change the allocation pattern or implement a streaming mode. So I sincerely recommend fixing this ASAP.

    I’m not sure what the best course of action is here. gcc and clang compilers allow you to perform arithmetic operations with overflow checking. I suspect that you cannot expect these builtins to exist however. So in case where you don’t have them, maybe https://www.fefe.de/intof.html is of help to construct similar functionality.

    It might be a good idea to also drop the current overflow checks which rely on sizes never growing by more than 8 at once. Instead, whenever you increase a length you should use addition with overflow checking.

    opened by palant 0
  • What is allocated?

    What is allocated?

    The description says that this library never allocates more memory than it needs. That's nice but what is needed? Other JSON parser libs make explicit statements about whether they allocate any memory for the parsed data. This one looks like it needs to allocate memory for all parsed values, including all strings (providing a zero-terminated copy) and also those object keys that I'm not interested in. I'm looking for a JSON parser to use on an ESP32 microcontroller in conjunction with MQTT and WiFi. There is some RAM available but I'd like to keep its use for this task to a minimum.

    I don't need the original JSON string anymore after parsing, so destroying it and providing pointers into it would be fine with me (adding terminating zero and shifting backslash sequences in-place).

    If that's not supported, would I be able to prevent running out of memory by limiting the accepted JSON string length so something reasonable for my application?

    opened by ygoe 1
  • Upgrade CodeQL and GitHub Actions

    Upgrade CodeQL and GitHub Actions

    CodeQL Action v1 will be deprecated on December 7th, 2022.

    For more information, see: https://github.blog/changelog/2022-04-27-code-scanning-deprecation-of-codeql-action-v1/

    opened by DimitriPapadopoulos 1
  • Runtime error when running with clang -fsanitize=undefined

    Runtime error when running with clang -fsanitize=undefined

    To reproduce, I built the code 'examples' with the following command on my mac:

    cd examples
    clang test_json.c ../json.c -I ../ -fsanitize=undefined
    

    Then when I run:

    ./a.out ../tests/valid-0000.json
    

    I get this runtime warning:

    ../json.c:437:34: runtime error: applying non-zero offset 8 to null pointer
    

    It seems to work if I replace in the code the line:

    json_car **char = (json_char **) &top->u.object.values;
    

    by:

    intptr_t *chars = (intptr_t *) &top->u.object.values;
    
    opened by guillaumechereau 0
  • 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.

    opened by kloczek 1
  • 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.

    opened by arkamar 1
Owner
James McLaughlin
James McLaughlin
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-

json-c 2.6k Dec 31, 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

Daniel Parker 547 Jan 4, 2023
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

Dave Gamble 8.3k Jan 4, 2023
Very simple C++ JSON Parser

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

Amir Saboury 67 Nov 20, 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

Jeaye Wilkerson 128 Nov 28, 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

TeskaLabs 234 Jan 8, 2023
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

Cesanta Software 637 Dec 30, 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

Chris Manning 40 Sep 14, 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

Serge Zaitsev 3.2k Jan 9, 2023
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

Hong Jiang 498 Dec 28, 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

Neil Henning 544 Jan 7, 2023
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

Vincent Hanquez 260 Nov 21, 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

Kazuho Oku 1k Dec 27, 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 Tencent is pleased to support the open source community by making RapidJSON available

Tencent 12.6k Dec 30, 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

Chad Austin 546 Dec 16, 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

Recep Aslantas 23 Dec 10, 2022
RapidJSON is a JSON parser and generator for C++.

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

Tencent 12.6k Dec 30, 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

garrison hinson-hasty 14 Dec 1, 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

Fuzzbuzz 1 Apr 11, 2022