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

fmt.Sprintf: verb %q returns a surjective function #40175

Closed
ghost opened this issue Jul 12, 2020 · 2 comments
Closed

fmt.Sprintf: verb %q returns a surjective function #40175

ghost opened this issue Jul 12, 2020 · 2 comments

Comments

@ghost
Copy link

ghost commented Jul 12, 2020

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

$ go version
go version go1.14.4 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/mk/.cache/go-build"
GOENV="/home/mk/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/mk/go"
GOPRIVATE=""
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-build089759562=/tmp/go-build -gno-record-gcc-switches"

What did you do?

package main

import (
	"fmt"
)

func main() {
	const i int = 55555
	const j int = 55556
	
	u := fmt.Sprintf("%+q", i)
	v := fmt.Sprintf("%+q", j)
	
	fmt.Println(i, j, i == j, u, v, u == v)
}

For readability I use %+q instead of %q. The behavior is the same.

https://play.golang.org/p/Mrx55HYohK_u

What did you expect to see?

55555 55556 false %!q(int=+55555) %!q(int=+55556) false

What did you see instead?

55555 55556 false '\ufffd' '\ufffd' true

The behavior is strongly dependent on the input values.

According to documentation, the verb %q produces "a single-quoted character literal safely escaped with Go syntax.".

  1. It is not clear for which input values %q returns an escaped Unicode character \u[0-9a-f]+, \U[0-9a-f]+, or "a single-quoted character literal safely escaped with Go syntax.".
  2. It is not reasonable that different input values (i <> j) have the same output (u == v).
@martisch
Copy link
Contributor

martisch commented Jul 12, 2020

  1. It seems to me the property that for any Integer input (%q is listed for Integers) "a single quoted character literal" is met in the example. '\ufffd' seems to be a single quoted character literal containing a single Unicode character (here it is the unicode.ReplacementChar https://golang.org/pkg/unicode/#pkg-constants).

If this is about larger or negative inputs then an issue already exists about this. I dont think bad verb behaviour should be triggered based on value range:
#14569

If this is the issue I would suggest to close this issue as a duplicate and the discussion can continue on the older issue.

  1. I think its reasonable for different input values to have the same output in form of the unicode.ReplacementChar because not all integers can be mapped to different valid unicode characters and therefore single quoted characters with valid encoding in a character literal.

@ianlancetaylor
Copy link
Contributor

Yes, I think this is a duplicate of #14569. Let's discuss there. Please comment if you disagree.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants