[SCM] WebKit Debian packaging branch, webkit-1.3, updated. upstream/1.3.7-4207-g178b198

simon.fraser at apple.com simon.fraser at apple.com
Sun Feb 20 23:18:39 UTC 2011


The following commit has been merged in the webkit-1.3 branch:
commit 3fa248181a8dde9a219f8143d060d5541fb435e0
Author: simon.fraser at apple.com <simon.fraser at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Jan 19 21:29:01 2011 +0000

    2011-01-19  Simon Fraser  <simon.fraser at apple.com>
    
            Reviewed by Adam Roben.
    
            [CSS Gradients] Crash due to out-of-memory with repeating-linear-gradient and latter stop positioned before former
            https://bugs.webkit.org/show_bug.cgi?id=52732
    
            When repeating gradient stops, make sure that the first and last stops are not at the same
            place, otherwise we'll add stops indefinitely and run out of memory.
    
            Test: fast/gradients/zero-range-repeating-gradient-hang.html
    
            * css/CSSGradientValue.cpp:
            (WebCore::CSSGradientValue::addStops):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@76154 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 7e3b6cd..45eba07 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,17 @@
+2011-01-19  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Adam Roben.
+
+        [CSS Gradients] Crash due to out-of-memory with repeating-linear-gradient and latter stop positioned before former
+        https://bugs.webkit.org/show_bug.cgi?id=52732
+        
+        Test for repeating gradient with zero range.
+
+        * fast/gradients/zero-range-repeating-gradient-hang-expected.checksum: Added.
+        * fast/gradients/zero-range-repeating-gradient-hang-expected.png: Added.
+        * fast/gradients/zero-range-repeating-gradient-hang-expected.txt: Added.
+        * fast/gradients/zero-range-repeating-gradient-hang.html: Added.
+
 2011-01-19  Robert Hogan  <robert at webkit.org>
 
         Reviewed by Simon Hausmann.
diff --git a/LayoutTests/fast/flexbox/block-axis-expected.checksum b/LayoutTests/fast/gradients/zero-range-repeating-gradient-hang-expected.checksum
similarity index 100%
copy from LayoutTests/fast/flexbox/block-axis-expected.checksum
copy to LayoutTests/fast/gradients/zero-range-repeating-gradient-hang-expected.checksum
diff --git a/LayoutTests/fast/gradients/zero-range-repeating-gradient-hang-expected.txt b/LayoutTests/fast/gradients/zero-range-repeating-gradient-hang-expected.txt
new file mode 100644
index 0000000..a90cc4c
--- /dev/null
+++ b/LayoutTests/fast/gradients/zero-range-repeating-gradient-hang-expected.txt
@@ -0,0 +1,6 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x116
+  RenderBlock {HTML} at (0,0) size 800x116
+    RenderBody {BODY} at (8,8) size 784x100
+      RenderBlock {DIV} at (0,0) size 100x100
diff --git a/LayoutTests/fast/gradients/zero-range-repeating-gradient-hang.html b/LayoutTests/fast/gradients/zero-range-repeating-gradient-hang.html
new file mode 100644
index 0000000..31d3e69
--- /dev/null
+++ b/LayoutTests/fast/gradients/zero-range-repeating-gradient-hang.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <style type="text/css">
+    .box {
+      height: 100px;
+      width: 100px;
+      background: no-repeat -webkit-repeating-linear-gradient(red, blue, green 0);
+    }
+  </style>
+</head>
+<body>
+  <!-- This test should not hang. You should see a green square. -->
+  <div class="box"></div>
+</body>
+</html>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index f61ef79..c9a4a73 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,18 @@
+2011-01-19  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Adam Roben.
+
+        [CSS Gradients] Crash due to out-of-memory with repeating-linear-gradient and latter stop positioned before former
+        https://bugs.webkit.org/show_bug.cgi?id=52732
+        
+        When repeating gradient stops, make sure that the first and last stops are not at the same
+        place, otherwise we'll add stops indefinitely and run out of memory.
+
+        Test: fast/gradients/zero-range-repeating-gradient-hang.html
+
+        * css/CSSGradientValue.cpp:
+        (WebCore::CSSGradientValue::addStops):
+
 2011-01-14  Dimitri Glazkov  <dglazkov at chromium.org>
 
         Reviewed by Darin Adler.
