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: cannot compare to '.' constant (byte(46)) #34483

Closed
twpayne opened this issue Sep 23, 2019 · 4 comments
Closed

text/template: cannot compare to '.' constant (byte(46)) #34483

twpayne opened this issue Sep 23, 2019 · 4 comments
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@twpayne
Copy link
Contributor

twpayne commented Sep 23, 2019

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

$ go version
go version go1.13 darwin/amd64

Does this issue reproduce with the latest release?

Not tested, but I can't find any existing issues.

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

go env Output
$ go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/twp/Library/Caches/go-build"
GOENV="/Users/twp/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/twp"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/Cellar/go/1.13/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.13/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/dev/null"
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 -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/7m/6k5drphj6gjfgm_8gj44_55w0000gn/T/go-build109468161=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

The bug is demonstrated by this program:

package main

import (
	"bytes"
	"fmt"
	"text/template"
)

func main() {
	tmpl := template.Must(template.New("").Parse(`
		{{- if (eq .X '.') -}}
			x is a dot
		{{- else -}}
			x is not a dot
		{{- end -}}
	`))
	b := &bytes.Buffer{}
	if err := tmpl.Execute(b, map[string]interface{}{
		"X": '.',
	}); err != nil {
		panic(err)
	}
	fmt.Println(b.String())
}

Link to play.golang.org.

What did you expect to see?

I expected to see the output

x is a dot

What did you see instead?

The program panics with:

panic: template: :2:10: executing "" at <eq .X '.'>: error calling eq: incompatible types for comparison

goroutine 1 [running]:
main.main()
	/tmp/sandbox073720964/prog.go:21 +0x420

Note that if I replace the '.' constant in the template with the integer 46, then the output is as expected, as demonstrated in this link to play.golang.org. If I replace the '.' with a different character constant, e.g. 'a', then the output is as expected.

The text/template documentation states:

- A boolean, string, character, integer, floating-point, imaginary
  or complex constant in Go syntax. These behave like Go's untyped
  constants. Note that, as in Go, whether a large integer constant
  overflows when assigned or passed to a function can depend on whether
  the host machine's ints are 32 or 64 bits.

but it looks like the byte constant '.' is not treated the same way as other byte constants.

@mvdan
Copy link
Member

mvdan commented Sep 24, 2019

Slightly simpler reproducer: https://play.golang.org/p/xY1QhSsYOry

Investigating.

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

mvdan commented Sep 24, 2019

Oh, this was a weird one - the template package got confused and thought that the dot meant that the value was part of a floating point literal. Fix incoming.

I'm afraid this has been broken since at least Go 1.12, and there's a temporary workaround (use a number literal instead of a rune literal), so I don't think we should backport.

@gopherbot
Copy link

Change https://golang.org/cl/196808 mentions this issue: text/template: don't evaluate '.' as a float64

@twpayne
Copy link
Contributor Author

twpayne commented Sep 24, 2019

Many thanks for the speedy investigation and fix! I'm happy to use the workaround for now.

@golang golang locked and limited conversation to collaborators Sep 24, 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