Unreviewed, rolling out r207795.
authorryanhaddad@apple.com <ryanhaddad@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 25 Oct 2016 03:46:32 +0000 (03:46 +0000)
committerryanhaddad@apple.com <ryanhaddad@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 25 Oct 2016 03:46:32 +0000 (03:46 +0000)
Introduced API test failures on iOS and macOS.

Reverted changeset:

"URLParser should match old URL::parse with %2E in path"
https://bugs.webkit.org/show_bug.cgi?id=163929
http://trac.webkit.org/changeset/207795

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

12 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/url/path-expected.txt
LayoutTests/fast/url/standard-url-expected.txt
LayoutTests/fetch/fetch-url-serialization-expected.txt
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/url/a-element-expected.txt
LayoutTests/imported/w3c/web-platform-tests/url/a-element-xhtml-expected.txt
LayoutTests/imported/w3c/web-platform-tests/url/url-constructor-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/platform/URLParser.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebCore/URLParser.cpp

index 89328d8fc3082df11d7cff566aea6a1639455682..87d88e5bd6957ec9e6bc6d4340d67691bcd32862 100644 (file)
@@ -1,3 +1,15 @@
+2016-10-24  Ryan Haddad  <ryanhaddad@apple.com>
+
+        Unreviewed, rolling out r207795.
+
+        Introduced API test failures on iOS and macOS.
+
+        Reverted changeset:
+
+        "URLParser should match old URL::parse with %2E in path"
+        https://bugs.webkit.org/show_bug.cgi?id=163929
+        http://trac.webkit.org/changeset/207795
+
 2016-10-24  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         Arrow functions with concise bodies cannot return regular expressions
index e9b357d6f9f8c3fd2b876c84b44ad8770b9db911..7060c69ebf44d4fa83243d7129d5f7efd7f9575f 100644 (file)
@@ -14,9 +14,9 @@ PASS canonicalize('http://example.com/foo/bar/../ton') is 'http://example.com/fo
 PASS canonicalize('http://example.com/foo/bar/../ton/../../a') is 'http://example.com/a'
 PASS canonicalize('http://example.com/foo/../../..') is 'http://example.com/'
 PASS canonicalize('http://example.com/foo/../../../ton') is 'http://example.com/ton'
-FAIL canonicalize('http://example.com/foo/%2e') should be http://example.com/foo/. Was http://example.com/foo/%2e.
-FAIL canonicalize('http://example.com/foo/%2e%2') should be http://example.com/foo/.%2. Was http://example.com/foo/%2e%2.
-FAIL canonicalize('http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar') should be http://example.com/..bar. Was http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar.
+PASS canonicalize('http://example.com/foo/%2e') is 'http://example.com/foo/'
+PASS canonicalize('http://example.com/foo/%2e%2') is 'http://example.com/foo/.%2'
+PASS canonicalize('http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar') is 'http://example.com/..bar'
 PASS canonicalize('http://example.com////../..') is 'http://example.com//'
 PASS canonicalize('http://example.com/foo/bar//../..') is 'http://example.com/foo/'
 PASS canonicalize('http://example.com/foo/bar//..') is 'http://example.com/foo/bar/'
index 06d4613b35a5a607b2211151bf4ca2644bf5aed5..6a3cff2def9f310ae112b22133b5c9c30a37cce4 100644 (file)
@@ -9,7 +9,7 @@ PASS canonicalize('http://[www.google.com]/') is 'http://[www.google.com]/'
 PASS canonicalize('http://www.google.com') is 'http://www.google.com/'
 PASS canonicalize('http:////////user:@google.com:99?foo') is 'http://user@google.com:99/?foo'
 PASS canonicalize('http://192.0x00A80001') is 'http://192.168.0.1/'
-FAIL canonicalize('http://www/foo%2Ehtml') should be http://www/foo.html. Was http://www/foo%2Ehtml.
+PASS canonicalize('http://www/foo%2Ehtml') is 'http://www/foo.html'
 PASS canonicalize('http://user:pass@/') is 'http://user:pass@/'
 PASS canonicalize('http://%25DOMAIN:foobar@foodomain.com/') is 'http://%25DOMAIN:foobar@foodomain.com/'
 PASS canonicalize('http:\\\\www.google.com\\foo') is 'http://www.google.com/foo'
