diff --git a/percent_encoding/lib.rs b/percent_encoding/lib.rs index 35aadee2d..86cc863a0 100644 --- a/percent_encoding/lib.rs +++ b/percent_encoding/lib.rs @@ -116,6 +116,14 @@ impl EncodeSet for SIMPLE_ENCODE_SET { } } +define_encode_set! { + /// This encode set is used in the URL parser for fragments. + /// + /// Aside from special chacters defined in the [`SIMPLE_ENCODE_SET`](struct.SIMPLE_ENCODE_SET.html), + /// space, double quote ("), hash (#), inequality qualifiers (<), (>), and backtick (`) are encoded. + pub FRAGMENT_ENCODE_SET = [SIMPLE_ENCODE_SET] | {' ', '"', '#', '<', '>', '`'} +} + define_encode_set! { /// This encode set is used in the URL parser for query strings. /// diff --git a/src/parser.rs b/src/parser.rs index 4f9cc524b..b447364a8 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -18,8 +18,8 @@ use encoding::EncodingOverride; use host::{Host, HostInternal}; use percent_encoding::{ utf8_percent_encode, percent_encode, - SIMPLE_ENCODE_SET, DEFAULT_ENCODE_SET, USERINFO_ENCODE_SET, QUERY_ENCODE_SET, - PATH_SEGMENT_ENCODE_SET + SIMPLE_ENCODE_SET, FRAGMENT_ENCODE_SET, DEFAULT_ENCODE_SET, USERINFO_ENCODE_SET, + QUERY_ENCODE_SET, PATH_SEGMENT_ENCODE_SET }; define_encode_set! { @@ -1198,7 +1198,7 @@ impl<'a> Parser<'a> { } else { self.check_url_code_point(c, &input); self.serialization.extend(utf8_percent_encode(utf8_c, - SIMPLE_ENCODE_SET)); + FRAGMENT_ENCODE_SET)); } } } diff --git a/tests/setters_tests.json b/tests/setters_tests.json index a45171bf3..e723b13a3 100644 --- a/tests/setters_tests.json +++ b/tests/setters_tests.json @@ -1483,8 +1483,8 @@ "href": "https://example.net?lang=en-US", "new_value": "##nav", "expected": { - "href": "https://example.net/?lang=en-US##nav", - "hash": "##nav" + "href": "https://example.net/?lang=en-US#%23nav", + "hash": "#%23nav" } }, { @@ -1512,12 +1512,12 @@ } }, { - "comment": "Simple percent-encoding; nuls, tabs, and newlines are removed", + "comment": "Fragment percent-encoding; nuls, tabs, spaces, double quotes, backticks, inequality qualifiers and newlines are removed", "href": "a:/", "new_value": "\u0000\u0001\t\n\r\u001f !\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé", "expected": { - "href": "a:/#!%01%1F !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~%7F%C2%80%C2%81%C3%89%C3%A9", - "hash": "#!%01%1F !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~%7F%C2%80%C2%81%C3%89%C3%A9" + "href": "a:/#!%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_%60az{|}~%7F%C2%80%C2%81%C3%89%C3%A9", + "hash": "#!%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_%60az{|}~%7F%C2%80%C2%81%C3%89%C3%A9" } }, { diff --git a/tests/urltestdata.json b/tests/urltestdata.json index 5565c938f..0bc22f1ba 100644 --- a/tests/urltestdata.json +++ b/tests/urltestdata.json @@ -153,7 +153,7 @@ { "input": "http://f:21/ b ? d # e ", "base": "http://example.org/foo/bar", - "href": "http://f:21/%20b%20?%20d%20# e", + "href": "http://f:21/%20b%20?%20d%20#%20e", "origin": "http://f:21", "protocol": "http:", "username": "", @@ -163,12 +163,12 @@ "port": "21", "pathname": "/%20b%20", "search": "?%20d%20", - "hash": "# e" + "hash": "#%20e" }, { "input": "lolscheme:x x#x x", "base": "about:blank", - "href": "lolscheme:x x#x x", + "href": "lolscheme:x x#x%20x", "protocol": "lolscheme:", "username": "", "password": "", @@ -177,7 +177,7 @@ "port": "", "pathname": "x x", "search": "", - "hash": "#x x" + "hash": "#x%20x" }, { "input": "http://f:/c", @@ -812,7 +812,7 @@ { "input": "http://foo/path;a??e#f#g", "base": "http://example.org/foo/bar", - "href": "http://foo/path;a??e#f#g", + "href": "http://foo/path;a??e#f%23g", "origin": "http://foo", "protocol": "http:", "username": "", @@ -822,7 +822,7 @@ "port": "", "pathname": "/path;a", "search": "??e", - "hash": "#f#g" + "hash": "#f%23g" }, { "input": "http://foo/abcd?efgh?ijkl", @@ -2260,7 +2260,7 @@ { "input": "http://www.google.com/foo?bar=baz# »", "base": "about:blank", - "href": "http://www.google.com/foo?bar=baz# %C2%BB", + "href": "http://www.google.com/foo?bar=baz#%20%C2%BB", "origin": "http://www.google.com", "protocol": "http:", "username": "", @@ -2270,12 +2270,12 @@ "port": "", "pathname": "/foo", "search": "?bar=baz", - "hash": "# %C2%BB" + "hash": "#%20%C2%BB" }, { "input": "data:test# »", "base": "about:blank", - "href": "data:test# %C2%BB", + "href": "data:test#%20%C2%BB", "origin": "null", "protocol": "data:", "username": "", @@ -2285,7 +2285,7 @@ "port": "", "pathname": "test", "search": "", - "hash": "# %C2%BB" + "hash": "#%20%C2%BB" }, { "input": "http://www.google.com",