示例#1
0
文件: idna.go 项目: DanielOaks/go-idn
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")
}
示例#2
0
// 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
}
示例#3
0
文件: idna.go 项目: DanielOaks/go-idn
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")
}