Skip to content

Commit

Permalink
Fix --nul-output option to abort on a string containing NUL
Browse files Browse the repository at this point in the history
  • Loading branch information
itchyny committed Jul 22, 2023
1 parent e0e1b22 commit 86699b4
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 2 deletions.
1 change: 1 addition & 0 deletions docs/content/manual/manual.yml
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ sections:
Like `-r` but jq will print NUL instead of newline after each output.
This can be useful when the values being output can contain newlines.
When the output value contains NUL, jq exits with non-zero code.
* `-f filename` / `--from-file filename`:
Expand Down
11 changes: 9 additions & 2 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,18 @@ static int process(jq_state *jq, jv value, int flags, int dumpopts, int options)
if ((options & RAW_OUTPUT) && jv_get_kind(result) == JV_KIND_STRING) {
if (options & ASCII_OUTPUT) {
jv_dumpf(jv_copy(result), stdout, JV_PRINT_ASCII);
ret = JQ_OK;
} else if ((options & RAW_NUL) && strlen(jv_string_value(result)) != (unsigned long)jv_string_length_bytes(jv_copy(result))) {
jv input_pos = jq_util_input_get_position(jq);
fprintf(stderr, "jq: error (at %s): %s\n",
jv_string_value(input_pos), "Cannot dump a string containing NUL with --nul-output option");
jv_free(input_pos);
ret = JQ_ERROR_UNKNOWN;
} else {
priv_fwrite(jv_string_value(result), jv_string_length_bytes(jv_copy(result)),
stdout, dumpopts & JV_PRINT_ISATTY);
ret = JQ_OK;
}
ret = JQ_OK;
jv_free(result);
} else {
if (jv_get_kind(result) == JV_KIND_FALSE || jv_get_kind(result) == JV_KIND_NULL)
Expand All @@ -198,7 +205,7 @@ static int process(jq_state *jq, jv value, int flags, int dumpopts, int options)
}
if (!(options & RAW_NO_LF))
priv_fwrite("\n", 1, stdout, dumpopts & JV_PRINT_ISATTY);
if (options & RAW_NUL)
if ((options & RAW_NUL) && ret != JQ_ERROR_UNKNOWN)
priv_fwrite("\0", 1, stdout, dumpopts & JV_PRINT_ISATTY);
if (options & UNBUFFERED_OUTPUT)
fflush(stdout);
Expand Down
10 changes: 10 additions & 0 deletions tests/shtest
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,16 @@ printf '["a", "b"]' | $JQ -0 .[] > $d/out 2>&1
cmp $d/out $d/expected
printf '["a", "b"]' | $JQ --nul-output .[] > $d/out 2>&1
cmp $d/out $d/expected
printf '["a", "c\\u0000d", "b"]' | $JQ --nul-output .[] > $d/out 2>/dev/null
cmp $d/out $d/expected

if printf '{"foo":"foo\\u0000bar"}' | $JQ --nul-output .foo; then
echo "Should exit error on string containing NUL with --nul-output" 1>&2
exit 1
elif [ $? -ne 5 ]; then
echo "Invalid error code" 1>&2
exit 1
fi

## Test streaming parser

Expand Down

0 comments on commit 86699b4

Please sign in to comment.