Skip to content

text/template: new keywords (e.g. break, continue) breaks older working programs #56538

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

Closed
bep opened this issue Nov 3, 2022 · 7 comments
Closed
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.

Comments

@bep
Copy link
Contributor

bep commented Nov 3, 2022

E.g.

package main

import (
	"os"
	"text/template"
)

func main() {

	t := `{{ break 32 }}`

	echo := func(in any) any {
		return in
	}

	funcs := template.FuncMap{
		"break": echo,
	}

	tmpl, err := template.New("test").Funcs(funcs).Parse(t)
	if err != nil {
		panic(err)
	}

	err = tmpl.Execute(os.Stdout, nil)
	if err != nil {
		panic(err)
	}
}

Note that the above program is a little constructed; I, personally, am not concerned about break/continue. But I notice that the upcoming new return keyword (#53015) uses the same approach. And an app I'm maintaining (Hugo) does have a return template func.

Go 1.18:

go1.18 run main.go                                                              
32

Go 1.19.3:

go version && go run main.go                                                       
go version go1.19.3 darwin/arm64
panic: template: test:1: unexpected "32" in {{break}}
goroutine 1 [running]:
main.main()
	/Users/bep/dev/go/bep/temp/main.go:24 +0x258
exit status 2
@seankhliao
Copy link
Member

cc @robpike

@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 3, 2022
@bcmills
Copy link
Contributor

bcmills commented Nov 3, 2022

FWIW, the change could be made non-breaking by only giving the new behavior to new keywords if they do not have a corresponding entry in the FuncMap.

@bep
Copy link
Contributor Author

bep commented Nov 3, 2022

FWIW, the change could be made non-breaking by only giving the new behavior to new keywords if they do not have a corresponding entry in the FuncMap.

Yes, and that was also the original implementation (note that break and continue was introduced in Go 1.18, this is a Go 1.19 regression).

@bcmills
Copy link
Contributor

bcmills commented Nov 3, 2022

this is a Go 1.19 regression

Any idea when specifically it regressed?

https://go.dev/cl/410414 (for #53234) looks like a likely culprit to me (attn @eliben; CC @mvdan)

@eliben
Copy link
Member

eliben commented Nov 3, 2022

Just a note that I can reproduce this with tip as well (go version devel go1.20-2af48cbb7d).

@robpike significantly refactored the template lexer for 1.20 (https://go-review.googlesource.com/c/go/+/421883) but this doesn't affect the issue (it works in 1.18 but not 1.19 or 1.20)

@eliben
Copy link
Member

eliben commented Nov 3, 2022

Indeed, https://go-review.googlesource.com/c/go/+/410414 is the culprit as @bcmills suspected.

The fix is straightforward; I want to spend a bit of time devising tests, since it's annoying that the package's tests didn't catch this bug.

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/447775 mentions this issue: text/template/parse: fix interaction of break/continue keywords and functions

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

No branches or pull requests

5 participants