[CSS Grid Layout] Limit the size of explicit/implicit grid
authorsvillar@igalia.com <svillar@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 11 Nov 2014 16:26:06 +0000 (16:26 +0000)
committersvillar@igalia.com <svillar@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 11 Nov 2014 16:26:06 +0000 (16:26 +0000)
https://bugs.webkit.org/show_bug.cgi?id=136217

Reviewed by Andreas Kling.

Source/WebCore:

A recent change in the specs allow us to set a limit (maximum
size) for both the explicit and implicit grids so we can protect
ourselves from absurdly huge grid specifications. It was decided
to use the recommended limit which is 1 million.

This means that we can remove the old limitation for the number of
repetitions in repeat(). Instead we now clamp the number of
repetitions to the maximum value that allow us to have the maximum
number of whole repetitions without exceeding the track number
limit.

* WebCore.xcodeproj/project.pbxproj:
* css/CSSParser.cpp:
(WebCore::CSSParser::parseGridTrackRepeatFunction): Replaced the
old limit by the new one.
* rendering/RenderGrid.cpp:
(WebCore::RenderGrid::placeItemsOnGrid): Use the amount of tracks
provided by GridResolvedPosition.
(WebCore::RenderGrid::populateExplicitGridAndOrderIterator): Ditto.
* rendering/style/GridCoordinate.h:
(WebCore::GridSpan::GridSpan):
* rendering/style/GridResolvedPosition.cpp:
(WebCore::GridResolvedPosition::explicitGridColumnCount): Bring
the static function back to life.
(WebCore::GridResolvedPosition::explicitGridRowCount): Ditto.
(WebCore::explicitGridSizeForSide):
* rendering/style/GridResolvedPosition.h:

Tools:

Added a new unit test for the CSS parser. Right now it only checks
that we properly clamp the maximum number of tracks on a grid to a
maximum of 1 million.

* TestWebKitAPI/CMakeLists.txt:
* TestWebKitAPI/PlatformEfl.cmake:
* TestWebKitAPI/PlatformGTK.cmake:
* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebCore/CSSParser.cpp: Added.
(TestWebKitAPI::computeNumberOfTracks): Helper function.
(TestWebKitAPI::TEST): Added a
CSSPropertyParserTest.GridTrackLimits test case.

LayoutTests:

Removed as they are now part of the WebCore's CSSParser.cpp unit
test. The reason why it was moved there is because the test would
require huge (~1000000 tracks) grid allocations, making the test
quite slow specially on Debug builds.

* fast/css-grid-layout/grid-element-repeat-max-repetitions-expected.txt: Removed.
* fast/css-grid-layout/grid-element-repeat-max-repetitions.html: Removed.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@175930 268f45cc-cd09-0410-ab3c-d52691b4dbfc

16 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/css-grid-layout/grid-element-repeat-max-repetitions-expected.txt [deleted file]
LayoutTests/fast/css-grid-layout/grid-element-repeat-max-repetitions.html [deleted file]
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/css/CSSParser.cpp
Source/WebCore/rendering/RenderGrid.cpp
Source/WebCore/rendering/style/GridCoordinate.h
Source/WebCore/rendering/style/GridResolvedPosition.cpp
Source/WebCore/rendering/style/GridResolvedPosition.h
Tools/ChangeLog
Tools/TestWebKitAPI/CMakeLists.txt
Tools/TestWebKitAPI/PlatformEfl.cmake
Tools/TestWebKitAPI/PlatformGTK.cmake
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebCore/CSSParser.cpp [new file with mode: 0644]

index a598c5d..f5fb364 100644 (file)
@@ -1,3 +1,18 @@
+2014-10-07  Sergio Villar Senin  <svillar@igalia.com>
+
+        [CSS Grid Layout] Limit the size of explicit/implicit grid
+        https://bugs.webkit.org/show_bug.cgi?id=136217
+
+        Reviewed by Andreas Kling.
+
+        Removed as they are now part of the WebCore's CSSParser.cpp unit
+        test. The reason why it was moved there is because the test would
+        require huge (~1000000 tracks) grid allocations, making the test
+        quite slow specially on Debug builds.
+
+        * fast/css-grid-layout/grid-element-repeat-max-repetitions-expected.txt: Removed.
+        * fast/css-grid-layout/grid-element-repeat-max-repetitions.html: Removed.
+
 2014-11-11  Jinwoo Song  <jinwoo7.song@samsung.com>
 
         [EFL] Unreviewed EFL gardening after r174233.
