Skip to content

Commit

Permalink
[v2] fix stack overflow error in helm template. (#7185)
Browse files Browse the repository at this point in the history
* fix #6116

Signed-off-by: zwwhdls <zwwhdls@hotmail.com>

* fix another extreme case

Signed-off-by: zwwhdls <zwwhdls@hotmail.com>
  • Loading branch information
zwwhdls committed Jul 7, 2020
1 parent 0ea9e6c commit 0b31450
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 27 deletions.
12 changes: 10 additions & 2 deletions pkg/strvals/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,12 +277,20 @@ func (t *parser) listItem(list []interface{}, i int) ([]interface{}, error) {
}
case last == '[':
// now we have a nested list. Read the index and handle.
i, err := t.keyIndex()
nextI, err := t.keyIndex()
if err != nil {
return list, fmt.Errorf("error parsing index: %s", err)
}
var crtList []interface{}
if len(list) > i {
// If nested list already exists, take the value of list to next cycle.
existed := list[i]
if existed != nil {
crtList = list[i].([]interface{})
}
}
// Now we need to get the value after the ].
list2, err := t.listItem(list, i)
list2, err := t.listItem(crtList, nextI)
return setIndex(list, i, list2), err
case last == '.':
// We have a nested object. Send to t.key
Expand Down
129 changes: 104 additions & 25 deletions pkg/strvals/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,39 +382,118 @@ func TestParseSet(t *testing.T) {
}

func TestParseInto(t *testing.T) {
got := map[string]interface{}{
"outer": map[string]interface{}{
"inner1": "overwrite",
"inner2": "value2",
tests := []struct {
input string
input2 string
got map[string]interface{}
expect map[string]interface{}
err bool
}{
{
input: "outer.inner1=value1,outer.inner3=value3,outer.inner4=4",
got: map[string]interface{}{
"outer": map[string]interface{}{
"inner1": "overwrite",
"inner2": "value2",
},
},
expect: map[string]interface{}{
"outer": map[string]interface{}{
"inner1": "value1",
"inner2": "value2",
"inner3": "value3",
"inner4": 4,
}},
err: false,
},
}
input := "outer.inner1=value1,outer.inner3=value3,outer.inner4=4"
expect := map[string]interface{}{
"outer": map[string]interface{}{
"inner1": "value1",
"inner2": "value2",
"inner3": "value3",
"inner4": 4,
{
input: "listOuter[0][0].type=listValue",
input2: "listOuter[0][0].status=alive",
got: map[string]interface{}{},
expect: map[string]interface{}{
"listOuter": [][]interface{}{{map[string]string{
"type": "listValue",
"status": "alive",
}}},
},
err: false,
},
{
input: "listOuter[0][0].type=listValue",
input2: "listOuter[1][0].status=alive",
got: map[string]interface{}{},
expect: map[string]interface{}{
"listOuter": [][]interface{}{
{
map[string]string{"type": "listValue"},
},
{
map[string]string{"status": "alive"},
},
},
},
err: false,
},
{
input: "listOuter[0][1][0].type=listValue",
input2: "listOuter[0][0][1].status=alive",
got: map[string]interface{}{
"listOuter": []interface{}{
[]interface{}{
[]interface{}{
map[string]string{"exited": "old"},
},
},
},
},
expect: map[string]interface{}{
"listOuter": [][][]interface{}{
{
{
map[string]string{"exited": "old"},
map[string]string{"status": "alive"},
},
{
map[string]string{"type": "listValue"},
},
},
},
},
err: false,
},
}
for _, tt := range tests {
if err := ParseInto(tt.input, tt.got); err != nil {
t.Fatal(err)
}
if tt.err {
t.Errorf("%s: Expected error. Got nil", tt.input)
}

if err := ParseInto(input, got); err != nil {
t.Fatal(err)
}
if tt.input2 != "" {
if err := ParseInto(tt.input2, tt.got); err != nil {
t.Fatal(err)
}
if tt.err {
t.Errorf("%s: Expected error. Got nil", tt.input2)
}
}

y1, err := yaml.Marshal(expect)
if err != nil {
t.Fatal(err)
}
y2, err := yaml.Marshal(got)
if err != nil {
t.Fatalf("Error serializing parsed value: %s", err)
}
y1, err := yaml.Marshal(tt.expect)
if err != nil {
t.Fatal(err)
}
y2, err := yaml.Marshal(tt.got)
if err != nil {
t.Fatalf("Error serializing parsed value: %s", err)
}

if string(y1) != string(y2) {
t.Errorf("%s: Expected:\n%s\nGot:\n%s", input, y1, y2)
if string(y1) != string(y2) {
t.Errorf("%s: Expected:\n%s\nGot:\n%s", tt.input, y1, y2)
}
}
}

func TestParseIntoString(t *testing.T) {
got := map[string]interface{}{
"outer": map[string]interface{}{
Expand Down

0 comments on commit 0b31450

Please sign in to comment.