Align colspan/rowspan limits with the latest HTML specification
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 28 Apr 2017 01:53:56 +0000 (01:53 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 28 Apr 2017 01:53:56 +0000 (01:53 +0000)
https://bugs.webkit.org/show_bug.cgi?id=171322

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Re-sync some web-platform-tests from upstream to gain test coverage and
rebaseline.

* resources/import-expectations.json:
* web-platform-tests/html/dom/elements-tabular.js:
* web-platform-tests/html/dom/reflection-embedded-expected.txt:
* web-platform-tests/html/dom/reflection-tabular-expected.txt:
* web-platform-tests/html/dom/reflection.js:
(ReflectionTests.typeMap.string_appeared_here.toString):
(ReflectionTests.typeMap.string_appeared_here.valueOf):
(ReflectionTests.reflects):
* web-platform-tests/html/semantics/tabular-data/attributes-common-to-td-and-th-elements/w3c-import.log:
* web-platform-tests/html/semantics/tabular-data/processing-model-1/span-limits-expected.txt: Added.
* web-platform-tests/html/semantics/tabular-data/processing-model-1/span-limits.html: Added.
* web-platform-tests/html/semantics/tabular-data/processing-model-1/w3c-import.log:
* web-platform-tests/html/semantics/tabular-data/the-caption-element/w3c-import.log:
* web-platform-tests/html/semantics/tabular-data/the-table-element/w3c-import.log:
* web-platform-tests/html/semantics/tabular-data/the-tbody-element/w3c-import.log:
* web-platform-tests/html/semantics/tabular-data/the-tfoot-element/w3c-import.log:
* web-platform-tests/html/semantics/tabular-data/the-thead-element/w3c-import.log:
* web-platform-tests/html/semantics/tabular-data/the-tr-element/w3c-import.log:
* web-platform-tests/html/semantics/tabular-data/w3c-import.log:

Source/WebCore:

Align colspan/rowspan limits with the latest HTML specification after:
- https://github.com/whatwg/html/pull/1993

The following changes were made:
- Our rowspan limit was raised from 8190 to 65534
- A colspan limit of 1000 was introduced. Blink has UseCounter data showing that
  colspans over 1000 are extremely rare and Gecko has data showing that when we
  get a colspan greater than 1000, it is usually a bug. Therefore, this change
  should be fine.
- The limits are now properly reflected via the IDL attributes instead of lying
  to the Web about the colspan / rowspan we are using internally.

Test: imported/w3c/web-platform-tests/html/semantics/tabular-data/processing-model-1/span-limits.html

* html/HTMLTableCellElement.cpp:
(WebCore::HTMLTableCellElement::colSpan):
(WebCore::HTMLTableCellElement::rowSpan):
(WebCore::HTMLTableCellElement::rowSpanForBindings):
(WebCore::HTMLTableCellElement::setColSpan):
* html/HTMLTableCellElement.h:
* html/HTMLTableCellElement.idl:
* html/parser/HTMLParserIdioms.cpp:
(WebCore::parseHTMLIntegerInternal):
(WebCore::parseHTMLInteger):
(WebCore::parseHTMLNonNegativeInteger):
(WebCore::parseValidHTMLNonNegativeIntegerInternal):
(WebCore::parseHTTPRefreshInternal):
* html/parser/HTMLParserIdioms.h:
(WebCore::parseHTMLInteger):
(WebCore::parseHTMLNonNegativeInteger):

(WebCore::clampHTMLNonNegativeIntegerToRange):
Add utility function to implement:
- https://html.spec.whatwg.org/#clamped-to-the-range

Source/WebKit/mac:

ObjC bindings build fix.

* DOM/DOMHTMLTableCellElement.mm:
(-[DOMHTMLTableCellElement colSpan]):
(-[DOMHTMLTableCellElement setColSpan:]):

Source/WebKit2:

GTK build fix.

* WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLTableCellElement.cpp:
(webkit_dom_html_table_cell_element_get_col_span):
(webkit_dom_html_table_cell_element_set_col_span):

LayoutTests:

Rebaseline a couple of rowspan tests now that our max limit has changed.

* fast/table/giantRowspan2-expected.txt:
* platform/ios/fast/table/giantRowspan-expected.txt:
* platform/ios/imported/w3c/web-platform-tests/html/dom/reflection-embedded-expected.txt:
* platform/mac/fast/table/giantRowspan-expected.txt:

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

41 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/table/giantRowspan2-expected.txt
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/resources/import-expectations.json
LayoutTests/imported/w3c/web-platform-tests/html/dom/elements-tabular.js
LayoutTests/imported/w3c/web-platform-tests/html/dom/reflection-embedded-expected.txt
LayoutTests/imported/w3c/web-platform-tests/html/dom/reflection-tabular-expected.txt
LayoutTests/imported/w3c/web-platform-tests/html/dom/reflection.js
LayoutTests/imported/w3c/web-platform-tests/html/semantics/tabular-data/attributes-common-to-td-and-th-elements/w3c-import.log
LayoutTests/imported/w3c/web-platform-tests/html/semantics/tabular-data/processing-model-1/span-limits-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/html/semantics/tabular-data/processing-model-1/span-limits.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/html/semantics/tabular-data/processing-model-1/w3c-import.log
LayoutTests/imported/w3c/web-platform-tests/html/semantics/tabular-data/the-caption-element/w3c-import.log
LayoutTests/imported/w3c/web-platform-tests/html/semantics/tabular-data/the-table-element/w3c-import.log
LayoutTests/imported/w3c/web-platform-tests/html/semantics/tabular-data/the-tbody-element/w3c-import.log
LayoutTests/imported/w3c/web-platform-tests/html/semantics/tabular-data/the-tfoot-element/w3c-import.log
LayoutTests/imported/w3c/web-platform-tests/html/semantics/tabular-data/the-thead-element/w3c-import.log
LayoutTests/imported/w3c/web-platform-tests/html/semantics/tabular-data/the-tr-element/w3c-import.log
LayoutTests/imported/w3c/web-platform-tests/html/semantics/tabular-data/w3c-import.log
LayoutTests/platform/ios/fast/table/giantRowspan-expected.txt
LayoutTests/platform/ios/imported/w3c/web-platform-tests/html/dom/reflection-embedded-expected.txt
LayoutTests/platform/mac/fast/table/giantRowspan-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/dom/Element.cpp
Source/WebCore/html/HTMLElement.cpp
Source/WebCore/html/HTMLImageElement.cpp
Source/WebCore/html/HTMLInputElement.cpp
Source/WebCore/html/HTMLOListElement.cpp
Source/WebCore/html/HTMLTableCellElement.cpp
Source/WebCore/html/HTMLTableCellElement.h
Source/WebCore/html/HTMLTableCellElement.idl
Source/WebCore/html/HTMLTextAreaElement.cpp
Source/WebCore/html/ImageInputType.cpp
Source/WebCore/html/parser/HTMLParserIdioms.cpp
Source/WebCore/html/parser/HTMLParserIdioms.h
Source/WebCore/svg/SVGElement.cpp
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/DOM/DOMHTMLTableCellElement.mm
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLTableCellElement.cpp
Tools/TestWebKitAPI/Tests/WebCore/HTMLParserIdioms.cpp

index 1cd03ac..a0f43d8 100644 (file)
@@ -1,3 +1,17 @@
+2017-04-27  Chris Dumez  <cdumez@apple.com>
+
+        Align colspan/rowspan limits with the latest HTML specification
+        https://bugs.webkit.org/show_bug.cgi?id=171322
+
+        Reviewed by Darin Adler.
+
+        Rebaseline a couple of rowspan tests now that our max limit has changed.
+
+        * fast/table/giantRowspan2-expected.txt:
+        * platform/ios/fast/table/giantRowspan-expected.txt:
+        * platform/ios/imported/w3c/web-platform-tests/html/dom/reflection-embedded-expected.txt:
+        * platform/mac/fast/table/giantRowspan-expected.txt:
+
 2017-04-27  Matt Lewis  <jlewis3@apple.com>
 
         Mark fast/mediacapturefromelement/CanvasCaptureMediaStream-2d-events.html as a flaky failure.
index 8401705..b414e0a 100644 (file)
@@ -6,7 +6,7 @@ layer at (0,0) size 800x600
       RenderTable {TABLE} at (0,0) size 784x78
         RenderTableSection {TBODY} at (0,0) size 784x78
           RenderTableRow {TR} at (0,2) size 784x74
-            RenderTableCell {TD} at (2,2) size 780x74 [r=0 c=0 rs=8190 cs=1]
+            RenderTableCell {TD} at (2,2) size 780x74 [r=0 c=0 rs=65534 cs=1]
               RenderText {#text} at (1,1) size 771x72
                 text run at (1,1) width 687: "This test succeeds if it does not crash. We implemented a heuristic a while back to prevent giant rowspans. "
                 text run at (687,1) width 85: "The heuristic"
index 15db352..db59aad 100644 (file)
@@ -1,5 +1,35 @@
 2017-04-27  Chris Dumez  <cdumez@apple.com>
 
+        Align colspan/rowspan limits with the latest HTML specification
+        https://bugs.webkit.org/show_bug.cgi?id=171322
+
+        Reviewed by Darin Adler.
+
+        Re-sync some web-platform-tests from upstream to gain test coverage and
+        rebaseline.
+
+        * resources/import-expectations.json:
+        * web-platform-tests/html/dom/elements-tabular.js:
+        * web-platform-tests/html/dom/reflection-embedded-expected.txt:
+        * web-platform-tests/html/dom/reflection-tabular-expected.txt:
+        * web-platform-tests/html/dom/reflection.js:
+        (ReflectionTests.typeMap.string_appeared_here.toString):
+        (ReflectionTests.typeMap.string_appeared_here.valueOf):
+        (ReflectionTests.reflects):
+        * web-platform-tests/html/semantics/tabular-data/attributes-common-to-td-and-th-elements/w3c-import.log:
+        * web-platform-tests/html/semantics/tabular-data/processing-model-1/span-limits-expected.txt: Added.
+        * web-platform-tests/html/semantics/tabular-data/processing-model-1/span-limits.html: Added.
+        * web-platform-tests/html/semantics/tabular-data/processing-model-1/w3c-import.log:
+        * web-platform-tests/html/semantics/tabular-data/the-caption-element/w3c-import.log:
+        * web-platform-tests/html/semantics/tabular-data/the-table-element/w3c-import.log:
+        * web-platform-tests/html/semantics/tabular-data/the-tbody-element/w3c-import.log:
+        * web-platform-tests/html/semantics/tabular-data/the-tfoot-element/w3c-import.log:
+        * web-platform-tests/html/semantics/tabular-data/the-thead-element/w3c-import.log:
+        * web-platform-tests/html/semantics/tabular-data/the-tr-element/w3c-import.log:
+        * web-platform-tests/html/semantics/tabular-data/w3c-import.log:
+
+2017-04-27  Chris Dumez  <cdumez@apple.com>
+
         Element.getBoundingClientRect() / getClientRects() should return a DOMRect types
         https://bugs.webkit.org/show_bug.cgi?id=171226
 
index 95eb5b7..61f25be 100644 (file)
     "web-platform-tests/html/semantics/scripting-1/the-script-element/module": "skip", 
     "web-platform-tests/html/semantics/scripting-1/the-script-element/script-for-event.xhtml": "skip", 
     "web-platform-tests/html/semantics/scripting-1/the-script-element/script-text.xhtml": "skip", 
+    "web-platform-tests/html/semantics/tabular-data": "import", 
     "web-platform-tests/html/semantics/text-level-semantics/the-data-element": "skip", 
     "web-platform-tests/html/syntax": "import", 
     "web-platform-tests/html/the-xhtml-syntax": "skip", 
index bb54ade..ee66f7a 100644 (file)
@@ -68,8 +68,8 @@ var tabularElements = {
   },
   td: {
     // HTMLTableCellElement (Conforming)
-    colSpan: {type: "unsigned long", defaultVal: 1},
-    rowSpan: {type: "unsigned long", defaultVal: 1},
+    colSpan: {type: "clamped unsigned long", defaultVal: 1, min: 1, max: 1000},
+    rowSpan: {type: "clamped unsigned long", defaultVal: 1, min: 0, max: 65534},
     headers: "settable tokenlist",
     scope: {type: "enum", keywords: ["row", "col", "rowgroup", "colgroup"]},
     abbr: "string",
@@ -87,8 +87,8 @@ var tabularElements = {
   },
   th: {
     // HTMLTableCellElement (Conforming)
-    colSpan: {type: "unsigned long", defaultVal: 1},
-    rowSpan: {type: "unsigned long", defaultVal: 1},
+    colSpan: {type: "clamped unsigned long", defaultVal: 1, min: 1, max: 1000},
+    rowSpan: {type: "clamped unsigned long", defaultVal: 1, min: 0, max: 65534},
     headers: "settable tokenlist",
     scope: {type: "enum", keywords: ["row", "col", "rowgroup", "colgroup"]},
     abbr: "string",
index 3033d69..b4fcc36 100644 (file)
@@ -6,19 +6,19 @@ Blocked access to external URL http://site.example/
 Blocked access to external URL http://site.example/path???@#l
 Blocked access to external URL http://site.example/
 Blocked access to external URL http://site.example/path???@#l
-CONSOLE MESSAGE: line 707: The language contains a null character and is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language 'undefined' is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language '7' is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language '1.5' is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language 'true' is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language 'false' is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language '[object Object]' is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language 'Infinity' is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language '-Infinity' is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language contains a null character and is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language 'null' is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language 'test-toString' is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language 'test-valueOf' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language contains a null character and is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language 'undefined' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language '7' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language '1.5' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language 'true' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language 'false' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language '[object Object]' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language 'Infinity' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language '-Infinity' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language contains a null character and is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language 'null' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language 'test-toString' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language 'test-valueOf' is not a valid BCP 47 language tag.
 CONSOLE MESSAGE: line 1406: The language contains a null character and is not a valid BCP 47 language tag.
 CONSOLE MESSAGE: line 1406: The language 'undefined' is not a valid BCP 47 language tag.
 CONSOLE MESSAGE: line 1406: The language '7' is not a valid BCP 47 language tag.
index 01af8b7..8c6bdac 100644 (file)
@@ -3534,7 +3534,6 @@ PASS td.colSpan: setAttribute() to -36
 PASS td.colSpan: setAttribute() to -1 
 PASS td.colSpan: setAttribute() to 0 
 PASS td.colSpan: setAttribute() to 1 
-PASS td.colSpan: setAttribute() to 257 
 PASS td.colSpan: setAttribute() to 2147483647 
 PASS td.colSpan: setAttribute() to 2147483648 
 PASS td.colSpan: setAttribute() to 4294967295 
@@ -3581,6 +3580,8 @@ PASS td.colSpan: setAttribute() to -Infinity
 PASS td.colSpan: setAttribute() to "\0" 
 PASS td.colSpan: setAttribute() to object "2" 
 PASS td.colSpan: setAttribute() to object "3" 
+PASS td.colSpan: setAttribute() to 1000 
+PASS td.colSpan: setAttribute() to 1001 
 PASS td.colSpan: IDL set to 0 
 PASS td.colSpan: IDL set to 1 
 PASS td.colSpan: IDL set to 257 
@@ -3588,6 +3589,8 @@ PASS td.colSpan: IDL set to 2147483647
 PASS td.colSpan: IDL set to "-0" 
 PASS td.colSpan: IDL set to 2147483648 
 PASS td.colSpan: IDL set to 4294967295 
+PASS td.colSpan: IDL set to 1000 
+PASS td.colSpan: IDL set to 1001 
 PASS td.rowSpan: typeof IDL attribute 
 PASS td.rowSpan: IDL get with DOM attribute unset 
 PASS td.rowSpan: setAttribute() to -2147483649 
@@ -3596,7 +3599,6 @@ PASS td.rowSpan: setAttribute() to -36
 PASS td.rowSpan: setAttribute() to -1 
 PASS td.rowSpan: setAttribute() to 0 
 PASS td.rowSpan: setAttribute() to 1 
-PASS td.rowSpan: setAttribute() to 257 
 PASS td.rowSpan: setAttribute() to 2147483647 
 PASS td.rowSpan: setAttribute() to 2147483648 
 PASS td.rowSpan: setAttribute() to 4294967295 
@@ -3643,6 +3645,8 @@ PASS td.rowSpan: setAttribute() to -Infinity
 PASS td.rowSpan: setAttribute() to "\0" 
 PASS td.rowSpan: setAttribute() to object "2" 
 PASS td.rowSpan: setAttribute() to object "3" 
+PASS td.rowSpan: setAttribute() to 65534 
+PASS td.rowSpan: setAttribute() to 65535 
 PASS td.rowSpan: IDL set to 0 
 PASS td.rowSpan: IDL set to 1 
 PASS td.rowSpan: IDL set to 257 
@@ -3650,6 +3654,8 @@ PASS td.rowSpan: IDL set to 2147483647
 PASS td.rowSpan: IDL set to "-0" 
 PASS td.rowSpan: IDL set to 2147483648 
 PASS td.rowSpan: IDL set to 4294967295 
+PASS td.rowSpan: IDL set to 65534 
+PASS td.rowSpan: IDL set to 65535 
 PASS td.scope: typeof IDL attribute 
 PASS td.scope: IDL get with DOM attribute unset 
 PASS td.scope: setAttribute() to "" 
@@ -4298,7 +4304,6 @@ PASS th.colSpan: setAttribute() to -36
 PASS th.colSpan: setAttribute() to -1 
 PASS th.colSpan: setAttribute() to 0 
 PASS th.colSpan: setAttribute() to 1 
-PASS th.colSpan: setAttribute() to 257 
 PASS th.colSpan: setAttribute() to 2147483647 
 PASS th.colSpan: setAttribute() to 2147483648 
 PASS th.colSpan: setAttribute() to 4294967295 
@@ -4345,6 +4350,8 @@ PASS th.colSpan: setAttribute() to -Infinity
 PASS th.colSpan: setAttribute() to "\0" 
 PASS th.colSpan: setAttribute() to object "2" 
 PASS th.colSpan: setAttribute() to object "3" 
+PASS th.colSpan: setAttribute() to 1000 
+PASS th.colSpan: setAttribute() to 1001 
 PASS th.colSpan: IDL set to 0 
 PASS th.colSpan: IDL set to 1 
 PASS th.colSpan: IDL set to 257 
@@ -4352,6 +4359,8 @@ PASS th.colSpan: IDL set to 2147483647
 PASS th.colSpan: IDL set to "-0" 
 PASS th.colSpan: IDL set to 2147483648 
 PASS th.colSpan: IDL set to 4294967295 
+PASS th.colSpan: IDL set to 1000 
+PASS th.colSpan: IDL set to 1001 
 PASS th.rowSpan: typeof IDL attribute 
 PASS th.rowSpan: IDL get with DOM attribute unset 
 PASS th.rowSpan: setAttribute() to -2147483649 
@@ -4360,7 +4369,6 @@ PASS th.rowSpan: setAttribute() to -36
 PASS th.rowSpan: setAttribute() to -1 
 PASS th.rowSpan: setAttribute() to 0 
 PASS th.rowSpan: setAttribute() to 1 
-PASS th.rowSpan: setAttribute() to 257 
 PASS th.rowSpan: setAttribute() to 2147483647 
 PASS th.rowSpan: setAttribute() to 2147483648 
 PASS th.rowSpan: setAttribute() to 4294967295 
@@ -4407,6 +4415,8 @@ PASS th.rowSpan: setAttribute() to -Infinity
 PASS th.rowSpan: setAttribute() to "\0" 
 PASS th.rowSpan: setAttribute() to object "2" 
 PASS th.rowSpan: setAttribute() to object "3" 
+PASS th.rowSpan: setAttribute() to 65534 
+PASS th.rowSpan: setAttribute() to 65535 
 PASS th.rowSpan: IDL set to 0 
 PASS th.rowSpan: IDL set to 1 
 PASS th.rowSpan: IDL set to 257 
@@ -4414,6 +4424,8 @@ PASS th.rowSpan: IDL set to 2147483647
 PASS th.rowSpan: IDL set to "-0" 
 PASS th.rowSpan: IDL set to 2147483648 
 PASS th.rowSpan: IDL set to 4294967295 
+PASS th.rowSpan: IDL set to 65534 
+PASS th.rowSpan: IDL set to 65535 
 PASS th.scope: typeof IDL attribute 
 PASS th.scope: IDL get with DOM attribute unset 
 PASS th.scope: setAttribute() to "" 
index e3ff415..b50e99b 100644 (file)
@@ -455,6 +455,37 @@ ReflectionTests.typeMap = {
             "idlDomExpected": [null, 1, maxInt, null, null]
     },
     /**
+     * "If a reflecting IDL attribute has an unsigned integer type (unsigned
+     * long) that is clamped to the range [min, max], then on getting, the
+     * content attribute must first be parsed according to the rules for
+     * parsing non-negative integers, and if that is successful, and the value
+     * is between min and max inclusive, the resulting value must be returned.
+     * If it fails, the default value must be returned. If it succeeds but the
+     * value is less than min, min must be returned. If it succeeds but the
+     * value is greater than max, max must be returned. On setting, it behaves
+     * the same as a regular reflected unsigned integer."
+     *
+     * The data object passed to reflects must contain the keys defaultVal,
+     * min, and max.  As with enum, domExpected is generated later once we have
+     * access to the min and max.
+     */
+    "clamped unsigned long": {
+        "jsType": "number",
+        "domTests": [minInt - 1, minInt, -36,  -1,   0,    1, maxInt,
+                     maxInt + 1, maxUnsigned, maxUnsigned + 1, "", "-1", "-0", "0", "1",
+                     "\u00097", "\u000B7", "\u000C7", "\u00207", "\u00A07", "\uFEFF7",
+                     "\u000A7", "\u000D7", "\u20287", "\u20297", "\u16807", "\u180E7",
+                     "\u20007", "\u20017", "\u20027", "\u20037", "\u20047", "\u20057",
+                     "\u20067", "\u20077", "\u20087", "\u20097", "\u200A7", "\u202F7",
+                     "\u30007",
+                     " " + binaryString + " foo ", undefined, 1.5, true, false,
+                     {"test": 6}, NaN, +Infinity, -Infinity, "\0",
+                     {toString:function() {return 2;}, valueOf: null},
+                     {valueOf:function() {return 3;}}],
+        "idlTests": [0, 1, 257, maxInt, "-0", maxInt + 1, maxUnsigned],
+        "idlDomExpected": [0, 1, 257, maxInt, 0, null, null],
+    },
+    /**
      * "If a reflecting IDL attribute is a floating point number type (double),
      * then, on getting, the content attribute must be parsed according to the
      * rules for parsing floating point number values, and if that is
@@ -681,6 +712,54 @@ ReflectionTests.reflects = function(data, idlName, idlObj, domName, domObj) {
             }
         }
         break;
+
+        case "clamped unsigned long":
+        [data.min - 1, data.min, data.max, data.max + 1].forEach(function(val) {
+          if (domTests.indexOf(val) == -1) {
+            domTests.push(val);
+          }
+          if (idlTests.indexOf(val) == -1 && 0 <= val && val <= maxUnsigned) {
+            idlTests.push(val);
+            if (typeof val != "number") {
+              val = ReflectionTests.parseNonneg(val);
+            }
+            idlDomExpected.push(val > maxInt ? null : val);
+          }
+        });
+
+        // Rewrite expected values
+        domExpected = domTests.map(function(val) {
+            var parsed = ReflectionTests.parseNonneg(String(val));
+            if (parsed === false) {
+                return defaultVal;
+            }
+            if (parsed < data.min) {
+              return data.min;
+            }
+            if (parsed > data.max) {
+              return data.max;
+            }
+            return parsed;
+        });
+        idlIdlExpected = idlTests.map(function(val) {
+            if (typeof val != "number") {
+              val = ReflectionTests.parseNonneg(val);
+            }
+            if (val < 0 || val > maxUnsigned) {
+              throw "Test bug: val should be an unsigned long";
+            }
+            if (val > maxInt) {
+              return defaultVal;
+            }
+            if (val < data.min) {
+              return data.min;
+            }
+            if (val > data.max) {
+              return data.max;
+            }
+            return val;
+        });
+        break;
     }
     if (domObj.tagName.toLowerCase() == "canvas" && (domName == "width" || domName == "height")) {
         // Opera tries to allocate a canvas with the given width and height, so
index 3224f00..fceeff6 100644 (file)
@@ -1,7 +1,6 @@
 The tests in this directory were imported from the W3C repository.
 Do NOT modify these tests directly in WebKit.
-Instead, create a pull request on the W3C CSS or WPT github:
-       https://github.com/w3c/csswg-test
+Instead, create a pull request on the WPT github:
        https://github.com/w3c/web-platform-tests
 
 Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport
diff --git a/LayoutTests/imported/w3c/web-platform-tests/html/semantics/tabular-data/processing-model-1/span-limits-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/html/semantics/tabular-data/processing-model-1/span-limits-expected.txt
new file mode 100644 (file)
index 0000000..8e4ef1e
--- /dev/null
@@ -0,0 +1,12 @@
+
+PASS colspan of 1000 must work 
+PASS colspan of 1001 must be treated as 1000 
+PASS rowspan of 65534 must work 
+PASS rowspan of 65535 must be treated as 65534 
+a      a
+a
+a      a
+a
+a      
+a      
+a      
diff --git a/LayoutTests/imported/w3c/web-platform-tests/html/semantics/tabular-data/processing-model-1/span-limits.html b/LayoutTests/imported/w3c/web-platform-tests/html/semantics/tabular-data/processing-model-1/span-limits.html
new file mode 100644 (file)
index 0000000..55d2388
--- /dev/null
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<title>Limits on colSpan/rowSpan</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+
+<table border=1>
+  <tr><td colspan=500>a<td colspan=500 id=a1>a
+  <!--  This cell must span the previous two  -->
+  <tr><td colspan=1000 id=a2>a
+</table>
+
+<table border=1>
+  <tr><td colspan=1000 id=b1>a<td>a
+  <!--  This cell must span only the first cell in the previous row  -->
+  <tr><td colspan=1001 id=b2>a
+</table>
+
+<table border=1 style="float:left">
+  <!--  The first column must go all the way down to the bottom  -->
+  <tr><td rowspan=65534 id=c1>a<td>
+  <!--  We'll add another 65533 rows later  -->
+</table>
+
+<table border=1>
+  <!--  The first column must go one cell below the bottom  -->
+  <tr><td rowspan=65535 id=d1>a<td>
+  <!--  We'll add another 65534 rows later  -->
+</table>
+
+<script>
+var $ = document.querySelector.bind(document);
+
+test(() => {
+    assert_equals($("#a2").getBoundingClientRect().right,
+                  $("#a1").getBoundingClientRect().right);
+}, "colspan of 1000 must work");
+
+test(() => {
+    assert_equals($("#b2").getBoundingClientRect().right,
+                  $("#b1").getBoundingClientRect().right);
+}, "colspan of 1001 must be treated as 1000");
+
+test(() => {
+    var s = "";
+    for (var i = 0; i < 65532; i++) {
+      s += "<tr><td>";
+    }
+    s += "<tr><td id=c2>";
+    document.querySelectorAll("table")[2].firstElementChild.innerHTML += s;
+    assert_equals($("#c1").getBoundingClientRect().bottom,
+                  $("#c2").getBoundingClientRect().bottom);
+}, "rowspan of 65534 must work");
+
+test(() => {
+    var s = "";
+    for (var i = 0; i < 65532; i++) {
+      s += "<tr><td>";
+    }
+    s += "<tr><td id=d2><tr><td>a<td>";
+    document.querySelectorAll("table")[3].firstElementChild.innerHTML += s;
+    assert_equals($("#d1").getBoundingClientRect().bottom,
+                  $("#d2").getBoundingClientRect().bottom);
+}, "rowspan of 65535 must be treated as 65534");
+</script>
index 6d15d6b..bc21136 100644 (file)
@@ -1,7 +1,6 @@
 The tests in this directory were imported from the W3C repository.
 Do NOT modify these tests directly in WebKit.
-Instead, create a pull request on the W3C CSS or WPT github:
-       https://github.com/w3c/csswg-test
+Instead, create a pull request on the WPT github:
        https://github.com/w3c/web-platform-tests
 
 Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport
@@ -16,3 +15,4 @@ None
 ------------------------------------------------------------------------
 List of files:
 /LayoutTests/imported/w3c/web-platform-tests/html/semantics/tabular-data/processing-model-1/contains.json
+/LayoutTests/imported/w3c/web-platform-tests/html/semantics/tabular-data/processing-model-1/span-limits.html
index 3cec5ad..2fb6b34 100644 (file)
@@ -1,7 +1,6 @@
 The tests in this directory were imported from the W3C repository.
 Do NOT modify these tests directly in WebKit.
-Instead, create a pull request on the W3C CSS or WPT github:
-       https://github.com/w3c/csswg-test
+Instead, create a pull request on the WPT github:
        https://github.com/w3c/web-platform-tests
 
 Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport
index 19408cd..957f63c 100644 (file)
@@ -1,7 +1,6 @@
 The tests in this directory were imported from the W3C repository.
 Do NOT modify these tests directly in WebKit.
-Instead, create a pull request on the W3C CSS or WPT github:
-       https://github.com/w3c/csswg-test
+Instead, create a pull request on the WPT github:
        https://github.com/w3c/web-platform-tests
 
 Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport
index bab0556..a7154ff 100644 (file)
@@ -1,7 +1,6 @@
 The tests in this directory were imported from the W3C repository.
 Do NOT modify these tests directly in WebKit.
-Instead, create a pull request on the W3C CSS or WPT github:
-       https://github.com/w3c/csswg-test
+Instead, create a pull request on the WPT github:
        https://github.com/w3c/web-platform-tests
 
 Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport
index 2fa5e95..bd0f35b 100644 (file)
@@ -1,7 +1,6 @@
 The tests in this directory were imported from the W3C repository.
 Do NOT modify these tests directly in WebKit.
-Instead, create a pull request on the W3C CSS or WPT github:
-       https://github.com/w3c/csswg-test
+Instead, create a pull request on the WPT github:
        https://github.com/w3c/web-platform-tests
 
 Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport
index d138e53..6fbda22 100644 (file)
@@ -1,7 +1,6 @@
 The tests in this directory were imported from the W3C repository.
 Do NOT modify these tests directly in WebKit.
-Instead, create a pull request on the W3C CSS or WPT github:
-       https://github.com/w3c/csswg-test
+Instead, create a pull request on the WPT github:
        https://github.com/w3c/web-platform-tests
 
 Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport
index 6c9491a..66b1612 100644 (file)
@@ -1,7 +1,6 @@
 The tests in this directory were imported from the W3C repository.
 Do NOT modify these tests directly in WebKit.
-Instead, create a pull request on the W3C CSS or WPT github:
-       https://github.com/w3c/csswg-test
+Instead, create a pull request on the WPT github:
        https://github.com/w3c/web-platform-tests
 
 Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport
index 9757022..da08769 100644 (file)
@@ -1,7 +1,6 @@
 The tests in this directory were imported from the W3C repository.
 Do NOT modify these tests directly in WebKit.
-Instead, create a pull request on the W3C CSS or WPT github:
-       https://github.com/w3c/csswg-test
+Instead, create a pull request on the WPT github:
        https://github.com/w3c/web-platform-tests
 
 Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport
index 1050b7d..f8fb919 100644 (file)
@@ -7,4 +7,4 @@ layer at (0,0) size 800x600
       RenderTable {TABLE} at (0,10) size 6x6
         RenderTableSection {TBODY} at (0,0) size 6x6
           RenderTableRow {TR} at (0,2) size 6x2
-            RenderTableCell {TD} at (2,2) size 2x2 [r=0 c=0 rs=8190 cs=1]
+            RenderTableCell {TD} at (2,2) size 2x2 [r=0 c=0 rs=65534 cs=1]
index 7804ac0..cd496c8 100644 (file)
@@ -6,19 +6,19 @@ Blocked access to external URL http://site.example/
 Blocked access to external URL http://site.example/path???@#l
 Blocked access to external URL http://site.example/
 Blocked access to external URL http://site.example/path???@#l
-CONSOLE MESSAGE: line 707: The language contains a null character and is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language 'undefined' is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language '7' is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language '1.5' is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language 'true' is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language 'false' is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language '[object Object]' is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language 'Infinity' is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language '-Infinity' is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language contains a null character and is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language 'null' is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language 'test-toString' is not a valid BCP 47 language tag.
-CONSOLE MESSAGE: line 707: The language 'test-valueOf' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language contains a null character and is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language 'undefined' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language '7' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language '1.5' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language 'true' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language 'false' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language '[object Object]' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language 'Infinity' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language '-Infinity' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language contains a null character and is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language 'null' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language 'test-toString' is not a valid BCP 47 language tag.
+CONSOLE MESSAGE: line 786: The language 'test-valueOf' is not a valid BCP 47 language tag.
 CONSOLE MESSAGE: line 1406: The language contains a null character and is not a valid BCP 47 language tag.
 CONSOLE MESSAGE: line 1406: The language 'undefined' is not a valid BCP 47 language tag.
 CONSOLE MESSAGE: line 1406: The language '7' is not a valid BCP 47 language tag.
index 1050b7d..f8fb919 100644 (file)
@@ -7,4 +7,4 @@ layer at (0,0) size 800x600
       RenderTable {TABLE} at (0,10) size 6x6
         RenderTableSection {TBODY} at (0,0) size 6x6
           RenderTableRow {TR} at (0,2) size 6x2
-            RenderTableCell {TD} at (2,2) size 2x2 [r=0 c=0 rs=8190 cs=1]
+            RenderTableCell {TD} at (2,2) size 2x2 [r=0 c=0 rs=65534 cs=1]
index c8214d8..3a381e1 100644 (file)
@@ -1,3 +1,45 @@
+2017-04-27  Chris Dumez  <cdumez@apple.com>
+
+        Align colspan/rowspan limits with the latest HTML specification
+        https://bugs.webkit.org/show_bug.cgi?id=171322
+
+        Reviewed by Darin Adler.
+
+        Align colspan/rowspan limits with the latest HTML specification after:
+        - https://github.com/whatwg/html/pull/1993
+
+        The following changes were made:
+        - Our rowspan limit was raised from 8190 to 65534
+        - A colspan limit of 1000 was introduced. Blink has UseCounter data showing that
+          colspans over 1000 are extremely rare and Gecko has data showing that when we
+          get a colspan greater than 1000, it is usually a bug. Therefore, this change
+          should be fine.
+        - The limits are now properly reflected via the IDL attributes instead of lying
+          to the Web about the colspan / rowspan we are using internally.
+
+        Test: imported/w3c/web-platform-tests/html/semantics/tabular-data/processing-model-1/span-limits.html
+
+        * html/HTMLTableCellElement.cpp:
+        (WebCore::HTMLTableCellElement::colSpan):
+        (WebCore::HTMLTableCellElement::rowSpan):
+        (WebCore::HTMLTableCellElement::rowSpanForBindings):
+        (WebCore::HTMLTableCellElement::setColSpan):
+        * html/HTMLTableCellElement.h:
+        * html/HTMLTableCellElement.idl:
+        * html/parser/HTMLParserIdioms.cpp:
+        (WebCore::parseHTMLIntegerInternal):
+        (WebCore::parseHTMLInteger):
+        (WebCore::parseHTMLNonNegativeInteger):
+        (WebCore::parseValidHTMLNonNegativeIntegerInternal):
+        (WebCore::parseHTTPRefreshInternal):
+        * html/parser/HTMLParserIdioms.h:
+        (WebCore::parseHTMLInteger):
+        (WebCore::parseHTMLNonNegativeInteger):
+
+        (WebCore::clampHTMLNonNegativeIntegerToRange):
+        Add utility function to implement:
+        - https://html.spec.whatwg.org/#clamped-to-the-range
+
 2017-04-27  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         WKUIDelegatePrivate needs a hook to vend data used to initialize item providers for data interaction
index 48646c0..0b2f310 100644 (file)
@@ -3048,7 +3048,7 @@ URL Element::getNonEmptyURLAttribute(const QualifiedName& name) const
 
 int Element::getIntegralAttribute(const QualifiedName& attributeName) const
 {
-    return parseHTMLInteger(getAttribute(attributeName)).value_or(0);
+    return parseHTMLInteger(getAttribute(attributeName)).valueOr(0);
 }
 
 void Element::setIntegralAttribute(const QualifiedName& attributeName, int value)
@@ -3058,7 +3058,7 @@ void Element::setIntegralAttribute(const QualifiedName& attributeName, int value
 
 unsigned Element::getUnsignedIntegralAttribute(const QualifiedName& attributeName) const
 {
-    return parseHTMLNonNegativeInteger(getAttribute(attributeName)).value_or(0);
+    return parseHTMLNonNegativeInteger(getAttribute(attributeName)).valueOr(0);
 }
 
 void Element::setUnsignedIntegralAttribute(const QualifiedName& attributeName, unsigned value)
index ac6288e..d2adac5 100644 (file)
@@ -101,8 +101,8 @@ static inline CSSValueID unicodeBidiAttributeForDirAuto(HTMLElement& element)
 
 unsigned HTMLElement::parseBorderWidthAttribute(const AtomicString& value) const
 {
-    if (std::optional<unsigned> borderWidth = parseHTMLNonNegativeInteger(value))
-        return borderWidth.value();
+    if (auto optionalBorderWidth = parseHTMLNonNegativeInteger(value))
+        return optionalBorderWidth.value();
 
     return hasTagName(tableTag) ? 1 : 0;
 }
@@ -424,8 +424,8 @@ void HTMLElement::parseAttribute(const QualifiedName& name, const AtomicString&
     if (name == tabindexAttr) {
         if (value.isEmpty())
             clearTabIndexExplicitlyIfNeeded();
-        else if (std::optional<int> tabIndex = parseHTMLInteger(value))
-            setTabIndexExplicitly(tabIndex.value());
+        else if (auto optionalTabIndex = parseHTMLInteger(value))
+            setTabIndexExplicitly(optionalTabIndex.value());
         return;
     }
 
index 94869cf..5a9c6e9 100644 (file)
@@ -371,9 +371,9 @@ unsigned HTMLImageElement::width(bool ignorePendingStylesheets)
 {
     if (!renderer()) {
         // check the attribute first for an explicit pixel value
-        std::optional<unsigned> width = parseHTMLNonNegativeInteger(attributeWithoutSynchronization(widthAttr));
-        if (width)
-            return width.value();
+        auto optionalWidth = parseHTMLNonNegativeInteger(attributeWithoutSynchronization(widthAttr));
+        if (optionalWidth)
+            return optionalWidth.value();
 
         // if the image is available, use its width
         if (m_imageLoader.image())
@@ -396,9 +396,9 @@ unsigned HTMLImageElement::height(bool ignorePendingStylesheets)
 {
     if (!renderer()) {
         // check the attribute first for an explicit pixel value
-        std::optional<unsigned> height = parseHTMLNonNegativeInteger(attributeWithoutSynchronization(heightAttr));
-        if (height)
-            return height.value();
+        auto optionalHeight = parseHTMLNonNegativeInteger(attributeWithoutSynchronization(heightAttr));
+        if (optionalHeight)
+            return optionalHeight.value();
 
         // if the image is available, use its height
         if (m_imageLoader.image())
index e0a7ec3..20e6810 100644 (file)
@@ -1771,7 +1771,7 @@ bool HTMLInputElement::isEmptyValue() const
 void HTMLInputElement::maxLengthAttributeChanged(const AtomicString& newValue)
 {
     unsigned oldEffectiveMaxLength = effectiveMaxLength();
-    internalSetMaxLength(parseHTMLNonNegativeInteger(newValue).value_or(-1));
+    internalSetMaxLength(parseHTMLNonNegativeInteger(newValue).valueOr(-1));
     if (oldEffectiveMaxLength != effectiveMaxLength())
         updateValueIfNeeded();
 
@@ -1783,7 +1783,7 @@ void HTMLInputElement::maxLengthAttributeChanged(const AtomicString& newValue)
 void HTMLInputElement::minLengthAttributeChanged(const AtomicString& newValue)
 {
     int oldMinLength = minLength();
-    internalSetMinLength(parseHTMLNonNegativeInteger(newValue).value_or(-1));
+    internalSetMinLength(parseHTMLNonNegativeInteger(newValue).valueOr(-1));
     if (oldMinLength != minLength())
         updateValueIfNeeded();
 
index 66ab9e0..a4405fc 100644 (file)
@@ -80,7 +80,8 @@ void HTMLOListElement::parseAttribute(const QualifiedName& name, const AtomicStr
 {
     if (name == startAttr) {
         int oldStart = start();
-        m_start = parseHTMLInteger(value);
+        auto optionalStart = parseHTMLInteger(value);
+        m_start = optionalStart ? std::optional<int>(optionalStart.value()) : std::nullopt;
         if (oldStart == start())
             return;
         updateItemValues();
index c096dcf..46beaae 100644 (file)
@@ -36,6 +36,16 @@ namespace WebCore {
 
 using namespace HTMLNames;
 
+// These limits are defined in the HTML specification:
+// - https://html.spec.whatwg.org/#dom-tdth-colspan
+// - https://html.spec.whatwg.org/#dom-tdth-rowspan
+static const unsigned minColspan = 1;
+static const unsigned maxColspan = 1000;
+static const unsigned defaultColspan = 1;
+static const unsigned minRowspan = 0;
+static const unsigned maxRowspan = 65534;
+static const unsigned defaultRowspan = 1;
+
 Ref<HTMLTableCellElement> HTMLTableCellElement::create(const QualifiedName& tagName, Document& document)
 {
     return adoptRef(*new HTMLTableCellElement(tagName, document));
@@ -49,24 +59,18 @@ HTMLTableCellElement::HTMLTableCellElement(const QualifiedName& tagName, Documen
 
 unsigned HTMLTableCellElement::colSpan() const
 {
-    return std::max(1u, colSpanForBindings());
-}
-
-unsigned HTMLTableCellElement::colSpanForBindings() const
-{
-    return limitToOnlyHTMLNonNegative(attributeWithoutSynchronization(colspanAttr), 1u);
+    return clampHTMLNonNegativeIntegerToRange(attributeWithoutSynchronization(colspanAttr), minColspan, maxColspan, defaultColspan);
 }
 
 unsigned HTMLTableCellElement::rowSpan() const
 {
-    static const unsigned maxRowspan = 8190;
     // FIXME: a rowSpan equal to 0 should be allowed, and mean that the cell is to span all the remaining rows in the row group.
-    return std::max(1u, std::min(rowSpanForBindings(), maxRowspan));
+    return std::max(1u, rowSpanForBindings());
 }
 
 unsigned HTMLTableCellElement::rowSpanForBindings() const
 {
-    return limitToOnlyHTMLNonNegative(attributeWithoutSynchronization(rowspanAttr), 1u);
+    return clampHTMLNonNegativeIntegerToRange(attributeWithoutSynchronization(rowspanAttr), minRowspan, maxRowspan, defaultRowspan);
 }
 
 int HTMLTableCellElement::cellIndex() const
@@ -144,7 +148,7 @@ String HTMLTableCellElement::axis() const
     return attributeWithoutSynchronization(axisAttr);
 }
 
-void HTMLTableCellElement::setColSpanForBindings(unsigned n)
+void HTMLTableCellElement::setColSpan(unsigned n)
 {
     setAttributeWithoutSynchronization(colspanAttr, AtomicString::number(limitToOnlyHTMLNonNegative(n, 1)));
 }
index d93997c..0709bce 100644 (file)
@@ -34,13 +34,12 @@ public:
     static Ref<HTMLTableCellElement> create(const QualifiedName&, Document&);
 
     WEBCORE_EXPORT int cellIndex() const;
-    unsigned colSpan() const;
-    WEBCORE_EXPORT unsigned colSpanForBindings() const;
+    WEBCORE_EXPORT unsigned colSpan() const;
     unsigned rowSpan() const;
     WEBCORE_EXPORT unsigned rowSpanForBindings() const;
 
     void setCellIndex(int);
-    WEBCORE_EXPORT void setColSpanForBindings(unsigned);
+    WEBCORE_EXPORT void setColSpan(unsigned);
     WEBCORE_EXPORT void setRowSpanForBindings(unsigned);
 
     String abbr() const;
index 23735b3..a730916 100644 (file)
@@ -26,7 +26,7 @@ interface HTMLTableCellElement : HTMLElement {
     [Reflect=char] attribute DOMString ch;
     [Reflect=charoff] attribute DOMString chOff;
 
-    [ImplementedAs=colSpanForBindings] attribute unsigned long colSpan;
+    attribute unsigned long colSpan;
     [ImplementedAs=rowSpanForBindings] attribute unsigned long rowSpan;
 
     [Reflect] attribute DOMString headers;
index 44e0330..7306749 100644 (file)
@@ -202,13 +202,13 @@ void HTMLTextAreaElement::parseAttribute(const QualifiedName& name, const Atomic
 
 void HTMLTextAreaElement::maxLengthAttributeChanged(const AtomicString& newValue)
 {
-    internalSetMaxLength(parseHTMLNonNegativeInteger(newValue).value_or(-1));
+    internalSetMaxLength(parseHTMLNonNegativeInteger(newValue).valueOr(-1));
     updateValidity();
 }
 
 void HTMLTextAreaElement::minLengthAttributeChanged(const AtomicString& newValue)
 {
-    internalSetMinLength(parseHTMLNonNegativeInteger(newValue).value_or(-1));
+    internalSetMinLength(parseHTMLNonNegativeInteger(newValue).valueOr(-1));
     updateValidity();
 }
 
index f396a3e..99ca100 100644 (file)
@@ -179,8 +179,8 @@ unsigned ImageInputType::height() const
 
     if (!element->renderer()) {
         // Check the attribute first for an explicit pixel value.
-        if (std::optional<unsigned> height = parseHTMLNonNegativeInteger(element->attributeWithoutSynchronization(heightAttr)))
-            return height.value();
+        if (auto optionalHeight = parseHTMLNonNegativeInteger(element->attributeWithoutSynchronization(heightAttr)))
+            return optionalHeight.value();
 
         // If the image is available, use its height.
         HTMLImageLoader* imageLoader = element->imageLoader();
@@ -200,8 +200,8 @@ unsigned ImageInputType::width() const
 
     if (!element->renderer()) {
         // Check the attribute first for an explicit pixel value.
-        if (std::optional<unsigned> width = parseHTMLNonNegativeInteger(element->attributeWithoutSynchronization(widthAttr)))
-            return width.value();
+        if (auto optionalWidth = parseHTMLNonNegativeInteger(element->attributeWithoutSynchronization(widthAttr)))
+            return optionalWidth.value();
 
         // If the image is available, use its width.
         HTMLImageLoader* imageLoader = element->imageLoader();
index e20276d..6283122 100644 (file)
@@ -154,13 +154,13 @@ double parseToDoubleForNumberType(const String& string)
 }
 
 template <typename CharacterType>
-static std::optional<int> parseHTMLIntegerInternal(const CharacterType* position, const CharacterType* end)
+static Expected<int, HTMLIntegerParsingError> parseHTMLIntegerInternal(const CharacterType* position, const CharacterType* end)
 {
     while (position < end && isHTMLSpace(*position))
         ++position;
 
     if (position == end)
-        return std::nullopt;
+        return makeUnexpected(HTMLIntegerParsingError::Other);
 
     bool isNegative = false;
     if (*position == '-') {
@@ -170,7 +170,7 @@ static std::optional<int> parseHTMLIntegerInternal(const CharacterType* position
         ++position;
 
     if (position == end || !isASCIIDigit(*position))
-        return std::nullopt;
+        return makeUnexpected(HTMLIntegerParsingError::Other);
 
     constexpr int intMax = std::numeric_limits<int>::max();
     constexpr int base = 10;
@@ -181,7 +181,7 @@ static std::optional<int> parseHTMLIntegerInternal(const CharacterType* position
         int digitValue = *position - '0';
 
         if (result > maxMultiplier || (result == maxMultiplier && digitValue > (intMax % base) + isNegative))
-            return std::nullopt;
+            return makeUnexpected(isNegative ? HTMLIntegerParsingError::NegativeOverflow : HTMLIntegerParsingError::PositiveOverflow);
 
         result = base * result + digitValue;
         ++position;
@@ -191,11 +191,11 @@ static std::optional<int> parseHTMLIntegerInternal(const CharacterType* position
 }
 
 // https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-integers
-std::optional<int> parseHTMLInteger(StringView input)
+Expected<int, HTMLIntegerParsingError> parseHTMLInteger(StringView input)
 {
     unsigned length = input.length();
     if (!length)
-        return std::nullopt;
+        return makeUnexpected(HTMLIntegerParsingError::Other);
 
     if (LIKELY(input.is8Bit())) {
         auto* start = input.characters8();
@@ -207,13 +207,16 @@ std::optional<int> parseHTMLInteger(StringView input)
 }
 
 // https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-non-negative-integers
-std::optional<unsigned> parseHTMLNonNegativeInteger(StringView input)
+Expected<unsigned, HTMLIntegerParsingError> parseHTMLNonNegativeInteger(StringView input)
 {
-    std::optional<int> signedValue = parseHTMLInteger(input);
-    if (!signedValue || signedValue.value() < 0)
-        return std::nullopt;
+    auto optionalSignedResult = parseHTMLInteger(input);
+    if (!optionalSignedResult)
+        return optionalSignedResult.getUnexpected();
+
+    if (optionalSignedResult.value() < 0)
+        return makeUnexpected(HTMLIntegerParsingError::NegativeOverflow);
 
-    return static_cast<unsigned>(signedValue.value());
+    return static_cast<unsigned>(optionalSignedResult.value());
 }
 
 template <typename CharacterType>
@@ -225,11 +228,11 @@ static std::optional<int> parseValidHTMLNonNegativeIntegerInternal(const Charact
             return std::nullopt;
     }
 
-    std::optional<int> signedValue = parseHTMLIntegerInternal(position, end);
-    if (!signedValue || signedValue.value() < 0)
+    auto optionalSignedValue = parseHTMLIntegerInternal(position, end);
+    if (!optionalSignedValue || optionalSignedValue.value() < 0)
         return std::nullopt;
 
-    return signedValue;
+    return optionalSignedValue.value();
 }
 
 // https://html.spec.whatwg.org/#valid-non-negative-integer
@@ -363,22 +366,22 @@ static bool parseHTTPRefreshInternal(const CharacterType* position, const Charac
     while (position < end && isASCIIDigit(*position))
         ++position;
 
-    std::optional<unsigned> number = parseHTMLNonNegativeInteger(StringView(numberStart, position - numberStart));
-    if (!number)
+    auto optionalNumber = parseHTMLNonNegativeInteger(StringView(numberStart, position - numberStart));
+    if (!optionalNumber)
         return false;
 
     while (position < end && (isASCIIDigit(*position) || *position == '.'))
         ++position;
 
     if (position == end) {
-        parsedDelay = number.value();
+        parsedDelay = optionalNumber.value();
         return true;
     }
 
     if (*position != ';' && *position != ',' && !isHTMLSpace(*position))
         return false;
 
-    parsedDelay = number.value();
+    parsedDelay = optionalNumber.value();
 
     while (position < end && isHTMLSpace(*position))
         ++position;
index 29a6c6e..e92cc42 100644 (file)
@@ -25,6 +25,7 @@
 #pragma once
 
 #include <unicode/uchar.h>
+#include <wtf/Expected.h>
 #include <wtf/Forward.h>
 #include <wtf/Optional.h>
 #include <wtf/Vector.h>
@@ -62,10 +63,12 @@ double parseToDoubleForNumberType(const String&);
 double parseToDoubleForNumberType(const String&, double fallbackValue);
 
 // http://www.whatwg.org/specs/web-apps/current-work/#rules-for-parsing-integers
-WEBCORE_EXPORT std::optional<int> parseHTMLInteger(StringView);
+enum class HTMLIntegerParsingError { NegativeOverflow, PositiveOverflow, Other };
+
+WEBCORE_EXPORT Expected<int, HTMLIntegerParsingError> parseHTMLInteger(StringView);
 
 // http://www.whatwg.org/specs/web-apps/current-work/#rules-for-parsing-non-negative-integers
-WEBCORE_EXPORT std::optional<unsigned> parseHTMLNonNegativeInteger(StringView);
+WEBCORE_EXPORT Expected<unsigned, HTMLIntegerParsingError> parseHTMLNonNegativeInteger(StringView);
 
 // https://html.spec.whatwg.org/#valid-non-negative-integer
 std::optional<int> parseValidHTMLNonNegativeInteger(StringView);
@@ -155,9 +158,21 @@ inline unsigned limitToOnlyHTMLNonNegative(unsigned value, unsigned defaultValue
 inline unsigned limitToOnlyHTMLNonNegative(StringView stringValue, unsigned defaultValue = 0)
 {
     ASSERT(defaultValue <= maxHTMLNonNegativeInteger);
-    unsigned value = parseHTMLNonNegativeInteger(stringValue).value_or(defaultValue);
+    unsigned value = parseHTMLNonNegativeInteger(stringValue).valueOr(defaultValue);
     ASSERT(value <= maxHTMLNonNegativeInteger);
     return value;
 }
 
+// https://html.spec.whatwg.org/#clamped-to-the-range
+inline unsigned clampHTMLNonNegativeIntegerToRange(StringView stringValue, unsigned min, unsigned max, unsigned defaultValue = 0)
+{
+    ASSERT(defaultValue >= min);
+    ASSERT(defaultValue <= max);
+    auto optionalValue = parseHTMLNonNegativeInteger(stringValue);
+    if (optionalValue)
+        return std::min(std::max(optionalValue.value(), min), max);
+
+    return optionalValue.error() == HTMLIntegerParsingError::PositiveOverflow ? max : defaultValue;
+}
+
 } // namespace WebCore
index 8e9302e..c4ad89e 100644 (file)
@@ -462,8 +462,8 @@ void SVGElement::parseAttribute(const QualifiedName& name, const AtomicString& v
     if (name == HTMLNames::tabindexAttr) {
         if (value.isEmpty())
             clearTabIndexExplicitlyIfNeeded();
-        else if (std::optional<int> tabIndex = parseHTMLInteger(value))
-            setTabIndexExplicitly(tabIndex.value());
+        else if (auto optionalTabIndex = parseHTMLInteger(value))
+            setTabIndexExplicitly(optionalTabIndex.value());
         return;
     }
 
index 9368c7d..49f6a3e 100644 (file)
@@ -1,3 +1,16 @@
+2017-04-27  Chris Dumez  <cdumez@apple.com>
+
+        Align colspan/rowspan limits with the latest HTML specification
+        https://bugs.webkit.org/show_bug.cgi?id=171322
+
+        Reviewed by Darin Adler.
+
+        ObjC bindings build fix.
+
+        * DOM/DOMHTMLTableCellElement.mm:
+        (-[DOMHTMLTableCellElement colSpan]):
+        (-[DOMHTMLTableCellElement setColSpan:]):
+
 2017-04-27  Said Abou-Hallawa  <sabouhallawa@apple.com>
 
         REGRESSION(r213764): Async decoding of animated images is disabled for ImageDocument
index 816fbc3..a91e2f8 100644 (file)
 - (int)colSpan
 {
     WebCore::JSMainThreadNullState state;
-    return IMPL->colSpanForBindings();
+    return IMPL->colSpan();
 }
 
 - (void)setColSpan:(int)newColSpan
 {
     WebCore::JSMainThreadNullState state;
-    IMPL->setColSpanForBindings(newColSpan);
+    IMPL->setColSpan(newColSpan);
 }
 
 - (int)rowSpan
index 1322819..d7ae05c 100644 (file)
@@ -1,3 +1,16 @@
+2017-04-27  Chris Dumez  <cdumez@apple.com>
+
+        Align colspan/rowspan limits with the latest HTML specification
+        https://bugs.webkit.org/show_bug.cgi?id=171322
+
+        Reviewed by Darin Adler.
+
+        GTK build fix.
+
+        * WebProcess/InjectedBundle/API/gtk/DOM/WebKitDOMHTMLTableCellElement.cpp:
+        (webkit_dom_html_table_cell_element_get_col_span):
+        (webkit_dom_html_table_cell_element_set_col_span):
+
 2017-04-27  Wenson Hsieh  <wenson_hsieh@apple.com>
 
         WKUIDelegatePrivate needs a hook to vend data used to initialize item providers for data interaction
index 80c19f0..b4687ab 100644 (file)
@@ -494,7 +494,7 @@ glong webkit_dom_html_table_cell_element_get_col_span(WebKitDOMHTMLTableCellElem
     WebCore::JSMainThreadNullState state;
     g_return_val_if_fail(WEBKIT_DOM_IS_HTML_TABLE_CELL_ELEMENT(self), 0);
     WebCore::HTMLTableCellElement* item = WebKit::core(self);
-    glong result = item->colSpanForBindings();
+    glong result = item->colSpan();
     return result;
 }
 
@@ -503,7 +503,7 @@ void webkit_dom_html_table_cell_element_set_col_span(WebKitDOMHTMLTableCellEleme
     WebCore::JSMainThreadNullState state;
     g_return_if_fail(WEBKIT_DOM_IS_HTML_TABLE_CELL_ELEMENT(self));
     WebCore::HTMLTableCellElement* item = WebKit::core(self);
-    item->setColSpanForBindings(value);
+    item->setColSpan(value);
 }
 
 glong webkit_dom_html_table_cell_element_get_row_span(WebKitDOMHTMLTableCellElement* self)
index 6e9e738..0f1c02d 100644 (file)
@@ -37,7 +37,7 @@ static int testParseHTMLInteger(const String& input)
 {
     auto optionalResult = parseHTMLInteger(input);
     EXPECT_TRUE(!!optionalResult);
-    return optionalResult.value_or(0);
+    return optionalResult.valueOr(0);
 }
 
 static bool parseHTMLIntegerFails(const String& input)
@@ -101,7 +101,7 @@ static unsigned testParseHTMLNonNegativeInteger(const String& input)
 {
     auto optionalResult = parseHTMLNonNegativeInteger(input);
     EXPECT_TRUE(!!optionalResult);
-    return optionalResult.value_or(0);
+    return optionalResult.valueOr(0);
 }
 
 static bool parseHTMLNonNegativeIntegerFails(const String& input)