index 33c02f659efe4d36295253edc8cd33f0c863ca41..7caddac71fddac783233833ba6fa073d59ddee59 100644 (file)
@@ -123,9 +123,9 @@ PASS Testing Request url 'http://example.com/foo/bar/../ton' with base 'about:bl
 PASS Testing Request url 'http://example.com/foo/bar/../ton/../../a' with base 'about:blank' 
 PASS Testing Request url 'http://example.com/foo/../../..' with base 'about:blank' 
 PASS Testing Request url 'http://example.com/foo/../../../ton' with base 'about:blank' 
-FAIL Testing Request url 'http://example.com/foo/%2e' with base 'about:blank' assert_equals: expected "http://example.com/foo/" but got "http://example.com/foo/%2e"
-FAIL Testing Request url 'http://example.com/foo/%2e%2' with base 'about:blank' assert_equals: expected "http://example.com/foo/.%2" but got "http://example.com/foo/%2e%2"
-FAIL Testing Request url 'http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar' with base 'about:blank' assert_equals: expected "http://example.com/..bar" but got "http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar"
+PASS Testing Request url 'http://example.com/foo/%2e' with base 'about:blank' 
+PASS Testing Request url 'http://example.com/foo/%2e%2' with base 'about:blank' 
+PASS Testing Request url 'http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar' with base 'about:blank' 
 PASS Testing Request url 'http://example.com////../..' with base 'about:blank' 
 PASS Testing Request url 'http://example.com/foo/bar//../..' with base 'about:blank' 
 PASS Testing Request url 'http://example.com/foo/bar//..' with base 'about:blank' 
@@ -154,8 +154,8 @@ FAIL Testing Request url 'data:test# »' with base 'about:blank' assert_equals:
 PASS Testing Request url 'http://[www.google.com]/' with base 'about:blank' 
 PASS Testing Request url 'http://www.google.com' with base 'about:blank' 
 PASS Testing Request url 'http://192.0x00A80001' with base 'about:blank' 
-FAIL Testing Request url 'http://www/foo%2Ehtml' with base 'about:blank' assert_equals: expected "http://www/foo.html" but got "http://www/foo%2Ehtml"
-FAIL Testing Request url 'http://www/foo/%2E/html' with base 'about:blank' assert_equals: expected "http://www/foo/html" but got "http://www/foo/%2E/html"
+PASS Testing Request url 'http://www/foo%2Ehtml' with base 'about:blank' 
+PASS Testing Request url 'http://www/foo/%2E/html' with base 'about:blank' 
 PASS Testing Request url 'http://user:pass@/' with base 'about:blank' 
 PASS Testing Request url 'http://%25DOMAIN:foobar@foodomain.com/' with base 'about:blank' 
 PASS Testing Request url 'http:\\www.google.com\foo' with base 'about:blank' 
index 03d806ed9971a6a9763d3d5b12a8c43d47bdf30f..29a67b4258e7f170046d3a10778a94ad49856c9a 100644 (file)
@@ -1,3 +1,15 @@
+2016-10-24  Ryan Haddad  <ryanhaddad@apple.com>
+
+        Unreviewed, rolling out r207795.
+
+        Introduced API test failures on iOS and macOS.
+
+        Reverted changeset:
+
+        "URLParser should match old URL::parse with %2E in path"
+        https://bugs.webkit.org/show_bug.cgi?id=163929
+        http://trac.webkit.org/changeset/207795
+
 2016-10-24  Alex Christensen  <achristensen@webkit.org>
 
         URLParser should match old URL::parse with %2E in path
index 0c934a263aba83b39eafb1426b3da2bd8f6a096a..40a911f9c0c8f870421171de0b63495b6ce9835a 100644 (file)
@@ -126,9 +126,9 @@ PASS Parsing: <http://example.com/foo/bar/../ton> against <about:blank>
 PASS Parsing: <http://example.com/foo/bar/../ton/../../a> against <about:blank> 
 PASS Parsing: <http://example.com/foo/../../..> against <about:blank> 
 PASS Parsing: <http://example.com/foo/../../../ton> against <about:blank> 
