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

fix parsing issues and nits #97

Merged
merged 4 commits into from
Dec 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (p V0Builder) Sum(data []byte) (Cid, error) {
if err != nil {
return Undef, err
}
return NewCidV0(hash), nil
return Cid{string(hash)}, nil
}

func (p V0Builder) GetCodec() uint64 {
Expand Down
36 changes: 25 additions & 11 deletions cid.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,25 +137,39 @@ var CodecToStr = map[uint64]string{
DashTx: "dash-tx",
}

// tryNewCidV0 tries to convert a multihash into a CIDv0 CID and returns an
// error on failure.
func tryNewCidV0(mhash mh.Multihash) (Cid, error) {
// Need to make sure hash is valid for CidV0 otherwise we will
// incorrectly detect it as CidV1 in the Version() method
dec, err := mh.Decode(mhash)
if err != nil {
return Undef, err
}
if dec.Code != mh.SHA2_256 || dec.Length != 32 {
return Undef, fmt.Errorf("invalid hash for cidv0 %d-%d", dec.Code, dec.Length)
}
return Cid{string(mhash)}, nil
}

// NewCidV0 returns a Cid-wrapped multihash.
// They exist to allow IPFS to work with Cids while keeping
// compatibility with the plain-multihash format used used in IPFS.
// NewCidV1 should be used preferentially.
//
// Panics if the multihash isn't sha2-256.
func NewCidV0(mhash mh.Multihash) Cid {
// Need to make sure hash is valid for CidV0 otherwise we will
// incorrectly detect it as CidV1 in the Version() method
dec, err := mh.Decode(mhash)
c, err := tryNewCidV0(mhash)
if err != nil {
panic(err)
}
if dec.Code != mh.SHA2_256 || dec.Length != 32 {
panic("invalid hash for cidv0")
}
return Cid{string(mhash)}
return c
}

// NewCidV1 returns a new Cid using the given multicodec-packed
// content type.
//
// Panics if the multihash is invalid.
func NewCidV1(codecType uint64, mhash mh.Multihash) Cid {
hashlen := len(mhash)
// two 8 bytes (max) numbers plus hash
Expand Down Expand Up @@ -203,7 +217,7 @@ func Parse(v interface{}) (Cid, error) {
case []byte:
return Cast(v2)
case mh.Multihash:
return NewCidV0(v2), nil
return tryNewCidV0(v2)
case Cid:
return v2, nil
default:
Expand Down Expand Up @@ -234,7 +248,7 @@ func Decode(v string) (Cid, error) {
return Undef, err
}

return NewCidV0(hash), nil
return tryNewCidV0(hash)
}

_, data, err := mbase.Decode(v)
Expand Down Expand Up @@ -589,7 +603,7 @@ func PrefixFromBytes(buf []byte) (Prefix, error) {
}

func CidFromBytes(data []byte) (int, Cid, error) {
if len(data) > 2 && data[0] == 18 && data[1] == 32 {
if len(data) > 2 && data[0] == mh.SHA2_256 && data[1] == 32 {
if len(data) < 34 {
return 0, Undef, fmt.Errorf("not enough bytes for cid v0")
}
Expand All @@ -599,7 +613,7 @@ func CidFromBytes(data []byte) (int, Cid, error) {
return 0, Undef, err
}

return 34, NewCidV0(h), nil
return 34, Cid{string(h)}, nil
}

vers, n := binary.Uvarint(data)
Expand Down
11 changes: 11 additions & 0 deletions cid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -584,3 +584,14 @@ func TestReadCidsFromBuffer(t *testing.T) {
t.Fatal("had trailing bytes")
}
}

func TestBadParse(t *testing.T) {
hash, err := mh.Sum([]byte("foobar"), mh.SHA3_256, -1)
if err != nil {
t.Fatal(err)
}
_, err = Parse(hash)
if err == nil {
t.Fatal("expected to fail to parse an invalid CIDv1 CID")
}
}