Skip to content

Commit

Permalink
Issue #305: allow kv values with equal signs
Browse files Browse the repository at this point in the history
This patch fixes the parsing of "a=b=c" into "a": "b=c"

Fixes #305
  • Loading branch information
magiconair committed Jun 13, 2017
1 parent b6ac346 commit 2baaef4
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 18 deletions.
38 changes: 20 additions & 18 deletions config/kvslice.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func parseKVSlice(in string) ([]map[string]string, error) {
}
}

v := ""
s := []rune(in)
state := stateFirstKey
for {
Expand All @@ -37,7 +38,7 @@ func parseKVSlice(in string) ([]map[string]string, error) {
}
typ, val, n := lex(s)
s = s[n:]
// fmt.Println("parse:", "typ:", typ, "val:", val, "state:", string(state), "s:", string(s))
// fmt.Println("parse:", "typ:", typ, "val:", val, "v:", v, "state:", string(state), "s:", string(s))
switch state {
case stateFirstKey:
switch typ {
Expand Down Expand Up @@ -92,27 +93,29 @@ func parseKVSlice(in string) ([]map[string]string, error) {

case stateVal:
switch typ {
case itemText:
m[keyOrFirstVal] = val
state = stateNextKVOrNewMap
default:
return nil, errors.New(val)
}

case stateNextKVOrNewMap:
switch typ {
case itemText, itemEqual:
v += val
case itemComma:
m[keyOrFirstVal] = v
v = ""
newMap()
state = stateFirstKey
case itemSemicolon:
m[keyOrFirstVal] = v
v = ""
state = stateKey
default:
return nil, errors.New(val)
}
}
}
if state == stateAfterFirstKey && keyOrFirstVal != "" {
m[""] = keyOrFirstVal
switch state {
case stateVal:
m[keyOrFirstVal] = v
case stateAfterFirstKey:
if keyOrFirstVal != "" {
m[""] = keyOrFirstVal
}
}
if len(m) > 0 {
maps = append(maps, m)
Expand Down Expand Up @@ -149,12 +152,11 @@ const (
stateQTextEsc = "qtextesc"

// parser states
stateFirstKey = "first-key"
stateKey = "key"
stateEqual = "equal"
stateVal = "val"
stateNextKVOrNewMap = "comma-semicolon"
stateAfterFirstKey = "equal-comma-semicolon"
stateFirstKey = "first-key"
stateKey = "key"
stateEqual = "equal"
stateVal = "val"
stateAfterFirstKey = "equal-comma-semicolon"
)

func lex(s []rune) (itemType, string, int) {
Expand Down
3 changes: 3 additions & 0 deletions config/kvslice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ func TestParseKVSlice(t *testing.T) {
{"first key empty and more values", "b;c=d", []map[string]string{{"": "b", "c": "d"}}, nil},
{"first key empty and more maps", "b,c", []map[string]string{{"": "b"}, {"": "c"}}, nil},
{"first key empty and more maps and values", "b;c=d,e;f=g", []map[string]string{{"": "b", "c": "d"}, {"": "e", "f": "g"}}, nil},
{"issue 305", "a=b=c,d=e=f", []map[string]string{{"a": "b=c"}, {"d": "e=f"}}, nil},
{"issue 305", "a=b=c;d=e=f", []map[string]string{{"a": "b=c", "d": "e=f"}}, nil},
{"issue 305", "a=b;d=e=f", []map[string]string{{"a": "b", "d": "e=f"}}, nil},
}

for _, tt := range tests {
Expand Down
20 changes: 20 additions & 0 deletions config/load_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,26 @@ func TestLoad(t *testing.T) {
return cfg
},
},
{
desc: "issue 305",
args: []string{
"-proxy.addr", ":443;cs=consul-cs,:80,:2375;proto=tcp+sni",
"-proxy.cs", "cs=consul-cs;type=consul;cert=http://localhost:8500/v1/kv/ssl?token=token",
},
cfg: func(cfg *Config) *Config {
cfg.Listen = []Listen{
Listen{Addr: ":443", Proto: "https"},
Listen{Addr: ":80", Proto: "http"},
Listen{Addr: ":2375", Proto: "tcp+sni"},
}
cfg.Listen[0].CertSource = CertSource{
Name: "consul-cs",
Type: "consul",
CertPath: "http://localhost:8500/v1/kv/ssl?token=token",
}
return cfg
},
},
{
args: []string{"-proxy.localip", "1.2.3.4"},
cfg: func(cfg *Config) *Config {
Expand Down

0 comments on commit 2baaef4

Please sign in to comment.