1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-16 10:24:59 +00:00
serenity/Userland/Libraries/LibWeb/Bindings/CrossOriginAbstractOperations.cpp

74 lines
4.4 KiB
C++

/*
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Variant.h>
#include <AK/Vector.h>
#include <LibJS/Runtime/Completion.h>
#include <LibJS/Runtime/GlobalObject.h>
#include <LibJS/Runtime/Object.h>
#include <LibJS/Runtime/PropertyDescriptor.h>
#include <LibJS/Runtime/PropertyKey.h>
#include <LibWeb/Bindings/CrossOriginAbstractOperations.h>
#include <LibWeb/Bindings/DOMExceptionWrapper.h>
#include <LibWeb/Bindings/LocationObject.h>
#include <LibWeb/Bindings/WindowObject.h>
#include <LibWeb/DOM/DOMException.h>
#include <LibWeb/HTML/Scripting/Environments.h>
namespace Web::Bindings {
// 7.2.3.1 CrossOriginProperties ( O ), https://html.spec.whatwg.org/multipage/browsers.html#crossoriginproperties-(-o-)
Vector<CrossOriginProperty> cross_origin_properties(Variant<LocationObject const*, WindowObject const*> const& object)
{
// 1. Assert: O is a Location or Window object.
return object.visit(
// 2. If O is a Location object, then return « { [[Property]]: "href", [[NeedsGet]]: false, [[NeedsSet]]: true }, { [[Property]]: "replace" } ».
[](LocationObject const*) -> Vector<CrossOriginProperty> {
return {
{ .property = "href"sv, .needs_get = false, .needs_set = true },
{ .property = "replace"sv },
};
},
// 3. Return « { [[Property]]: "window", [[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]: "self", [[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]: "location", [[NeedsGet]]: true, [[NeedsSet]]: true }, { [[Property]]: "close" }, { [[Property]]: "closed", [[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]: "focus" }, { [[Property]]: "blur" }, { [[Property]]: "frames", [[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]: "length", [[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]: "top", [[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]: "opener", [[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]: "parent", [[NeedsGet]]: true, [[NeedsSet]]: false }, { [[Property]]: "postMessage" } ».
[](WindowObject const*) -> Vector<CrossOriginProperty> {
return {
{ .property = "window"sv, .needs_get = true, .needs_set = false },
{ .property = "self"sv, .needs_get = true, .needs_set = false },
{ .property = "location"sv, .needs_get = true, .needs_set = true },
{ .property = "close"sv },
{ .property = "closed"sv, .needs_get = true, .needs_set = false },
{ .property = "focus"sv },
{ .property = "blur"sv },
{ .property = "frames"sv, .needs_get = true, .needs_set = false },
{ .property = "length"sv, .needs_get = true, .needs_set = false },
{ .property = "top"sv, .needs_get = true, .needs_set = false },
{ .property = "opener"sv, .needs_get = true, .needs_set = false },
{ .property = "parent"sv, .needs_get = true, .needs_set = false },
{ .property = "postMessage"sv },
};
});
}
// 7.2.3.2 CrossOriginPropertyFallback ( P ), https://html.spec.whatwg.org/multipage/browsers.html#crossoriginpropertyfallback-(-p-)
JS::ThrowCompletionOr<JS::PropertyDescriptor> cross_origin_property_fallback(JS::GlobalObject& global_object, JS::PropertyKey const& property_key)
{
auto& vm = global_object.vm();
// 1. If P is "then", @@toStringTag, @@hasInstance, or @@isConcatSpreadable, then return PropertyDescriptor{ [[Value]]: undefined, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.
auto property_key_is_then = property_key.is_string() && property_key.as_string() == vm.names.then.as_string();
auto property_key_is_allowed_symbol = property_key.is_symbol()
&& (property_key.as_symbol() == vm.well_known_symbol_to_string_tag()
|| property_key.as_symbol() == vm.well_known_symbol_has_instance()
|| property_key.as_symbol() == vm.well_known_symbol_is_concat_spreadable());
if (property_key_is_then || property_key_is_allowed_symbol)
return JS::PropertyDescriptor { .value = JS::js_undefined(), .writable = false, .enumerable = false, .configurable = true };
// 2. Throw a "SecurityError" DOMException.
return vm.throw_completion<DOMExceptionWrapper>(global_object, DOM::SecurityError::create(String::formatted("Can't access property '{}' on cross-origin object", property_key)));
}
}