From: Dmitry Volyntsev Date: Wed, 14 Aug 2019 17:22:26 +0000 (+0300) Subject: Fixed [[SetPrototypeOf]]. X-Git-Tag: 0.3.5~3 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=629699c39d212d30e8f7d4d2431d49ed92b522a0;p=njs.git Fixed [[SetPrototypeOf]]. --- diff --git a/src/njs_object.c b/src/njs_object.c index 7994f485..9c734115 100644 --- a/src/njs_object.c +++ b/src/njs_object.c @@ -1846,27 +1846,30 @@ const njs_object_init_t njs_object_constructor_init = { /* * 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, njs_object_t *object, 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, njs_value_t *value, 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 --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 7ac78b6b..6fb8a59f 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -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") },