Stop traversing at the container block when computing RTL inline static distance.
https://bugs.webkit.org/show_bug.cgi?id=157349
<rdar://problem/25994087>

Reviewed by David Hyatt.

When computing the inline static distance for a child renderer, we start at its enclosing box
and traverse up all the way to the container block.
However when the enclosing box is the ancestor of the container block, we
should just bail out right away since there's no container to use to adjust the position.

Source/WebCore:

Test: fast/multicol/positioned-rtl-column-crash.html

* rendering/RenderBox.cpp:
(WebCore::computeInlineStaticDistance):

LayoutTests:

* fast/multicol/positioned-rtl-column-crash-expected.txt: Added.
* fast/multicol/positioned-rtl-column-crash.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@200492 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 2677226..f07f7e5 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,19 @@
+2016-05-05  Zalan Bujtas  <zalan@apple.com>
+
+        Stop traversing at the container block when computing RTL inline static distance.
+        https://bugs.webkit.org/show_bug.cgi?id=157349
+        <rdar://problem/25994087>
+
+        Reviewed by David Hyatt.
+
+        When computing the inline static distance for a child renderer, we start at its enclosing box
+        and traverse up all the way to the container block.
+        However when the enclosing box is the ancestor of the container block, we
+        should just bail out right away since there's no container to use to adjust the position.
+
+        * fast/multicol/positioned-rtl-column-crash-expected.txt: Added.
+        * fast/multicol/positioned-rtl-column-crash.html: Added.
+
 2016-05-05  Ryan Haddad  <ryanhaddad@apple.com>
 
         Unskip 9 compositing tests on ios-simulator, mark 2 as failures on ios-simulator-wk1
diff --git a/LayoutTests/fast/multicol/positioned-rtl-column-crash-expected.txt b/LayoutTests/fast/multicol/positioned-rtl-column-crash-expected.txt
new file mode 100644
index 0000000..b4d63d6
--- /dev/null
+++ b/LayoutTests/fast/multicol/positioned-rtl-column-crash-expected.txt
@@ -0,0 +1 @@
+PASS if no crash or ASSERT.
diff --git a/LayoutTests/fast/multicol/positioned-rtl-column-crash.html b/LayoutTests/fast/multicol/positioned-rtl-column-crash.html
new file mode 100644
index 0000000..1575e6d
--- /dev/null
+++ b/LayoutTests/fast/multicol/positioned-rtl-column-crash.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that multi-column positioned RTL content works.</title>
+<style>
+div { 
+    -webkit-column-count: 2; 
+}
+.outer { 
+    position: relative;  
+    direction: rtl; 
+}
+.inner { 
+    position: absolute; 
+}
+</style>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+</script>
+</head>
+<body>
+<div><span class=outer><span class=inner></span></span></div>
+PASS if no crash or ASSERT.
+</body>
+</html>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index a5a9288..02c09c18 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,21 @@
+2016-05-05  Zalan Bujtas  <zalan@apple.com>
+
+        Stop traversing at the container block when computing RTL inline static distance.
+        https://bugs.webkit.org/show_bug.cgi?id=157349
+        <rdar://problem/25994087>
+
+        Reviewed by David Hyatt.
+
+        When computing the inline static distance for a child renderer, we start at its enclosing box
+        and traverse up all the way to the container block.
+        However when the enclosing box is the ancestor of the container block, we
+        should just bail out right away since there's no container to use to adjust the position.
+
+        Test: fast/multicol/positioned-rtl-column-crash.html
+
+        * rendering/RenderBox.cpp:
+        (WebCore::computeInlineStaticDistance):
+
 2016-05-05  Ada Chan  <adachan@apple.com>
 
         Add WebKitAdditions extension points in media controls related code in RenderThemeMac
diff --git a/Source/WebCore/rendering/RenderBox.cpp b/Source/WebCore/rendering/RenderBox.cpp
index a61b189..6c1602d 100644
--- a/Source/WebCore/rendering/RenderBox.cpp
+++ b/Source/WebCore/rendering/RenderBox.cpp
@@ -3383,28 +3383,33 @@
         }
         logicalLeft.setValue(Fixed, staticPosition);
     } else {
-        const RenderBox& enclosingBox = child->parent()->enclosingBox();
         LayoutUnit staticPosition = child->layer()->staticInlinePosition() + containerLogicalWidth + containerBlock.borderLogicalLeft();
+        auto& enclosingBox = child->parent()->enclosingBox();
+        if (&enclosingBox != &containerBlock && containerBlock.isDescendantOf(&enclosingBox)) {
+            logicalRight.setValue(Fixed, staticPosition);
+            return;
+        }
+
+        staticPosition -= enclosingBox.logicalWidth();
         for (const RenderElement* current = &enclosingBox; current; current = current->container()) {
-            if (is<RenderBox>(*current)) {
-                if (current != &containerBlock) {
-                    const auto& renderBox = downcast<RenderBox>(*current);
-                    staticPosition -= renderBox.logicalLeft();
-                    if (renderBox.isInFlowPositioned())
-                        staticPosition -= renderBox.isHorizontalWritingMode() ? renderBox.offsetForInFlowPosition().width() : renderBox.offsetForInFlowPosition().height();
-                }
-                if (current == &enclosingBox)
-                    staticPosition -= enclosingBox.logicalWidth();
-                if (region && is<RenderBlock>(*current)) {
-                    const RenderBlock& currentBlock = downcast<RenderBlock>(*current);
-                    region = currentBlock.clampToStartAndEndRegions(region);
-                    RenderBoxRegionInfo* boxInfo = currentBlock.renderBoxRegionInfo(region);
-                    if (boxInfo) {
-                        if (current != &containerBlock)
-                            staticPosition -= currentBlock.logicalWidth() - (boxInfo->logicalLeft() + boxInfo->logicalWidth());
-                        if (current == &enclosingBox)
-                            staticPosition += enclosingBox.logicalWidth() - boxInfo->logicalWidth();
-                    }
+            if (!is<RenderBox>(*current))
+                continue;
+
+            if (current != &containerBlock) {
+                auto& renderBox = downcast<RenderBox>(*current);
+                staticPosition -= renderBox.logicalLeft();
+                if (renderBox.isInFlowPositioned())
+                    staticPosition -= renderBox.isHorizontalWritingMode() ? renderBox.offsetForInFlowPosition().width() : renderBox.offsetForInFlowPosition().height();
+            }
+            if (region && is<RenderBlock>(*current)) {
+                auto& currentBlock = downcast<RenderBlock>(*current);
+                region = currentBlock.clampToStartAndEndRegions(region);
+                RenderBoxRegionInfo* boxInfo = currentBlock.renderBoxRegionInfo(region);
+                if (boxInfo) {
+                    if (current != &containerBlock)
+                        staticPosition -= currentBlock.logicalWidth() - (boxInfo->logicalLeft() + boxInfo->logicalWidth());
+                    if (current == &enclosingBox)
+                        staticPosition += enclosingBox.logicalWidth() - boxInfo->logicalWidth();
                 }
             }
             if (current == &containerBlock)