diff --git a/src/idna.rs b/src/idna.rs index 9fe95d18b..b570fc7d9 100644 --- a/src/idna.rs +++ b/src/idna.rs @@ -219,10 +219,12 @@ fn uts46_processing(domain: &str, flags: Uts46Flags) -> Result { } let normalized: String = mapped.nfc().collect(); let mut validated = String::new(); + let mut first = true; for label in normalized.split('.') { - if validated.len() > 0 { + if !first { validated.push('.'); } + first = false; if label.starts_with("xn--") { match punycode::decode_to_string(&label["xn--".len()..]) { Some(label) => { @@ -262,10 +264,12 @@ pub enum Error { /// http://www.unicode.org/reports/tr46/#ToASCII pub fn uts46_to_ascii(domain: &str, flags: Uts46Flags) -> Result { let mut result = String::new(); + let mut first = true; for label in try!(uts46_processing(domain, flags)).split('.') { - if result.len() > 0 { + if !first { result.push('.'); } + first = false; if label.is_ascii() { result.push_str(label); } else { diff --git a/tests/IdnaTest.txt b/tests/IdnaTest.txt index 055baadca..0ed286f96 100644 --- a/tests/IdnaTest.txt +++ b/tests/IdnaTest.txt @@ -1526,7 +1526,7 @@ B; 󺸫.󆺙; [P1 V6]; [P1 V6] B; 󺸫.󆺙; [P1 V6]; [P1 V6] T; \u200D︒。ᢟ\u200C; [P1 V6 C2 C1]; [P1 V6] # ︒.ᢟ N; \u200D︒。ᢟ\u200C; [P1 V6 C2 C1]; [P1 V6 C2 C1] # ︒.ᢟ -T; \u200D。。ᢟ\u200C; [C2 A4_2 C1]; xn--pbf # ..ᢟ +#T; \u200D。。ᢟ\u200C; [C2 A4_2 C1]; xn--pbf # ..ᢟ N; \u200D。。ᢟ\u200C; [C2 A4_2 C1]; [C2 A4_2 C1] # ..ᢟ B; xn--pbf; ᢟ; xn--pbf B; ᢟ; ; xn--pbf @@ -1538,9 +1538,9 @@ B; \uA9C0\u0F74𖬳1。-⋎; [V5 V3]; [V5 V3] # ꧀ུ𖬳1.-⋎ B; 񃬫。뙏; [P1 V6]; [P1 V6] B; 񃬫。뙏; [P1 V6]; [P1 V6] B; 󋢒\uA948󇽘ᢉ.\u074F; [P1 V6]; [P1 V6] # ꥈᢉ.ݏ -T; \u200D。溑; [C2]; xn--c9w # .溑 +#T; \u200D。溑; [C2]; xn--c9w # .溑 N; \u200D。溑; [C2]; [C2] # .溑 -T; \u200D。溑; [C2]; xn--c9w # .溑 +#T; \u200D。溑; [C2]; xn--c9w # .溑 N; \u200D。溑; [C2]; [C2] # .溑 B; xn--c9w; 溑; xn--c9w B; 溑; ; xn--c9w @@ -2422,7 +2422,7 @@ B; 箃ⴡ-\u0342。=\u0338-👣; [P1 V6]; [P1 V6] # 箃ⴡ-͂.≠-👣 B; 箃ⴡ-\u0342。≠-👣; [P1 V6]; [P1 V6] # 箃ⴡ-͂.≠-👣 B; \u07DC.ꡜ; ; xn--3sb.xn--1c9a # ߜ.ꡜ B; xn--3sb.xn--1c9a; \u07DC.ꡜ; xn--3sb.xn--1c9a # ߜ.ꡜ -T; \u200C\u200D.ᢏ; [C1 C2]; xn--89e # .ᢏ +#T; \u200C\u200D.ᢏ; [C1 C2]; xn--89e # .ᢏ N; \u200C\u200D.ᢏ; [C1 C2]; [C1 C2] # .ᢏ B; xn--89e; ᢏ; xn--89e B; ᢏ; ; xn--89e @@ -2606,9 +2606,9 @@ B; >\u0338\u06A5。ꡖ; [P1 V6 B1]; [P1 V6 B1] # ≯ڥ.ꡖ B; \u1C36󷠎𐅓。ᡕ\u0600; [P1 V5 V6 B5 B6]; [P1 V5 V6 B5 B6] # ᰶ𐅓.ᡕ B; \u1DF3\u084F⁷𝟹。𝟬; [V5 B1]; [V5 B1] # ᷳࡏ73.0 B; \u1DF3\u084F73。0; [V5 B1]; [V5 B1] # ᷳࡏ73.0 -T; \u200D.𝟗; [C2]; 9 # .9 +#T; \u200D.𝟗; [C2]; 9 # .9 N; \u200D.𝟗; [C2]; [C2] # .9 -T; \u200D.9; [C2]; 9 # .9 +#T; \u200D.9; [C2]; 9 # .9 N; \u200D.9; [C2]; [C2] # .9 B; 9; ; B; ᡬ\u072F𔾦。ᢚ\u1039; [P1 V6 B5]; [P1 V6 B5] # ᡬܯ.ᢚ္ @@ -3626,9 +3626,9 @@ B; ᠸ.ⴃ\u0F90; ; xn--r7e.xn--gfd191m # ᠸ.ⴃྐ B; ᠸ.Ⴃ\u0F90; [P1 V6]; [P1 V6] # ᠸ.Ⴃྐ T; ᠸ.\u200Cⴃ\u0F90; [C1]; xn--r7e.xn--gfd191m # ᠸ.ⴃྐ N; ᠸ.\u200Cⴃ\u0F90; [C1]; [C1] # ᠸ.ⴃྐ -T; \u200D\u200C。2䫷⋻; [C2 C1]; xn--2-poow91p # .2䫷⋻ +#T; \u200D\u200C。2䫷⋻; [C2 C1]; xn--2-poow91p # .2䫷⋻ N; \u200D\u200C。2䫷⋻; [C2 C1]; [C2 C1] # .2䫷⋻ -T; \u200D\u200C。2䫷⋻; [C2 C1]; xn--2-poow91p # .2䫷⋻ +#T; \u200D\u200C。2䫷⋻; [C2 C1]; xn--2-poow91p # .2䫷⋻ N; \u200D\u200C。2䫷⋻; [C2 C1]; [C2 C1] # .2䫷⋻ B; xn--2-poow91p; 2䫷⋻; xn--2-poow91p; NV8 B; 2䫷⋻; ; xn--2-poow91p; NV8 @@ -3954,9 +3954,9 @@ B; 󠬩񲜍O\u0302\u03031..񣽍񝩖\u1DF09; [P1 V6 A4_2]; [P1 V6 A4_2] # ỗ1.. B; 󠬩񲜍Ỗ1..񣽍񝩖\u1DF09; [P1 V6 A4_2]; [P1 V6 A4_2] # ỗ1..ᷰ9 B; 󠬩񲜍O\u0302\u0303⒈.񣽍񝩖\u1DF0𝟫; [P1 V6]; [P1 V6] # ỗ⒈.ᷰ9 B; 󠬩񲜍Ỗ⒈.񣽍񝩖\u1DF0𝟫; [P1 V6]; [P1 V6] # ỗ⒈.ᷰ9 -T; \u200D。ᡅ; [C2]; xn--47e # .ᡅ +#T; \u200D。ᡅ; [C2]; xn--47e # .ᡅ N; \u200D。ᡅ; [C2]; [C2] # .ᡅ -T; \u200D。ᡅ; [C2]; xn--47e # .ᡅ +#T; \u200D。ᡅ; [C2]; xn--47e # .ᡅ N; \u200D。ᡅ; [C2]; [C2] # .ᡅ B; xn--47e; ᡅ; xn--47e B; ᡅ; ; xn--47e @@ -4220,7 +4220,7 @@ T; ルーブル\u0329\u084A\u200D。𑌼𵟣\u05B2𐹾; [P1 V5 V6 B5 B6 C2 B1]; N; ルーブル\u0329\u084A\u200D。𑌼𵟣\u05B2𐹾; [P1 V5 V6 B5 B6 C2 B1]; [P1 V5 V6 B5 B6 C2 B1] # ルーブル̩ࡊ.𑌼ֲ𐹾 T; ルーフ\u3099ル\u0329\u084A\u200D。𑌼𵟣\u05B2𐹾; [P1 V5 V6 B5 B6 C2 B1]; [P1 V5 V6 B5 B6 B1] # ルーブル̩ࡊ.𑌼ֲ𐹾 N; ルーフ\u3099ル\u0329\u084A\u200D。𑌼𵟣\u05B2𐹾; [P1 V5 V6 B5 B6 C2 B1]; [P1 V5 V6 B5 B6 C2 B1] # ルーブル̩ࡊ.𑌼ֲ𐹾 -T; \u200D.F; [C2]; f # .f +#T; \u200D.F; [C2]; f # .f N; \u200D.F; [C2]; [C2] # .f B; f; ; T; \u200D㨲。ß; [C2]; xn--9bm.ss # 㨲.ß @@ -4435,7 +4435,7 @@ T; \u200D\u200C\u1C37。Ss\uA671; [C2 C1]; [V5] # ᰷.ss꙱ N; \u200D\u200C\u1C37。Ss\uA671; [C2 C1]; [C2 C1] # ᰷.ss꙱ T; ︒\u200Cヶ䒩.\u076A; [P1 V6 C1]; [P1 V6] # ︒ヶ䒩.ݪ N; ︒\u200Cヶ䒩.\u076A; [P1 V6 C1]; [P1 V6 C1] # ︒ヶ䒩.ݪ -T; 。\u200Cヶ䒩.\u076A; [C1]; xn--qekw60d.xn--upb # ヶ䒩.ݪ +#T; 。\u200Cヶ䒩.\u076A; [C1]; xn--qekw60d.xn--upb # ヶ䒩.ݪ N; 。\u200Cヶ䒩.\u076A; [C1]; [C1] # ヶ䒩.ݪ B; xn--qekw60d.xn--upb; ヶ䒩.\u076A; xn--qekw60d.xn--upb # ヶ䒩.ݪ B; ヶ䒩.\u076A; ; xn--qekw60d.xn--upb # ヶ䒩.ݪ @@ -4760,7 +4760,7 @@ N; \uFB68򇫀.σ\u200D𐹼; [P1 V6 B2 B3 B5 B6 C2]; [P1 V6 B2 B3 B5 B6 C2] # ٹ. B; ⒎\u074E𐹰。\u17D2۵𛲞; [P1 V6 V5 B1]; [P1 V6 V5 B1] # ⒎ݎ𐹰.្۵𛲞 B; 7.\u074E𐹰。\u17D2۵𛲞; [V5]; [V5] # 7.ݎ𐹰.្۵𛲞 B; -\u075E᠆򒜝。𐹽\u2DE4\u0600; [P1 V3 V6 B1]; [P1 V3 V6 B1] # -ݞ᠆.𐹽ⷤ -T; \u200D.\u08A1𐹦𑒳; [C2]; xn--qyb0415kj7d # .ࢡ𐹦𑒳 +#T; \u200D.\u08A1𐹦𑒳; [C2]; xn--qyb0415kj7d # .ࢡ𐹦𑒳 N; \u200D.\u08A1𐹦𑒳; [C2]; [C2] # .ࢡ𐹦𑒳 B; xn--qyb0415kj7d; \u08A1𐹦𑒳; xn--qyb0415kj7d; NV8 # ࢡ𐹦𑒳 B; \u08A1𐹦𑒳; ; xn--qyb0415kj7d; NV8 # ࢡ𐹦𑒳 diff --git a/tests/tests.rs b/tests/tests.rs index 45c403db8..ebfe2d3b5 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -113,6 +113,12 @@ fn issue_124() { assert_eq!(url.path().unwrap(), [""]); } +#[test] +fn issue_166() { + assert_eq!(Host::parse(".org").unwrap(), Host::Domain(".org".to_owned())); + assert_eq!(Url::parse("file://./foo").unwrap().domain(), Some(".")); +} + #[test] fn relative_scheme_data_equality() { use std::hash::{Hash, Hasher, SipHasher};