From: Artem S. Povalyukhin Date: Sat, 24 Aug 2019 02:41:46 +0000 (+0300) Subject: Fixed "caller" and "arguments" properties of a function instance. X-Git-Tag: 0.3.6~6 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=b55e067da0adf45e587b6d55882593f8c04a1e8f;p=njs.git Fixed "caller" and "arguments" properties of a function instance. This closes #209 issue on Github. --- diff --git a/src/njs_function.c b/src/njs_function.c index 2a4ee501..3bca2890 100644 --- a/src/njs_function.c +++ b/src/njs_function.c @@ -254,10 +254,11 @@ njs_function_rest_parameters_init(njs_vm_t *vm, njs_native_frame_t *frame) static njs_int_t -njs_function_arguments_thrower(njs_vm_t *vm, njs_value_t *value, - njs_value_t *setval, njs_value_t *retval) +njs_function_prototype_thrower(njs_vm_t *vm, njs_value_t *args, + njs_uint_t nargs, njs_index_t unused) { - njs_type_error(vm, "\"caller\", \"callee\" properties may not be accessed"); + njs_type_error(vm, "\"caller\", \"callee\", \"arguments\" " + "properties may not be accessed"); return NJS_ERROR; } @@ -265,15 +266,12 @@ njs_function_arguments_thrower(njs_vm_t *vm, njs_value_t *value, const njs_object_prop_t njs_arguments_object_instance_properties[] = { { - .type = NJS_PROPERTY_HANDLER, - .name = njs_string("caller"), - .value = njs_prop_handler(njs_function_arguments_thrower), - }, - - { - .type = NJS_PROPERTY_HANDLER, + .type = NJS_PROPERTY, .name = njs_string("callee"), - .value = njs_prop_handler(njs_function_arguments_thrower), + .value = njs_value(NJS_INVALID, 1, NAN), + .getter = njs_native_function(njs_function_prototype_thrower, 0, 0), + .setter = njs_native_function(njs_function_prototype_thrower, 0, 0), + .writable = NJS_ATTRIBUTE_UNSET, }, }; @@ -1279,6 +1277,26 @@ static const njs_object_prop_t njs_function_prototype_properties[] = .writable = 1, .configurable = 1, }, + + { + .type = NJS_PROPERTY, + .name = njs_string("caller"), + .value = njs_value(NJS_INVALID, 1, NAN), + .getter = njs_native_function(njs_function_prototype_thrower, 0, 0), + .setter = njs_native_function(njs_function_prototype_thrower, 0, 0), + .writable = NJS_ATTRIBUTE_UNSET, + .configurable = 1, + }, + + { + .type = NJS_PROPERTY, + .name = njs_string("arguments"), + .value = njs_value(NJS_INVALID, 1, NAN), + .getter = njs_native_function(njs_function_prototype_thrower, 0, 0), + .setter = njs_native_function(njs_function_prototype_thrower, 0, 0), + .writable = NJS_ATTRIBUTE_UNSET, + .configurable = 1, + }, }; diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 6c9e3540..032b6c41 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -8025,12 +8025,6 @@ static njs_unit_test_t njs_test[] = { njs_str("(function(){return arguments[3];}).bind(null, 0)('a','b','c')"), njs_str("c") }, - { njs_str("(function(){return arguments.callee;})()"), - njs_str("TypeError: \"caller\", \"callee\" properties may not be accessed") }, - - { njs_str("(function(){return arguments.caller;})()"), - njs_str("TypeError: \"caller\", \"callee\" properties may not be accessed") }, - { njs_str("function sum() { var args = Array.prototype.slice.call(arguments); " "return args.reduce(function(prev, curr) {return prev + curr})};" "[sum(1), sum(1,2), sum(1,2,3), sum(1,2,3,4)]"), @@ -8041,6 +8035,39 @@ static njs_unit_test_t njs_test[] = "[concat('.',1,2,3), concat('+',1,2,3,4)]"), njs_str("1.2.3,1+2+3+4") }, + /* strict mode restrictions */ + + { njs_str("(function() {}).caller"), + njs_str("TypeError: \"caller\", \"callee\", \"arguments\" properties may not be accessed") }, + + { njs_str("(function() {}).arguments"), + njs_str("TypeError: \"caller\", \"callee\", \"arguments\" properties may not be accessed") }, + + { njs_str("var p = Object.getPrototypeOf(function() {});" + "var d = Object.getOwnPropertyDescriptor(p, 'caller');" + "typeof d.get == 'function' && typeof d.get == typeof d.set" + " && d.configurable && !d.enumerable"), + njs_str("true") }, + + { njs_str("var p = Object.getPrototypeOf(function() {});" + "var d = Object.getOwnPropertyDescriptor(p, 'arguments');" + "typeof d.get == 'function' && typeof d.get == typeof d.set" + " && d.configurable && !d.enumerable"), + njs_str("true") }, + + { njs_str("(function(){return arguments.callee;})()"), + njs_str("TypeError: \"caller\", \"callee\", \"arguments\" properties may not be accessed") }, + + { njs_str("var f = function() { return arguments; };" + "Object.getOwnPropertyDescriptor(f(), 'caller')"), + njs_str("undefined") }, + + { njs_str("var f = function() { return arguments; };" + "var d = Object.getOwnPropertyDescriptor(f(), 'callee');" + "typeof d.get == 'function' && typeof d.get == typeof d.set" + " && !d.configurable && !d.enumerable"), + njs_str("true") }, + /* rest parameters. */ { njs_str("function myFoo(a,b,...other) { return other };" @@ -11487,6 +11514,8 @@ static njs_unit_test_t njs_test[] = "function isConfigurableMethods(o) {" " var except = [" " 'prototype'," + " 'caller'," + " 'arguments'," " ];" " return Object.getOwnPropertyNames(o)" " .filter(v => !except.includes(v)" @@ -11516,6 +11545,8 @@ static njs_unit_test_t njs_test[] = "function isWritableMethods(o) {" " var except = [" " 'prototype'," + " 'caller'," + " 'arguments'," " ];" " return Object.getOwnPropertyNames(o)" " .filter(v => !except.includes(v)" @@ -13939,6 +13970,8 @@ static njs_unit_test_t njs_test[] = " var except = [" " 'prototype'," " 'constructor'," + " 'caller'," + " 'arguments'," " ];" " return Object.getOwnPropertyNames(o)" " .filter(v => !except.includes(v)"