github.com/blend/go-sdk@v1.20220411.3/selector/check_dns.go (about) 1 /* 2 3 Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file. 5 6 */ 7 8 package selector 9 10 import "unicode/utf8" 11 12 // CheckDNS returns if a given value is a conformant DNS_SUBDOMAIN. 13 // 14 // See: https://www.ietf.org/rfc/rfc952.txt and https://www.ietf.org/rfc/rfc1123.txt (2.1) for more information. 15 // 16 // Specifically a DNS_SUBDOMAIN must: 17 // - Be constituted of ([a-z0-9\-\.]) 18 // - It must start and end with ([a-z0-9]) 19 // - it must be less than 254 characters in length 20 // - Characters ('.', '-') cannot repeat 21 func CheckDNS(value string) (err error) { 22 valueLen := len(value) 23 if valueLen == 0 { 24 err = ErrLabelKeyDNSSubdomainEmpty 25 return 26 } 27 if valueLen > MaxLabelKeyDNSSubdomainLen { 28 err = ErrLabelKeyDNSSubdomainTooLong 29 return 30 } 31 32 var state int 33 var ch rune 34 var width int 35 36 const ( 37 statePrefixSuffix = 0 38 stateAlpha = 1 39 stateDotDash = 2 40 ) 41 42 for pos := 0; pos < valueLen; pos += width { 43 ch, width = utf8.DecodeRuneInString(value[pos:]) 44 switch state { 45 case statePrefixSuffix: 46 if !isDNSAlpha(ch) { 47 return ErrLabelKeyInvalidDNSSubdomain 48 } 49 state = stateAlpha 50 continue 51 52 // the last character was a ... 53 case stateAlpha: 54 if ch == Dot || ch == Dash { 55 state = stateDotDash 56 continue 57 } 58 if !isDNSAlpha(ch) { 59 err = ErrLabelKeyInvalidDNSSubdomain 60 return 61 } 62 // if we're at the penultimate char 63 if pos == valueLen-2 { 64 state = statePrefixSuffix 65 continue 66 } 67 continue 68 69 // the last character was a ... 70 case stateDotDash: 71 if isDNSAlpha(ch) { 72 state = stateAlpha 73 continue 74 } 75 err = ErrLabelKeyInvalidDNSSubdomain 76 return 77 } 78 } 79 return nil 80 }