[njs] Fixed "caller" and "arguments" properties of a function instance.
Dmitry Volyntsev
xeioex at nginx.com
Fri Oct 18 13:27:45 UTC 2019
details: https://hg.nginx.org/njs/rev/ed4472f545a1
branches:
changeset: 1186:ed4472f545a1
user: Artem S. Povalyukhin <artem.povaluhin at gmail.com>
date: Sat Aug 24 05:41:46 2019 +0300
description:
Fixed "caller" and "arguments" properties of a function instance.
This closes #209 issue on Github.
diffstat:
src/njs_function.c | 40 +++++++++++++++++++++++++++++-----------
src/test/njs_unit_test.c | 45 +++++++++++++++++++++++++++++++++++++++------
2 files changed, 68 insertions(+), 17 deletions(-)
diffs (149 lines):
diff -r eae54eb41bfc -r ed4472f545a1 src/njs_function.c
--- a/src/njs_function.c Tue Oct 15 20:09:49 2019 +0300
+++ b/src/njs_function.c Sat Aug 24 05:41:46 2019 +0300
@@ -254,10 +254,11 @@ njs_function_rest_parameters_init(njs_vm
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
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_func
.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 -r eae54eb41bfc -r ed4472f545a1 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Tue Oct 15 20:09:49 2019 +0300
+++ b/src/test/njs_unit_test.c Sat Aug 24 05:41:46 2019 +0300
@@ -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)"
More information about the nginx-devel
mailing list