Diff
Modified: trunk/LayoutTests/ChangeLog (137364 => 137365)
--- trunk/LayoutTests/ChangeLog 2012-12-11 22:51:39 UTC (rev 137364)
+++ trunk/LayoutTests/ChangeLog 2012-12-11 22:56:54 UTC (rev 137365)
@@ -1,3 +1,22 @@
+2012-12-11 Emil A Eklund <[email protected]>
+
+ Clamp out-of-range numbers in CSS
+ https://bugs.webkit.org/show_bug.cgi?id=102735
+
+ Reviewed by Simon Fraser.
+
+ Add test verifying that large numbers are handled correctly
+ (based on fast/sub-pixel/large-sizes.html).
+ Update css/large-number-round-trip and css3/flexbox/flex-algorithm.html
+
+ * css3/flexbox/flex-algorithm.html:
+ * fast/css/large-numbers-expected.txt: Added.
+ * fast/css/large-numbers.html: Copied from LayoutTests/fast/sub-pixel/large-sizes.html.
+ * fast/sub-pixel/large-sizes-expected.txt: Removed.
+ * fast/sub-pixel/large-sizes.html: Removed.
+ * platform/chromium/fast/css/large-number-round-trip-expected.txt:
+ * platform/mac/fast/css/large-number-round-trip-expected.txt:
+
2012-12-11 Adam Klein <[email protected]>
Mark another inspector test as flaky.
Modified: trunk/LayoutTests/css3/flexbox/flex-algorithm.html (137364 => 137365)
--- trunk/LayoutTests/css3/flexbox/flex-algorithm.html 2012-12-11 22:51:39 UTC (rev 137364)
+++ trunk/LayoutTests/css3/flexbox/flex-algorithm.html 2012-12-11 22:56:54 UTC (rev 137365)
@@ -128,9 +128,9 @@
</div>
<div class="flexbox">
- <div data-expected-width="600" style="-webkit-flex: 100000000000000000000000000000000000000 0 600px; -moz-flex: 100000000000000000000000000000000000000 0 600px"></div>
+ <div data-expected-width="0" style="-webkit-flex: 100000000000000000000000000000000000000 0 600px; -moz-flex: 100000000000000000000000000000000000000 0 600px"></div>
<div data-expected-width="600" style="-webkit-flex: 0 100000000000000000000000000000000000000 600px; -moz-flex: 0 100000000000000000000000000000000000000 600px"></div>
- <div data-expected-width="0" style="-webkit-flex: 1 1 100000000000000000000000000000000000000px; -moz-flex: 1 1 100000000000000000000000000000000000000px"></div>
+ <div data-expected-width="33554428" style="-webkit-flex: 1 1 100000000000000000000000000000000000000px; -moz-flex: 1 1 100000000000000000000000000000000000000px"></div>
</div>
<!-- Test flexitem borders. -->
Modified: trunk/LayoutTests/fast/css/large-number-round-trip.html (137364 => 137365)
--- trunk/LayoutTests/fast/css/large-number-round-trip.html 2012-12-11 22:51:39 UTC (rev 137364)
+++ trunk/LayoutTests/fast/css/large-number-round-trip.html 2012-12-11 22:56:54 UTC (rev 137365)
@@ -19,25 +19,35 @@
<script type="text/_javascript_" charset="utf-8">
if (window.testRunner)
testRunner.dumpAsText();
+
+ var output = [];
- var box = document.getElementById('box');
+ function test(value)
+ {
+ var box = document.getElementById('box');
- var testValue = "90010000px";
- box.style.left = testValue;
+ var testValue = value + "px";
+ box.style.left = testValue;
- var leftValue = window.getComputedStyle(box, null).left;
+ var leftValue = window.getComputedStyle(box, null).left;
- box.style.left = "0px";
- box.style.left = leftValue;
- var newLeftValue = window.getComputedStyle(box, null).left;
+ box.style.left = "0px";
+ box.style.left = leftValue;
+ var newLeftValue = window.getComputedStyle(box, null).left;
- var results = document.getElementById('results');
- var result;
- if (leftValue == newLeftValue)
- result = "PASS: read " + testValue + " back as " + leftValue + ", read again as " + newLeftValue;
- else
- result = "FAIL: read " + testValue + " back as " + leftValue + ", read again as " + newLeftValue;
- results.innerHTML = result;
+ var results = document.getElementById('results');
+ var result;
+ if (leftValue == newLeftValue)
+ output.push("PASS: read " + testValue + " back as " + leftValue + ", read again as " + newLeftValue);
+ else
+ output.push("FAIL: read " + testValue + " back as " + leftValue + ", read again as " + newLeftValue);
+ }
+
+ test(90010000);
+ test(-33554430);
+ test(-90010000);
+
+ document.getElementById('results').innerHTML = output.join('<br>');
</script>
</body>
</html>
Added: trunk/LayoutTests/fast/css/large-numbers-expected.txt (0 => 137365)
--- trunk/LayoutTests/fast/css/large-numbers-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/css/large-numbers-expected.txt 2012-12-11 22:56:54 UTC (rev 137365)
@@ -0,0 +1,53 @@
+PASS element.width = 0px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = 1px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = 10px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = 100px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = 10000px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = 100000px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = 1000000px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = 10000000px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = 100000000px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = 1000000000px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = 10000000000px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = 100000000000px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = 1000000000000px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = 0px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = -1px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = -10px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = -100px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = -10000px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = -100000px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = -1000000px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = -10000000px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = -100000000px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = -1000000000px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = -10000000000px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.width = -100000000000px, returns offsetWidth, rect.width and computed width as expected.
+PASS element.left = 0px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = 1px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = 10px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = 100px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = 10000px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = 100000px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = 1000000px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = 10000000px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = 100000000px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = 1000000000px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = 10000000000px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = 100000000000px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = 1000000000000px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = -1px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = -10px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = -100px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = -10000px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = -100000px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = -1000000px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = -10000000px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = -100000000px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = -1000000000px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = -10000000000px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = -100000000000px, returns offsetLeft, rect.left and computed left as expected.
+PASS element.left = -1000000000000px, returns offsetLeft, rect.left and computed left as expected.
+Test handling of numbers outside of the supported range.
+
+Properties may restrict numeric values to some range. If the value is outside the allowed range, the declaration is invalid and must be ignored. As per the CSS3 specification.
Added: trunk/LayoutTests/fast/css/large-numbers.html (0 => 137365)
--- trunk/LayoutTests/fast/css/large-numbers.html (rev 0)
+++ trunk/LayoutTests/fast/css/large-numbers.html 2012-12-11 22:56:54 UTC (rev 137365)
@@ -0,0 +1,115 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src=""
+ <style>
+ .test { position: absolute; width: 50px; left: 25px; }
+ </style>
+ </head>
+ <body>
+ <p>
+ Test handling of numbers outside of the supported range.
+ </p>
+ <p>
+ <q cite="" may restrict numeric values to some range. If the value is outside the allowed range, the declaration is invalid and must be ignored.</q>
+ As per the <a href="" specification</a>.
+ </p>
+ <script>
+ function testSize(width, opt_expectedWidth)
+ {
+ var expectedWidth = typeof opt_expectedWidth == 'number' ? opt_expectedWidth : width;
+
+ el.style.width = width + 'px';
+
+ var style = window.getComputedStyle(el, null);
+ var rect = el.getBoundingClientRect();
+ var computedWidth = Number(style.width.replace('px', ''));
+ if (el.offsetWidth == expectedWidth && rect.width == expectedWidth && computedWidth == expectedWidth)
+ testPassed('element.width = ' + width + 'px, returns offsetWidth, rect.width and computed width as expected.');
+ else
+ testFailed('element.width = ' + width + 'px, returns offsetWidth ' + el.offsetWidth + ', rect.width ' + rect.width + ' and computed width ' + computedWidth + ', expected ' + expectedWidth + '.');
+ }
+
+
+ function testLeft(left, opt_expectedLeft)
+ {
+ var expectedLeft = typeof opt_expectedLeft == 'number' ? opt_expectedLeft : left;
+
+ el.style.left = left + 'px';
+
+ var style = window.getComputedStyle(el, null);
+ var rect = el.getBoundingClientRect();
+ var computedLeft = Number(style.left.replace('px', ''));
+ if (el.offsetLeft == expectedLeft && rect.left == expectedLeft && computedLeft == expectedLeft)
+ testPassed('element.left = ' + left + 'px, returns offsetLeft, rect.left and computed left as expected.');
+ else
+ testFailed('element.left = ' + left + 'px, returns offsetLeft ' + el.offsetLeft + ', rect.left ' + rect.left + ' and computed left ' + computedLeft + ', expected ' + expectedLeft + '.');
+ }
+
+ var el = document.createElement('div');
+ el.className = 'test';
+ document.body.appendChild(el);
+
+ var MAX_VALUE = 33554428;
+ var MIN_VALUE = -33554430;
+
+ // Test setting style.width, negative values are considered invalid.
+ testSize(0);
+ testSize(1);
+ testSize(10);
+ testSize(100);
+ testSize(10000);
+ testSize(100000);
+ testSize(1000000);
+ testSize(10000000);
+ testSize(100000000, MAX_VALUE);
+ testSize(1000000000, MAX_VALUE);
+ testSize(10000000000, MAX_VALUE);
+ testSize(100000000000, MAX_VALUE);
+ testSize(1000000000000, MAX_VALUE);
+
+ testSize(0, 0);
+ testSize(-1, 0);
+ testSize(-10, 0);
+ testSize(-100, 0);
+ testSize(-10000, 0);
+ testSize(-100000, 0);
+ testSize(-1000000, 0);
+ testSize(-10000000, 0);
+ testSize(-100000000, 0);
+ testSize(-1000000000, 0);
+ testSize(-10000000000, 0);
+ testSize(-100000000000, 0);
+
+ // Test setting style.left, negative values are considered valid.
+ testLeft(0);
+ testLeft(1);
+ testLeft(10);
+ testLeft(100);
+ testLeft(10000);
+ testLeft(100000);
+ testLeft(1000000);
+ testLeft(10000000);
+ testLeft(100000000, MAX_VALUE);
+ testLeft(1000000000, MAX_VALUE);
+ testLeft(10000000000, MAX_VALUE);
+ testLeft(100000000000, MAX_VALUE);
+ testLeft(1000000000000, MAX_VALUE);
+
+ testLeft(-1);
+ testLeft(-10);
+ testLeft(-100);
+ testLeft(-10000);
+ testLeft(-100000);
+ testLeft(-1000000);
+ testLeft(-10000000);
+ testLeft(-100000000, MIN_VALUE);
+ testLeft(-1000000000, MIN_VALUE);
+ testLeft(-10000000000, MIN_VALUE);
+ testLeft(-100000000000, MIN_VALUE);
+ testLeft(-1000000000000, MIN_VALUE);
+
+ document.body.removeChild(el);
+ </script>
+ </body>
+</html>
Deleted: trunk/LayoutTests/fast/sub-pixel/large-sizes-expected.txt (137364 => 137365)
--- trunk/LayoutTests/fast/sub-pixel/large-sizes-expected.txt 2012-12-11 22:51:39 UTC (rev 137364)
+++ trunk/LayoutTests/fast/sub-pixel/large-sizes-expected.txt 2012-12-11 22:56:54 UTC (rev 137365)
@@ -1,16 +0,0 @@
-PASS element.width = 5000px, returns offsetWidth, rect.width and computed width as expected.
-PASS element.width = 50000px, returns offsetWidth, rect.width and computed width as expected.
-PASS element.width = 500000px, returns offsetWidth, rect.width and computed width as expected.
-PASS element.width = 5000000px, returns offsetWidth, rect.width and computed width as expected.
-PASS element.width = 50000000px, returns offsetWidth, rect.width and computed width as expected.
-PASS element.width = 33554424px, returns offsetWidth, rect.width and computed width as expected.
-PASS element.width = 33554425px, returns offsetWidth, rect.width and computed width as expected.
-PASS element.width = 33554426px, returns offsetWidth, rect.width and computed width as expected.
-PASS element.width = 33554427px, returns offsetWidth, rect.width and computed width as expected.
-PASS element.width = 33554428px, returns offsetWidth, rect.width and computed width as expected.
-PASS element.width = 33554429px, returns offsetWidth, rect.width and computed width as expected.
-PASS element.width = 33554430px, returns offsetWidth, rect.width and computed width as expected.
-PASS element.width = 33554432px, returns offsetWidth, rect.width and computed width as expected.
-PASS element.width = 35791395px, returns offsetWidth, rect.width and computed width as expected.
-PASS element.width = 35791396px, returns offsetWidth, rect.width and computed width as expected.
-Test handling of sizes exceeding the maximum supported value.
Deleted: trunk/LayoutTests/fast/sub-pixel/large-sizes.html (137364 => 137365)
--- trunk/LayoutTests/fast/sub-pixel/large-sizes.html 2012-12-11 22:51:39 UTC (rev 137364)
+++ trunk/LayoutTests/fast/sub-pixel/large-sizes.html 2012-12-11 22:56:54 UTC (rev 137365)
@@ -1,45 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <script src=""
- </head>
- <body>
- <p>
- Test handling of sizes exceeding the maximum supported value.
- </p>
- <script>
- function testSize(width, expectedWidth, opt_tolerance)
- {
- el.style.width = width + 'px';
- var style = window.getComputedStyle(el, null);
- var rect = el.getBoundingClientRect();
- var tolerance = opt_tolerance || 0;
- if (Math.abs(el.offsetWidth - expectedWidth) <= tolerance && Math.abs(rect.width - expectedWidth) <= tolerance && Math.abs(parseInt(style.width, 10) - expectedWidth) <= tolerance)
- testPassed('element.width = ' + width + 'px, returns offsetWidth, rect.width and computed width as expected.');
- else
- testFailed('element.width = ' + width + 'px, returns offsetWidth ' + el.offsetWidth + ', rect.width ' + rect.width + ' and computed width ' + style.width + ', expected ' + expectedWidth + '.');
- }
-
- var el = document.createElement('div');
- document.body.appendChild(el);
-
- testSize(5000, 5000);
- testSize(50000, 50000);
- testSize(500000, 500000);
- testSize(5000000, 5000000);
- testSize(50000000, 0);
- testSize(33554424, 33554424);
- testSize(33554425, 33554425, 2); // float imprecision
- testSize(33554426, 33554426, 2);
- testSize(33554427, 33554427, 2);
- testSize(33554428, 33554428, 2);
- testSize(33554429, 33554429, 2);
- testSize(33554430, 33554430, 2);
- testSize(33554432, 0);
- testSize(35791395, 0);
- testSize(35791396, 0);
-
- document.body.removeChild(el);
- </script>
- </body>
-</html>
Modified: trunk/LayoutTests/platform/chromium/fast/css/large-number-round-trip-expected.txt (137364 => 137365)
--- trunk/LayoutTests/platform/chromium/fast/css/large-number-round-trip-expected.txt 2012-12-11 22:51:39 UTC (rev 137364)
+++ trunk/LayoutTests/platform/chromium/fast/css/large-number-round-trip-expected.txt 2012-12-11 22:56:54 UTC (rev 137365)
@@ -1 +1,3 @@
-PASS: read 90010000px back as 0px, read again as 0px
+PASS: read 90010000px back as 33554428px, read again as 33554428px
+PASS: read -33554430px back as -33554430px, read again as -33554430px
+PASS: read -90010000px back as -33554430px, read again as -33554430px
Modified: trunk/LayoutTests/platform/mac/fast/css/large-number-round-trip-expected.txt (137364 => 137365)
--- trunk/LayoutTests/platform/mac/fast/css/large-number-round-trip-expected.txt 2012-12-11 22:51:39 UTC (rev 137364)
+++ trunk/LayoutTests/platform/mac/fast/css/large-number-round-trip-expected.txt 2012-12-11 22:56:54 UTC (rev 137365)
@@ -1 +1,3 @@
-PASS: read 90010000px back as 0px, read again as 0px
+PASS: read 90010000px back as 33554428px, read again as 33554428px
+PASS: read -33554430px back as -33554430px, read again as -33554430px
+PASS: read -90010000px back as -33554430px, read again as -33554430px
Modified: trunk/Source/WebCore/ChangeLog (137364 => 137365)
--- trunk/Source/WebCore/ChangeLog 2012-12-11 22:51:39 UTC (rev 137364)
+++ trunk/Source/WebCore/ChangeLog 2012-12-11 22:56:54 UTC (rev 137365)
@@ -1,3 +1,25 @@
+2012-12-11 Emil A Eklund <[email protected]>
+
+ Clamp out-of-range numbers in CSS
+ https://bugs.webkit.org/show_bug.cgi?id=102735
+
+ Reviewed by Simon Fraser.
+
+ Currently when a large number (outside of the supported range)
+ is applied from a style rule or set from _javascript_ using
+ Element.style we check if it is within the supported range and
+ set it to zero if it is not. This is incorrect and confusing.
+
+ Change it to clamp values to the supported range. This matches
+ the behavior in Gecko.
+
+ Test: fast/css/large-numbers.html
+
+ * css/CSSPrimitiveValue.cpp:
+ (WebCore::CSSPrimitiveValue::computeLength):
+ Change to clamp out-of-range values instead of interpreting them
+ as zero.
+
2012-12-11 Nate Chapin <[email protected]>
Ensure ResourceRequests for main resources include fragment indentifiers when necessary,
Modified: trunk/Source/WebCore/css/CSSPrimitiveValue.cpp (137364 => 137365)
--- trunk/Source/WebCore/css/CSSPrimitiveValue.cpp 2012-12-11 22:51:39 UTC (rev 137364)
+++ trunk/Source/WebCore/css/CSSPrimitiveValue.cpp 2012-12-11 22:56:54 UTC (rev 137365)
@@ -32,6 +32,7 @@
#include "Counter.h"
#include "ExceptionCode.h"
#include "Font.h"
+#include "LayoutUnit.h"
#include "Node.h"
#include "Pair.h"
#include "RGBColor.h"
@@ -52,6 +53,11 @@
using namespace WTF;
namespace WebCore {
+
+// Max/min values for CSS, needs to slightly smaller/larger than the true max/min values to allow for rounding without overflowing.
+// Subtract two (rather than one) to allow for values to be converted to float and back without exceeding the LayoutUnit::max.
+const int maxValueForCssLength = INT_MAX / kFixedPointDenominator - 2;
+const int minValueForCssLength = INT_MIN / kFixedPointDenominator + 2;
static inline bool isValidCSSUnitTypeForDoubleConversion(CSSPrimitiveValue::UnitTypes unitType)
{
@@ -479,10 +485,9 @@
template<> Length CSSPrimitiveValue::computeLength(RenderStyle* style, RenderStyle* rootStyle, float multiplier, bool computingFontSize)
{
#if ENABLE(SUBPIXEL_LAYOUT)
- double value = computeLengthDouble(style, rootStyle, multiplier, computingFontSize);
- return Length(static_cast<float>(value > intMaxForLayoutUnit || value < intMinForLayoutUnit ? 0.0 : value), Fixed);
+ return Length(clampTo<float>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize), minValueForCssLength, maxValueForCssLength), Fixed);
#else
- return Length(roundForImpreciseConversion<float>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize)), Fixed);
+ return Length(clampTo<float>(roundForImpreciseConversion<float>(computeLengthDouble(style, rootStyle, multiplier, computingFontSize)), minValueForCssLength, maxValueForCssLength), Fixed);
#endif
}