From 484411868bf9351ae7513008f6efd28caa72574f Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Mon, 27 Feb 2023 22:14:36 -0800 Subject: [PATCH] Fixed njs_object_property() with NJS_WHITEOUT properties. Previosly, an error object dumping might result in invalid pointer dereference when 'name' or 'message' property of accessor descriptor type was added and removed before. The fix is to properly handle NJS_WHITEOUT properties. This fixes #617 issue on Github. --- src/njs_object_prop.c | 6 +++++- src/njs_value.c | 9 ++++++--- src/test/njs_unit_test.c | 10 ++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/njs_object_prop.c b/src/njs_object_prop.c index 6bf1c280..005c2eac 100644 --- a/src/njs_object_prop.c +++ b/src/njs_object_prop.c @@ -102,7 +102,11 @@ njs_object_property(njs_vm_t *vm, njs_object_t *object, njs_lvlhsh_query_t *lhq, ret = njs_lvlhsh_find(&object->hash, lhq); if (njs_fast_path(ret == NJS_OK)) { - goto found; + prop = lhq->value; + + if (prop->type != NJS_WHITEOUT) { + goto found; + } } ret = njs_lvlhsh_find(&object->shared_hash, lhq); diff --git a/src/njs_value.c b/src/njs_value.c index 296f057a..c54e36d3 100644 --- a/src/njs_value.c +++ b/src/njs_value.c @@ -1487,13 +1487,16 @@ slow_path: return NJS_ERROR; } - /* GC: release value. */ if (removed != NULL) { - njs_value_assign(removed, njs_prop_value(prop)); + if (njs_is_valid(njs_prop_value(prop))) { + njs_value_assign(removed, njs_prop_value(prop)); + + } else { + njs_set_undefined(removed); + } } prop->type = NJS_WHITEOUT; - njs_set_invalid(njs_prop_value(prop)); return NJS_OK; } diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index ec432b35..4e537917 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -22855,6 +22855,16 @@ static njs_unit_test_t njs_shell_test[] = { njs_str("var a = []; Object.defineProperty(a, 'b', {enumerable: true, get: Object}); a" ENTER), njs_str("[\n b: '[Getter]'\n]") }, + { njs_str("var e = Error()" ENTER + "Object.defineProperty(e, 'message', { configurable: true, set: Object })" ENTER + "delete e.message; e" ENTER), + njs_str("Error") }, + + { njs_str("var e = Error()" ENTER + "Object.defineProperty(e, 'message', { configurable: true, get(){ return 'foo'} })" ENTER + "e" ENTER), + njs_str("Error: foo") }, + /* Temporary indexes */ { njs_str("var a = [1,2,3], i; for (i in a) {Object.seal({});}" ENTER), -- 2.47.3