From 1d728af5c46045245ada2141d39b6ccc9fcafc8a Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Tue, 11 Aug 2020 17:42:18 +0200 Subject: [PATCH] LibWeb: Clear exceptions in each Document::run_javascript() call We don't want to carry over exceptions across multiple Document::run_javascript() calls as Interpreter::run() and every of its exception checks will get confused - in this case there would be an exception, but not because a certain action failed. Real-life example: The above HTML will invoke Document::run_javascript() twice, the first call will result in a TypeError, which is still stored during the second call. The interpreter will eventually call the following functions (in order) for the alert() invocation: - Identifier::execute() - Interpreter::get_variable() - Object::get() (on the global object) That last Object::get() call has an exception check which is triggered as we still carry around the exception from earlier - and eventually returns an empty value. Long story short, the second script will wrongly fail with "ReferenceError, 'alert' is not defined". Fixes #3091. --- Libraries/LibWeb/DOM/Document.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Libraries/LibWeb/DOM/Document.cpp b/Libraries/LibWeb/DOM/Document.cpp index 7191b42a68..0a762d6200 100644 --- a/Libraries/LibWeb/DOM/Document.cpp +++ b/Libraries/LibWeb/DOM/Document.cpp @@ -436,7 +436,11 @@ JS::Value Document::run_javascript(const StringView& source) parser.print_errors(); return JS::js_undefined(); } - return document().interpreter().run(document().interpreter().global_object(), *program); + auto& interpreter = document().interpreter(); + auto result = interpreter.run(interpreter.global_object(), *program); + if (interpreter.exception()) + interpreter.clear_exception(); + return result; } NonnullRefPtr Document::create_element(const String& tag_name)