-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
text/template: panics on method on nil interface value #30143
Comments
Thanks for the report. It seems like the issue here is with field evaluation, not with the actual call; we panic on Of course, the problem is that the receiver is a nil interface, so there's no method function we can get to. That small piece of code should add an extra check at best, or a recover at worst. Not a regression in 1.12, and the release is overdue, so I'm going to milestone for 1.13 for now. If we decide this is important enough for a backport, we can always reconsider for a bugfix release like 1.12.1. |
So, this may be a new test case and a different code path, but for the end user, this is the same issue. And in that sense, it is a regression since the error behaviour now is inconsistent (two panics is more consistent than 1 error and 1 panic for the "same thing"). I know that argument isn't the strongest argument in The Book of Arguments, but I had to try :-) ... The workaround for the above would be to always return typed nils:
Which I guess is doable in most situations. But it would, of course, be simpler if a patch to fix this in Go was accepted for Go 1.12 beta3/rc1 ... /cc @spf13 I will try to get in earlier to test the Go beta releases in the future, but the merge of the #28242 fix went unnoticed for little too long. But as always, I really appreciated the hard and solid work you, @mvdan, and the other Go contributors do. |
Perhaps so. And I would have definitely said we should include it in 1.12, had the bug report been opened a couple of weeks ago :) At this point, I don't want to assume that it is fine to add more blocking issues for the 1.12 release. For now, I'll work on a CL, and we can try to get it cherry-picked for the release early next week. I'm sure others will have opinions on the matter; CC @ianlancetaylor @andybons |
Smaller repro: https://play.golang.org/p/U1AnSliUbIT |
Change https://golang.org/cl/161761 mentions this issue: |
@ianlancetaylor asked for code to show that this is a regression in Go 1.12. package main
import (
"bytes"
"fmt"
"log"
"text/template"
)
type Namer interface {
Name() string
}
type F struct {
name string
}
func (f *F) Name() string {
return f.name
}
var nilF *F
func (f *F) A1() Namer {
var ff *F
return ff
}
func (f *F) A2() Namer {
return nil
}
func main() {
data := &F{name: "foo"}
do(data, "A1")
do(data, "A2")
}
func do(data interface{}, key string) {
defer func() {
if r := recover(); r != nil {
fmt.Println("Recovered in f", r)
}
}()
var buf bytes.Buffer
tmpl, err := template.New("").Parse(fmt.Sprintf(`{{ .%s.Name }}`, key))
if err != nil {
log.Fatal(err)
}
if err := tmpl.Execute(&buf, data); err != nil {
log.Fatal(err)
}
} For Go 1.11 the above runs as: ▶ go run main.go
Recovered in f runtime error: invalid memory address or nil pointer dereference
Recovered in f reflect: Method on nil interface value FOr Go 1.12 the above runs as: 019/02/10 00:12:07 template: :1:6: executing "" at <.A1.Name>: error calling Name: runtime error: invalid memory address or nil pointer dereference
exit status 1 So, the second panic is fixed, leaving us with an inconsistent error behavior; If one of them panics, is the other now considered less of an error? How do I handle that? Note that I'm not going further into the "is this a regression" arguments. This small patch would save thousands of work hours. |
Continuing the cherry-pick discussion here instead of the CL. I agree with @ianlancetaylor that it's unnecessary risk to merge this now, given that the 1.12 release is already very late. I see @bep's point about the inconsistency, but that's a double edged sword; at this point in the freeze, if we were to take a decision in favor of consistency, it would probably be to revert my older CL. As I said before, I'd be happy to vouch for its inclusion in 1.12, had the issue been opened last month. For now, the earliest we can aim for is 1.12.1, arguing that the original 1.12 CL did not cover all edge cases.
I don't think I buy that argument; the same can be said about adding risk and further delay to an already late release. It's unfortunate that the first 1.12 release won't be perfect, but we're way past the point where non-regression bugs can be included. |
@gopherbot please backport to 1.12 |
Backport issue(s) opened: #30464 (for 1.12). Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://golang.org/wiki/MinorReleases. |
This is a follow-up to #28242 and discovered while testing
go1.12beta2
with Hugo.The program below is a common variant of the crasher in #28242 -- that still panics with
go1.12beta2
/cc @mvdan
The text was updated successfully, but these errors were encountered: