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

text/template: slice function does not work when value is wrapped in interface #36199

icza opened this issue Dec 18, 2019 · 3 comments
Assignees
Labels
Milestone

Comments

@icza
Copy link

@icza 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 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 label Dec 18, 2019
@mvdan mvdan added this to the Go1.14 milestone Dec 18, 2019
@gopherbot
Copy link

@gopherbot gopherbot commented Dec 18, 2019

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

@gopherbot gopherbot closed this in 5481a97 Dec 19, 2019
@gopherbot
Copy link

@gopherbot gopherbot commented Dec 19, 2019

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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.