diff --git a/LayoutTests/fast/css-grid-layout/grid-element-repeat-max-repetitions-expected.txt b/LayoutTests/fast/css-grid-layout/grid-element-repeat-max-repetitions-expected.txt
deleted file mode 100644 (file)
index 3b4e965..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-Test the values greater than the maximum repetitions value are clamped through CSS.
-PASS
-PASS
-PASS
diff --git a/LayoutTests/fast/css-grid-layout/grid-element-repeat-max-repetitions.html b/LayoutTests/fast/css-grid-layout/grid-element-repeat-max-repetitions.html
deleted file mode 100644 (file)
index 52bfe13..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<script>
-if (window.testRunner)
-    testRunner.overridePreference("WebKitCSSGridLayoutEnabled", 1);
-</script>
-<link href="resources/grid.css" rel="stylesheet">
-<style>
-.clampRepetitionsBelowLimit {
-    -webkit-grid-template-rows: repeat(9995, 1px);
-}
-
-.clampRepetitionsOnLimit {
-    -webkit-grid-template-rows: repeat(10000, 1px);
-}
-
-.clampRepetitionsAboveLimit {
-    -webkit-grid-template-rows: repeat(10005, 1px);
-}
-</style>
-<script src="../../resources/check-layout.js"></script>
-</head>
-<body onload="checkLayout('.grid')">
-
-<div>Test the values greater than the maximum repetitions value are clamped through CSS.</div>
-
-<div class="grid clampRepetitionsBelowLimit" data-expected-height="9995"></div>
-
-<div class="grid clampRepetitionsOnLimit" data-expected-height="10000"></div>
-
-<div class="grid clampRepetitionsAboveLimit" data-expected-height="10000"></div>
-
-</body>
-</html>
index 7567640..5059d40 100644 (file)
@@ -1,3 +1,38 @@
+2014-10-07  Sergio Villar Senin  <svillar@igalia.com>
+
+        [CSS Grid Layout] Limit the size of explicit/implicit grid
+        https://bugs.webkit.org/show_bug.cgi?id=136217
+
+        Reviewed by Andreas Kling.
+
+        A recent change in the specs allow us to set a limit (maximum
+        size) for both the explicit and implicit grids so we can protect
+        ourselves from absurdly huge grid specifications. It was decided
+        to use the recommended limit which is 1 million.
+
+        This means that we can remove the old limitation for the number of
+        repetitions in repeat(). Instead we now clamp the number of
+        repetitions to the maximum value that allow us to have the maximum
+        number of whole repetitions without exceeding the track number
+        limit.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::parseGridTrackRepeatFunction): Replaced the
+        old limit by the new one.
+        * rendering/RenderGrid.cpp:
+        (WebCore::RenderGrid::placeItemsOnGrid): Use the amount of tracks
+        provided by GridResolvedPosition.
+        (WebCore::RenderGrid::populateExplicitGridAndOrderIterator): Ditto.
+        * rendering/style/GridCoordinate.h:
+        (WebCore::GridSpan::GridSpan):
+        * rendering/style/GridResolvedPosition.cpp:
+        (WebCore::GridResolvedPosition::explicitGridColumnCount): Bring
+        the static function back to life.
+        (WebCore::GridResolvedPosition::explicitGridRowCount): Ditto.
+        (WebCore::explicitGridSizeForSide):
+        * rendering/style/GridResolvedPosition.h:
+
 2014-11-11  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         CSS4 Selectors: Add multiple pseudo elements support to :matches
index 0d07d53..8894f34 100644 (file)
                499B3ED7128CD31400E726C2 /* GraphicsLayerCA.h in Headers */ = {isa = PBXBuildFile; fileRef = 499B3ED5128CD31400E726C2 /* GraphicsLayerCA.h */; settings = {ATTRIBUTES = (Private, ); }; };
                499B3EDD128DB50200E726C2 /* PlatformCAAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 499B3EDC128DB50100E726C2 /* PlatformCAAnimation.h */; settings = {ATTRIBUTES = (Private, ); }; };
                49AE2D8E134EE50C0072920A /* CSSCalculationValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49AE2D8C134EE50C0072920A /* CSSCalculationValue.cpp */; };
