Title: [205515] trunk
Revision
205515
Author
[email protected]
Date
2016-09-06 15:59:29 -0700 (Tue, 06 Sep 2016)

Log Message

Align srcset attribute parsing with the HTML specification
https://bugs.webkit.org/show_bug.cgi?id=161636

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Rebaseline a couple of W3C tests now that more checks are passing.

* web-platform-tests/html/semantics/embedded-content/the-img-element/current-pixel-density/basic-expected.txt:
* web-platform-tests/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute-expected.txt:

Source/WebCore:

Align srcset attribute parsing with the HTML specification:
- https://html.spec.whatwg.org/#parse-a-srcset-attribute

The new behavior is also consistent with Firefox and Chrome
as all 3 browsers now pass 100% of the checks at:
- http://w3c-test.org/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html

No new tests, rebaselined existing tests.

* html/parser/HTMLParserIdioms.cpp:
(WebCore::parseValidHTMLNonNegativeIntegerInternal):
(WebCore::parseValidHTMLNonNegativeInteger):
(WebCore::parseValidHTMLFloatingPointNumberInternal):
(WebCore::parseValidHTMLFloatingPointNumber):
* html/parser/HTMLParserIdioms.h:
Add convenience for parsing *valid* HTML non-negative integers and
*valid* floating point number values.

* html/parser/HTMLSrcsetParser.cpp:
(WebCore::parseDescriptors):
- Use parseValidHTMLFloatingPointNumber() to parse density so that the value
  is parsed as a valid HTML floating point number value, as per the spec.
- Use parseValidHTMLNonNegativeInteger() to parse width and height so that
  the value is parsed as a valid HTML non-negative integer value, as per the
  spec.
- Return false if descriptor does not have a h, w and x at the end as per:
  https://html.spec.whatwg.org/#parse-a-srcset-attribute (step 13: Anything else)
- Return false if height is set but not width, as per:
  https://html.spec.whatwg.org/#parse-a-srcset-attribute (step 14)

(WebCore::parseImageCandidatesFromSrcsetAttribute):
- Skip whitespace if URL does not end with a comma instead of assuming there is
  a single space character, as per:
  https://html.spec.whatwg.org/#parse-a-srcset-attribute (step 8. Otherwise 1.)

LayoutTests:

Re-sync fast/hidpi/image-srcset-invalid-descriptor.html with Blink.

* fast/hidpi/image-srcset-invalid-descriptor-expected.txt:
* fast/hidpi/image-srcset-invalid-descriptor.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (205514 => 205515)


--- trunk/LayoutTests/ChangeLog	2016-09-06 22:19:51 UTC (rev 205514)
+++ trunk/LayoutTests/ChangeLog	2016-09-06 22:59:29 UTC (rev 205515)
@@ -1,3 +1,15 @@
+2016-09-06  Chris Dumez  <[email protected]>
+
+        Align srcset attribute parsing with the HTML specification
+        https://bugs.webkit.org/show_bug.cgi?id=161636
+
+        Reviewed by Darin Adler.
+
+        Re-sync fast/hidpi/image-srcset-invalid-descriptor.html with Blink.
+
+        * fast/hidpi/image-srcset-invalid-descriptor-expected.txt:
+        * fast/hidpi/image-srcset-invalid-descriptor.html:
+
 2016-09-06  Ryan Haddad  <[email protected]>
 
         Marking storage/indexeddb/objectstore-cursor.html as flaky on mac-wk2 debug.

Modified: trunk/LayoutTests/fast/hidpi/image-srcset-invalid-descriptor-expected.txt (205514 => 205515)


--- trunk/LayoutTests/fast/hidpi/image-srcset-invalid-descriptor-expected.txt	2016-09-06 22:19:51 UTC (rev 205514)
+++ trunk/LayoutTests/fast/hidpi/image-srcset-invalid-descriptor-expected.txt	2016-09-06 22:59:29 UTC (rev 205515)
@@ -1,12 +1,17 @@
-PASS document.getElementById("invalid_with_x").clientWidth is 100
-PASS document.getElementById("invalid_without_x").clientWidth is 100
-PASS document.getElementById("future_descriptor").clientWidth is 100
-PASS document.getElementById("future_descriptor_without_x").clientWidth is 100
-PASS document.getElementById("x_with_w_ignored").clientWidth is 200
-PASS document.getElementById("x_with_h_ignored").clientWidth is 200
+PASS document.getElementById("foo").clientWidth==200 is true
+PASS document.getElementById("foo2").clientWidth==200 is true
+PASS document.getElementById("foo3").clientWidth==200 is true
+PASS document.getElementById("foo4").clientWidth==200 is true
+PASS document.getElementById("foo5").clientWidth==200 is true
+PASS document.getElementById("foo6").clientWidth==200 is true
+PASS document.getElementById("foo7").clientWidth==200 is true
+PASS document.getElementById("foo8").clientWidth==200 is true
+PASS document.getElementById("foo9").clientWidth==200 is true
+PASS document.getElementById("foo10").clientWidth==200 is true
 PASS successfullyParsed is true
 
 TEST COMPLETE
