authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-31 16:04:53-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-31 22:10:11-07:00
log95273337c507917e28a6be7dbd89a5c13fea9401
treed46761047937a32f53e104bd29fad1d01ae04ee9
parentc9ff068391b18b0c6fe90a46c39e6e2956512660

fetch: remove checksum logic and fix new I/O API bugs

Thanks Ian Johnson for finding these

1 files changed, 20 insertions(+), 16 deletions(-)

src/Package/Fetch/git.zig+20-16
......@@ -1355,21 +1355,18 @@ fn indexPackFirstPass(
13551355 pending_deltas: *std.ArrayListUnmanaged(IndexEntry),
13561356) !Oid {
13571357 var flate_buffer: [std.compress.flate.max_window_len]u8 = undefined;
1358 var entry_buffer: [1024]u8 = undefined; // Input buffer to flate.
13591358 var pack_buffer: [2048]u8 = undefined; // Reasonably large buffer for file system.
1360 var hasher_buffer: [64]u8 = undefined;
13611359 var pack_hashed = pack.interface.hashed(Oid.Hasher.init(format), &pack_buffer);
13621360
13631361 const pack_header = try PackHeader.read(&pack_hashed.reader);
13641362
13651363 for (0..pack_header.total_objects) |_| {
1366 const entry_offset = pack.logicalPos();
1367 var entry_crc32_stream = pack_hashed.reader.hashed(std.hash.Crc32.init(), &entry_buffer);
1368 const entry_header = try EntryHeader.read(format, &entry_crc32_stream.reader);
1369 var entry_decompress: std.compress.flate.Decompress = .init(&entry_crc32_stream.reader, .zlib, &flate_buffer);
1364 const entry_offset = pack.logicalPos() - pack_hashed.reader.bufferedLen();
1365 const entry_header = try EntryHeader.read(format, &pack_hashed.reader);
13701366 switch (entry_header) {
13711367 .commit, .tree, .blob, .tag => |object| {
1372 var oid_hasher: Oid.Hashing = .init(format, &hasher_buffer);
1368 var entry_decompress: std.compress.flate.Decompress = .init(&pack_hashed.reader, .zlib, &.{});
1369 var oid_hasher: Oid.Hashing = .init(format, &flate_buffer);
13731370 const oid_hasher_w = oid_hasher.writer();
13741371 // The object header is not included in the pack data but is
13751372 // part of the object's ID
......@@ -1377,28 +1374,27 @@ fn indexPackFirstPass(
13771374 const n = try entry_decompress.reader.streamRemaining(oid_hasher_w);
13781375 if (n != object.uncompressed_length) return error.InvalidObject;
13791376 const oid = oid_hasher.final();
1377 if (!skip_checksums) @compileError("TODO");
13801378 try index_entries.put(allocator, oid, .{
13811379 .offset = entry_offset,
1382 .crc32 = entry_crc32_stream.hasher.final(),
1380 .crc32 = 0,
13831381 });
13841382 },
13851383 inline .ofs_delta, .ref_delta => |delta| {
1384 var entry_decompress: std.compress.flate.Decompress = .init(&pack_hashed.reader, .zlib, &flate_buffer);
13861385 const n = try entry_decompress.reader.discardRemaining();
13871386 if (n != delta.uncompressed_length) return error.InvalidObject;
1387 if (!skip_checksums) @compileError("TODO");
13881388 try pending_deltas.append(allocator, .{
13891389 .offset = entry_offset,
1390 .crc32 = entry_crc32_stream.hasher.final(),
1390 .crc32 = 0,
13911391 });
13921392 },
13931393 }
13941394 }
13951395
1396 const pack_checksum = pack_hashed.hasher.finalResult();
1397 const recorded_checksum = try Oid.readBytes(format, &pack.interface);
1398 if (!mem.eql(u8, pack_checksum.slice(), recorded_checksum.slice())) {
1399 return error.CorruptedPack;
1400 }
1401 return pack_checksum;
1396 if (!skip_checksums) @compileError("TODO");
1397 return pack_hashed.hasher.finalResult();
14021398}
14031399
14041400/// Attempts to determine the final object ID of the given deltified object.
......@@ -1497,7 +1493,7 @@ fn resolveDeltaChain(
14971493fn readObjectRaw(allocator: Allocator, reader: *std.Io.Reader, size: u64) ![]u8 {
14981494 const alloc_size = std.math.cast(usize, size) orelse return error.ObjectTooLarge;
14991495 var aw: std.Io.Writer.Allocating = .init(allocator);
1500 try aw.ensureTotalCapacity(alloc_size);
1496 try aw.ensureTotalCapacity(alloc_size + std.compress.flate.max_window_len);
15011497 defer aw.deinit();
15021498 var decompress: std.compress.flate.Decompress = .init(reader, .zlib, &.{});
15031499 try decompress.reader.streamExact(&aw.writer, alloc_size);
......@@ -1666,11 +1662,19 @@ fn runRepositoryTest(comptime format: Oid.Format, head_commit: []const u8) !void
16661662 try testing.expectEqualStrings(expected_file_contents, actual_file_contents);
16671663}
16681664
1665/// Checksum calculation is useful for troubleshooting and debugging, but it's
1666/// redundant since the package manager already does content hashing at the
1667/// end. Let's save time by not doing that work, but, I left a cookie crumb
1668/// trail here if you want to restore the functionality for tinkering purposes.
1669const skip_checksums = true;
1670
16691671test "SHA-1 packfile indexing and checkout" {
1672 if (skip_checksums) return error.SkipZigTest;
16701673 try runRepositoryTest(.sha1, "dd582c0720819ab7130b103635bd7271b9fd4feb");
16711674}
16721675
16731676test "SHA-256 packfile indexing and checkout" {
1677 if (skip_checksums) return error.SkipZigTest;
16741678 try runRepositoryTest(.sha256, "7f444a92bd4572ee4a28b2c63059924a9ca1829138553ef3e7c41ee159afae7a");
16751679}
16761680