mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 12:28:12 +00:00
LibJS: Prevent stack overflow if Proxy handler's __proto__ is the Proxy
Fixes #9322.
This commit is contained in:
parent
9998a2c91e
commit
941ff0cf60
2 changed files with 27 additions and 0 deletions
|
@ -577,6 +577,24 @@ Value ProxyObject::internal_get(PropertyName const& property_name, Value receive
|
|||
// 4. Assert: Type(handler) is Object.
|
||||
// 5. Let target be O.[[ProxyTarget]].
|
||||
|
||||
// NOTE: We need to protect ourselves from a Proxy with the handler's prototype set to the
|
||||
// Proxy itself, which would by default bounce between these functions indefinitely and lead to
|
||||
// a stack overflow when the Proxy's (p) or Proxy handler's (h) Object::get() is called and the
|
||||
// handler doesn't have a `get` trap:
|
||||
//
|
||||
// 1. p -> ProxyObject::internal_get() <- you are here
|
||||
// 2. h -> Value::get_method()
|
||||
// 3. h -> Value::get()
|
||||
// 4. h -> Object::internal_get()
|
||||
// 5. h -> Object::internal_get_prototype_of() (result is p)
|
||||
// 6. goto 1
|
||||
//
|
||||
// In JS code: `h = {}; p = new Proxy({}, h); h.__proto__ = p; p.foo // or h.foo`
|
||||
if (vm.did_reach_stack_space_limit()) {
|
||||
vm.throw_exception<Error>(global_object, ErrorType::CallStackSizeExceeded);
|
||||
return {};
|
||||
}
|
||||
|
||||
// 6. Let trap be ? GetMethod(handler, "get").
|
||||
auto trap = Value(&m_handler).get_method(global_object, vm.names.get);
|
||||
if (vm.exception())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue