func()

in internal/export/idna/idna10.0.0.go [337:426]


func (p *Profile) process(s string, toASCII bool) (string, error) {
	var err error
	var isBidi bool
	if p.mapping != nil {
		s, isBidi, err = p.mapping(p, s)
	}
	// Remove leading empty labels.
	if p.removeLeadingDots {
		for ; len(s) > 0 && s[0] == '.'; s = s[1:] {
		}
	}
	// TODO: allow for a quick check of the tables data.
	// It seems like we should only create this error on ToASCII, but the
	// UTS 46 conformance tests suggests we should always check this.
	if err == nil && p.verifyDNSLength && s == "" {
		err = &labelError{s, "A4"}
	}
	labels := labelIter{orig: s}
	for ; !labels.done(); labels.next() {
		label := labels.label()
		if label == "" {
			// Empty labels are not okay. The label iterator skips the last
			// label if it is empty.
			if err == nil && p.verifyDNSLength {
				err = &labelError{s, "A4"}
			}
			continue
		}
		if strings.HasPrefix(label, acePrefix) {
			u, err2 := decode(label[len(acePrefix):])
			if err2 != nil {
				if err == nil {
					err = err2
				}
				// Spec says keep the old label.
				continue
			}
			isBidi = isBidi || bidirule.DirectionString(u) != bidi.LeftToRight
			labels.set(u)
			if err == nil && p.fromPuny != nil {
				err = p.fromPuny(p, u)
			}
			if err == nil {
				// This should be called on NonTransitional, according to the
				// spec, but that currently does not have any effect. Use the
				// original profile to preserve options.
				err = p.validateLabel(u)
			}
		} else if err == nil {
			err = p.validateLabel(label)
		}
	}
	if isBidi && p.bidirule != nil && err == nil {
		for labels.reset(); !labels.done(); labels.next() {
			if !p.bidirule(labels.label()) {
				err = &labelError{s, "B"}
				break
			}
		}
	}
	if toASCII {
		for labels.reset(); !labels.done(); labels.next() {
			label := labels.label()
			if !ascii(label) {
				a, err2 := encode(acePrefix, label)
				if err == nil {
					err = err2
				}
				label = a
				labels.set(a)
			}
			n := len(label)
			if p.verifyDNSLength && err == nil && (n == 0 || n > 63) {
				err = &labelError{label, "A4"}
			}
		}
	}
	s = labels.result()
	if toASCII && p.verifyDNSLength && err == nil {
		// Compute the length of the domain name minus the root label and its dot.
		n := len(s)
		if n > 0 && s[n-1] == '.' {
			n--
		}
		if len(s) < 1 || n > 253 {
			err = &labelError{s, "A4"}
		}
	}
	return s, err
}