Make configMap marshaling code aware of quotes.

A value in a configMap that is a map itself
(a key:value string separated by commas) may include commans inside
quotes (i.e. search_path:"public,"$user"). The changes make marshaling
code process such cases correctly.
This commit is contained in:
Oleksii Kliukin 2017-11-06 18:09:02 +01:00
parent 2352fc9a39
commit e95f80e351
1 changed files with 54 additions and 1 deletions

View File

@ -141,7 +141,10 @@ func processField(value string, field reflect.Value) error {
}
field.Set(sl)
case reflect.Map:
pairs := strings.Split(value, ",")
pairs, err := getMapPairsFromString(value)
if err != nil {
return fmt.Errorf("could not split value %q into map items: %v", value, err)
}
mp := reflect.MakeMap(typ)
for _, pair := range pairs {
kvpair := strings.Split(pair, ":")
@ -166,6 +169,56 @@ func processField(value string, field reflect.Value) error {
return nil
}
type parserState int
const (
Plain parserState = iota
DoubleQuoted
SingleQuoted
)
// Split the pair candidates by commas not located inside open quotes
// Escape characters are not supported for simplicity, as we don't
// expect to find them inside the map values for our use cases
func getMapPairsFromString(value string) (pairs []string , err error) {
pairs = make([]string, 0)
state := Plain
var start, quote int
if value == "" {
return
}
for i, ch := range(strings.Split(value, "")) {
if ch == `"` {
if state == Plain {
state = DoubleQuoted
quote = i
} else if state == DoubleQuoted {
state = Plain
quote = 0
}
}
if ch == "'" {
if state == Plain {
state = SingleQuoted
quote = i
} else if state == SingleQuoted {
state = Plain
quote = 0
}
}
if ch == "," && state == Plain {
pairs = append(pairs, value[start:i])
start = i
}
}
if state != Plain {
err = fmt.Errorf("unclosed quote starting at position %d", quote)
}
pairs = append(pairs, value[start:])
return
}
func (f *stringTemplate) Decode(value string) error {
*f = stringTemplate(value)