Skip to content

Commit

Permalink
codec: make cbor and json codecs use ErrUnexpectedEOF
Browse files Browse the repository at this point in the history
In particular, if the input doesn't have a single token, we would return
io.EOF, which can be easily mistaken by an error that can be ignored.
In particular, go-ipfs-cmds ignored it as such.

Make them return a clearly bad "unexpected EOF" error,
which mirrors the behavior found in many other unmarshal APIs
such as encoding/json.Unmarshal.

Finally, add a table-driven test that we can extend in the future,
which tests all four codecs.

For ipfs/kubo#8378.
  • Loading branch information
mvdan committed Sep 8, 2021
1 parent c32e220 commit f51cf4a
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 0 deletions.
3 changes: 3 additions & 0 deletions codec/dagcbor/unmarshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ func Unmarshal(na datamodel.NodeAssembler, tokSrc shared.TokenSource, options De
func unmarshal1(na datamodel.NodeAssembler, tokSrc shared.TokenSource, gas *int, options DecodeOptions) error {
var tk tok.Token
done, err := tokSrc.Step(&tk)
if err == io.EOF {
return io.ErrUnexpectedEOF
}
if err != nil {
return err
}
Expand Down
3 changes: 3 additions & 0 deletions codec/dagjson/unmarshal.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ func Unmarshal(na datamodel.NodeAssembler, tokSrc shared.TokenSource, options De
var st unmarshalState
st.options = options
done, err := tokSrc.Step(&st.tk[0])
if err == io.EOF {
return io.ErrUnexpectedEOF
}
if err != nil {
return err
}
Expand Down
38 changes: 38 additions & 0 deletions codec/decode_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package codec_test

import (
"errors"
"io"
"strings"
"testing"

_ "github.com/ipld/go-ipld-prime/codec/cbor"
_ "github.com/ipld/go-ipld-prime/codec/dagcbor"
_ "github.com/ipld/go-ipld-prime/codec/dagjson"
_ "github.com/ipld/go-ipld-prime/codec/json"
mcregistry "github.com/ipld/go-ipld-prime/multicodec"
basicnode "github.com/ipld/go-ipld-prime/node/basic"
"github.com/multiformats/go-multicodec"
)

func TestDecodeZero(t *testing.T) {
for _, code := range []multicodec.Code{
multicodec.Cbor,
multicodec.DagCbor,
multicodec.Json,
multicodec.DagJson,
} {
t.Run(code.String(), func(t *testing.T) {
nb := basicnode.Prototype.Any.NewBuilder()
decode, err := mcregistry.LookupDecoder(uint64(code))
if err != nil {
t.Fatal(err)
}

err = decode(nb, strings.NewReader(""))
if !errors.Is(err, io.ErrUnexpectedEOF) {
t.Fatalf("unexpected error: %v", err)
}
})
}
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.16
require (
github.com/frankban/quicktest v1.11.3
github.com/ipfs/go-cid v0.0.4
github.com/multiformats/go-multicodec v0.3.0
github.com/multiformats/go-multihash v0.0.15
github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e
github.com/smartystreets/goconvey v1.6.4 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp
github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA=
github.com/multiformats/go-multibase v0.0.1 h1:PN9/v21eLywrFWdFNsFKaU04kLJzuYzmrJR+ubhT9qA=
github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs=
github.com/multiformats/go-multicodec v0.3.0 h1:tstDwfIjiHbnIjeM5Lp+pMrSeN+LCMsEwOrkPmWm03A=
github.com/multiformats/go-multicodec v0.3.0/go.mod h1:qGGaQmioCDh+TeFOnxrbU0DaIPw8yFgAZgFG0V7p1qQ=
github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew=
github.com/multiformats/go-multihash v0.0.15 h1:hWOPdrNqDjwHDx82vsYGSDZNyktOJJ2dzZJzFkOV1jM=
github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg=
Expand Down
2 changes: 2 additions & 0 deletions multicodec/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ func (r *Registry) ListEncoders() []uint64 {
return encoders
}

// TODO(mvdan): turn most of these uint64s into multicodec.Code

// RegisterDecoder updates a simple map of multicodec indicator number to codec.Decoder function.
// The decoder functions registered can be subsequently looked up using LookupDecoder.
func (r *Registry) RegisterDecoder(indicator uint64, decodeFunc codec.Decoder) {
Expand Down

0 comments on commit f51cf4a

Please sign in to comment.