diff options
author | Daniel Martí <mvdan@mvdan.cc> | 2019-12-18 10:05:59 +0000 |
---|---|---|
committer | Daniel Martí <mvdan@mvdan.cc> | 2019-12-19 13:52:09 +0000 |
commit | 5481a97ab097ad27e9eeb9d10feeae22fd20e5ec (patch) | |
tree | 0ce759f34689baf98b4275d2be89d16a1b3f7663 /src/text | |
parent | ba66797392da2b6538ce014a4f7e13c490e74d59 (diff) | |
download | go-5481a97ab097ad27e9eeb9d10feeae22fd20e5ec.tar.gz go-5481a97ab097ad27e9eeb9d10feeae22fd20e5ec.zip |
text/template: indirect interfaces before slicing
The recently added slice function used indirectInterface, but then
forgot to actually call reflect.Value.Slice on its result. Calling the
Slice method on the original Value without indirectInterface would
result in a panic, if our slice was indeed behind an interface.
Fix that, and add test cases for all three built-in functions that work
with slices.
Fixes #36199.
Change-Id: I9a18f4f604a3b29967eefeb573f8960000936b88
Reviewed-on: https://go-review.googlesource.com/c/go/+/211877
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
Diffstat (limited to 'src/text')
-rw-r--r-- | src/text/template/exec_test.go | 3 | ||||
-rw-r--r-- | src/text/template/funcs.go | 4 |
2 files changed, 5 insertions, 2 deletions
diff --git a/src/text/template/exec_test.go b/src/text/template/exec_test.go index aa5cd4c552..77294eda4b 100644 --- a/src/text/template/exec_test.go +++ b/src/text/template/exec_test.go @@ -502,6 +502,7 @@ var execTests = []execTest{ {"map MUI64S", "{{index .MUI64S 3}}", "ui643", tVal, true}, {"map MI8S", "{{index .MI8S 3}}", "i83", tVal, true}, {"map MUI8S", "{{index .MUI8S 2}}", "u82", tVal, true}, + {"index of an interface field", "{{index .Empty3 0}}", "7", tVal, true}, // Slicing. {"slice[:]", "{{slice .SI}}", "[3 4 5]", tVal, true}, @@ -527,12 +528,14 @@ var execTests = []execTest{ {"string[1:2]", "{{slice .S 1 2}}", "y", tVal, true}, {"out of range", "{{slice .S 1 5}}", "", tVal, false}, {"3-index slice of string", "{{slice .S 1 2 2}}", "", tVal, false}, + {"slice of an interface field", "{{slice .Empty3 0 1}}", "[7]", tVal, true}, // Len. {"slice", "{{len .SI}}", "3", tVal, true}, {"map", "{{len .MSI }}", "3", tVal, true}, {"len of int", "{{len 3}}", "", tVal, false}, {"len of nothing", "{{len .Empty0}}", "", tVal, false}, + {"len of an interface field", "{{len .Empty3}}", "2", tVal, true}, // With. {"with true", "{{with true}}{{.}}{{end}}", "true", tVal, true}, diff --git a/src/text/template/funcs.go b/src/text/template/funcs.go index 0568c798a8..46125bc216 100644 --- a/src/text/template/funcs.go +++ b/src/text/template/funcs.go @@ -264,13 +264,13 @@ func slice(item reflect.Value, indexes ...reflect.Value) (reflect.Value, error) return reflect.Value{}, fmt.Errorf("invalid slice index: %d > %d", idx[0], idx[1]) } if len(indexes) < 3 { - return item.Slice(idx[0], idx[1]), nil + return v.Slice(idx[0], idx[1]), nil } // given item[i:j:k], make sure i <= j <= k. if idx[1] > idx[2] { return reflect.Value{}, fmt.Errorf("invalid slice index: %d > %d", idx[1], idx[2]) } - return item.Slice3(idx[0], idx[1], idx[2]), nil + return v.Slice3(idx[0], idx[1], idx[2]), nil } // Length |