The option naming --nul-output was confusing, especially when we have a
similar option for input stream in the future (--nul-input vs --null-input).
Based on the observation of other command line tools, we rename the option
to --raw-output0. We also drop the short option -0 to avoid confusion on
introducing the NUL-delimited input option.
Unlike the other command line tools outputting file names with NUL delimiter,
jq deals with JSON, and its strings may contain NUL character. To protect
users from the risk of injection attacks, we abort the program and print an
error message before outputting strings including NUL character. Closes#2683.
RS should only only have special meaning when parsing json-seq.
Before this fix, RS was sometimes treated as a value terminator, causing
weird results.
Bug discovered by OSS fuzz.
Ref: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60835
It seems that bison doesn't call destructors for mid-rule action
components on error, since it does not know their type.
A mid-rule action was used to allocate the "text" string used as format
by string literals without a format, which would leak on error.
This patch replaces it with a new NoFormat component of type <literal>.
Now bison will call jv_free() on that string after a syntax error.
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60836
$ ./jq '"'
jq: error: syntax error, unexpected end of file, expecting QQSTRING_TEXT or QQSTRING_INTERP_START or QQSTRING_END (Unix shell quoting issues?) at <top-level>, line 1:
"
jq: 1 compile error
=================================================================
==1495450==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 21 byte(s) in 1 object(s) allocated from:
#0 0x7fc21aee1359 in __interceptor_malloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:69
#1 0x557ccb6ff608 in jv_mem_alloc src/jv_alloc.c:141
SUMMARY: AddressSanitizer: 21 byte(s) leaked in 1 allocation(s).
Error on non-number and nan codepoint, would asserd before
Replace negative codepoint and surrogate range with unicode replacement character, would assert before
Fixes#1160
In previous code nomem_handler in jv_alloc.c is called only once
and therefore the structure is not initialized for second and
following threads.
This leads to segmentation fault in multi-threading environment.
This patch moves initialization of nomem_handler out of the
pthread_once call.
valgrind (3.19.0) locally on macOS docker container seems to detect this leak but not CI.
$ cat modulemeta.test
modulemeta | .deps |= length
"c"
{"whatever":null,"deps":6}
$ valgrind --error-exitcode=1 --leak-check=full -q ./jq --run-tests < modulemeta.test
Test #1: 'modulemeta | .deps |= length' at line number 1
*** Insufficient results for test at line number 3: modulemeta | .deps |= length
0 of 1 tests passed (0 malformed, 0 skipped)
==14129== 482 (392 direct, 90 indirect) bytes in 1 blocks are definitely lost in loss record 7 of 8
==14129== at 0x48407B4: malloc (vg_replace_malloc.c:381)
==14129== by 0x13BC78: jv_mem_alloc (jv_alloc.c:122)
==14129== by 0x1371C6: jvp_object_new (jv.c:1521)
==14129== by 0x145840: parse_token (jv_parse.c:167)
==14129== by 0x145840: scan (jv_parse.c:684)
==14129== by 0x145840: jv_parser_next (jv_parse.c:793)
==14129== by 0x1463CB: jv_parse_sized (jv_parse.c:865)
==14129== by 0x136BD9: run_jq_tests (jq_test.c:183)
==14129== by 0x1370FA: jq_testsuite (jq_test.c:34)
==14129== by 0x13135C: main (main.c:582)
==14129==
This is unnecessary since we are using AC_USE_SYSTEM_EXTENSIONS in
configure.ac, which makes the compiler always run with -D_GNU_SOURCE=1
when building for GNU/Linux.
Also, the #define _GNU_SOURCE in src/util.c, and in
src/inject_errors.c (--enable-inject-errors), were not guarded by a
#ifndef _GNU_SOURCE so they were just triggering redefinition warnings.
Close#1885, #2140, #2011, #2220, #2485, #2073
Rename the FORK_OPT opcode to TRY_BEGIN, add a TRY_END opcode, and wrap
errors when raising through a TRY_END so that they will not be caught by
the matching TRY_BEGIN.
Now a `try exp catch handler` expression generates code like:
TRY_BEGIN handler
<exp>
TRY_END
JUMP past_handler
handler: <handler>
past_handler:
...
On backtrack through TRY_BEGIN it just backtracks.
If anything past the whole thing raises when <exp> produced a value,
then the TRY_END will catch the error, wrap it in another, and
backtrack. The TRY_BEGIN will see a wrapped error and then it will
unwrap and re-raise the error.
If <exp> raises, then TRY_BEGIN will catch the error and jump to the
handler, but the TRY_BEGIN will not stack_save() in that case, so on
raise/backtrack the TRY_BEGIN will not execute again (nor will the
TRY_END).
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60691
$ ./jq <<< 0E2202012202
src/decNumber/decNumber.c:598:18: runtime error: signed integer overflow: 440402440 + 1761609760 cannot be represented in type 'int'
0E+999999999
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=60683
$ ./jq <<< 5E7657765755
src/decNumber/decNumber.c:598:18: runtime error: left shift of 765776575 by 3 places cannot be represented in type 'int'
src/decNumber/decNumber.c:598:18: runtime error: signed integer overflow: 1531553150 + 1831245304 cannot be represented in type 'int'
1.7976931348623157e+308
Instead of just using {"captures":[]}.
sub functions are use captures for replacement expressions.
If we don't populate, captures for empty matches, the replacement
expression is run with an empty object as input instead of an object
containing the named captures with "" as value:
* before:
$ jq -n '"123foo456bar" | gsub("[^a-z]*(?<x>[a-z]*)"; "Z\(.x)")'
"ZfooZbarZnull"
* after:
$ jq -n '"123foo456bar" | gsub("[^a-z]*(?<x>[a-z]*)"; "Z\(.x)")'
"ZfooZbarZ"
---
I also removed a redundant
result = NULL;
if (result) {
...
}
To make debug/0 not call an uninitialised function pointer when using
--run-tests or when using a jq_state on which jq_set_debug_cb() has not
been called.
To avoid causing segmentation faults when input/1 is called in a
jq_state on which jq_set_input_cb() has not been called; e.g. the one
used by jq --run-tests.
That segfault could also be fixed in run_jq_tests() by calling:
jq_set_input_cb(jq, NULL, NULL);
But I think it makes sense to just make jq_init() initialise those
values to NULL.
Ref: https://github.com/jqlang/jq/pull/2717#discussion_r1264338841
* Fix memory leak for has(nan)
jv_array_get() used to be responsible of freeing the input array, but
since b5c4c3d67d, it is no longer called
if the key is nan. We need to free it manually to avoid leaking the
array.
* Parse nan in JSON as NaN instead of triggering a parse error
Fixes#2021
n.b.: { $__loc__: "foo" } is still not allowed.
$__loc__ cannot be overwritten, and it is always an object.
Using { $x: "foo" } where $x is not a string is an error, so there is
not much of a point in supporting that.
Previously, bindings were parsed as the combination of two tokens:
'$' IDENT
This meant that using a keyword as variable name (e.g. $then, $label)
did not work.
Attempts were made to allow $keyword to work by adding some '$' Keyword
rules in the parser, but this did not allow $keyword in all places:
jq --arg label foo -n '$label' # ok
jq -n '"foo" as $label | .' # error
Treating $foo as a single token is much simpler, in my opinion.
This patch also changes how LOC is lexed: "$__loc__" instead of as
"__loc__" that gets combined with '$' in the parser.
This patch also disallows having spaces after '$' when recalling a
variable `$ foo' since that was probably just an unintentional side
effect of the implementation, and it was not documented.
Fixes#2675