-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Closed
Labels
Description
What version of Go are you using (go version
)?
$ go version go version go1.16.4 linux/amd64
Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (go env
)?
Operating System is XUbuntu 20.10 (amd64).
CPU is Intel Xeon E5-2678 v3
GOARCH="amd64"
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
go env
Output
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/home/***/.cache/go-build" GOENV="/home/***/.config/go/env" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GOMODCACHE="/home/***/go/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/home/***/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" GOVCS="" GOVERSION="go1.16.4" GCCGO="gccgo" AR="ar" CC="gcc" CXX="g++" 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 -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build740936505=/tmp/go-build -gno-record-gcc-switches"
What did you do?
I try to run the IsZero()
Method on an Object of reflect.Value
Type.
In the Debugger I reach the Code which in Comments is said to be unreachable.
panic: reflect: call of reflect.Value.IsZero on zero Value
goroutine 1 [running]:
reflect.Value.IsZero(0x0, 0x0, 0x0, 0x0)
/usr/local/go/src/reflect/value.go:1134 +0x70b
// IsZero reports whether v is the zero value for its type.
// It panics if the argument is invalid.
func (v Value) IsZero() bool {
switch v.kind() {
//...
default:
// This should never happens, but will act as a safeguard for
// later, as a default value doesn't makes sense here.
panic(&ValueError{"reflect.Value.IsZero", v.Kind()})
}
}
https://play.golang.org/p/o5j2PKXxpwJ
package main
import (
"encoding/json"
"errors"
"fmt"
"log"
"reflect"
)
type JsonObject = map[string]interface{}
type ResponseRaw struct {
Records []JsonObject
}
func main() {
text := `[{"x": 1, "y": 2}, {"z": 3, "zz": 4, "step": 123}, {}, {"id": 999}, {"q": "test", "lto": {"a": 8, "step": 456}}, null]`
rr, err := parseValidJson([]byte(text))
if err != nil {
log.Println(err)
}
fmt.Println("rr:", rr)
}
func parseValidJson(jsonText []byte) (rr *ResponseRaw, err error) {
responseAnonymous := make([]interface{}, 0)
err = json.Unmarshal(jsonText, &responseAnonymous)
if err != nil {
return nil, err
}
rr = &ResponseRaw{
Records: make([]JsonObject, 0),
}
for _, arrayItem := range responseAnonymous {
arrayItemAsJsonObject, ok := arrayItem.(JsonObject)
if !ok {
arrayItemValue := reflect.ValueOf(arrayItem)
// Here we may receive an empty Value, i.e. reflect.Value{}.
// When we receive it and check it for Zero Value, we reach that
// Part of the Code which should be unreachable.
if arrayItemValue.IsZero() {
continue
}
if arrayItemValue.IsNil() {
continue
}
// The built-in JSON Parser thinks that an empty Object '{}' is an
// empty Slice of Objects. It may be a Bug in the Parser.
arrayItemType := reflect.TypeOf(arrayItem)
if arrayItemType.Kind() == reflect.Slice {
continue
}
return nil, errors.New("json object parsing error")
}
rr.Records = append(rr.Records, arrayItemAsJsonObject)
}
return rr, nil
}
What did you expect to see?
I expected to see the reflect.Value.IsZero()
Method returning a boolean Value.
What did you see instead?
I saw the reflect.Value.IsZero()
Method reaching the unreachable code and panicing.
Samyoul and xakepp35