-FAIL Parsing: <http://example.com/foo/%2e> against <about:blank> assert_equals: href expected "http://example.com/foo/" but got "http://example.com/foo/%2e"
-FAIL Parsing: <http://example.com/foo/%2e%2> against <about:blank> assert_equals: href expected "http://example.com/foo/.%2" but got "http://example.com/foo/%2e%2"
-FAIL Parsing: <http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar> against <about:blank> assert_equals: href expected "http://example.com/..bar" but got "http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar"
+PASS Parsing: <http://example.com/foo/%2e> against <about:blank> 
+PASS Parsing: <http://example.com/foo/%2e%2> against <about:blank> 
+PASS Parsing: <http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar> against <about:blank> 
 PASS Parsing: <http://example.com////../..> against <about:blank> 
 PASS Parsing: <http://example.com/foo/bar//../..> against <about:blank> 
 PASS Parsing: <http://example.com/foo/bar//..> against <about:blank> 
@@ -157,8 +157,8 @@ FAIL Parsing: <data:test# »> against <about:blank> assert_equals: href expected
 PASS Parsing: <http://[www.google.com]/> against <about:blank> 
 PASS Parsing: <http://www.google.com> against <about:blank> 
 PASS Parsing: <http://192.0x00A80001> against <about:blank> 
-FAIL Parsing: <http://www/foo%2Ehtml> against <about:blank> assert_equals: href expected "http://www/foo.html" but got "http://www/foo%2Ehtml"
-FAIL Parsing: <http://www/foo/%2E/html> against <about:blank> assert_equals: href expected "http://www/foo/html" but got "http://www/foo/%2E/html"
+PASS Parsing: <http://www/foo%2Ehtml> against <about:blank> 
+PASS Parsing: <http://www/foo/%2E/html> against <about:blank> 
 PASS Parsing: <http://user:pass@/> against <about:blank> 
 PASS Parsing: <http://%25DOMAIN:foobar@foodomain.com/> against <about:blank> 
 PASS Parsing: <http:\\www.google.com\foo> against <about:blank> 
index 0c934a263aba83b39eafb1426b3da2bd8f6a096a..40a911f9c0c8f870421171de0b63495b6ce9835a 100644 (file)
@@ -126,9 +126,9 @@ PASS Parsing: <http://example.com/foo/bar/../ton> against <about:blank>
 PASS Parsing: <http://example.com/foo/bar/../ton/../../a> against <about:blank> 
 PASS Parsing: <http://example.com/foo/../../..> against <about:blank> 
 PASS Parsing: <http://example.com/foo/../../../ton> against <about:blank> 
-FAIL Parsing: <http://example.com/foo/%2e> against <about:blank> assert_equals: href expected "http://example.com/foo/" but got "http://example.com/foo/%2e"
-FAIL Parsing: <http://example.com/foo/%2e%2> against <about:blank> assert_equals: href expected "http://example.com/foo/.%2" but got "http://example.com/foo/%2e%2"
-FAIL Parsing: <http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar> against <about:blank> assert_equals: href expected "http://example.com/..bar" but got "http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar"
+PASS Parsing: <http://example.com/foo/%2e> against <about:blank> 
+PASS Parsing: <http://example.com/foo/%2e%2> against <about:blank> 
+PASS Parsing: <http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar> against <about:blank> 
 PASS Parsing: <http://example.com////../..> against <about:blank> 
 PASS Parsing: <http://example.com/foo/bar//../..> against <about:blank> 
 PASS Parsing: <http://example.com/foo/bar//..> against <about:blank> 
@@ -157,8 +157,8 @@ FAIL Parsing: <data:test# »> against <about:blank> assert_equals: href expected
 PASS Parsing: <http://[www.google.com]/> against <about:blank> 
 PASS Parsing: <http://www.google.com> against <about:blank> 
 PASS Parsing: <http://192.0x00A80001> against <about:blank> 
-FAIL Parsing: <http://www/foo%2Ehtml> against <about:blank> assert_equals: href expected "http://www/foo.html" but got "http://www/foo%2Ehtml"
-FAIL Parsing: <http://www/foo/%2E/html> against <about:blank> assert_equals: href expected "http://www/foo/html" but got "http://www/foo/%2E/html"
+PASS Parsing: <http://www/foo%2Ehtml> against <about:blank> 
+PASS Parsing: <http://www/foo/%2E/html> against <about:blank> 
 PASS Parsing: <http://user:pass@/> against <about:blank> 
 PASS Parsing: <http://%25DOMAIN:foobar@foodomain.com/> against <about:blank> 
 PASS Parsing: <http:\\www.google.com\foo> against <about:blank> 
