mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 08:17:35 +00:00
LibJS: Fix UB downcast during GlobalObject construction
When constructing a GlobalObject, it has to pass itself as the global object to its own Shape. Since this is done in the Object constructor, and Object is a base class of GlobalObject, it's not yet valid to cast "this" to a GlobalObject*. Fix this by having Shape store the global object as an Object& and move Shape::global_object() to GlobalObject.h where we can at least perform a valid static_cast in the getter. Found by oss-fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=29267
This commit is contained in:
parent
279d2eee04
commit
fdd974b7ef
4 changed files with 10 additions and 5 deletions
|
@ -125,4 +125,9 @@ inline void GlobalObject::add_constructor(const FlyString& property_name, Constr
|
||||||
define_property(property_name, constructor, Attribute::Writable | Attribute::Configurable);
|
define_property(property_name, constructor, Attribute::Writable | Attribute::Configurable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline GlobalObject* Shape::global_object() const
|
||||||
|
{
|
||||||
|
return static_cast<GlobalObject*>(m_global_object);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ Object* Object::create_empty(GlobalObject& global_object)
|
||||||
Object::Object(GlobalObjectTag)
|
Object::Object(GlobalObjectTag)
|
||||||
{
|
{
|
||||||
// This is the global object
|
// This is the global object
|
||||||
m_shape = heap().allocate_without_global_object<Shape>(static_cast<GlobalObject&>(*this));
|
m_shape = heap().allocate_without_global_object<Shape>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Object::Object(ConstructWithoutPrototypeTag, GlobalObject& global_object)
|
Object::Object(ConstructWithoutPrototypeTag, GlobalObject& global_object)
|
||||||
|
|
|
@ -72,7 +72,7 @@ Shape::Shape(ShapeWithoutGlobalObjectTag)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Shape::Shape(GlobalObject& global_object)
|
Shape::Shape(Object& global_object)
|
||||||
: m_global_object(&global_object)
|
: m_global_object(&global_object)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,7 +65,7 @@ public:
|
||||||
enum class ShapeWithoutGlobalObjectTag { Tag };
|
enum class ShapeWithoutGlobalObjectTag { Tag };
|
||||||
|
|
||||||
explicit Shape(ShapeWithoutGlobalObjectTag);
|
explicit Shape(ShapeWithoutGlobalObjectTag);
|
||||||
explicit Shape(GlobalObject&);
|
explicit Shape(Object& global_object);
|
||||||
Shape(Shape& previous_shape, const StringOrSymbol& property_name, PropertyAttributes attributes, TransitionType);
|
Shape(Shape& previous_shape, const StringOrSymbol& property_name, PropertyAttributes attributes, TransitionType);
|
||||||
Shape(Shape& previous_shape, Object* new_prototype);
|
Shape(Shape& previous_shape, Object* new_prototype);
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ public:
|
||||||
bool is_unique() const { return m_unique; }
|
bool is_unique() const { return m_unique; }
|
||||||
Shape* create_unique_clone() const;
|
Shape* create_unique_clone() const;
|
||||||
|
|
||||||
GlobalObject* global_object() const { return m_global_object; }
|
GlobalObject* global_object() const;
|
||||||
|
|
||||||
Object* prototype() { return m_prototype; }
|
Object* prototype() { return m_prototype; }
|
||||||
const Object* prototype() const { return m_prototype; }
|
const Object* prototype() const { return m_prototype; }
|
||||||
|
@ -110,7 +110,7 @@ private:
|
||||||
TransitionType m_transition_type : 6 { TransitionType::Invalid };
|
TransitionType m_transition_type : 6 { TransitionType::Invalid };
|
||||||
bool m_unique : 1 { false };
|
bool m_unique : 1 { false };
|
||||||
|
|
||||||
GlobalObject* m_global_object { nullptr };
|
Object* m_global_object { nullptr };
|
||||||
|
|
||||||
mutable OwnPtr<HashMap<StringOrSymbol, PropertyMetadata>> m_property_table;
|
mutable OwnPtr<HashMap<StringOrSymbol, PropertyMetadata>> m_property_table;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue