File CVE-2024-53427.patch of Package jq

This is a combined patch consisting of upstream patches:

https://github.com/jqlang/jq/commit/b86ff49f46a4a37e5a8e75a140cb5fd6e1331384
https://github.com/jqlang/jq/commit/a09a4dfd55e6c24d04b35062ccfe4509748b1dd3

which have been slightly tweaked so they apply to the jq 1.7.1 release.

The purpose of the patch is to fix CVE-2024-53427.
Index: jq-1.7.1/src/jv.c
===================================================================
--- jq-1.7.1.orig/src/jv.c
+++ jq-1.7.1/src/jv.c
@@ -206,9 +206,6 @@ enum {
   JVP_NUMBER_DECIMAL = 1
 };
 
-#define JV_NUMBER_SIZE_INIT      (0)
-#define JV_NUMBER_SIZE_CONVERTED (1)
-
 #define JVP_FLAGS_NUMBER_NATIVE       JVP_MAKE_FLAGS(JV_KIND_NUMBER, JVP_MAKE_PFLAGS(JVP_NUMBER_NATIVE, 0))
 #define JVP_FLAGS_NUMBER_LITERAL      JVP_MAKE_FLAGS(JV_KIND_NUMBER, JVP_MAKE_PFLAGS(JVP_NUMBER_DECIMAL, 1))
 
@@ -589,8 +586,17 @@ static jv jvp_literal_number_new(const c
     jv_mem_free(n);
     return JV_INVALID;
   }
+  if (decNumberIsNaN(&n->num_decimal)) {
+    // Reject NaN with payload.
+    if (n->num_decimal.digits > 1 || *n->num_decimal.lsu != 0) {
+      jv_mem_free(n);
+      return JV_INVALID;
+    }
+    jv_mem_free(n);
+    return jv_number(NAN);
+  }
 
-  jv r = {JVP_FLAGS_NUMBER_LITERAL, 0, 0, JV_NUMBER_SIZE_INIT, {&n->refcnt}};
+  jv r = {JVP_FLAGS_NUMBER_LITERAL, 0, 0, 0, {&n->refcnt}};
   return r;
 }
 
@@ -698,9 +704,8 @@ double jv_number_value(jv j) {
   if (JVP_HAS_FLAGS(j, JVP_FLAGS_NUMBER_LITERAL)) {
     jvp_literal_number* n = jvp_literal_number_ptr(j);
 
-    if (j.size != JV_NUMBER_SIZE_CONVERTED) {
+    if (isnan(n->num_double)) {
       n->num_double = jvp_literal_number_to_double(j);
-      j.size = JV_NUMBER_SIZE_CONVERTED;
     }
 
     return n->num_double;
@@ -731,7 +736,7 @@ int jvp_number_is_nan(jv n) {
     return decNumberIsNaN(pdec);
   }
 #endif
-  return n.u.number != n.u.number;
+  return isnan(n.u.number);
 }
 
 int jvp_number_cmp(jv a, jv b) {
Index: jq-1.7.1/tests/jq.test
===================================================================
--- jq-1.7.1.orig/tests/jq.test
+++ jq-1.7.1/tests/jq.test
@@ -1938,11 +1938,17 @@ tojson | fromjson
 {"a":nan}
 {"a":null}
 
-# also "nan with payload" #2985
-fromjson | isnan
-"nan1234"
+# NaN with payload is not parsed
+.[] | try (fromjson | isnan) catch .
+["NaN","-NaN","NaN1","NaN10","NaN100","NaN1000","NaN10000","NaN100000"]
 true
-
+true
+"Invalid numeric literal at EOF at line 1, column 4 (while parsing 'NaN1')"
+"Invalid numeric literal at EOF at line 1, column 5 (while parsing 'NaN10')"
+"Invalid numeric literal at EOF at line 1, column 6 (while parsing 'NaN100')"
+"Invalid numeric literal at EOF at line 1, column 7 (while parsing 'NaN1000')"
+"Invalid numeric literal at EOF at line 1, column 8 (while parsing 'NaN10000')"
+"Invalid numeric literal at EOF at line 1, column 9 (while parsing 'NaN100000')"
 
 # calling input/0, or debug/0 in a test doesn't crash jq
 
Index: jq-1.7.1/tests/shtest
===================================================================
--- jq-1.7.1.orig/tests/shtest
+++ jq-1.7.1/tests/shtest
@@ -594,11 +594,6 @@ if ! x=$($JQ -n "1 # foo$cr + 2") || [ "
   exit 1
 fi
 
-# CVE-2023-50268: No stack overflow comparing a nan with a large payload
-$VALGRIND $Q $JQ '1 != .' <<\EOF >/dev/null
-Nan4000
-EOF
-
 # Allow passing the inline jq script before -- #2919
 if ! r=$($JQ --args -rn -- '$ARGS.positional[0]' bar) || [ "$r" != bar ]; then
     echo "passing the inline script after -- didn't work"
openSUSE Build Service is sponsored by