fixed BJSON array serialization (#457)

This commit is contained in:
Fabrice Bellard
2025-11-15 14:52:50 +01:00
parent 4bd485d713
commit fcbf5ea2a6
2 changed files with 67 additions and 20 deletions

View File

@@ -37258,13 +37258,16 @@ static int JS_WriteModule(BCWriterState *s, JSValueConst obj)
return -1;
}
/* XXX: be compatible with the structured clone algorithm */
static int JS_WriteArray(BCWriterState *s, JSValueConst obj)
{
JSContext *ctx = s->ctx;
JSObject *p = JS_VALUE_GET_OBJ(obj);
uint32_t i, len;
JSValue val;
int ret;
BOOL is_template;
JSShapeProperty *prs;
JSProperty *pr;
if (s->allow_bytecode && !p->extensible) {
/* not extensible array: we consider it is a
@@ -37275,29 +37278,62 @@ static int JS_WriteArray(BCWriterState *s, JSValueConst obj)
bc_put_u8(s, BC_TAG_ARRAY);
is_template = FALSE;
}
if (js_get_length32(s->ctx, &len, obj))
goto fail1;
if (js_get_length32(ctx, &len, obj)) /* no side effect */
goto fail;
bc_put_leb128(s, len);
for(i = 0; i < len; i++) {
val = JS_GetPropertyUint32(s->ctx, obj, i);
if (JS_IsException(val))
goto fail1;
ret = JS_WriteObjectRec(s, val);
JS_FreeValue(s->ctx, val);
if (ret)
goto fail1;
if (p->fast_array) {
for(i = 0; i < p->u.array.count; i++) {
ret = JS_WriteObjectRec(s, p->u.array.u.values[i]);
if (ret)
goto fail;
}
for(i = p->u.array.count; i < len; i++) {
ret = JS_WriteObjectRec(s, JS_UNDEFINED);
if (ret)
goto fail;
}
} else {
for(i = 0; i < len; i++) {
JSAtom atom;
atom = JS_NewAtomUInt32(ctx, i);
if (atom == JS_ATOM_NULL)
goto fail;
prs = find_own_property(&pr, p, atom);
JS_FreeAtom(ctx, atom);
if (prs && (prs->flags & JS_PROP_ENUMERABLE)) {
if (prs->flags & JS_PROP_TMASK) {
JS_ThrowTypeError(ctx, "only value properties are supported");
goto fail;
}
ret = JS_WriteObjectRec(s, pr->u.value);
if (ret)
goto fail;
} else {
ret = JS_WriteObjectRec(s, JS_UNDEFINED);
if (ret)
goto fail;
}
}
}
if (is_template) {
val = JS_GetProperty(s->ctx, obj, JS_ATOM_raw);
if (JS_IsException(val))
goto fail1;
ret = JS_WriteObjectRec(s, val);
JS_FreeValue(s->ctx, val);
if (ret)
goto fail1;
/* the 'raw' property is not enumerable */
prs = find_own_property(&pr, p, JS_ATOM_raw);
if (prs) {
if (prs->flags & JS_PROP_TMASK) {
JS_ThrowTypeError(ctx, "only value properties are supported");
goto fail;
}
ret = JS_WriteObjectRec(s, pr->u.value);
if (ret)
goto fail;
} else {
ret = JS_WriteObjectRec(s, JS_UNDEFINED);
if (ret)
goto fail;
}
}
return 0;
fail1:
fail:
return -1;
}

View File

@@ -184,7 +184,18 @@ function bjson_test_all()
var obj;
bjson_test({x:1, y:2, if:3});
bjson_test([1, 2, 3]);
/* array with holes */
bjson_test([1, , 2, , 3]);
/* fast array with hole */
obj = new Array(5);
obj[0] = 1;
obj[1] = 2;
bjson_test(obj);
bjson_test([1.0, "aa", true, false, undefined, null, NaN, -Infinity, -0.0]);
if (typeof BigInt !== "undefined") {
bjson_test([BigInt("1"), -BigInt("0x123456789"),