html/template: invalid memory address or nil pointer dereference
dvyukov opened this issue · 2 comments
dvyukov commented
package main
import (
"html/template"
"io/ioutil"
)
func main() {
t, err := template.New("foo").Parse(string(data))
if err != nil {
return
}
t.Execute(ioutil.Discard, nil)
}
var data = "{{.0.E}}"
panic: runtime error: invalid memory address or nil pointer dereference
goroutine 1 [running]:
text/template.errRecover(0xc208041eb0)
src/text/template/exec.go:100 +0xb2
text/template.(*state).evalArg(0xc2080105c0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7f01b141c210, 0xc208020120, 0x0, 0x0, ...)
src/text/template/exec.go:667 +0x46a
text/template.(*state).evalChainNode(0xc2080105c0, 0x0, 0x0, 0x0, 0xc208010500, 0xc20800a5b0, 0x1, 0x1, 0x0, 0x0, ...)
src/text/template/exec.go:439 +0x28a
text/template.(*state).evalCommand(0xc2080105c0, 0x0, 0x0, 0x0, 0xc208014810, 0x0, 0x0, 0x0, 0x0, 0x0, ...)
src/text/template/exec.go:367 +0x31d
text/template.(*state).evalPipeline(0xc2080105c0, 0x0, 0x0, 0x0, 0xc208012190, 0x0, 0x0, 0x0)
src/text/template/exec.go:343 +0x1a0
text/template.(*state).walk(0xc2080105c0, 0x0, 0x0, 0x0, 0x7f01b141c2a0, 0xc2080148a0)
src/text/template/exec.go:178 +0x13b
text/template.(*state).walk(0xc2080105c0, 0x0, 0x0, 0x0, 0x7f01b141c2e8, 0xc2080147e0)
src/text/template/exec.go:186 +0x766
text/template.(*Template).Execute(0xc208010440, 0x7f01b141c1c0, 0xc20800a4c0, 0x0, 0x0, 0x0, 0x0)
src/text/template/exec.go:141 +0x429
html/template.(*Template).Execute(0xc2080146f0, 0x7f01b141c1c0, 0xc20800a4c0, 0x0, 0x0, 0x0, 0x0)
src/html/template/template.go:104 +0x9d
main.main()
/tmp/htmltempl.go:13 +0x290
on commit ccc76db
dspezia commented
Actually, the problem happens when a dot immediately follows a literal. It can be reproduced also with {{true.E}} or {{'x'.any}}. I guess this could be caught at parsing time, providing the TODO in Tree.operand is addressed:
// Compatibility with original API: If the term is of type NodeField
// or NodeVariable, just put more fields on the original.
// Otherwise, keep the Chain node.
// TODO: Switch to Chains always when we can.
switch node.Type() {
case NodeField:
node = t.newField(chain.Position(), chain.String())
case NodeVariable:
node = t.newVariable(chain.Position(), chain.String())
default:
node = chain
}
Trying to prepare a CL.
gopherbot commented
CL https://golang.org/cl/9621 mentions this issue.