Skip to content

Commit

Permalink
Avoid crash in intersection observer with inline root
Browse files Browse the repository at this point in the history
crrev.com/c/4583590 caused the problem by changing ContainingBlock()
to Container() (which actually means "containing block" in the specs).
As an inline element doesn't clip, now check IsBox() in ClipToRoot
to avoid crash before casting the root to LayoutBox.

(cherry picked from commit 14f10fa)

Bug: 1455919, 1456208
Change-Id: I8d38c46233e0e74acbeeed35626cbc689c77ac33
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4626450
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: Philip Rogers <pdr@chromium.org>
Cr-Original-Commit-Position: refs/heads/main@{#1161346}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4641372
Auto-Submit: Xianzhu Wang <wangxianzhu@chromium.org>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/branch-heads/5845@{#55}
Cr-Branched-From: 5a5dff6-refs/heads/main@{#1160321}
  • Loading branch information
wangxianzhu authored and Chromium LUCI CQ committed Jun 23, 2023
1 parent c1bb30e commit 0aad7a8
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,10 @@ static const unsigned kConstructorFlagsMask =
IntersectionGeometry::RootGeometry::RootGeometry(const LayoutObject* root,
const Vector<Length>& margin) {
if (!root || !root->GetNode() || !root->GetNode()->isConnected() ||
!root->IsBox())
// TODO(crbug.com/1456208): Support inline root.
!root->IsBox()) {
return;
}
zoom = root->StyleRef().EffectiveZoom();
local_root_rect = InitializeRootRect(root, margin);
TransformState transform_state(TransformState::kApplyTransformDirection);
Expand Down Expand Up @@ -555,6 +557,9 @@ bool IntersectionGeometry::ClipToRoot(const LayoutObject* root,
PhysicalRect& unclipped_intersection_rect,
PhysicalRect& intersection_rect,
CachedRects* cached_rects) {
if (!root->IsBox()) {
return false;
}
// Map and clip rect into root element coordinates.
// TODO(szager): the writing mode flipping needs a test.
const LayoutBox* local_ancestor = nullptr;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1746,4 +1746,37 @@ TEST_P(IntersectionObserverTest, TargetMarginPercentResolvesAgainstRoot) {
EXPECT_EQ(target_margin_delegate->EntryCount(), 1);
EXPECT_TRUE(target_margin_delegate->LastEntry()->isIntersecting());
}

TEST_P(IntersectionObserverTest, InlineRoot) {
SimRequest main_resource("https://example.com/", "text/html");
LoadURL("https://example.com/");
main_resource.Complete(R"HTML(
<span id="root">
<div id="target" style="display: inline-block">TARGET</div>
</span>
)HTML");
Compositor().BeginFrame();

Element* root = GetDocument().getElementById("root");
ASSERT_TRUE(root);
IntersectionObserverInit* observer_init = IntersectionObserverInit::Create();
observer_init->setRoot(MakeGarbageCollected<V8UnionDocumentOrElement>(root));
DummyExceptionStateForTesting exception_state;
TestIntersectionObserverDelegate* observer_delegate =
MakeGarbageCollected<TestIntersectionObserverDelegate>(GetDocument());
IntersectionObserver* observer = IntersectionObserver::Create(
observer_init, *observer_delegate, exception_state);
ASSERT_FALSE(exception_state.HadException());
Element* target = GetDocument().getElementById("target");
ASSERT_TRUE(target);
observer->observe(target, exception_state);

Compositor().BeginFrame();
test::RunPendingTasks();
EXPECT_EQ(observer_delegate->CallCount(), 1);
EXPECT_EQ(observer_delegate->EntryCount(), 1);
// TODO(crbug.com/1456208): Support inline root.
EXPECT_FALSE(observer_delegate->LastEntry()->isIntersecting());
}

} // namespace blink

0 comments on commit 0aad7a8

Please sign in to comment.