github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/pkg/scanners/azure/arm/parser/armjson/parse_number.go (about) 1 package armjson 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 8 "github.com/khulnasoft-lab/defsec/pkg/types" 9 ) 10 11 func (p *parser) parseNumber(parentMetadata *types.Metadata) (Node, error) { 12 13 n, _ := p.newNode(KindNumber, parentMetadata) 14 15 var str string 16 17 if p.swallowIfEqual('-') { 18 str = "-" 19 } 20 21 integral, err := p.parseIntegral() 22 if err != nil { 23 return nil, err 24 } 25 fraction, err := p.parseFraction() 26 if err != nil { 27 return nil, err 28 } 29 exponent, err := p.parseExponent() 30 if err != nil { 31 return nil, err 32 } 33 34 str = fmt.Sprintf("%s%s%s%s", str, integral, fraction, exponent) 35 n.end = p.position 36 37 if fraction != "" || exponent != "" { 38 f, err := strconv.ParseFloat(str, 64) 39 if err != nil { 40 return nil, p.makeError("%s", err) 41 } 42 n.raw = f 43 return n, nil 44 } 45 46 i, err := strconv.ParseInt(str, 10, 64) 47 if err != nil { 48 return nil, p.makeError("%s", err) 49 } 50 n.raw = i 51 52 return n, nil 53 } 54 55 func (p *parser) parseIntegral() (string, error) { 56 r, err := p.next() 57 if err != nil { 58 return "", err 59 } 60 if r == '0' { 61 r, _ := p.peeker.Peek() 62 if r >= '0' && r <= '9' { 63 return "", p.makeError("invalid number") 64 } 65 return "0", nil 66 } 67 68 var sb strings.Builder 69 if r < '1' || r > '9' { 70 return "", p.makeError("invalid number") 71 } 72 sb.WriteRune(r) 73 74 for { 75 r, err := p.next() 76 if err != nil { 77 return sb.String(), nil 78 } 79 if r < '0' || r > '9' { 80 return sb.String(), p.undo() 81 } 82 sb.WriteRune(r) 83 } 84 } 85 86 func (p *parser) parseFraction() (string, error) { 87 r, err := p.next() 88 if err != nil { 89 return "", nil 90 } 91 if r != '.' { 92 return "", p.undo() 93 } 94 95 var sb strings.Builder 96 sb.WriteRune('.') 97 98 for { 99 r, err := p.next() 100 if err != nil { 101 break 102 } 103 if r < '0' || r > '9' { 104 if err := p.undo(); err != nil { 105 return "", err 106 } 107 break 108 } 109 sb.WriteRune(r) 110 } 111 112 str := sb.String() 113 if str == "." { 114 return "", p.makeError("invalid number - missing digits after decimal point") 115 } 116 117 return str, nil 118 } 119 120 func (p *parser) parseExponent() (string, error) { 121 r, err := p.next() 122 if err != nil { 123 return "", nil 124 } 125 if r != 'e' && r != 'E' { 126 return "", p.undo() 127 } 128 129 var sb strings.Builder 130 sb.WriteRune(r) 131 132 r, err = p.next() 133 if err != nil { 134 return "", nil 135 } 136 hasDigits := r >= '0' && r <= '9' 137 if r != '-' && r != '+' && !hasDigits { 138 return "", p.undo() 139 } 140 141 sb.WriteRune(r) 142 143 for { 144 r, err := p.next() 145 if err != nil { 146 break 147 } 148 if r < '0' || r > '9' { 149 if err := p.undo(); err != nil { 150 return "", err 151 } 152 break 153 } 154 hasDigits = true 155 sb.WriteRune(r) 156 } 157 158 if !hasDigits { 159 return "", p.makeError("invalid number - no digits in exponent") 160 } 161 162 return sb.String(), nil 163 }