你正在使用的Go版本是什么( go version
)?
$ go version
go version go1.11 darwin/amd64
这个问题在最新版本的发布中是否重现?
是的
你正在使用什么操作系统和处理器架构( go env
)?
go env
输出
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/msl21dp/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/msl21dp/go"
GOPROXY=""
GORACE=""
GOROOT="/Users/msl21dp/.gvm/gos/go1.11"
GOTMPDIR=""
GOTOOLDIR="/Users/msl21dp/.gvm/gos/go1.11/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/msl21dp/gomod/homedepot.com/vulcancore/go.mod"
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/4y/g8py5x0x0rx2qxlpxls23gnw0000gn/T/go-build585874623=/tmp/go-build -gno-record-gcc-switches -fno-common"
你做了什么?
使用日志库github.com/spf13/jwalterweatherman,我们的日志中有这样一行:
logging.INFO.Println("Logs can be viewed at https://console.cloud.google.com/logs/viewer?project=redacted&logName=projects%2Fredacted%2Flogs%redacted")
这应该在控制台打印一个用户可以点击的URL。由于URL包含一个作为参数的斜杠分隔的字符串,这些斜杠必须进行URL编码,对于正则表达式来说,这是 %2F
。
你期望看到什么?
没有验证错误
你看到了什么?
vet触发了一个错误:
Logger.Println call has possible formatting directive %2F
通常情况下这不是问题,但从Go 1.10开始,现在原生运行 go test
,并使用硬编码的检查列表,唯一的选择是将此转换为Printf并将百分号加倍以转义它们,或者在 go test
期间禁用 go vet
,这两种方法都不是很好的解决方案。
建议/可能的解决方案:
- 找出如何过滤这种情况。在这种情况下,可能的格式化指令是A)大写,以及B)在没有参数的Print调用中使用该指令(这意味着我不得不不正确地在非
f
调用中使用格式化指令,并且忘记在格式化字符串中包含要替换它的值)。 - 让特定的测试在
go test
自动运行go vet
时被禁用,可能通过类似-vetflags="-printf=false"
这样的标志来实现。这也将允许任何其他针对vet的特定标志传递给它。
6条答案
按热度按时间5n0oy7gb1#
真正的问题是为什么vet认为Println是一个printf Package 器,而实际上它并不是。如果它确实是一个printf Package 器,那么报告将是正确的,你应该使用
%%2F
来转义%
。v440hwme2#
我认为这更像是在指出,这个print调用可能是有意将其编码为Println的,但无意中被错误地编码为Println,导致指令被忽略,任何参数都被简单地附加。这是一个合理且相当有用的检查。只是在使用Println打印URL编码的字符时,它会模仿实际的格式指令时才会失效。
mm5n2pyu3#
当然,你是对的。
vmpqdwk34#
也许我们可以教分类器忽略某些常见的误报,比如
%2F
对于/
,%3F
对于?
,%3D
对于=
等等。只要我们将这些限制在字母上,我认为我们不应该担心添加误报。@alandonovan@josharian 有什么想法?
gajydyqb5#
是的,检查%XX(不以零开头的大写十六进制)可能是你提到的所有URL编码情况的最简单的解决方法。当然,仍然会有偶尔的误报。
anhgbhbe6#
我认为它不应该对只有一个参数的调用进行标记。不太可能有人不小心使用了Println而不是Printf,并且忘记为格式动词提供参数。