Просмотр исходного кода

LibWeb: Protect LayoutCheckBox against crashes after event dispatch

After dispatching a "change" event due to the checked state being
modified, we may have been removed from the layout tree.

Make LayoutCheckBox protect itself to prevent this from crashing.

Also, add a little test page for checkboxes. :^)
Andreas Kling 4 лет назад
Родитель
Сommit
b62043dbca

+ 11 - 0
Base/res/html/misc/checkbox.html

@@ -0,0 +1,11 @@
+<html>
+    <input id=foo type=checkbox> This is a checkbox
+    <pre id=bar></pre>
+    <script>
+        var foo = document.getElementById("foo");
+        var bar = document.getElementById("bar");
+        foo.addEventListener("change", function() {
+            bar.innerHTML += foo.checked + "\n";
+        });
+    </script>
+</html>

+ 1 - 0
Base/res/html/misc/welcome.html

@@ -31,6 +31,7 @@ span#ua {
     <p>Your user agent is: <b><span id="ua"></span></b></p>
     <p>Some small test pages:</p>
     <ul>
+        <li><a href="checkbox.html">checkbox</a></li>
         <li><a href="canvas-rotate.html">canvas rotate()</a></li>
         <li><a href="margin-collapse-2.html">margin collapsing 2</a></li>
         <li><a href="margin-collapse-1.html">margin collapsing 1</a></li>

+ 3 - 0
Libraries/LibWeb/Layout/LayoutCheckBox.cpp

@@ -80,6 +80,9 @@ void LayoutCheckBox::handle_mouseup(Badge<EventHandler>, const Gfx::IntPoint& po
     if (!m_tracking_mouse || button != GUI::MouseButton::Left)
         return;
 
+    // NOTE: Changing the checked state of the DOM node may run arbitrary JS, which could disappear this node.
+    NonnullRefPtr protect = *this;
+
     bool is_inside = enclosing_int_rect(absolute_rect()).contains(position);
     if (is_inside)
         node().set_checked(!node().checked());