Log Message
URL::setUser and URL::setPass don't percent encode https://bugs.webkit.org/show_bug.cgi?id=141453 rdar://problem/14844503&16551802&19623145
Reviewed by Darin Adler.
Source/WebCore:
Tests: fast/url/url-credentials-escaping.html
http/tests/xmlhttprequest/basic-auth-credentials-escaping.html
Start adding some code that performs escaping in a way that matches the URL Standard.
Right now, it's only used where we failed to do any escaping at all, and over time,
we'll be moving towards a new implementation.
* html/URLUtils.h:
(WebCore::URLUtils<T>::username):
(WebCore::URLUtils<T>::password):
* platform/URL.cpp:
(WebCore::isSchemeFirstChar):
(WebCore::URL::user):
(WebCore::URL::pass):
(WebCore::URL::encodedUser):
(WebCore::URL::encodedPass):
(WebCore::URL::setUser):
(WebCore::URL::setPass):
(WebCore::encodeWithURLEscapeSequences):
* platform/URL.h:
LayoutTests:
* fast/url/url-credentials-escaping-expected.txt: Added.
* fast/url/url-credentials-escaping.html: Added.
This change is most directly testable via URL API.
* http/tests/xmlhttprequest/basic-auth-credentials-escaping-expected.txt: Added.
* http/tests/xmlhttprequest/basic-auth-credentials-escaping.html: Added.
Verify that this doesn't break XMLHttpRequest authentication.
* fast/dom/DOMURL/invalid-url-getters-expected.txt: Removed.
* fast/dom/DOMURL/invalid-url-getters.html: Removed.
* fast/dom/DOMURL/url-origin-expected.txt:
* fast/dom/DOMURL/url-origin.html:
Removed tests for invalid URLs, there is no such thing with URL API.
Modified Paths
- trunk/LayoutTests/ChangeLog
- trunk/LayoutTests/fast/dom/DOMURL/url-origin-expected.txt
- trunk/LayoutTests/fast/dom/DOMURL/url-origin.html
- trunk/Source/WebCore/ChangeLog
- trunk/Source/WebCore/html/URLUtils.h
- trunk/Source/WebCore/platform/URL.cpp
- trunk/Source/WebCore/platform/URL.h
Added Paths
- trunk/LayoutTests/fast/url/url-credentials-escaping-expected.txt
- trunk/LayoutTests/fast/url/url-credentials-escaping.html
- trunk/LayoutTests/http/tests/xmlhttprequest/basic-auth-credentials-escaping-expected.txt
- trunk/LayoutTests/http/tests/xmlhttprequest/basic-auth-credentials-escaping.html
Removed Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (179932 => 179933)
--- trunk/LayoutTests/ChangeLog 2015-02-11 17:58:33 UTC (rev 179932)
+++ trunk/LayoutTests/ChangeLog 2015-02-11 18:03:42 UTC (rev 179933)
@@ -1,3 +1,25 @@
+2015-02-10 Alexey Proskuryakov <[email protected]>
+
+ URL::setUser and URL::setPass don't percent encode
+ https://bugs.webkit.org/show_bug.cgi?id=141453
+ rdar://problem/14844503&16551802&19623145
+
+ Reviewed by Darin Adler.
+
+ * fast/url/url-credentials-escaping-expected.txt: Added.
+ * fast/url/url-credentials-escaping.html: Added.
+ This change is most directly testable via URL API.
+
+ * http/tests/xmlhttprequest/basic-auth-credentials-escaping-expected.txt: Added.
+ * http/tests/xmlhttprequest/basic-auth-credentials-escaping.html: Added.
+ Verify that this doesn't break XMLHttpRequest authentication.
+
+ * fast/dom/DOMURL/invalid-url-getters-expected.txt: Removed.
+ * fast/dom/DOMURL/invalid-url-getters.html: Removed.
+ * fast/dom/DOMURL/url-origin-expected.txt:
+ * fast/dom/DOMURL/url-origin.html:
+ Removed tests for invalid URLs, there is no such thing with URL API.
+
2015-02-11 Commit Queue <[email protected]>
Unreviewed, rolling out r179921.
Deleted: trunk/LayoutTests/fast/dom/DOMURL/invalid-url-getters-expected.txt (179932 => 179933)
--- trunk/LayoutTests/fast/dom/DOMURL/invalid-url-getters-expected.txt 2015-02-11 17:58:33 UTC (rev 179932)
+++ trunk/LayoutTests/fast/dom/DOMURL/invalid-url-getters-expected.txt 2015-02-11 18:03:42 UTC (rev 179933)
@@ -1,19 +0,0 @@
-Test what getters return on an invalid URL
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS invalidURL.toString() is 'http://@@:[email protected]:22/bar?x#y'
-FAIL invalidURL.origin should be . Was null.
-PASS invalidURL.username is ''
-PASS invalidURL.password is ''
-PASS invalidURL.host is ''
-PASS invalidURL.hostname is ''
-PASS invalidURL.port is ''
-PASS invalidURL.pathname is ''
-PASS invalidURL.search is ''
-PASS invalidURL.hash is ''
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
Deleted: trunk/LayoutTests/fast/dom/DOMURL/invalid-url-getters.html (179932 => 179933)
--- trunk/LayoutTests/fast/dom/DOMURL/invalid-url-getters.html 2015-02-11 17:58:33 UTC (rev 179932)
+++ trunk/LayoutTests/fast/dom/DOMURL/invalid-url-getters.html 2015-02-11 18:03:42 UTC (rev 179933)
@@ -1,29 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta charset="utf-8">
-<script src=""
-</head>
-<body>
-<script>
-
-description("Test what getters return on an invalid URL");
-
-var invalidURL = new URL("http://u:[email protected]:22/bar?x#y")
-invalidURL.username = "@@";
-
-shouldBe("invalidURL.toString()", "'http://@@:[email protected]:22/bar?x#y'");
-shouldBe("invalidURL.origin", "''");
-shouldBe("invalidURL.username", "''");
-shouldBe("invalidURL.password", "''");
-shouldBe("invalidURL.host", "''");
-shouldBe("invalidURL.hostname", "''");
-shouldBe("invalidURL.port", "''");
-shouldBe("invalidURL.pathname", "''");
-shouldBe("invalidURL.search", "''");
-shouldBe("invalidURL.hash", "''");
-
-</script>
-<script src=""
-</body>
-</html>
Modified: trunk/LayoutTests/fast/dom/DOMURL/url-origin-expected.txt (179932 => 179933)
--- trunk/LayoutTests/fast/dom/DOMURL/url-origin-expected.txt 2015-02-11 17:58:33 UTC (rev 179932)
+++ trunk/LayoutTests/fast/dom/DOMURL/url-origin-expected.txt 2015-02-11 18:03:42 UTC (rev 179933)
@@ -4,5 +4,4 @@
ftp://example.com/ttt?ggg => ftp://example.com
file:///home/abarth => file://
data:text/html,<b>foo</b> => null
-http://@@@www.example.com/bar => null
Modified: trunk/LayoutTests/fast/dom/DOMURL/url-origin.html (179932 => 179933)
--- trunk/LayoutTests/fast/dom/DOMURL/url-origin.html 2015-02-11 17:58:33 UTC (rev 179932)
+++ trunk/LayoutTests/fast/dom/DOMURL/url-origin.html 2015-02-11 18:03:42 UTC (rev 179933)
@@ -5,9 +5,6 @@
if (window.testRunner)
testRunner.dumpAsText();
-var invalidURL = new URL("http://www.example.com/bar")
-invalidURL.username = "@@";
-
var cases = [
new URL("http://example.com/foo/bar"),
new URL("HTTP://example.com/foo/bar"),
@@ -15,7 +12,6 @@
new URL("ftp://example.com/ttt?ggg"),
new URL("file:///home/abarth"),
new URL("data:text/html,<b>foo</b>"),
- invalidURL
];
window._onload_ = function(e)
Added: trunk/LayoutTests/fast/url/url-credentials-escaping-expected.txt (0 => 179933)
--- trunk/LayoutTests/fast/url/url-credentials-escaping-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/url/url-credentials-escaping-expected.txt 2015-02-11 18:03:42 UTC (rev 179933)
@@ -0,0 +1,51 @@
+Test that URL username and password accessors encode/decode correctly
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Basic syntax
+PASS build('user').toString() is "http://[email protected]/"
+PASS build('user').username is "user"
+PASS build('%').toString() is "http://%@www.apple.com/"
+PASS build('%').username is "%"
+PASS build('%%').toString() is "http://%%@www.apple.com/"
+PASS build('%%').username is "%%"
+PASS build('%z').toString() is "http://%[email protected]/"
+PASS build('%z').username is "%z"
+PASS build('%61').toString() is "http://%[email protected]/"
+PASS build('%61').username is "%61"
+PASS build('%40').toString() is "http://%[email protected]/"
+PASS build('%40').username is "%40"
+
+Simple encode set
+PASS build('').toString() is "http://%[email protected]/"
+PASS build('user', '').toString() is "http://user:%[email protected]/"
+
+Default encode set additions
+PASS build(' "#><?`').toString() is "http://%20%22%23%3e%3c%[email protected]/"
+PASS build('user', ' "#><?`').toString() is "http://user:%20%22%23%3e%3c%[email protected]/"
+
+Password encode set additions
+PASS build('/@\\').toString() is "http://%2f%[email protected]/"
+PASS build('user', '/@\\').toString() is "http://user:%2f%[email protected]/"
+':' shouldn't be encoded in the password per the URL Standard, although both Firefox and Chrome encode it
+PASS build('user', ':').toString() is "http://user::@www.apple.com/"
+
+Username encode set addition
+PASS build(':').toString() is "http://%[email protected]/"
+
+8-bit
+PASS build('юзер', 'пароль').toString() is "http://%D1%8E%D0%B7%D0%B5%D1%80:%d0%bf%d0%b0%d1%80%d0%be%d0%bb%[email protected]/"
+PASS build('юзер').username is "%D1%8E%D0%B7%D0%B5%D1%80"
+PASS build('user', 'пароль').password is "%D0%BF%D0%B0%D1%80%D0%BE%D0%BB%D1%8C"
+
+Some special characters that don't get encoded when used in credentials
+PASS build('!$&*()-+~').toString() is "http://!$&*()[email protected]/"
+
+Some characters that shouldn't be encoded per the URL Standard, although both Firefox and Chrome encode them
+PASS build('^{|}[]=').toString() is "http://^{|}[][email protected]/"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Property changes on: trunk/LayoutTests/fast/url/url-credentials-escaping-expected.txt
___________________________________________________________________
Added: svn:mime-type
Added: svn:eol-style
Added: trunk/LayoutTests/fast/url/url-credentials-escaping.html (0 => 179933)
--- trunk/LayoutTests/fast/url/url-credentials-escaping.html (rev 0)
+++ trunk/LayoutTests/fast/url/url-credentials-escaping.html 2015-02-11 18:03:42 UTC (rev 179933)
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src=""
+</head>
+<body>
+<script>
+
+description("Test that URL username and password accessors encode/decode correctly");
+
+function build(username, password)
+{
+ var url = "" URL("http://www.apple.com");
+ if (username)
+ url.username = username;
+ if (password)
+ url.password = password;
+ return url;
+}
+
+debug("\nBasic syntax");
+
+shouldBe("build('user').toString()", '"http://[email protected]/"');
+shouldBe("build('user').username", '"user"');
+
+shouldBe("build('%').toString()", '"http://%@www.apple.com/"');
+shouldBe("build('%').username", '"%"');
+
+shouldBe("build('%%').toString()", '"http://%%@www.apple.com/"');
+shouldBe("build('%%').username", '"%%"');
+
+shouldBe("build('%z').toString()", '"http://%[email protected]/"');
+shouldBe("build('%z').username", '"%z"');
+
+// Yes, this is weird, percent signs don't get encoded.
+shouldBe("build('%61').toString()", '"http://%[email protected]/"');
+shouldBe("build('%61').username", '"%61"');
+shouldBe("build('%40').toString()", '"http://%[email protected]/"');
+shouldBe("build('%40').username", '"%40"');
+
+debug("\nSimple encode set");
+shouldBe("build('\x07\x7f').toString()", '"http://%[email protected]/"');
+shouldBe("build('user', '\x07\x7f').toString()", '"http://user:%[email protected]/"');
+
+debug("\nDefault encode set additions");
+shouldBe("build(' \"#><?`').toString()", '"http://%20%22%23%3e%3c%[email protected]/"');
+shouldBe("build('user', ' \"#><?`').toString()", '"http://user:%20%22%23%3e%3c%[email protected]/"');
+
+debug("\nPassword encode set additions");
+shouldBe("build('/@\\\\').toString()", '"http://%2f%[email protected]/"');
+shouldBe("build('user', '/@\\\\').toString()", '"http://user:%2f%[email protected]/"');
+debug("':' shouldn't be encoded in the password per the URL Standard, although both Firefox and Chrome encode it")
+shouldBe("build('user', ':').toString()", '"http://user::@www.apple.com/"');
+
+debug("\nUsername encode set addition");
+shouldBe("build(':').toString()", '"http://%[email protected]/"');
+
+debug("\n8-bit");
+shouldBe("build('юзер', 'пароль').toString()", '"http://%D1%8E%D0%B7%D0%B5%D1%80:%d0%bf%d0%b0%d1%80%d0%be%d0%bb%[email protected]/"');
+shouldBe("build('юзер').username", '"%D1%8E%D0%B7%D0%B5%D1%80"');
+shouldBe("build('user', 'пароль').password", '"%D0%BF%D0%B0%D1%80%D0%BE%D0%BB%D1%8C"');
+
+debug("\nSome special characters that don't get encoded when used in credentials");
+shouldBe("build('!$&*()-+~').toString()", '"http://!$&*()[email protected]/"');
+
+debug("\nSome characters that shouldn't be encoded per the URL Standard, although both Firefox and Chrome encode them")
+shouldBe("build('^{|}[]=').toString()", '"http://^{|}[][email protected]/"');
+
+</script>
+</body>
+</html>
Property changes on: trunk/LayoutTests/fast/url/url-credentials-escaping.html
___________________________________________________________________
Added: svn:mime-type
Added: trunk/LayoutTests/http/tests/xmlhttprequest/basic-auth-credentials-escaping-expected.txt (0 => 179933)
--- trunk/LayoutTests/http/tests/xmlhttprequest/basic-auth-credentials-escaping-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/xmlhttprequest/basic-auth-credentials-escaping-expected.txt 2015-02-11 18:03:42 UTC (rev 179933)
@@ -0,0 +1,9 @@
+Tests for XMLHttpRequest authentication.
+
+async: User: 1, password: %a%.
+async2: User: 2, password: @.
+async3: User: 3, password: @.
+async4: User: 4, password: :.
+async5: User: 5, password: .
+async6: User: 6, password: a.
+async7: User: 7, password: /@\ "#><?`.
Property changes on: trunk/LayoutTests/http/tests/xmlhttprequest/basic-auth-credentials-escaping-expected.txt
___________________________________________________________________
Added: svn:mime-type
Added: svn:eol-style
Added: trunk/LayoutTests/http/tests/xmlhttprequest/basic-auth-credentials-escaping.html (0 => 179933)
--- trunk/LayoutTests/http/tests/xmlhttprequest/basic-auth-credentials-escaping.html (rev 0)
+++ trunk/LayoutTests/http/tests/xmlhttprequest/basic-auth-credentials-escaping.html 2015-02-11 18:03:42 UTC (rev 179933)
@@ -0,0 +1,95 @@
+<html>
+<meta charset="utf-8">
+<body>
+<p>Tests for XMLHttpRequest authentication.
+<script>
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
+
+ var console_messages = document.createElement("ol");
+ document.body.appendChild(console_messages);
+
+ function log(message)
+ {
+ var item = document.createElement("li");
+ item.appendChild(document.createTextNode(message));
+ console_messages.appendChild(item);
+ }
+
+ function sendAndLogResponse(uid, req)
+ {
+ try {
+ req.send("");
+ log(uid + ': ' + req.responseText);
+ } catch (e) {
+ log(uid + ": req.send raised exception: " + e);
+ log(uid + ": req.readyState: " + req.readyState);
+ log(uid + ": req.status: " + req.status);
+ }
+ }
+
+ // async
+ var asyncStep = 1;
+
+ req = new XMLHttpRequest;
+ req._onreadystatechange_ = processStateChange;
+ req.open("GET", "resources/basic-auth/basic-auth.php?uid=1", true, "1", "%a%");
+ req.send("");
+
+ function processStateChange() {
+
+ if (req.readyState == 4){
+ if (req.status == 200){
+ if (asyncStep == 1) {
+ asyncStep = 2;
+ log('async: ' + req.responseText);
+ req._onreadystatechange_ = processStateChange;
+ req.open("GET", "resources/basic-auth/basic-auth.php?uid=2", true, "2", "%40");
+ req.send("");
+ } else if (asyncStep == 2) {
+ asyncStep = 3;
+ log('async2: ' + req.responseText);
+ req._onreadystatechange_ = processStateChange;
+ req.open("GET", "resources/basic-auth/basic-auth.php?uid=3", true, "3", "@");
+ req.send("");
+ } else if (asyncStep == 3) {
+ asyncStep = 4;
+ log('async3: ' + req.responseText);
+ req._onreadystatechange_ = processStateChange;
+ req.open("GET", "resources/basic-auth/basic-auth.php?uid=4", true, "4", ":");
+ req.send("");
+ } else if (asyncStep == 4) {
+ asyncStep = 5;
+ log('async4: ' + req.responseText);
+ req._onreadystatechange_ = processStateChange;
+ req.open("GET", "resources/basic-auth/basic-auth.php?uid=5", true, "5", " ");
+ req.send("");
+ } else if (asyncStep == 5) {
+ asyncStep = 6;
+ log('async5: ' + req.responseText);
+ req._onreadystatechange_ = processStateChange;
+ req.open("GET", "resources/basic-auth/basic-auth.php?uid=6", true, "6", "%61");
+ req.send("");
+ } else if (asyncStep == 6) {
+ asyncStep = 7;
+ log('async6: ' + req.responseText);
+ req._onreadystatechange_ = processStateChange;
+ req.open("GET", "resources/basic-auth/basic-auth.php?uid=7", true, "7", "/@\\ \"#><?`");
+ req.send("");
+ } else if (asyncStep == 7) {
+ log('async7: ' + req.responseText);
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }
+ } else {
+ log("async" + asyncStep + " failed with unexpected status: " + req.status + ". Response: '" + req.responseText + "'.");
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }
+ }
+ }
+</script>
+</body>
+</html>
Property changes on: trunk/LayoutTests/http/tests/xmlhttprequest/basic-auth-credentials-escaping.html
___________________________________________________________________
Added: svn:mime-type
Modified: trunk/Source/WebCore/ChangeLog (179932 => 179933)
--- trunk/Source/WebCore/ChangeLog 2015-02-11 17:58:33 UTC (rev 179932)
+++ trunk/Source/WebCore/ChangeLog 2015-02-11 18:03:42 UTC (rev 179933)
@@ -1,3 +1,32 @@
+2015-02-10 Alexey Proskuryakov <[email protected]>
+
+ URL::setUser and URL::setPass don't percent encode
+ https://bugs.webkit.org/show_bug.cgi?id=141453
+ rdar://problem/14844503&16551802&19623145
+
+ Reviewed by Darin Adler.
+
+ Tests: fast/url/url-credentials-escaping.html
+ http/tests/xmlhttprequest/basic-auth-credentials-escaping.html
+
+ Start adding some code that performs escaping in a way that matches the URL Standard.
+ Right now, it's only used where we failed to do any escaping at all, and over time,
+ we'll be moving towards a new implementation.
+
+ * html/URLUtils.h:
+ (WebCore::URLUtils<T>::username):
+ (WebCore::URLUtils<T>::password):
+ * platform/URL.cpp:
+ (WebCore::isSchemeFirstChar):
+ (WebCore::URL::user):
+ (WebCore::URL::pass):
+ (WebCore::URL::encodedUser):
+ (WebCore::URL::encodedPass):
+ (WebCore::URL::setUser):
+ (WebCore::URL::setPass):
+ (WebCore::encodeWithURLEscapeSequences):
+ * platform/URL.h:
+
2015-02-11 Alex Christensen <[email protected]>
Add a few more WEBCORE_EXPORT macros for debug and iOS builds.
Modified: trunk/Source/WebCore/html/URLUtils.h (179932 => 179933)
--- trunk/Source/WebCore/html/URLUtils.h 2015-02-11 17:58:33 UTC (rev 179932)
+++ trunk/Source/WebCore/html/URLUtils.h 2015-02-11 18:03:42 UTC (rev 179933)
@@ -98,7 +98,7 @@
template <typename T>
String URLUtils<T>::username() const
{
- return href().user();
+ return href().encodedUser();
}
template <typename T>
@@ -112,7 +112,7 @@
template <typename T>
String URLUtils<T>::password() const
{
- return href().pass();
+ return href().encodedPass();
}
template <typename T>
Modified: trunk/Source/WebCore/platform/URL.cpp (179932 => 179933)
--- trunk/Source/WebCore/platform/URL.cpp 2015-02-11 17:58:33 UTC (rev 179932)
+++ trunk/Source/WebCore/platform/URL.cpp 2015-02-11 18:03:42 UTC (rev 179933)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007, 2008, 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2007, 2008, 2011, 2012, 2013, 2015 Apple Inc. All rights reserved.
* Copyright (C) 2012 Research In Motion Limited. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -233,6 +233,108 @@
/* 252 */ BadChar, /* 253 */ BadChar, /* 254 */ BadChar, /* 255 */ BadChar
};
+enum PercentEncodeCharacterClass {
+ // Class names match the URL Standard; each class is a superset of the previous one.
+ PercentEncodeSimple = 255,
+ PercentEncodeDefault = 127,
+ PercentEncodePassword = 63,
+ PercentEncodeUsername = 31,
+};
+
+static const unsigned char percentEncodeClassTable[256] = {
+ /* 0 nul */ PercentEncodeSimple, /* 1 soh */ PercentEncodeSimple, /* 2 stx */ PercentEncodeSimple, /* 3 etx */ PercentEncodeSimple,
+ /* 4 eot */ PercentEncodeSimple, /* 5 enq */ PercentEncodeSimple, /* 6 ack */ PercentEncodeSimple, /* 7 bel */ PercentEncodeSimple,
+ /* 8 bs */ PercentEncodeSimple, /* 9 ht */ PercentEncodeSimple, /* 10 nl */ PercentEncodeSimple, /* 11 vt */ PercentEncodeSimple,
+ /* 12 np */ PercentEncodeSimple, /* 13 cr */ PercentEncodeSimple, /* 14 so */ PercentEncodeSimple, /* 15 si */ PercentEncodeSimple,
+ /* 16 dle */ PercentEncodeSimple, /* 17 dc1 */ PercentEncodeSimple, /* 18 dc2 */ PercentEncodeSimple, /* 19 dc3 */ PercentEncodeSimple,
+ /* 20 dc4 */ PercentEncodeSimple, /* 21 nak */ PercentEncodeSimple, /* 22 syn */ PercentEncodeSimple, /* 23 etb */ PercentEncodeSimple,
+ /* 24 can */ PercentEncodeSimple, /* 25 em */ PercentEncodeSimple, /* 26 sub */ PercentEncodeSimple, /* 27 esc */ PercentEncodeSimple,
+ /* 28 fs */ PercentEncodeSimple, /* 29 gs */ PercentEncodeSimple, /* 30 rs */ PercentEncodeSimple, /* 31 us */ PercentEncodeSimple,
+ /* 32 sp */ PercentEncodeDefault,
+ /* 33 ! */ 0,
+ /* 34 " */ PercentEncodeDefault,
+ /* 35 # */ PercentEncodeDefault,
+ /* 36 $ */ 0,
+ /* 37 % */ 0,
+ /* 38 & */ 0,
+ /* 39 ' */ 0,
+ /* 40 ( */ 0,
+ /* 41 ) */ 0,
+ /* 42 * */ 0,
+ /* 43 + */ 0,
+ /* 44 , */ 0,
+ /* 45 - */ 0,
+ /* 46 . */ 0,
+ /* 47 / */ PercentEncodePassword,
+ /* 48 0 */ 0, /* 49 1 */ 0, /* 50 2 */ 0, /* 51 3 */ 0,
+ /* 52 4 */ 0, /* 53 5 */ 0, /* 54 6 */ 0, /* 55 7 */ 0,
+ /* 56 8 */ 0, /* 57 9 */ 0,
+ /* 58 : */ PercentEncodeUsername,
+ /* 59 ; */ 0,
+ /* 60 < */ PercentEncodeDefault,
+ /* 61 = */ 0,
+ /* 62 > */ PercentEncodeDefault,
+ /* 63 ? */ PercentEncodeDefault,
+ /* 64 @ */ PercentEncodePassword,
+ /* 65 A */ 0, /* 66 B */ 0, /* 67 C */ 0, /* 68 D */ 0,
+ /* 69 E */ 0, /* 70 F */ 0, /* 71 G */ 0, /* 72 H */ 0,
+ /* 73 I */ 0, /* 74 J */ 0, /* 75 K */ 0, /* 76 L */ 0,
+ /* 77 M */ 0, /* 78 N */ 0, /* 79 O */ 0, /* 80 P */ 0,
+ /* 81 Q */ 0, /* 82 R */ 0, /* 83 S */ 0, /* 84 T */ 0,
+ /* 85 U */ 0, /* 86 V */ 0, /* 87 W */ 0, /* 88 X */ 0,
+ /* 89 Y */ 0, /* 90 Z */ 0,
+ /* 91 [ */ 0,
+ /* 92 \ */ PercentEncodePassword,
+ /* 93 ] */ 0,
+ /* 94 ^ */ 0,
+ /* 95 _ */ 0,
+ /* 96 ` */ PercentEncodeDefault,
+ /* 97 a */ 0, /* 98 b */ 0, /* 99 c */ 0, /* 100 d */ 0,
+ /* 101 e */ 0, /* 102 f */ 0, /* 103 g */ 0, /* 104 h */ 0,
+ /* 105 i */ 0, /* 106 j */ 0, /* 107 k */ 0, /* 108 l */ 0,
+ /* 109 m */ 0, /* 110 n */ 0, /* 111 o */ 0, /* 112 p */ 0,
+ /* 113 q */ 0, /* 114 r */ 0, /* 115 s */ 0, /* 116 t */ 0,
+ /* 117 u */ 0, /* 118 v */ 0, /* 119 w */ 0, /* 120 x */ 0,
+ /* 121 y */ 0, /* 122 z */ 0,
+ /* 123 { */ 0,
+ /* 124 | */ 0,
+ /* 125 } */ 0,
+ /* 126 ~ */ 0,
+ /* 127 del */ PercentEncodeSimple,
+ /* 128 */ PercentEncodeSimple, /* 129 */ PercentEncodeSimple, /* 130 */ PercentEncodeSimple, /* 131 */ PercentEncodeSimple,
+ /* 132 */ PercentEncodeSimple, /* 133 */ PercentEncodeSimple, /* 134 */ PercentEncodeSimple, /* 135 */ PercentEncodeSimple,
+ /* 136 */ PercentEncodeSimple, /* 137 */ PercentEncodeSimple, /* 138 */ PercentEncodeSimple, /* 139 */ PercentEncodeSimple,
+ /* 140 */ PercentEncodeSimple, /* 141 */ PercentEncodeSimple, /* 142 */ PercentEncodeSimple, /* 143 */ PercentEncodeSimple,
+ /* 144 */ PercentEncodeSimple, /* 145 */ PercentEncodeSimple, /* 146 */ PercentEncodeSimple, /* 147 */ PercentEncodeSimple,
+ /* 148 */ PercentEncodeSimple, /* 149 */ PercentEncodeSimple, /* 150 */ PercentEncodeSimple, /* 151 */ PercentEncodeSimple,
+ /* 152 */ PercentEncodeSimple, /* 153 */ PercentEncodeSimple, /* 154 */ PercentEncodeSimple, /* 155 */ PercentEncodeSimple,
+ /* 156 */ PercentEncodeSimple, /* 157 */ PercentEncodeSimple, /* 158 */ PercentEncodeSimple, /* 159 */ PercentEncodeSimple,
+ /* 160 */ PercentEncodeSimple, /* 161 */ PercentEncodeSimple, /* 162 */ PercentEncodeSimple, /* 163 */ PercentEncodeSimple,
+ /* 164 */ PercentEncodeSimple, /* 165 */ PercentEncodeSimple, /* 166 */ PercentEncodeSimple, /* 167 */ PercentEncodeSimple,
+ /* 168 */ PercentEncodeSimple, /* 169 */ PercentEncodeSimple, /* 170 */ PercentEncodeSimple, /* 171 */ PercentEncodeSimple,
+ /* 172 */ PercentEncodeSimple, /* 173 */ PercentEncodeSimple, /* 174 */ PercentEncodeSimple, /* 175 */ PercentEncodeSimple,
+ /* 176 */ PercentEncodeSimple, /* 177 */ PercentEncodeSimple, /* 178 */ PercentEncodeSimple, /* 179 */ PercentEncodeSimple,
+ /* 180 */ PercentEncodeSimple, /* 181 */ PercentEncodeSimple, /* 182 */ PercentEncodeSimple, /* 183 */ PercentEncodeSimple,
+ /* 184 */ PercentEncodeSimple, /* 185 */ PercentEncodeSimple, /* 186 */ PercentEncodeSimple, /* 187 */ PercentEncodeSimple,
+ /* 188 */ PercentEncodeSimple, /* 189 */ PercentEncodeSimple, /* 190 */ PercentEncodeSimple, /* 191 */ PercentEncodeSimple,
+ /* 192 */ PercentEncodeSimple, /* 193 */ PercentEncodeSimple, /* 194 */ PercentEncodeSimple, /* 195 */ PercentEncodeSimple,
+ /* 196 */ PercentEncodeSimple, /* 197 */ PercentEncodeSimple, /* 198 */ PercentEncodeSimple, /* 199 */ PercentEncodeSimple,
+ /* 200 */ PercentEncodeSimple, /* 201 */ PercentEncodeSimple, /* 202 */ PercentEncodeSimple, /* 203 */ PercentEncodeSimple,
+ /* 204 */ PercentEncodeSimple, /* 205 */ PercentEncodeSimple, /* 206 */ PercentEncodeSimple, /* 207 */ PercentEncodeSimple,
+ /* 208 */ PercentEncodeSimple, /* 209 */ PercentEncodeSimple, /* 210 */ PercentEncodeSimple, /* 211 */ PercentEncodeSimple,
+ /* 212 */ PercentEncodeSimple, /* 213 */ PercentEncodeSimple, /* 214 */ PercentEncodeSimple, /* 215 */ PercentEncodeSimple,
+ /* 216 */ PercentEncodeSimple, /* 217 */ PercentEncodeSimple, /* 218 */ PercentEncodeSimple, /* 219 */ PercentEncodeSimple,
+ /* 220 */ PercentEncodeSimple, /* 221 */ PercentEncodeSimple, /* 222 */ PercentEncodeSimple, /* 223 */ PercentEncodeSimple,
+ /* 224 */ PercentEncodeSimple, /* 225 */ PercentEncodeSimple, /* 226 */ PercentEncodeSimple, /* 227 */ PercentEncodeSimple,
+ /* 228 */ PercentEncodeSimple, /* 229 */ PercentEncodeSimple, /* 230 */ PercentEncodeSimple, /* 231 */ PercentEncodeSimple,
+ /* 232 */ PercentEncodeSimple, /* 233 */ PercentEncodeSimple, /* 234 */ PercentEncodeSimple, /* 235 */ PercentEncodeSimple,
+ /* 236 */ PercentEncodeSimple, /* 237 */ PercentEncodeSimple, /* 238 */ PercentEncodeSimple, /* 239 */ PercentEncodeSimple,
+ /* 240 */ PercentEncodeSimple, /* 241 */ PercentEncodeSimple, /* 242 */ PercentEncodeSimple, /* 243 */ PercentEncodeSimple,
+ /* 244 */ PercentEncodeSimple, /* 245 */ PercentEncodeSimple, /* 246 */ PercentEncodeSimple, /* 247 */ PercentEncodeSimple,
+ /* 248 */ PercentEncodeSimple, /* 249 */ PercentEncodeSimple, /* 250 */ PercentEncodeSimple, /* 251 */ PercentEncodeSimple,
+ /* 252 */ PercentEncodeSimple, /* 253 */ PercentEncodeSimple, /* 254 */ PercentEncodeSimple, /* 255 */ PercentEncodeSimple
+};
+
static int copyPathRemovingDots(char* dst, const char* src, int srcStart, int srcEnd);
static void encodeRelativeString(const String& rel, const TextEncoding&, CharBuffer& ouput);
static String substituteBackslashes(const String&);
@@ -256,6 +358,8 @@
return (character | 0x20) == schemeCharacter;
}
+String encodeWithURLEscapeSequences(const String& notEncodedString, PercentEncodeCharacterClass whatToEncode);
+
// Copies the source to the destination, assuming all the source characters are
// ASCII. The destination buffer must be large enough. Null characters are allowed
// in the source string, and no attempt is made to null-terminate the result.
@@ -598,19 +702,32 @@
return number;
}
+String URL::user() const
+{
+ return decodeURLEscapeSequences(m_string.substring(m_userStart, m_userEnd - m_userStart));
+}
+
String URL::pass() const
{
if (m_passwordEnd == m_userEnd)
return String();
- return decodeURLEscapeSequences(m_string.substring(m_userEnd + 1, m_passwordEnd - m_userEnd - 1));
+ return decodeURLEscapeSequences(m_string.substring(m_userEnd + 1, m_passwordEnd - m_userEnd - 1));
}
-String URL::user() const
+String URL::encodedUser() const
{
- return decodeURLEscapeSequences(m_string.substring(m_userStart, m_userEnd - m_userStart));
+ return m_string.substring(m_userStart, m_userEnd - m_userStart);
}
+String URL::encodedPass() const
+{
+ if (m_passwordEnd == m_userEnd)
+ return String();
+
+ return m_string.substring(m_userEnd + 1, m_passwordEnd - m_userEnd - 1);
+}
+
String URL::fragmentIdentifier() const
{
if (m_fragmentEnd == m_queryEnd)
@@ -762,7 +879,7 @@
int end = m_userEnd;
if (!user.isEmpty()) {
- String u = user;
+ String u = encodeWithURLEscapeSequences(user, PercentEncodeUsername);
if (m_userStart == m_schemeEnd + 1)
u = "//" + u;
// Add '@' if we didn't have one before.
@@ -784,12 +901,9 @@
if (!m_isValid)
return;
- // FIXME: Non-ASCII characters must be encoded and escaped to match parse() expectations,
- // and to avoid changing more than just the user password.
-
int end = m_passwordEnd;
if (!password.isEmpty()) {
- String p = ":" + password + "@";
+ String p = ":" + encodeWithURLEscapeSequences(password, PercentEncodePassword) + "@";
if (m_userEnd == m_schemeEnd + 1)
p = "//" + p;
// Eat the existing '@' since we are going to add our own.
@@ -1478,6 +1592,28 @@
return true;
}
+String encodeWithURLEscapeSequences(const String& notEncodedString, PercentEncodeCharacterClass whatToEncode)
+{
+ CString asUTF8 = notEncodedString.utf8();
+
+ CharBuffer buffer(asUTF8.length() * 3 + 1);
+ char* p = buffer.data();
+
+ const char* str = asUTF8.data();
+ const char* strEnd = str + asUTF8.length();
+ while (str < strEnd) {
+ unsigned char c = *str++;
+ if (percentEncodeClassTable[c] >= whatToEncode)
+ appendEscapedChar(p, c);
+ else
+ *p++ = c;
+ }
+
+ ASSERT(p - buffer.data() <= static_cast<int>(buffer.size()));
+
+ return String(buffer.data(), p - buffer.data());
+}
+
String encodeWithURLEscapeSequences(const String& notEncodedString)
{
CString asUTF8 = notEncodedString.utf8();
Modified: trunk/Source/WebCore/platform/URL.h (179932 => 179933)
--- trunk/Source/WebCore/platform/URL.h 2015-02-11 17:58:33 UTC (rev 179932)
+++ trunk/Source/WebCore/platform/URL.h 2015-02-11 18:03:42 UTC (rev 179933)
@@ -113,6 +113,11 @@
WEBCORE_EXPORT String fragmentIdentifier() const;
WEBCORE_EXPORT bool hasFragmentIdentifier() const;
+ // Unlike user() and pass(), these functions don't decode escape sequences.
+ // This is necessary for accurate round-tripping, because encoding doesn't encode '%' characters.
+ String encodedUser() const;
+ String encodedPass() const;
+
WEBCORE_EXPORT String baseAsString() const;
WEBCORE_EXPORT String fileSystemPath() const;
@@ -253,6 +258,7 @@
WEBCORE_EXPORT String decodeURLEscapeSequences(const String&);
String decodeURLEscapeSequences(const String&, const TextEncoding&);
+// FIXME: This is a wrong concept to expose, different parts of a URL need different escaping per the URL Standard.
WEBCORE_EXPORT String encodeWithURLEscapeSequences(const String&);
#if PLATFORM(IOS)
_______________________________________________ webkit-changes mailing list [email protected] https://lists.webkit.org/mailman/listinfo/webkit-changes