-This test passes if the image below is a 100px blue square when the deviceScaleFactor is 1.
-It tests that even though the 1x resource contains many invalid descriptors, only the invalid descriptors are ignored (according to the spec).
+This test passes if the image below is a 200px green square when the deviceScaleFactor is 1.
+It tests that the 1x resource is ignored since it contains invalid descriptors.
+The 2x resource has an intrinsic width of 200px, since it's a 400px wide image at 2x DPR.
          

Modified: trunk/LayoutTests/fast/hidpi/image-srcset-invalid-descriptor.html (205514 => 205515)


--- trunk/LayoutTests/fast/hidpi/image-srcset-invalid-descriptor.html	2016-09-06 22:19:51 UTC (rev 205514)
+++ trunk/LayoutTests/fast/hidpi/image-srcset-invalid-descriptor.html	2016-09-06 22:59:29 UTC (rev 205515)
@@ -1,31 +1,33 @@
-<html>
-<head>
+<!DOCTYPE html>
 <script>
     window.targetScaleFactor = 1;
 </script>
-<script src=""
+<script src=""
 <script src=""
 <script>
-    function runTest() {
-        shouldBe('document.getElementById("invalid_with_x").clientWidth', '100');
-        shouldBe('document.getElementById("invalid_without_x").clientWidth', '100');
-        shouldBe('document.getElementById("future_descriptor").clientWidth', '100');
-        shouldBe('document.getElementById("future_descriptor_without_x").clientWidth', '100');
-        shouldBe('document.getElementById("x_with_w_ignored").clientWidth', '200');
-        shouldBe('document.getElementById("x_with_h_ignored").clientWidth', '200');
-    }
+    addEventListener("load", function() {
+        shouldBeTrue('document.getElementById("foo").clientWidth==200');
+        shouldBeTrue('document.getElementById("foo2").clientWidth==200');
+        shouldBeTrue('document.getElementById("foo3").clientWidth==200');
+        shouldBeTrue('document.getElementById("foo4").clientWidth==200');
+        shouldBeTrue('document.getElementById("foo5").clientWidth==200');
+        shouldBeTrue('document.getElementById("foo6").clientWidth==200');
+        shouldBeTrue('document.getElementById("foo7").clientWidth==200');
+        shouldBeTrue('document.getElementById("foo8").clientWidth==200');
+        shouldBeTrue('document.getElementById("foo9").clientWidth==200');
+        shouldBeTrue('document.getElementById("foo10").clientWidth==200');
+    }, false);
 </script>
