1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 13:48:12 +00:00

LibJS: Check if class extends value has a valid prototype

If we have a function as class extends value, we still cannot assume
that it has a prototype property and that property has a function or
null as its value - blindly calling to_object() on it may fail.

Fixes #5075.
This commit is contained in:
Linus Groh 2021-01-23 23:49:04 +01:00 committed by Andreas Kling
parent 397f432aed
commit 766f30f593
3 changed files with 27 additions and 3 deletions

View file

@ -810,7 +810,7 @@ Value ClassExpression::execute(Interpreter& interpreter, GlobalObject& global_ob
if (interpreter.exception())
return {};
if (!super_constructor.is_function() && !super_constructor.is_null()) {
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::ClassDoesNotExtendAConstructorOrNull, super_constructor.to_string_without_side_effects());
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::ClassExtendsValueNotAConstructorOrNull, super_constructor.to_string_without_side_effects());
return {};
}
class_constructor->set_constructor_kind(Function::ConstructorKind::Derived);
@ -818,9 +818,18 @@ Value ClassExpression::execute(Interpreter& interpreter, GlobalObject& global_ob
Object* super_constructor_prototype = nullptr;
if (!super_constructor.is_null()) {
super_constructor_prototype = &super_constructor.as_object().get(vm.names.prototype).as_object();
auto super_constructor_prototype_value = super_constructor.as_object().get(vm.names.prototype);
if (interpreter.exception())
return {};
if (!super_constructor_prototype_value.is_object() && !super_constructor_prototype_value.is_null()) {
interpreter.vm().throw_exception<TypeError>(global_object, ErrorType::ClassExtendsValueInvalidPrototype, super_constructor_prototype_value.to_string_without_side_effects());
return {};
}
if (super_constructor_prototype_value.is_object()) {
super_constructor_prototype = &super_constructor_prototype_value.as_object();
if (interpreter.exception())
return {};
}
}
prototype->set_prototype(super_constructor_prototype);