mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 03:57:43 +00:00
LibJS: Check validity of computed_property_name() result before using it
This fixes two cases obj[expr] and obj[expr]() (MemberExpression and CallExpression respectively) when expr throws an exception and results in an empty value, causing a crash by passing the invalid PropertyName created by computed_property_name() to Object::get() without checking it first. Fixes #3459.
This commit is contained in:
parent
75dac35d0e
commit
568d53c9b1
3 changed files with 17 additions and 3 deletions
|
@ -122,7 +122,10 @@ CallExpression::ThisAndCallee CallExpression::compute_this_and_callee(Interprete
|
||||||
auto* this_value = is_super_property_lookup ? &interpreter.this_value(global_object).as_object() : lookup_target.to_object(interpreter, global_object);
|
auto* this_value = is_super_property_lookup ? &interpreter.this_value(global_object).as_object() : lookup_target.to_object(interpreter, global_object);
|
||||||
if (interpreter.exception())
|
if (interpreter.exception())
|
||||||
return {};
|
return {};
|
||||||
auto callee = lookup_target.to_object(interpreter, global_object)->get(member_expression.computed_property_name(interpreter, global_object)).value_or(js_undefined());
|
auto property_name = member_expression.computed_property_name(interpreter, global_object);
|
||||||
|
if (!property_name.is_valid())
|
||||||
|
return {};
|
||||||
|
auto callee = lookup_target.to_object(interpreter, global_object)->get(property_name).value_or(js_undefined());
|
||||||
return { this_value, callee };
|
return { this_value, callee };
|
||||||
}
|
}
|
||||||
return { &global_object, m_callee->execute(interpreter, global_object) };
|
return { &global_object, m_callee->execute(interpreter, global_object) };
|
||||||
|
@ -1589,7 +1592,10 @@ Value MemberExpression::execute(Interpreter& interpreter, GlobalObject& global_o
|
||||||
auto* object_result = object_value.to_object(interpreter, global_object);
|
auto* object_result = object_value.to_object(interpreter, global_object);
|
||||||
if (interpreter.exception())
|
if (interpreter.exception())
|
||||||
return {};
|
return {};
|
||||||
return object_result->get(computed_property_name(interpreter, global_object)).value_or(js_undefined());
|
auto property_name = computed_property_name(interpreter, global_object);
|
||||||
|
if (!property_name.is_valid())
|
||||||
|
return {};
|
||||||
|
return object_result->get(property_name).value_or(js_undefined());
|
||||||
}
|
}
|
||||||
|
|
||||||
Value StringLiteral::execute(Interpreter& interpreter, GlobalObject&) const
|
Value StringLiteral::execute(Interpreter& interpreter, GlobalObject&) const
|
||||||
|
|
8
Libraries/LibJS/Tests/computed-property-throws.js
Normal file
8
Libraries/LibJS/Tests/computed-property-throws.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
test("Issue #3459, exception in computed property expression", () => {
|
||||||
|
expect(() => {
|
||||||
|
"foo"[bar];
|
||||||
|
}).toThrow(ReferenceError);
|
||||||
|
expect(() => {
|
||||||
|
"foo"[bar]();
|
||||||
|
}).toThrow(ReferenceError);
|
||||||
|
});
|
|
@ -1,4 +1,4 @@
|
||||||
test("Issue #1992, exception thrown in catch {} block", () => {
|
test("Issue #3437, exception thrown in catch {} block", () => {
|
||||||
var tryHasBeenExecuted = false;
|
var tryHasBeenExecuted = false;
|
||||||
var catchHasBeenExecuted = false;
|
var catchHasBeenExecuted = false;
|
||||||
var finallyHasBeenExecuted = false;
|
var finallyHasBeenExecuted = false;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue