|
|
|
@ -17,6 +17,7 @@ package strvals
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
|
|
|
|
"fmt"
|
|
|
|
|
"io"
|
|
|
|
|
"strconv"
|
|
|
|
|
"strings"
|
|
|
|
@ -149,7 +150,12 @@ func runeSet(r []rune) map[rune]bool {
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t *parser) key(data map[string]interface{}) error {
|
|
|
|
|
func (t *parser) key(data map[string]interface{}) (reterr error) {
|
|
|
|
|
defer func() {
|
|
|
|
|
if r := recover(); r != nil {
|
|
|
|
|
reterr = fmt.Errorf("unable to parse key: %s", r)
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
stop := runeSet([]rune{'=', '[', ',', '.'})
|
|
|
|
|
for {
|
|
|
|
|
switch k, last, err := runesUntil(t.sc, stop); {
|
|
|
|
@ -230,14 +236,26 @@ func set(data map[string]interface{}, key string, val interface{}) {
|
|
|
|
|
data[key] = val
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func setIndex(list []interface{}, index int, val interface{}) []interface{} {
|
|
|
|
|
func setIndex(list []interface{}, index int, val interface{}) (l2 []interface{}, err error) {
|
|
|
|
|
// There are possible index values that are out of range on a target system
|
|
|
|
|
// causing a panic. This will catch the panic and return an error instead.
|
|
|
|
|
// The value of the index that causes a panic varies from system to system.
|
|
|
|
|
defer func() {
|
|
|
|
|
if r := recover(); r != nil {
|
|
|
|
|
err = fmt.Errorf("error processing index %d: %s", index, r)
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
if index < 0 {
|
|
|
|
|
return list, fmt.Errorf("negative %d index not allowed", index)
|
|
|
|
|
}
|
|
|
|
|
if len(list) <= index {
|
|
|
|
|
newlist := make([]interface{}, index+1)
|
|
|
|
|
copy(newlist, list)
|
|
|
|
|
list = newlist
|
|
|
|
|
}
|
|
|
|
|
list[index] = val
|
|
|
|
|
return list
|
|
|
|
|
return list, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (t *parser) keyIndex() (int, error) {
|
|
|
|
@ -252,6 +270,9 @@ func (t *parser) keyIndex() (int, error) {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
func (t *parser) listItem(list []interface{}, i int) ([]interface{}, error) {
|
|
|
|
|
if i < 0 {
|
|
|
|
|
return list, fmt.Errorf("negative %d index not allowed", i)
|
|
|
|
|
}
|
|
|
|
|
stop := runeSet([]rune{'[', '.', '='})
|
|
|
|
|
switch k, last, err := runesUntil(t.sc, stop); {
|
|
|
|
|
case len(k) > 0:
|
|
|
|
@ -262,16 +283,19 @@ func (t *parser) listItem(list []interface{}, i int) ([]interface{}, error) {
|
|
|
|
|
vl, e := t.valList()
|
|
|
|
|
switch e {
|
|
|
|
|
case nil:
|
|
|
|
|
return setIndex(list, i, vl), nil
|
|
|
|
|
return setIndex(list, i, vl)
|
|
|
|
|
case io.EOF:
|
|
|
|
|
return setIndex(list, i, ""), err
|
|
|
|
|
return setIndex(list, i, "")
|
|
|
|
|
case ErrNotList:
|
|
|
|
|
rs, e := t.val()
|
|
|
|
|
if e != nil && e != io.EOF {
|
|
|
|
|
return list, e
|
|
|
|
|
}
|
|
|
|
|
v, e := t.reader(rs)
|
|
|
|
|
return setIndex(list, i, v), e
|
|
|
|
|
if e != nil {
|
|
|
|
|
return list, e
|
|
|
|
|
}
|
|
|
|
|
return setIndex(list, i, v)
|
|
|
|
|
default:
|
|
|
|
|
return list, e
|
|
|
|
|
}
|
|
|
|
@ -283,7 +307,10 @@ func (t *parser) listItem(list []interface{}, i int) ([]interface{}, error) {
|
|
|
|
|
}
|
|
|
|
|
// Now we need to get the value after the ].
|
|
|
|
|
list2, err := t.listItem(list, i)
|
|
|
|
|
return setIndex(list, i, list2), err
|
|
|
|
|
if err != nil {
|
|
|
|
|
return list, err
|
|
|
|
|
}
|
|
|
|
|
return setIndex(list, i, list2)
|
|
|
|
|
case last == '.':
|
|
|
|
|
// We have a nested object. Send to t.key
|
|
|
|
|
inner := map[string]interface{}{}
|
|
|
|
@ -299,7 +326,10 @@ func (t *parser) listItem(list []interface{}, i int) ([]interface{}, error) {
|
|
|
|
|
|
|
|
|
|
// Recurse
|
|
|
|
|
e := t.key(inner)
|
|
|
|
|
return setIndex(list, i, inner), e
|
|
|
|
|
if e != nil {
|
|
|
|
|
return list, e
|
|
|
|
|
}
|
|
|
|
|
return setIndex(list, i, inner)
|
|
|
|
|
default:
|
|
|
|
|
return nil, errors.Errorf("parse error: unexpected token %v", last)
|
|
|
|
|
}
|
|
|
|
|