Source File
idna10.0.0.go
Belonging Package
golang.org/x/net/idna
package idna // import "golang.org/x/net/idna"
import (
)
func ( bool) Option {
return func( *options) { .transitional = true }
}
func ( bool) Option {
return func( *options) { .verifyDNSLength = }
}
func ( bool) Option {
return func( *options) { .removeLeadingDots = }
}
if .mapping == nil && {
.mapping = normalize
}
.trie = trie
.validateLabels =
.fromPuny = validateFromPunycode
}
}
func ( bool) Option {
return func( *options) {
.trie = trie
.useSTD3Rules =
.fromPuny = validateFromPunycode
}
}
func () Option {
return func( *options) { .bidirule = bidirule.ValidString }
}
func () Option {
return func( *options) {
.mapping = validateRegistration
StrictDomainName(true)()
ValidateLabels(true)()
VerifyDNSLength(true)()
BidiRule()()
}
}
func () Option {
return func( *options) {
.mapping = validateAndMap
StrictDomainName(true)()
ValidateLabels(true)()
}
}
type options struct {
transitional bool
useSTD3Rules bool
validateLabels bool
verifyDNSLength bool
removeLeadingDots bool
trie *idnaTrie
func ( *Profile) () string {
:= ""
if .transitional {
= "Transitional"
} else {
= "NonTransitional"
}
if .useSTD3Rules {
+= ":UseSTD3Rules"
}
if .validateLabels {
+= ":ValidateLabels"
}
if .verifyDNSLength {
+= ":VerifyDNSLength"
}
return
}
Registration *Profile = registration
punycode = &Profile{}
lookup = &Profile{options{
transitional: true,
useSTD3Rules: true,
validateLabels: true,
trie: trie,
fromPuny: validateFromPunycode,
mapping: validateAndMap,
bidirule: bidirule.ValidString,
}}
display = &Profile{options{
useSTD3Rules: true,
validateLabels: true,
trie: trie,
fromPuny: validateFromPunycode,
mapping: validateAndMap,
bidirule: bidirule.ValidString,
}}
registration = &Profile{options{
useSTD3Rules: true,
validateLabels: true,
verifyDNSLength: true,
trie: trie,
fromPuny: validateFromPunycode,
mapping: validateRegistration,
bidirule: bidirule.ValidString,
}}
)
type labelError struct{ label, code_ string }
func ( labelError) () string { return .code_ }
func ( labelError) () string {
return fmt.Sprintf("idna: invalid label %q", .label)
}
type runeError rune
func ( runeError) () string { return "P1" }
func ( runeError) () string {
return fmt.Sprintf("idna: disallowed rune %U", )
}
if .removeLeadingDots {
for ; len() > 0 && [0] == '.'; = [1:] {
}
if == nil && .verifyDNSLength && == "" {
= &labelError{, "A4"}
}
:= labelIter{orig: }
for ; !.done(); .next() {
:= .label()
continue
}
= || bidirule.DirectionString() != bidi.LeftToRight
.set()
if == nil && .validateLabels {
= .fromPuny(, )
}
= .validateLabel()
}
} else if == nil {
= .validateLabel()
}
}
if && .bidirule != nil && == nil {
for .reset(); !.done(); .next() {
if !.bidirule(.label()) {
= &labelError{, "B"}
break
}
}
}
if {
for .reset(); !.done(); .next() {
:= .label()
if !ascii() {
, := encode(acePrefix, )
if == nil {
=
}
=
.set()
}
:= len()
if .verifyDNSLength && == nil && ( == 0 || > 63) {
= &labelError{, "A4"}
}
}
}
= .result()
:= len()
if > 0 && [-1] == '.' {
--
}
if len() < 1 || > 253 {
= &labelError{, "A4"}
}
}
return ,
}
= norm.NFC.String()
= bidirule.DirectionString() == bidi.RightToLeft
return , , nil
}
if !norm.NFC.IsNormalString() {
return , false, &labelError{, "V1"}
}
for := 0; < len(); {
, := trie.lookupString([:])
if == 0 {
return , , runeError(utf8.RuneError)
}
switch .simplify(info().category()) {
case valid:
continue
case disallowed:
if == nil {
, := utf8.DecodeRuneInString([:])
= runeError()
}
continue
case mapped, deviation:
= append(, [:]...)
= info().appendMapping(, [:])
case ignored:
= string()
}
return , ,
}
type labelIter struct {
orig string
slice []string
curStart int
curEnd int
i int
}
func ( *labelIter) () {
.curStart = 0
.curEnd = 0
.i = 0
}
func ( *labelIter) () bool {
return .curStart >= len(.orig)
}
func ( *labelIter) () string {
if .slice != nil {
return strings.Join(.slice, ".")
}
return .orig
}
func ( *labelIter) () string {
if .slice != nil {
return .slice[.i]
}
:= strings.IndexByte(.orig[.curStart:], '.')
.curEnd = .curStart +
if == -1 {
.curEnd = len(.orig)
}
return .orig[.curStart:.curEnd]
}
func ( *labelIter) () {
.i++
if .slice != nil {
if .i >= len(.slice) || .i == len(.slice)-1 && .slice[.i] == "" {
.curStart = len(.orig)
}
} else {
.curStart = .curEnd + 1
if .curStart == len(.orig)-1 && .orig[.curStart] == '.' {
.curStart = len(.orig)
}
}
}
func ( *labelIter) ( string) {
if .slice == nil {
.slice = strings.Split(.orig, ".")
}
.slice[.i] =
}
const acePrefix = "xn--"
func ( *Profile) ( category) category {
switch {
case disallowedSTD3Mapped:
if .useSTD3Rules {
= disallowed
} else {
= mapped
}
case disallowedSTD3Valid:
if .useSTD3Rules {
= disallowed
} else {
= valid
}
case deviation:
if !.transitional {
= valid
}
= valid
}
return
}
func ( *Profile, string) error {
if !norm.NFC.IsNormalString() {
return &labelError{, "V1"}
for := 0; < len(); {
, := trie.lookupString([:])
if == 0 {
return runeError(utf8.RuneError)
}
if := .simplify(info().category()); != valid && != deviation {
return &labelError{, "V6"}
}
+=
}
return nil
}
const (
zwnj = "\u200c"
zwj = "\u200d"
)
type joinState int8
const (
stateStart joinState = iota
stateVirama
stateBefore
stateBeforeVirama
stateAfter
stateFAIL
)
var joinStates = [][numJoinTypes]joinState{
stateStart: {
joiningL: stateBefore,
joiningD: stateBefore,
joinZWNJ: stateFAIL,
joinZWJ: stateFAIL,
joinVirama: stateVirama,
},
stateVirama: {
joiningL: stateBefore,
joiningD: stateBefore,
},
stateBefore: {
joiningL: stateBefore,
joiningD: stateBefore,
joiningT: stateBefore,
joinZWNJ: stateAfter,
joinZWJ: stateFAIL,
joinVirama: stateBeforeVirama,
},
stateBeforeVirama: {
joiningL: stateBefore,
joiningD: stateBefore,
joiningT: stateBefore,
},
stateAfter: {
joiningL: stateFAIL,
joiningD: stateBefore,
joiningT: stateAfter,
joiningR: stateStart,
joinZWNJ: stateFAIL,
joinZWJ: stateFAIL,
joinVirama: stateAfter, // no-op as we can't accept joiners here
},
stateFAIL: {
0: stateFAIL,
joiningL: stateFAIL,
joiningD: stateFAIL,
joiningT: stateFAIL,
joiningR: stateFAIL,
joinZWNJ: stateFAIL,
joinZWJ: stateFAIL,
joinVirama: stateFAIL,
},
}
func ( *Profile) ( string) ( error) {
if == "" {
if .verifyDNSLength {
return &labelError{, "A4"}
}
return nil
}
if !.validateLabels {
return nil
}
:= .trie // p.validateLabels is only set if trie is set.
if len() > 4 && [2] == '-' && [3] == '-' {
return &labelError{, "V2"}
}
if [0] == '-' || [len()-1] == '-' {
return &labelError{, "V3"}
, := .lookupString()
:= info()
if .isModifier() {
return &labelError{, "V5"}
if strings.Index(, zwj) == -1 && strings.Index(, zwnj) == -1 {
return nil
}
:= stateStart
for := 0; ; {
:= .joinType()
if [:+] == zwj {
= joinZWJ
} else if [:+] == zwnj {
= joinZWNJ
}
= joinStates[][]
if .isViramaModifier() {
= joinStates[][joinVirama]
}
if += ; == len() {
break
}
, = .lookupString([:])
= info()
}
if == stateFAIL || == stateAfter {
return &labelError{, "C"}
}
return nil
}
func ( string) bool {
for := 0; < len(); ++ {
if [] >= utf8.RuneSelf {
return false
}
}
return true
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |