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

     1  package armjson
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/khulnasoft-lab/defsec/pkg/types"
     8  )
     9  
    10  type parser struct {
    11  	position Position
    12  	size     int
    13  	peeker   *PeekReader
    14  }
    15  
    16  func newParser(p *PeekReader, pos Position) *parser {
    17  	return &parser{
    18  		position: pos,
    19  		peeker:   p,
    20  	}
    21  }
    22  
    23  func (p *parser) parse(rootMetadata *types.Metadata) (Node, error) {
    24  	root, err := p.parseElement(rootMetadata)
    25  	if err != nil {
    26  		return nil, err
    27  	}
    28  	root.(*node).updateMetadata("")
    29  	return root, nil
    30  }
    31  
    32  func (p *parser) parseElement(parentMetadata *types.Metadata) (Node, error) {
    33  	if err := p.parseWhitespace(); err != nil {
    34  		return nil, err
    35  	}
    36  	n, err := p.parseValue(parentMetadata)
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  	if err := p.parseWhitespace(); err != nil {
    41  		return nil, err
    42  	}
    43  	return n, nil
    44  }
    45  
    46  func (p *parser) parseValue(parentMetadata *types.Metadata) (Node, error) {
    47  	c, err := p.peeker.Peek()
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  
    52  	switch c {
    53  	case '/':
    54  		return p.parseComment(parentMetadata)
    55  	case '"':
    56  		return p.parseString(parentMetadata)
    57  	case '{':
    58  		return p.parseObject(parentMetadata)
    59  	case '[':
    60  		return p.parseArray(parentMetadata)
    61  	case 'n':
    62  		return p.parseNull(parentMetadata)
    63  	case 't', 'f':
    64  		return p.parseBoolean(parentMetadata)
    65  	default:
    66  		if c == '-' || (c >= '0' && c <= '9') {
    67  			return p.parseNumber(parentMetadata)
    68  		}
    69  		return nil, fmt.Errorf("unexpected character '%c'", c)
    70  	}
    71  }
    72  
    73  func (p *parser) next() (rune, error) {
    74  	b, err := p.peeker.Next()
    75  	if err != nil {
    76  		return 0, err
    77  	}
    78  	p.position.Column++
    79  	p.size++
    80  	return b, nil
    81  }
    82  
    83  func (p *parser) undo() error {
    84  	if err := p.peeker.Undo(); err != nil {
    85  		return err
    86  	}
    87  	p.position.Column--
    88  	p.size--
    89  	return nil
    90  }
    91  
    92  func (p *parser) makeError(format string, args ...interface{}) error {
    93  	return fmt.Errorf(
    94  		"error at line %d, column %d: %s",
    95  		p.position.Line,
    96  		p.position.Column,
    97  		fmt.Sprintf(format, args...),
    98  	)
    99  }
   100  
   101  func (p *parser) newNode(k Kind, parentMetadata *types.Metadata) (*node, *types.Metadata) {
   102  	n := &node{
   103  		start: p.position,
   104  		kind:  k,
   105  	}
   106  	metadata := types.NewMetadata(
   107  		types.NewRange(parentMetadata.Range().GetFilename(), n.start.Line, n.end.Line, "", parentMetadata.Range().GetFS()),
   108  		n.ref,
   109  	)
   110  	metadata.SetParentPtr(parentMetadata)
   111  	n.metadata = &metadata
   112  	return n, n.metadata
   113  }
   114  
   115  func (n *node) updateMetadata(prefix string) {
   116  
   117  	var full string
   118  	// nolint:gocritic
   119  	if strings.HasPrefix(n.ref, "[") {
   120  		full = prefix + n.ref
   121  	} else if prefix != "" {
   122  		full = prefix + "." + n.ref
   123  	} else {
   124  		full = n.ref
   125  	}
   126  
   127  	n.metadata.SetRange(types.NewRange(n.metadata.Range().GetFilename(),
   128  		n.start.Line,
   129  		n.end.Line,
   130  		"",
   131  		n.metadata.Range().GetFS()))
   132  
   133  	n.metadata.SetReference(full)
   134  
   135  	for i := range n.content {
   136  		n.content[i].(*node).updateMetadata(full)
   137  	}
   138  }
   139  
   140  func (p *parser) swallowIfEqual(r rune) bool {
   141  	c, err := p.peeker.Peek()
   142  	if err != nil {
   143  		return false
   144  	}
   145  	if c != r {
   146  		return false
   147  	}
   148  	_, _ = p.next()
   149  	return true
   150  }