Commit 95273337c5

Andrew Kelley <andrew@ziglang.org>
2025-08-01 01:04:53
fetch: remove checksum logic and fix new I/O API bugs
Thanks Ian Johnson for finding these
1 parent c9ff068
Changed files (1)
src
Package
Fetch
src/Package/Fetch/git.zig
@@ -1355,21 +1355,18 @@ fn indexPackFirstPass(
     pending_deltas: *std.ArrayListUnmanaged(IndexEntry),
 ) !Oid {
     var flate_buffer: [std.compress.flate.max_window_len]u8 = undefined;
-    var entry_buffer: [1024]u8 = undefined; // Input buffer to flate.
     var pack_buffer: [2048]u8 = undefined; // Reasonably large buffer for file system.
-    var hasher_buffer: [64]u8 = undefined;
     var pack_hashed = pack.interface.hashed(Oid.Hasher.init(format), &pack_buffer);
 
     const pack_header = try PackHeader.read(&pack_hashed.reader);
 
     for (0..pack_header.total_objects) |_| {
-        const entry_offset = pack.logicalPos();
-        var entry_crc32_stream = pack_hashed.reader.hashed(std.hash.Crc32.init(), &entry_buffer);
-        const entry_header = try EntryHeader.read(format, &entry_crc32_stream.reader);
-        var entry_decompress: std.compress.flate.Decompress = .init(&entry_crc32_stream.reader, .zlib, &flate_buffer);
+        const entry_offset = pack.logicalPos() - pack_hashed.reader.bufferedLen();
+        const entry_header = try EntryHeader.read(format, &pack_hashed.reader);
         switch (entry_header) {
             .commit, .tree, .blob, .tag => |object| {
-                var oid_hasher: Oid.Hashing = .init(format, &hasher_buffer);
+                var entry_decompress: std.compress.flate.Decompress = .init(&pack_hashed.reader, .zlib, &.{});
+                var oid_hasher: Oid.Hashing = .init(format, &flate_buffer);
                 const oid_hasher_w = oid_hasher.writer();
                 // The object header is not included in the pack data but is
                 // part of the object's ID
@@ -1377,28 +1374,27 @@ fn indexPackFirstPass(
                 const n = try entry_decompress.reader.streamRemaining(oid_hasher_w);
                 if (n != object.uncompressed_length) return error.InvalidObject;
                 const oid = oid_hasher.final();
+                if (!skip_checksums) @compileError("TODO");
                 try index_entries.put(allocator, oid, .{
                     .offset = entry_offset,
-                    .crc32 = entry_crc32_stream.hasher.final(),
+                    .crc32 = 0,
                 });
             },
             inline .ofs_delta, .ref_delta => |delta| {
+                var entry_decompress: std.compress.flate.Decompress = .init(&pack_hashed.reader, .zlib, &flate_buffer);
                 const n = try entry_decompress.reader.discardRemaining();
                 if (n != delta.uncompressed_length) return error.InvalidObject;
+                if (!skip_checksums) @compileError("TODO");
                 try pending_deltas.append(allocator, .{
                     .offset = entry_offset,
-                    .crc32 = entry_crc32_stream.hasher.final(),
+                    .crc32 = 0,
                 });
             },
         }
     }
 
-    const pack_checksum = pack_hashed.hasher.finalResult();
-    const recorded_checksum = try Oid.readBytes(format, &pack.interface);
-    if (!mem.eql(u8, pack_checksum.slice(), recorded_checksum.slice())) {
-        return error.CorruptedPack;
-    }
-    return pack_checksum;
+    if (!skip_checksums) @compileError("TODO");
+    return pack_hashed.hasher.finalResult();
 }
 
 /// Attempts to determine the final object ID of the given deltified object.
@@ -1497,7 +1493,7 @@ fn resolveDeltaChain(
 fn readObjectRaw(allocator: Allocator, reader: *std.Io.Reader, size: u64) ![]u8 {
     const alloc_size = std.math.cast(usize, size) orelse return error.ObjectTooLarge;
     var aw: std.Io.Writer.Allocating = .init(allocator);
-    try aw.ensureTotalCapacity(alloc_size);
+    try aw.ensureTotalCapacity(alloc_size + std.compress.flate.max_window_len);
     defer aw.deinit();
     var decompress: std.compress.flate.Decompress = .init(reader, .zlib, &.{});
     try decompress.reader.streamExact(&aw.writer, alloc_size);
@@ -1666,11 +1662,19 @@ fn runRepositoryTest(comptime format: Oid.Format, head_commit: []const u8) !void
     try testing.expectEqualStrings(expected_file_contents, actual_file_contents);
 }
 
+/// Checksum calculation is useful for troubleshooting and debugging, but it's
+/// redundant since the package manager already does content hashing at the
+/// end. Let's save time by not doing that work, but, I left a cookie crumb
+/// trail here if you want to restore the functionality for tinkering purposes.
+const skip_checksums = true;
+
 test "SHA-1 packfile indexing and checkout" {
+    if (skip_checksums) return error.SkipZigTest;
     try runRepositoryTest(.sha1, "dd582c0720819ab7130b103635bd7271b9fd4feb");
 }
 
 test "SHA-256 packfile indexing and checkout" {
+    if (skip_checksums) return error.SkipZigTest;
     try runRepositoryTest(.sha256, "7f444a92bd4572ee4a28b2c63059924a9ca1829138553ef3e7c41ee159afae7a");
 }