Kaynağa Gözat

Auto merge of #248 - Manishearth:percent-fragment, r=SimonSapin

Percent-encode fragments while parsing

Based on https://github.com/whatwg/url/pull/169

Fixes #246

cc @valenting

r? @SimonSapin

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/rust-url/248)
<!-- Reviewable:end -->
bors-servo 9 yıl önce
ebeveyn
işleme
37fe8a78d1
3 değiştirilmiş dosya ile 31 ekleme ve 13 silme
  1. 3 2
      src/parser.rs
  2. 5 5
      tests/setters_tests.json
  3. 23 6
      tests/urltestdata.json

+ 3 - 2
src/parser.rs

@@ -1083,12 +1083,13 @@ impl<'a> Parser<'a> {
     }
     }
 
 
     pub fn parse_fragment(&mut self, mut input: Input) {
     pub fn parse_fragment(&mut self, mut input: Input) {
-        while let Some(c) = input.next() {
+        while let Some((c, utf8_c)) = input.next_utf8() {
             if c ==  '\0' {
             if c ==  '\0' {
                 self.syntax_violation("NULL characters are ignored in URL fragment identifiers")
                 self.syntax_violation("NULL characters are ignored in URL fragment identifiers")
             } else {
             } else {
                 self.check_url_code_point(c, &input);
                 self.check_url_code_point(c, &input);
-                self.serialization.push(c);  // No percent-encoding here.
+                self.serialization.extend(utf8_percent_encode(utf8_c,
+                                                              SIMPLE_ENCODE_SET));
             }
             }
         }
         }
     }
     }

+ 5 - 5
tests/setters_tests.json

@@ -1127,12 +1127,12 @@
             }
             }
         },
         },
         {
         {
-            "comment": "No percent-encoding at all (!); nuls, tabs, and newlines are removed. Leading or training C0 controls and space are removed.",
+            "comment": "Simple percent-encoding; nuls, tabs, and newlines are removed",
             "href": "a:/",
             "href": "a:/",
             "new_value": "\u0000\u0001\t\n\r\u001f !\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé",
             "new_value": "\u0000\u0001\t\n\r\u001f !\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé",
             "expected": {
             "expected": {
-                "href": "a:/#!\u0001\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé",
-                "hash": "#!\u0001\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé"
+                "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"
             }
             }
         },
         },
         {
         {
@@ -1140,8 +1140,8 @@
             "href": "http://example.net",
             "href": "http://example.net",
             "new_value": "%c3%89té",
             "new_value": "%c3%89té",
             "expected": {
             "expected": {
-                "href": "http://example.net/#%c3%89té",
-                "hash": "#%c3%89té"
+                "href": "http://example.net/#%c3%89t%C3%A9",
+                "hash": "#%c3%89t%C3%A9"
             }
             }
         }
         }
     ]
     ]

+ 23 - 6
tests/urltestdata.json

@@ -1292,7 +1292,7 @@
   {
   {
     "input": "#β",
     "input": "#β",
     "base": "http://example.org/foo/bar",
     "base": "http://example.org/foo/bar",
-    "href": "http://example.org/foo/bar#β",
+    "href": "http://example.org/foo/bar#%CE%B2",
     "origin": "http://example.org",
     "origin": "http://example.org",
     "protocol": "http:",
     "protocol": "http:",
     "username": "",
     "username": "",
@@ -1302,7 +1302,7 @@
     "port": "",
     "port": "",
     "pathname": "/foo/bar",
     "pathname": "/foo/bar",
     "search": "",
     "search": "",
-    "hash": "#β"
+    "hash": "#%CE%B2"
   },
   },
   {
   {
     "input": "data:text/html,test#test",
     "input": "data:text/html,test#test",
@@ -2161,7 +2161,7 @@
   {
   {
     "input": "http://www.google.com/foo?bar=baz# »",
     "input": "http://www.google.com/foo?bar=baz# »",
     "base": "about:blank",
     "base": "about:blank",
-    "href": "http://www.google.com/foo?bar=baz# »",
+    "href": "http://www.google.com/foo?bar=baz# %C2%BB",
     "origin": "http://www.google.com",
     "origin": "http://www.google.com",
     "protocol": "http:",
     "protocol": "http:",
     "username": "",
     "username": "",
@@ -2171,12 +2171,12 @@
     "port": "",
     "port": "",
     "pathname": "/foo",
     "pathname": "/foo",
     "search": "?bar=baz",
     "search": "?bar=baz",
-    "hash": "# »"
+    "hash": "# %C2%BB"
   },
   },
   {
   {
     "input": "data:test# »",
     "input": "data:test# »",
     "base": "about:blank",
     "base": "about:blank",
-    "href": "data:test# »",
+    "href": "data:test# %C2%BB",
     "origin": "null",
     "origin": "null",
     "protocol": "data:",
     "protocol": "data:",
     "username": "",
     "username": "",
@@ -2186,7 +2186,7 @@
     "port": "",
     "port": "",
     "pathname": "test",
     "pathname": "test",
     "search": "",
     "search": "",
-    "hash": "# »"
+    "hash": "# %C2%BB"
   },
   },
   {
   {
     "input": "http://[www.google.com]/",
     "input": "http://[www.google.com]/",
@@ -4356,5 +4356,22 @@
     "search": "",
     "search": "",
     "searchParams": "",
     "searchParams": "",
     "hash": ""
     "hash": ""
+  },
+  "# Percent encoding of fragments",
+  {
+    "input": "http://foo.bar/baz?qux#foo\bbar",
+    "base": "about:blank",
+    "href": "http://foo.bar/baz?qux#foo%08bar",
+    "origin": "http://foo.bar",
+    "protocol": "http:",
+    "username": "",
+    "password": "",
+    "host": "foo.bar",
+    "hostname": "foo.bar",
+    "port": "",
+    "pathname": "/baz",
+    "search": "?qux",
+    "searchParams": "",
+    "hash": "#foo%08bar"
   }
   }
 ]
 ]