Răsfoiți Sursa

Merge pull request #694 from djc/fix-unicode-before-delimiter

idna: fix hang with unicode character before delimiter (fixes #692)
Valentin Gosu 5 ani în urmă
părinte
comite
73042861be
5 a modificat fișierele cu 25 adăugiri și 16 ștergeri
  1. 4 0
      idna/src/punycode.rs
  2. 0 1
      idna/src/uts46.rs
  3. 6 0
      idna/tests/unit.rs
  4. 9 9
      url/src/lib.rs
  5. 6 6
      url/src/quirks.rs

+ 4 - 0
idna/src/punycode.rs

@@ -78,6 +78,10 @@ impl Decoder {
             ),
         };
 
+        if !base.is_ascii() {
+            return Err(());
+        }
+
         let base_len = base.len();
         let mut length = base_len as u32;
         let mut code_point = INITIAL_N;

+ 0 - 1
idna/src/uts46.rs

@@ -309,7 +309,6 @@ fn check_validity(label: &str, config: Config, errors: &mut Errors) {
         _ => true,
     }) {
         errors.invalid_mapping = true;
-        return;
     }
 
     // V7: ContextJ rules

+ 6 - 0
idna/tests/unit.rs

@@ -131,3 +131,9 @@ fn emoji_domains() {
     let error = format!("{:?}", config.to_ascii("☕.com").unwrap_err());
     assert!(error.contains("disallowed_in_idna_2008"));
 }
+
+#[test]
+fn unicode_before_delimiter() {
+    let config = idna::Config::default();
+    assert!(config.to_ascii("xn--f\u{34a}-PTP").is_err());
+}

+ 9 - 9
url/src/lib.rs

