|
@@ -239,10 +239,12 @@ fn processing(domain: &str, flags: Flags, errors: &mut Vec<Error>) -> String {
|
|
|
}
|
|
}
|
|
|
let normalized: String = mapped.nfc().collect();
|
|
let normalized: String = mapped.nfc().collect();
|
|
|
let mut validated = String::new();
|
|
let mut validated = String::new();
|
|
|
|
|
+ let mut first = true;
|
|
|
for label in normalized.split('.') {
|
|
for label in normalized.split('.') {
|
|
|
- if validated.len() > 0 {
|
|
|
|
|
|
|
+ if !first {
|
|
|
validated.push('.');
|
|
validated.push('.');
|
|
|
}
|
|
}
|
|
|
|
|
+ first = false;
|
|
|
if label.starts_with("xn--") {
|
|
if label.starts_with("xn--") {
|
|
|
match punycode::decode_to_string(&label["xn--".len()..]) {
|
|
match punycode::decode_to_string(&label["xn--".len()..]) {
|
|
|
Some(decoded_label) => {
|
|
Some(decoded_label) => {
|
|
@@ -275,6 +277,7 @@ enum Error {
|
|
|
DissallowedMappedInStd3,
|
|
DissallowedMappedInStd3,
|
|
|
DissallowedCharacter,
|
|
DissallowedCharacter,
|
|
|
TooLongForDns,
|
|
TooLongForDns,
|
|
|
|
|
+ TooShortForDns,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/// Errors recorded during UTS #46 processing.
|
|
/// Errors recorded during UTS #46 processing.
|
|
@@ -288,10 +291,12 @@ pub struct Errors(Vec<Error>);
|
|
|
pub fn to_ascii(domain: &str, flags: Flags) -> Result<String, Errors> {
|
|
pub fn to_ascii(domain: &str, flags: Flags) -> Result<String, Errors> {
|
|
|
let mut errors = Vec::new();
|
|
let mut errors = Vec::new();
|
|
|
let mut result = String::new();
|
|
let mut result = String::new();
|
|
|
|
|
+ let mut first = true;
|
|
|
for label in processing(domain, flags, &mut errors).split('.') {
|
|
for label in processing(domain, flags, &mut errors).split('.') {
|
|
|
- if result.len() > 0 {
|
|
|
|
|
|
|
+ if !first {
|
|
|
result.push('.');
|
|
result.push('.');
|
|
|
}
|
|
}
|
|
|
|
|
+ first = false;
|
|
|
if label.is_ascii() {
|
|
if label.is_ascii() {
|
|
|
result.push_str(label);
|
|
result.push_str(label);
|
|
|
} else {
|
|
} else {
|
|
@@ -307,8 +312,10 @@ pub fn to_ascii(domain: &str, flags: Flags) -> Result<String, Errors> {
|
|
|
|
|
|
|
|
if flags.verify_dns_length {
|
|
if flags.verify_dns_length {
|
|
|
let domain = if result.ends_with(".") { &result[..result.len()-1] } else { &*result };
|
|
let domain = if result.ends_with(".") { &result[..result.len()-1] } else { &*result };
|
|
|
- if domain.len() < 1 || domain.len() > 253 ||
|
|
|
|
|
- domain.split('.').any(|label| label.len() < 1 || label.len() > 63) {
|
|
|
|
|
|
|
+ if domain.len() < 1 || domain.split('.').any(|label| label.len() < 1) {
|
|
|
|
|
+ errors.push(Error::TooShortForDns)
|
|
|
|
|
+ }
|
|
|
|
|
+ if domain.len() > 253 || domain.split('.').any(|label| label.len() > 63) {
|
|
|
errors.push(Error::TooLongForDns)
|
|
errors.push(Error::TooLongForDns)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|