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: call with no arguments after a pipe crashes the program #70341

Open
ozelis opened this issue Nov 14, 2024 · 4 comments
Open

text/template: call with no arguments after a pipe crashes the program #70341

ozelis opened this issue Nov 14, 2024 · 4 comments
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.

Comments

@ozelis
Copy link

ozelis commented Nov 14, 2024

Go version

go version go1.23.2 linux/amd64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/ao/.cache/go-build'
GOENV='/home/ao/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/ao/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/ao/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/lib/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/lib/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.23.2'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/ao/.config/go/telemetry'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build785295111=/tmp/go-build -gno-record-gcc-switches'

What did you do?

https://go.dev/play/p/RapayQaYsZw

package main

import "fmt"
import "text/template"
import "bytes"

func main() {
    tmpl, err := template.New("foo").Parse("{{ 1 | call }}")

    if err != nil {
      fmt.Println(err)
    } else {
      var buf bytes.Buffer
      tmpl.Execute(&buf, "whatever")
      fmt.Println(&buf)
    }
}

What did you see happen?

panic: runtime error: index out of range [0] with length 0 [recovered]
	panic: runtime error: index out of range [0] with length 0

goroutine 1 [running]:
text/template.errRecover(0xc00010ae48)
	/usr/lib/go/src/text/template/exec.go:170 +0x15a
panic({0x539c80?, 0xc00001a150?})
	/usr/lib/go/src/runtime/panic.go:785 +0x132
text/template.(*state).evalCall(0xc00010ae58, {0x51f500?, 0x57ffa0?, 0xc00010aac0?}, {0x525b40?, 0x553530?, 0x1?}, 0x1, {0x582240, 0xc000102270}, ...)
	/usr/lib/go/src/text/template/exec.go:806 +0xb65
text/template.(*state).evalFunction(0xc00010ae58, {0x51f500?, 0x57ffa0?, 0xc00010e1a0?}, 0xf?, {0x582240, 0xc000102270}, {0xc0000140d0, 0x1, 0x1}, ...)
	/usr/lib/go/src/text/template/exec.go:623 +0x1ff
text/template.(*state).evalCommand(0xc00010ae58, {0x51f500?, 0x57ffa0?, 0x0?}, 0xc000102270, {0x51f740?, 0x65b4e8?, 0x469485?})
	/usr/lib/go/src/text/template/exec.go:510 +0x1ce
text/template.(*state).evalPipeline(0xc000125e58, {0x51f500?, 0x57ffa0?, 0xc000102360?}, 0xc00002e1e0)
	/usr/lib/go/src/text/template/exec.go:479 +0x125
text/template.(*state).walk(0xc000125e58, {0x51f500?, 0x57ffa0?, 0x7e0d9f96b108?}, {0x582360?, 0xc0001022d0})
	/usr/lib/go/src/text/template/exec.go:267 +0x225
text/template.(*state).walk(0xc000125e58, {0x51f500?, 0x57ffa0?, 0xc00010aea0?}, {0x5822d0?, 0xc000102210?})
	/usr/lib/go/src/text/template/exec.go:280 +0x2e5
text/template.(*Template).execute(0xc0001040c0, {0x580b58?, 0xc000102330?}, {0x51f500?, 0x57ffa0?})
	/usr/lib/go/src/text/template/exec.go:224 +0x275
text/template.(*Template).Execute(...)
	/usr/lib/go/src/text/template/exec.go:207
main.main()
	/home/ao/proj/go_test/test.go:14 +0x185

What did you expect to see?

Previously it would report a normal error calling call: non-function of type int, but after changes in recent
commit c506f03

// ...
	if isBuiltin && name == "call" {
		calleeName := args[0].String()
		argv = append([]reflect.Value{reflect.ValueOf(calleeName)}, argv...)
		fun = reflect.ValueOf(call)
	}
// ...

it tries to access args[0] which in this case is empty and crashes the whole program.

@seankhliao
Copy link
Member

cc @Zxilly

@seankhliao seankhliao added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Nov 14, 2024
callthingsoff added a commit to callthingsoff/go that referenced this issue Nov 14, 2024
Fixes golang#70341

Change-Id: I3df0175929b4aed76522ef36aecfa924f3883d9e
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/628095 mentions this issue: text/template: avoid index-out-of-range panic when accessing args[0]

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/628096 mentions this issue: text/template: don't crash piping to call with no arguments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants