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  }