github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/pkg/scanners/azure/arm/parser/armjson/parse_string.go (about)

     1  package armjson
     2  
     3  import (
     4  	"strconv"
     5  	"strings"
     6  
     7  	"github.com/khulnasoft-lab/defsec/pkg/types"
     8  )
     9  
    10  var escapes = map[rune]string{
    11  	'\\': "\\",
    12  	'/':  "/",
    13  	'"':  "\"",
    14  	'n':  "\n",
    15  	'r':  "\r",
    16  	'b':  "\b",
    17  	'f':  "\f",
    18  	't':  "\t",
    19  }
    20  
    21  // nolint: cyclop
    22  func (p *parser) parseString(parentMetadata *types.Metadata) (Node, error) {
    23  
    24  	n, _ := p.newNode(KindString, parentMetadata)
    25  
    26  	b, err := p.next()
    27  	if err != nil {
    28  		return nil, err
    29  	}
    30  
    31  	if b != '"' {
    32  		return nil, p.makeError("expecting string delimiter")
    33  	}
    34  
    35  	var sb strings.Builder
    36  
    37  	var inEscape bool
    38  	var inHex bool
    39  	var hex []rune
    40  
    41  	for {
    42  		c, err := p.next()
    43  		if err != nil {
    44  			return nil, err
    45  		}
    46  		// nolint: gocritic
    47  		if inHex {
    48  			switch {
    49  			case c >= 'a' && c <= 'f', c >= 'A' && c <= 'F', c >= '0' && c <= '9':
    50  				hex = append(hex, c)
    51  				if len(hex) == 4 {
    52  					inHex = false
    53  					char, err := strconv.Unquote("\\u" + string(hex))
    54  					if err != nil {
    55  						return nil, p.makeError("invalid unicode character '%s'", err)
    56  					}
    57  					sb.WriteString(char)
    58  					hex = nil
    59  				}
    60  			default:
    61  				return nil, p.makeError("invalid hexedecimal escape sequence '\\%s%c'", string(hex), c)
    62  			}
    63  		} else if inEscape {
    64  			inEscape = false
    65  			if c == 'u' {
    66  				inHex = true
    67  				continue
    68  			}
    69  			seq, ok := escapes[c]
    70  			if !ok {
    71  				return nil, p.makeError("invalid escape sequence '\\%c'", c)
    72  			}
    73  			sb.WriteString(seq)
    74  		} else {
    75  			switch c {
    76  			case '\\':
    77  				inEscape = true
    78  			case '"':
    79  				n.raw = sb.String()
    80  				n.end = p.position
    81  				return n, nil
    82  			default:
    83  				if c < 0x20 || c > 0x10FFFF {
    84  					return nil, p.makeError("invalid unescaped character '0x%X'", c)
    85  				}
    86  				sb.WriteRune(c)
    87  			}
    88  		}
    89  
    90  	}
    91  }