From bf3328ad729ce27e6888f8abc56662ab3c2be11c Mon Sep 17 00:00:00 2001 From: "Artem S. Povalyukhin" Date: Wed, 17 Feb 2021 16:05:28 +0300 Subject: [PATCH] Fixed property descriptor reuse for not extensible objects. This closes #375 issue on Github. --- src/njs_value.c | 17 +++++++++++++---- src/test/njs_unit_test.c | 29 +++++++++++++++++------------ 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/njs_value.c b/src/njs_value.c index 0008ffdf..62cd7320 100644 --- a/src/njs_value.c +++ b/src/njs_value.c @@ -1250,6 +1250,10 @@ slow_path: case NJS_DECLINED: if (njs_slow_path(pq.own_whiteout != NULL)) { /* Previously deleted property. */ + if (!njs_object(value)->extensible) { + goto fail; + } + prop = pq.own_whiteout; prop->type = NJS_PROPERTY; @@ -1278,10 +1282,7 @@ slow_path: } if (njs_slow_path(!njs_object(value)->extensible)) { - njs_key_string_get(vm, &pq.key, &pq.lhq.key); - njs_type_error(vm, "Cannot add property \"%V\", " - "object is not extensible", &pq.lhq.key); - return NJS_ERROR; + goto fail; } prop = njs_object_prop_alloc(vm, &pq.key, &njs_value_undefined, 1); @@ -1304,6 +1305,14 @@ found: prop->value = *setval; return NJS_OK; + +fail: + + njs_key_string_get(vm, &pq.key, &pq.lhq.key); + njs_type_error(vm, "Cannot add property \"%V\", object is not extensible", + &pq.lhq.key); + + return NJS_ERROR; } diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 760d6f91..eae27127 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -14144,42 +14144,44 @@ static njs_unit_test_t njs_test[] = njs_str("false") }, { njs_str("var o = Object.defineProperties({}, {a:{}, b:{}});" - "o = Object.preventExtensions(o);" - "Object.isSealed(o)"), + "o = Object.preventExtensions(o);" + "Object.isSealed(o)"), njs_str("true") }, { njs_str("var o = Object.defineProperties({}, {a:{}, b:{writable:1}});" - "o = Object.preventExtensions(o);" - "Object.isSealed(o)"), + "o = Object.preventExtensions(o);" + "Object.isSealed(o)"), njs_str("true") }, { njs_str("var o = Object.defineProperties({}, {a:{writable:1}});" - "o = Object.preventExtensions(o);" - "Object.isSealed(o)"), + "o = Object.preventExtensions(o);" + "Object.isSealed(o)"), njs_str("true") }, { njs_str("var o = Object.defineProperties({}, {a:{configurable:1}});" - "o = Object.preventExtensions(o);" - "Object.isSealed(o)"), + "o = Object.preventExtensions(o);" + "Object.isSealed(o)"), njs_str("false") }, { njs_str("var o = Object.preventExtensions({a:1});" - "Object.isFrozen(o)"), + "Object.isFrozen(o)"), njs_str("false") }, { njs_str("var o = Object.freeze({a:1}); Object.isFrozen(o)"), njs_str("true") }, + /* Object.preventExtensions() */ + { njs_str("var o = Object.preventExtensions({a:1});" - "Object.defineProperty(o, 'b', {value:1})"), + "Object.defineProperty(o, 'b', {value:1})"), njs_str("TypeError: Cannot add property \"b\", object is not extensible") }, { njs_str("var o = Object.preventExtensions({});" - "Object.defineProperty(o, Symbol.unscopables, {})"), + "Object.defineProperty(o, Symbol.unscopables, {})"), njs_str("TypeError: Cannot add property \"Symbol(Symbol.unscopables)\", object is not extensible") }, { njs_str("var o = Object.preventExtensions({a:1});" - "Object.defineProperties(o, {b:{value:1}})"), + "Object.defineProperties(o, {b:{value:1}})"), njs_str("TypeError: Cannot add property \"b\", object is not extensible") }, { njs_str("var o = Object.preventExtensions({a:1}); o.a = 2; o.a"), @@ -14194,6 +14196,9 @@ static njs_unit_test_t njs_test[] = { njs_str("var o = Object.preventExtensions({a:1}); o[Symbol.unscopables] = 1"), njs_str("TypeError: Cannot add property \"Symbol(Symbol.unscopables)\", object is not extensible") }, + { njs_str("var o = { a: 1 }; delete o.a; Object.preventExtensions(o).a = 1"), + njs_str("TypeError: Cannot add property \"a\", object is not extensible") }, + { njs_str("Object.preventExtensions()"), njs_str("undefined") }, -- 2.47.3