1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 01:27:34 +00:00

LibJS: Don't allow delete super.property

This should throw a ReferenceError, since `delete` is not allowed
on super references.
This commit is contained in:
Andreas Kling 2021-07-03 01:25:07 +02:00
parent 1270df257b
commit e8430cf0d3
3 changed files with 40 additions and 4 deletions

View file

@ -110,26 +110,61 @@ Value Reference::get_value(GlobalObject& global_object, bool throw_if_undefined)
bool Reference::delete_(GlobalObject& global_object)
{
// 13.5.1.2 Runtime Semantics: Evaluation, https://tc39.es/ecma262/#sec-delete-operator-runtime-semantics-evaluation
// UnaryExpression : delete UnaryExpression
// NOTE: The following steps have already been evaluated by the time we get here:
// 1. Let ref be the result of evaluating UnaryExpression.
// 2. ReturnIfAbrupt(ref).
// 3. If ref is not a Reference Record, return true.
// 4. If IsUnresolvableReference(ref) is true, then
if (is_unresolvable()) {
// a. Assert: ref.[[Strict]] is false.
VERIFY(!m_strict);
// b. Return true.
return true;
}
auto& vm = global_object.vm();
// 5. If IsPropertyReference(ref) is true, then
if (is_property_reference()) {
// a. Assert: ! IsPrivateReference(ref) is false.
// FIXME: We don't have private references yet.
// b. If IsSuperReference(ref) is true, throw a ReferenceError exception.
if (is_super_reference()) {
vm.throw_exception<ReferenceError>(global_object, ErrorType::UnsupportedDeleteSuperProperty);
return false;
}
// c. Let baseObj be ! ToObject(ref.[[Base]]).
auto* base_obj = m_base_value.to_object(global_object);
if (!base_obj)
return false;
bool succeeded = base_obj->delete_property(m_name);
if (!succeeded && m_strict) {
// d. Let deleteStatus be ? baseObj.[[Delete]](ref.[[ReferencedName]]).
bool delete_status = base_obj->delete_property(m_name);
// e. If deleteStatus is false and ref.[[Strict]] is true, throw a TypeError exception.
if (!delete_status && m_strict) {
vm.throw_exception<TypeError>(global_object, ErrorType::ReferenceNullishDeleteProperty, m_name.to_value(vm).to_string_without_side_effects(), m_base_value.to_string_without_side_effects());
return false;
}
return succeeded;
// f. Return deleteStatus.
return delete_status;
}
// 6. Else,
// a. Let base be ref.[[Base]].
// b. Assert: base is an Environment Record.
VERIFY(m_base_type == BaseType::Environment);
// c. Return ? base.DeleteBinding(ref.[[ReferencedName]]).
// FIXME: This is ad-hoc, we should be calling DeleteBinding.
return m_base_environment->delete_from_environment(m_name.as_string());
}