-               49AE2D8F134EE50C0072920A /* CSSCalculationValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 49AE2D8D134EE50C0072920A /* CSSCalculationValue.h */; };
+               49AE2D8F134EE50C0072920A /* CSSCalculationValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 49AE2D8D134EE50C0072920A /* CSSCalculationValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
                49AE2D96134EE5F90072920A /* CalculationValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49AE2D94134EE5F90072920A /* CalculationValue.cpp */; };
                49AE2D97134EE5F90072920A /* CalculationValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 49AE2D95134EE5F90072920A /* CalculationValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
                49AF2D6914435D050016A784 /* DisplayRefreshMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 49AF2D6814435D050016A784 /* DisplayRefreshMonitor.h */; settings = {ATTRIBUTES = (Private, ); }; };
                4B8AF4AA0B1CE02B00687690 /* DataTransferAccessPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B8AF4A90B1CE02B00687690 /* DataTransferAccessPolicy.h */; settings = {ATTRIBUTES = (Private, ); }; };
                4BAE95B10B2FA9CE00AED8A0 /* EditorDeleteAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BAE95B00B2FA9CE00AED8A0 /* EditorDeleteAction.h */; settings = {ATTRIBUTES = (Private, ); }; };
                4E1959210A39DABA00220FE5 /* MediaFeatureNames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E19591F0A39DABA00220FE5 /* MediaFeatureNames.cpp */; };
-               4E1959220A39DABA00220FE5 /* MediaFeatureNames.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E1959200A39DABA00220FE5 /* MediaFeatureNames.h */; };
+               4E1959220A39DABA00220FE5 /* MediaFeatureNames.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E1959200A39DABA00220FE5 /* MediaFeatureNames.h */; settings = {ATTRIBUTES = (Private, ); }; };
                4E1959290A39DACC00220FE5 /* MediaQuery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E1959230A39DACC00220FE5 /* MediaQuery.cpp */; };
-               4E19592A0A39DACC00220FE5 /* MediaQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E1959240A39DACC00220FE5 /* MediaQuery.h */; };
+               4E19592A0A39DACC00220FE5 /* MediaQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E1959240A39DACC00220FE5 /* MediaQuery.h */; settings = {ATTRIBUTES = (Private, ); }; };
                4E19592B0A39DACC00220FE5 /* MediaQueryEvaluator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E1959250A39DACC00220FE5 /* MediaQueryEvaluator.cpp */; };
                4E19592C0A39DACC00220FE5 /* MediaQueryEvaluator.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E1959260A39DACC00220FE5 /* MediaQueryEvaluator.h */; };
                4E19592D0A39DACC00220FE5 /* MediaQueryExp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4E1959270A39DACC00220FE5 /* MediaQueryExp.cpp */; };
-               4E19592E0A39DACC00220FE5 /* MediaQueryExp.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E1959280A39DACC00220FE5 /* MediaQueryExp.h */; };
+               4E19592E0A39DACC00220FE5 /* MediaQueryExp.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E1959280A39DACC00220FE5 /* MediaQueryExp.h */; settings = {ATTRIBUTES = (Private, ); }; };
                4F1534DE11B532EC0021FD86 /* EditingBehavior.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F1534DD11B532EC0021FD86 /* EditingBehavior.h */; settings = {ATTRIBUTES = (Private, ); }; };
                4F1534E011B533020021FD86 /* EditingBehaviorTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 4F1534DF11B533020021FD86 /* EditingBehaviorTypes.h */; settings = {ATTRIBUTES = (Private, ); }; };
                4F6FDD641341DEDD001F8EE3 /* InspectorPageAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4F6FDD621341DEDD001F8EE3 /* InspectorPageAgent.cpp */; };
                536D5A21193E18EE00CE4CAB /* HTMLSrcsetParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 536D5A1E193E18D000CE4CAB /* HTMLSrcsetParser.cpp */; };
                536D5A23193E8E0C00CE4CAB /* ParsingUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 536D5A22193E8E0C00CE4CAB /* ParsingUtilities.h */; };
                536D5A25193F40FC00CE4CAB /* SourceSizeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 536D5A24193F40FC00CE4CAB /* SourceSizeList.cpp */; };
-               536D5A27193F410B00CE4CAB /* SourceSizeList.h in Headers */ = {isa = PBXBuildFile; fileRef = 536D5A26193F410B00CE4CAB /* SourceSizeList.h */; };
+               536D5A27193F410B00CE4CAB /* SourceSizeList.h in Headers */ = {isa = PBXBuildFile; fileRef = 536D5A26193F410B00CE4CAB /* SourceSizeList.h */; settings = {ATTRIBUTES = (Private, ); }; };
                53C8298D13D8D92700DE2DEB /* RenderFlexibleBox.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53C8298B13D8D92700DE2DEB /* RenderFlexibleBox.cpp */; };
                53C8298E13D8D92700DE2DEB /* RenderFlexibleBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 53C8298C13D8D92700DE2DEB /* RenderFlexibleBox.h */; settings = {ATTRIBUTES = (Private, ); }; };
                53E29E5E167A8A1900586D3D /* InternalSettingsGenerated.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53E29E5C167A8A1900586D3D /* InternalSettingsGenerated.cpp */; };
                57CF497514EE36D700ECFF14 /* InsertionPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 57CF497314EE36D700ECFF14 /* InsertionPoint.h */; };
                589556ED18D4A44000764B03 /* BorderEdge.h in Headers */ = {isa = PBXBuildFile; fileRef = 589556EC18D4A44000764B03 /* BorderEdge.h */; };
                58AEE2F418D4BCCF0022E7FE /* BorderEdge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 58AEE2F318D4BCCF0022E7FE /* BorderEdge.cpp */; };
