]> Cypherpunks repositories - gostls13.git/commitdiff
text/template: fix slice builtin for pointers to arrays
authorNathan Nguyen <nhan13574@gmail.com>
Fri, 5 Dec 2025 20:50:24 +0000 (15:50 -0500)
committerSean Liao <sean@liao.dev>
Mon, 15 Dec 2025 17:04:58 +0000 (09:04 -0800)
The slice function now properly handles pointers to arrays by calling
indirect() to dereference pointers, matching the behavior of the index
function.

Fixes #39596

Change-Id: Id4920edbfd8fd3df3a181b59a61733f88b0f104d
Reviewed-on: https://go-review.googlesource.com/c/go/+/727400
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Sean Liao <sean@liao.dev>
Reviewed-by: Rob Pike <r@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
src/text/template/exec_test.go
src/text/template/funcs.go

index 8665f3ad4987c2add0bc60d8a43e19e30d219a60..5812c7b1369b7832424554bad425074dc09bae65 100644 (file)
@@ -43,7 +43,8 @@ type T struct {
        SIEmpty []int
        SB      []bool
        // Arrays
-       AI [3]int
+       AI  [3]int
+       PAI *[3]int // pointer to array
        // Maps
        MSI      map[string]int
        MSIone   map[string]int // one element, for deterministic output
@@ -142,6 +143,7 @@ var tVal = &T{
        SI:     []int{3, 4, 5},
        SICap:  make([]int, 5, 10),
        AI:     [3]int{3, 4, 5},
+       PAI:    &[3]int{3, 4, 5},
        SB:     []bool{true, false},
        MSI:    map[string]int{"one": 1, "two": 2, "three": 3},
        MSIone: map[string]int{"one": 1},
@@ -556,6 +558,9 @@ var execTests = []execTest{
        {"array[:]", "{{slice .AI}}", "[3 4 5]", tVal, true},
        {"array[1:]", "{{slice .AI 1}}", "[4 5]", tVal, true},
        {"array[1:2]", "{{slice .AI 1 2}}", "[4]", tVal, true},
+       {"pointer to array[:]", "{{slice .PAI}}", "[3 4 5]", tVal, true},
+       {"pointer to array[1:]", "{{slice .PAI 1}}", "[4 5]", tVal, true},
+       {"pointer to array[1:2]", "{{slice .PAI 1 2}}", "[4]", tVal, true},
        {"string[:]", "{{slice .S}}", "xyz", tVal, true},
        {"string[0:1]", "{{slice .S 0 1}}", "x", tVal, true},
        {"string[1:]", "{{slice .S 1}}", "yz", tVal, true},
index 30b3243a5a841604d98e3e3cba50b6df3614d30a..ed9c7ea5d550158c8f6deb4aa277bb59bb49cf58 100644 (file)
@@ -244,6 +244,10 @@ func slice(item reflect.Value, indexes ...reflect.Value) (reflect.Value, error)
        if !item.IsValid() {
                return reflect.Value{}, fmt.Errorf("slice of untyped nil")
        }
+       var isNil bool
+       if item, isNil = indirect(item); isNil {
+               return reflect.Value{}, fmt.Errorf("slice of nil pointer")
+       }
        if len(indexes) > 3 {
                return reflect.Value{}, fmt.Errorf("too many slice indexes: %d", len(indexes))
        }