index 01c8060cbb287525ded035d6e247f2fa5ae9a433..64f6872c8edcb5723528b808717c5c08306fced6 100644 (file)
@@ -130,9 +130,9 @@ PASS Parsing: <http://example.com/foo/bar/../ton> against <about:blank>
 PASS Parsing: <http://example.com/foo/bar/../ton/../../a> against <about:blank> 
 PASS Parsing: <http://example.com/foo/../../..> against <about:blank> 
 PASS Parsing: <http://example.com/foo/../../../ton> against <about:blank> 
-FAIL Parsing: <http://example.com/foo/%2e> against <about:blank> assert_equals: href expected "http://example.com/foo/" but got "http://example.com/foo/%2e"
-FAIL Parsing: <http://example.com/foo/%2e%2> against <about:blank> assert_equals: href expected "http://example.com/foo/.%2" but got "http://example.com/foo/%2e%2"
-FAIL Parsing: <http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar> against <about:blank> assert_equals: href expected "http://example.com/..bar" but got "http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar"
+PASS Parsing: <http://example.com/foo/%2e> against <about:blank> 
+PASS Parsing: <http://example.com/foo/%2e%2> against <about:blank> 
+PASS Parsing: <http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar> against <about:blank> 
 PASS Parsing: <http://example.com////../..> against <about:blank> 
 PASS Parsing: <http://example.com/foo/bar//../..> against <about:blank> 
 PASS Parsing: <http://example.com/foo/bar//..> against <about:blank> 
@@ -161,8 +161,8 @@ FAIL Parsing: <data:test# »> against <about:blank> assert_equals: href expected
 PASS Parsing: <http://[www.google.com]/> against <about:blank> 
 PASS Parsing: <http://www.google.com> against <about:blank> 
 PASS Parsing: <http://192.0x00A80001> against <about:blank> 
-FAIL Parsing: <http://www/foo%2Ehtml> against <about:blank> assert_equals: href expected "http://www/foo.html" but got "http://www/foo%2Ehtml"
-FAIL Parsing: <http://www/foo/%2E/html> against <about:blank> assert_equals: href expected "http://www/foo/html" but got "http://www/foo/%2E/html"
+PASS Parsing: <http://www/foo%2Ehtml> against <about:blank> 
+PASS Parsing: <http://www/foo/%2E/html> against <about:blank> 
 PASS Parsing: <http://user:pass@/> against <about:blank> 
 PASS Parsing: <http://%25DOMAIN:foobar@foodomain.com/> against <about:blank> 
 PASS Parsing: <http:\\www.google.com\foo> against <about:blank> 
index a32a06ea478b705e2725ce2503714e15a0508157..4ca4985278b7c19520187018f6b5967b2b13d768 100644 (file)
@@ -1,3 +1,15 @@
+2016-10-24  Ryan Haddad  <ryanhaddad@apple.com>
+
+        Unreviewed, rolling out r207795.
+
+        Introduced API test failures on iOS and macOS.
+
+        Reverted changeset:
+
+        "URLParser should match old URL::parse with %2E in path"
+        https://bugs.webkit.org/show_bug.cgi?id=163929
+        http://trac.webkit.org/changeset/207795
+
 2016-10-24  Yusuke Suzuki  <utatane.tea@gmail.com>
 
         Unreviewed, attempt to fix Windows build after r207787
index 48281b7fa354dc1583b7afe493a3c4eaee049c4e..a4f55e4e01e24e68fe52fcb3ea20e713bc4ed4a2 100644 (file)
@@ -891,6 +891,26 @@ void URLParser::copyURLPartsUntil(const URL& base, URLPart part, const CodePoint
     ASSERT_NOT_REACHED();
 }
 
+static const char* dotASCIICode = "2e";
+
+template<typename CharacterType>
+ALWAYS_INLINE bool URLParser::isPercentEncodedDot(CodePointIterator<CharacterType> c)
+{
+    if (c.atEnd())
+        return false;
+    if (*c != '%')
+        return false;
+    advance<CharacterType, ReportSyntaxViolation::No>(c);
+    if (c.atEnd())
+        return false;
+    if (*c != dotASCIICode[0])
+        return false;
+    advance<CharacterType, ReportSyntaxViolation::No>(c);
+    if (c.atEnd())
+        return false;
+    return toASCIILower(*c) == dotASCIICode[1];
+}
+
 template<typename CharacterType>
 ALWAYS_INLINE bool URLParser::isSingleDotPathSegment(CodePointIterator<CharacterType> c)
 {
@@ -900,6 +920,18 @@ ALWAYS_INLINE bool URLParser::isSingleDotPathSegment(CodePointIterator<Character
         advance<CharacterType, ReportSyntaxViolation::No>(c);
         return c.atEnd() || isSlashQuestionOrHash(*c);
     }
+    if (*c != '%')
+        return false;
+    advance<CharacterType, ReportSyntaxViolation::No>(c);
+    if (c.atEnd() || *c != dotASCIICode[0])
+        return false;
+    advance<CharacterType, ReportSyntaxViolation::No>(c);
+    if (c.atEnd())
+        return false;
+    if (toASCIILower(*c) == dotASCIICode[1]) {
+        advance<CharacterType, ReportSyntaxViolation::No>(c);
+        return c.atEnd() || isSlashQuestionOrHash(*c);
+    }
     return false;
 }
 
