Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

small recursive type leads to infinite loop #171

Closed
glycerine opened this issue Jan 1, 2017 · 0 comments
Closed

small recursive type leads to infinite loop #171

glycerine opened this issue Jan 1, 2017 · 0 comments

Comments

@glycerine
Copy link
Contributor

I found this when testing ZebraPack, it appears to also be present in the upstream msgp: the small (low complexity) recursive struct Tree below causes an infinite loop during codegen. There is a check below in parse/inline.go (https://github.com/tinylib/msgp/blob/master/parse/inline.go#L118), but the types look different when printed so I don't think the check works anymore.

package main

//go:generate msgp

type S2 struct {
	A struct{}
	B string
	R map[string]uint8
	P uint16
	Q uint32
	T int64

	Arr [6]float64

	MyTree *Tree
}

type Tree struct {
	Chld []Tree
	Str  string
}

func main() {}

the fix (at least to me; please advise--it works to fix this example but will it miss other cases?) seemed something like this in parse/inline.go:

func (f *FileSet) nextInline(ref *gen.Elem, root string) {
    switch el := (*ref).(type) {
    case *gen.BaseElem:
        // ensure that we're not inlining                                                        
        // a type into itself                                                                    
        typ := el.TypeName()
        if el.Value == gen.IDENT && typ != root {
            if node, ok := f.Identities[typ]; ok && node.Complexity() < maxComplex {
+                // detect infinite loop:                                                         
+               if node.TypeName() == typ {
+                  infof("detected recursive type, not inlining %s\n", typ)
+                 return
+                }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant