From aedd55b1f85b780666eccc678dd4b17fc5415720 Mon Sep 17 00:00:00 2001 From: Szilagyi Adam Date: Tue, 7 Jan 2020 15:13:28 +0100 Subject: [PATCH] Add unscopables check to ecma_op_get_value_lex_env_base (#3476) Also added a special test case for this to symbol-unscopables.js JerryScript-DCO-1.0-Signed-off-by: Adam Szilagyi aszilagy@inf.u-szeged.hu --- .../ecma/operations/ecma-get-put-value.c | 23 +++++++++++++++++++ jerry-core/ecma/operations/ecma-reference.c | 2 +- jerry-core/ecma/operations/ecma-reference.h | 1 + tests/jerry/es2015/symbol-unscopables.js | 18 +++++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/jerry-core/ecma/operations/ecma-get-put-value.c b/jerry-core/ecma/operations/ecma-get-put-value.c index a1bedf464..eba5a0672 100644 --- a/jerry-core/ecma/operations/ecma-get-put-value.c +++ b/jerry-core/ecma/operations/ecma-get-put-value.c @@ -26,6 +26,7 @@ #include "ecma-function-object.h" #include "ecma-objects-general.h" #include "ecma-try-catch-macro.h" +#include "ecma-reference.h" /** \addtogroup ecma ECMA * @{ @@ -92,7 +93,29 @@ ecma_op_get_value_lex_env_base (ecma_object_t *lex_env_p, /**< lexical environme if (ecma_is_value_found (result)) { *ref_base_lex_env_p = lex_env_p; + +#if ENABLED (JERRY_ES2015) + ecma_value_t blocked = ecma_op_is_prop_unscopable (lex_env_p, name_p); + + if (ECMA_IS_VALUE_ERROR (blocked)) + { + ecma_free_value (result); + return blocked; + } + + if (ecma_is_value_true (blocked)) + { + *ref_base_lex_env_p = NULL; + ecma_free_value (result); + } + else + { + return result; + } +#else /* !ENABLED (JERRY_ES2015) */ return result; +#endif /* ENABLED (JERRY_ES2015) */ + } break; diff --git a/jerry-core/ecma/operations/ecma-reference.c b/jerry-core/ecma/operations/ecma-reference.c index 5da480603..5be8fac51 100644 --- a/jerry-core/ecma/operations/ecma-reference.c +++ b/jerry-core/ecma/operations/ecma-reference.c @@ -102,7 +102,7 @@ ecma_op_resolve_super_reference_value (ecma_object_t *lex_env_p) /**< starting l * ECMA_VALUE_FALSE - if a the property is not unscopable * ECMA_VALUE_ERROR - otherwise */ -static ecma_value_t +ecma_value_t ecma_op_is_prop_unscopable (ecma_object_t *lex_env_p, /**< lexical environment */ ecma_string_t *prop_name_p) /**< property's name */ { diff --git a/jerry-core/ecma/operations/ecma-reference.h b/jerry-core/ecma/operations/ecma-reference.h index f974c7b57..8a1162f3a 100644 --- a/jerry-core/ecma/operations/ecma-reference.h +++ b/jerry-core/ecma/operations/ecma-reference.h @@ -30,6 +30,7 @@ ecma_object_t *ecma_op_resolve_reference_base (ecma_object_t *lex_env_p, ecma_st ecma_value_t ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, ecma_string_t *name_p); #if ENABLED (JERRY_ES2015) ecma_object_t *ecma_op_resolve_super_reference_value (ecma_object_t *lex_env_p); +ecma_value_t ecma_op_is_prop_unscopable (ecma_object_t *lex_env_p, ecma_string_t *prop_name_p); #endif /* ENABLED (JERRY_ES2015) */ /** diff --git a/tests/jerry/es2015/symbol-unscopables.js b/tests/jerry/es2015/symbol-unscopables.js index 8fc7076af..e1f74eadd 100644 --- a/tests/jerry/es2015/symbol-unscopables.js +++ b/tests/jerry/es2015/symbol-unscopables.js @@ -70,6 +70,17 @@ with (obj2) { } } +var obj3 = { foo: 12 }; +Object.defineProperty(obj3, Symbol.unscopables, { get: function () { throw 42; } }); + +with (obj3) { + try { + typeof foo; + } catch (e) { + assert(e === 42); + } +} + var symbol_obj = Array.prototype[Symbol.unscopables]; assert(symbol_obj.copyWithin === true); assert(symbol_obj.entries === true); @@ -86,3 +97,10 @@ assert(obj3.value === true); assert(obj3.writable === true); assert(obj3.enumerable == true); assert(obj3.configurable == true); + +var a = { foo: 1, bar: 2 }; +a[Symbol.unscopables] = { bar: true }; +with (a) { + assert(foo === 1); + assert(typeof bar === "undefined"); +}