-</head>
-
-<body id="body">
-    <div>This test passes if the image below is a 100px blue square when the deviceScaleFactor is 1.</div>
-    <div> It tests that even though the 1x resource contains many invalid descriptors,
-        only the invalid descriptors are ignored (according to the spec).</div>
-    <img id="invalid_with_x" src="" srcset="resources/blue-100-px-square.png 43q 1x dfs 3dd, resources/green-400-px-square.png 2x">
-    <img id="invalid_without_x" src="" srcset="resources/blue-100-px-square.png 300q, resources/green-400-px-square.png 2x">
-    <img id="future_descriptor" srcset=",resources/blue-100-px-square.png 1x future-descriptor(3x, 4h, whatever), resources/green-400-px-square.png 2x">
-    <img id="future_descriptor_without_x" srcset=",resources/blue-100-px-square.png future-descriptor(3x, 4h, whatever), resources/green-400-px-square.png 2x">
-    <img id="x_with_w_ignored" srcset=",resources/blue-100-px-square.png 1x 100w, resources/green-400-px-square.png 2x">
-    <img id="x_with_h_ignored" srcset=",resources/blue-100-px-square.png 1x 100h, resources/green-400-px-square.png 2x">
-</body>
-</html>
+<div>This test passes if the image below is a 200px green square when the deviceScaleFactor is 1.</div>
+<div>It tests that the 1x resource is ignored since it contains invalid descriptors.</div>
+<div>The 2x resource has an intrinsic width of 200px, since it's a 400px wide image at 2x DPR.</div>
+<img id="foo" src="" srcset="resources/blue-100-px-square.png 43q 1x dfs 3dd, resources/green-400-px-square.png 2x">
+<img id="foo2" src="" srcset="resources/blue-100-px-square.png 300q, resources/green-400-px-square.png 2x">
+<img id="foo3" src="" srcset="resources/blue-100-px-square.png 100w 100w, resources/green-400-px-square.png 2x">
+<img id="foo4" src="" srcset="resources/blue-100-px-square.png 100h 100h, resources/green-400-px-square.png 2x">
+<img id="foo5" src="" srcset="resources/blue-100-px-square.png 100x 100h, resources/green-400-px-square.png 2x">
+<img id="foo6" src="" srcset="resources/blue-100-px-square.png 100x 100w, resources/green-400-px-square.png 2x">
+<img id="foo7" src="" srcset="resources/blue-100-px-square.png -100w, resources/green-400-px-square.png 2x">
+<img id="foo8" src="" srcset="resources/blue-100-px-square.png -100h, resources/green-400-px-square.png 2x">
+<img id="foo9" src="" srcset="resources/blue-100-px-square.png -1x, resources/green-400-px-square.png 2x">
+<img id="foo10" src="" srcset="resources/blue-100-px-square.png 100h, resources/green-400-px-square.png 2x">

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (205514 => 205515)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2016-09-06 22:19:51 UTC (rev 205514)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2016-09-06 22:59:29 UTC (rev 205515)
@@ -1,3 +1,15 @@
+2016-09-06  Chris Dumez  <[email protected]>
+
+        Align srcset attribute parsing with the HTML specification
+        https://bugs.webkit.org/show_bug.cgi?id=161636
+
+        Reviewed by Darin Adler.
+
+        Rebaseline a couple of W3C tests now that more checks are passing.
+
+        * web-platform-tests/html/semantics/embedded-content/the-img-element/current-pixel-density/basic-expected.txt:
+        * web-platform-tests/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute-expected.txt:
+
 2016-09-06  Youenn Fablet  <[email protected]>
 
         CachedResourceLoader is not taking into account fetch options to use or not cached resources

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/the-img-element/current-pixel-density/basic-expected.txt (205514 => 205515)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/the-img-element/current-pixel-density/basic-expected.txt	2016-09-06 22:19:51 UTC (rev 205514)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/the-img-element/current-pixel-density/basic-expected.txt	2016-09-06 22:59:29 UTC (rev 205515)
@@ -4,7 +4,7 @@
 FAIL <img srcset="/images/green-256x256.png 1.6x" data-expect="160"> assert_equals: naturalWidth expected 160 but got 256
 FAIL <img srcset="/images/green-256x256.png 2x" data-expect="128"> assert_equals: naturalWidth expected 128 but got 256
 FAIL <img srcset="/images/green-256x256.png 10000x" data-expect="0"> assert_equals: naturalWidth expected 0 but got 256
-FAIL <img srcset="/images/green-256x256.png 9e99999999999999999999999x" data-expect="0"> assert_equals: naturalWidth expected 0 but got 256
+PASS <img srcset="/images/green-256x256.png 9e99999999999999999999999x" data-expect="0"> 
 PASS <img srcset="/images/green-256x256.png 256w" sizes="256px" data-expect="256"> 
 FAIL <img srcset="/images/green-256x256.png 512w" sizes="256px" data-expect="128"> assert_equals: naturalWidth expected 128 but got 256
 FAIL <img srcset="/images/green-256x256.png 256w" sizes="512px" data-expect="512"> assert_equals: naturalWidth expected 512 but got 256

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute-expected.txt (205514 => 205515)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute-expected.txt	2016-09-06 22:19:51 UTC (rev 205514)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute-expected.txt	2016-09-06 22:59:29 UTC (rev 205515)
@@ -26,26 +26,26 @@
 PASS "data:,a 1x" 
 PASS "data:,a 1x " 
 PASS "data:,a 1x," 
-FAIL "data:,a ( , data:,b 1x, ), data:,c" assert_equals: expected "data:,c" but got "data:,a"
-FAIL "data:,a ((( , data:,b 1x, ), data:,c" assert_equals: expected "data:,c" but got "data:,a"
-FAIL "data:,a [ , data:,b 1x, ], data:,c" assert_equals: expected "data:,b" but got "data:,a"
-FAIL "data:,a { , data:,b 1x, }, data:,c" assert_equals: expected "data:,b" but got "data:,a"
-FAIL "data:,a \" , data:,b 1x, \", data:,c" assert_equals: expected "data:,b" but got "data:,a"
-FAIL "data:,a \\,data:;\,b, data:,c" assert_equals: expected "data:;\\,b" but got "data:,a"
+PASS "data:,a ( , data:,b 1x, ), data:,c" 
+PASS "data:,a ((( , data:,b 1x, ), data:,c" 
+PASS "data:,a [ , data:,b 1x, ], data:,c" 
+PASS "data:,a { , data:,b 1x, }, data:,c" 
+PASS "data:,a \" , data:,b 1x, \", data:,c" 
+PASS "data:,a \\,data:;\,b, data:,c" 
 PASS "data:,a, data:,b (" 
 PASS "data:,a, data:,b (  " 
 PASS "data:,a, data:,b (," 
 PASS "data:,a, data:,b (x" 
 PASS "data:,a, data:,b ()" 
