From e22539bdd95e0bc8a78f64aa0a778bc96a4b9091 Mon Sep 17 00:00:00 2001 From: davidot Date: Mon, 26 Jul 2021 00:01:54 +0200 Subject: [PATCH] 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. --- .../Libraries/LibWeb/Bindings/WindowObject.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp b/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp index ef18f4a8612..55249e4803a 100644 --- a/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp +++ b/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) { - 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()) { vm.throw_exception(global_object, JS::ErrorType::NotA, "WindowObject"); return nullptr;