@@ -1434,7 +1434,7 @@ impl Url {
     /// Return an object with methods to manipulate this URL’s path segments.
     ///
     /// Return `Err(())` if this URL is cannot-be-a-base.
-    #[allow(clippy::result_map_unit_fn)]
+    #[allow(clippy::result_unit_err)]
     pub fn path_segments_mut(&mut self) -> Result<PathSegmentsMut<'_>, ()> {
         if self.cannot_be_a_base() {
             Err(())
@@ -1518,7 +1518,7 @@ impl Url {
     /// # }
     /// # run().unwrap();
     /// ```
-    #[allow(clippy::result_map_unit_fn)]
+    #[allow(clippy::result_unit_err)]
     pub fn set_port(&mut self, mut port: Option<u16>) -> Result<(), ()> {
         // has_host implies !cannot_be_a_base
         if !self.has_host() || self.host() == Some(Host::Domain("")) || self.scheme() == "file" {
@@ -1789,7 +1789,7 @@ impl Url {
     /// # run().unwrap();
     /// ```
     ///
-    #[allow(clippy::result_map_unit_fn)]
+    #[allow(clippy::result_unit_err)]
     pub fn set_ip_host(&mut self, address: IpAddr) -> Result<(), ()> {
         if self.cannot_be_a_base() {
             return Err(());
@@ -1829,7 +1829,7 @@ impl Url {
     /// # }
     /// # run().unwrap();
     /// ```
-    #[allow(clippy::result_map_unit_fn)]
+    #[allow(clippy::result_unit_err)]
     pub fn set_password(&mut self, password: Option<&str>) -> Result<(), ()> {
         // has_host implies !cannot_be_a_base
         if !self.has_host() || self.host() == Some(Host::Domain("")) || self.scheme() == "file" {
@@ -1922,7 +1922,7 @@ impl Url {
     /// # }
     /// # run().unwrap();
     /// ```
-    #[allow(clippy::result_map_unit_fn)]
+    #[allow(clippy::result_unit_err)]
     pub fn set_username(&mut self, username: &str) -> Result<(), ()> {
         // has_host implies !cannot_be_a_base
         if !self.has_host() || self.host() == Some(Host::Domain("")) || self.scheme() == "file" {
@@ -2084,7 +2084,7 @@ impl Url {
     /// # }
     /// # run().unwrap();
     /// ```
-    #[allow(clippy::result_map_unit_fn)]
+    #[allow(clippy::result_unit_err, clippy::suspicious_operation_groupings)]
     pub fn set_scheme(&mut self, scheme: &str) -> Result<(), ()> {
         let mut parser = Parser::for_setter(String::new());
         let remaining = parser.parse_scheme(parser::Input::new(scheme))?;
@@ -2164,7 +2164,7 @@ impl Url {
     /// # }
     /// ```
     #[cfg(any(unix, windows, target_os = "redox"))]
-    #[allow(clippy::result_map_unit_fn)]
+    #[allow(clippy::result_unit_err)]
     pub fn from_file_path<P: AsRef<Path>>(path: P) -> Result<Url, ()> {
         let mut serialization = "file://".to_owned();
         let host_start = serialization.len() as u32;
@@ -2201,7 +2201,7 @@ impl Url {
     /// Note that `std::path` does not consider trailing slashes significant
     /// and usually does not include them (e.g. in `Path::parent()`).
     #[cfg(any(unix, windows, target_os = "redox"))]
-    #[allow(clippy::result_map_unit_fn)]
+    #[allow(clippy::result_unit_err)]
     pub fn from_directory_path<P: AsRef<Path>>(path: P) -> Result<Url, ()> {
         let mut url = Url::from_file_path(path)?;
         if !url.serialization.ends_with('/') {
@@ -2318,7 +2318,7 @@ impl Url {
     /// for a Windows path, is not UTF-8.)
     #[inline]
     #[cfg(any(unix, windows, target_os = "redox"))]
-    #[allow(clippy::result_map_unit_fn)]
+    #[allow(clippy::result_unit_err)]
     pub fn to_file_path(&self) -> Result<PathBuf, ()> {
         if let Some(segments) = self.path_segments() {
             let host = match self.host() {

+ 6 - 6
url/src/quirks.rs

@@ -56,7 +56,7 @@ pub fn protocol(url: &Url) -> &str {
 }
 
 /// Setter for https://url.spec.whatwg.org/#dom-url-protocol
-#[allow(clippy::result_map_unit_fn)]
+#[allow(clippy::result_unit_err)]
 pub fn set_protocol(url: &mut Url, mut new_protocol: &str) -> Result<(), ()> {
     // The scheme state in the spec ignores everything after the first `:`,
     // but `set_scheme` errors if there is more.
@@ -73,7 +73,7 @@ pub fn username(url: &Url) -> &str {
 }
 
 /// Setter for https://url.spec.whatwg.org/#dom-url-username
-#[allow(clippy::result_map_unit_fn)]
+#[allow(clippy::result_unit_err)]
 pub fn set_username(url: &mut Url, new_username: &str) -> Result<(), ()> {
     url.set_username(new_username)
 }
@@ -85,7 +85,7 @@ pub fn password(url: &Url) -> &str {
 }
 
 /// Setter for https://url.spec.whatwg.org/#dom-url-password
-#[allow(clippy::result_map_unit_fn)]
+#[allow(clippy::result_unit_err)]
 pub fn set_password(url: &mut Url, new_password: &str) -> Result<(), ()> {
     url.set_password(if new_password.is_empty() {
         None
@@ -101,7 +101,7 @@ pub fn host(url: &Url) -> &str {
 }
 
 /// Setter for https://url.spec.whatwg.org/#dom-url-host
-#[allow(clippy::result_map_unit_fn)]
+#[allow(clippy::result_unit_err)]
 pub fn set_host(url: &mut Url, new_host: &str) -> Result<(), ()> {
     // If context object’s url’s cannot-be-a-base-URL flag is set, then return.
     if url.cannot_be_a_base() {
@@ -158,7 +158,7 @@ pub fn hostname(url: &Url) -> &str {
 }
 
 /// Setter for https://url.spec.whatwg.org/#dom-url-hostname
-#[allow(clippy::result_map_unit_fn)]
+#[allow(clippy::result_unit_err)]
 pub fn set_hostname(url: &mut Url, new_hostname: &str) -> Result<(), ()> {
     if url.cannot_be_a_base() {
         return Err(());
@@ -200,7 +200,7 @@ pub fn port(url: &Url) -> &str {
 }
 
 /// Setter for https://url.spec.whatwg.org/#dom-url-port
-#[allow(clippy::result_map_unit_fn)]
+#[allow(clippy::result_unit_err)]
 pub fn set_port(url: &mut Url, new_port: &str) -> Result<(), ()> {
     let result;
     {