diff --git a/jerry-core/ecma/operations/ecma-objects.c b/jerry-core/ecma/operations/ecma-objects.c index 76daa04348..cc1b0e3b5c 100644 --- a/jerry-core/ecma/operations/ecma-objects.c +++ b/jerry-core/ecma/operations/ecma-objects.c @@ -2041,7 +2041,37 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */ #if ENABLED (JERRY_ES2015_BUILTIN_PROXY) if (ECMA_OBJECT_IS_PROXY (obj_p)) { - return ecma_proxy_object_own_property_keys (obj_p); + /* Integrated a part of ECMA 262 v6 7.3.21 EnumerableOwnNames operation. */ + ecma_collection_t *proxy_keys = ecma_proxy_object_own_property_keys (obj_p); + if (JERRY_UNLIKELY (proxy_keys == NULL)) + { + return proxy_keys; + } + ecma_collection_t *return_keys = ecma_new_collection (); + + /* Move valid elements to the output collection */ + for (uint32_t i = 0; i < proxy_keys->item_count; i++) + { + ecma_value_t entry = proxy_keys->buffer_p[i]; + ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (entry); + bool prop_is_symbol = ecma_prop_name_is_symbol (prop_name_p); + + if (prop_is_symbol && ((opts & (ECMA_LIST_SYMBOLS | ECMA_LIST_SYMBOLS_ONLY)) != 0)) + { + ecma_collection_push_back (return_keys, entry); + } + else if (!prop_is_symbol && (opts & ECMA_LIST_SYMBOLS_ONLY) == 0) + { + ecma_collection_push_back (return_keys, entry); + } + else + { + ecma_free_value (entry); + } + } + + ecma_collection_destroy (proxy_keys); + return return_keys; } #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */ diff --git a/tests/jerry/es2015/proxy_own_keys.js b/tests/jerry/es2015/proxy_own_keys.js index 5cc79be171..9c2f038043 100644 --- a/tests/jerry/es2015/proxy_own_keys.js +++ b/tests/jerry/es2015/proxy_own_keys.js @@ -16,6 +16,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +function array_check(result_array, expected_array) { + assert(result_array instanceof Array); + assert(result_array.length === expected_array.length); + for (var idx = 0; idx < expected_array.length; idx++) { + assert(result_array[idx] === expected_array[idx]); + } +} + var target = {}; var handler = { ownKeys (target) { throw 42; @@ -56,26 +64,29 @@ try { } // test basic functionality +var symA = Symbol("smA"); +var symB = Symbol("smB"); var target = { prop1: "prop1", prop2: "prop2"}; +target[symB] = "s3"; var handler = { ownKeys: function(target) { - return ["foo", "bar"]; + return ["foo", "bar", symA]; } } var proxy = new Proxy(target, handler); -assert(JSON.stringify(Reflect.ownKeys(proxy)) === '["foo","bar"]'); -assert(JSON.stringify(Object.getOwnPropertyNames(proxy)) === '["foo","bar"]'); -assert(JSON.stringify(Object.keys(proxy)) === '["foo","bar"]'); -assert(JSON.stringify(Object.getOwnPropertySymbols(proxy)) === '["foo","bar"]'); +array_check(Reflect.ownKeys(proxy), ["foo", "bar", symA]); +array_check(Object.getOwnPropertyNames(proxy), ["foo", "bar"]); +array_check(Object.keys(proxy), ["foo", "bar"]); +array_check(Object.getOwnPropertySymbols(proxy), [symA]); handler.ownKeys = function(target) {return Object.getOwnPropertyNames(target);}; -assert(JSON.stringify(Reflect.ownKeys(proxy)) === '["prop1","prop2"]'); -assert(JSON.stringify(Object.getOwnPropertyNames(proxy)) === '["prop1","prop2"]'); -assert(JSON.stringify(Object.keys(proxy)) === '["prop1","prop2"]'); -assert(JSON.stringify(Object.getOwnPropertySymbols(proxy)) === '["prop1","prop2"]'); +array_check(Reflect.ownKeys(proxy), ["prop1", "prop2"]); +array_check(Object.getOwnPropertyNames(proxy), ["prop1", "prop2"]); +array_check(Object.keys(proxy), ["prop1", "prop2"]); +array_check(Object.getOwnPropertySymbols(proxy), []); // test with no trap var target = { prop1: "prop1", prop2: "prop2"}; diff --git a/tests/jerry/es2015/regression-test-issue-3787.js b/tests/jerry/es2015/regression-test-issue-3787.js new file mode 100644 index 0000000000..40a4a0394f --- /dev/null +++ b/tests/jerry/es2015/regression-test-issue-3787.js @@ -0,0 +1,22 @@ +// Copyright JS Foundation and other contributors, http://js.foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +var symbol = Symbol("s"); +var obj = {demo: "3"}; +obj[symbol] = 3; + +var proxy = new Proxy(obj, []); +var str = JSON.stringify(proxy); + +assert(str === '{"demo":"3"}');