mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-21 03:55:24 +00:00
LibWeb: Don't crash when upgrading custom element with a bad constructor
Previously, a crash would occur when attempting to throw an error in this case because the method used to create the exception tried to get the current realm from the execution context stack, which is empty. The realm is now passed explicitly when constructing the error, avoiding the crash.
This commit is contained in:
parent
403cda5cd6
commit
619df0bc2c
Notes:
github-actions[bot]
2025-01-13 10:56:42 +00:00
Author: https://github.com/tcl3 Commit: https://github.com/LadybirdBrowser/ladybird/commit/619df0bc2c6 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3235
3 changed files with 101 additions and 3 deletions
|
@ -568,8 +568,6 @@ WebIDL::ExceptionOr<GC::Ref<Element>> create_element(Document& document, FlyStri
|
|||
// 1. If the synchronous custom elements flag is set, then run these steps while catching any exceptions:
|
||||
if (synchronous_custom_elements_flag) {
|
||||
auto synchronously_upgrade_custom_element = [&]() -> JS::ThrowCompletionOr<GC::Ref<HTML::HTMLElement>> {
|
||||
auto& vm = document.vm();
|
||||
|
||||
// 1. Let C be definition’s constructor.
|
||||
auto& constructor = definition->constructor();
|
||||
|
||||
|
@ -578,7 +576,7 @@ WebIDL::ExceptionOr<GC::Ref<Element>> create_element(Document& document, FlyStri
|
|||
|
||||
// NOTE: IDL does not currently convert the object for us, so we will have to do it here.
|
||||
if (!result.has_value() || !result->is_object() || !is<HTML::HTMLElement>(result->as_object()))
|
||||
return vm.throw_completion<JS::TypeError>(JS::ErrorType::NotAnObjectOfType, "HTMLElement"sv);
|
||||
return JS::throw_completion(JS::TypeError::create(realm, "Custom element constructor must return an object that implements HTMLElement"_string));
|
||||
|
||||
GC::Ref<HTML::HTMLElement> element = verify_cast<HTML::HTMLElement>(result->as_object());
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 4 tests
|
||||
|
||||
4 Pass
|
||||
Pass HTML parser must create a fallback HTMLUnknownElement when a custom element constructor returns a Text node
|
||||
Pass HTML parser must create a fallback HTMLUnknownElement when a custom element constructor returns non-Element object
|
||||
Pass HTML parser must create a fallback HTMLUnknownElement when a custom element constructor does not call super()
|
||||
Pass HTML parser must create a fallback HTMLUnknownElement when a custom element constructor throws an exception
|
|
@ -0,0 +1,91 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Custom Elements: Changes to the HTML parser</title>
|
||||
<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
|
||||
<meta name="assert" content="HTML parser must fallback to creating a HTMLUnknownElement when a custom element construction fails">
|
||||
<link rel="help" href="https://html.spec.whatwg.org/#create-an-element-for-the-token">
|
||||
<link rel="help" href="https://dom.spec.whatwg.org/#concept-create-element">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
|
||||
setup({allow_uncaught_exception:true});
|
||||
|
||||
class ReturnsTextNode extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
return document.createTextNode('some text');
|
||||
}
|
||||
};
|
||||
customElements.define('returns-text', ReturnsTextNode);
|
||||
|
||||
class ReturnsNonElementObject extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
return {};
|
||||
}
|
||||
};
|
||||
customElements.define('returns-non-element-object', ReturnsNonElementObject);
|
||||
|
||||
class LacksSuperCall extends HTMLElement {
|
||||
constructor() { }
|
||||
};
|
||||
customElements.define('lacks-super-call', LacksSuperCall);
|
||||
|
||||
class ThrowsException extends HTMLElement {
|
||||
constructor() {
|
||||
throw 'Bad';
|
||||
}
|
||||
};
|
||||
customElements.define('throws-exception', ThrowsException);
|
||||
|
||||
</script>
|
||||
<returns-text></returns-text>
|
||||
<returns-non-element-object></returns-non-element-object>
|
||||
<lacks-super-call></lacks-super-call>
|
||||
<throws-exception></throws-exception>
|
||||
<script>
|
||||
|
||||
test(function () {
|
||||
var instance = document.querySelector('returns-text');
|
||||
|
||||
assert_false(instance instanceof ReturnsTextNode, 'HTML parser must NOT instantiate a custom element when the constructor returns a Text node');
|
||||
assert_true(instance instanceof HTMLElement, 'The fallback element created by HTML parser must be an instance of HTMLElement');
|
||||
assert_true(instance instanceof HTMLUnknownElement, 'The fallback element created by HTML parser must be an instance of HTMLUnknownElement');
|
||||
|
||||
}, 'HTML parser must create a fallback HTMLUnknownElement when a custom element constructor returns a Text node');
|
||||
|
||||
test(function () {
|
||||
var instance = document.querySelector('returns-non-element-object');
|
||||
|
||||
assert_false(instance instanceof ReturnsNonElementObject, 'HTML parser must NOT instantiate a custom element when the constructor returns a non-Element object');
|
||||
assert_true(instance instanceof HTMLElement, 'The fallback element created by HTML parser must be an instance of HTMLElement');
|
||||
assert_true(instance instanceof HTMLUnknownElement, 'The fallback element created by HTML parser must be an instance of HTMLUnknownElement');
|
||||
|
||||
}, 'HTML parser must create a fallback HTMLUnknownElement when a custom element constructor returns non-Element object');
|
||||
|
||||
test(function () {
|
||||
var instance = document.querySelector('lacks-super-call');
|
||||
|
||||
assert_false(instance instanceof LacksSuperCall, 'HTML parser must NOT instantiate a custom element when the constructor does not call super()');
|
||||
assert_true(instance instanceof HTMLElement, 'The fallback element created by HTML parser must be an instance of HTMLElement');
|
||||
assert_true(instance instanceof HTMLUnknownElement, 'The fallback element created by HTML parser must be an instance of HTMLUnknownElement');
|
||||
|
||||
}, 'HTML parser must create a fallback HTMLUnknownElement when a custom element constructor does not call super()');
|
||||
|
||||
test(function () {
|
||||
var instance = document.querySelector('throws-exception');
|
||||
|
||||
assert_false(instance instanceof ThrowsException, 'HTML parser must NOT instantiate a custom element when the constructor throws an exception');
|
||||
assert_true(instance instanceof HTMLElement, 'The fallback element created by HTML parser must be an instance of HTMLElement');
|
||||
assert_true(instance instanceof HTMLUnknownElement, 'The fallback element created by HTML parser must be an instance of HTMLUnknownElement');
|
||||
|
||||
}, 'HTML parser must create a fallback HTMLUnknownElement when a custom element constructor throws an exception');
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Reference in a new issue