From ed3c7f214b192024ade9b5c501f32800a87984b5 Mon Sep 17 00:00:00 2001 From: itchyny Date: Thu, 5 Mar 2026 08:28:43 +0900 Subject: [PATCH] Fix tonumber and toboolean to reject strings with embedded null bytes (#3496) --- src/builtin.c | 8 ++++++++ tests/jq.test | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/src/builtin.c b/src/builtin.c index 8b85ca39..a6a1d333 100644 --- a/src/builtin.c +++ b/src/builtin.c @@ -446,6 +446,10 @@ static jv f_tonumber(jq_state *jq, jv input) { } if (jv_get_kind(input) == JV_KIND_STRING) { const char* s = jv_string_value(input); + int len = jv_string_length_bytes(jv_copy(input)); + if ((size_t)len != strlen(s)) { + return type_error(input, "cannot be parsed as a number"); + } #ifdef USE_DECNUM jv number = jv_number_with_literal(s); if (jv_get_kind(number) == JV_KIND_INVALID) { @@ -471,6 +475,10 @@ static jv f_toboolean(jq_state *jq, jv input) { } if (jv_get_kind(input) == JV_KIND_STRING) { const char *s = jv_string_value(input); + int len = jv_string_length_bytes(jv_copy(input)); + if ((size_t)len != strlen(s)) { + return type_error(input, "cannot be parsed as a boolean"); + } if (strcmp(s, "true") == 0) { jv_free(input); return jv_true(); diff --git a/tests/jq.test b/tests/jq.test index cf7f8b47..169a7ac8 100644 --- a/tests/jq.test +++ b/tests/jq.test @@ -698,6 +698,10 @@ null 4 15 +"123\u0000456" | try tonumber catch . +null +"string (\"123\\u0000456\") cannot be parsed as a number" + map(toboolean) ["false","true",false,true] [false,true,false,true] @@ -713,6 +717,11 @@ map(toboolean) "array ([]) cannot be parsed as a boolean" "object ({}) cannot be parsed as a boolean" +"true\u0000x", "false\u0000" | try toboolean catch . +null +"string (\"true\\u0000x\") cannot be parsed as a boolean" +"string (\"false\\u0000\") cannot be parsed as a boolean" + [{"a":42},.object,10,.num,false,true,null,"b",[1,4]] | .[] as $x | [$x == .[]] {"object": {"a":42}, "num":10.0} [true, true, false, false, false, false, false, false, false]