From: Dmitry Volyntsev Date: Fri, 4 Sep 2026 01:47:58 +0000 (-0700) Subject: Fix indexed fast paths for exotic objects X-Git-Tag: 1.0.2~78 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=bb6f23ccc119041657263555d686563097a3d09e;p=njs.git Fix indexed fast paths for exotic objects Previously, Object.values() and Object.entries() erased the concrete type of an exotic receiver, while indexed property fast paths accepted any object with the fast_array bit. Typed arrays could consequently be interpreted as njs_array_t objects, causing invalid memory reads and writes. The fix is to preserve the receiver type during enumeration and to use njs_is_fast_array() for both indexed get and set fast paths. The issue was introduced in 69072164 (0.8.6); the overbroad fast path dates to 912ab387 (0.3.8). This closes #1098 issue on GitHub. --- diff --git a/src/njs_object.c b/src/njs_object.c index fbaf2208..65964070 100644 --- a/src/njs_object.c +++ b/src/njs_object.c @@ -1140,7 +1140,7 @@ njs_object_own_enumerate_object(njs_vm_t *vm, const njs_object_t *object, } entry = NULL; - njs_set_object(&value, (njs_object_t *) object); + njs_set_type_object(&value, (njs_object_t *) object, object->type); for (i = 0; i< items_sorted->length; i++) { ret = njs_value_property_val(vm, &value, &items_sorted->start[i], diff --git a/src/njs_value.c b/src/njs_value.c index 2a7f7fd5..7d77e341 100644 --- a/src/njs_value.c +++ b/src/njs_value.c @@ -1075,9 +1075,7 @@ njs_value_property(njs_vm_t *vm, njs_value_t *value, uint32_t atom_id, return NJS_OK; } - if (njs_slow_path(!(njs_is_object(value) - && njs_object(value)->fast_array))) - { + if (njs_slow_path(!njs_is_fast_array(value))) { goto slow_path; } @@ -1194,9 +1192,7 @@ njs_value_property_set(njs_vm_t *vm, njs_value_t *value, uint32_t atom_id, return NJS_OK; } - if (njs_slow_path(!(njs_is_object(value) - && njs_object(value)->fast_array))) - { + if (njs_slow_path(!njs_is_fast_array(value))) { goto slow_path; } diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index baa4cd58..8ce6c53f 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -6996,6 +6996,24 @@ static njs_unit_test_t njs_test[] = " try {a.set(init,Infinity)} catch (e) {return e.name == 'RangeError'};})"), njs_str("true") }, + { njs_str("var a = new Uint8Array([1]);" + "Object.defineProperty(a, 'x', {enumerable: true," + " get() { return this === a && this[0]; }});" + "Object.values(a)"), + njs_str("1,1") }, + + { njs_str("var a = new Uint8Array([1]);" + "Object.defineProperty(a, 'x', {enumerable: true," + " get() { this[0] = 2; return this[0]; }});" + "Object.values(a); a[0]"), + njs_str("2") }, + + { njs_str("var a = Buffer.from([1]);" + "Object.defineProperty(a, 'x', {enumerable: true," + " get() { return this === a && this[0]; }});" + "Object.values(a)"), + njs_str("1,1") }, + { njs_str(NJS_INT_TYPED_ARRAY_LIST ".map(v=>{try { var a = new v(1); $262.detachArrayBuffer(a.buffer); Object.entries(a)} " "catch (e) {return e.name}}).every(v=>v === 'TypeError')"),