authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-09-03 19:47:08-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-09-04 17:42:22-07:00
log91e1010a5afe3a28512aeb4ee1fd20c8afb81bc3
treecd421072f5807997689bd7d9b6b14f1d34e73a83
parent9152a4e63a36dfb40ab88e01b5098c8fbf960f48

std.Build.Cache: fix calculation of File size when reading manifest


1 files changed, 14 insertions(+), 5 deletions(-)

lib/std/Build/Cache.zig+14-5
......@@ -409,6 +409,7 @@ pub const Manifest = struct {
409409
410410 pub fn getFallible(offset: Offset, contents: []u8) error{InvalidFormat}!*File {
411411 if (@backingInt(offset) + @sizeOf(File) >= contents.len) return error.InvalidFormat;
412 if (!mem.isAligned(@backingInt(offset), @alignOf(File))) return error.InvalidFormat;
412413 return get(offset, contents);
413414 }
414415 };
......@@ -458,6 +459,14 @@ pub const Manifest = struct {
458459 return true;
459460 }
460461 }
462
463 /// `path_len` does not include the null byte.
464 fn sizeOf(path_len: usize) usize {
465 const end = @offsetOf(File, "path_start") + path_len;
466 const needed_alignment = @alignOf(File) - (end % @alignOf(File));
467 assert(needed_alignment >= 1); // Always need at least a null byte.
468 return end + needed_alignment;
469 }
461470 };
462471
463472 pub const Diagnostic = union(enum) {
......@@ -809,7 +818,7 @@ pub const Manifest = struct {
809818 };
810819 const contents = m.contents.items;
811820
812 var off: u32 = 0;
821 var off: usize = 0;
813822 var c: Check = .{};
814823
815824 // This group we always want to compute the hash digests, even on a
......@@ -821,7 +830,7 @@ pub const Manifest = struct {
821830 // otherwise it's invalid format.
822831 for (m.input_paths.items, m.files.keys()[0..m.input_paths.items.len]) |*input_path, input_file_off| {
823832 if (off + 1 >= contents.len) return error.InvalidFormat;
824 const file_off: File.Offset = @fromBackingInt(off);
833 const file_off: File.Offset = @fromBackingInt(@intCast(off));
825834 const file = try file_off.getFallible(contents);
826835 if (file.flags.prefix >= m.cache.prefixes_len) return error.InvalidFormat;
827836 const path = try filePathFallible(contents, file_off);
......@@ -830,7 +839,7 @@ pub const Manifest = struct {
830839
831840 input_group.async(io, checkInputFile, .{ m, &c, file_off, path, input_path });
832841
833 off = @intCast(@as(usize, off) + @sizeOf(File) + path.len + 1);
842 off += File.sizeOf(path.len);
834843 }
835844
836845 // Guess number of files based on manifest contents len to reduce allocations.
......@@ -849,7 +858,7 @@ pub const Manifest = struct {
849858 defer post_select.cancelDiscard();
850859
851860 while (off + 1 < contents.len) {
852 const file_off: File.Offset = @fromBackingInt(off);
861 const file_off: File.Offset = @fromBackingInt(@intCast(off));
853862 const file = try file_off.getFallible(contents);
854863 if (file.flags.prefix >= m.cache.prefixes_len) return error.InvalidFormat;
855864 const path = try filePathFallible(contents, file_off);
......@@ -860,7 +869,7 @@ pub const Manifest = struct {
860869 post_select.async(.checkFile, checkFile, .{ m, &c, file_off, path });
861870 post_select_remaining += 1;
862871
863 off = @intCast(@as(usize, off) + @sizeOf(File) + path.len + 1);
872 off += File.sizeOf(path.len);
864873 }
865874
866875 // Final terminating zero byte to distinguish empty manifest file from