]> git.kaiwu.me - quickjs.git/commitdiff
fix super property assignment on non-extensible receiver with existing property
authorFabrice Bellard <fabrice@bellard.org>
Tue, 29 Sep 2026 10:10:31 +0000 (12:10 +0200)
committerFabrice Bellard <fabrice@bellard.org>
Tue, 29 Sep 2026 10:10:31 +0000 (12:10 +0200)
quickjs.c
test262_errors.txt

index 51ea4e2072275d9d3afb9ab85482ef2b42cf48ed..f1c696e83e394959c9bd1d993b088524ba5c70d8 100644 (file)
--- a/quickjs.c
+++ b/quickjs.c
@@ -9881,17 +9881,16 @@ int JS_SetPropertyInternal(JSContext *ctx, JSValueConst obj,
         return JS_ThrowTypeErrorOrFalse(ctx, flags, "not an object");
     }
 
-    if (unlikely(!p->extensible)) {
-        JS_FreeValue(ctx, val);
-        return JS_ThrowTypeErrorOrFalse(ctx, flags, "object is not extensible");
-    }
-
     if (likely(p == JS_VALUE_GET_OBJ(obj))) {
         if (p->is_exotic) {
             if (p->class_id == JS_CLASS_ARRAY && p->fast_array &&
                 __JS_AtomIsTaggedInt(prop)) {
                 uint32_t idx = __JS_AtomToUInt32(prop);
                 if (idx == p->u.array.count) {
+                    if (unlikely(!p->extensible)) {
+                        JS_FreeValue(ctx, val);
+                        return JS_ThrowTypeErrorOrFalse(ctx, flags, "object is not extensible");
+                    }
                     /* fast case */
                     return add_fast_array_element(ctx, p, val, flags);
                 } else {
@@ -9903,6 +9902,10 @@ int JS_SetPropertyInternal(JSContext *ctx, JSValueConst obj,
         } else {
             if (unlikely(p->class_id == JS_CLASS_GLOBAL_OBJECT))
                 goto generic_create_prop;
+            if (unlikely(!p->extensible)) {
+                JS_FreeValue(ctx, val);
+                return JS_ThrowTypeErrorOrFalse(ctx, flags, "object is not extensible");
+            }
             pr = add_property(ctx, p, prop, JS_PROP_C_W_E);
             if (unlikely(!pr)) {
                 JS_FreeValue(ctx, val);
@@ -9940,6 +9943,7 @@ int JS_SetPropertyInternal(JSContext *ctx, JSValueConst obj,
             return ret;
         } else {
         generic_create_prop:
+            /* the extensibility test is included in JS_CreateProperty() */
             ret = JS_CreateProperty(ctx, p, prop, val, JS_UNDEFINED, JS_UNDEFINED,
                                     flags |
                                     JS_PROP_HAS_VALUE |
index f4b50206b73ae07c72e1022c301c9525551c0664..e0ff14502fc3f1de7afeaa60c040405e0b83ee53 100644 (file)
@@ -11,7 +11,6 @@ test262/test/language/expressions/compound-assignment/S11.13.2_A6.8_T1.js:24: Te
 test262/test/language/expressions/compound-assignment/S11.13.2_A6.9_T1.js:24: Test262Error: #1: innerX === 2. Actual: 1
 test262/test/language/expressions/compound-assignment/S11.13.2_A6.10_T1.js:24: Test262Error: #1: innerX === 2. Actual: 5
 test262/test/language/expressions/compound-assignment/S11.13.2_A6.11_T1.js:24: Test262Error: #1: innerX === 2. Actual: 5
-test262/test/language/module-code/namespace/internals/super-access-to-tdz-binding.js:32: Test262Error: Expected a ReferenceError but got a TypeError
 test262/test/staging/sm/Function/arguments-parameter-shadowing.js:14: Test262Error: Expected SameValue(«true», «false») to be true
 test262/test/staging/sm/Function/constructor-binding.js:11: Test262Error: Expected SameValue(«"function"», «"undefined"») to be true
 test262/test/staging/sm/Function/function-bind.js:24: Test262Error: Conforms to NativeFunction Syntax: "function bound unbound() {\n    [native code]\n}"