diff --git a/Source/WebCore/css/CSSGradientValue.cpp b/Source/WebCore/css/CSSGradientValue.cpp
index fde4a4e..b6b9ebe 100644
--- a/Source/WebCore/css/CSSGradientValue.cpp
+++ b/Source/WebCore/css/CSSGradientValue.cpp
@@ -230,58 +230,68 @@ void CSSGradientValue::addStops(Gradient* gradient, RenderObject* renderer, Rend
     // We can't just push this logic down into the platform-specific Gradient code,
     // because we have to know the extent of the gradient, and possible move the end points.
     if (m_repeating && numStops > 1) {
-        float maxExtent = 1;
-
-        // Radial gradients may need to extend further than the endpoints, because they have
-        // to repeat out to the corners of the box.
-        if (isRadialGradient()) {
-            if (!computedGradientLength) {
-                FloatSize gradientSize(gradientStart - gradientEnd);
-                gradientLength = gradientSize.diagonalLength();
-            }
-            
-            if (maxLengthForRepeat > gradientLength)
-                maxExtent = maxLengthForRepeat / gradientLength;
-        }
+        // If the difference in the positions of the first and last color-stops is 0,
+        // the gradient defines a solid-color image with the color of the last color-stop in the rule.
+        float gradientRange = stops[numStops - 1].offset - stops[0].offset;
+        if (!gradientRange) {
+            stops.first().offset = 0;
+            stops.first().color = stops.last().color;
+            stops.shrink(1);
+            numStops = 1;
+        } else {
+            float maxExtent = 1;
 
-        size_t originalNumStops = numStops;
-        size_t originalFirstStopIndex = 0;
+            // Radial gradients may need to extend further than the endpoints, because they have
+            // to repeat out to the corners of the box.
+            if (isRadialGradient()) {
+                if (!computedGradientLength) {
+                    FloatSize gradientSize(gradientStart - gradientEnd);
+                    gradientLength = gradientSize.diagonalLength();
+                }
+                
+                if (maxLengthForRepeat > gradientLength)
+                    maxExtent = maxLengthForRepeat / gradientLength;
+            }
 
-        // Work backwards from the first, adding stops until we get one before 0.
-        float firstOffset = stops[0].offset;
-        if (firstOffset > 0) {
-            float currOffset = firstOffset;
-            size_t srcStopOrdinal = originalNumStops - 1;
-            
-            while (true) {
-                GradientStop newStop = stops[originalFirstStopIndex + srcStopOrdinal];
-                newStop.offset = currOffset;
-                stops.prepend(newStop);
-                ++originalFirstStopIndex;
-                if (currOffset < 0)
-                    break;
+            size_t originalNumStops = numStops;
+            size_t originalFirstStopIndex = 0;
 
-                if (srcStopOrdinal)
-                    currOffset -= stops[originalFirstStopIndex + srcStopOrdinal].offset - stops[originalFirstStopIndex + srcStopOrdinal - 1].offset;
-                srcStopOrdinal = (srcStopOrdinal + originalNumStops - 1) % originalNumStops;
+            // Work backwards from the first, adding stops until we get one before 0.
+            float firstOffset = stops[0].offset;
+            if (firstOffset > 0) {
+                float currOffset = firstOffset;
+                size_t srcStopOrdinal = originalNumStops - 1;
+                
+                while (true) {
+                    GradientStop newStop = stops[originalFirstStopIndex + srcStopOrdinal];
+                    newStop.offset = currOffset;
+                    stops.prepend(newStop);
+                    ++originalFirstStopIndex;
+                    if (currOffset < 0)
+                        break;
+
+                    if (srcStopOrdinal)
+                        currOffset -= stops[originalFirstStopIndex + srcStopOrdinal].offset - stops[originalFirstStopIndex + srcStopOrdinal - 1].offset;
+                    srcStopOrdinal = (srcStopOrdinal + originalNumStops - 1) % originalNumStops;
+                }
             }
-        }
-        
-        // Work forwards from the end, adding stops until we get one after 1.
-        float lastOffset = stops[stops.size() - 1].offset;
-        if (lastOffset < maxExtent) {
-            float currOffset = lastOffset;
-            size_t srcStopOrdinal = 0;
-
-            while (true) {
-                GradientStop newStop = stops[srcStopOrdinal];
-                newStop.offset = currOffset;
-                stops.append(newStop);
-                if (currOffset > maxExtent)
-                    break;
-                if (srcStopOrdinal < originalNumStops - 1)
-                    currOffset += stops[originalFirstStopIndex + srcStopOrdinal + 1].offset - stops[originalFirstStopIndex + srcStopOrdinal].offset;
-                srcStopOrdinal = (srcStopOrdinal + 1) % originalNumStops;
+            
+            // Work forwards from the end, adding stops until we get one after 1.
+            float lastOffset = stops[stops.size() - 1].offset;
+            if (lastOffset < maxExtent) {
+                float currOffset = lastOffset;
+                size_t srcStopOrdinal = 0;
+
+                while (true) {
+                    GradientStop newStop = stops[srcStopOrdinal];
+                    newStop.offset = currOffset;
+                    stops.append(newStop);
+                    if (currOffset > maxExtent)
+                        break;
+                    if (srcStopOrdinal < originalNumStops - 1)
+                        currOffset += stops[originalFirstStopIndex + srcStopOrdinal + 1].offset - stops[originalFirstStopIndex + srcStopOrdinal].offset;
+                    srcStopOrdinal = (srcStopOrdinal + 1) % originalNumStops;
+                }
             }
         }
     }

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list