Browse Source

LibWeb: Do not shrink the CPU painter's corner clipping vector

If the provided ID is smaller than the corner clipping vector, we would
shrink the vector to match. This causes a crash when we have nested
PaintContext instances (as these IDs are allocated by PaintContext),
each of which perform radius painting.

This is seen on https://www.strava.com/login when it loads a reCAPTCHA.
The outer div has a border radius, which contains the reCAPTCHA in an
iframe. That iframe contains an SVG which also has a border radius.
Timothy Flynn 1 year ago
parent
commit
842caf5e8c

+ 7 - 0
Tests/LibWeb/Text/data/iframe-with-border-radius-svg.html

@@ -0,0 +1,7 @@
+<style>
+    div {
+        background-image: url('data:image/svg+xml;utf8,<svg version="1.1" xmlns="http://www.w3.org/2000/svg"></svg>');
+        border-radius: 1px;
+    }
+</style>
+<div>Text</div>

+ 1 - 0
Tests/LibWeb/Text/expected/border-radius-div-containing-iframe-with-border-radius-svg.txt

@@ -0,0 +1 @@
+   PASS! (didn't crash)

+ 13 - 0
Tests/LibWeb/Text/input/border-radius-div-containing-iframe-with-border-radius-svg.html

@@ -0,0 +1,13 @@
+<style>
+    div {
+        border-radius: 1px;
+        overflow: hidden;
+    }
+</style>
+<div><iframe src="../data/iframe-with-border-radius-svg.html"></iframe></div>
+<script src="include.js"></script>
+<script>
+    test(() => {
+        println("PASS! (didn't crash)");
+    });
+</script>

+ 3 - 1
Userland/Libraries/LibWeb/Painting/CommandExecutorCPU.cpp

@@ -461,7 +461,9 @@ CommandResult CommandExecutorCPU::draw_triangle_wave(Gfx::IntPoint const& p1, Gf
 
 
 CommandResult CommandExecutorCPU::sample_under_corners(u32 id, CornerRadii const& corner_radii, Gfx::IntRect const& border_rect, CornerClip corner_clip)
 CommandResult CommandExecutorCPU::sample_under_corners(u32 id, CornerRadii const& corner_radii, Gfx::IntRect const& border_rect, CornerClip corner_clip)
 {
 {
-    m_corner_clippers.resize(id + 1);
+    if (id >= m_corner_clippers.size())
+        m_corner_clippers.resize(id + 1);
+
     auto clipper = BorderRadiusCornerClipper::create(corner_radii, border_rect.to_type<DevicePixels>(), corner_clip);
     auto clipper = BorderRadiusCornerClipper::create(corner_radii, border_rect.to_type<DevicePixels>(), corner_clip);
     m_corner_clippers[id] = clipper.release_value_but_fixme_should_propagate_errors();
     m_corner_clippers[id] = clipper.release_value_but_fixme_should_propagate_errors();
     m_corner_clippers[id]->sample_under_corners(painter());
     m_corner_clippers[id]->sample_under_corners(painter());