[njs] Native methods and non-constructor functions must throw
Igor Sysoev
igor at sysoev.ru
Tue Nov 15 15:02:46 UTC 2016
details: http://hg.nginx.org/njs/rev/d2ab98ea87ad
branches:
changeset: 254:d2ab98ea87ad
user: Igor Sysoev <igor at sysoev.ru>
date: Tue Nov 15 17:43:05 2016 +0300
description:
Native methods and non-constructor functions must throw
TypeError exception if they are called as constructor.
diffstat:
njs/njs_builtin.c | 1 +
njs/njs_vm.c | 22 +++++++++++++++++-----
njs/njs_vm.h | 16 +++-------------
njs/test/njs_unit_test.c | 6 ++++++
4 files changed, 27 insertions(+), 18 deletions(-)
diffs (127 lines):
diff -r 91640c0405f4 -r d2ab98ea87ad njs/njs_builtin.c
--- a/njs/njs_builtin.c Fri Nov 11 18:12:13 2016 +0300
+++ b/njs/njs_builtin.c Tue Nov 15 17:43:05 2016 +0300
@@ -237,6 +237,7 @@ njs_builtin_objects_create(njs_vm_t *vm)
for (i = NJS_CONSTRUCTOR_OBJECT; i < NJS_CONSTRUCTOR_MAX; i++) {
constructors[i].object.shared = 0;
constructors[i].native = 1;
+ constructors[i].ctor = 1;
constructors[i].args_offset = 1;
constructors[i].u.native = native_constructors[i].native;
constructors[i].args_types[0] = native_constructors[i].args_types[0];
diff -r 91640c0405f4 -r d2ab98ea87ad njs/njs_vm.c
--- a/njs/njs_vm.c Fri Nov 11 18:12:13 2016 +0300
+++ b/njs/njs_vm.c Tue Nov 15 17:43:05 2016 +0300
@@ -2152,6 +2152,7 @@ njs_ret_t
njs_vmcode_function_frame(njs_vm_t *vm, njs_value_t *value, njs_value_t *nargs)
{
njs_ret_t ret;
+ nxt_bool_t ctor;
njs_value_t val, *this;
njs_object_t *object;
njs_function_t *function;
@@ -2160,13 +2161,17 @@ njs_vmcode_function_frame(njs_vm_t *vm,
if (nxt_fast_path(njs_is_function(value))) {
func = (njs_vmcode_function_frame_t *) vm->current;
+ ctor = func->code.ctor;
function = value->data.u.function;
if (function->native) {
+ if (ctor && !function->ctor) {
+ goto fail;
+ }
+
ret = njs_function_native_frame(vm, function, &njs_value_void,
- NULL, (uintptr_t) nargs, 0,
- func->code.ctor);
+ NULL, (uintptr_t) nargs, 0, ctor);
if (nxt_fast_path(ret == NXT_OK)) {
return sizeof(njs_vmcode_function_frame_t);
@@ -2175,7 +2180,7 @@ njs_vmcode_function_frame(njs_vm_t *vm,
return ret;
}
- if (func->code.ctor) {
+ if (ctor) {
object = njs_function_new_object(vm, value);
if (nxt_slow_path(object == NULL)) {
return NXT_ERROR;
@@ -2191,7 +2196,7 @@ njs_vmcode_function_frame(njs_vm_t *vm,
}
ret = njs_function_frame(vm, function, this, NULL, (uintptr_t) nargs,
- func->code.ctor);
+ ctor);
if (nxt_fast_path(ret == NXT_OK)) {
return sizeof(njs_vmcode_function_frame_t);
@@ -2200,6 +2205,8 @@ njs_vmcode_function_frame(njs_vm_t *vm,
return ret;
}
+fail:
+
vm->exception = &njs_exception_type_error;
return NXT_ERROR;
@@ -2329,8 +2336,13 @@ njs_vmcode_method_call(njs_vm_t *vm, njs
return ret;
}
+ if (method->code.ctor) {
+ vm->exception = &njs_exception_type_error;
+ return NXT_ERROR;
+ }
+
ret = njs_function_native_frame(vm, function, object, NULL, method->nargs,
- 0, method->code.ctor);
+ 0, 0);
if (nxt_fast_path(ret == NXT_OK)) {
njs_retain(object);
diff -r 91640c0405f4 -r d2ab98ea87ad njs/njs_vm.h
--- a/njs/njs_vm.h Fri Nov 11 18:12:13 2016 +0300
+++ b/njs/njs_vm.h Tue Nov 15 17:43:05 2016 +0300
@@ -230,20 +230,10 @@ struct njs_function_s {
uint8_t args_types[NJS_ARGS_TYPES_MAX];
uint8_t args_offset;
-
- /*
- * TODO Shared
- * When function object is used as value: in assignments,
- * as function argument, as property and as object to get properties.
- */
+ uint8_t continuation_size;
-#if (NXT_64BIT)
- uint8_t native;
- uint8_t continuation_size;
-#else
- uint8_t native;
- uint8_t continuation_size;
-#endif
+ uint8_t native:1;
+ uint8_t ctor:1;
union {
njs_function_lambda_t *lambda;
diff -r 91640c0405f4 -r d2ab98ea87ad njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Fri Nov 11 18:12:13 2016 +0300
+++ b/njs/test/njs_unit_test.c Tue Nov 15 17:43:05 2016 +0300
@@ -4223,6 +4223,12 @@ static njs_unit_test_t njs_test[] =
{ nxt_string("var F = function (){}; typeof F.prototype"),
nxt_string("object") },
+ { nxt_string("new decodeURI('%00')"),
+ nxt_string("TypeError")},
+
+ { nxt_string("new ''.toString"),
+ nxt_string("TypeError")},
+
{ nxt_string("function F() { return Number }"
"var o = new (F())(5);"
"typeof o +' '+ o"),
More information about the nginx-devel
mailing list