Skip to content

Commit 3ed9110

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

File tree

1 file changed

+26
-7
lines changed

1 file changed

+26
-7
lines changed

src/Package/Fetch.zig

+26-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,26 @@ const FileHeader = struct {
18041801
self.bytes_read += n;
18051802
}
18061803

1804+
fn isScript(self: *FileHeader) bool {
1805+
const shebang = "#!";
1806+
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+
const magic_number = std.mem.readInt(u32, &self.header, builtin.cpu.arch.endian());
1816+
return magic_number == std.macho.MH_MAGIC or
1817+
magic_number == std.macho.MH_MAGIC_64 or
1818+
magic_number == std.macho.FAT_MAGIC or
1819+
magic_number == std.macho.FAT_MAGIC_64;
1820+
}
1821+
18071822
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);
1823+
return self.isScript() or self.isElf() or self.isMachO();
18101824
}
18111825
};
18121826

@@ -1821,6 +1835,11 @@ test FileHeader {
18211835

18221836
h.update(FileHeader.elf_magic[2..4]);
18231837
try std.testing.expect(h.isExecutable());
1838+
1839+
const macho64_magic_bytes = [_]u8{ 0xCF, 0xFA, 0xED, 0xFE };
1840+
h.bytes_read = 0;
1841+
h.update(&macho64_magic_bytes);
1842+
try std.testing.expect(h.isExecutable());
18241843
}
18251844

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

0 commit comments

Comments
 (0)