-FAIL "data:,a (, data:,b" assert_equals: expected "" but got "data:,a"
-FAIL "data:,a /*, data:,b, data:,c */" assert_equals: expected "data:,b" but got "data:,a"
-FAIL "data:,a //, data:,b" assert_equals: expected "data:,b" but got "data:,a"
-FAIL "data:,a foo" assert_equals: expected "" but got "data:,a"
-FAIL "data:,a foo foo" assert_equals: expected "" but got "data:,a"
-FAIL "data:,a foo 1x" assert_equals: expected "" but got "data:,a"
-FAIL "data:,a foo 1x foo" assert_equals: expected "" but got "data:,a"
-FAIL "data:,a foo 1w" assert_equals: expected "" but got "data:,a"
-FAIL "data:,a foo 1w foo" assert_equals: expected "" but got "data:,a"
+PASS "data:,a (, data:,b" 
+PASS "data:,a /*, data:,b, data:,c */" 
+PASS "data:,a //, data:,b" 
+PASS "data:,a foo" 
+PASS "data:,a foo foo" 
+PASS "data:,a foo 1x" 
+PASS "data:,a foo 1x foo" 
+PASS "data:,a foo 1w" 
+PASS "data:,a foo 1w foo" 
 PASS "data:,a 1x 1x" 
 PASS "data:,a 1w 1w" 
 PASS "data:,a 1w 1x" 
@@ -57,22 +57,22 @@
 PASS "data:,a 1h 1w 1x" 
 PASS "data:,a 1x 1w 1h" 
 PASS "data:,a 1w" 
-FAIL "data:,a 1h" assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1h foo" assert_equals: expected "" but got "data:,a"
-FAIL "data:,a foo 1h" assert_equals: expected "" but got "data:,a"
+PASS "data:,a 1h" 
+PASS "data:,a 1h foo" 
+PASS "data:,a foo 1h" 
 PASS "data:,a 0w" 
 PASS "data:,a -1w" 
 PASS "data:,a 1w -1w" 
-FAIL "data:,a 1.0w" assert_equals: expected "" but got "data:,a"
+PASS "data:,a 1.0w" 
 PASS "data:,a 1w 1.0w" 
-FAIL "data:,a 1e0w" assert_equals: expected "" but got "data:,a"
+PASS "data:,a 1e0w" 
 PASS "data:,a 1w 1e0w" 
-FAIL "data:,a 1www" assert_equals: expected "" but got "data:,a"
+PASS "data:,a 1www" 
 PASS "data:,a 1w 1www" 
-FAIL "data:,a +1w" assert_equals: expected "" but got "data:,a"
+PASS "data:,a +1w" 
 PASS "data:,a 1w +1w" 
-FAIL "data:,a 1W" assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1W" assert_equals: expected "" but got "data:,a"
+PASS "data:,a 1W" 
+PASS "data:,a 1w 1W" 
 PASS "data:,a Infinityw" 
 PASS "data:,a 1w Infinityw" 
 PASS "data:,a NaNw" 
@@ -79,45 +79,45 @@
 PASS "data:,a 1w NaNw" 
 PASS "data:,a 0x1w" 
 PASS "data:,a 0X1w" 
