Skip to content

Commit

Permalink
track the visited structures in the checkStruct fucntion
Browse files Browse the repository at this point in the history
fix #16 with stack overflow issue when a struct has the fields of self type
  • Loading branch information
SVilgelm committed Feb 10, 2023
1 parent 27a84af commit 9605dbe
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 3 deletions.
11 changes: 8 additions & 3 deletions musttag.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ func run(pass *analysis.Pass, funcs map[string]Func) (any, error) {

walk := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
filter := []ast.Node{(*ast.CallExpr)(nil)}
visited := make(map[string]struct{})

walk.Preorder(filter, func(n ast.Node) {
call, ok := n.(*ast.CallExpr)
Expand Down Expand Up @@ -171,7 +172,7 @@ func run(pass *analysis.Pass, funcs map[string]Func) (any, error) {
return // not a struct argument.
}

reportPos, ok := checkStruct(s, fn.Tag)
reportPos, ok := checkStruct(s, fn.Tag, visited)
if ok {
return // nothing to report.
}
Expand Down Expand Up @@ -222,7 +223,8 @@ func parseStruct(t types.Type, pos token.Pos) (*structInfo, bool) {

// checkStruct recursively checks the given struct and returns the position for report,
// in case one of its fields is missing the tag.
func checkStruct(s *structInfo, tag string) (token.Pos, bool) {
func checkStruct(s *structInfo, tag string, visited map[string]struct{}) (token.Pos, bool) {
visited[s.String()] = struct{}{}
for i := 0; i < s.NumFields(); i++ {
if !s.Field(i).Exported() {
continue
Expand All @@ -238,7 +240,10 @@ func checkStruct(s *structInfo, tag string) (token.Pos, bool) {
if !ok {
continue
}
if pos, ok := checkStruct(nested, tag); !ok {
if _, ok := visited[nested.String()]; ok {
continue
}
if pos, ok := checkStruct(nested, tag, visited); !ok {
return pos, false
}
}
Expand Down
11 changes: 11 additions & 0 deletions testdata/src/tests/tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -468,3 +468,14 @@ func nonStructArgument() {
custom.Marshal(0)
custom.Unmarshal(nil, &[]int{})
}

// test for stack overflow issue: https://github.com/junk1tm/musttag/issues/16
func selfType() {
type Human struct {
Mom *Human `json:"mom"`
Dad *Human `json:"dad"`
Children []*Human `json:"children"`
}
var v *Human
json.Marshal(v)
}

0 comments on commit 9605dbe

Please sign in to comment.