ソースを参照

Implement potentially strip spaces for opaque paths

cybai 3 年 前
コミット
fdbe16cd62
2 ファイル変更42 行追加1 行削除
  1. 31 1
      url/src/lib.rs
  2. 11 0
      url/tests/unit.rs

+ 31 - 1
url/src/lib.rs

@@ -322,6 +322,32 @@ impl Url {
         url
     }
 
+    /// https://url.spec.whatwg.org/#potentially-strip-trailing-spaces-from-an-opaque-path
+    fn strip_trailing_spaces_from_opaque_path(&mut self) {
+        if !self.cannot_be_a_base() {
+            return;
+        }
+
+        if self.fragment_start.is_some() {
+            return;
+        }
+
+        if self.query_start.is_some() {
+            return;
+        }
+
+        let trailing_space_count = self
+            .serialization
+            .chars()
+            .rev()
+            .take_while(|c| *c == ' ')
+            .count();
+
+        let start = self.serialization.len() - trailing_space_count;
+
+        self.serialization.truncate(start);
+    }
+
     /// Parse a string as an URL, with this URL as the base URL.
     ///
     /// The inverse of this is [`make_relative`].
@@ -1434,7 +1460,8 @@ impl Url {
             self.serialization.push('#');
             self.mutate(|parser| parser.parse_fragment(parser::Input::no_trim(input)))
         } else {
-            self.fragment_start = None
+            self.fragment_start = None;
+            self.strip_trailing_spaces_from_opaque_path();
         }
     }
 
@@ -1497,6 +1524,9 @@ impl Url {
                     parser::Input::trim_tab_and_newlines(input, vfn),
                 )
             });
+        } else {
+            self.query_start = None;
+            self.strip_trailing_spaces_from_opaque_path();
         }
 
         self.restore_already_parsed_fragment(fragment);

+ 11 - 0
url/tests/unit.rs

@@ -34,6 +34,17 @@ fn test_relative_empty() {
     assert_eq!(url.as_str(), "sc://%C3%B1");
 }
 
+#[test]
+fn test_strip_trailing_spaces_from_opaque_path() {
+    let mut url: Url = "data:space   ?query".parse().unwrap();
+    url.set_query(None);
+    assert_eq!(url.as_str(), "data:space");
+
+    let mut url: Url = "data:space   #hash".parse().unwrap();
+    url.set_fragment(None);
+    assert_eq!(url.as_str(), "data:space");
+}
+
 #[test]
 fn test_set_empty_host() {
     let mut base: Url = "moz://foo:bar@servo/baz".parse().unwrap();