@@ -912,6 +944,18 @@ ALWAYS_INLINE bool URLParser::isDoubleDotPathSegment(CodePointIterator<Character
         advance<CharacterType, ReportSyntaxViolation::No>(c);
         return isSingleDotPathSegment(c);
     }
+    if (*c != '%')
+        return false;
+    advance<CharacterType, ReportSyntaxViolation::No>(c);
+    if (c.atEnd() || *c != dotASCIICode[0])
+        return false;
+    advance<CharacterType, ReportSyntaxViolation::No>(c);
+    if (c.atEnd())
+        return false;
+    if (toASCIILower(*c) == dotASCIICode[1]) {
+        advance<CharacterType, ReportSyntaxViolation::No>(c);
+        return isSingleDotPathSegment(c);
+    }
     return false;
 }
 
@@ -919,12 +963,27 @@ template<typename CharacterType>
 void URLParser::consumeSingleDotPathSegment(CodePointIterator<CharacterType>& c)
 {
     ASSERT(isSingleDotPathSegment(c));
-    advance(c);
-    if (!c.atEnd()) {
-        if (*c == '/' || *c == '\\')
-            advance(c);
-        else
-            ASSERT(*c == '?' || *c == '#');
+    if (*c == '.') {
+        advance(c);
+        if (!c.atEnd()) {
+            if (*c == '/' || *c == '\\')
+                advance(c);
+            else
+                ASSERT(*c == '?' || *c == '#');
+        }
+    } else {
+        ASSERT(*c == '%');
+        advance(c);
+        ASSERT(*c == dotASCIICode[0]);
+        advance(c);
+        ASSERT(toASCIILower(*c) == dotASCIICode[1]);
+        advance(c);
+        if (!c.atEnd()) {
+            if (*c == '/' || *c == '\\')
+                advance(c);
+            else
+                ASSERT(*c == '?' || *c == '#');
+        }
     }
 }
 
@@ -932,7 +991,16 @@ template<typename CharacterType>
 void URLParser::consumeDoubleDotPathSegment(CodePointIterator<CharacterType>& c)
 {
     ASSERT(isDoubleDotPathSegment(c));
-    advance(c);
+    if (*c == '.')
+        advance(c);
+    else {
+        ASSERT(*c == '%');
+        advance(c);
+        ASSERT(*c == dotASCIICode[0]);
+        advance(c);
+        ASSERT(toASCIILower(*c) == dotASCIICode[1]);
+        advance(c);
+    }
     consumeSingleDotPathSegment(c);
 }
 
@@ -1655,6 +1723,17 @@ void URLParser::parse(const CharacterType* input, const unsigned length, const U
                 state = State::Fragment;
                 break;
             }
+            if (UNLIKELY(isPercentEncodedDot(c))) {
+                syntaxViolation(c);
+                appendToASCIIBuffer('.');
+                ASSERT(*c == '%');
+                advance(c);
+                ASSERT(*c == dotASCIICode[0]);
+                advance(c);
+                ASSERT(toASCIILower(*c) == dotASCIICode[1]);
+                advance(c);
+                break;
+            }
             utf8PercentEncode<isInDefaultEncodeSet>(c);
             ++c;
             break;
@@ -2789,8 +2868,6 @@ void URLParser::setEnabled(bool enabled)
 
 bool URLParser::enabled()
 {
-    return true;
-    /*
     if (urlParserEnabled == URLParserEnabled::Undetermined) {
 #if PLATFORM(MAC)
         urlParserEnabled = MacApplication::isSafari() ? URLParserEnabled::Yes : URLParserEnabled::No;
@@ -2801,7 +2878,6 @@ bool URLParser::enabled()
 #endif
     }
     return urlParserEnabled == URLParserEnabled::Yes;
-     */
 }
 
 } // namespace WebCore
