Skip to content
Permalink
Browse files

syntax: fix nested <<- printer crash

Found by go-fuzz. Instead of relying on the parent to initialise
tabsPrinter, allocate a new one each time.

This is a bit more wasteful in the common case, but at least it's not
buggy.
  • Loading branch information...
mvdan committed Jun 4, 2019
1 parent a4613d0 commit 90c668d38bb31c31976ed8b8cad3cf514aff6c62
Showing with 24 additions and 5 deletions.
  1. +4 −5 syntax/printer.go
  2. +20 −0 syntax/printer_test.go
@@ -53,9 +53,8 @@ func Minify(p *Printer) { p.minify = true }
// NewPrinter allocates a new Printer and applies any number of options.
func NewPrinter(options ...func(*Printer)) *Printer {
p := &Printer{
bufWriter: bufio.NewWriter(nil),
tabsPrinter: new(Printer),
tabWriter: new(tabwriter.Writer),
bufWriter: bufio.NewWriter(nil),
tabWriter: new(tabwriter.Writer),
}
for _, opt := range options {
opt(p)
@@ -393,10 +392,10 @@ func (p *Printer) flushHeredocs() {
baseIndent: int(p.level + 1),
firstIndent: -1,
}
*p.tabsPrinter = Printer{
p.tabsPrinter = &Printer{
bufWriter: &extra,
line: r.Hdoc.Pos().Line(),
}
p.tabsPrinter.line = r.Hdoc.Pos().Line()
p.tabsPrinter.word(r.Hdoc)
p.indent()
p.line = r.Hdoc.End().Line()
@@ -1043,3 +1043,23 @@ func TestPrintManyStmts(t *testing.T) {
})
}
}

func TestPrintCrash(t *testing.T) {
t.Parallel()
inputs := []string{
"<<-EOF\n`<<-''\n\uffcb\n`\n",
}
parser := NewParser(KeepComments)
printer := NewPrinter()
for i, in := range inputs {
t.Run(fmt.Sprintf("%02d", i), func(t *testing.T) {
prog, err := parser.Parse(strings.NewReader(in), "")
if err != nil {
t.Fatal(err)
}
if _, err := strPrint(printer, prog); err != nil {
t.Fatal(err)
}
})
}
}

0 comments on commit 90c668d

Please sign in to comment.
You can’t perform that action at this time.