From: Fabrice Bellard Date: Tue, 29 Sep 2026 13:16:59 +0000 (+0200) Subject: repect the spec operation order in Object.defineProperties X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=535a7c250ff4a577ec36c3e103daab6dadeea650;p=quickjs.git repect the spec operation order in Object.defineProperties --- diff --git a/quickjs.c b/quickjs.c index 8b3a450..66d4514 100644 --- a/quickjs.c +++ b/quickjs.c @@ -40303,7 +40303,7 @@ static __exception int JS_ObjectDefineProperties(JSContext *ctx, JSValueConst obj, JSValueConst properties) { - JSValue props, desc; + JSValue props, *descs = NULL; JSObject *p; JSPropertyEnum *atoms; uint32_t len, i; @@ -40313,28 +40313,54 @@ static __exception int JS_ObjectDefineProperties(JSContext *ctx, JS_ThrowTypeErrorNotAnObject(ctx); return -1; } - desc = JS_UNDEFINED; props = JS_ToObject(ctx, properties); if (JS_IsException(props)) return -1; p = JS_VALUE_GET_OBJ(props); - /* XXX: not done in the same order as the spec */ - if (JS_GetOwnPropertyNamesInternal(ctx, &atoms, &len, p, JS_GPN_ENUM_ONLY | JS_GPN_STRING_MASK | JS_GPN_SYMBOL_MASK) < 0) + if (JS_GetOwnPropertyNamesInternal(ctx, &atoms, &len, p, JS_GPN_STRING_MASK | JS_GPN_SYMBOL_MASK) < 0) goto exception; + descs = js_malloc(ctx, sizeof(descs[0]) * len); + if (!descs) + goto exception; + for(i = 0; i < len; i++) + descs[i] = JS_UNDEFINED; for(i = 0; i < len; i++) { - JS_FreeValue(ctx, desc); - desc = JS_GetProperty(ctx, props, atoms[i].atom); - if (JS_IsException(desc)) - goto exception; - if (JS_DefinePropertyDesc(ctx, obj, atoms[i].atom, desc, JS_PROP_THROW) < 0) + JSPropertyDescriptor prop_desc; + int res; + /* must do the getOwnProperty here to respect the spec */ + res = JS_GetOwnPropertyInternal(ctx, &prop_desc, p, atoms[i].atom); + if (res < 0) goto exception; + if (res) { + atoms[i].is_enumerable = (prop_desc.flags & JS_PROP_ENUMERABLE) != 0; + js_free_desc(ctx, &prop_desc); + if (atoms[i].is_enumerable) { + JSValue desc; + desc = JS_GetProperty(ctx, props, atoms[i].atom); + if (JS_IsException(desc)) + goto exception; + descs[i] = desc; + } + } else { + atoms[i].is_enumerable = FALSE; + } + } + for(i = 0; i < len; i++) { + if (atoms[i].is_enumerable) { + if (JS_DefinePropertyDesc(ctx, obj, atoms[i].atom, descs[i], JS_PROP_THROW) < 0) + goto exception; + } } ret = 0; exception: + if (descs) { + for(i = 0; i < len; i++) + JS_FreeValue(ctx, descs[i]); + js_free(ctx, descs); + } JS_FreePropertyEnum(ctx, atoms, len); JS_FreeValue(ctx, props); - JS_FreeValue(ctx, desc); return ret; } diff --git a/test262_errors.txt b/test262_errors.txt index 386b674..474092f 100644 --- a/test262_errors.txt +++ b/test262_errors.txt @@ -11,6 +11,5 @@ test262/test/staging/sm/lexical-environment/block-scoped-functions-annex-b-if.js test262/test/staging/sm/lexical-environment/block-scoped-functions-annex-b-notapplicable.js:14: Test262Error: Expected SameValue(«function x() {2}», «function x() {1}») to be true test262/test/staging/sm/lexical-environment/block-scoped-functions-deprecated-redecl.js:23: Test262Error: Expected SameValue(«3», «4») to be true test262/test/staging/sm/lexical-environment/var-in-catch-body-annex-b-eval.js:16: Test262Error: Expected SameValue(«"g"», «"global-x"») to be true -test262/test/staging/sm/object/defineProperties-order.js:11: Test262Error: Expected SameValue(«"ownKeys,getOwnPropertyDescriptor,getOwnPropertyDescriptor,get,get"», «"ownKeys,getOwnPropertyDescriptor,get,getOwnPropertyDescriptor,get"») to be true test262/test/staging/sm/regress/regress-602621.js:13: Test262Error: function sub-statement must override arguments Expected SameValue(«"function"», «"object"») to be true test262/test/staging/sm/statements/arrow-function-in-for-statement-head.js:13: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all