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  }