json rooting fix

This commit is contained in:
2026-02-17 14:00:23 -06:00
parent 2e78e7e0b8
commit 51815b66d8
3 changed files with 219 additions and 9 deletions

View File

@@ -5749,6 +5749,18 @@ exception:
return JS_EXCEPTION;
}
/* Check if val is already on the visited stack (circular reference detection).
Uses identity comparison (===) since we're checking for the same object. */
static BOOL json_stack_has (JSContext *ctx, JSValue stack, JSValue val) {
if (!JS_IsArray (stack)) return FALSE;
JSArray *arr = JS_VALUE_GET_ARRAY (stack);
for (word_t i = 0; i < arr->len; i++) {
if (JS_StrictEq (ctx, arr->values[i], val))
return TRUE;
}
return FALSE;
}
static int js_json_to_str (JSContext *ctx, JSONStringifyContext *jsc, JSValue holder, JSValue val, JSValue indent) {
JSValue v;
int64_t i, len;
@@ -5784,9 +5796,7 @@ static int js_json_to_str (JSContext *ctx, JSONStringifyContext *jsc, JSValue ho
if (mist_is_gc_object (
val_ref.val)) { /* includes arrays (OBJ_ARRAY) since they have JS_TAG_PTR */
v = js_array_includes (ctx, jsc->stack, 1, &val_ref.val);
if (JS_IsException (v)) goto exception;
if (JS_ToBool (ctx, v)) {
if (json_stack_has (ctx, jsc->stack, val_ref.val)) {
JS_ThrowTypeError (ctx, "circular reference");
goto exception;
}
@@ -5801,8 +5811,7 @@ static int js_json_to_str (JSContext *ctx, JSONStringifyContext *jsc, JSValue ho
sep_ref.val = jsc->empty;
sep1_ref.val = jsc->empty;
}
v = js_cell_push (ctx, jsc->stack, 1, &val_ref.val);
if (check_exception_free (ctx, v)) goto exception;
if (JS_ArrayPush (ctx, &jsc->stack, val_ref.val) < 0) goto exception;
ret = JS_IsArray (val_ref.val);
if (ret < 0) goto exception;
if (ret) {
@@ -5890,8 +5899,8 @@ static int js_json_to_str (JSContext *ctx, JSONStringifyContext *jsc, JSValue ho
}
JSC_B_PUTC (jsc, '}');
}
if (check_exception_free (ctx, js_cell_pop (ctx, jsc->stack, 0, NULL)))
goto exception;
v = JS_ArrayPop (ctx, jsc->stack);
if (JS_IsException (v)) goto exception;
goto done;
}
switch (JS_VALUE_GET_NORM_TAG (val_ref.val)) {