Welcome! Log In Create A New Profile

Advanced

[njs] Fixed operator "in" according to the specification.

Dmitry Volyntsev
November 26, 2019 10:40AM
details: https://hg.nginx.org/njs/rev/a41681864650
branches:
changeset: 1261:a41681864650
user: Artem S. Povalyukhin <artem.povaluhin@gmail.com>
date: Tue Nov 26 13:22:09 2019 +0300
description:
Fixed operator "in" according to the specification.

diffstat:

src/njs_vmcode.c | 35 +++++++++++++----------------------
src/test/njs_unit_test.c | 25 ++++++++++++++++++++-----
2 files changed, 33 insertions(+), 27 deletions(-)

diffs (103 lines):

diff -r e5917fbde8d2 -r a41681864650 src/njs_vmcode.c
--- a/src/njs_vmcode.c Tue Nov 26 15:11:40 2019 +0300
+++ b/src/njs_vmcode.c Tue Nov 26 13:22:09 2019 +0300
@@ -1268,11 +1268,20 @@ static njs_jump_off_t
njs_vmcode_property_in(njs_vm_t *vm, njs_value_t *value, njs_value_t *key)
{
njs_int_t ret;
- njs_bool_t found;
- njs_object_prop_t *prop;
njs_property_query_t pq;

- found = 0;
+ if (njs_slow_path(njs_is_primitive(value))) {
+ njs_type_error(vm, "property \"in\" on primitive %s type",
+ njs_type_string(value->type));
+ return NJS_ERROR;
+ }
+
+ if (njs_slow_path(!njs_is_key(key))) {
+ ret = njs_value_to_key(vm, key, key);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
+ }

njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0);

@@ -1281,25 +1290,7 @@ njs_vmcode_property_in(njs_vm_t *vm, njs
return ret;
}

- if (ret == NJS_DECLINED) {
- if (!njs_is_object(value) && !njs_is_external(value)) {
- njs_type_error(vm, "property in on a primitive value");
-
- return NJS_ERROR;
- }
-
- } else {
- prop = pq.lhq.value;
-
- if (/* !njs_is_data_descriptor(prop) */
- prop->writable == NJS_ATTRIBUTE_UNSET
- || njs_is_valid(&prop->value))
- {
- found = 1;
- }
- }
-
- njs_set_boolean(&vm->retval, found);
+ njs_set_boolean(&vm->retval, ret == NJS_OK);

return sizeof(njs_vmcode_3addr_t);
}
diff -r e5917fbde8d2 -r a41681864650 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Tue Nov 26 15:11:40 2019 +0300
+++ b/src/test/njs_unit_test.c Tue Nov 26 13:22:09 2019 +0300
@@ -3583,6 +3583,8 @@ static njs_unit_test_t njs_test[] =
{ njs_str("Math.E = 1"),
njs_str("TypeError: Cannot assign to read-only property \"E\" of object") },

+ /* "in" operation. */
+
{ njs_str("var o = { 'a': 1, 'b': 2 }; var i; "
"for (i in o) { delete o.a; delete o.b; }; njs.dump(o)"),
njs_str("{}") },
@@ -3597,6 +3599,12 @@ static njs_unit_test_t njs_test[] =
{ njs_str("'a' in {a:1}"),
njs_str("true") },

+ { njs_str("Symbol.unscopables in { [Symbol.unscopables]: 1 }"),
+ njs_str("true") },
+
+ { njs_str("Object(Symbol.toStringTag) in Math"),
+ njs_str("true") },
+
{ njs_str("'1' in [0,,2]"),
njs_str("false") },

@@ -3609,11 +3617,18 @@ static njs_unit_test_t njs_test[] =
{ njs_str("'a' in Object.create({a:1})"),
njs_str("true") },

- { njs_str("var a = 1; 1 in a"),
- njs_str("TypeError: property in on a primitive value") },
-
- { njs_str("var a = true; 1 in a"),
- njs_str("TypeError: property in on a primitive value") },
+ { njs_str("[false, NaN, '', Symbol()]"
+ ".map((x) => { "
+ " try { 'toString' in x; } "
+ " catch (e) { return e instanceof TypeError ? e.message : ''; } "
+ "})"
+ ".every((x) => x.startsWith('property \"in\" on primitive'))"),
+ njs_str("true") },
+
+ { njs_str("var p = new String('test');"
+ "p.toString = () => { throw new Error('failed') };"
+ "p in 1"),
+ njs_str("TypeError: property \"in\" on primitive number type") },

{ njs_str("var n = { toString: function() { return 'a' } };"
"var o = { a: 5 }; o[n]"),
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[njs] Fixed operator "in" according to the specification.

Dmitry Volyntsev 65 November 26, 2019 10:40AM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 75
Record Number of Users: 6 on February 13, 2018
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready