From 22335391268e6bf661a89f5bd9c682154c2883b5 Mon Sep 17 00:00:00 2001 From: Emanuele Torre Date: Thu, 13 Jul 2023 20:34:25 +0200 Subject: [PATCH 1/2] Fix memory leak for has(nan) jv_array_get() used to be responsible of freeing the input array, but since b5c4c3d67decec22d34f494a200af59bbcadcc80, it is no longer called if the key is nan. We need to free it manually to avoid leaking the array. --- src/jv_aux.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/jv_aux.c b/src/jv_aux.c index 3153d6e61b..6a5efa9432 100644 --- a/src/jv_aux.c +++ b/src/jv_aux.c @@ -215,6 +215,7 @@ jv jv_has(jv t, jv k) { } else if (jv_get_kind(t) == JV_KIND_ARRAY && jv_get_kind(k) == JV_KIND_NUMBER) { if (jvp_number_is_nan(k)) { + jv_free(t); ret = jv_false(); } else { jv elem = jv_array_get(t, (int)jv_number_value(k)); From b4bf2ceb2958eb9aac54cdf949af27d6ae1e5c3c Mon Sep 17 00:00:00 2001 From: Emanuele Torre Date: Thu, 13 Jul 2023 19:04:08 +0200 Subject: [PATCH 2/2] Parse nan in JSON as NaN instead of triggering a parse error Fixes #2021 --- src/jv_parse.c | 6 +++++- tests/jq.test | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/jv_parse.c b/src/jv_parse.c index e91f65d02b..2caf330b29 100644 --- a/src/jv_parse.c +++ b/src/jv_parse.c @@ -490,7 +490,11 @@ static pfunc check_literal(struct jv_parser* p) { switch (p->tokenbuf[0]) { case 't': pattern = "true"; plen = 4; v = jv_true(); break; case 'f': pattern = "false"; plen = 5; v = jv_false(); break; - case 'n': pattern = "null"; plen = 4; v = jv_null(); break; + case 'n': + // if it starts with 'n', it could be a literal "nan" + if (p->tokenpos != 3) { + pattern = "null"; plen = 4; v = jv_null(); + } } if (pattern) { if (p->tokenpos != plen) return "Invalid literal"; diff --git a/tests/jq.test b/tests/jq.test index 3182c1f362..4a8bfeee0c 100644 --- a/tests/jq.test +++ b/tests/jq.test @@ -1799,6 +1799,18 @@ reduce .[] as $then (4 as $else | $else; . as $elif | . + $then * $elif) # { $__loc__ } works + { a, $__loc__, c } {"a":[1,2,3],"b":"foo","c":{"hi":"hey"}} {"a":[1,2,3],"__loc__":{"file":"","line":1},"c":{"hi":"hey"}} + + +# nan is parsed as a valid NaN value from JSON + +fromjson | isnan +"nan" +true + +tojson | fromjson +{"a":nan} +{"a":null}