Skip to content
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: slice function does not work when value is wrapped in interface #36199

Closed
icza opened this issue Dec 18, 2019 · 3 comments
Closed
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@icza
Copy link

icza commented Dec 18, 2019

What version of Go are you using (go version)?

$ go version
go version go1.13.3 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/icza/.cache/go-build"
GOENV="/home/icza/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GONOPROXY="xxx"
GONOSUMDB="xxx"
GOOS="linux"
GOPATH="/home/icza/gows"
GOPRIVATE="xxx"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
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 -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build339874310=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Tried to use the slice template function introduced in Go 1.13.

Playground:

t := template.Must(template.New("").Parse(`{{slice .x 0 2}}`))

m1 := map[string][]int{
	"x": []int{1, 2, 3, 4},
}
fmt.Println(t.Execute(os.Stdout, m1))

m2 := map[string]interface{}{
	"x": []int{1, 2, 3, 4},
}
fmt.Println(t.Execute(os.Stdout, m2))

It only works if value is not wrapped in an interface value (e.g. interface{}). In my opinion, a concrete slice value stored in an interface should be "extracted" and used.

What did you expect to see?

[1 2]<nil>
[1 2]<nil>

What did you see instead?

[1 2]<nil>
template: :1:2: executing "" at <slice .x 0 2>: error calling slice: reflect: call of reflect.Value.Slice on interface Value
@mvdan
Copy link
Member

mvdan commented Dec 18, 2019

Thanks for reporting this; I think I've spotted the bug.

@mvdan mvdan self-assigned this Dec 18, 2019
@mvdan mvdan added the NeedsFix The path to resolution is known, but the work has not been done. label Dec 18, 2019
@mvdan mvdan added this to the Go1.14 milestone Dec 18, 2019
@gopherbot
Copy link

Change https://golang.org/cl/211877 mentions this issue: text/template: indirect interfaces before slicing

@gopherbot
Copy link

Change https://golang.org/cl/212117 mentions this issue: text/template: make reflect.Value indirections more robust

gopherbot pushed a commit that referenced this issue Feb 24, 2020
Always shadow or modify the original parameter name. With code like:

	func index(item reflect.Value, ... {
		v := indirectInterface(item)

It was possible to incorrectly use 'item' and 'v' later in the function,
which could result in subtle bugs. This is precisely the kind of mistake
that led to #36199.

Instead, don't keep both the old and new reflect.Value variables in
scope. Always shadow or modify the original variable.

While at it, simplify the signature of 'length', to receive a
reflect.Value directly and save a few redundant lines.

Change-Id: I01416636a9d49f81246d28b91aca6413b1ba1aa5
Reviewed-on: https://go-review.googlesource.com/c/go/+/212117
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Roberto Clapis <robclap8@gmail.com>
Reviewed-by: Rob Pike <r@golang.org>
@golang golang locked and limited conversation to collaborators Dec 18, 2020
@rsc rsc unassigned mvdan Jun 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

3 participants