-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Closed
Closed
Copy link
Labels
FrozenDueToAgeNeedsDecisionFeedback is required from experts, contributors, and/or the community before a change can be made.Feedback is required from experts, contributors, and/or the community before a change can be made.
Milestone
Description
go version && go env
go version go1.11 darwin/amd64
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/bep/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/bep/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/Cellar/go/1.11/libexec"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.11/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/bep/dev/go/gohugoio/hugo/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/n6/s_85mm8d31j6yctssnmn_g1r0000gn/T/go-build656061374=/tmp/go-build -gno-record-gcc-switches -fno-common"
package main
import (
"bytes"
"log"
"strings"
"text/template"
)
type F struct {
name string
}
func (f *F) Name() string {
return f.name
}
func (f *F) Other() *F {
return nil
}
func main() {
var buf bytes.Buffer
tmpl, err := template.New("").Parse(`{{ .Other.Name }}`)
if err != nil {
log.Fatal(err)
}
data := &F{name: "foo"}
if err := tmpl.Execute(&buf, data); err != nil {
log.Fatal(err)
}
result := strings.TrimSpace(buf.String())
if !strings.Contains(result, "foo") {
log.Fatal(result)
}
}The above panics:
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x10ec8a5]
goroutine 1 [running]:
text/template.errRecover(0xc0000a9ec0)
/usr/local/Cellar/go/1.11/libexec/src/text/template/exec.go:160 +0x1d0
panic(0x110e180, 0x121a910)
/usr/local/Cellar/go/1.11/libexec/src/runtime/panic.go:513 +0x1b9
main.(*F).Name(0x0, 0x0, 0x0)
/Users/bep/dev/go/bep/temp/main.go:15 +0x5
reflect.Value.call(0x110e5c0, 0xc000068338, 0x293, 0x112ebd0, 0x4, 0x123da30, 0x0, 0x0, 0x112d940, 0x1, ...)
/usr/local/Cellar/go/1.11/libexec/src/reflect/value.go:447 +0x449
reflect.Value.Call(0x110e5c0, 0xc000068338, 0x293, 0x123da30, 0x0, 0x0, 0xc000072100, 0x1, 0x1)
/usr/local/Cellar/go/1.11/libexec/src/reflect/value.go:308 +0xa4
text/template.(*state).evalCall(0xc0000a9e40, 0x110e5c0, 0xc000068290, 0x16, 0x110e5c0, 0xc000068338, 0x293, 0x114e920, 0xc00006a360, 0xc000082027, ...)
/usr/local/Cellar/go/1.11/libexec/src/text/template/exec.go:695 +0x6bd
text/template.(*state).evalField(0xc0000a9e40, 0x110e5c0, 0xc000068290, 0x16, 0xc000082027, 0x4, 0x114e920, 0xc00006a360, 0xc000068270, 0x1, ...)
/usr/local/Cellar/go/1.11/libexec/src/text/template/exec.go:585 +0xd78
text/template.(*state).evalFieldChain(0xc0000a9e40, 0x110e5c0, 0xc000068290, 0x16, 0x110e5c0, 0xc000068290, 0x16, 0x114e920, 0xc00006a360, 0xc000072060, ...)
/usr/local/Cellar/go/1.11/libexec/src/text/template/exec.go:553 +0x217
text/template.(*state).evalFieldNode(0xc0000a9e40, 0x110e5c0, 0xc000068290, 0x16, 0xc00006a360, 0xc000068270, 0x1, 0x1, 0x110e420, 0x123da30, ...)
/usr/local/Cellar/go/1.11/libexec/src/text/template/exec.go:517 +0x113
text/template.(*state).evalCommand(0xc0000a9e40, 0x110e5c0, 0xc000068290, 0x16, 0xc00006a300, 0x110e420, 0x123da30, 0x99, 0x100b738, 0xd0, ...)
/usr/local/Cellar/go/1.11/libexec/src/text/template/exec.go:455 +0x725
text/template.(*state).evalPipeline(0xc0000a9e40, 0x110e5c0, 0xc000068290, 0x16, 0xc000092180, 0xc0000a9c01, 0xc000074750, 0xc0000a9d40)
/usr/local/Cellar/go/1.11/libexec/src/text/template/exec.go:429 +0x126
text/template.(*state).walk(0xc0000a9e40, 0x110e5c0, 0xc000068290, 0x16, 0x114e7e0, 0xc00006a390)
/usr/local/Cellar/go/1.11/libexec/src/text/template/exec.go:254 +0x49b
text/template.(*state).walk(0xc0000a9e40, 0x110e5c0, 0xc000068290, 0x16, 0x114e9e0, 0xc00006a2d0)
/usr/local/Cellar/go/1.11/libexec/src/text/template/exec.go:262 +0x142
text/template.(*Template).execute(0xc000084080, 0x114e2e0, 0xc0000a0000, 0x110e5c0, 0xc000068290, 0x0, 0x0)
/usr/local/Cellar/go/1.11/libexec/src/text/template/exec.go:217 +0x215
text/template.(*Template).Execute(0xc000084080, 0x114e2e0, 0xc0000a0000, 0x110e5c0, 0xc000068290, 0x0, 0xc00007ef38)
/usr/local/Cellar/go/1.11/libexec/src/text/template/exec.go:200 +0x53
main.main()
I understand that the user should wrap the above in a with or something, but having maintained Hugo for some years I can say this:
- This is a very common problem
- And the error you get from this is extremely hard to debug
That, and if you follow the code in the Go source, there are nil checks for the other cases, but not for the "method case":
https://github.com/golang/go/blob/master/src/text/template/exec.go#L594
hanzei, kaushalmodi, mcandre, zwbetz-gh, a-hilaly and 1 more
Metadata
Metadata
Assignees
Labels
FrozenDueToAgeNeedsDecisionFeedback is required from experts, contributors, and/or the community before a change can be made.Feedback is required from experts, contributors, and/or the community before a change can be made.