Navigation Menu

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

encoding/json: Unmarshalling *websocket.Conn over a websocket with JSON crashes #14665

Closed
dolanor opened this issue Mar 6, 2016 · 3 comments
Closed

Comments

@dolanor
Copy link

dolanor commented Mar 6, 2016

  1. What version of Go are you using (go version)?
    go version go1.6 linux/amd64
  2. What operating system and processor architecture are you using (go env)?
    GOARCH="amd64"
    GOBIN=""
    GOEXE=""
    GOHOSTARCH="amd64"
    GOHOSTOS="linux"
    GOOS="linux"
    GOPATH="/home/dolanor/.local/gopath/"
    GORACE=""
    GOROOT="/usr/local/go"
    GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
    GO15VENDOREXPERIMENT="1"
    CC="gcc"
    GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
    CXX="g++"
    CGO_ENABLED="1"
  3. What did you do?
    I sent a *websocket.Conn on a websocket in JSON (by pure laziness, without caring about having it on the other side).
  4. What did you expect to see?
    I expected to get unmarshalling kind of working, even if the *websocket.Conn wouldn't work: I didn't really wanted to get this information on the other side, but it was part of a struct I wanted to send over the wire.

If I put this *websocket.Conn to nil, then I don't get problems on the other side.

  1. What did you see instead?
    panic: reflect: reflect.Value.Set using value obtained using unexported field [recovered]
        panic: interface conversion: string is not error: missing method Error

    goroutine 7 [running]:
    panic(0x752c40, 0xc820010680)
        /usr/local/go/src/runtime/panic.go:464 +0x3e6
    encoding/json.(*decodeState).unmarshal.func1(0xc8200dbd98)
        /usr/local/go/src/encoding/json/decode.go:156 +0xba
    panic(0x6c2ba0, 0xc8200e8650)
        /usr/local/go/src/runtime/panic.go:426 +0x4e9
    reflect.flag.mustBeAssignable(0x1d4)
        /usr/local/go/src/reflect/value.go:226 +0x161
    reflect.Value.Set(0x762fa0, 0xc82008c430, 0x1d4, 0x762fa0, 0xc8200e8640, 0x94)
        /usr/local/go/src/reflect/value.go:1328 +0x25
    encoding/json.(*decodeState).literalStore(0xc820106000, 0xc8201040f9, 0x4, 0x507, 0x762fa0, 0xc82008c430, 0x1d4, 0xc8200da700)
        /usr/local/go/src/encoding/json/decode.go:786 +0x3549
    encoding/json.(*decodeState).literal(0xc820106000, 0x762fa0, 0xc82008c430, 0x1d4)
        /usr/local/go/src/encoding/json/decode.go:717 +0xe9
    encoding/json.(*decodeState).value(0xc820106000, 0x762fa0, 0xc82008c430, 0x1d4)
        /usr/local/go/src/encoding/json/decode.go:370 +0x37b
    encoding/json.(*decodeState).object(0xc820106000, 0x7a7320, 0xc82008c3f0, 0x199)
        /usr/local/go/src/encoding/json/decode.go:684 +0x116a
    encoding/json.(*decodeState).value(0xc820106000, 0x7a9260, 0xc820010648, 0x196)
        /usr/local/go/src/encoding/json/decode.go:367 +0x3a1
    encoding/json.(*decodeState).object(0xc820106000, 0x795d40, 0xc820010640, 0x199)
        /usr/local/go/src/encoding/json/decode.go:684 +0x116a
    encoding/json.(*decodeState).value(0xc820106000, 0x7a19e0, 0xc8200c5da0, 0x196)
        /usr/local/go/src/encoding/json/decode.go:367 +0x3a1
    encoding/json.(*decodeState).array(0xc820106000, 0x6c3220, 0xc8200c5d60, 0x197)
        /usr/local/go/src/encoding/json/decode.go:518 +0xa6b
    encoding/json.(*decodeState).value(0xc820106000, 0x6c3220, 0xc8200c5d60, 0x197)
        /usr/local/go/src/encoding/json/decode.go:364 +0x3c1
    encoding/json.(*decodeState).object(0xc820106000, 0x741a80, 0xc8200c5d60, 0x199)
        /usr/local/go/src/encoding/json/decode.go:684 +0x116a
    encoding/json.(*decodeState).value(0xc820106000, 0x6a6400, 0xc820056b78, 0x196)
        /usr/local/go/src/encoding/json/decode.go:367 +0x3a1
    encoding/json.(*decodeState).object(0xc820106000, 0x79e600, 0xc820056b60, 0x199)
        /usr/local/go/src/encoding/json/decode.go:684 +0x116a
    encoding/json.(*decodeState).value(0xc820106000, 0x6a61c0, 0xc820056b60, 0x16)
        /usr/local/go/src/encoding/json/decode.go:367 +0x3a1
    encoding/json.(*decodeState).unmarshal(0xc820106000, 0x6a61c0, 0xc820056b60, 0x0, 0x0)
        /usr/local/go/src/encoding/json/decode.go:168 +0x196
    encoding/json.Unmarshal(0xc820104000, 0x23b, 0x600, 0x6a61c0, 0xc820056b60, 0x0, 0x0)
        /usr/local/go/src/encoding/json/decode.go:96 +0x12b
    golang.org/x/net/websocket.jsonUnmarshal(0xc820104000, 0x23b, 0x600, 0x201, 0x6a61c0, 0xc820056b60, 0x0, 0x0)
        /home/dolanor/.local/gopath/src/golang.org/x/net/websocket/websocket.go:390 +0x57
    golang.org/x/net/websocket.Codec.Receive(0x861560, 0x861568, 0xc82008c240, 0x6a61c0, 0xc820056b60, 0x0, 0x0)
        /home/dolanor/.local/gopath/src/golang.org/x/net/websocket/websocket.go:331 +0x34d

@mikioh mikioh changed the title Unmarshalling *websocket.Conn over a websocket with JSON crashes encoding/json: Unmarshalling *websocket.Conn over a websocket with JSON crashes Apr 3, 2016
@mikioh
Copy link
Contributor

mikioh commented Apr 3, 2016

I have no strong opinion on how unexposed, non-assignable fields should be treated in encoding/json package.

@OneOfOne
Copy link
Contributor

OneOfOne commented Apr 3, 2016

the json package maybe should just check if a field is exported or not for the internal type cache?

@bradfitz
Copy link
Contributor

I am unable to reproduce this.

Do you have a repro?

I tried:

package main

import (
        "encoding/json"
        "fmt"
        "log"

        "golang.org/x/net/websocket"
)

func main() {
        type T struct {
                Foo  string
                conn *websocket.Conn
        }
        t := &T{"bar", new(websocket.Conn)}
        enc, err := json.Marshal(t)
        if err != nil {
                log.Fatalf("Marshal: %v", err)
        }
        var t2 T
        if err := json.Unmarshal(enc, &t2); err != nil {
                log.Fatalf("Unmarshal: %v", err)
        }
        fmt.Printf("%#v\n", t2)
}

But it works at tip, Go 1.6, and Go 1.5 just fine with:

main.T{Foo:"bar", conn:(*websocket.Conn)(nil)}

Let me know and I can reopen this.

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

5 participants