-               58CD35CB18EB4C3900B9F3AC /* FloatSizeHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 58CD35CA18EB4C3900B9F3AC /* FloatSizeHash.h */; };
+               58CD35CB18EB4C3900B9F3AC /* FloatSizeHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 58CD35CA18EB4C3900B9F3AC /* FloatSizeHash.h */; settings = {ATTRIBUTES = (Private, ); }; };
                58DEED8619873FF000888FF3 /* RenderSelectionInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 58DEED8519873FF000888FF3 /* RenderSelectionInfo.cpp */; };
                5905ADBF1302F3CE00F116DF /* XMLTreeViewer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5905ADBD1302F3CE00F116DF /* XMLTreeViewer.cpp */; };
                5905ADC01302F3CE00F116DF /* XMLTreeViewer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5905ADBE1302F3CE00F116DF /* XMLTreeViewer.h */; };
                BC53C5F50DA56B920021EB5D /* Gradient.h in Headers */ = {isa = PBXBuildFile; fileRef = BC53C5F40DA56B920021EB5D /* Gradient.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC53C6080DA56C570021EB5D /* Gradient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC53C6070DA56C570021EB5D /* Gradient.cpp */; };
                BC53C60B0DA56CF10021EB5D /* GradientCG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC53C60A0DA56CF10021EB5D /* GradientCG.cpp */; };
-               BC53C6920DA591140021EB5D /* CSSGradientValue.h in Headers */ = {isa = PBXBuildFile; fileRef = BC53C6910DA591140021EB5D /* CSSGradientValue.h */; };
+               BC53C6920DA591140021EB5D /* CSSGradientValue.h in Headers */ = {isa = PBXBuildFile; fileRef = BC53C6910DA591140021EB5D /* CSSGradientValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC53D911114310CC000D817E /* WebCoreJSClientData.h in Headers */ = {isa = PBXBuildFile; fileRef = BC53D910114310CC000D817E /* WebCoreJSClientData.h */; };
                BC53DA2E1143121E000D817E /* DOMWrapperWorld.h in Headers */ = {isa = PBXBuildFile; fileRef = BC53DA2D1143121E000D817E /* DOMWrapperWorld.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC53DA481143134D000D817E /* DOMWrapperWorld.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC53DA471143134D000D817E /* DOMWrapperWorld.cpp */; };
                BC76AC130DD7AD5C00415F34 /* ParserUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = BC76AC110DD7AD5C00415F34 /* ParserUtilities.h */; };
                BC772B3C0C4EA91E0083285F /* CSSHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = BC772B360C4EA91E0083285F /* CSSHelper.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC772B3D0C4EA91E0083285F /* CSSParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC772B370C4EA91E0083285F /* CSSParser.cpp */; };
-               BC772B3E0C4EA91E0083285F /* CSSParser.h in Headers */ = {isa = PBXBuildFile; fileRef = BC772B380C4EA91E0083285F /* CSSParser.h */; };
+               BC772B3E0C4EA91E0083285F /* CSSParser.h in Headers */ = {isa = PBXBuildFile; fileRef = BC772B380C4EA91E0083285F /* CSSParser.h */; settings = {ATTRIBUTES = (Private, ); }; };
                BC772C460C4EB2C60083285F /* XMLHttpRequest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC772C440C4EB2C60083285F /* XMLHttpRequest.cpp */; };
                BC772C470C4EB2C60083285F /* XMLHttpRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = BC772C450C4EB2C60083285F /* XMLHttpRequest.h */; };
                BC772C4E0C4EB3040083285F /* MIMETypeRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC772C4C0C4EB3040083285F /* MIMETypeRegistry.cpp */; };
index 5a9e94f..6a107b0 100644 (file)
@@ -60,6 +60,7 @@
 #include "Counter.h"
 #include "Document.h"
 #include "FloatConversion.h"
+#include "GridCoordinate.h"
 #include "HTMLParserIdioms.h"
 #include "HashTools.h"
 #include "MediaList.h"
