From 532ccea6080ed6758f39fe9f6208a44b665023d2 Mon Sep 17 00:00:00 2001 From: itchyny Date: Tue, 5 May 2026 22:44:02 +0900 Subject: [PATCH] Limit recursive object merge depth to prevent stack overflow This fixes CVE-2026-43896. CVE: CVE-2026-43896 Upstream: https://github.com/jqlang/jq/commit/532ccea6080ed6758f39fe9f6208a44b665023d2 Signed-off-by: Thomas Perale --- src/jv.c | 25 +++++++++++++++++++++++-- tests/jq.test | 9 +++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/jv.c b/src/jv.c index feb68d1a1c..84fafef666 100644 --- a/src/jv.c +++ b/src/jv.c @@ -1933,16 +1933,33 @@ jv jv_object_merge(jv a, jv b) { return a; } -jv jv_object_merge_recursive(jv a, jv b) { +#ifndef MAX_OBJECT_MERGE_DEPTH +#define MAX_OBJECT_MERGE_DEPTH (10000) +#endif + +static jv jvp_object_merge_recursive(jv a, jv b, int depth) { assert(JVP_HAS_KIND(a, JV_KIND_OBJECT)); assert(JVP_HAS_KIND(b, JV_KIND_OBJECT)); + if (depth > MAX_OBJECT_MERGE_DEPTH) { + jv_free(a); + jv_free(b); + return jv_invalid_with_msg(jv_string("Object merge too deep")); + } + jv_object_foreach(b, k, v) { jv elem = jv_object_get(jv_copy(a), jv_copy(k)); if (jv_is_valid(elem) && JVP_HAS_KIND(elem, JV_KIND_OBJECT) && JVP_HAS_KIND(v, JV_KIND_OBJECT)) { - a = jv_object_set(a, k, jv_object_merge_recursive(elem, v)); + jv merged = jvp_object_merge_recursive(elem, v, depth + 1); + if (!jv_is_valid(merged)) { + jv_free(k); + jv_free(a); + jv_free(b); + return merged; + } + a = jv_object_set(a, k, merged); } else { jv_free(elem); a = jv_object_set(a, k, v); @@ -1953,6 +1970,10 @@ jv jv_object_merge_recursive(jv a, jv b) { return a; } +jv jv_object_merge_recursive(jv a, jv b) { + return jvp_object_merge_recursive(a, b, 0); +} + /* * Object iteration (internal helpers) */