volume-manager: cover the GPT non-128 entry-size offset path (S1 review)
The S1 adversarial boundary review found the off = (i*entry_size) % 512 arithmetic tested only for 128-byte entries. Add a test with 256-byte entries and the sole valid entry at index 1 (offset 256), exercising the non-zero-offset path. No code change — the parser was already correct (off is always a multiple of entry_size >= 128, so off + 128 <= 512); this closes the coverage gap.
This commit is contained in:
@@ -351,9 +351,9 @@ fn gptEntry(type_nonzero: bool, unique_guid: u128, start: u64, end: u64) [128]u8
|
||||
return e;
|
||||
}
|
||||
|
||||
/// Lay out a 4-sector disk: protective MBR (LBA 0), GPT header with a correct
|
||||
/// CRC (LBA 1), and the entry array (LBA 2).
|
||||
fn buildGptDisk(disk: []u8, entries: []const [128]u8) void {
|
||||
/// Lay out a disk with `entry_size`-spaced GPT entries: protective MBR (LBA 0),
|
||||
/// GPT header with a correct CRC (LBA 1), the entry array (LBA 2+).
|
||||
fn buildGptDiskSized(disk: []u8, entries: []const [128]u8, entry_size: u32) void {
|
||||
@memset(disk, 0);
|
||||
disk[510] = 0x55;
|
||||
disk[511] = 0xAA;
|
||||
@@ -365,16 +365,22 @@ fn buildGptDisk(disk: []u8, entries: []const [128]u8) void {
|
||||
std.mem.writeInt(u32, h[12..16], 92, .little); // header_size
|
||||
std.mem.writeInt(u64, h[72..80], 2, .little); // partition_entry_lba
|
||||
std.mem.writeInt(u32, h[80..84], @intCast(entries.len), .little);
|
||||
std.mem.writeInt(u32, h[84..88], 128, .little); // size_of_partition_entry
|
||||
std.mem.writeInt(u32, h[84..88], entry_size, .little); // size_of_partition_entry
|
||||
@memset(h[16..20], 0);
|
||||
std.mem.writeInt(u32, h[16..20], crc32(h[0..92]), .little);
|
||||
const ea = disk[2 * sector_bytes ..][0..sector_bytes];
|
||||
const step: usize = @intCast(entry_size);
|
||||
var i: usize = 0;
|
||||
while (i < entries.len and i < 4) : (i += 1) {
|
||||
@memcpy(ea[i * 128 ..][0..128], &entries[i]);
|
||||
while (i < entries.len) : (i += 1) {
|
||||
const abs = 2 * sector_bytes + i * step;
|
||||
@memcpy(disk[abs..][0..128], &entries[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/// The common 128-byte-entry case.
|
||||
fn buildGptDisk(disk: []u8, entries: []const [128]u8) void {
|
||||
buildGptDiskSized(disk, entries, 128);
|
||||
}
|
||||
|
||||
test "a GPT disk yields the partition GUID as the identity id" {
|
||||
var disk = [_]u8{0} ** (4 * sector_bytes);
|
||||
const guid: u128 = 0x112233445566778899AABBCCDDEEFF00;
|
||||
@@ -468,3 +474,20 @@ test "an MBR FAT partition prefers the volume serial; a non-FAT partition keeps
|
||||
try std.testing.expectEqual(Rung.mbr_index, v2.identity.rung);
|
||||
try std.testing.expectEqual((@as(u128, 0xDEADBEEF) << 8) | 0, v2.identity.key);
|
||||
}
|
||||
|
||||
test "GPT with 256-byte entries reads the non-128 offset arithmetic correctly" {
|
||||
// With entry_size 256, entry 1 lands at offset 256 of the same sector (LBA 2).
|
||||
// Put the only valid entry at index 1 so the off = (i*entry_size) % 512 path
|
||||
// (256, not 0) is exercised — the sharp edge the 128-byte tests never hit.
|
||||
var disk = [_]u8{0} ** (5 * sector_bytes);
|
||||
const entries = [_][128]u8{
|
||||
gptEntry(false, 0, 0, 0), // index 0: unused (type GUID zero)
|
||||
gptEntry(true, 0xF00D, 4096, 8191), // index 1: at offset 256
|
||||
};
|
||||
buildGptDiskSized(&disk, &entries, 256);
|
||||
const rd = RamDisk{ .sectors = &disk };
|
||||
const v = firstVolume(rd.reader(), 200000).?;
|
||||
try std.testing.expectEqual(@as(u64, 4096), v.base_lba);
|
||||
try std.testing.expectEqual(Rung.gpt_guid, v.identity.rung);
|
||||
try std.testing.expectEqual(@as(u128, 0xF00D), v.identity.key);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user