@@ -150,9 +151,6 @@ namespace WebCore {
 
 static const unsigned INVALID_NUM_PARSED_PROPERTIES = UINT_MAX;
 static const double MAX_SCALE = 1000000;
-#if ENABLE(CSS_GRID_LAYOUT)
-static const unsigned MAX_GRID_TRACK_REPETITIONS = 10000;
-#endif
 
 template <unsigned N>
 static bool equal(const CSSParserString& a, const char (&b)[N])
@@ -5268,12 +5266,11 @@ bool CSSParser::parseGridTrackRepeatFunction(CSSValueList& list)
     if (!arguments || arguments->size() < 3 || !validUnit(arguments->valueAt(0), FPositiveInteger) || !isComma(arguments->valueAt(1)))
         return false;
 
-    ASSERT_WITH_SECURITY_IMPLICATION(arguments->valueAt(0)->fValue > 0);
-    size_t repetitions = arguments->valueAt(0)->fValue;
-    // Clamp repetitions at MAX_GRID_TRACK_REPETITIONS.
-    // http://www.w3.org/TR/css-grid-1/#repeat-notation
-    if (repetitions > MAX_GRID_TRACK_REPETITIONS)
-        repetitions = MAX_GRID_TRACK_REPETITIONS;
+    ASSERT(arguments->valueAt(0)->fValue > 0);
+    // If arguments->valueAt(0)->fValue > SIZE_MAX then repetitions becomes 0 during the type casting, that's why we
+    // clamp it down to kGridMaxTracks before the type casting.
+    size_t repetitions = clampTo<size_t>(arguments->valueAt(0)->fValue, 0, kGridMaxTracks);
+
     RefPtr<CSSValueList> repeatedValues = CSSValueList::createSpaceSeparated();
     arguments->next(); // Skip the repetition count.
     arguments->next(); // Skip the comma.
@@ -5283,14 +5280,14 @@ bool CSSParser::parseGridTrackRepeatFunction(CSSValueList& list)
     if (currentValue && currentValue->unit == CSSParserValue::ValueList)
         parseGridLineNames(*arguments, *repeatedValues);
 
-    bool sawTrackSize = false;
+    unsigned numberOfTracks = 0;
     while (arguments->current()) {
         RefPtr<CSSValue> trackSize = parseGridTrackSize(*arguments);
         if (!trackSize)
             return false;
 
         repeatedValues->append(trackSize.releaseNonNull());
-        sawTrackSize = true;
+        ++numberOfTracks;
 
         // This takes care of any trailing <custom-ident>* in the grammar.
         currentValue = arguments->current();
@@ -5299,9 +5296,13 @@ bool CSSParser::parseGridTrackRepeatFunction(CSSValueList& list)
     }
 
     // We should have found at least one <track-size>, otherwise the declaration is invalid.
-    if (!sawTrackSize)
+    if (!numberOfTracks)
         return false;
 
+    // We clamp the number of repetitions to a multiple of the repeat() track list's size, while staying below the max
+    // grid size.
+    repetitions = std::min(repetitions, kGridMaxTracks / numberOfTracks);
+
     for (size_t i = 0; i < repetitions; ++i) {
         for (size_t j = 0; j < repeatedValues->length(); ++j)
             list.append(*repeatedValues->itemWithoutBoundsCheck(j));
index dfdeae2..ee54bc7 100644 (file)
@@ -740,8 +740,8 @@ void RenderGrid::placeItemsOnGrid()
         insertItemIntoGrid(*child, GridCoordinate(*rowPositions, *columnPositions));
     }
 
-    ASSERT(gridRowCount() >= style().gridRows().size());
-    ASSERT(gridColumnCount() >= style().gridColumns().size());
+    ASSERT(gridRowCount() >= GridResolvedPosition::explicitGridRowCount(style()));
+    ASSERT(gridColumnCount() >= GridResolvedPosition::explicitGridColumnCount(style()));
 
     // FIXME: Implement properly "stack" value in auto-placement algorithm.
     if (style().isGridAutoFlowAlgorithmStack()) {
@@ -758,8 +758,8 @@ void RenderGrid::placeItemsOnGrid()
 void RenderGrid::populateExplicitGridAndOrderIterator()
 {
     OrderIteratorPopulator populator(m_orderIterator);
-    size_t maximumRowIndex = std::max<size_t>(1, style().gridRows().size());
-    size_t maximumColumnIndex = std::max<size_t>(1, style().gridColumns().size());
+    size_t maximumRowIndex = std::max<size_t>(1, GridResolvedPosition::explicitGridRowCount(style()));
+    size_t maximumColumnIndex = std::max<size_t>(1, GridResolvedPosition::explicitGridColumnCount(style()));
 
     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
         populator.collectChild(*child);
index 583af5b..92f96e6 100644 (file)
 
 namespace WebCore {
 
+// Recommended maximum size for both explicit and implicit grids.
+const size_t kGridMaxTracks = 1000000;
+
 // A span in a single direction (either rows or columns). Note that |resolvedInitialPosition|
 // and |resolvedFinalPosition| are grid areas' indexes, NOT grid lines'. Iterating over the
 // span should include both |resolvedInitialPosition| and |resolvedFinalPosition| to be correct.
 class GridSpan {
 public:
     GridSpan(const GridResolvedPosition& resolvedInitialPosition, const GridResolvedPosition& resolvedFinalPosition)
-        : resolvedInitialPosition(resolvedInitialPosition)
-        , resolvedFinalPosition(resolvedFinalPosition)
+        : resolvedInitialPosition(std::min(resolvedInitialPosition.toInt(), kGridMaxTracks - 1))
+        , resolvedFinalPosition(std::min(resolvedFinalPosition.toInt(), kGridMaxTracks))
     {
         ASSERT(resolvedInitialPosition <= resolvedFinalPosition);
     }
index 69a8a59..0f362ae 100644 (file)
@@ -48,9 +48,19 @@ static inline bool isStartSide(GridPositionSide side)
     return side == ColumnStartSide || side == RowStartSide;
 }
 
+size_t GridResolvedPosition::explicitGridColumnCount(const RenderStyle& gridContainerStyle)
+{
+    return std::min(gridContainerStyle.gridColumns().size(), kGridMaxTracks);
+}
+
+size_t GridResolvedPosition::explicitGridRowCount(const RenderStyle& gridContainerStyle)
+{
+    return std::min(gridContainerStyle.gridRows().size(), kGridMaxTracks);
+}
+
 static size_t explicitGridSizeForSide(const RenderStyle& gridContainerStyle, GridPositionSide side)
 {
-    return isColumnSide(side) ? gridContainerStyle.gridColumns().size() : gridContainerStyle.gridRows().size();
+    return isColumnSide(side) ? GridResolvedPosition::explicitGridColumnCount(gridContainerStyle) : GridResolvedPosition::explicitGridRowCount(gridContainerStyle);
 }
 
 GridSpan GridResolvedPosition::resolveGridPositionsFromAutoPlacementPosition(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction, const GridResolvedPosition& resolvedInitialPosition)
index 263b524..8fb143f 100644 (file)
@@ -146,6 +146,9 @@ public:
         return GridResolvedPosition(m_integerPosition + 1);
     }
 
+    static size_t explicitGridColumnCount(const RenderStyle&);
+    static size_t explicitGridRowCount(const RenderStyle&);
+
 private:
 
     size_t m_integerPosition;
index 62777a1..770334b 100644 (file)
@@ -1,3 +1,23 @@
+2014-10-07  Sergio Villar Senin  <svillar@igalia.com>
+
+        [CSS Grid Layout] Limit the size of explicit/implicit grid
+        https://bugs.webkit.org/show_bug.cgi?id=136217
+
+        Reviewed by Andreas Kling.
+
+        Added a new unit test for the CSS parser. Right now it only checks
+        that we properly clamp the maximum number of tracks on a grid to a
+        maximum of 1 million.
+
+        * TestWebKitAPI/CMakeLists.txt:
+        * TestWebKitAPI/PlatformEfl.cmake:
+        * TestWebKitAPI/PlatformGTK.cmake:
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebCore/CSSParser.cpp: Added.
+        (TestWebKitAPI::computeNumberOfTracks): Helper function.
+        (TestWebKitAPI::TEST): Added a
+        CSSPropertyParserTest.GridTrackLimits test case.
+
 2014-11-11  Eva Balazsfalvi  <evab.u-szeged@partner.samsung.com>
 
         webkitpy test fix after r175867
index bc5d0be..a30f7f4 100644 (file)
@@ -19,12 +19,17 @@ include_directories(${CMAKE_BINARY_DIR}
     ${JAVASCRIPTCORE_DIR}/parser
     ${JAVASCRIPTCORE_DIR}/runtime
     ${THIRDPARTY_DIR}/gtest/include
+    ${WEBCORE_DIR}/css
+    ${WEBCORE_DIR}/dom
     ${WEBCORE_DIR}/editing
     ${WEBCORE_DIR}/platform
+    ${WEBCORE_DIR}/platform/animation
     ${WEBCORE_DIR}/platform/graphics
     ${WEBCORE_DIR}/platform/text
     ${WEBCORE_DIR}/platform/network
     ${WEBCORE_DIR}/platform/network/soup
+    ${WEBCORE_DIR}/rendering
+    ${WEBCORE_DIR}/rendering/style
     ${WEBKIT2_DIR}/Platform/IPC
     ${WEBKIT2_DIR}/Shared
     ${WEBKIT2_DIR}/Shared/API/c
index 8677ea5..d440686 100644 (file)
@@ -57,6 +57,7 @@ list(APPEND TestJavaScriptCore_LIBRARIES
 # Release builds before adding it to test_{webkit2_api|webcore}_BINARIES.
 
 set(test_webcore_BINARIES
+    CSSParser
     LayoutUnit
     URL
 )
index aa9707a..bd3ad6b 100644 (file)
@@ -108,12 +108,14 @@ set_target_properties(TestWebKit2 PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${TESTWEBK
 
 set(TestWebCoreGtk_SOURCES
     ${TESTWEBKITAPI_DIR}/Tests/WebCore/gtk/UserAgentQuirks.cpp
+    ${DERIVED_SOURCES_WEBCORE_DIR}/UserAgentScriptsData.cpp
 )
 
 add_executable(TestWebCore
     ${test_main_SOURCES}
     ${TestWebCoreGtk_SOURCES}
     ${TESTWEBKITAPI_DIR}/TestsController.cpp
+    ${TESTWEBKITAPI_DIR}/Tests/WebCore/CSSParser.cpp
     ${TESTWEBKITAPI_DIR}/Tests/WebCore/LayoutUnit.cpp
     ${TESTWEBKITAPI_DIR}/Tests/WebCore/URL.cpp
 )
index e180341..65b74ec 100644 (file)
                C95501BF19AD2FAF0049BE3E /* Preferences.mm in Sources */ = {isa = PBXBuildFile; fileRef = C95501BE19AD2FAF0049BE3E /* Preferences.mm */; };
                CD5393C81757BA9700C07123 /* MD5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD5393C71757BA9700C07123 /* MD5.cpp */; };
                CD5393CA1757BAC400C07123 /* SHA1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD5393C91757BAC400C07123 /* SHA1.cpp */; };
+               CD5451EA19E41F9D0016936F /* CSSParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD5451E919E41F9D0016936F /* CSSParser.cpp */; };
                CD5497B415857F0C00B5BC30 /* MediaTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD5497B315857F0C00B5BC30 /* MediaTime.cpp */; };
                CD59F53419E9110D00CF1835 /* file-with-mse.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = CD59F53219E910AA00CF1835 /* file-with-mse.html */; };
                CD59F53519E9110D00CF1835 /* test-mse.mp4 in Copy Resources */ = {isa = PBXBuildFile; fileRef = CD59F53319E910BC00CF1835 /* test-mse.mp4 */; };
                C95501BE19AD2FAF0049BE3E /* Preferences.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Preferences.mm; sourceTree = "<group>"; };
                CD5393C71757BA9700C07123 /* MD5.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MD5.cpp; sourceTree = "<group>"; };
                CD5393C91757BAC400C07123 /* SHA1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SHA1.cpp; sourceTree = "<group>"; };
+               CD5451E919E41F9D0016936F /* CSSParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSParser.cpp; sourceTree = "<group>"; };
                CD5497B315857F0C00B5BC30 /* MediaTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaTime.cpp; sourceTree = "<group>"; };
                CD59F53219E910AA00CF1835 /* file-with-mse.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "file-with-mse.html"; sourceTree = "<group>"; };
                CD59F53319E910BC00CF1835 /* test-mse.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "test-mse.mp4"; sourceTree = "<group>"; };
                440A1D3614A01000008A66F2 /* WebCore */ = {
                        isa = PBXGroup;
                        children = (
+                               CD5451E919E41F9D0016936F /* CSSParser.cpp */,
                                93A720E518F1A0E800A848E1 /* CalculationValue.cpp */,
                                CDC2C7141797089D00E627FB /* TimeRanges.cpp */,
                                440A1D3814A0103A008A66F2 /* URL.cpp */,
                                1A7BFC0C171A0BDB00BC5F64 /* WillSendSubmitEvent.mm in Sources */,
                                BC22D31514DC689800FFB1DD /* UserMessage.cpp in Sources */,
                                BC55F5F914AD78EE00484BE1 /* Vector.cpp in Sources */,
+                               CD5451EA19E41F9D0016936F /* CSSParser.cpp in Sources */,
                                290A9BB71735DE8A00D71BBC /* CloseNewWindowInNavigationPolicyDelegate.mm in Sources */,
                                FE217ECD1640A54A0052988B /* VMInspector.cpp in Sources */,
                                520BCF4D141EB09E00937EA8 /* WebArchive.cpp in Sources */,
diff --git a/Tools/TestWebKitAPI/Tests/WebCore/CSSParser.cpp b/Tools/TestWebKitAPI/Tests/WebCore/CSSParser.cpp
new file mode 100644 (file)
index 0000000..6f22d77
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2014 Igalia, S.L. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <WebCore/CSSParser.h>
+#include <WebCore/CSSValueList.h>
+#include <WebCore/StyleProperties.h>
+
+namespace TestWebKitAPI {
+
+using namespace WebCore;
+
+#if ENABLE(CSS_GRID_LAYOUT)
+static unsigned computeNumberOfTracks(CSSValueList& valueList)
+{
+    unsigned numberOfTracks = 0;
+    for (const auto& value : valueList) {
+        if (value->isGridLineNamesValue())
+            continue;
+        ++numberOfTracks;
+    }
+    return numberOfTracks;
+}
+#endif
+
+TEST(CSSPropertyParserTest, GridTrackLimits)
+{
+#if ENABLE(CSS_GRID_LAYOUT)
+    struct {
+        const CSSPropertyID propertyID;
+        const char* input;
+        const size_t output;
+    } testCases[] = {
+        {CSSPropertyWebkitGridTemplateColumns, "-webkit-grid-template-columns: repeat(999999, 20px);", 999999},
+        {CSSPropertyWebkitGridTemplateRows, "-webkit-grid-template-rows: repeat(999999, 20px);", 999999},
+        {CSSPropertyWebkitGridTemplateColumns, "-webkit-grid-template-columns: repeat(1000000, 10%);", 1000000},
+        {CSSPropertyWebkitGridTemplateRows, "-webkit-grid-template-rows: repeat(1000000, 10%);", 1000000},
+        {CSSPropertyWebkitGridTemplateColumns, "-webkit-grid-template-columns: repeat(1000000, (first) -webkit-min-content (last));", 1000000},
+        {CSSPropertyWebkitGridTemplateRows, "-webkit-grid-template-rows: repeat(1000000, (first) -webkit-min-content (last));", 1000000},
+        {CSSPropertyWebkitGridTemplateColumns, "-webkit-grid-template-columns: repeat(1000001, auto);", 1000000},
+        {CSSPropertyWebkitGridTemplateRows, "-webkit-grid-template-rows: repeat(1000001, auto);", 1000000},
+        {CSSPropertyWebkitGridTemplateColumns, "-webkit-grid-template-columns: repeat(400000, 2em minmax(10px, -webkit-max-content) 0.5fr);", 999999},
+        {CSSPropertyWebkitGridTemplateRows, "-webkit-grid-template-rows: repeat(400000, 2em minmax(10px, -webkit-max-content) 0.5fr);", 999999},
+        {CSSPropertyWebkitGridTemplateColumns, "-webkit-grid-template-columns: repeat(600000, (first) 3vh 10% 2fr (nav) 10px auto 1fr 6em (last));", 999999},
+        {CSSPropertyWebkitGridTemplateRows, "-webkit-grid-template-rows: repeat(600000, (first) 3vh 10% 2fr (nav) 10px auto 1fr 6em (last));", 999999},
+        {CSSPropertyWebkitGridTemplateColumns, "-webkit-grid-template-columns: repeat(100000000000000000000, 10% 1fr);", 1000000},
+        {CSSPropertyWebkitGridTemplateRows, "-webkit-grid-template-rows: repeat(100000000000000000000, 10% 1fr);", 1000000},
+        {CSSPropertyWebkitGridTemplateColumns, "-webkit-grid-template-columns: repeat(100000000000000000000, 10% 5em 1fr auto auto 15px -webkit-min-content);", 999999},
+        {CSSPropertyWebkitGridTemplateRows, "-webkit-grid-template-rows: repeat(100000000000000000000, 10% 5em 1fr auto auto 15px -webkit-min-content);", 999999},
+    };
+
+    CSSParser parser(strictCSSParserContext());
+    RefPtr<MutableStyleProperties> properties = MutableStyleProperties::create();
+
+    for (auto& testCase : testCases) {
+        ASSERT_TRUE(parser.parseDeclaration(properties.get(), testCase.input, nullptr, nullptr));
+        RefPtr<CSSValue> value = properties->getPropertyCSSValue(testCase.propertyID);
+
+        ASSERT_TRUE(value->isValueList());
+        EXPECT_EQ(computeNumberOfTracks(*downcast<CSSValueList>(value.get())), testCase.output);
+    }
+#endif // ENABLE(CSS_GRID_LAYOUT)
+}
+
+} // namespace TestWebKitAPI