diff options
author | Linus Groh <mail@linusgroh.de> | 2020-08-11 17:42:18 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-08-11 21:08:30 +0200 |
commit | 1d728af5c46045245ada2141d39b6ccc9fcafc8a (patch) | |
tree | 4d138fdc7f2b78e3d0ad5e9024af3d29f1ba48d9 | |
parent | f8084cc0833df638697fd4264b3344df7caece40 (diff) | |
download | serenity-1d728af5c46045245ada2141d39b6ccc9fcafc8a.zip |
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:
<script>var a = {}; a.test()</script>
<script>alert("It worked!")</script>
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.
-rw-r--r-- | Libraries/LibWeb/DOM/Document.cpp | 6 |
1 files changed, 5 insertions, 1 deletions
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<Element> Document::create_element(const String& tag_name) |