Browse Source

chore: cherry-pick f8a74d72f3 from chromium. (#31211)

Co-authored-by: Electron Bot <[email protected]>
Pedro Pontes 3 years ago
parent
commit
8a9811a29d

+ 1 - 0
patches/chromium/.patches

@@ -160,4 +160,5 @@ cherry-pick-8623d711677d.patch
 contentindex_add_origin_checks_to_mojo_methods.patch
 skip_webgl_conformance_programs_program-test_html_on_all_platforms.patch
 cherry-pick-ddc4cf156505.patch
+content-visibility_add_a_clipper_fix_for_content-visibility.patch
 kill_a_renderer_if_it_provides_an_unexpected_frameownerelementtype.patch

+ 292 - 0
patches/chromium/content-visibility_add_a_clipper_fix_for_content-visibility.patch

@@ -0,0 +1,292 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Vladimir Levin <[email protected]>
+Date: Tue, 14 Sep 2021 00:06:00 +0000
+Subject: content-visibility: Add a clipper fix for content-visibility.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch adds a few checks in the svg painting code which may access
+a content-visibility locked element via an svg reference.
+
+R=​[email protected],[email protected]
+
+(cherry picked from commit e0d8a4f20bf98bbda2dc58199fca5caf0add1b00)
+
+Bug: 1247196
+Change-Id: I4dcb4ef298fb8d51aa0ec1a3b3bc130cfb560791
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3149811
+Reviewed-by: Fredrik Söderquist <[email protected]>
+Reviewed-by: Joey Arhar <[email protected]>
+Commit-Queue: vmpstr <[email protected]>
+Cr-Original-Commit-Position: refs/heads/main@{#920209}
+Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3158958
+Commit-Queue: Joey Arhar <[email protected]>
+Commit-Queue: Mason Freed <[email protected]>
+Auto-Submit: Joey Arhar <[email protected]>
+Reviewed-by: Mason Freed <[email protected]>
+Cr-Commit-Position: refs/branch-heads/4606@{#1011}
+Cr-Branched-From: 35b0d5a9dc8362adfd44e2614f0d5b7402ef63d0-refs/heads/master@{#911515}
+
+diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_container_test.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_container_test.cc
+index 57e3540f9dc9419261ed7be84bd951df75380009..a625a03d0cc3e120e26f104d564db10ef78601e4 100644
+--- a/third_party/blink/renderer/core/layout/svg/layout_svg_container_test.cc
++++ b/third_party/blink/renderer/core/layout/svg/layout_svg_container_test.cc
+@@ -117,4 +117,34 @@ TEST_F(LayoutSVGContainerTest,
+   EXPECT_TRUE(use->SlowFirstChild()->TransformAffectsVectorEffect());
+ }
+ 
++TEST_F(LayoutSVGContainerTest, PatternWithContentVisibility) {
++  SetBodyInnerHTML(R"HTML(
++    <svg viewBox="0 0 230 100" xmlns="http://www.w3.org/2000/svg">
++      <defs>
++        <pattern id="pattern" viewBox="0,0,10,10" width="10%" height="10%">
++          <polygon id="polygon" points="0,0 2,5 0,10 5,8 10,10 8,5 10,0 5,2"/>
++        </pattern>
++      </defs>
++
++      <circle id="circle" cx="50"  cy="50" r="50" fill="url(#pattern)"/>
++    </svg>
++  )HTML");
++
++  auto* pattern = GetDocument().getElementById("pattern");
++  auto* polygon = GetDocument().getElementById("polygon");
++
++  pattern->setAttribute("style", "contain: strict; content-visibility: hidden");
++
++  UpdateAllLifecyclePhasesForTest();
++
++  polygon->setAttribute("points", "0,0 2,5 0,10");
++
++  // This shouldn't cause a DCHECK, even though the pattern needs layout because
++  // it's under a content-visibility: hidden subtree.
++  UpdateAllLifecyclePhasesForTest();
++
++  EXPECT_TRUE(pattern->GetLayoutObject()->NeedsLayout());
++  EXPECT_FALSE(pattern->GetLayoutObject()->SelfNeedsLayout());
++}
++
+ }  // namespace blink
+diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc
+index f00325cb831e7037a7c61e8e185c73d6a09cb34c..d3d6fa311d3e22b5d9256d2d737d33f770ce4f4f 100644
+--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc
++++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.cc
+@@ -22,6 +22,7 @@
+ 
+ #include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_clipper.h"
+ 
++#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
+ #include "third_party/blink/renderer/core/dom/element_traversal.h"
+ #include "third_party/blink/renderer/core/layout/hit_test_result.h"
+ #include "third_party/blink/renderer/core/layout/layout_box_model_object.h"
+@@ -54,6 +55,8 @@ ClipStrategy DetermineClipStrategy(const SVGGraphicsElement& element) {
+   const LayoutObject* layout_object = element.GetLayoutObject();
+   if (!layout_object)
+     return ClipStrategy::kNone;
++  if (DisplayLockUtilities::LockedAncestorPreventingLayout(*layout_object))
++    return ClipStrategy::kNone;
+   const ComputedStyle& style = layout_object->StyleRef();
+   if (style.Display() == EDisplay::kNone ||
+       style.Visibility() != EVisibility::kVisible)
+@@ -74,8 +77,12 @@ ClipStrategy DetermineClipStrategy(const SVGElement& element) {
+   // (https://drafts.fxtf.org/css-masking/#ClipPathElement)
+   if (auto* svg_use_element = DynamicTo<SVGUseElement>(element)) {
+     const LayoutObject* use_layout_object = element.GetLayoutObject();
+-    if (!use_layout_object ||
+-        use_layout_object->StyleRef().Display() == EDisplay::kNone)
++    if (!use_layout_object)
++      return ClipStrategy::kNone;
++    if (DisplayLockUtilities::LockedAncestorPreventingLayout(
++            *use_layout_object))
++      return ClipStrategy::kNone;
++    if (use_layout_object->StyleRef().Display() == EDisplay::kNone)
+       return ClipStrategy::kNone;
+     const SVGGraphicsElement* shape_element =
+         svg_use_element->VisibleTargetGraphicsElementForClipping();
+@@ -271,7 +278,7 @@ bool LayoutSVGResourceClipper::HitTestClipContent(
+ FloatRect LayoutSVGResourceClipper::ResourceBoundingBox(
+     const FloatRect& reference_box) {
+   NOT_DESTROYED();
+-  DCHECK(!NeedsLayout());
++  DCHECK(!SelfNeedsLayout());
+ 
+   if (local_clip_bounds_.IsEmpty())
+     CalculateLocalClipBounds();
+diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.cc
+index d20bb36c00b84e200e518d2282a9db69072ca5f0..0b598d713f03e574dbd390225e81781b86e53d5e 100644
+--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.cc
++++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.cc
+@@ -19,6 +19,7 @@
+ 
+ #include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.h"
+ 
++#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
+ #include "third_party/blink/renderer/core/dom/element_traversal.h"
+ #include "third_party/blink/renderer/core/layout/svg/svg_layout_support.h"
+ #include "third_party/blink/renderer/core/paint/svg_object_painter.h"
+@@ -65,7 +66,9 @@ sk_sp<const PaintRecord> LayoutSVGResourceMasker::CreatePaintRecord(
+   for (const SVGElement& child_element :
+        Traversal<SVGElement>::ChildrenOf(*GetElement())) {
+     const LayoutObject* layout_object = child_element.GetLayoutObject();
+-    if (!layout_object ||
++    if (!layout_object)
++      continue;
++    if (DisplayLockUtilities::LockedAncestorPreventingLayout(*layout_object) ||
+         layout_object->StyleRef().Display() == EDisplay::kNone)
+       continue;
+     SVGObjectPainter(*layout_object).PaintResourceSubtree(builder.Context());
+@@ -91,7 +94,7 @@ FloatRect LayoutSVGResourceMasker::ResourceBoundingBox(
+     const FloatRect& reference_box,
+     float reference_box_zoom) {
+   NOT_DESTROYED();
+-  DCHECK(!NeedsLayout());
++  DCHECK(!SelfNeedsLayout());
+   auto* mask_element = To<SVGMaskElement>(GetElement());
+   DCHECK(mask_element);
+ 
+diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc
+index 1b9f67bc9e186654bfd03410b8e2d73654a7f1e2..c246bcd5a1d524302586cd145f39a1a2b47adef8 100644
+--- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc
++++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc
+@@ -24,6 +24,7 @@
+ #include <memory>
+ 
+ #include "base/memory/ptr_util.h"
++#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
+ #include "third_party/blink/renderer/core/layout/svg/svg_layout_support.h"
+ #include "third_party/blink/renderer/core/layout/svg/svg_resources.h"
+ #include "third_party/blink/renderer/core/paint/svg_object_painter.h"
+@@ -205,8 +206,20 @@ sk_sp<PaintRecord> LayoutSVGResourcePattern::AsPaintRecord(
+     content_transform = tile_transform;
+ 
+   FloatRect bounds(FloatPoint(), size);
++  PaintRecorder paint_recorder;
++  cc::PaintCanvas* canvas = paint_recorder.beginRecording(bounds);
++
++  auto* pattern_content_element = Attributes().PatternContentElement();
++  DCHECK(pattern_content_element);
++  // If the element or some of its ancestor prevents us from doing paint, we can
++  // early out. Note that any locked ancestor would prevent paint.
++  if (DisplayLockUtilities::NearestLockedInclusiveAncestor(
++          *pattern_content_element)) {
++    return paint_recorder.finishRecordingAsPicture();
++  }
++
+   const auto* pattern_layout_object = To<LayoutSVGResourceContainer>(
+-      Attributes().PatternContentElement()->GetLayoutObject());
++      pattern_content_element->GetLayoutObject());
+   DCHECK(pattern_layout_object);
+   DCHECK(!pattern_layout_object->NeedsLayout());
+ 
+@@ -216,8 +229,6 @@ sk_sp<PaintRecord> LayoutSVGResourcePattern::AsPaintRecord(
+   for (LayoutObject* child = pattern_layout_object->FirstChild(); child;
+        child = child->NextSibling())
+     SVGObjectPainter(*child).PaintResourceSubtree(builder.Context());
+-  PaintRecorder paint_recorder;
+-  cc::PaintCanvas* canvas = paint_recorder.beginRecording(bounds);
+   canvas->save();
+   canvas->concat(AffineTransformToSkMatrix(tile_transform));
+   builder.EndRecording(*canvas);
+diff --git a/third_party/blink/renderer/core/paint/clip_path_clipper.cc b/third_party/blink/renderer/core/paint/clip_path_clipper.cc
+index 66b6d44961aa7e2b534dcd402d9e9eede4447b52..7a7fa937d96641284ebbfc8b083965d7eb6e287d 100644
+--- a/third_party/blink/renderer/core/paint/clip_path_clipper.cc
++++ b/third_party/blink/renderer/core/paint/clip_path_clipper.cc
+@@ -4,6 +4,7 @@
+ 
+ #include "third_party/blink/renderer/core/paint/clip_path_clipper.h"
+ 
++#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
+ #include "third_party/blink/renderer/core/dom/element_traversal.h"
+ #include "third_party/blink/renderer/core/layout/layout_box.h"
+ #include "third_party/blink/renderer/core/layout/layout_inline.h"
+@@ -42,10 +43,14 @@ LayoutSVGResourceClipper* ResolveElementReference(
+     return nullptr;
+   LayoutSVGResourceClipper* resource_clipper =
+       GetSVGResourceAsType(*client, reference_clip_path_operation);
+-  if (resource_clipper) {
+-    SECURITY_DCHECK(!resource_clipper->NeedsLayout());
+-    resource_clipper->ClearInvalidationMask();
+-  }
++  if (!resource_clipper)
++    return nullptr;
++
++  resource_clipper->ClearInvalidationMask();
++  if (DisplayLockUtilities::LockedAncestorPreventingLayout(*resource_clipper))
++    return nullptr;
++
++  SECURITY_DCHECK(!resource_clipper->SelfNeedsLayout());
+   return resource_clipper;
+ }
+ 
+diff --git a/third_party/blink/renderer/core/paint/svg_mask_painter.cc b/third_party/blink/renderer/core/paint/svg_mask_painter.cc
+index d049d3e18eed09ed4755ef483e9cd4b60925232c..2d40adb1ff99f3d29dce027995871cba399af3fb 100644
+--- a/third_party/blink/renderer/core/paint/svg_mask_painter.cc
++++ b/third_party/blink/renderer/core/paint/svg_mask_painter.cc
+@@ -4,6 +4,7 @@
+ 
+ #include "third_party/blink/renderer/core/paint/svg_mask_painter.h"
+ 
++#include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h"
+ #include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_masker.h"
+ #include "third_party/blink/renderer/core/layout/svg/svg_resources.h"
+ #include "third_party/blink/renderer/core/paint/object_paint_properties.h"
+@@ -46,7 +47,9 @@ void SVGMaskPainter::Paint(GraphicsContext& context,
+   auto* masker = GetSVGResourceAsType<LayoutSVGResourceMasker>(
+       *client, svg_style.MaskerResource());
+   DCHECK(masker);
+-  SECURITY_DCHECK(!masker->NeedsLayout());
++  if (DisplayLockUtilities::LockedAncestorPreventingLayout(*masker))
++    return;
++  SECURITY_DCHECK(!masker->SelfNeedsLayout());
+   masker->ClearInvalidationMask();
+ 
+   FloatRect reference_box = SVGResources::ReferenceBoxForEffects(layout_object);
+diff --git a/third_party/blink/renderer/core/paint/svg_object_painter.cc b/third_party/blink/renderer/core/paint/svg_object_painter.cc
+index 8454ad348bd7d3daf8e24a0e8e7360c0888ca0e6..56d8732423028bf9850ee2b640dd335de5f2c67a 100644
+--- a/third_party/blink/renderer/core/paint/svg_object_painter.cc
++++ b/third_party/blink/renderer/core/paint/svg_object_painter.cc
+@@ -31,7 +31,7 @@ void CopyStateFromGraphicsContext(GraphicsContext& context, PaintFlags& flags) {
+ }  // namespace
+ 
+ void SVGObjectPainter::PaintResourceSubtree(GraphicsContext& context) {
+-  DCHECK(!layout_object_.NeedsLayout());
++  DCHECK(!layout_object_.SelfNeedsLayout());
+ 
+   PaintInfo info(context, LayoutRect::InfiniteIntRect(),
+                  PaintPhase::kForeground,
+diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-in-svg-000-crash.html b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-in-svg-000-crash.html
+new file mode 100644
+index 0000000000000000000000000000000000000000..d1084f7216510386f159033e2f7b0e3966bd2758
+--- /dev/null
++++ b/third_party/blink/web_tests/external/wpt/css/css-contain/content-visibility/content-visibility-in-svg-000-crash.html
+@@ -0,0 +1,30 @@
++<!DOCTYPE html>
++<html class="test-wait">
++<link rel="author" title="Vladimir Levin" href="mailto:[email protected]">
++<link rel="help" href="https://crbug.com/1247196">
++<meta name="assert" content="Clip path with content-visibility does not cause an assert">
++
++<svg width="138">
++  <defs>
++    <clipPath id="snowglobe_clipPath">
++      <circle cx="34" />
++    </clipPath>
++  </defs>
++  <circle />
++  <g class="group-snow" clip-path="url(#snowglobe_clipPath)">
++    <g class="snowContainer">
++      <circle class="snow" />
++    </g>
++  </g>
++</svg>
++<script type="text/javascript">
++onload = () => {
++  var test0 = document.getElementById("snowglobe_clipPath");
++  test0.style.setProperty("content-visibility", "auto ", "important");
++  test0.innerHTML = "";
++  test0.offsetHeight;
++
++  requestAnimationFrame(() => document.documentElement.classList.remove('test-wait'));
++};
++</script>
++</html>