diff --git a/config/kvslice.go b/config/kvslice.go index 112911cca..c9843e648 100644 --- a/config/kvslice.go +++ b/config/kvslice.go @@ -29,6 +29,7 @@ func parseKVSlice(in string) ([]map[string]string, error) { } } + v := "" s := []rune(in) state := stateFirstKey for { @@ -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 { @@ -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) @@ -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) { diff --git a/config/kvslice_test.go b/config/kvslice_test.go index 670b3a15b..d126b588a 100644 --- a/config/kvslice_test.go +++ b/config/kvslice_test.go @@ -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 { diff --git a/config/load_test.go b/config/load_test.go index 028118979..05e1af209 100644 --- a/config/load_test.go +++ b/config/load_test.go @@ -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 {