@@ -1789,12 +1789,9 @@ test {
1789
1789
_ = UnpackResult ;
1790
1790
}
1791
1791
1792
- // Detects executable header: ELF magic header or shebang line.
1792
+ // Detects executable header: ELF or Macho-O magic header or shebang line.
1793
1793
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 ,
1798
1795
bytes_read : usize = 0 ,
1799
1796
1800
1797
pub fn update (self : * FileHeader , buf : []const u8 ) void {
@@ -1804,22 +1801,46 @@ const FileHeader = struct {
1804
1801
self .bytes_read += n ;
1805
1802
}
1806
1803
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
+
1807
1823
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 ();
1810
1825
}
1811
1826
};
1812
1827
1813
1828
test FileHeader {
1814
1829
var h : FileHeader = .{};
1815
1830
try std .testing .expect (! h .isExecutable ());
1816
1831
1817
- h .update (FileHeader .elf_magic [0.. 2]);
1832
+ const elf_magic = std .elf .MAGIC ;
1833
+ h .update (elf_magic [0.. 2]);
1818
1834
try std .testing .expect (! h .isExecutable ());
1819
- h .update (FileHeader .elf_magic [2.. 4]);
1835
+ h .update (elf_magic [2.. 4]);
1836
+ try std .testing .expect (h .isExecutable ());
1837
+
1838
+ h .update (elf_magic [2.. 4]);
1820
1839
try std .testing .expect (h .isExecutable ());
1821
1840
1822
- h .update (FileHeader .elf_magic [2.. 4]);
1841
+ const macho64_magic_bytes = [_ ]u8 { 0xCF , 0xFA , 0xED , 0xFE };
1842
+ h .bytes_read = 0 ;
1843
+ h .update (& macho64_magic_bytes );
1823
1844
try std .testing .expect (h .isExecutable ());
1824
1845
}
1825
1846
0 commit comments