-FAIL "data:,a 1\x01w" (trailing U+0001) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1 w" (trailing U+00A0) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1 w" (trailing U+1680) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1 w" (trailing U+2000) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1 w" (trailing U+2001) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1 w" (trailing U+2002) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1 w" (trailing U+2003) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1 w" (trailing U+2004) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1 w" (trailing U+2005) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1 w" (trailing U+2006) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1 w" (trailing U+2007) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1 w" (trailing U+2008) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1 w" (trailing U+2009) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1 w" (trailing U+200A) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1‌w" (trailing U+200C) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1‍w" (trailing U+200D) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1 w" (trailing U+202F) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1 w" (trailing U+205F) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1 w" (trailing U+3000) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w" (trailing U+FEFF) assert_equals: expected "" but got "data:,a"
+PASS "data:,a 1\x01w" (trailing U+0001) 
+PASS "data:,a 1 w" (trailing U+00A0) 
+PASS "data:,a 1 w" (trailing U+1680) 
+PASS "data:,a 1 w" (trailing U+2000) 
+PASS "data:,a 1 w" (trailing U+2001) 
+PASS "data:,a 1 w" (trailing U+2002) 
+PASS "data:,a 1 w" (trailing U+2003) 
+PASS "data:,a 1 w" (trailing U+2004) 
+PASS "data:,a 1 w" (trailing U+2005) 
+PASS "data:,a 1 w" (trailing U+2006) 
+PASS "data:,a 1 w" (trailing U+2007) 
+PASS "data:,a 1 w" (trailing U+2008) 
+PASS "data:,a 1 w" (trailing U+2009) 
+PASS "data:,a 1 w" (trailing U+200A) 
+PASS "data:,a 1‌w" (trailing U+200C) 
+PASS "data:,a 1‍w" (trailing U+200D) 
+PASS "data:,a 1 w" (trailing U+202F) 
+PASS "data:,a 1 w" (trailing U+205F) 
+PASS "data:,a 1 w" (trailing U+3000) 
+PASS "data:,a 1w" (trailing U+FEFF) 
 PASS "data:,a \x011w" (leading U+0001) 
 PASS "data:,a  1w" (leading U+00A0) 
-FAIL "data:,a  1w" (leading U+1680) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a  1w" (leading U+2000) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a  1w" (leading U+2001) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a  1w" (leading U+2002) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a  1w" (leading U+2003) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a  1w" (leading U+2004) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a  1w" (leading U+2005) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a  1w" (leading U+2006) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a  1w" (leading U+2007) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a  1w" (leading U+2008) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a  1w" (leading U+2009) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a  1w" (leading U+200A) assert_equals: expected "" but got "data:,a"
+PASS "data:,a  1w" (leading U+1680) 
+PASS "data:,a  1w" (leading U+2000) 
+PASS "data:,a  1w" (leading U+2001) 
+PASS "data:,a  1w" (leading U+2002) 
+PASS "data:,a  1w" (leading U+2003) 
+PASS "data:,a  1w" (leading U+2004) 
+PASS "data:,a  1w" (leading U+2005) 
+PASS "data:,a  1w" (leading U+2006) 
+PASS "data:,a  1w" (leading U+2007) 
+PASS "data:,a  1w" (leading U+2008) 
+PASS "data:,a  1w" (leading U+2009) 
+PASS "data:,a  1w" (leading U+200A) 
 PASS "data:,a ‌1w" (leading U+200C) 
 PASS "data:,a ‍1w" (leading U+200D) 
 PASS "data:,a  1w" (leading U+202F) 
-FAIL "data:,a  1w" (leading U+205F) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a  1w" (leading U+3000) assert_equals: expected "" but got "data:,a"
+PASS "data:,a  1w" (leading U+205F) 
+PASS "data:,a  1w" (leading U+3000) 
 PASS "data:,a 1w" (leading U+FEFF) 
 PASS "data:,a 0x" 
 PASS "data:,a -0x" 
@@ -131,7 +131,7 @@
 PASS "data:,a -x" 
 PASS "data:,a .x" 
 PASS "data:,a -.x" 
-FAIL "data:,a 1.x" assert_equals: expected "" but got "data:,a"
+PASS "data:,a 1.x" 
 PASS "data:,a .5x" 
 PASS "data:,a .5e1x" 
 PASS "data:,a 1x 1.5e1x" 
@@ -138,8 +138,8 @@
 PASS "data:,a 1x 1e1.5x" 
 PASS "data:,a 1.0x" 
 PASS "data:,a 1x 1.0x" 
-FAIL "data:,a +1x" assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1X" assert_equals: expected "" but got "data:,a"
+PASS "data:,a +1x" 
+PASS "data:,a 1X" 
 PASS "data:,a Infinityx" 
 PASS "data:,a NaNx" 
 PASS "data:,a 0x1x" 
@@ -186,53 +186,53 @@
 PASS "data:,a 1x" (leading U+FEFF) 
 PASS "data:,a 1w 0h" 
 PASS "data:,a 1w -1h" 
-FAIL "data:,a 1w 1.0h" assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1e0h" assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1hhh" assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w +1h" assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1H" assert_equals: expected "" but got "data:,a"
+PASS "data:,a 1w 1.0h" 
+PASS "data:,a 1w 1e0h" 
+PASS "data:,a 1w 1hhh" 
+PASS "data:,a 1w +1h" 
+PASS "data:,a 1w 1H" 
 PASS "data:,a 1w Infinityh" 
 PASS "data:,a 1w NaNh" 
 PASS "data:,a 0x1h" 
 PASS "data:,a 0X1h" 
