Module: Omnizip::Formats::SevenZip
- Defined in:
- lib/omnizip/formats/seven_zip.rb,
lib/omnizip/formats/seven_zip/header.rb,
lib/omnizip/formats/seven_zip/models.rb,
lib/omnizip/formats/seven_zip/parser.rb,
lib/omnizip/formats/seven_zip/reader.rb,
lib/omnizip/formats/seven_zip/writer.rb,
lib/omnizip/formats/seven_zip/constants.rb,
lib/omnizip/formats/seven_zip/coder_chain.rb,
lib/omnizip/formats/seven_zip/header_writer.rb,
lib/omnizip/formats/seven_zip/models/folder.rb,
lib/omnizip/formats/seven_zip/encoded_header.rb,
lib/omnizip/formats/seven_zip/file_collector.rb,
lib/omnizip/formats/seven_zip/encrypted_header.rb,
lib/omnizip/formats/seven_zip/header_encryptor.rb,
lib/omnizip/formats/seven_zip/models/coder_info.rb,
lib/omnizip/formats/seven_zip/models/file_entry.rb,
lib/omnizip/formats/seven_zip/stream_compressor.rb,
lib/omnizip/formats/seven_zip/models/stream_info.rb,
lib/omnizip/formats/seven_zip/stream_decompressor.rb,
lib/omnizip/formats/seven_zip/split_archive_reader.rb,
lib/omnizip/formats/seven_zip/split_archive_writer.rb,
lib/omnizip/formats/seven_zip/bcj2_stream_decompressor.rb
Overview
.7z archive format support Provides read and write access to 7-Zip archives
This module implements the .7z archive format specification, supporting:
- Format signature and header validation
- Archive structure parsing
- File extraction
- Archive creation
- Split archives (multi-volume)
Defined Under Namespace
Modules: Constants, EncodedHeader, Models Classes: Bcj2StreamDecompressor, CoderChain, EncryptedHeader, FileCollector, Header, HeaderEncryptor, HeaderWriter, Parser, Reader, SplitArchiveReader, SplitArchiveWriter, StreamCompressor, StreamDecompressor, Writer
Class Method Summary collapse
-
.create(path, options = {}) {|writer| ... } ⇒ Object
Create a new .7z archive.
-
.create_split(path, split_options, options = {}) {|writer| ... } ⇒ Object
Create a split .7z archive.
-
.open(path, options = {}) {|reader| ... } ⇒ Reader
Open existing .7z archive.
-
.register! ⇒ Object
Auto-register .7z format when loaded.
-
.search_embedded(path) ⇒ Integer?
Search for embedded .7z archive in self-extracting executable.
-
.valid_7z_start_header?(data, offset, file_size) ⇒ Boolean
Validate a candidate 7z Start Header at the given offset.
Class Method Details
.create(path, options = {}) {|writer| ... } ⇒ Object
Create a new .7z archive
64 65 66 67 68 69 |
# File 'lib/omnizip/formats/seven_zip.rb', line 64 def self.create(path, = {}) writer = Writer.new(path, ) yield writer if block_given? writer.write writer end |
.create_split(path, split_options, options = {}) {|writer| ... } ⇒ Object
Create a split .7z archive
78 79 80 81 82 83 |
# File 'lib/omnizip/formats/seven_zip.rb', line 78 def self.create_split(path, , = {}) writer = SplitArchiveWriter.new(path, , ) yield writer if block_given? writer.write writer end |
.open(path, options = {}) {|reader| ... } ⇒ Reader
Open existing .7z archive
93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/omnizip/formats/seven_zip.rb', line 93 def self.open(path, = {}) reader = Reader.new(path, ) reader.open if block_given? begin yield reader ensure reader.split_reader&.close end end reader end |
.register! ⇒ Object
Auto-register .7z format when loaded
179 180 181 |
# File 'lib/omnizip/formats/seven_zip.rb', line 179 def self.register! FormatRegistry.register(".7z", "Omnizip::Formats::SevenZip::Reader") end |
.search_embedded(path) ⇒ Integer?
Search for embedded .7z archive in self-extracting executable
Scans the file for 7z signatures and validates each candidate by checking the Start Header (version bytes, CRC, and header field sanity). Returns the offset of the first valid embedded archive.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/omnizip/formats/seven_zip.rb', line 116 def self.(path) data = File.binread(path) file_size = data.bytesize signature = Constants::SIGNATURE pos = 0 while (offset = data.index(signature, pos)) if valid_7z_start_header?(data, offset, file_size) return offset end pos = offset + 1 end nil end |
.valid_7z_start_header?(data, offset, file_size) ⇒ Boolean
Validate a candidate 7z Start Header at the given offset.
Checks:
- Enough bytes remain for a full 32-byte Start Header
- Major version is 0 and minor version is 4 (only supported version)
- Next Header offset + size points within (or at the end of) the file
- Start Header CRC matches the header content
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/omnizip/formats/seven_zip.rb', line 145 def self.valid_7z_start_header?(data, offset, file_size) header_size = Constants::START_HEADER_SIZE # 32 return false if offset + header_size > file_size header_data = data.byteslice(offset, header_size) # Check version byte (offset 6) - only major version is validated per 7-Zip SDK # See: https://github.com/ip7z/7zip/blob/main/CPP/7zip/Archive/7z/7zIn.cpp#L1591-L1598 major_version = header_data.getbyte(6) return false unless major_version == Constants::MAJOR_VERSION # Parse Start Header fields (bytes 12-31) next_header_data = header_data.byteslice(12, 20) next_header_offset = next_header_data.unpack1("Q<") next_header_size = next_header_data.byteslice(8, 8).unpack1("Q<") # next_header_offset is relative to end of Start Header header_end = offset + header_size + next_header_offset + next_header_size return false if header_end > file_size return false if next_header_size.zero? || next_header_size > file_size # Validate Start Header CRC (bytes 8-11) over next_header_data (bytes 12-31) stored_crc = header_data.byteslice(8, 4).unpack1("V") computed_crc = Omnizip::Checksums::Crc32.new.tap do |c| c.update(next_header_data) end.finalize return false unless stored_crc == computed_crc true rescue StandardError false end |