mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-28 19:59:17 +00:00
LibWeb: Fix stack-use-after-scope
The refactor in the previous commit was storing a reference to a stack allocated `Infrastructure::Request::BodyType` which was then immediately freed. To fix this, we can store the `Infrastructure::Request::BodyType` in a variable beforehand, so it becomes safe to reference.
This commit is contained in:
parent
d7596a0a61
commit
211dc5659c
Notes:
github-actions[bot]
2024-12-04 00:59:15 +00:00
Author: https://github.com/yyny
Commit: 211dc5659c
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2567
Reviewed-by: https://github.com/alimpfard
Reviewed-by: https://github.com/gmta ✅
2 changed files with 9 additions and 8 deletions
|
@ -71,14 +71,17 @@ public:
|
||||||
return static_cast<Self const&>(*this).has_value() ? __builtin_launder(reinterpret_cast<T const*>(&static_cast<Self const&>(*this).value())) : nullptr;
|
return static_cast<Self const&>(*this).has_value() ? __builtin_launder(reinterpret_cast<T const*>(&static_cast<Self const&>(*this).value())) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] ALWAYS_INLINE T value_or(T const& fallback) const&
|
template<typename O = T, typename Fallback = O>
|
||||||
|
[[nodiscard]] ALWAYS_INLINE O value_or(Fallback const& fallback) const&
|
||||||
{
|
{
|
||||||
if (static_cast<Self const&>(*this).has_value())
|
if (static_cast<Self const&>(*this).has_value())
|
||||||
return static_cast<Self const&>(*this).value();
|
return static_cast<Self const&>(*this).value();
|
||||||
return fallback;
|
return fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] ALWAYS_INLINE T value_or(T&& fallback) &&
|
template<typename O = T, typename Fallback = O>
|
||||||
|
requires(!IsLvalueReference<O> && !IsRvalueReference<O>)
|
||||||
|
[[nodiscard]] ALWAYS_INLINE O value_or(Fallback&& fallback) &&
|
||||||
{
|
{
|
||||||
if (static_cast<Self&>(*this).has_value())
|
if (static_cast<Self&>(*this).has_value())
|
||||||
return move(static_cast<Self&>(*this).value());
|
return move(static_cast<Self&>(*this).value());
|
||||||
|
|
|
@ -448,7 +448,7 @@ WebIDL::ExceptionOr<GC::Ref<Request>> Request::construct_impl(JS::Realm& realm,
|
||||||
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Method must not be GET or HEAD when body is provided"sv };
|
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Method must not be GET or HEAD when body is provided"sv };
|
||||||
|
|
||||||
// 36. Let initBody be null.
|
// 36. Let initBody be null.
|
||||||
GC::Ptr<Infrastructure::Body> init_body;
|
Optional<Infrastructure::Request::BodyType> init_body;
|
||||||
|
|
||||||
// 37. If init["body"] exists and is non-null, then:
|
// 37. If init["body"] exists and is non-null, then:
|
||||||
if (init.body.has_value() && (*init.body).has_value()) {
|
if (init.body.has_value() && (*init.body).has_value()) {
|
||||||
|
@ -467,15 +467,13 @@ WebIDL::ExceptionOr<GC::Ref<Request>> Request::construct_impl(JS::Realm& realm,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 38. Let inputOrInitBody be initBody if it is non-null; otherwise inputBody.
|
// 38. Let inputOrInitBody be initBody if it is non-null; otherwise inputBody.
|
||||||
Optional<Infrastructure::Request::BodyType const&> input_or_init_body = init_body
|
auto input_or_init_body = init_body.value_or<Optional<Infrastructure::Request::BodyType const&>>(input_body);
|
||||||
? Infrastructure::Request::BodyType { *init_body }
|
|
||||||
: input_body;
|
|
||||||
|
|
||||||
// 39. If inputOrInitBody is non-null and inputOrInitBody’s source is null, then:
|
// 39. If inputOrInitBody is non-null and inputOrInitBody’s source is null, then:
|
||||||
// FIXME: The spec doesn't check if inputOrInitBody is a body before accessing source.
|
// FIXME: The spec doesn't check if inputOrInitBody is a body before accessing source.
|
||||||
if (input_or_init_body.has_value() && input_or_init_body->has<GC::Ref<Infrastructure::Body>>() && input_or_init_body->get<GC::Ref<Infrastructure::Body>>()->source().has<Empty>()) {
|
if (input_or_init_body.has_value() && input_or_init_body->has<GC::Ref<Infrastructure::Body>>() && input_or_init_body->get<GC::Ref<Infrastructure::Body>>()->source().has<Empty>()) {
|
||||||
// 1. If initBody is non-null and init["duplex"] does not exist, then throw a TypeError.
|
// 1. If initBody is non-null and init["duplex"] does not exist, then throw a TypeError.
|
||||||
if (init_body && !init.duplex.has_value())
|
if (init_body.has_value() && !init.duplex.has_value())
|
||||||
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Body without source requires 'duplex' value to be set"sv };
|
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Body without source requires 'duplex' value to be set"sv };
|
||||||
|
|
||||||
// 2. If this’s request’s mode is neither "same-origin" nor "cors", then throw a TypeError.
|
// 2. If this’s request’s mode is neither "same-origin" nor "cors", then throw a TypeError.
|
||||||
|
@ -490,7 +488,7 @@ WebIDL::ExceptionOr<GC::Ref<Request>> Request::construct_impl(JS::Realm& realm,
|
||||||
auto const& final_body = input_or_init_body;
|
auto const& final_body = input_or_init_body;
|
||||||
|
|
||||||
// 41. If initBody is null and inputBody is non-null, then:
|
// 41. If initBody is null and inputBody is non-null, then:
|
||||||
if (!init_body && input_body.has_value()) {
|
if (!init_body.has_value() && input_body.has_value()) {
|
||||||
// 2. If input is unusable, then throw a TypeError.
|
// 2. If input is unusable, then throw a TypeError.
|
||||||
if (input.has<GC::Root<Request>>() && input.get<GC::Root<Request>>()->is_unusable())
|
if (input.has<GC::Root<Request>>() && input.get<GC::Root<Request>>()->is_unusable())
|
||||||
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Request is unusable"sv };
|
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Request is unusable"sv };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue