func toUnicodeRaw(label string) (string, error) { original := label // Step 1: If all code points in the sequence are in the ASCII range (0..7F) then skip to step 3. for i := 0; i < len(label); i++ { if label[i] > 127 { // Step 2: Perform the steps specified in [NAMEPREP] and fail if there is an error. // BUG(dan) We should check error value here label, _ = stringprep.Nameprep(label) break } } // Step 3: Verify that the sequence begins with the ACE prefix, and save a copy of the sequence. if !strings.HasPrefix(label, AcePrefix) { return label, errors.New("Label doesn't begin with the ACE prefix") } // else // 4. Remove the ACE prefix. label = strings.SplitN(label, AcePrefix, -1)[1] // 5. Decode the sequence using the decoding algorithm in [PUNYCODE] and fail if there is an error. //fmt.Printf(label+"\n") results, err := punycode.DecodeString(label) if err != nil { return original, errors.New("Failed punycode decoding: " + err.Error()) } // 6. Apply ToASCII. verification, err := ToASCII(label) if err != nil { return original, errors.New("Failed ToASCII on the decoded sequence: " + err.Error()) } // 7. Verify that the result of step 6 matches the saved copy from step 3, // using a case-insensitive ASCII comparison. if strings.ToLower(verification) == strings.ToLower(original) { return results, nil } return original, errors.New("Failed verification step") }
// Casefold returns a string, lowercased/casefolded according to the given // mapping as defined by this package (or an error if the given string is not // valid in the chosen mapping). func Casefold(mapping MappingType, input string) (string, error) { var out string var err error if mapping == ASCII || mapping == RFC1459 { // strings.ToLower ONLY replaces a-z, no unicode stuff so we're safe // to use that here without any issues. out = strings.ToLower(input) if mapping == RFC1459 { out = strings.Map(rfc1459Fold, out) } } else if mapping == RFC3454 { out, err = stringprep.Nameprep(input) } return out, err }
func toASCIIRaw(label string) (string, error) { original := label // Step 1: If the sequence contains any code points outside the ASCII range // (0..7F) then proceed to step 2, otherwise skip to step 3. for i := 0; i < len(label); i++ { if label[i] > 127 { // Step 2: Perform the smake teps specified in [NAMEPREP] and fail if there is an error. // The AllowUnassigned flag is used in [NAMEPREP]. // BUG(dan) we should check error value here label, _ = stringprep.Nameprep(label) break } } // Step 3: - Verify the absence of non-LDH ASCII code points for _, c := range label { if (c <= 0x2c) || (c >= 0x2e && c <= 0x2f) || (c >= 0x3a && c <= 0x40) || (c >= 0x5b && c <= 0x60) || (c >= 0x7b && c <= 0x7f) { return original, errors.New("Contains non-LDH ASCII codepoints") } } if strings.HasPrefix(label, "-") || strings.HasSuffix(label, "-") { return original, errors.New("Contains hyphen at either end of the string") } // Step 4: If the sequence contains any code points outside the ASCII range // (0..7F) then proceed to step 5, otherwise skip to step 8. isASCII := true for i := 0; i < len(label); i++ { if label[i] > 127 { isASCII = false break } } if !isASCII { // Step 5 Verify that the sequence does NOT begin with the ACE prefix. if strings.HasPrefix(label, AcePrefix) { return label, errors.New("Label starts with ACE prefix") } var err error // Step 6: Encode with punycode label, err = punycode.EncodeString(label) if err != nil { return "", err // delegate err } // Step 7: Prepend ACE prefix label = AcePrefix + label } // 8. Verify that the number of code points is in the range 1 to 63 inclusive. if 0 < len(label) && len(label) < 64 { return label, nil } return original, errors.New("label empty or too long") }