Skip to content

Commit

Permalink
text/template: use reflect.Value.FieldByIndexErr
Browse files Browse the repository at this point in the history
to avoid a crash on a nil pointer as an embedded field.

Fixes #48215

Change-Id: I214faa6e3cf08cdec1c01035e4bbca0900c6a408
Reviewed-on: https://go-review.googlesource.com/c/go/+/357963
Trust: Rob Pike <[email protected]>
Run-TryBot: Rob Pike <[email protected]>
TryBot-Result: Go Bot <[email protected]>
Reviewed-by: Ian Lance Taylor <[email protected]>
  • Loading branch information
robpike committed Oct 29, 2021
1 parent 33c392f commit d3d8852
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/text/template/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -635,10 +635,13 @@ func (s *state) evalField(dot reflect.Value, fieldName string, node parse.Node,
case reflect.Struct:
tField, ok := receiver.Type().FieldByName(fieldName)
if ok {
field := receiver.FieldByIndex(tField.Index)
field, err := receiver.FieldByIndexErr(tField.Index)
if !tField.IsExported() {
s.errorf("%s is an unexported field of struct type %s", fieldName, typ)
}
if err != nil {
s.errorf("%v", err)
}
// If it's a function, we must call it.
if hasArgs {
s.errorf("%s has arguments but cannot be invoked as function", fieldName)
Expand Down
23 changes: 23 additions & 0 deletions src/text/template/exec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1787,3 +1787,26 @@ func TestIssue39807(t *testing.T) {

wg.Wait()
}

// Issue 48215: embedded nil pointer causes panic.
// Fixed by adding FieldByIndexErr to the reflect package.
func TestIssue48215(t *testing.T) {
type A struct {
S string
}
type B struct {
*A
}
tmpl, err := New("").Parse(`{{ .S }}`)
if err != nil {
t.Fatal(err)
}
err = tmpl.Execute(io.Discard, B{})
// We expect an error, not a panic.
if err == nil {
t.Fatal("did not get error for nil embedded struct")
}
if !strings.Contains(err.Error(), "reflect: indirection through nil pointer to embedded struct field A") {
t.Fatal(err)
}
}

0 comments on commit d3d8852

Please sign in to comment.