[njs] Fixed Object.values() and Object.entries() with shared properties.
noreply at nginx.com
noreply at nginx.com
Tue Jul 2 02:32:02 UTC 2024
details: https://github.com/nginx/njs/commit/69072164673d6dbe069ef05a4b38ef0a7a9d0908
branches: master
commit: 69072164673d6dbe069ef05a4b38ef0a7a9d0908
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Wed, 26 Jun 2024 16:39:59 -0700
description:
Fixed Object.values() and Object.entries() with shared properties.
Previously, the functions directly copied a shared object from
a shared_hash. The copying is nessessary for lazy instantiation
of shared properties.
This fixes #743 issue on Github.
---
src/njs_object.c | 111 ++++++++++-------------------------------------
src/test/njs_unit_test.c | 6 +++
2 files changed, 30 insertions(+), 87 deletions(-)
diff --git a/src/njs_object.c b/src/njs_object.c
index 1b92437c..5a5970c9 100644
--- a/src/njs_object.c
+++ b/src/njs_object.c
@@ -1076,82 +1076,14 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object,
}
-static njs_int_t
-njs_add_obj_prop_kind(njs_vm_t *vm, const njs_object_t *object,
- const njs_lvlhsh_t *hash, njs_lvlhsh_query_t *lhq,
- uint32_t flags, njs_array_t *items)
-{
- njs_int_t ret;
- njs_value_t value, *v, value1;
- njs_array_t *entry;
- njs_object_prop_t *prop;
-
- ret = njs_lvlhsh_find(hash, lhq);
- if (ret != NJS_OK) {
- return NJS_DECLINED;
- }
-
- prop = (njs_object_prop_t *) (lhq->value);
-
- if (prop->type != NJS_ACCESSOR) {
- v = njs_prop_value(prop);
-
- } else {
- if (njs_is_data_descriptor(prop)) {
- v = njs_prop_value(prop);
- goto add;
- }
-
- if (njs_prop_getter(prop) == NULL) {
- v = njs_value_arg(&njs_value_undefined);
- goto add;
- }
-
- v = &value1;
-
- njs_set_object(&value, (njs_object_t *) object);
- ret = njs_function_apply(vm, njs_prop_getter(prop), &value, 1, v);
- if (ret != NJS_OK) {
- return NJS_ERROR;
- }
- }
-
-add:
- if (njs_object_enum_kind(flags) != NJS_ENUM_VALUES) {
- entry = njs_array_alloc(vm, 0, 2, 0);
- if (njs_slow_path(entry == NULL)) {
- return NJS_ERROR;
- }
-
- njs_string_copy(&entry->start[0], &prop->name);
- njs_value_assign(&entry->start[1], v);
-
- njs_set_array(&value, entry);
- v = &value;
- }
-
- ret = njs_array_add(vm, items, v);
- if (njs_slow_path(ret != NJS_OK)) {
- return NJS_ERROR;
- }
-
- return NJS_OK;
-}
-
-
static njs_int_t
njs_object_own_enumerate_object(njs_vm_t *vm, const njs_object_t *object,
const njs_object_t *parent, njs_array_t *items, uint32_t flags)
{
- njs_int_t ret;
- uint32_t i;
- njs_array_t *items_sorted;
- njs_lvlhsh_each_t lhe;
- njs_lvlhsh_query_t lhq;
-
- lhq.proto = &njs_object_hash_proto;
-
- njs_lvlhsh_each_init(&lhe, &njs_object_hash_proto);
+ uint32_t i;
+ njs_int_t ret;
+ njs_array_t *items_sorted, *entry;
+ njs_value_t value, retval;
switch (njs_object_enum_kind(flags)) {
case NJS_ENUM_KEYS:
@@ -1174,26 +1106,31 @@ njs_object_own_enumerate_object(njs_vm_t *vm, const njs_object_t *object,
return NJS_ERROR;
}
- for (i = 0; i< items_sorted->length; i++) {
+ njs_set_object(&value, (njs_object_t *) object);
- lhe.key_hash = 0;
- njs_object_property_key_set(&lhq, &items_sorted->start[i],
- lhe.key_hash);
+ for (i = 0; i< items_sorted->length; i++) {
+ ret = njs_value_property(vm, &value, &items_sorted->start[i],
+ &retval);
+ if (njs_slow_path(ret != NJS_OK)) {
+ njs_array_destroy(vm, items_sorted);
+ return NJS_ERROR;
+ }
- ret = njs_add_obj_prop_kind(vm, object, &object->hash, &lhq, flags,
- items);
- if (ret != NJS_DECLINED) {
- if (ret != NJS_OK) {
+ if (njs_object_enum_kind(flags) != NJS_ENUM_VALUES) {
+ entry = njs_array_alloc(vm, 0, 2, 0);
+ if (njs_slow_path(entry == NULL)) {
return NJS_ERROR;
}
- } else {
- ret = njs_add_obj_prop_kind(vm, object, &object->shared_hash,
- &lhq, flags, items);
- njs_assert(ret != NJS_DECLINED);
- if (ret != NJS_OK) {
- return NJS_ERROR;
- }
+ njs_string_copy(&entry->start[0], &items_sorted->start[i]);
+ njs_value_assign(&entry->start[1], &retval);
+
+ njs_set_array(&retval, entry);
+ }
+
+ ret = njs_array_add(vm, items, &retval);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NJS_ERROR;
}
}
diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c
index d78c5b71..e63b0336 100644
--- a/src/test/njs_unit_test.c
+++ b/src/test/njs_unit_test.c
@@ -22693,6 +22693,12 @@ static njs_unit_test_t njs_shared_test[] =
{ njs_str("var v = Math.round(Math.random() * 1000); ExternalNull.set(v);"
"ExternalNull.get() == v"),
njs_str("true") },
+
+#if (NJS_HAVE_OPENSSL)
+ { njs_str("var cr = Object.entries(global).filter((v) => v[0] == 'crypto')[0][1];"
+ "cr.abc = 1; cr.abc"),
+ njs_str("1") },
+#endif
};
More information about the nginx-devel
mailing list