fetch: remove checksum logic and fix new I/O API bugs
Thanks Ian Johnson for finding these
This commit is contained in:
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user