-FAIL "data:,a 1w 1\x01h" (trailing U+0001) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1 h" (trailing U+00A0) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1 h" (trailing U+1680) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1 h" (trailing U+2000) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1 h" (trailing U+2001) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1 h" (trailing U+2002) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1 h" (trailing U+2003) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1 h" (trailing U+2004) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1 h" (trailing U+2005) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1 h" (trailing U+2006) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1 h" (trailing U+2007) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1 h" (trailing U+2008) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1 h" (trailing U+2009) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1 h" (trailing U+200A) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1‌h" (trailing U+200C) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1‍h" (trailing U+200D) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1 h" (trailing U+202F) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1 h" (trailing U+205F) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1 h" (trailing U+3000) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w 1h" (trailing U+FEFF) assert_equals: expected "" but got "data:,a"
+PASS "data:,a 1w 1\x01h" (trailing U+0001) 
+PASS "data:,a 1w 1 h" (trailing U+00A0) 
+PASS "data:,a 1w 1 h" (trailing U+1680) 
+PASS "data:,a 1w 1 h" (trailing U+2000) 
+PASS "data:,a 1w 1 h" (trailing U+2001) 
+PASS "data:,a 1w 1 h" (trailing U+2002) 
+PASS "data:,a 1w 1 h" (trailing U+2003) 
+PASS "data:,a 1w 1 h" (trailing U+2004) 
+PASS "data:,a 1w 1 h" (trailing U+2005) 
+PASS "data:,a 1w 1 h" (trailing U+2006) 
+PASS "data:,a 1w 1 h" (trailing U+2007) 
+PASS "data:,a 1w 1 h" (trailing U+2008) 
+PASS "data:,a 1w 1 h" (trailing U+2009) 
+PASS "data:,a 1w 1 h" (trailing U+200A) 
+PASS "data:,a 1w 1‌h" (trailing U+200C) 
+PASS "data:,a 1w 1‍h" (trailing U+200D) 
+PASS "data:,a 1w 1 h" (trailing U+202F) 
+PASS "data:,a 1w 1 h" (trailing U+205F) 
+PASS "data:,a 1w 1 h" (trailing U+3000) 
+PASS "data:,a 1w 1h" (trailing U+FEFF) 
 PASS "data:,a 1w \x011h" (leading U+0001) 
 PASS "data:,a 1w  1h" (leading U+00A0) 
-FAIL "data:,a 1w  1h" (leading U+1680) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w  1h" (leading U+2000) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w  1h" (leading U+2001) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w  1h" (leading U+2002) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w  1h" (leading U+2003) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w  1h" (leading U+2004) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w  1h" (leading U+2005) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w  1h" (leading U+2006) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w  1h" (leading U+2007) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w  1h" (leading U+2008) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w  1h" (leading U+2009) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w  1h" (leading U+200A) assert_equals: expected "" but got "data:,a"
+PASS "data:,a 1w  1h" (leading U+1680) 
+PASS "data:,a 1w  1h" (leading U+2000) 
+PASS "data:,a 1w  1h" (leading U+2001) 
+PASS "data:,a 1w  1h" (leading U+2002) 
+PASS "data:,a 1w  1h" (leading U+2003) 
+PASS "data:,a 1w  1h" (leading U+2004) 
+PASS "data:,a 1w  1h" (leading U+2005) 
+PASS "data:,a 1w  1h" (leading U+2006) 
+PASS "data:,a 1w  1h" (leading U+2007) 
+PASS "data:,a 1w  1h" (leading U+2008) 
+PASS "data:,a 1w  1h" (leading U+2009) 
+PASS "data:,a 1w  1h" (leading U+200A) 
 PASS "data:,a 1w ‌1h" (leading U+200C) 
 PASS "data:,a 1w ‍1h" (leading U+200D) 
 PASS "data:,a 1w  1h" (leading U+202F) 
-FAIL "data:,a 1w  1h" (leading U+205F) assert_equals: expected "" but got "data:,a"
-FAIL "data:,a 1w  1h" (leading U+3000) assert_equals: expected "" but got "data:,a"
+PASS "data:,a 1w  1h" (leading U+205F) 
+PASS "data:,a 1w  1h" (leading U+3000) 
 PASS "data:,a 1w 1h" (leading U+FEFF) 
                                                                                                                                                                                                                                              

Modified: trunk/Source/WebCore/ChangeLog (205514 => 205515)


