go 编码/json:在转义序列结束时的输入错误

jgwigjjp  于 4个月前  发布在  Go
关注(0)|答案(5)|浏览(44)

你正在使用哪个版本的Go( go version )?

$ go version
go version go1.20.1 linux/amd64

这个问题在最新版本中是否会重现?

是的。

你正在使用什么操作系统和处理器架构( go env )?

go env 输出

$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/lukeshu/.cache/go-build"
GOENV="/home/lukeshu/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/lukeshu/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/lukeshu/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/lib/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.20.1"
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 -fdebug-prefix-map=/run/user/1000/tmpdir/go-build3465712561=/tmp/go-build -gno-record-gcc-switches"

你做了什么?

我给JSON解析器提供了一个截断的JSON文档,其中最后一个字符是反斜杠。

package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	var obj any
	err := json.Unmarshal([]byte(`"\`), &obj)
	fmt.Println(err)
}

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

你期望看到什么?

我期望错误是 unexpected end of JSON input

你看到了什么?

我看到了错误 invalid character ' ' in string escape code ,这是一个无意义的错误,因为输入中根本没有 `` 字符!
json.Compactjson.Indent 也有同样的问题,而 json.Decoder.Decode 则正确地返回了 io.ErrUnexpectedEOF

wz3gfoph

wz3gfoph1#

@dsnet @bradfitz @mvdan per owners.

crcmnpdw

crcmnpdw2#

我认为问题的根本原因是下面的函数:

func (s *scanner) eof() int {
	if s.err != nil {
		return scanError
	}
	if s.endTop {
		return scanEnd
	}
	s.step(s, ' ')
	if s.endTop {
		return scanEnd
	}
	if s.err == nil {
		s.err = &SyntaxError{"unexpected end of JSON input", s.bytes}
	}
	return scanError
}

我确实更新了 s.err == nils.err != nil,但这导致了一些测试用例失败。

7qhs6swi

7qhs6swi3#

过去类似的错误:#56332
在encoding/json中有一些类似的"令人困惑的错误信息"。我的直觉是,我们不应该尝试单独修复其中的每一个。cc @dsnet

6ie5vjzr

6ie5vjzr4#

我正在进行一个实验性的CL,它将完全切换到一个新的"encoding/json"解析器实现,这将修复大多数(如果不是全部)这些奇怪的错误情况。

pbossiut

pbossiut5#

我猜我应该提一下,我是通过模糊测试my own JSON parserencoding/json来发现这些问题的。我的实现是GPL,但如果有什么你想偷走的话,我百分之百愿意重新许可它以便纳入标准库。

特别是,compat/json/compat_test.go可能是值得偷走的一些测试;它们是我觉得自己有必要添加的测试,尽管我的实现已经通过了encoding/json现有的测试套件(我已经将它们复制到了borrowed_*_test.go文件中)。

相关问题