Sfoglia il codice sorgente

IDNA: replace boolean parameters with a struct with named fields

… and fix values for URLs where true/false were swapped.
Simon Sapin 10 anni fa
parent
commit
727220a7b7
3 ha cambiato i file con 36 aggiunte e 18 eliminazioni
  1. 27 11
      src/idna.rs
  2. 6 4
      tests/idna.rs
  3. 3 3
      tests/tests.rs

+ 27 - 11
src/idna.rs

@@ -40,7 +40,7 @@ fn idna_disallowed_std3_mapped(mapping: &'static [u32], use_std3_asciirules: boo
     return idna_mapped(mapping);
 }
 
-fn map_char(codepoint: char, use_std3_asciirules: bool, transitional: bool) -> Result<String, &'static str> {
+fn map_char(codepoint: char, flags: Uts46Flags) -> Result<String, &'static str> {
     let mut min = 0;
     let mut max = TABLE.len() - 1;
     while max > min {
@@ -58,20 +58,33 @@ fn map_char(codepoint: char, use_std3_asciirules: bool, transitional: bool) -> R
     let mapping = TABLE[min].mapping;
 
     match TABLE[min].status {
-        MappingStatus::valid => return Ok(codepoint.to_string()),
-        MappingStatus::ignored => return Ok("".to_string()),
-        MappingStatus::mapped => return idna_mapped(mapping),
-        MappingStatus::deviation => return idna_deviation(codepoint, mapping, transitional),
-        MappingStatus::disallowed => return Err("Dissallowed"),
-        MappingStatus::disallowed_STD3_valid => return idna_disallowed_std3_valid(codepoint, use_std3_asciirules),
-        MappingStatus::disallowed_STD3_mapped => return idna_disallowed_std3_mapped(mapping, use_std3_asciirules),
+        MappingStatus::valid => Ok(codepoint.to_string()),
+        MappingStatus::ignored => Ok("".to_string()),
+        MappingStatus::mapped => idna_mapped(mapping),
+        MappingStatus::deviation => {
+            idna_deviation(codepoint, mapping, flags.transitional_processing)
+        }
+        MappingStatus::disallowed => Err("Dissallowed"),
+        MappingStatus::disallowed_STD3_valid => {
+            idna_disallowed_std3_valid(codepoint, flags.use_std3_ascii_rules)
+        }
+        MappingStatus::disallowed_STD3_mapped => {
+            idna_disallowed_std3_mapped(mapping, flags.use_std3_ascii_rules)
+        }
     }
 }
 
-pub fn domain_to_ascii_options(domain: &str, use_std3_asciirules: bool, transitional: bool) -> Result<String, &'static str> {
+#[derive(Copy, Clone)]
+pub struct Uts46Flags {
+   pub use_std3_ascii_rules: bool,
+   pub transitional_processing: bool,
+}
+
+/// http://www.unicode.org/reports/tr46/#ToASCII
+pub fn uts46_to_ascii(domain: &str, flags: Uts46Flags) -> Result<String, &'static str> {
     let mut ret = String::new();
     for c in domain.chars() {
-        match map_char(c, use_std3_asciirules, transitional) {
+        match map_char(c, flags) {
             Ok(mystr) => ret.push_str(&mystr),
             Err(x) => return Err(x)
         }
@@ -108,5 +121,8 @@ pub fn domain_to_ascii_options(domain: &str, use_std3_asciirules: bool, transiti
 
 /// https://url.spec.whatwg.org/#concept-domain-to-ascii
 pub fn domain_to_ascii(domain: &str) -> Result<String, &'static str> {
-    domain_to_ascii_options(domain, true, false)
+    uts46_to_ascii(domain, Uts46Flags {
+        use_std3_ascii_rules: false,
+        transitional_processing: true,
+    })
 }

+ 6 - 4
tests/idna.rs

@@ -1,8 +1,7 @@
 extern crate url;
 
-use std::ascii::AsciiExt;
 use std::char;
-use url::idna::domain_to_ascii_options;
+use url::idna;
 
 #[test]
 fn test_uts46() {
@@ -36,7 +35,10 @@ fn test_uts46() {
             continue;
         }
 
-        let result = domain_to_ascii_options(&source, true, testType != "N");
+        let result = idna::uts46_to_ascii(&source, idna::Uts46Flags {
+            use_std3_ascii_rules: true,
+            transitional_processing: testType != "N"
+        });
         let res = result.ok();
 
         if toAscii.starts_with("[") {
@@ -56,7 +58,7 @@ fn test_uts46() {
 
         assert!(res != None, "Couldn't parse {} ", source);
         let output = res.unwrap();
-        assert!(output == toAscii.to_ascii_lowercase(), "result: {} | expected: {} | original: {} | source: {}", output, toAscii, original, source);
+        assert!(output == toAscii, "result: {} | expected: {} | original: {} | source: {}", output, toAscii, original, source);
     }
 }
 

+ 3 - 3
tests/tests.rs

@@ -10,7 +10,7 @@ extern crate url;
 
 use std::char;
 use std::net::{Ipv4Addr, Ipv6Addr};
-use url::{UrlParser, ParseError, Url, SchemeData, RelativeSchemeData, Host};
+use url::{UrlParser, Url, SchemeData, RelativeSchemeData, Host};
 
 
 #[test]
@@ -355,12 +355,12 @@ fn host() {
     let a = Host::parse("www.mozilla.org").unwrap();
     let b = Host::parse("1.35.33.49").unwrap();
     let c = Host::parse("[2001:0db8:85a3:08d3:1319:8a2e:0370:7344]").unwrap();
-    let d = Host::parse("1.35.+33.49");
+    let d = Host::parse("1.35.+33.49").unwrap();
     assert_eq!(a, Host::Domain("www.mozilla.org".to_owned()));
     assert_eq!(b, Host::Ipv4(Ipv4Addr::new(1, 35, 33, 49)));
     assert_eq!(c, Host::Ipv6(Ipv6Addr::new(0x2001, 0x0db8, 0x85a3, 0x08d3,
         0x1319, 0x8a2e, 0x0370, 0x7344)));
-    assert_eq!(d, Err(ParseError::InvalidDomainCharacter));
+    assert_eq!(d, Host::Domain("1.35.+33.49".to_owned()));
     assert_eq!(Host::parse("[::]").unwrap(), Host::Ipv6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)));
     assert_eq!(Host::parse("[::1]").unwrap(), Host::Ipv6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)));
     assert_eq!(Host::parse("0x1.0X23.0x21.061").unwrap(), Host::Ipv4(Ipv4Addr::new(1, 35, 33, 49)));