@ 261102.1

261024.3 · bd56a745624a5246fac7fe80d11a9cd6fb361ddb

Fix halt_error adding a newline to non-string output (#3694)

The manual says halt_error prints its input with no decoration, not even a newline, but non-string values such as {"a":"xyz"} were printed with a trailing newline.

Dump non-string values to JSON and print them the same way as strings, so {"a":"xyz"} | halt_error(1) now writes exactly {"a":"xyz"} to stderr.

reading declarations

src/main.c

@@ -222,15 +222,16 @@ static int process(jq_state *jq, jv value, int flags, int dumpopts, int options)       ret = JQ_ERROR_UNKNOWN;     jv_free(exit_code);     jv error_message = jq_get_error_message(jq);-    if (jv_get_kind(error_message) == JV_KIND_STRING) {-      // No prefix should be added to the output of `halt_error`.-      priv_fwrite(jv_string_value(error_message), jv_string_length_bytes(jv_copy(error_message)),-          stderr, dumpopts & JV_PRINT_ISATTY);-    } else if (jv_get_kind(error_message) == JV_KIND_NULL) {+    if (jv_get_kind(error_message) == JV_KIND_NULL) {       // Halt with no output     } else if (jv_is_valid(error_message)) {-      error_message = jv_dump_string(error_message, 0);-      fprintf(stderr, "%s\n", jv_string_value(error_message));+      if (jv_get_kind(error_message) != JV_KIND_STRING) {+        error_message = jv_dump_string(error_message, 0);+      }+      // No prefix or trailing newline should be added to the output of+      // `halt_error`.+      priv_fwrite(jv_string_value(error_message), jv_string_length_bytes(jv_copy(error_message)),+          stderr, dumpopts & JV_PRINT_ISATTY);     } // else no message on stderr; use --debug-trace to see a message     fflush(stderr);     jv_free(error_message);

tests/shtest

@@ -566,7 +566,7 @@ if [ "$($VALGRIND $Q $JQ -n '"x\u0000y\u0000z" | halt_error(1)' 2>&1 | tr '\0' '     echo "jq halt_error(1) had unexpected output" 1>&2     exit 1 fi-if [ "$($VALGRIND $Q $JQ -n '{"a":"xyz"} | halt_error(1)' 2>&1)" != '{"a":"xyz"}' ]; then+if [ "$($VALGRIND $Q $JQ -n '{"a":"xyz"} | halt_error(1)' 2>&1 || echo "z")" != '{"a":"xyz"}z' ]; then     echo "jq halt_error(1) had unexpected output" 1>&2     exit 1 fi