@@ -299,16 +299,37 @@ fn fetchAndUnpack(
299
299
// Check if the expected_hash is already present in the global package
300
300
// cache, and thereby avoid both fetching and unpacking.
301
301
if (expected_hash ) | h | cached : {
302
- if (h .len != 2 * Hash .digest_length ) {
302
+ const hex_multihash_len = 2 * multihash_len ;
303
+ if (h .len >= 2 ) {
304
+ const their_multihash_func = std .fmt .parseInt (u8 , h [0.. 2], 16 ) catch | err | {
305
+ return reportError (
306
+ ini ,
307
+ comp_directory ,
308
+ h .ptr ,
309
+ "invalid multihash value: unable to parse hash function: {s}" ,
310
+ .{@errorName (err )},
311
+ );
312
+ };
313
+ if (@intToEnum (MultihashFunction , their_multihash_func ) != multihash_function ) {
314
+ return reportError (
315
+ ini ,
316
+ comp_directory ,
317
+ h .ptr ,
318
+ "unsupported hash function: only sha2-256 is supported" ,
319
+ .{},
320
+ );
321
+ }
322
+ }
323
+ if (h .len != hex_multihash_len ) {
303
324
return reportError (
304
325
ini ,
305
326
comp_directory ,
306
327
h .ptr ,
307
328
"wrong hash size. expected: {d}, found: {d}" ,
308
- .{ Hash . digest_length , h .len },
329
+ .{ hex_multihash_len , h .len },
309
330
);
310
331
}
311
- const hex_digest = h [0 .. 2 * Hash . digest_length ];
332
+ const hex_digest = h [0.. hex_multihash_len ];
312
333
const pkg_dir_sub_path = "p" ++ s ++ hex_digest ;
313
334
var pkg_dir = global_cache_directory .handle .openDir (pkg_dir_sub_path , .{}) catch | err | switch (err ) {
314
335
error .FileNotFound = > break :cached ,
@@ -397,8 +418,8 @@ fn fetchAndUnpack(
397
418
const pkg_dir_sub_path = "p" ++ s ++ hexDigest (actual_hash );
398
419
try renameTmpIntoCache (global_cache_directory .handle , tmp_dir_sub_path , pkg_dir_sub_path );
399
420
421
+ const actual_hex = hexDigest (actual_hash );
400
422
if (expected_hash ) | h | {
401
- const actual_hex = hexDigest (actual_hash );
402
423
if (! mem .eql (u8 , h , & actual_hex )) {
403
424
return reportError (
404
425
ini ,
@@ -414,7 +435,7 @@ fn fetchAndUnpack(
414
435
comp_directory ,
415
436
url .ptr ,
416
437
"url field is missing corresponding hash field: hash={s}" ,
417
- .{std . fmt . fmtSliceHexLower ( & actual_hash ) },
438
+ .{& actual_hex },
418
439
);
419
440
}
420
441
@@ -592,11 +613,30 @@ test hex64 {
592
613
try std .testing .expectEqualStrings ("[00efcdab78563412]" , s );
593
614
}
594
615
595
- fn hexDigest (digest : [Hash .digest_length ]u8 ) [Hash .digest_length * 2 ]u8 {
596
- var result : [Hash .digest_length * 2 ]u8 = undefined ;
616
+ const multihash_function : MultihashFunction = switch (Hash ) {
617
+ std .crypto .hash .sha2 .Sha256 = > .@"sha2-256" ,
618
+ else = > @compileError ("unreachable" ),
619
+ };
620
+ comptime {
621
+ // We avoid unnecessary uleb128 code in hexDigest by asserting here the
622
+ // values are small enough to be contained in the one-byte encoding.
623
+ assert (@enumToInt (multihash_function ) < 127 );
624
+ assert (Hash .digest_length < 127 );
625
+ }
626
+ const multihash_len = 1 + 1 + Hash .digest_length ;
627
+
628
+ fn hexDigest (digest : [Hash .digest_length ]u8 ) [multihash_len * 2 ]u8 {
629
+ var result : [multihash_len * 2 ]u8 = undefined ;
630
+
631
+ result [0 ] = hex_charset [@enumToInt (multihash_function ) >> 4 ];
632
+ result [1 ] = hex_charset [@enumToInt (multihash_function ) & 15 ];
633
+
634
+ result [2 ] = hex_charset [Hash .digest_length >> 4 ];
635
+ result [3 ] = hex_charset [Hash .digest_length & 15 ];
636
+
597
637
for (digest ) | byte , i | {
598
- result [i * 2 + 0 ] = hex_charset [byte >> 4 ];
599
- result [i * 2 + 1 ] = hex_charset [byte & 15 ];
638
+ result [4 + i * 2 ] = hex_charset [byte >> 4 ];
639
+ result [5 + i * 2 ] = hex_charset [byte & 15 ];
600
640
}
601
641
return result ;
602
642
}
@@ -629,3 +669,21 @@ fn renameTmpIntoCache(
629
669
break ;
630
670
}
631
671
}
672
+
673
+ const MultihashFunction = enum (u16 ) {
674
+ identity = 0x00 ,
675
+ sha1 = 0x11 ,
676
+ @"sha2-256" = 0x12 ,
677
+ @"sha2-512" = 0x13 ,
678
+ @"sha3-512" = 0x14 ,
679
+ @"sha3-384" = 0x15 ,
680
+ @"sha3-256" = 0x16 ,
681
+ @"sha3-224" = 0x17 ,
682
+ @"sha2-384" = 0x20 ,
683
+ @"sha2-256-trunc254-padded" = 0x1012 ,
684
+ @"sha2-224" = 0x1013 ,
685
+ @"sha2-512-224" = 0x1014 ,
686
+ @"sha2-512-256" = 0x1015 ,
687
+ @"blake2b-256" = 0xb220 ,
688
+ _ ,
689
+ };
0 commit comments