Prevent overflow of width/height of layout overflow rectangle which can cause scroll bar to misfunction.
When a child element is positioned very far away the width/height of layout overflow rectangle may overflow. The patch detects such cases in RenderOverflow::addLayoutOverflow and shift the top/left edges of the rectangle to avoid overflow.
BUG=267462
Review URL: https://chromiumcodereview.appspot.com/22799017
git-svn-id: svn://svn.chromium.org/blink/trunk@156567 bbb929c8-8fbe-4397-9dbb-9b2b20218538
diff --git a/LayoutTests/scrollbars/scrollbar-large-overflow-rectangle-expected.txt b/LayoutTests/scrollbars/scrollbar-large-overflow-rectangle-expected.txt
new file mode 100644
index 0000000..f91edcf
--- /dev/null
+++ b/LayoutTests/scrollbars/scrollbar-large-overflow-rectangle-expected.txt
@@ -0,0 +1,3 @@
+This page should be scrollable
+PASS
+
diff --git a/LayoutTests/scrollbars/scrollbar-large-overflow-rectangle.html b/LayoutTests/scrollbars/scrollbar-large-overflow-rectangle.html
new file mode 100644
index 0000000..94273b3
--- /dev/null
+++ b/LayoutTests/scrollbars/scrollbar-large-overflow-rectangle.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>absolute positioned element with large negative top value inside tall relative positioned box does not render scrollbars</title>
+ <style>
+ body, p{
+ margin:0;
+ }
+ div{
+ position: relative;
+ height:3000px;
+ }
+ span{
+ position: absolute;
+ top:-3355400000px;
+ }
+ </style>
+ <script>
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+ }
+
+ function test() {
+ var height = document.body.scrollHeight;
+ if (height == 3000)
+ document.getElementById("result").innerHTML = "PASS";
+ else
+ document.getElementById("result").innerHTML = "<p style='color:red'>FAIL document.body.scrollHeight = " + height +"</p>";
+ }
+ </script>
+ </head>
+
+ <body onload="test()">
+ <div>
+ <p> This page should be scrollable </p>
+ <p id="result"> </p>
+ <span style="visibility:hidden">filler <!--abs pos with very large negative top value--></span>
+ </div>
+
+ </body>
+</html>
diff --git a/Source/core/rendering/RenderOverflow.h b/Source/core/rendering/RenderOverflow.h
index 1c5417f..49ad02a 100644
--- a/Source/core/rendering/RenderOverflow.h
+++ b/Source/core/rendering/RenderOverflow.h
@@ -91,10 +91,13 @@
{
LayoutUnit maxX = std::max(rect.maxX(), m_layoutOverflow.maxX());
LayoutUnit maxY = std::max(rect.maxY(), m_layoutOverflow.maxY());
- m_layoutOverflow.setX(std::min(rect.x(), m_layoutOverflow.x()));
- m_layoutOverflow.setY(std::min(rect.y(), m_layoutOverflow.y()));
- m_layoutOverflow.setWidth(maxX - m_layoutOverflow.x());
- m_layoutOverflow.setHeight(maxY - m_layoutOverflow.y());
+ LayoutUnit minX = std::min(rect.x(), m_layoutOverflow.x());
+ LayoutUnit minY = std::min(rect.y(), m_layoutOverflow.y());
+ // In case the width/height is larger than LayoutUnit can represent, fix the right/bottom edge and shift the top/left ones
+ m_layoutOverflow.setWidth(maxX - minX);
+ m_layoutOverflow.setHeight(maxY - minY);
+ m_layoutOverflow.setX(maxX - m_layoutOverflow.width());
+ m_layoutOverflow.setY(maxY - m_layoutOverflow.height());
}
inline void RenderOverflow::addVisualOverflow(const LayoutRect& rect)