Extension Mapping
Simple Extensions
Extensions that map directly to a single extractor:
| Extension | Extractor | Format |
|---|---|---|
| SevenZipExtractor | 7-Zip |
| CabExtractor | Microsoft Cabinet |
| CpioExtractor | CPIO |
| GzipExtractor | GZIP |
| OleExtractor | Windows Installer |
| XarExtractor | macOS Package |
| RpmExtractor | Red Hat Package |
| TarExtractor | TAR |
| XarExtractor | XAR |
| XzExtractor | XZ |
| ZipExtractor | ZIP |
Compound Extensions
Extensions that trigger multiple extractors in sequence:
| Extension | Extraction Chain | Result |
|---|---|---|
| GzipExtractor → TarExtractor | Extracted TAR contents |
| GzipExtractor → TarExtractor | Extracted TAR contents |
| XzExtractor → TarExtractor | Extracted TAR contents |
| XzExtractor → TarExtractor | Extracted TAR contents |
Special Cases
EXE Files
EXE files are handled with fallback logic:
# Order of attempts:
1. SevenZipExtractor # Try 7-Zip self-extracting
2. CabExtractor # Fall back to CAB self-extractingDetection Logic
def extract(target)
extension = File.extname(@archive).downcase
case extension
when '.exe'
# Try 7-Zip first, then CAB
begin
SevenZipExtractor.new(@archive).extract(target)
rescue
CabExtractor.new(@archive).extract(target)
end
when '.gz'
# Verify GZIP magic bytes
if gzip_magic?(@archive)
GzipExtractor.new(@archive).extract(target)
else
raise UnknownArchiveError
end
else
# Standard extension mapping
extractor = TYPES[extension]
extractor.new(@archive).extract(target)
end
endImplementation
The TYPES hash maps extensions to extractors:
TYPES = {
"cab" => Extractors::CabExtractor,
"cpio" => Extractors::CpioExtractor,
"exe" => Extractors::SevenZipExtractor,
"gz" => Extractors::GzipExtractor,
"msi" => Extractors::OleExtractor,
"pkg" => Extractors::XarExtractor,
"rpm" => Extractors::RpmExtractor,
"tar" => Extractors::TarExtractor,
"xz" => Extractors::XzExtractor,
"zip" => Extractors::ZipExtractor
}Adding New Formats
To support a new format:
-
Create a new extractor class
-
Add mapping to TYPES hash
-
Handle compound extensions if needed
# 1. Create extractor
class Extractors::NewFormatExtractor < Extractor
def extract(target)
# Implementation
end
end
# 2. Add to TYPES
TYPES["newfmt"] = Extractors::NewFormatExtractor