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

json.Unmarshal return json.UnmarshalTypeError at certain situation, which should not #45717

Closed
yibaoren opened this issue Apr 23, 2021 · 3 comments

Comments

@yibaoren
Copy link

yibaoren commented Apr 23, 2021

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

$ go version
go1.15.5 
go1.16.3 darwin/amd64

Does this issue reproduce with the latest release?

yes , with go1.16.3 darwin/amd64

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

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/root/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/root/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-build705674470=/tmp/go-build -gno-record-gcc-switches"

What did you do?

package main

import (
	"encoding/json"
	"log"
)

type DepthItem struct {
	EventTime int `json:"E"`
	EventType string `json:"e"`
	Symbol string `json:"s"`
	TargetSymbol string     `json:"ps"`
	Timestamp    int        `json:"T"`
	FIRST_CODE   int        `json:"U"`
	CHECK_CODE   int        `json:"u"`
	PRE_CODE     int        `json:"pu"`
	Bids         [][]string `json:"b"`
	Asks         [][]string `json:"a"`
}
type WSDepthResponse struct {
	Stream string    `json:"stream"`
	Data   DepthItem `json:"data"`
}

func main()  {
	depth:=new(WSDepthResponse)
	msg:="{\"stream\":\"btcusd_perp@depth@100ms\",\"data\":{\"e\":\"depthUpdate\",\"E\":1619145795649,\"T\":1619145795645,\"s\":\"BTCUSD_PERP\",\"ps\":\"BTCUSD\",\"U\":91362955964,\"u\":91362957944,\"pu\":91362955955}}"
	log.Println(msg)
	err:=json.Unmarshal([]byte(msg),depth)
	if err==nil {
		log.Printf("解析成功:%v",*depth)
	} else {
		log.Printf("解析失败:%v",err)
		panic(err)
	}

}

The link is below
https://play.golang.org/p/7uoE9d7b1KM

What did you expect to see?

I expect json.Unmarshal to work normally without error.

What did you see instead?

the program panic when either the field of EventTime or EventType of DepthItem struct is comment.
panic: json: cannot unmarshal string into Go struct field DepthItem.data.E of type int
when both EventTime and EventType of DepthItem struct are comment, it work fine.
when both EventTime and EventType of DepthItem struct are uncomment, it works fine.

The error occurs because two fields has similary names "E" and "e".And, json.Unmarshal function can not distinguish them.

@akupila
Copy link

akupila commented Apr 23, 2021

Similar to #43664

@mvdan
Copy link
Member

mvdan commented Apr 23, 2021

You get the error because you commented out the `json:"E"` field, and the json package matches key names in a case insensitive way:

To unmarshal JSON into a struct, Unmarshal matches incoming object keys to the keys used by Marshal (either the struct field name or its tag), preferring an exact match but also accepting a case-insensitive match.

Also see #14750. The whole key name matching logic should be overhauled to be made less confusing, and we can't change this one behavior without breaking programs.

@mvdan mvdan closed this as completed Apr 23, 2021
@yibaoren
Copy link
Author

Thanks for your explanation @mvdan

@golang golang locked and limited conversation to collaborators Apr 25, 2022
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

4 participants