Non-extensible holey array: a failed `a[i] = v`, `push()` or `defineProperty` past the end still sets `length` (regression for assignment since fce112d)
I maintainer di solito rispondono entro 2 giorni
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 74/100
Direzione di ricerca
Inizia in quickjs.c, in corrispondenza di JS_CreateProperty() e dell’etichetta generic_array:; segui quando viene aggiornata la lunghezza dell’array rispetto al controllo di estensibilità. Aggiungi un caso di regressione a tests/test_builtin.js per il tentativo non riuscito di aggiungere una proprietà oltre la fine di un array sparso non estensibile, quindi esegui make test. Il lavoro è completato quando l’operazione fallisce senza modificare length e la suite di test viene superata.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Environment
- QuickJS master 712e8c0 (2026-11-02): every case below
- QuickJS 2026-06-04 (release): only the
defineProperty/Reflect.definePropertycase - The assignment and
pushcases bisect to fce112d ("fix super property assignment on non-extensible receiver with existing property", 2026-09-29) make qjs, Debian 12 x86-64, gcc 12.2. Reference: node v26.13.0- Checked on 2026-11-03
Reproduction
"use strict";
var b = [1, , 3]; // a hole: not a fast array
Object.preventExtensions(b);
try { b[3] = 9; } catch (e) { console.log(e.name); }
console.log(b.length); // expected: TypeError, 3 master: TypeError, 4
var c = [1, , 3]; Object.preventExtensions(c);
try { c.push(9); } catch (e) { console.log(e.name); }
console.log(c.length); // expected: TypeError, 3 master: TypeError, 4
var s = [1, , 3]; Object.seal(s);
try { s[5] = 1; } catch (e) { console.log(e.name); }
console.log(s.length); // expected: TypeError, 3 master: TypeError, 6
var o = [1, , 3]; Object.preventExtensions(o);
console.log(Reflect.defineProperty(o, 7, { value: 1 }), o.length);
// expected: false 3 master and 2026-06-04: false 8
The element itself is not created (Object.getOwnPropertyNames(b) stays 0,2,length); only length changes. Arrays
without holes are not affected.
Expected (spec)
Array [[DefineOwnProperty]] for an array
index: Let succeeded be ! OrdinaryDefineOwnProperty(A, P, Desc). If succeeded is false, return false. Only after that:
If index ≥ length, then Set lengthDesc.[[Value]] to index + 1 …. A new property on a non-extensible object is rejected,
so length must not change. b[3] = 9 and push reach the same method through OrdinarySet / CreateDataProperty.
Cause and patch
JS_CreateProperty(), Array case, label generic_array:, updates length (XXX: should update the length after defining the property) before the if (!p->extensible) goto not_extensible check further down. Before fce112d,
JS_SetPropertyInternal() rejected non-extensible receivers before calling JS_CreateProperty(), so only the define path
showed the bug. fce112d moved that test ("the extensibility test is included in JS_CreateProperty()"), which exposes the
early length update to ordinary assignment and push.
diff --git a/quickjs.c b/quickjs.c
--- a/quickjs.c
+++ b/quickjs.c
@@ -10374,6 +10374,9 @@ static int JS_CreateProperty(JSContext *ctx, JSObject *p,
JSProperty *plen;
JSShapeProperty *pslen;
generic_array:
+ /* the length must not change if the property cannot be added */
+ if (!p->extensible)
+ goto not_extensible;
/* update the length field */
plen = &p->prop[0];
JS_ToUint32(ctx, &len, plen->u.value);
With the patch the cases above match node, make test passes (a test is added to tests/test_builtin.js), and test262
shows no new failures against test262_errors.txt.
Related
- quickjs-ng has the
definePropertyhalf of this: quickjs-ng/quickjs#1882
- Lingua principale
- C
- Stelle
- 11.1k
- Fork
- 1.2k
- Merge medio
- 11h 20m
- PR unite (30g)
- 1
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di bellard/quickjs
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 45/100
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 68/100
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
I maintainer di solito rispondono entro 2 giorni
Tutte le issue di bellard/quickjs
Issue simili
-
contrib/ivorysql_ora/src/builtin_packages/utl_file/utl_file.c:517 - FCOPY destroys a file when source and destination are the sameForse già presa @Metastarx l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 75/100
ly05010419/MacNativeGames#1848 ·
I maintainer di solito rispondono entro 1 giorno
-
libc++ test-suite
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
llvm/llvm-project#239851 ·
I maintainer di solito rispondono entro 1 giorno
-
Missing input validationAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 77/100
-
bug game: 010042D00D900000 mac
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
I maintainer di solito rispondono entro 1 giorno