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 {...@@ -409,6 +409,7 @@ pub const Manifest = struct {
409409
410 pub fn getFallible(offset: Offset, contents: []u8) error{InvalidFormat}!*File {410 pub fn getFallible(offset: Offset, contents: []u8) error{InvalidFormat}!*File {
411 if (@backingInt(offset) + @sizeOf(File) >= contents.len) return error.InvalidFormat;411 if (@backingInt(offset) + @sizeOf(File) >= contents.len) return error.InvalidFormat;
412 if (!mem.isAligned(@backingInt(offset), @alignOf(File))) return error.InvalidFormat;
412 return get(offset, contents);413 return get(offset, contents);
413 }414 }
414 };415 };
...@@ -458,6 +459,14 @@ pub const Manifest = struct {...@@ -458,6 +459,14 @@ pub const Manifest = struct {
458 return true;459 return true;
459 }460 }
460 }461 }
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 }
461 };470 };
462471
463 pub const Diagnostic = union(enum) {472 pub const Diagnostic = union(enum) {
...@@ -809,7 +818,7 @@ pub const Manifest = struct {...@@ -809,7 +818,7 @@ pub const Manifest = struct {
809 };818 };
810 const contents = m.contents.items;819 const contents = m.contents.items;
811820
812 var off: u32 = 0;821 var off: usize = 0;
813 var c: Check = .{};822 var c: Check = .{};
814823
815 // This group we always want to compute the hash digests, even on a824 // This group we always want to compute the hash digests, even on a
...@@ -821,7 +830,7 @@ pub const Manifest = struct {...@@ -821,7 +830,7 @@ pub const Manifest = struct {
821 // otherwise it's invalid format.830 // otherwise it's invalid format.
822 for (m.input_paths.items, m.files.keys()[0..m.input_paths.items.len]) |*input_path, input_file_off| {831 for (m.input_paths.items, m.files.keys()[0..m.input_paths.items.len]) |*input_path, input_file_off| {
823 if (off + 1 >= contents.len) return error.InvalidFormat;832 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));
825 const file = try file_off.getFallible(contents);834 const file = try file_off.getFallible(contents);
826 if (file.flags.prefix >= m.cache.prefixes_len) return error.InvalidFormat;835 if (file.flags.prefix >= m.cache.prefixes_len) return error.InvalidFormat;
827 const path = try filePathFallible(contents, file_off);836 const path = try filePathFallible(contents, file_off);
...@@ -830,7 +839,7 @@ pub const Manifest = struct {...@@ -830,7 +839,7 @@ pub const Manifest = struct {
830839
831 input_group.async(io, checkInputFile, .{ m, &c, file_off, path, input_path });840 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);
834 }843 }
835844
836 // Guess number of files based on manifest contents len to reduce allocations.845 // Guess number of files based on manifest contents len to reduce allocations.
...@@ -849,7 +858,7 @@ pub const Manifest = struct {...@@ -849,7 +858,7 @@ pub const Manifest = struct {
849 defer post_select.cancelDiscard();858 defer post_select.cancelDiscard();
850859
851 while (off + 1 < contents.len) {860 while (off + 1 < contents.len) {
852 const file_off: File.Offset = @fromBackingInt(off);861 const file_off: File.Offset = @fromBackingInt(@intCast(off));
853 const file = try file_off.getFallible(contents);862 const file = try file_off.getFallible(contents);
854 if (file.flags.prefix >= m.cache.prefixes_len) return error.InvalidFormat;863 if (file.flags.prefix >= m.cache.prefixes_len) return error.InvalidFormat;
855 const path = try filePathFallible(contents, file_off);864 const path = try filePathFallible(contents, file_off);
...@@ -860,7 +869,7 @@ pub const Manifest = struct {...@@ -860,7 +869,7 @@ pub const Manifest = struct {
860 post_select.async(.checkFile, checkFile, .{ m, &c, file_off, path });869 post_select.async(.checkFile, checkFile, .{ m, &c, file_off, path });
861 post_select_remaining += 1;870 post_select_remaining += 1;
862871
863 off = @intCast(@as(usize, off) + @sizeOf(File) + path.len + 1);872 off += File.sizeOf(path.len);
864 }873 }
865874
866 // Final terminating zero byte to distinguish empty manifest file from875 // Final terminating zero byte to distinguish empty manifest file from