Skip to content

Commit

Permalink
Merge pull request #97 from ipfs/fix/parse-panic
Browse files Browse the repository at this point in the history
fix parsing issues and nits
  • Loading branch information
Stebalien authored Dec 3, 2019
2 parents 79e75df + 5df8995 commit ed7dab1
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 12 deletions.
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")
}
}

0 comments on commit ed7dab1

Please sign in to comment.