Skip to content

Commit

Permalink
ISSUE-22 Fix stack overflow when messages have descendants of its own…
Browse files Browse the repository at this point in the history
… type
  • Loading branch information
carvalhorr committed Jul 14, 2020
1 parent 162f83c commit 4b73df2
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 7 deletions.
1 change: 1 addition & 0 deletions stub/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ func jsonStringMatches(jsonMap, otherJsonMap map[string]interface{}, mustBeEqual
if !jsonStringMatches(jsonMap[key].(map[string]interface{}), otherJsonMap[key].(map[string]interface{}), mustBeEqual) {
return false
}
continue
case "[]interface {}": // repeated object
// naive implementation of comparison of repeated messages.
// TODO investigate a more performant way to compare
Expand Down
21 changes: 14 additions & 7 deletions stub/stubexamples.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,20 @@ import (

func CreateStubExample(req proto.Message) string {
// TODO make marshal work with child structs
return generateJSONForType(reflect.TypeOf(req).Elem(), &bytes.Buffer{}).String()
stack := make(map[string]bool)
return generateJSONForType(reflect.TypeOf(req).Elem(), &bytes.Buffer{}, stack).String()
}

func generateJSONForType(t reflect.Type, writer *bytes.Buffer) *bytes.Buffer {
func generateJSONForType(t reflect.Type, writer *bytes.Buffer, stack map[string]bool) *bytes.Buffer {
if t.Kind() != reflect.Struct || t.NumField() == 0 {
return writer
}
typeName := t.String()
if stack[typeName] {
writer.WriteString("{}")
return writer
}
stack[typeName] = true
writer.WriteString("{")
first := true
for i := 0; i < t.NumField(); i++ {
Expand All @@ -35,22 +42,22 @@ func generateJSONForType(t reflect.Type, writer *bytes.Buffer) *bytes.Buffer {
switch t.Field(i).Type.Kind() {
case reflect.Ptr:
writer.WriteString(fmt.Sprintf("\"%s\": ", json))
generateJSONForType(t.Field(i).Type.Elem(), writer)
generateJSONForType(t.Field(i).Type.Elem(), writer, stack)
case reflect.Struct:
writer.WriteString(fmt.Sprintf("\"%s\": ", json))
generateJSONForType(t.Field(i).Type, writer)
generateJSONForType(t.Field(i).Type, writer, stack)
case reflect.String:
writer.WriteString(fmt.Sprintf("\"%s\": \"\"", json))
case reflect.Array:
writer.WriteString(fmt.Sprintf("\"%s\": [ARRAY]", json)) // Should not happen, leaving ARRAY to indicate to the consumer that it may need work
generateJSONForType(t.Field(i).Type, writer)
generateJSONForType(t.Field(i).Type, writer, stack)
case reflect.Slice:
writer.WriteString(fmt.Sprintf("\"%s\": [", json))
switch t.Field(i).Type.Elem().Kind() {
case reflect.Struct:
generateJSONForType(t.Field(i).Type.Elem(), writer)
generateJSONForType(t.Field(i).Type.Elem(), writer, stack)
case reflect.Ptr:
generateJSONForType(t.Field(i).Type.Elem().Elem(), writer)
generateJSONForType(t.Field(i).Type.Elem().Elem(), writer, stack)
}
writer.WriteString("]")
case reflect.Map:
Expand Down

0 comments on commit 4b73df2

Please sign in to comment.