Forráskód Böngészése

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 1 éve
szülő
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
 // 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
 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).
         // 1. Return ? PlatformObjectGetOwnProperty(O, P, false).
         return TRY(legacy_platform_object_get_own_property(property_name, IgnoreNamedProps::No));
         return TRY(legacy_platform_object_get_own_property(property_name, IgnoreNamedProps::No));
     } else {
     } else {
@@ -228,7 +228,7 @@ JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> PlatformObject::internal
 // https://webidl.spec.whatwg.org/#legacy-platform-object-set
 // 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)
 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);
         return Base::internal_set(property_name, value, receiver, metadata);
 
 
     auto& vm = this->vm();
     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
 // 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)
 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);
         return Base::internal_define_own_property(property_name, property_descriptor);
 
 
     auto& vm = this->vm();
     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
 // https://webidl.spec.whatwg.org/#legacy-platform-object-delete
 JS::ThrowCompletionOr<bool> PlatformObject::internal_delete(JS::PropertyKey const& property_name)
 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);
         return Base::internal_delete(property_name);
 
 
     auto& vm = this->vm();
     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
 // https://webidl.spec.whatwg.org/#legacy-platform-object-preventextensions
 JS::ThrowCompletionOr<bool> PlatformObject::internal_prevent_extensions()
 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();
         return Base::internal_prevent_extensions();
 
 
     // 1. Return false.
     // 1. Return false.