--- trunk/Source/WebCore/ChangeLog	2016-09-06 22:19:51 UTC (rev 205514)
+++ trunk/Source/WebCore/ChangeLog	2016-09-06 22:59:29 UTC (rev 205515)
@@ -1,3 +1,45 @@
+2016-09-06  Chris Dumez  <[email protected]>
+
+        Align srcset attribute parsing with the HTML specification
+        https://bugs.webkit.org/show_bug.cgi?id=161636
+
+        Reviewed by Darin Adler.
+
+        Align srcset attribute parsing with the HTML specification:
+        - https://html.spec.whatwg.org/#parse-a-srcset-attribute
+
+        The new behavior is also consistent with Firefox and Chrome
+        as all 3 browsers now pass 100% of the checks at:
+        - http://w3c-test.org/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html
+
+        No new tests, rebaselined existing tests.
+
+        * html/parser/HTMLParserIdioms.cpp:
+        (WebCore::parseValidHTMLNonNegativeIntegerInternal):
+        (WebCore::parseValidHTMLNonNegativeInteger):
+        (WebCore::parseValidHTMLFloatingPointNumberInternal):
+        (WebCore::parseValidHTMLFloatingPointNumber):
+        * html/parser/HTMLParserIdioms.h:
+        Add convenience for parsing *valid* HTML non-negative integers and
+        *valid* floating point number values.
+
+        * html/parser/HTMLSrcsetParser.cpp:
+        (WebCore::parseDescriptors):
+        - Use parseValidHTMLFloatingPointNumber() to parse density so that the value
+          is parsed as a valid HTML floating point number value, as per the spec.
+        - Use parseValidHTMLNonNegativeInteger() to parse width and height so that
+          the value is parsed as a valid HTML non-negative integer value, as per the
+          spec.
+        - Return false if descriptor does not have a h, w and x at the end as per:
+          https://html.spec.whatwg.org/#parse-a-srcset-attribute (step 13: Anything else)
+        - Return false if height is set but not width, as per:
+          https://html.spec.whatwg.org/#parse-a-srcset-attribute (step 14)
+
+        (WebCore::parseImageCandidatesFromSrcsetAttribute):
+        - Skip whitespace if URL does not end with a comma instead of assuming there is
+          a single space character, as per:
+          https://html.spec.whatwg.org/#parse-a-srcset-attribute (step 8. Otherwise 1.)
+
 2016-09-06  Fujii Hironori  <[email protected]>
 
         [CMake] Decouple generating bindings of WebCore and WebCoreTestSupport

Modified: trunk/Source/WebCore/html/parser/HTMLParserIdioms.cpp (205514 => 205515)


--- trunk/Source/WebCore/html/parser/HTMLParserIdioms.cpp	2016-09-06 22:19:51 UTC (rev 205514)
+++ trunk/Source/WebCore/html/parser/HTMLParserIdioms.cpp	2016-09-06 22:59:29 UTC (rev 205515)
@@ -216,6 +216,67 @@
     return signedValue;
 }
 
+template <typename CharacterType>
+static Optional<int> parseValidHTMLNonNegativeIntegerInternal(const CharacterType* position, const CharacterType* end)
+{
+    // A string is a valid non-negative integer if it consists of one or more ASCII digits.
+    for (auto* c = position; c < end; ++c) {
+        if (!isASCIIDigit(*c))
+            return Nullopt;
+    }
+
+    Optional<int> signedValue = parseHTMLIntegerInternal(position, end);
+    if (!signedValue || signedValue.value() < 0)
+        return Nullopt;
+
+    return signedValue;
+}
+
+// https://html.spec.whatwg.org/#valid-non-negative-integer
+Optional<int> parseValidHTMLNonNegativeInteger(StringView input)
+{
+    if (input.isEmpty())
+        return Nullopt;
+
+    if (LIKELY(input.is8Bit())) {
+        auto* start = input.characters8();
+        return parseValidHTMLNonNegativeIntegerInternal(start, start + input.length());
+    }
+
+    auto* start = input.characters16();
+    return parseValidHTMLNonNegativeIntegerInternal(start, start + input.length());
+}
+
+template <typename CharacterType>
+static Optional<double> parseValidHTMLFloatingPointNumberInternal(const CharacterType* position, size_t length)
+{
+    ASSERT(length > 0);
+
+    // parseDouble() allows the string to start with a '+' or to end with a '.' but those
+    // are not valid floating point numbers as per HTML.
+    if (*position == '+' || *(position + length - 1) == '.')
+        return Nullopt;
+
+    size_t parsedLength = 0;
+    double number = parseDouble(position, length, parsedLength);
+    return parsedLength == length && std::isfinite(number) ? number : Optional<double>();
+}
+
+// https://html.spec.whatwg.org/#valid-floating-point-number
+Optional<double> parseValidHTMLFloatingPointNumber(StringView input)
+{
+    if (input.isEmpty())
+        return Nullopt;
+
+    if (LIKELY(input.is8Bit())) {
+        auto* start = input.characters8();
+        return parseValidHTMLFloatingPointNumberInternal(start, input.length());
+    }
+
+    auto* start = input.characters16();
+    return parseValidHTMLFloatingPointNumberInternal(start, input.length());
+}
+
 static inline bool isHTMLSpaceOrDelimiter(UChar character)
 {
     return isHTMLSpace(character) || character == ',' || character == ';';

Modified: trunk/Source/WebCore/html/parser/HTMLParserIdioms.h (205514 => 205515)


--- trunk/Source/WebCore/html/parser/HTMLParserIdioms.h	2016-09-06 22:19:51 UTC (rev 205514)
+++ trunk/Source/WebCore/html/parser/HTMLParserIdioms.h	2016-09-06 22:59:29 UTC (rev 205515)
@@ -67,6 +67,12 @@
 // http://www.whatwg.org/specs/web-apps/current-work/#rules-for-parsing-non-negative-integers
 WEBCORE_EXPORT Optional<int> parseHTMLNonNegativeInteger(const String&);
 
+// https://html.spec.whatwg.org/#valid-non-negative-integer
+Optional<int> parseValidHTMLNonNegativeInteger(StringView);
+
+// https://html.spec.whatwg.org/#valid-floating-point-number
+Optional<double> parseValidHTMLFloatingPointNumber(StringView);
+
 // https://html.spec.whatwg.org/multipage/infrastructure.html#rules-for-parsing-floating-point-number-values
 Vector<double> parseHTMLListOfOfFloatingPointNumberValues(StringView);
 

Modified: trunk/Source/WebCore/html/parser/HTMLSrcsetParser.cpp (205514 => 205515)


--- trunk/Source/WebCore/html/parser/HTMLSrcsetParser.cpp	2016-09-06 22:19:51 UTC (rev 205514)
+++ trunk/Source/WebCore/html/parser/HTMLSrcsetParser.cpp	2016-09-06 22:59:29 UTC (rev 205515)
@@ -131,33 +131,33 @@
         unsigned descriptorCharPosition = descriptor.length() - 1;
         UChar descriptorChar = descriptor[descriptorCharPosition];
         descriptor = descriptor.substring(0, descriptorCharPosition);
-        bool isValid = false;
         if (descriptorChar == 'x') {
             if (result.hasDensity() || result.hasHeight() || result.hasWidth())
                 return false;
-            float density = descriptor.toFloat(isValid);
-            if (!isValid || density < 0)
+            Optional<double> density = parseValidHTMLFloatingPointNumber(descriptor);
+            if (!density || density.value() < 0)
                 return false;
-            result.setDensity(density);
+            result.setDensity(density.value());
         } else if (descriptorChar == 'w') {
             if (result.hasDensity() || result.hasWidth())
                 return false;
-            int resourceWidth = descriptor.toInt(isValid);
-            if (!isValid || resourceWidth <= 0)
+            Optional<int> resourceWidth = parseValidHTMLNonNegativeInteger(descriptor);
+            if (!resourceWidth || resourceWidth.value() <= 0)
                 return false;
-            result.setResourceWidth(resourceWidth);
+            result.setResourceWidth(resourceWidth.value());
         } else if (descriptorChar == 'h') {
             // This is here only for future compat purposes.
             // The value of the 'h' descriptor is not used.
             if (result.hasDensity() || result.hasHeight())
                 return false;
-            int resourceHeight = descriptor.toInt(isValid);
-            if (!isValid || resourceHeight <= 0)
+            Optional<int> resourceHeight = parseValidHTMLNonNegativeInteger(descriptor);
+            if (!resourceHeight || resourceHeight.value() <= 0)
                 return false;
-            result.setResourceHeight(resourceHeight);
-        }
+            result.setResourceHeight(resourceHeight.value());
+        } else
+            return false;
     }
-    return true;
+    return !result.hasHeight() || result.hasWidth();
 }
 
 // http://picture.responsiveimages.org/#parse-srcset-attr
@@ -193,9 +193,7 @@
             if (imageURLStart == imageURLEnd)
                 continue;
         } else {
-            // Advancing position here (contrary to spec) to avoid an useless extra state machine step.
-            // Filed a spec bug: https://github.com/ResponsiveImagesCG/picture-element/issues/189
-            ++position;
+            skipWhile<CharType, isHTMLSpace<CharType>>(position, attributeEnd);
             Vector<StringView> descriptorTokens;
             tokenizeDescriptors(position, attributeEnd, descriptorTokens);
             // Contrary to spec language - descriptor parsing happens on each candidate.
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to