index a0e7e073d2af1834ff7d2b3c2955576fac956185..deaa4df28a6a2ae258222ff2fa5b145c0060d049 100644 (file)
@@ -1,3 +1,15 @@
+2016-10-24  Ryan Haddad  <ryanhaddad@apple.com>
+
+        Unreviewed, rolling out r207795.
+
+        Introduced API test failures on iOS and macOS.
+
+        Reverted changeset:
+
+        "URLParser should match old URL::parse with %2E in path"
+        https://bugs.webkit.org/show_bug.cgi?id=163929
+        http://trac.webkit.org/changeset/207795
+
 2016-10-24  Alex Christensen  <achristensen@webkit.org>
 
         URLParser should match old URL::parse with %2E in path
index 95be5e5232ea8d9f582916da2f29b010814ec6fd..f3dcddfec9acedc123ea45a63c397a268ce80e07 100644 (file)
@@ -596,18 +596,42 @@ TEST_F(URLParserTest, ParserDifferences)
     checkURLDifferences("http://127.0.0.01/",
         {"http", "", "", "127.0.0.1", 0, "/", "", "", "http://127.0.0.1/"},
         {"http", "", "", "127.0.0.01", 0, "/", "", "", "http://127.0.0.01/"});
-    checkURL("http://example.com/path1/.%2e", {"http", "", "", "example.com", 0, "/path1/.%2e", "", "", "http://example.com/path1/.%2e"});
-    checkURL("http://example.com/path1/.%2E", {"http", "", "", "example.com", 0, "/path1/.%2E", "", "", "http://example.com/path1/.%2E"});
-    checkURL("http://example.com/path1/.%2E/", {"http", "", "", "example.com", 0, "/path1/.%2E/", "", "", "http://example.com/path1/.%2E/"});
-    checkURL("http://example.com/path1/%2e.", {"http", "", "", "example.com", 0, "/path1/%2e.", "", "", "http://example.com/path1/%2e."});
-    checkURL("http://example.com/path1/%2E%2e", {"http", "", "", "example.com", 0, "/path1/%2E%2e", "", "", "http://example.com/path1/%2E%2e"});
-    checkURL("http://example.com/path1/%2e", {"http", "", "", "example.com", 0, "/path1/%2e", "", "", "http://example.com/path1/%2e"});
-    checkURL("http://example.com/path1/%2E", {"http", "", "", "example.com", 0, "/path1/%2E", "", "", "http://example.com/path1/%2E"});
-    checkURL("http://example.com/path1/%2E/", {"http", "", "", "example.com", 0, "/path1/%2E/", "", "", "http://example.com/path1/%2E/"});
-    checkURL("http://example.com/path1/path2/%2e?query", {"http", "", "", "example.com", 0, "/path1/path2/%2e", "query", "", "http://example.com/path1/path2/%2e?query"});
-    checkURL("http://example.com/path1/path2/%2e%2e?query", {"http", "", "", "example.com", 0, "/path1/path2/%2e%2e", "query", "", "http://example.com/path1/path2/%2e%2e?query"});
-    checkURL("http://example.com/path1/path2/%2e#fragment", {"http", "", "", "example.com", 0, "/path1/path2/%2e", "", "fragment", "http://example.com/path1/path2/%2e#fragment"});
-    checkURL("http://example.com/path1/path2/%2e%2e#fragment", {"http", "", "", "example.com", 0, "/path1/path2/%2e%2e", "", "fragment", "http://example.com/path1/path2/%2e%2e#fragment"});
+    checkURLDifferences("http://example.com/path1/.%2e",
+        {"http", "", "", "example.com", 0, "/", "", "", "http://example.com/"},
+        {"http", "", "", "example.com", 0, "/path1/.%2e", "", "", "http://example.com/path1/.%2e"});
+    checkURLDifferences("http://example.com/path1/.%2E",
+        {"http", "", "", "example.com", 0, "/", "", "", "http://example.com/"},
+        {"http", "", "", "example.com", 0, "/path1/.%2E", "", "", "http://example.com/path1/.%2E"});
+    checkURLDifferences("http://example.com/path1/.%2E/",
+        {"http", "", "", "example.com", 0, "/", "", "", "http://example.com/"},
+        {"http", "", "", "example.com", 0, "/path1/.%2E/", "", "", "http://example.com/path1/.%2E/"});
+    checkURLDifferences("http://example.com/path1/%2e.",
+        {"http", "", "", "example.com", 0, "/", "", "", "http://example.com/"},
+        {"http", "", "", "example.com", 0, "/path1/%2e.", "", "", "http://example.com/path1/%2e."});
+    checkURLDifferences("http://example.com/path1/%2E%2e",
+        {"http", "", "", "example.com", 0, "/", "", "", "http://example.com/"},
+        {"http", "", "", "example.com", 0, "/path1/%2E%2e", "", "", "http://example.com/path1/%2E%2e"});
+    checkURLDifferences("http://example.com/path1/%2e",
+        {"http", "", "", "example.com", 0, "/path1/", "", "", "http://example.com/path1/"},
+        {"http", "", "", "example.com", 0, "/path1/%2e", "", "", "http://example.com/path1/%2e"});
+    checkURLDifferences("http://example.com/path1/%2E",
+        {"http", "", "", "example.com", 0, "/path1/", "", "", "http://example.com/path1/"},
+        {"http", "", "", "example.com", 0, "/path1/%2E", "", "", "http://example.com/path1/%2E"});
+    checkURLDifferences("http://example.com/path1/%2E/",
+        {"http", "", "", "example.com", 0, "/path1/", "", "", "http://example.com/path1/"},
+        {"http", "", "", "example.com", 0, "/path1/%2E/", "", "", "http://example.com/path1/%2E/"});
+    checkURLDifferences("http://example.com/path1/path2/%2e?query",
+        {"http", "", "", "example.com", 0, "/path1/path2/", "query", "", "http://example.com/path1/path2/?query"},
+        {"http", "", "", "example.com", 0, "/path1/path2/%2e", "query", "", "http://example.com/path1/path2/%2e?query"});
+    checkURLDifferences("http://example.com/path1/path2/%2e%2e?query",
+        {"http", "", "", "example.com", 0, "/path1/", "query", "", "http://example.com/path1/?query"},
+        {"http", "", "", "example.com", 0, "/path1/path2/%2e%2e", "query", "", "http://example.com/path1/path2/%2e%2e?query"});
+    checkURLDifferences("http://example.com/path1/path2/%2e#fragment",
+        {"http", "", "", "example.com", 0, "/path1/path2/", "", "fragment", "http://example.com/path1/path2/#fragment"},
+        {"http", "", "", "example.com", 0, "/path1/path2/%2e", "", "fragment", "http://example.com/path1/path2/%2e#fragment"});
+    checkURLDifferences("http://example.com/path1/path2/%2e%2e#fragment",
+        {"http", "", "", "example.com", 0, "/path1/", "", "fragment", "http://example.com/path1/#fragment"},
+        {"http", "", "", "example.com", 0, "/path1/path2/%2e%2e", "", "fragment", "http://example.com/path1/path2/%2e%2e#fragment"});
     checkURLDifferences("file://[0:a:0:0:b:c:0:0]/path",
         {"file", "", "", "[0:a::b:c:0:0]", 0, "/path", "", "", "file://[0:a::b:c:0:0]/path"},
         {"file", "", "", "[0:a:0:0:b:c:0:0]", 0, "/path", "", "", "file://[0:a:0:0:b:c:0:0]/path"});
@@ -710,8 +734,9 @@ TEST_F(URLParserTest, ParserDifferences)
     checkURLDifferences(utf16String(u"http://0Xc0.0250.01"),
         {"http", "", "", "192.168.0.1", 0, "/", "", "", "http://192.168.0.1/"},
         {"http", "", "", "0xc0.0250.01", 0, "/", "", "", "http://0xc0.0250.01/"});
-
-    checkURL("http://host/path%2e.%2E", {"http", "", "", "host", 0, "/path%2e.%2E", "", "", "http://host/path%2e.%2E"});
+    checkURLDifferences("http://host/path%2e.%2E",
+        {"http", "", "", "host", 0, "/path...", "", "", "http://host/path..."},
+        {"http", "", "", "host", 0, "/path%2e.%2E", "", "", "http://host/path%2e.%2E"});
 
     checkRelativeURLDifferences(utf16String(u"http://foo:💩@example.com/bar"), "http://other.com/",
         {"http", "foo", utf16String(u"💩"), "example.com", 0, "/bar", "", "", "http://foo:%F0%9F%92%A9@example.com/bar"},