Primitive this values of accessors should not be coerced in strict mode (#3854)

JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai dbatyai@inf.u-szeged.hu
This commit is contained in:
Dániel Bátyai
2020-06-05 15:58:10 +02:00
committed by GitHub
parent 10e78a4eef
commit cae6cd08fb
2 changed files with 96 additions and 63 deletions
+49 -32
View File
@@ -154,50 +154,68 @@ vm_op_get_value (ecma_value_t object, /**< base object */
* if the property setting is unsuccessful * if the property setting is unsuccessful
*/ */
static ecma_value_t static ecma_value_t
vm_op_set_value (ecma_value_t object, /**< base object */ vm_op_set_value (ecma_value_t base, /**< base object */
ecma_value_t property, /**< property name */ ecma_value_t property, /**< property name */
ecma_value_t value, /**< ecma value */ ecma_value_t value, /**< ecma value */
bool is_strict) /**< strict mode */ bool is_strict) /**< strict mode */
{ {
ecma_object_t * object_p; ecma_value_t result = ECMA_VALUE_EMPTY;
ecma_object_t *object_p;
ecma_string_t *property_p;
if (JERRY_UNLIKELY (!ecma_is_value_object (object))) if (JERRY_UNLIKELY (!ecma_is_value_object (base)))
{ {
ecma_value_t to_object = ecma_op_to_object (object); if (JERRY_UNLIKELY (ecma_is_value_null (base) || ecma_is_value_undefined (base)))
ecma_free_value (object);
if (ECMA_IS_VALUE_ERROR (to_object))
{ {
#if ENABLED (JERRY_ERROR_MESSAGES) #if ENABLED (JERRY_ERROR_MESSAGES)
ecma_free_value (to_object); result = ecma_raise_standard_error_with_format (ECMA_ERROR_TYPE,
jcontext_release_exception ();
ecma_value_t error_value = ecma_raise_standard_error_with_format (ECMA_ERROR_TYPE,
"Cannot set property '%' of %", "Cannot set property '%' of %",
property, property,
object); base);
ecma_free_value (property);
return error_value;
#else /* !ENABLED (JERRY_ERROR_MESSAGES) */ #else /* !ENABLED (JERRY_ERROR_MESSAGES) */
ecma_free_value (property); result = ecma_raise_type_error (NULL);
return to_object;
#endif /* ENABLED (JERRY_ERROR_MESSAGES) */ #endif /* ENABLED (JERRY_ERROR_MESSAGES) */
ecma_free_value (property);
return result;
} }
object_p = ecma_get_object_from_value (to_object); if (JERRY_UNLIKELY (!ecma_is_value_prop_name (property)))
ecma_op_ordinary_object_prevent_extensions (object_p); {
property_p = ecma_op_to_string (property);
ecma_fast_free_value (property);
if (JERRY_UNLIKELY (property_p == NULL))
{
ecma_free_value (base);
return ECMA_VALUE_ERROR;
}
} }
else else
{ {
object_p = ecma_get_object_from_value (object); property_p = ecma_get_prop_name_from_value (property);
} }
ecma_string_t *property_p; ecma_value_t object = ecma_op_to_object (base);
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (object));
if (!ecma_is_value_prop_name (property)) object_p = ecma_get_object_from_value (object);
ecma_op_ordinary_object_prevent_extensions (object_p);
result = ecma_op_object_put_with_receiver (object_p,
property_p,
value,
base,
is_strict);
ecma_free_value (base);
}
else
{ {
property_p = ecma_op_to_prop_name (property); object_p = ecma_get_object_from_value (base);
if (JERRY_UNLIKELY (!ecma_is_value_prop_name (property)))
{
property_p = ecma_op_to_string (property);
ecma_fast_free_value (property); ecma_fast_free_value (property);
if (JERRY_UNLIKELY (property_p == NULL)) if (JERRY_UNLIKELY (property_p == NULL))
@@ -211,27 +229,26 @@ vm_op_set_value (ecma_value_t object, /**< base object */
property_p = ecma_get_prop_name_from_value (property); property_p = ecma_get_prop_name_from_value (property);
} }
ecma_value_t completion_value = ECMA_VALUE_EMPTY;
if (!ecma_is_lexical_environment (object_p)) if (!ecma_is_lexical_environment (object_p))
{ {
completion_value = ecma_op_object_put (object_p, result = ecma_op_object_put_with_receiver (object_p,
property_p, property_p,
value, value,
base,
is_strict); is_strict);
} }
else else
{ {
completion_value = ecma_op_set_mutable_binding (object_p, result = ecma_op_set_mutable_binding (object_p,
property_p, property_p,
value, value,
is_strict); is_strict);
} }
}
ecma_deref_object (object_p); ecma_deref_object (object_p);
ecma_deref_ecma_string (property_p); ecma_deref_ecma_string (property_p);
return result;
return completion_value;
} /* vm_op_set_value */ } /* vm_op_set_value */
/** Compact bytecode define */ /** Compact bytecode define */
@@ -3882,9 +3899,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
else if (opcode_data & VM_OC_PUT_REFERENCE) else if (opcode_data & VM_OC_PUT_REFERENCE)
{ {
ecma_value_t property = *(--stack_top_p); ecma_value_t property = *(--stack_top_p);
ecma_value_t object = *(--stack_top_p); ecma_value_t base = *(--stack_top_p);
if (object == ECMA_VALUE_REGISTER_REF) if (base == ECMA_VALUE_REGISTER_REF)
{ {
property = (ecma_value_t) ecma_get_integer_from_value (property); property = (ecma_value_t) ecma_get_integer_from_value (property);
ecma_fast_free_value (VM_GET_REGISTER (frame_ctx_p, property)); ecma_fast_free_value (VM_GET_REGISTER (frame_ctx_p, property));
@@ -3898,7 +3915,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
} }
else else
{ {
ecma_value_t set_value_result = vm_op_set_value (object, ecma_value_t set_value_result = vm_op_set_value (base,
property, property,
result, result,
is_strict); is_strict);
+16
View File
@@ -32,3 +32,19 @@ Object.defineProperty(Box.prototype, 'data', {
assert(box.data === '='); assert(box.data === '=');
box.data = '+'; box.data = '+';
assert(box.data === '+'); assert(box.data === '+');
function test_access(value, proto) {
"use strict"
Object.defineProperty(proto, 'test', {
get: function () { assert (this === value) },
set: function () { assert (this === value) }
});
value.test;
value.test = undefined;
}
test_access ("str", String.prototype);
test_access (1, Number.prototype);
test_access (true, Boolean.prototype);