From a4efa8c091bb41968c2a2e198fa239625ed8a24e Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Thu, 10 Oct 2019 11:55:52 +0200 Subject: pkg/compiler: fix infinite recursion in template instantiation Currently we replace a template argument and then recurse into the new type AST to see if there is more to replace. If the description is buggy and the template argument contains itself, then we will recurse infintiely trying to replace it more and more. Use post-order traversal when replacing template argument to fix this. --- pkg/ast/walk.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'pkg/ast/walk.go') diff --git a/pkg/ast/walk.go b/pkg/ast/walk.go index fe9112578..1ec3a8fc6 100644 --- a/pkg/ast/walk.go +++ b/pkg/ast/walk.go @@ -4,7 +4,7 @@ package ast // Walk calls callback cb for every top-level node in description. -// Note: it's not recursive. Use Recursive helper for recursive walk. +// Note: it's not recursive. Use Recursive/PostRecursive helpers for recursive walk. func (desc *Description) Walk(cb func(Node)) { for _, n := range desc.Nodes { cb(n) @@ -20,6 +20,15 @@ func Recursive(cb func(Node)) func(Node) { return rec } +func PostRecursive(cb func(Node)) func(Node) { + var rec func(Node) + rec = func(n Node) { + n.Walk(rec) + cb(n) + } + return rec +} + func (n *NewLine) Walk(cb func(Node)) {} func (n *Comment) Walk(cb func(Node)) {} func (n *Ident) Walk(cb func(Node)) {} -- cgit mrf-deployment