pack_string should never free str on error. This wouldn't be a problem
except the check for `ours` was inverted. Just remove the check for
ours since the true condition is unreachable.
json_vpack_ex also had an error check for s.has_error. This can never
be true unless value is NULL.
Expand pack_unpack testing to cover empty format string, NULL object
value with non-null concatenated key, array containing a non-null object
after a NULL (error) string.
Fixes#444
* Remove errant line-feed from pack_object error message.
* Correct error message in pack_object_inter.
* Create pack_integer / pack_real to get the correct error messages on
failure when packing numeric values.
* Add tests for packing NAN and infinity directly, in an array and as
an object value.
When NULL is received for an optional argument we should not set an
error message as this would block later error messages. If NULL is
received for a non-optional string we should set has_error. Set
has_error for UTF-8 errors to ensure optional strings with UTF-8
errors are not replaced with json_null(). Use 'purpose' argument in
NULL error messages of read_string.
Add error handling and tests for invalid formats where '+', '#', or '%'
is used on an optional string 's?' or 's*'.
Fix NULL string error messages to use 'purpose'.
Refactor skipping of '*' token, this is now handled by read_string and
pack_object_inter. This allows invalid format strings such as 's*#' and
's*+' to produce error messages.
Fixes#437
This adds a compiler warning when strbuffer_init return value is
ignored. unpack_object is updated to deal with errors produced
while building unrecognized_keys.
* Test equality of different length strings.
* Add tab to json_pack whitespace test.
* Test json_sprintf with empty result and invalid UTF.
* Test json_get_alloc_funcs with NULL arguments.
* Test invalid arguments.
* Add test_chaos to test allocation failure code paths.
* Remove redundant json_is_string checks from json_string_equal and
json_string_copy. Both functions are static and can only be called
with a json string.
Fixes to issues found by test_chaos:
* Fix crash on OOM in pack_unpack.c:read_string().
* Unconditionally free string in string_create upon allocation failure.
Update load.c:parse_value() to reflect this. This resolves a leak on
allocation failure for pack_unpack.c:pack_string() and
value.c:json_sprintf().
Although not visible from CodeCoverage these changes significantly
increase branch coverage. Especially in src/value.c where we previously
covered 67.4% of branches and now cover 96.3% of branches.
Users of the "o" format have an expectation that the object reference
will be stolen. Any error causes the collection process to end early.
This patch causes json_pack and related functions to continue scanning
the format and parameters so all references can be stolen to prevent
leaks. This makes no attempt to continue processing if the format
string is broken or missing.
'make check' still passes. Ran test_pack under valgrind and verified
that the leaked reference is fixed. Added a test which uses refcounts
to verify that the reference was correctly stolen after a NULL value
error.
Issue #135
Otherwise figuring out what's wrong with your JSON can be tricky,
especially if you're using a single fmt string to validate a large,
complicated schema.
The comma delimiting will make separating keys that contain commas
difficult. For example:
{"foo, bar": true, "baz": false}
will generate errors like:
2 object item(s) left unpacked: foo, bar, baz
but that seems like a small enough corner case to not be worth much
worrying.
I wanted to find a way to handle this without have_unrecognized_keys,
but the strbuffer tooling makes it look like I shouldn't be reaching
in to do things like:
strbuffer_t unrecognized_keys;
unrecognized_keys.value = NULL;
and then using 'unrecognized_keys.value == NULL' in place of
have_unrecognized_keys.
The previous commit introduced a loop on all input keys to check the
strict mode. We can avoid this if we don't expect an optional key. In
this case, we fallback to the previous method to compare the length of
the set of expected keys and the length of the parsed keys.
On unpack, one may want to mix `JSON_STRICT` and optional keys by using
a format like `{s:i,s?o!}`. Unfortunately, this fails the stric test
with `-1 object item(s) left unpacked` error when the second key is not
specified.
To fix that, we iter on each key and we check if we have successfully
unpacked them. This is less efficient than the previous method but it
brings correctness.
The keys which are stored temporarily to a hashtable to make sure that
all object keys are unpacked, were hashed with the object key hashing
function. It is meant to compute hashes for object_key_t values, and
it works incorrectly for plain strings.
Fixed by introducing suitable functions for hashing and comparing
strings for string-keyed hashtables.
- Add a new field position to the json_error_t structure. This is the
position in bytes from the beginning of the input.
- Keep track of line, column and input position in the stream level.
Previously, only line was tracked, and it was in the lexer level, so
this info was not available for UTF-8 decoding errors.
- While at it, refactor tests so that no separate "stripped" tests are
required. json_process is now able to strip whitespace from its
input, and the "valid" and "invalid" test suites now use this to
test both non-stripped and stripped input.
Closes GH-9.
Functions taking va_args are munged to receive arguments of type
'__va_list_tag *'. This patch uses va_copy to coerce them to the expected type
so we don't get compiler errors.
Tested on x86_64, both 32-bit and 64-bit compiles.
Reported-By: Basile Starynkevitch <basile@starynkevitch.net>
Now, by default, unpacking doesn't check that all array and object
items are accessed. The check can be enabled globally by using the
JSON_STRICT flag (formerly JSON_UNPACK_ONLY), or on a per-value basis
by using the new '!' format character. The '*' format character is
still available to disable the global check on a per-value basis.
Expand the pack/unpack API: json_(un)pack is the simple version with
no error output, json_(un)pack_ex has error output and flags,
json_v(un)pack_ex is a va_list version of json_(un)pack_ex.
Implement unpacking flags:
- JSON_UNPACK_ONLY turns off extra validation, i.e. array and object
unpacking doesn't check that all items are unpacked. This is really
just convenience for not adding '*' after each object and array.
- JSON_VALIDATE_ONLY turns off unpacking, i.e. no varargs are expected
and nothing is unpacked.
* By default, json_unpack() now checks that all items of arrays and
objects are unpacked. This is useful for validation.
* Add format specifier '*' to suppress this check for individual
arrays and objects. '*' must appear as the last format specifier
before the closing ']' or '}'.