Parcourir la source

LibWeb: Exclude [Global] interfaces from legacy platform object methods

Window and other global objects are not technically legacy platform
objects, and have other ways to override their setters and getters.

However, Window does need to share some code with the legacy platform
object paths, and simply adding another bool check to the mix seems
the shortest putt.
Andrew Kaster il y a 1 an
Parent
commit
2505cecc0f

+ 6 - 0
Tests/LibWeb/Text/expected/HTML/Window-set-properties.txt

@@ -0,0 +1,6 @@
+window.__NEXT_DATA__ = [object HTMLScriptElement]
+window.__NEXT_DATA__ = undefined
+window[0] = undefined
+e = TypeError: Cannot set property '0' of [object WindowProxy]
+window[0] = undefined
+window[0] = 42

+ 22 - 0
Tests/LibWeb/Text/input/HTML/Window-set-properties.html

@@ -0,0 +1,22 @@
+<script src="../include.js"></script>
+<script id="__NEXT_DATA__"></script>
+<script>
+    test(() => {
+        "use strict";
+        println(`window.__NEXT_DATA__ = ${window.__NEXT_DATA__}`);
+        window.__NEXT_DATA__ = undefined;
+        println(`window.__NEXT_DATA__ = ${window.__NEXT_DATA__}`);
+
+        println(`window[0] = ${window[0]}`);
+
+        // FIXME: Other browsers just swallow this error, but we throw an exception.
+        try {
+            window[0] = 42;
+        } catch (e) {
+            println(`e = ${e}`);
+        }
+        println(`window[0] = ${window[0]}`);
+        window.__proto__[0] = 42;
+        println(`window[0] = ${window[0]}`);
+    });
+</script>

+ 5 - 5
Userland/Libraries/LibWeb/Bindings/PlatformObject.cpp

@@ -217,7 +217,7 @@ WebIDL::ExceptionOr<void> PlatformObject::invoke_named_property_setter(String co
 // https://webidl.spec.whatwg.org/#legacy-platform-object-getownproperty
 JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> PlatformObject::internal_get_own_property(JS::PropertyKey const& property_name) const
 {
-    if (m_legacy_platform_object_flags.has_value()) {
+    if (m_legacy_platform_object_flags.has_value() && !m_legacy_platform_object_flags->has_global_interface_extended_attribute) {
         // 1. Return ? PlatformObjectGetOwnProperty(O, P, false).
         return TRY(legacy_platform_object_get_own_property(property_name, IgnoreNamedProps::No));
     } else {
@@ -228,7 +228,7 @@ JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> PlatformObject::internal
 // https://webidl.spec.whatwg.org/#legacy-platform-object-set
 JS::ThrowCompletionOr<bool> PlatformObject::internal_set(JS::PropertyKey const& property_name, JS::Value value, JS::Value receiver, JS::CacheablePropertyMetadata* metadata)
 {
-    if (!m_legacy_platform_object_flags.has_value())
+    if (!m_legacy_platform_object_flags.has_value() || m_legacy_platform_object_flags->has_global_interface_extended_attribute)
         return Base::internal_set(property_name, value, receiver, metadata);
 
     auto& vm = this->vm();
@@ -266,7 +266,7 @@ JS::ThrowCompletionOr<bool> PlatformObject::internal_set(JS::PropertyKey const&
 // https://webidl.spec.whatwg.org/#legacy-platform-object-defineownproperty
 JS::ThrowCompletionOr<bool> PlatformObject::internal_define_own_property(JS::PropertyKey const& property_name, JS::PropertyDescriptor const& property_descriptor)
 {
-    if (!m_legacy_platform_object_flags.has_value())
+    if (!m_legacy_platform_object_flags.has_value() || m_legacy_platform_object_flags->has_global_interface_extended_attribute)
         return Base::internal_define_own_property(property_name, property_descriptor);
 
     auto& vm = this->vm();
@@ -335,7 +335,7 @@ JS::ThrowCompletionOr<bool> PlatformObject::internal_define_own_property(JS::Pro
 // https://webidl.spec.whatwg.org/#legacy-platform-object-delete
 JS::ThrowCompletionOr<bool> PlatformObject::internal_delete(JS::PropertyKey const& property_name)
 {
-    if (!m_legacy_platform_object_flags.has_value())
+    if (!m_legacy_platform_object_flags.has_value() || m_legacy_platform_object_flags->has_global_interface_extended_attribute)
         return Base::internal_delete(property_name);
 
     auto& vm = this->vm();
@@ -403,7 +403,7 @@ JS::ThrowCompletionOr<bool> PlatformObject::internal_delete(JS::PropertyKey cons
 // https://webidl.spec.whatwg.org/#legacy-platform-object-preventextensions
 JS::ThrowCompletionOr<bool> PlatformObject::internal_prevent_extensions()
 {
-    if (!m_legacy_platform_object_flags.has_value())
+    if (!m_legacy_platform_object_flags.has_value() || m_legacy_platform_object_flags->has_global_interface_extended_attribute)
         return Base::internal_prevent_extensions();
 
     // 1. Return false.