Commit 55138770 authored by Stefan Zager's avatar Stefan Zager Committed by Commit Bot

Clamp size of remote frame viewport intersection to frame bounds

When calculating the viewport intersection of an iframe, we walk up
the LayoutObject hierarchy, mapping the iframe's bounds into the
coordinate system of each of its ancestors. When we encounter an
ancestor with a clip, we take the axis-aligned enclosing rect of the
iframe bounds to calculate the clip, and continue with that. As a
result, the final computed intersection rect can be *larger* than the
initial rect.

This patch clamps the size and location of the viewport intersection
to the size of the iframe's contents.

Change-Id: Ie78cd824d68509ede748a906cefad4d611642388
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2427187
Commit-Queue: Stefan Zager <szager@chromium.org>
Reviewed-by: default avatarKen Buchanan <kenrb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#811500}
parent 65a4aa0a
......@@ -10670,6 +10670,59 @@ TEST_F(WebFrameTest, MaxFrames) {
EXPECT_FALSE(iframe->ContentFrame());
}
class ViewportIntersectionCatcher
: public frame_test_helpers::TestWebRemoteFrameClient {
public:
void UpdateRemoteViewportIntersection(
const ViewportIntersectionState& state) override {
intersection_state_ = state;
frame_test_helpers::TestWebRemoteFrameClient::
UpdateRemoteViewportIntersection(state);
}
const ViewportIntersectionState& GetState() const {
return intersection_state_;
}
private:
ViewportIntersectionState intersection_state_;
};
TEST_F(WebFrameTest, RotatedIframeViewportIntersection) {
frame_test_helpers::WebViewHelper web_view_helper;
web_view_helper.Initialize();
WebViewImpl* web_view = web_view_helper.GetWebView();
web_view->Resize(WebSize(800, 600));
InitializeWithHTML(*web_view->MainFrameImpl()->GetFrame(), R"HTML(
<!DOCTYPE html>
<style>
iframe {
position: absolute;
top: 200px;
left: 200px;
transform: rotate(45deg);
}
</style>
<iframe></iframe>
)HTML");
ViewportIntersectionCatcher intersection_catcher;
WebRemoteFrameImpl* remote_frame =
frame_test_helpers::CreateRemote(&intersection_catcher);
web_view_helper.LocalMainFrame()->FirstChild()->Swap(remote_frame);
web_view->MainFrameImpl()->GetFrame()->View()->UpdateAllLifecyclePhases(
DocumentUpdateReason::kTest);
web_view->MainFrameImpl()->GetFrame()->View()->RunPostLifecycleSteps();
ASSERT_TRUE(!intersection_catcher.GetState().viewport_intersection.IsEmpty());
EXPECT_TRUE(
IntRect(IntPoint(), remote_frame->GetFrame()->View()->Size())
.Contains(intersection_catcher.GetState().viewport_intersection));
ASSERT_TRUE(
!intersection_catcher.GetState().main_frame_intersection.IsEmpty());
EXPECT_TRUE(
IntRect(IntPoint(), remote_frame->GetFrame()->View()->Size())
.Contains(intersection_catcher.GetState().main_frame_intersection));
remote_frame->Detach();
}
TEST_F(WebFrameTest, ImageDocumentLoadResponseEnd) {
// Loading an image resource directly generates an ImageDocument with
// the document loader feeding image data into the resource of a generated
......
......@@ -130,6 +130,15 @@ void FrameView::UpdateViewportIntersection(unsigned flags,
} else {
viewport_intersection = EnclosingIntRect(intersection_rect);
}
// Because the geometry code uses enclosing rects, we may end up with an
// intersection rect that is bigger than the rect we started with. Clamp
// the size of the viewport intersection to the bounds of the iframe's
// content rect.
viewport_intersection.SetLocation(
viewport_intersection.Location().ExpandedTo(IntPoint()));
viewport_intersection.SetSize(viewport_intersection.Size().ShrunkTo(
RoundedIntSize(owner_layout_object->ContentSize())));
}
PhysicalRect mainframe_intersection_rect;
......@@ -144,6 +153,10 @@ void FrameView::UpdateViewportIntersection(unsigned flags,
} else {
mainframe_intersection = EnclosingIntRect(mainframe_intersection_rect);
}
mainframe_intersection.SetLocation(
mainframe_intersection.Location().ExpandedTo(IntPoint()));
mainframe_intersection.SetSize(mainframe_intersection.Size().ShrunkTo(
RoundedIntSize(owner_layout_object->ContentSize())));
}
TransformState child_frame_to_root_frame(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment