diff --git a/Library/Homebrew/Gemfile.lock b/Library/Homebrew/Gemfile.lock index 203e396584..9815067960 100644 --- a/Library/Homebrew/Gemfile.lock +++ b/Library/Homebrew/Gemfile.lock @@ -146,7 +146,7 @@ GEM rubocop (~> 1.19) rubocop-sorbet (0.6.5) rubocop (>= 0.90.0) - ruby-macho (2.5.1) + ruby-macho (3.0.0) ruby-progressbar (1.11.0) rubyntlm (0.6.3) simplecov (0.21.2) diff --git a/Library/Homebrew/sorbet/rbi/gems/ruby-macho@2.5.1.rbi b/Library/Homebrew/sorbet/rbi/gems/ruby-macho@3.0.0.rbi similarity index 93% rename from Library/Homebrew/sorbet/rbi/gems/ruby-macho@2.5.1.rbi rename to Library/Homebrew/sorbet/rbi/gems/ruby-macho@3.0.0.rbi index d2b577b81c..d271ed05e1 100644 --- a/Library/Homebrew/sorbet/rbi/gems/ruby-macho@2.5.1.rbi +++ b/Library/Homebrew/sorbet/rbi/gems/ruby-macho@3.0.0.rbi @@ -1,9 +1,9 @@ +# typed: true + # DO NOT EDIT MANUALLY # This is an autogenerated file for types exported from the `ruby-macho` gem. # Please instead update this file by running `bin/tapioca gem ruby-macho`. -# typed: true - module MachO class << self def codesign!(filename); end @@ -20,6 +20,8 @@ class MachO::CPUTypeError < ::MachO::MachOError end class MachO::CodeSigningError < ::MachO::MachOError; end +class MachO::CompressedMachOError < ::MachO::MachOError; end +class MachO::DecompressionError < ::MachO::MachOError; end class MachO::DylibIdMissingError < ::MachO::RecoverableModificationError def initialize; end @@ -104,6 +106,9 @@ class MachO::HeaderPadError < ::MachO::ModificationError end module MachO::Headers; end +MachO::Headers::COMPRESSED_MAGIC = T.let(T.unsafe(nil), Integer) +MachO::Headers::COMP_TYPE_FASTLIB = T.let(T.unsafe(nil), Integer) +MachO::Headers::COMP_TYPE_LZSS = T.let(T.unsafe(nil), Integer) MachO::Headers::CPU_ARCH_ABI32 = T.let(T.unsafe(nil), Integer) MachO::Headers::CPU_ARCH_ABI64 = T.let(T.unsafe(nil), Integer) MachO::Headers::CPU_SUBTYPES = T.let(T.unsafe(nil), Hash) @@ -220,6 +225,7 @@ MachO::Headers::MH_DYLIB = T.let(T.unsafe(nil), Integer) MachO::Headers::MH_DYLIB_STUB = T.let(T.unsafe(nil), Integer) MachO::Headers::MH_DYLINKER = T.let(T.unsafe(nil), Integer) MachO::Headers::MH_EXECUTE = T.let(T.unsafe(nil), Integer) +MachO::Headers::MH_FILESET = T.let(T.unsafe(nil), Integer) MachO::Headers::MH_FILETYPES = T.let(T.unsafe(nil), Hash) MachO::Headers::MH_FLAGS = T.let(T.unsafe(nil), Hash) MachO::Headers::MH_FVMLIB = T.let(T.unsafe(nil), Integer) @@ -242,6 +248,7 @@ class MachO::Headers::MachHeader < ::MachO::MachOStructure def dylib?; end def dylinker?; end def executable?; end + def fileset?; end def filetype; end def flag?(flag); end def flags; end @@ -269,6 +276,27 @@ MachO::Headers::MachHeader64::SIZEOF = T.let(T.unsafe(nil), Integer) MachO::Headers::MachHeader::FORMAT = T.let(T.unsafe(nil), String) MachO::Headers::MachHeader::SIZEOF = T.let(T.unsafe(nil), Integer) +class MachO::Headers::PrelinkedKernelHeader < ::MachO::MachOStructure + def initialize(signature, compress_type, adler32, uncompressed_size, compressed_size, prelink_version, reserved, platform_name, root_path); end + + def adler32; end + def compress_type; end + def compressed_size; end + def kaslr?; end + def lzss?; end + def lzvn?; end + def platform_name; end + def prelink_version; end + def reserved; end + def root_path; end + def signature; end + def to_h; end + def uncompressed_size; end +end + +MachO::Headers::PrelinkedKernelHeader::FORMAT = T.let(T.unsafe(nil), String) +MachO::Headers::PrelinkedKernelHeader::SIZEOF = T.let(T.unsafe(nil), Integer) + class MachO::JavaClassFileError < ::MachO::NotAMachOError def initialize; end end @@ -430,6 +458,19 @@ end MachO::LoadCommands::EntryPointCommand::FORMAT = T.let(T.unsafe(nil), String) MachO::LoadCommands::EntryPointCommand::SIZEOF = T.let(T.unsafe(nil), Integer) +class MachO::LoadCommands::FilesetEntryCommand < ::MachO::LoadCommands::LoadCommand + def initialize(view, cmd, cmdsize, vmaddr, fileoff, entry_id, reserved); end + + def entry_id; end + def fileoff; end + def reserved; end + def to_h; end + def vmaddr; end +end + +MachO::LoadCommands::FilesetEntryCommand::FORMAT = T.let(T.unsafe(nil), String) +MachO::LoadCommands::FilesetEntryCommand::SIZEOF = T.let(T.unsafe(nil), Integer) + class MachO::LoadCommands::FvmfileCommand < ::MachO::LoadCommands::LoadCommand def initialize(view, cmd, cmdsize, name, header_addr); end @@ -762,13 +803,13 @@ class MachO::MachOFile def change_dylib(old_name, new_name, _options = T.unsafe(nil)); end def change_dylib_id(new_id, _options = T.unsafe(nil)); end def change_install_name(old_name, new_name, _options = T.unsafe(nil)); end - def change_rpath(old_path, new_path, _options = T.unsafe(nil)); end + def change_rpath(old_path, new_path, options = T.unsafe(nil)); end def command(name); end def core?(*args, &block); end def cpusubtype; end def cputype; end def delete_command(lc, options = T.unsafe(nil)); end - def delete_rpath(path, _options = T.unsafe(nil)); end + def delete_rpath(path, options = T.unsafe(nil)); end def dsym?(*args, &block); end def dylib?(*args, &block); end def dylib_id; end @@ -812,10 +853,12 @@ class MachO::MachOFile def check_cpusubtype(cputype, cpusubtype); end def check_cputype(cputype); end def check_filetype(filetype); end + def decompress_macho_lzvn; end def low_fileoff; end def populate_and_check_magic; end def populate_load_commands; end def populate_mach_header; end + def populate_prelinked_kernel_header; end def update_ncmds(ncmds); end def update_sizeofcmds(size); end @@ -872,18 +915,22 @@ end module MachO::Sections; end MachO::Sections::MAX_SECT_ALIGN = T.let(T.unsafe(nil), Integer) -MachO::Sections::SECTION_ATTRIBUTES = T.let(T.unsafe(nil), Integer) -MachO::Sections::SECTION_ATTRIBUTES_SYS = T.let(T.unsafe(nil), Integer) -MachO::Sections::SECTION_ATTRIBUTES_USR = T.let(T.unsafe(nil), Integer) +MachO::Sections::SECTION_ATTRIBUTES = T.let(T.unsafe(nil), Hash) +MachO::Sections::SECTION_ATTRIBUTES_MASK = T.let(T.unsafe(nil), Integer) +MachO::Sections::SECTION_ATTRIBUTES_SYS_MASK = T.let(T.unsafe(nil), Integer) +MachO::Sections::SECTION_ATTRIBUTES_USR_MASK = T.let(T.unsafe(nil), Integer) MachO::Sections::SECTION_FLAGS = T.let(T.unsafe(nil), Hash) MachO::Sections::SECTION_NAMES = T.let(T.unsafe(nil), Hash) -MachO::Sections::SECTION_TYPE = T.let(T.unsafe(nil), Integer) +MachO::Sections::SECTION_TYPES = T.let(T.unsafe(nil), Hash) +MachO::Sections::SECTION_TYPE_MASK = T.let(T.unsafe(nil), Integer) class MachO::Sections::Section < ::MachO::MachOStructure def initialize(sectname, segname, addr, size, offset, align, reloff, nreloc, flags, reserved1, reserved2); end def addr; end def align; end + def attribute?(attr_sym); end + def attributes; end def empty?; end def flag?(flag); end def flags; end @@ -898,6 +945,8 @@ class MachO::Sections::Section < ::MachO::MachOStructure def segname; end def size; end def to_h; end + def type; end + def type?(type_sym); end end class MachO::Sections::Section64 < ::MachO::Sections::Section @@ -935,6 +984,7 @@ end module MachO::Utils class << self def big_magic?(num); end + def compressed_magic?(num); end def fat_magic32?(num); end def fat_magic64?(num); end def fat_magic?(num); end diff --git a/Library/Homebrew/vendor/bundle/bundler/setup.rb b/Library/Homebrew/vendor/bundle/bundler/setup.rb index 83455f15ec..2c3f376d71 100644 --- a/Library/Homebrew/vendor/bundle/bundler/setup.rb +++ b/Library/Homebrew/vendor/bundle/bundler/setup.rb @@ -91,7 +91,7 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-performance-1 $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rails-2.13.1/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rspec-2.7.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-sorbet-0.6.5/lib" -$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-macho-2.5.1/lib" +$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-macho-3.0.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/simplecov-html-0.12.3/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/simplecov_json_formatter-0.1.3/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/simplecov-0.21.2/lib" diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho.rb similarity index 99% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho.rb index db4dc2237b..8b9e24f81a 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho.rb @@ -16,7 +16,7 @@ require_relative "macho/tools" # The primary namespace for ruby-macho. module MachO # release version - VERSION = "2.5.1" + VERSION = "3.0.0" # Opens the given filename as a MachOFile or FatFile, depending on its magic. # @param filename [String] the file being opened diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/exceptions.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/exceptions.rb similarity index 91% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/exceptions.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/exceptions.rb index b3b53e340c..368c16e9c2 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/exceptions.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/exceptions.rb @@ -84,7 +84,7 @@ module MachO # @param cpusubtype [Integer] the CPU sub-type of the unknown pair def initialize(cputype, cpusubtype) super "Unrecognized CPU sub-type: 0x%08x" \ - " (for CPU type: 0x%08x" % { :cputype => cputype, :cpusubtype => cpusubtype } + " (for CPU type: 0x%08x" % { :cputype => cputype, :cpusubtype => cpusubtype } end end @@ -120,7 +120,7 @@ module MachO # @param actual_arity [Integer] the number of arguments received def initialize(cmd_sym, expected_arity, actual_arity) super "Expected #{expected_arity} arguments for #{cmd_sym} creation," \ - " got #{actual_arity}" + " got #{actual_arity}" end end @@ -137,7 +137,7 @@ module MachO # @param lc [MachO::LoadCommand] the load command containing the string def initialize(lc) super "Load command #{lc.type} at offset #{lc.view.offset} contains a" \ - " malformed string" + " malformed string" end end @@ -154,8 +154,8 @@ module MachO # @param filename [String] the filename def initialize(filename) super "Updated load commands do not fit in the header of " \ - "#{filename}. #{filename} needs to be relinked, possibly with " \ - "-headerpad or -headerpad_max_install_names" + "#{filename}. #{filename} needs to be relinked, possibly with " \ + "-headerpad or -headerpad_max_install_names" end end @@ -207,4 +207,14 @@ module MachO " Consider merging with `fat64: true`" end end + + # Raised when attempting to parse a compressed Mach-O without explicitly + # requesting decompression. + class CompressedMachOError < MachOError + end + + # Raised when attempting to decompress a compressed Mach-O without adequate + # dependencies, or on other decompression errors. + class DecompressionError < MachOError + end end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/fat_file.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/fat_file.rb similarity index 96% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/fat_file.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/fat_file.rb index 0eecdcf326..569250cc75 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/fat_file.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/fat_file.rb @@ -55,7 +55,7 @@ module MachO machos.each do |macho| macho_offset = Utils.round(offset, 2**macho.segment_alignment) - raise FatArchOffsetOverflowError, macho_offset if !fat64 && macho_offset > (2**32 - 1) + raise FatArchOffsetOverflowError, macho_offset if !fat64 && macho_offset > ((2**32) - 1) macho_pads[macho] = Utils.padding_for(offset, 2**macho.segment_alignment) @@ -96,7 +96,7 @@ module MachO @filename = filename @options = opts - @raw_data = File.open(@filename, "rb", &:read) + @raw_data = File.binread(@filename) populate_fields end @@ -238,6 +238,8 @@ module MachO # @param options [Hash] # @option options [Boolean] :strict (true) if true, fail if one slice fails. # if false, fail only if all slices fail. + # @option options [Boolean] :uniq (false) for each slice: if true, change + # each rpath simultaneously. # @return [void] # @see MachOFile#change_rpath def change_rpath(old_path, new_path, options = {}) @@ -268,6 +270,9 @@ module MachO # @param options [Hash] # @option options [Boolean] :strict (true) if true, fail if one slice fails. # if false, fail only if all slices fail. + # @option options [Boolean] :uniq (false) for each slice: if true, delete + # only the first runtime path that matches. if false, delete all duplicate + # paths that match. # @return void # @see MachOFile#delete_rpath def delete_rpath(path, options = {}) @@ -291,7 +296,7 @@ module MachO # @param filename [String] the file to write to # @return [void] def write(filename) - File.open(filename, "wb") { |f| f.write(@raw_data) } + File.binwrite(filename, @raw_data) end # Write all (fat) data to the file used to initialize the instance. @@ -301,7 +306,7 @@ module MachO def write! raise MachOError, "no initial file to write to" if filename.nil? - File.open(@filename, "wb") { |f| f.write(@raw_data) } + File.binwrite(@filename, @raw_data) end # @return [Hash] a hash representation of this {FatFile} diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/headers.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/headers.rb similarity index 86% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/headers.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/headers.rb index a7ed2cacf3..a810f6317d 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/headers.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/headers.rb @@ -37,6 +37,18 @@ module MachO # @api private MH_CIGAM_64 = 0xcffaedfe + # compressed mach-o magic + # @api private + COMPRESSED_MAGIC = 0x636f6d70 # "comp" + + # a compressed mach-o slice, using LZSS for compression + # @api private + COMP_TYPE_LZSS = 0x6c7a7373 # "lzss" + + # a compressed mach-o slice, using LZVN ("FastLib") for compression + # @api private + COMP_TYPE_FASTLIB = 0x6c7a766e # "lzvn" + # association of magic numbers to string representations # @api private MH_MAGICS = { @@ -433,6 +445,11 @@ module MachO # @api private MH_KEXT_BUNDLE = 0xb + # a set of Mach-Os, running in the same userspace, sharing a linkedit. The kext collection files are an example + # of this object type + # @api private + MH_FILESET = 0xc + # association of filetypes to Symbol representations # @api private MH_FILETYPES = { @@ -447,6 +464,7 @@ module MachO MH_DYLIB_STUB => :dylib_stub, MH_DSYM => :dsym, MH_KEXT_BUNDLE => :kext_bundle, + MH_FILESET => :fileset, }.freeze # association of mach header flag symbols to values @@ -478,6 +496,9 @@ module MachO :MH_HAS_TLV_DESCRIPTORS => 0x800000, :MH_NO_HEAP_EXECUTION => 0x1000000, :MH_APP_EXTENSION_SAFE => 0x02000000, + :MH_NLIST_OUTOFSYNC_WITH_DYLDINFO => 0x04000000, + :MH_SIM_SUPPORT => 0x08000000, + :MH_DYLIB_IN_CACHE => 0x80000000, }.freeze # Fat binary header structure @@ -724,6 +745,11 @@ module MachO filetype == Headers::MH_KEXT_BUNDLE end + # @return [Boolean] whether or not the file is of type `MH_FILESET` + def fileset? + filetype == Headers::MH_FILESET + end + # @return [Boolean] true if the Mach-O has 32-bit magic, false otherwise def magic32? Utils.magic32?(magic) @@ -785,5 +811,88 @@ module MachO }.merge super end end + + # Prelinked kernel/"kernelcache" header structure + class PrelinkedKernelHeader < MachOStructure + # @return [Integer] the magic number for a compressed header ({COMPRESSED_MAGIC}) + attr_reader :signature + + # @return [Integer] the type of compression used + attr_reader :compress_type + + # @return [Integer] a checksum for the uncompressed data + attr_reader :adler32 + + # @return [Integer] the size of the uncompressed data, in bytes + attr_reader :uncompressed_size + + # @return [Integer] the size of the compressed data, in bytes + attr_reader :compressed_size + + # @return [Integer] the version of the prelink format + attr_reader :prelink_version + + # @return [void] + attr_reader :reserved + + # @return [void] + attr_reader :platform_name + + # @return [void] + attr_reader :root_path + + # @see MachOStructure::FORMAT + # @api private + FORMAT = "L>6a40a64a256" + + # @see MachOStructure::SIZEOF + # @api private + SIZEOF = 384 + + # @api private + def initialize(signature, compress_type, adler32, uncompressed_size, compressed_size, prelink_version, reserved, platform_name, root_path) + super() + + @signature = signature + @compress_type = compress_type + @adler32 = adler32 + @uncompressed_size = uncompressed_size + @compressed_size = compressed_size + @prelink_version = prelink_version + @reserved = reserved.unpack("L>10") + @platform_name = platform_name + @root_path = root_path + end + + # @return [Boolean] whether this prelinked kernel supports KASLR + def kaslr? + prelink_version >= 1 + end + + # @return [Boolean] whether this prelinked kernel is compressed with LZSS + def lzss? + compress_type == COMP_TYPE_LZSS + end + + # @return [Boolean] whether this prelinked kernel is compressed with LZVN + def lzvn? + compress_type == COMP_TYPE_FASTLIB + end + + # @return [Hash] a hash representation of this {PrelinkedKernelHeader} + def to_h + { + "signature" => signature, + "compress_type" => compress_type, + "adler32" => adler32, + "uncompressed_size" => uncompressed_size, + "compressed_size" => compressed_size, + "prelink_version" => prelink_version, + "reserved" => reserved, + "platform_name" => platform_name, + "root_path" => root_path, + }.merge super + end + end end end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/load_commands.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/load_commands.rb similarity index 97% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/load_commands.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/load_commands.rb index aa90c0b7cf..c1404e4c4a 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/load_commands.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/load_commands.rb @@ -63,7 +63,8 @@ module MachO 0x31 => :LC_NOTE, 0x32 => :LC_BUILD_VERSION, (0x33 | LC_REQ_DYLD) => :LC_DYLD_EXPORTS_TRIE, - (0x34 | LC_REQ_DYLD) => :LD_DYLD_CHAINED_FIXUPS, + (0x34 | LC_REQ_DYLD) => :LC_DYLD_CHAINED_FIXUPS, + (0x35 | LC_REQ_DYLD) => :LC_FILESET_ENTRY, }.freeze # association of symbol representations to load command constants @@ -150,7 +151,8 @@ module MachO :LC_NOTE => "NoteCommand", :LC_BUILD_VERSION => "BuildVersionCommand", :LC_DYLD_EXPORTS_TRIE => "LinkeditDataCommand", - :LD_DYLD_CHAINED_FIXUPS => "LinkeditDataCommand", + :LC_DYLD_CHAINED_FIXUPS => "LinkeditDataCommand", + :LC_FILESET_ENTRY => "FilesetEntryCommand", }.freeze # association of segment name symbols to names @@ -173,6 +175,7 @@ module MachO :SG_FVMLIB => 0x2, :SG_NORELOC => 0x4, :SG_PROTECTED_VERSION_1 => 0x8, + :SG_READ_ONLY => 0x10, }.freeze # The top-level Mach-O load command structure. @@ -1794,5 +1797,48 @@ module MachO }.merge super end end + + # A load command containing a description of a Mach-O that is a constituent of a fileset. + # Each entry is further described by its own Mach header. + # Corresponds to LC_FILESET_ENTRY. + class FilesetEntryCommand < LoadCommand + # @return [Integer] the virtual memory address of the entry + attr_reader :vmaddr + + # @return [Integer] the file offset of the entry + attr_reader :fileoff + + # @return [LCStr] the entry's ID + attr_reader :entry_id + + # @return [void] + attr_reader :reserved + + # @see MachOStructure::FORMAT + # @api private + FORMAT = "L=2Q=2L=2" + + # @see MachOStructure::SIZEOF + # @api private + SIZEOF = 28 + + def initialize(view, cmd, cmdsize, vmaddr, fileoff, entry_id, reserved) + super(view, cmd, cmdsize) + @vmaddr = vmaddr + @fileoff = fileoff + @entry_id = LCStr.new(self, entry_id) + @reserved = reserved + end + + # @return [Hash] a hash representation of this {FilesetEntryCommand} + def to_h + { + "vmaddr" => vmaddr, + "fileoff" => fileoff, + "entry_id" => entry_id, + "reserved" => reserved, + }.merge super + end + end end end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/macho_file.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/macho_file.rb similarity index 84% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/macho_file.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/macho_file.rb index 85be72742f..af9df10956 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/macho_file.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/macho_file.rb @@ -34,7 +34,11 @@ module MachO # @param bin [String] a binary string containing raw Mach-O data # @param opts [Hash] options to control the parser with # @option opts [Boolean] :permissive whether to ignore unknown load commands + # @option opts [Boolean] :decompress whether to decompress, if capable # @return [MachOFile] a new MachOFile + # @note The `:decompress` option relies on non-default dependencies. Compression + # is only used in niche Mach-Os, so leaving this disabled is a reasonable default for + # virtually all normal uses. def self.new_from_bin(bin, **opts) instance = allocate instance.initialize_from_bin(bin, opts) @@ -46,13 +50,17 @@ module MachO # @param filename [String] the Mach-O file to load from # @param opts [Hash] options to control the parser with # @option opts [Boolean] :permissive whether to ignore unknown load commands + # @option opts [Boolean] :decompress whether to decompress, if capable # @raise [ArgumentError] if the given file does not exist + # @note The `:decompress` option relies on non-default dependencies. Compression + # is only used in niche Mach-Os, so leaving this disabled is a reasonable default for + # virtually all normal uses. def initialize(filename, **opts) raise ArgumentError, "#{filename}: no such file" unless File.file?(filename) @filename = filename @options = opts - @raw_data = File.open(@filename, "rb", &:read) + @raw_data = File.binread(@filename) populate_fields end @@ -152,8 +160,8 @@ module MachO # the instance fields # @raise [OffsetInsertionError] if the offset is not in the load command region # @raise [HeaderPadError] if the new command exceeds the header pad buffer - # @note Calling this method with an arbitrary offset in the load command - # region **will leave the object in an inconsistent state**. + # @note Calling this method with an arbitrary offset in the load command region + # **will leave the object in an inconsistent state**. def insert_command(offset, lc, options = {}) context = LoadCommands::LoadCommand::SerializationContext.context_for(self) cmd_raw = lc.serialize(context) @@ -196,7 +204,7 @@ module MachO # Appends a new load command to the Mach-O. # @param lc [LoadCommands::LoadCommand] the load command being added # @param options [Hash] - # @option options [Boolean] :repopulate (true) whether or not to repopulate + # @option f [Boolean] :repopulate (true) whether or not to repopulate # the instance fields # @return [void] # @see #insert_command @@ -368,20 +376,20 @@ module MachO # file.change_rpath("/usr/lib", "/usr/local/lib") # @param old_path [String] the old runtime path # @param new_path [String] the new runtime path - # @param _options [Hash] + # @param options [Hash] + # @option options [Boolean] :uniq (false) if true, change duplicate + # rpaths simultaneously. # @return [void] # @raise [RpathUnknownError] if no such old runtime path exists # @raise [RpathExistsError] if the new runtime path already exists - # @note `_options` is currently unused and is provided for signature - # compatibility with {MachO::FatFile#change_rpath} - def change_rpath(old_path, new_path, _options = {}) + def change_rpath(old_path, new_path, options = {}) old_lc = command(:LC_RPATH).find { |r| r.path.to_s == old_path } raise RpathUnknownError, old_path if old_lc.nil? raise RpathExistsError, new_path if rpaths.include?(new_path) new_lc = LoadCommands::LoadCommand.create(:LC_RPATH, new_path) - delete_rpath(old_path) + delete_rpath(old_path, options) insert_command(old_lc.view.offset, new_lc) end @@ -409,13 +417,18 @@ module MachO # file.delete_rpath("/lib") # file.rpaths # => [] # @param path [String] the runtime path to delete - # @param _options [Hash] + # @param options [Hash] + # @option options [Boolean] :uniq (false) if true, also delete + # duplicates of the requested path. If false, delete the first + # instance (by offset) of the requested path. # @return void # @raise [RpathUnknownError] if no such runtime path exists - # @note `_options` is currently unused and is provided for signature - # compatibility with {MachO::FatFile#delete_rpath} - def delete_rpath(path, _options = {}) - rpath_cmds = command(:LC_RPATH).select { |r| r.path.to_s == path } + def delete_rpath(path, options = {}) + uniq = options.fetch(:uniq, false) + search_method = uniq ? :select : :find + + # Cast rpath_cmds into an Array so we can handle the uniq and non-uniq cases the same way + rpath_cmds = Array(command(:LC_RPATH).method(search_method).call { |r| r.path.to_s == path }) raise RpathUnknownError, path if rpath_cmds.empty? # delete the commands in reverse order, offset descending. @@ -426,7 +439,7 @@ module MachO # @param filename [String] the file to write to # @return [void] def write(filename) - File.open(filename, "wb") { |f| f.write(@raw_data) } + File.binwrite(filename, @raw_data) end # Write all Mach-O data to the file used to initialize the instance. @@ -436,7 +449,7 @@ module MachO def write! raise MachOError, "no initial file to write to" if @filename.nil? - File.open(@filename, "wb") { |f| f.write(@raw_data) } + File.binwrite(@filename, @raw_data) end # @return [Hash] a hash representation of this {MachOFile} @@ -458,6 +471,9 @@ module MachO # the smallest Mach-O header is 28 bytes raise TruncatedFileError if @raw_data.size < 28 + magic = @raw_data[0..3].unpack1("N") + populate_prelinked_kernel_header if Utils.compressed_magic?(magic) + magic = populate_and_check_magic mh_klass = Utils.magic32?(magic) ? Headers::MachHeader : Headers::MachHeader64 mh = mh_klass.new_from_bin(endianness, @raw_data[0, mh_klass.bytesize]) @@ -469,6 +485,48 @@ module MachO mh end + # Read a compressed Mach-O header and check its validity, as well as whether we're able + # to parse it. + # @return [void] + # @raise [CompressedMachOError] if we weren't asked to perform decompression + # @raise [DecompressionError] if decompression is impossible or fails + # @api private + def populate_prelinked_kernel_header + raise CompressedMachOError unless options.fetch(:decompress, false) + + @plh = Headers::PrelinkedKernelHeader.new_from_bin :big, @raw_data[0, Headers::PrelinkedKernelHeader.bytesize] + + raise DecompressionError, "unsupported compression type: LZSS" if @plh.lzss? + raise DecompressionError, "unknown compression type: 0x#{plh.compress_type.to_s 16}" unless @plh.lzvn? + + decompress_macho_lzvn + end + + # Attempt to decompress a Mach-O file from the data specified in a prelinked kernel header. + # @return [void] + # @raise [DecompressionError] if decompression is impossible or fails + # @api private + # @note This method rewrites the internal state of {MachOFile} to pretend as if it was never + # compressed to begin with, allowing all other APIs to transparently act on compressed Mach-Os. + def decompress_macho_lzvn + begin + require "lzfse" + rescue LoadError + raise DecompressionError, "LZVN required but the optional 'lzfse' gem is not installed" + end + + # From this point onwards, the internal buffer of this MachOFile refers to the decompressed + # contents specified by the prelinked kernel header. + begin + @raw_data = LZFSE.lzvn_decompress @raw_data.slice(Headers::PrelinkedKernelHeader.bytesize, @plh.compressed_size) + # Sanity checks. + raise DecompressionError if @raw_data.size != @plh.uncompressed_size + # TODO: check the adler32 CRC in @plh + rescue LZFSE::DecodeError + raise DecompressionError, "LZVN decompression failed" + end + end + # Read just the file's magic number and check its validity. # @return [Integer] the magic # @raise [MagicError] if the magic is not valid Mach-O magic @@ -553,8 +611,8 @@ module MachO segments.each do |seg| seg.sections.each do |sect| next if sect.empty? - next if sect.flag?(:S_ZEROFILL) - next if sect.flag?(:S_THREAD_LOCAL_ZEROFILL) + next if sect.type?(:S_ZEROFILL) + next if sect.type?(:S_THREAD_LOCAL_ZEROFILL) next unless sect.offset < offset offset = sect.offset diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/sections.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/sections.rb similarity index 80% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/sections.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/sections.rb index d53811a25a..ab9650ad67 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/sections.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/sections.rb @@ -4,24 +4,24 @@ module MachO # Classes and constants for parsing sections in Mach-O binaries. module Sections # type mask - SECTION_TYPE = 0x000000ff + SECTION_TYPE_MASK = 0x000000ff # attributes mask - SECTION_ATTRIBUTES = 0xffffff00 + SECTION_ATTRIBUTES_MASK = 0xffffff00 # user settable attributes mask - SECTION_ATTRIBUTES_USR = 0xff000000 + SECTION_ATTRIBUTES_USR_MASK = 0xff000000 # system settable attributes mask - SECTION_ATTRIBUTES_SYS = 0x00ffff00 + SECTION_ATTRIBUTES_SYS_MASK = 0x00ffff00 # maximum specifiable section alignment, as a power of 2 # @note see `MAXSECTALIGN` macro in `cctools/misc/lipo.c` MAX_SECT_ALIGN = 15 - # association of section flag symbols to values + # association of section type symbols to values # @api private - SECTION_FLAGS = { + SECTION_TYPES = { :S_REGULAR => 0x0, :S_ZEROFILL => 0x1, :S_CSTRING_LITERALS => 0x2, @@ -44,6 +44,12 @@ module MachO :S_THREAD_LOCAL_VARIABLES => 0x13, :S_THREAD_LOCAL_VARIABLE_POINTERS => 0x14, :S_THREAD_LOCAL_INIT_FUNCTION_POINTERS => 0x15, + :S_INIT_FUNC_OFFSETS => 0x16, + }.freeze + + # association of section attribute symbols to values + # @api private + SECTION_ATTRIBUTES = { :S_ATTR_PURE_INSTRUCTIONS => 0x80000000, :S_ATTR_NO_TOC => 0x40000000, :S_ATTR_STRIP_STATIC_SYMS => 0x20000000, @@ -56,6 +62,13 @@ module MachO :S_ATTR_LOC_RELOC => 0x00000100, }.freeze + # association of section flag symbols to values + # @api private + SECTION_FLAGS = { + **SECTION_TYPES, + **SECTION_ATTRIBUTES, + }.freeze + # association of section name symbols to names # @api private SECTION_NAMES = { @@ -147,6 +160,33 @@ module MachO size.zero? end + # @return [Integer] the raw numeric type of this section + def type + flags & SECTION_TYPE_MASK + end + + # @example + # puts "this section is regular" if sect.type?(:S_REGULAR) + # @param type_sym [Symbol] a section type symbol + # @return [Boolean] whether this section is of the given type + def type?(type_sym) + type == SECTION_TYPES[type_sym] + end + + # @return [Integer] the raw numeric attributes of this section + def attributes + flags & SECTION_ATTRIBUTES_MASK + end + + # @example + # puts "pure instructions" if sect.attribute?(:S_ATTR_PURE_INSTRUCTIONS) + # @param attr_sym [Symbol] a section attribute symbol + # @return [Boolean] whether this section is of the given type + def attribute?(attr_sym) + !!(attributes & SECTION_ATTRIBUTES[attr_sym]) + end + + # @deprecated Use {#type?} or {#attribute?} instead. # @example # puts "this section is regular" if sect.flag?(:S_REGULAR) # @param flag [Symbol] a section flag symbol diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/structure.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/structure.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/structure.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/structure.rb diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/tools.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/tools.rb similarity index 94% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/tools.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/tools.rb index 2bb05fdd6d..b49a01fdc8 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/tools.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/tools.rb @@ -51,6 +51,8 @@ module MachO # @param options [Hash] # @option options [Boolean] :strict (true) whether or not to fail loudly # with an exception if the change cannot be performed + # @option options [Boolean] :uniq (false) whether or not to change duplicate + # rpaths simultaneously # @return [void] def self.change_rpath(filename, old_path, new_path, options = {}) file = MachO.open(filename) @@ -80,6 +82,8 @@ module MachO # @param options [Hash] # @option options [Boolean] :strict (true) whether or not to fail loudly # with an exception if the change cannot be performed + # @option options [Boolean] :uniq (false) whether or not to delete duplicate + # rpaths simultaneously # @return [void] def self.delete_rpath(filename, old_path, options = {}) file = MachO.open(filename) diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/utils.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/utils.rb similarity index 93% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/utils.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/utils.rb index 362e4dbf03..5e6e97bae5 100644 --- a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/utils.rb +++ b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/utils.rb @@ -121,5 +121,12 @@ module MachO def self.big_magic?(num) [Headers::MH_MAGIC, Headers::MH_MAGIC_64].include? num end + + # Compares the given number to the known magic number for a compressed Mach-O slice. + # @param num [Integer] the number being checked + # @return [Boolean] whether `num` is a valid compressed header magic number + def self.compressed_magic?(num) + num == Headers::COMPRESSED_MAGIC + end end end diff --git a/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/view.rb b/Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/view.rb similarity index 100% rename from Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-2.5.1/lib/macho/view.rb rename to Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/ruby-macho-3.0.0/lib/macho/view.rb