Browse Source

Do not allow username,password,port for URLs without a host or file URLs

Valentin Gosu 9 years ago
parent
commit
f9d797190a
5 changed files with 49 additions and 22 deletions
  1. 1 1
      Cargo.toml
  2. 7 4
      src/lib.rs
  3. 1 1
      src/quirks.rs
  4. 40 0
      tests/setters_tests.json
  5. 0 16
      tests/unit.rs

+ 1 - 1
Cargo.toml

@@ -2,7 +2,7 @@
 
 name = "url"
 # When updating version, also modify html_root_url in the lib.rs
-version = "1.6.0"
+version = "1.6.1"
 authors = ["The rust-url developers"]
 
 description = "URL library for Rust, based on the WHATWG URL Standard"

+ 7 - 4
src/lib.rs

@@ -104,7 +104,7 @@ assert_eq!(css_url.as_str(), "http://servo.github.io/rust-url/main.css");
 # run().unwrap();
 */
 
-#![doc(html_root_url = "https://docs.rs/url/1.6.0")]
+#![doc(html_root_url = "https://docs.rs/url/1.6.1")]
 
 #[cfg(feature="rustc-serialize")] extern crate rustc_serialize;
 #[macro_use] extern crate matches;
@@ -1427,7 +1427,8 @@ impl Url {
     /// # run().unwrap();
     /// ```
     pub fn set_port(&mut self, mut port: Option<u16>) -> Result<(), ()> {
-        if !self.has_host() || self.scheme() == "file" {
+        // has_host implies !cannot_be_a_base
+        if !self.has_host() || self.host() == Some(Host::Domain("")) || self.scheme() == "file" {
             return Err(())
         }
         if port.is_some() && port == parser::default_port(self.scheme()) {
@@ -1695,7 +1696,8 @@ impl Url {
     /// # run().unwrap();
     /// ```
     pub fn set_password(&mut self, password: Option<&str>) -> Result<(), ()> {
-        if !self.has_host() {
+        // has_host implies !cannot_be_a_base
+        if !self.has_host() || self.host() == Some(Host::Domain("")) || self.scheme() == "file" {
             return Err(())
         }
         if let Some(password) = password {
@@ -1776,7 +1778,8 @@ impl Url {
     /// # run().unwrap();
     /// ```
     pub fn set_username(&mut self, username: &str) -> Result<(), ()> {
-        if !self.has_host() {
+        // has_host implies !cannot_be_a_base
+        if !self.has_host() || self.host() == Some(Host::Domain("")) || self.scheme() == "file" {
             return Err(())
         }
         let username_start = self.scheme_end + 3;

+ 1 - 1
src/quirks.rs

@@ -152,7 +152,7 @@ pub fn set_port(url: &mut Url, new_port: &str) -> Result<(), ()> {
     {
         // has_host implies !cannot_be_a_base
         let scheme = url.scheme();
-        if !url.has_host() || scheme == "file" {
+        if !url.has_host() || url.host() == Some(Host::Domain("")) || scheme == "file" {
             return Err(())
         }
         result = Parser::parse_port(Input::new(new_port), || default_port(scheme), Context::Setter)

+ 40 - 0
tests/setters_tests.json

@@ -258,6 +258,22 @@
                 "username": "%c3%89t%C3%A9"
             }
         },
+        {
+            "href": "sc:///",
+            "new_value": "x",
+            "expected": {
+                "href": "sc:///",
+                "username": ""
+            }
+        },
+        {
+            "href": "file://test/",
+            "new_value": "test",
+            "expected": {
+                "href": "file://test/",
+                "username": ""
+            }
+        },
         {
             "href": "javascript://x/",
             "new_value": "wario",
@@ -345,6 +361,22 @@
                 "password": "%c3%89t%C3%A9"
             }
         },
+        {
+            "href": "sc:///",
+            "new_value": "x",
+            "expected": {
+                "href": "sc:///",
+                "password": ""
+            }
+        },
+        {
+            "href": "file://test/",
+            "new_value": "test",
+            "expected": {
+                "href": "file://test/",
+                "password": ""
+            }
+        },
         {
             "href": "javascript://x/",
             "new_value": "bowser",
@@ -1214,6 +1246,14 @@
                 "port": ""
             }
         },
+        {
+            "href": "sc:///",
+            "new_value": "12",
+            "expected": {
+                "href": "sc:///",
+                "port": ""
+            }
+        },
         {
             "href": "sc://x/",
             "new_value": "12",

+ 0 - 16
tests/unit.rs

@@ -295,22 +295,6 @@ fn host_and_port_display() {
     )
 }
 
-#[test]
-/// https://github.com/servo/rust-url/issues/25
-fn issue_25() {
-    let filename = if cfg!(windows) { r"C:\run\pg.sock" } else { "/run/pg.sock" };
-    let mut url = Url::from_file_path(filename).unwrap();
-    url.check_invariants().unwrap();
-    url.set_scheme("postgres").unwrap();
-    url.check_invariants().unwrap();
-    url.set_host(Some("")).unwrap();
-    url.check_invariants().unwrap();
-    url.set_username("me").unwrap();
-    url.check_invariants().unwrap();
-    let expected = format!("postgres://me@/{}run/pg.sock", if cfg!(windows) { "C:/" } else { "" });
-    assert_eq!(url.as_str(), expected);
-}
-
 #[test]
 /// https://github.com/servo/rust-url/issues/61
 fn issue_61() {