diff --git a/doc/apiref.rst b/doc/apiref.rst index d6b89e3..5003a04 100644 --- a/doc/apiref.rst +++ b/doc/apiref.rst @@ -675,7 +675,9 @@ and pass a pointer to a function. Example:: } Also note that if the call succeeded (``json != NULL`` in the above -example), the contents of ``error`` are unspecified. +example), the contents of ``error`` are generally left unspecified. +The decoding functions write to the ``position`` member also on +success. See :ref:`apiref-decoding` for more info. All functions also accept *NULL* as the :type:`json_error_t` pointer, in which case no error information is returned to the caller. @@ -819,15 +821,6 @@ macros can be ORed together to obtain *flags*. .. versionadded:: 2.1 -``JSON_DISABLE_EOF_CHECK`` - By default, the decoder expects that its whole input constitutes a - valid JSON text, and issues an error if there's extra data after - the otherwise valid JSON input. With this flag enabled, the decoder - stops after decoding a valid JSON array or object, and thus allows - extra data after the JSON text. - - .. versionadded:: 2.1 - ``JSON_DECODE_ANY`` By default, the decoder expects an array or object as the input. With this flag enabled, the decoder accepts any valid JSON value. @@ -839,6 +832,36 @@ macros can be ORed together to obtain *flags*. .. versionadded:: 2.3 +``JSON_DISABLE_EOF_CHECK`` + By default, the decoder expects that its whole input constitutes a + valid JSON text, and issues an error if there's extra data after + the otherwise valid JSON input. With this flag enabled, the decoder + stops after decoding a valid JSON array or object, and thus allows + extra data after the JSON text. + + Normally, reading will stop when the last ``]`` or ``}`` in the + JSON input is encountered. If both ``JSON_DISABLE_EOF_CHECK`` and + ``JSON_DECODE_ANY`` flags are used, the decoder may read one extra + UTF-8 code unit (up to 4 bytes of input). For example, decoding + ``4true`` correctly decodes the integer 4, but also reads the + ``t``. For this reason, if reading multiple consecutive values that + are not arrays or objects, they should be separated by at least one + whitespace character. + + .. versionadded:: 2.1 + +Each function also takes an optional :type:`json_error_t` parameter +that is filled with error information if decoding fails. It's also +updated on success; the number of bytes of input read is written to +its ``position`` field. This is especially useful when using +``JSON_DISABLE_EOF_CHECK`` to read multiple consecutive JSON texts. + +.. versionadded:: 2.3 + Number of bytes of input read is written to the ``position`` field + of the :type:`json_error_t` structure. + +If no error or position information is needed, you can pass *NULL*. + The following functions perform the actual JSON decoding. .. function:: json_t *json_loads(const char *input, size_t flags, json_error_t *error) @@ -880,14 +903,6 @@ The following functions perform the actual JSON decoding. multiple times, if the input consists of consecutive JSON texts, possibly separated by whitespace. - If both ``JSON_DISABLE_EOF_CHECK`` and ``JSON_DECODE_ANY`` flags - are used, the decoder may read one extra UTF-8 code unit (up to 4 - bytes of input). For example, decoding ``4true`` correctly decodes - the integer 4, but leaves the file position pointing at ``r`` - instead of ``t``. For this reason, if reading multiple consecutive - values that are not arrays and objects, they should be separated by - at least one whitespace character. - .. function:: json_t *json_load_file(const char *path, size_t flags, json_error_t *error) .. refcounting:: new diff --git a/src/load.c b/src/load.c index f5cbf68..193db45 100644 --- a/src/load.c +++ b/src/load.c @@ -836,10 +836,15 @@ static json_t *parse_json(lex_t *lex, size_t flags, json_error_t *error) if(lex->token != TOKEN_EOF) { error_set(error, lex, "end of file expected"); json_decref(result); - result = NULL; + return NULL; } } + if(error) { + /* Save the position even though there was no error */ + error->position = lex->stream.position; + } + return result; } diff --git a/test/suites/api/test_load.c b/test/suites/api/test_load.c index 8143d46..d8cb912 100644 --- a/test/suites/api/test_load.c +++ b/test/suites/api/test_load.c @@ -98,6 +98,23 @@ static void load_wrong_args() fail("json_loadf should return NULL if the first argument is NULL"); } +static void position() +{ + json_t *json; + size_t flags = JSON_DISABLE_EOF_CHECK; + json_error_t error; + + json = json_loads("{\"foo\": \"bar\"}", 0, &error); + if(error.position != 14) + fail("json_loads returned a wrong position"); + json_decref(json); + + json = json_loads("{\"foo\": \"bar\"} baz quux", flags, &error); + if(error.position != 14) + fail("json_loads returned a wrong position"); + json_decref(json); +} + static void run_tests() { file_not_found(); @@ -105,4 +122,5 @@ static void run_tests() disable_eof_check(); decode_any(); load_wrong_args(); + position(); }