details: https://hg.nginx.org/njs/rev/beb180165976 branches: changeset: 1860:beb180165976 user: Dmitry Volyntsev <xei...@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-le...@nginx.org