[njs] Fixed property descriptor reuse for not extensible objects.

Dmitry Volyntsev xeioex at nginx.com
Fri Feb 19 15:50:19 UTC 2021


details:   https://hg.nginx.org/njs/rev/21057966d82d
branches:  
changeset: 1608:21057966d82d
user:      Artem S. Povalyukhin <artem.povaluhin at gmail.com>
date:      Wed Feb 17 16:05:28 2021 +0300
description:
Fixed property descriptor reuse for not extensible objects.

This closes #375 issue on Github.

diffstat:

 src/njs_value.c          |  17 +++++++++++++----
 src/test/njs_unit_test.c |  29 +++++++++++++++++------------
 2 files changed, 30 insertions(+), 16 deletions(-)

diffs (111 lines):

diff -r 8770e0292110 -r 21057966d82d src/njs_value.c
--- a/src/njs_value.c	Thu Feb 18 19:51:10 2021 +0000
+++ b/src/njs_value.c	Wed Feb 17 16:05:28 2021 +0300
@@ -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 -r 8770e0292110 -r 21057966d82d src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c	Thu Feb 18 19:51:10 2021 +0000
+++ b/src/test/njs_unit_test.c	Wed Feb 17 16:05:28 2021 +0300
@@ -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") },
 


More information about the nginx-devel mailing list