Skip to content

Commit ed7dab1

Browse files
authored
Merge pull request #97 from ipfs/fix/parse-panic
fix parsing issues and nits
2 parents 79e75df + 5df8995 commit ed7dab1

File tree

3 files changed

+37
-12
lines changed

3 files changed

+37
-12
lines changed

builder.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func (p V0Builder) Sum(data []byte) (Cid, error) {
3838
if err != nil {
3939
return Undef, err
4040
}
41-
return NewCidV0(hash), nil
41+
return Cid{string(hash)}, nil
4242
}
4343

4444
func (p V0Builder) GetCodec() uint64 {

cid.go

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -137,25 +137,39 @@ var CodecToStr = map[uint64]string{
137137
DashTx: "dash-tx",
138138
}
139139

140+
// tryNewCidV0 tries to convert a multihash into a CIDv0 CID and returns an
141+
// error on failure.
142+
func tryNewCidV0(mhash mh.Multihash) (Cid, error) {
143+
// Need to make sure hash is valid for CidV0 otherwise we will
144+
// incorrectly detect it as CidV1 in the Version() method
145+
dec, err := mh.Decode(mhash)
146+
if err != nil {
147+
return Undef, err
148+
}
149+
if dec.Code != mh.SHA2_256 || dec.Length != 32 {
150+
return Undef, fmt.Errorf("invalid hash for cidv0 %d-%d", dec.Code, dec.Length)
151+
}
152+
return Cid{string(mhash)}, nil
153+
}
154+
140155
// NewCidV0 returns a Cid-wrapped multihash.
141156
// They exist to allow IPFS to work with Cids while keeping
142157
// compatibility with the plain-multihash format used used in IPFS.
143158
// NewCidV1 should be used preferentially.
159+
//
160+
// Panics if the multihash isn't sha2-256.
144161
func NewCidV0(mhash mh.Multihash) Cid {
145-
// Need to make sure hash is valid for CidV0 otherwise we will
146-
// incorrectly detect it as CidV1 in the Version() method
147-
dec, err := mh.Decode(mhash)
162+
c, err := tryNewCidV0(mhash)
148163
if err != nil {
149164
panic(err)
150165
}
151-
if dec.Code != mh.SHA2_256 || dec.Length != 32 {
152-
panic("invalid hash for cidv0")
153-
}
154-
return Cid{string(mhash)}
166+
return c
155167
}
156168

157169
// NewCidV1 returns a new Cid using the given multicodec-packed
158170
// content type.
171+
//
172+
// Panics if the multihash is invalid.
159173
func NewCidV1(codecType uint64, mhash mh.Multihash) Cid {
160174
hashlen := len(mhash)
161175
// two 8 bytes (max) numbers plus hash
@@ -203,7 +217,7 @@ func Parse(v interface{}) (Cid, error) {
203217
case []byte:
204218
return Cast(v2)
205219
case mh.Multihash:
206-
return NewCidV0(v2), nil
220+
return tryNewCidV0(v2)
207221
case Cid:
208222
return v2, nil
209223
default:
@@ -234,7 +248,7 @@ func Decode(v string) (Cid, error) {
234248
return Undef, err
235249
}
236250

237-
return NewCidV0(hash), nil
251+
return tryNewCidV0(hash)
238252
}
239253

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

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

602-
return 34, NewCidV0(h), nil
616+
return 34, Cid{string(h)}, nil
603617
}
604618

605619
vers, n := binary.Uvarint(data)

cid_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,3 +584,14 @@ func TestReadCidsFromBuffer(t *testing.T) {
584584
t.Fatal("had trailing bytes")
585585
}
586586
}
587+
588+
func TestBadParse(t *testing.T) {
589+
hash, err := mh.Sum([]byte("foobar"), mh.SHA3_256, -1)
590+
if err != nil {
591+
t.Fatal(err)
592+
}
593+
_, err = Parse(hash)
594+
if err == nil {
595+
t.Fatal("expected to fail to parse an invalid CIDv1 CID")
596+
}
597+
}

0 commit comments

Comments
 (0)