@@ -122,26 +122,45 @@ var CodecToStr = map[uint64]string{
122
122
ZcashTx : "zcash-tx" ,
123
123
}
124
124
125
+ // Cid represents a self-describing content adressed
126
+ // identifier. It is formed by a Version, a Codec (which indicates
127
+ // a multicodec-packed content type) and a Multihash.
128
+ type Cid struct {
129
+ version uint64
130
+ codec uint64
131
+ hash mh.Multihash
132
+ }
133
+
125
134
// NewCidV0 returns a Cid-wrapped multihash.
126
135
// They exist to allow IPFS to work with Cids while keeping
127
136
// compatibility with the plain-multihash format used used in IPFS.
128
137
// NewCidV1 should be used preferentially.
129
- func NewCidV0 (mhash mh.Multihash ) * Cid {
130
- return & Cid {
138
+ func NewCidV0 (mhash mh.Multihash ) (* Cid , error ) {
139
+ if mhash [0 ] != mh .SHA2_256 && mhash [1 ] != byte (mh .DefaultLengths [mh .SHA2_256 ]) {
140
+ return nil , errors .New ("NewCidV0 accepts only SHA256 hashes of standard length" )
141
+ }
142
+
143
+ c := & Cid {
131
144
version : 0 ,
132
145
codec : DagProtobuf ,
133
146
hash : mhash ,
134
147
}
148
+ return c , nil
135
149
}
136
150
137
151
// NewCidV1 returns a new Cid using the given multicodec-packed
138
152
// content type.
139
- func NewCidV1 (codecType uint64 , mhash mh.Multihash ) * Cid {
140
- return & Cid {
153
+ func NewCidV1 (codecType uint64 , mhash mh.Multihash ) ( * Cid , error ) {
154
+ c := & Cid {
141
155
version : 1 ,
142
156
codec : codecType ,
143
157
hash : mhash ,
144
158
}
159
+ err := ValidateCid (c )
160
+ if err != nil {
161
+ return nil , err
162
+ }
163
+ return c , nil
145
164
}
146
165
147
166
// NewPrefixV0 returns a CIDv0 prefix with the specified multihash type.
@@ -165,15 +184,6 @@ func NewPrefixV1(codecType uint64, mhType uint64) Prefix {
165
184
}
166
185
}
167
186
168
- // Cid represents a self-describing content adressed
169
- // identifier. It is formed by a Version, a Codec (which indicates
170
- // a multicodec-packed content type) and a Multihash.
171
- type Cid struct {
172
- version uint64
173
- codec uint64
174
- hash mh.Multihash
175
- }
176
-
177
187
// Parse is a short-hand function to perform Decode, Cast etc... on
178
188
// a generic interface{} type.
179
189
func Parse (v interface {}) (* Cid , error ) {
@@ -186,7 +196,7 @@ func Parse(v interface{}) (*Cid, error) {
186
196
case []byte :
187
197
return Cast (v2 )
188
198
case mh.Multihash :
189
- return NewCidV0 (v2 ), nil
199
+ return NewCidV0 (v2 )
190
200
case * Cid :
191
201
return v2 , nil
192
202
default :
@@ -217,7 +227,7 @@ func Decode(v string) (*Cid, error) {
217
227
return nil , err
218
228
}
219
229
220
- return NewCidV0 (hash ), nil
230
+ return NewCidV0 (hash )
221
231
}
222
232
223
233
_ , data , err := mbase .Decode (v )
@@ -256,12 +266,7 @@ func Cast(data []byte) (*Cid, error) {
256
266
if err != nil {
257
267
return nil , err
258
268
}
259
-
260
- return & Cid {
261
- codec : DagProtobuf ,
262
- version : 0 ,
263
- hash : h ,
264
- }, nil
269
+ return NewCidV0 (h )
265
270
}
266
271
267
272
vers , n := binary .Uvarint (data )
@@ -284,11 +289,16 @@ func Cast(data []byte) (*Cid, error) {
284
289
return nil , err
285
290
}
286
291
287
- return & Cid {
292
+ c := & Cid {
288
293
version : vers ,
289
294
codec : codec ,
290
295
hash : h ,
291
- }, nil
296
+ }
297
+ err = ValidateCid (c )
298
+ if err != nil {
299
+ return nil , err
300
+ }
301
+ return c , nil
292
302
}
293
303
294
304
// Type returns the multicodec-packed content type of a Cid.
@@ -355,7 +365,7 @@ func (c *Cid) bytesV0() []byte {
355
365
}
356
366
357
367
func (c * Cid ) bytesV1 () []byte {
358
- // two 8 bytes (max) numbers plus hash
368
+ // two 10 bytes (max) numbers plus hash
359
369
buf := make ([]byte , 2 * binary .MaxVarintLen64 + len (c .hash ))
360
370
n := binary .PutUvarint (buf , c .version )
361
371
n += binary .PutUvarint (buf [n :], c .codec )
@@ -401,7 +411,14 @@ func (c *Cid) UnmarshalJSON(b []byte) error {
401
411
c .version = out .version
402
412
c .hash = out .hash
403
413
c .codec = out .codec
404
- return nil
414
+ err = ValidateCid (c )
415
+ if err != nil {
416
+ // Cleanup the struct so it is impossible to ignore the error
417
+ c .version = 0
418
+ c .hash = nil
419
+ c .codec = 0
420
+ }
421
+ return err
405
422
}
406
423
407
424
// MarshalJSON procudes a JSON representation of a Cid, which looks as follows:
@@ -459,9 +476,9 @@ func (p Prefix) Sum(data []byte) (*Cid, error) {
459
476
460
477
switch p .Version {
461
478
case 0 :
462
- return NewCidV0 (hash ), nil
479
+ return NewCidV0 (hash )
463
480
case 1 :
464
- return NewCidV1 (p .Codec , hash ), nil
481
+ return NewCidV1 (p .Codec , hash )
465
482
default :
466
483
return nil , fmt .Errorf ("invalid cid version" )
467
484
}
0 commit comments