Skip to content

Commit 35b7d0c

Browse files
committed
Package fetch: add executable detection for Mach-O file headers
1 parent 8019694 commit 35b7d0c

File tree

1 file changed

+27
-7
lines changed

1 file changed

+27
-7
lines changed

src/Package/Fetch.zig

+27-7
Original file line numberDiff line numberDiff line change
@@ -1789,12 +1789,9 @@ test {
17891789
_ = UnpackResult;
17901790
}
17911791

1792-
// Detects executable header: ELF magic header or shebang line.
1792+
// Detects executable header: ELF or Macho-O magic header or shebang line.
17931793
const FileHeader = struct {
1794-
const elf_magic = std.elf.MAGIC;
1795-
const shebang = "#!";
1796-
1797-
header: [@max(elf_magic.len, shebang.len)]u8 = undefined,
1794+
header: [4]u8 = undefined,
17981795
bytes_read: usize = 0,
17991796

18001797
pub fn update(self: *FileHeader, buf: []const u8) void {
@@ -1804,9 +1801,27 @@ const FileHeader = struct {
18041801
self.bytes_read += n;
18051802
}
18061803

1804+
fn isScript(self: *FileHeader) bool {
1805+
const shebang = "#!";
1806+
return std.mem.eql(u8, self.header[0..@min(self.bytes_read, shebang.len)], shebang);
1807+
}
1808+
1809+
fn isElf(self: *FileHeader) bool {
1810+
const elf_magic = std.elf.MAGIC;
1811+
return std.mem.eql(u8, self.header[0..@min(self.bytes_read, elf_magic.len)], elf_magic);
1812+
}
1813+
1814+
fn isMachO(self: *FileHeader) bool {
1815+
if (self.bytes_read < 4) return false;
1816+
const magic_number = std.mem.readInt(u32, &self.header, builtin.cpu.arch.endian());
1817+
return magic_number == std.macho.MH_MAGIC or
1818+
magic_number == std.macho.MH_MAGIC_64 or
1819+
magic_number == std.macho.FAT_MAGIC or
1820+
magic_number == std.macho.FAT_MAGIC_64;
1821+
}
1822+
18071823
pub fn isExecutable(self: *FileHeader) bool {
1808-
return std.mem.eql(u8, self.header[0..@min(self.bytes_read, shebang.len)], shebang) or
1809-
std.mem.eql(u8, self.header[0..@min(self.bytes_read, elf_magic.len)], elf_magic);
1824+
return self.isScript() or self.isElf() or self.isMachO();
18101825
}
18111826
};
18121827

@@ -1821,6 +1836,11 @@ test FileHeader {
18211836

18221837
h.update(FileHeader.elf_magic[2..4]);
18231838
try std.testing.expect(h.isExecutable());
1839+
1840+
const macho64_magic_bytes = [_]u8{ 0xCF, 0xFA, 0xED, 0xFE };
1841+
h.bytes_read = 0;
1842+
h.update(&macho64_magic_bytes);
1843+
try std.testing.expect(h.isExecutable());
18241844
}
18251845

18261846
// Result of the `unpackResource` operation. Enables collecting errors from

0 commit comments

Comments
 (0)