Pārlūkot izejas kodu

LibWeb: Fix that non-member calls to window gave the wrong this_value

We treat all NativeFunctions as strict mode and thus window function
which were called in a global context (i.e. `setTimeout(f, 0)`) got a
null this_value. But we really need to treat all functions not defined
by the ECMAScript specification as non-strict. In most cases this won't
matter however since Window is also the global_object we have an extra
bit of logic.
To fix this more correctly we would need to track the strictness of
NativeFunctions.
davidot 4 gadi atpakaļ
vecāks
revīzija
e22539bdd9
1 mainītis faili ar 13 papildinājumiem un 4 dzēšanām
  1. 13 4
      Userland/Libraries/LibWeb/Bindings/WindowObject.cpp

+ 13 - 4
Userland/Libraries/LibWeb/Bindings/WindowObject.cpp

@@ -102,11 +102,20 @@ Origin WindowObject::origin() const
 
 
 static DOM::Window* impl_from(JS::VM& vm, JS::GlobalObject& global_object)
 static DOM::Window* impl_from(JS::VM& vm, JS::GlobalObject& global_object)
 {
 {
-    auto* this_object = vm.this_value(global_object).to_object(global_object);
-    if (!this_object) {
-        VERIFY_NOT_REACHED();
-        return nullptr;
+    // Since this is a non built-in function we must treat it as non-strict mode
+    // this means that a nullish this_value should be converted to the
+    // global_object. Generally this does not matter as we try to convert the
+    // this_value to a specific object type in the bindings. But since window is
+    // the global object we make an exception here.
+    // This allows calls like `setTimeout(f, 10)` to work.
+    auto this_value = vm.this_value(global_object);
+    if (this_value.is_nullish()) {
+        this_value = global_object.value_of();
     }
     }
+
+    auto* this_object = this_value.to_object(global_object);
+    VERIFY(this_object);
+
     if (StringView("WindowObject") != this_object->class_name()) {
     if (StringView("WindowObject") != this_object->class_name()) {
         vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, "WindowObject");
         vm.throw_exception<JS::TypeError>(global_object, JS::ErrorType::NotA, "WindowObject");
         return nullptr;
         return nullptr;