[njs] Fixed [[SetPrototypeOf]].

Dmitry Volyntsev xeioex at nginx.com
Wed Aug 14 17:24:15 UTC 2019


details:   https://hg.nginx.org/njs/rev/857ecc6fbd25
branches:  
changeset: 1130:857ecc6fbd25
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Wed Aug 14 20:22:26 2019 +0300
description:
Fixed [[SetPrototypeOf]].

diffstat:

 src/njs_object.c         |  21 ++++++++++++---------
 src/test/njs_unit_test.c |  22 ++++++++++++++++++++++
 2 files changed, 34 insertions(+), 9 deletions(-)

diffs (102 lines):

diff -r 7361a69324ec -r 857ecc6fbd25 src/njs_object.c
--- a/src/njs_object.c	Wed Aug 14 20:22:20 2019 +0300
+++ b/src/njs_object.c	Wed Aug 14 20:22:26 2019 +0300
@@ -1846,27 +1846,30 @@ const njs_object_init_t  njs_object_cons
 /*
  * ES6, 9.1.2: [[SetPrototypeOf]].
  */
-static njs_bool_t
+static njs_int_t
 njs_object_set_prototype_of(njs_vm_t *vm, njs_object_t *object,
     const njs_value_t *value)
 {
     const njs_object_t *proto;
 
-    proto = njs_is_object(value) ? njs_object(value)->__proto__
-                                 : NULL;
+    proto = njs_object(value);
 
     if (njs_slow_path(object->__proto__ == proto)) {
-        return 1;
+        return NJS_OK;
+    }
+
+    if (!object->extensible) {
+        return NJS_DECLINED;
     }
 
     if (njs_slow_path(proto == NULL)) {
         object->__proto__ = NULL;
-        return 1;
+        return NJS_OK;
     }
 
     do {
         if (proto == object) {
-            return 0;
+            return NJS_ERROR;
         }
 
         proto = proto->__proto__;
@@ -1875,7 +1878,7 @@ njs_object_set_prototype_of(njs_vm_t *vm
 
     object->__proto__ = njs_object(value);
 
-    return 1;
+    return NJS_OK;
 }
 
 
@@ -1883,7 +1886,7 @@ njs_int_t
 njs_object_prototype_proto(njs_vm_t *vm, njs_value_t *value,
     njs_value_t *setval, njs_value_t *retval)
 {
-    njs_bool_t    ret;
+    njs_int_t     ret;
     njs_object_t  *proto, *object;
 
     if (!njs_is_object(value)) {
@@ -1896,7 +1899,7 @@ njs_object_prototype_proto(njs_vm_t *vm,
     if (setval != NULL) {
         if (njs_is_object(setval) || njs_is_null(setval)) {
             ret = njs_object_set_prototype_of(vm, object, setval);
-            if (njs_slow_path(!ret)) {
+            if (njs_slow_path(ret == NJS_ERROR)) {
                 njs_type_error(vm, "Cyclic __proto__ value");
                 return NJS_ERROR;
             }
diff -r 7361a69324ec -r 857ecc6fbd25 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c	Wed Aug 14 20:22:20 2019 +0300
+++ b/src/test/njs_unit_test.c	Wed Aug 14 20:22:26 2019 +0300
@@ -8782,9 +8782,31 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("({__proto__:null, a:1}).a"),
       njs_str("1") },
 
+    { njs_str("Object.getPrototypeOf({__proto__:null})"),
+      njs_str("null") },
+
+    { njs_str("Object.getPrototypeOf({__proto__:1}) === Object.prototype"),
+      njs_str("true") },
+
+    { njs_str("Object.getPrototypeOf({__proto__:Array.prototype}) === Array.prototype"),
+      njs_str("true") },
+
     { njs_str("({__proto__: []}) instanceof Array"),
       njs_str("true") },
 
+    { njs_str("({__proto__: Array.prototype}) instanceof Array"),
+      njs_str("true") },
+
+    { njs_str("var o = {};"
+              "o.__proto__ = Array.prototype;"
+              "Object.getPrototypeOf(o) === Array.prototype"),
+      njs_str("true") },
+
+    { njs_str("var o = Object.preventExtensions({});"
+              "o.__proto__ = Array.prototype;"
+              "Object.getPrototypeOf(o) === Object.prototype"),
+      njs_str("true") },
+
     { njs_str("({}).__proto__.constructor === Object"),
       njs_str("true") },
 


More information about the nginx-devel mailing list