Welcome! Log In Create A New Profile

Advanced

[njs] Fixed redefinition of special props in Object.defineProperty().

Dmitry Volyntsev
May 19, 2022 07:52PM
details: https://hg.nginx.org/njs/rev/beb180165976
branches:
changeset: 1860:beb180165976
user: Dmitry Volyntsev <xeioex@nginx.com>
date: Thu May 19 16:41:08 2022 -0700
description:
Fixed redefinition of special props in Object.defineProperty().

Previously, when NJS_PROPERTY_HANDLER property was updated it might be
left in inconsistent state. Namely, prop->type was left unchanged, but
prop->value did not have an expected property handler. As a result
consecutive reference to the property may result in a segment violation.

The fix is to update the prop->type during redefinition.

This closes #504 issue on Github.

diffstat:

src/njs_object.h | 4 +++-
src/njs_object_prop.c | 11 ++++++++++-
src/njs_value.c | 1 +
src/njs_value.h | 2 ++
src/test/njs_unit_test.c | 6 ++++++
5 files changed, 22 insertions(+), 2 deletions(-)

diffs (88 lines):

diff -r aa27056f4bc9 -r beb180165976 src/njs_object.h
--- a/src/njs_object.h Wed May 18 00:01:05 2022 -0700
+++ b/src/njs_object.h Thu May 19 16:41:08 2022 -0700
@@ -88,7 +88,9 @@ njs_int_t njs_object_prop_init(njs_vm_t
njs_inline njs_bool_t
njs_is_data_descriptor(njs_object_prop_t *prop)
{
- return prop->writable != NJS_ATTRIBUTE_UNSET || njs_is_valid(&prop->value);
+ return njs_is_valid(&prop->value) ||
+ prop->writable != NJS_ATTRIBUTE_UNSET ||
+ prop->type == NJS_PROPERTY_HANDLER;
}


diff -r aa27056f4bc9 -r beb180165976 src/njs_object_prop.c
--- a/src/njs_object_prop.c Wed May 18 00:01:05 2022 -0700
+++ b/src/njs_object_prop.c Thu May 19 16:41:08 2022 -0700
@@ -364,6 +364,15 @@ set_prop:
* the property's attributes to their default values.
*/

+ if (pq.temp) {
+ pq.lhq.value = NULL;
+ prop->configurable = prev->configurable;
+ prop->enumerable = prev->enumerable;
+ goto set_prop;
+ }
+
+ prev->type = prop->type;
+
if (njs_is_data_descriptor(prev)) {
njs_set_undefined(&prev->getter);
njs_set_undefined(&prev->setter);
@@ -414,7 +423,7 @@ set_prop:

done:

- if (njs_is_valid(&prop->value) || njs_is_accessor_descriptor(prop)) {
+ if (njs_is_valid(&prop->value)) {
if (prev->type == NJS_PROPERTY_HANDLER) {
if (prev->writable) {
ret = prev->value.data.u.prop_handler(vm, prev, object,
diff -r aa27056f4bc9 -r beb180165976 src/njs_value.c
--- a/src/njs_value.c Wed May 18 00:01:05 2022 -0700
+++ b/src/njs_value.c Thu May 19 16:41:08 2022 -0700
@@ -942,6 +942,7 @@ njs_external_property_query(njs_vm_t *vm
return NJS_DECLINED;
}

+ pq->temp = 1;
prop = &pq->scratch;

njs_memzero(prop, sizeof(njs_object_prop_t));
diff -r aa27056f4bc9 -r beb180165976 src/njs_value.h
--- a/src/njs_value.h Wed May 18 00:01:05 2022 -0700
+++ b/src/njs_value.h Thu May 19 16:41:08 2022 -0700
@@ -374,6 +374,7 @@ typedef struct {
njs_object_prop_t *own_whiteout;
uint8_t query;
uint8_t shared;
+ uint8_t temp;
uint8_t own;
} njs_property_query_t;

@@ -1030,6 +1031,7 @@ njs_set_object_value(njs_value_t *value,
(pq)->query = _query; \
(pq)->shared = 0; \
(pq)->own = _own; \
+ (pq)->temp = 0; \
} while (0)


diff -r aa27056f4bc9 -r beb180165976 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Wed May 18 00:01:05 2022 -0700
+++ b/src/test/njs_unit_test.c Thu May 19 16:41:08 2022 -0700
@@ -9681,6 +9681,12 @@ static njs_unit_test_t njs_test[] =
"fn(1); arr"),
njs_str("1,2,3,4,5,6") },

+ { njs_str("function f(){};"
+ "Object.defineProperty(f, 'length', {set: () => {}});"
+ "Object.defineProperty(f, 'length', {value: 42});"
+ "f.length"),
+ njs_str("42") },
+
/* Function nesting depth. */

{ njs_str("() => () => () => () => () => () => () => () => () => () => () =>"
_______________________________________________
nginx-devel mailing list -- nginx-devel@nginx.org
To unsubscribe send an email to nginx-devel-leave@nginx.org
Subject Author Views Posted

[njs] Fixed redefinition of special props in Object.defineProperty().

Dmitry Volyntsev 382 May 19, 2022 07:52PM



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

Online Users

Guests: 237
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready