Look for extension first, then fall back to magic number.

This commit is contained in:
Markus Reiter 2018-07-30 09:49:59 +02:00
parent a21e7ff742
commit 281ead3096
28 changed files with 132 additions and 26 deletions

View File

@ -43,17 +43,17 @@ module UnpackStrategy
Xar,
Ttf,
Otf,
Executable,
Git,
Mercurial,
Subversion,
Cvs,
SelfExtractingExecutable, # needs to be before Cab
Cab,
Executable,
Dmg, # needs to be before Bzip2
Bzip2,
Fossil,
Bazaar,
SelfExtractingExecutable, # needs to be before Cab
Cab,
Compress,
P7Zip,
Sit,
@ -77,19 +77,14 @@ module UnpackStrategy
end
def self.from_path(path)
strategy = strategies.detect do |s|
s.can_extract?(path)
end
strategy = strategies
.sort_by { |s| s.extensions.map(&:length).max(0) }
.reverse
.detect { |s| s.extensions.include?(path.extname) }
# This is so that bad files produce good error messages.
strategy ||= case path.extname
when ".tar", ".tar.gz", ".tgz", ".tar.bz2", ".tbz", ".tar.xz", ".txz"
Tar
when ".zip"
Zip
else
Uncompressed
end
strategy ||= strategies.detect { |s| s.can_extract?(path) }
strategy ||= Uncompressed
strategy
end

View File

@ -4,6 +4,10 @@ module UnpackStrategy
using Magic
def self.extensions
[".air"]
end
def self.can_extract?(path)
mime_type = "application/vnd.adobe.air-application-installer-package+zip"
path.magic_number.match?(/.{59}#{Regexp.escape(mime_type)}/)

View File

@ -4,6 +4,10 @@ module UnpackStrategy
using Magic
def self.extensions
[".bz2"]
end
def self.can_extract?(path)
path.magic_number.match?(/\ABZh/n)
end

View File

@ -4,6 +4,10 @@ module UnpackStrategy
using Magic
def self.extensions
[".cab"]
end
def self.can_extract?(path)
path.magic_number.match?(/\AMSCF/n)
end

View File

@ -4,6 +4,10 @@ module UnpackStrategy
class Compress < Tar
using Magic
def self.extensions
[".compress"]
end
def self.can_extract?(path)
path.magic_number.match?(/\A\037\235/n)
end

View File

@ -4,6 +4,10 @@ module UnpackStrategy
using Magic
def self.extensions
[]
end
def self.can_extract?(path)
path.directory?
end

View File

@ -92,14 +92,11 @@ module UnpackStrategy
end
private_constant :Mount
def self.extensions
[".dmg"]
end
def self.can_extract?(path)
bzip2 = Bzip2.can_extract?(path)
zlib = path.magic_number.match?(/\A(\x78|\x08|\x18|\x28|\x38|\x48|\x58|\x68)/n) &&
(path.magic_number[0...2].unpack("S>").first % 31).zero?
return false unless bzip2 || zlib
imageinfo = system_command("hdiutil",
args: ["imageinfo", path],
print_stderr: false).stdout

View File

@ -4,8 +4,13 @@ module UnpackStrategy
class Executable < Uncompressed
using Magic
def self.extensions
[".sh", ".bash"]
end
def self.can_extract?(path)
path.magic_number.match?(/\A#!\s*\S+/n)
path.magic_number.match?(/\A#!\s*\S+/n) ||
path.magic_number.match?(/\AMZ/n)
end
end
end

View File

@ -4,6 +4,10 @@ module UnpackStrategy
using Magic
def self.extensions
[]
end
def self.can_extract?(path)
return false unless path.magic_number.match?(/\ASQLite format 3\000/n)

View File

@ -4,6 +4,10 @@ module UnpackStrategy
using Magic
def self.extensions
[]
end
def self.can_extract?(_path)
false
end

View File

@ -4,6 +4,10 @@ module UnpackStrategy
using Magic
def self.extensions
[".gz"]
end
def self.can_extract?(path)
path.magic_number.match?(/\A\037\213/n)
end

View File

@ -4,6 +4,10 @@ module UnpackStrategy
class Jar < Uncompressed
using Magic
def self.extensions
[".apk", ".jar"]
end
def self.can_extract?(path)
return false unless Zip.can_extract?(path)

View File

@ -4,6 +4,10 @@ module UnpackStrategy
using Magic
def self.extensions
[".lha", ".lzh"]
end
def self.can_extract?(path)
path.magic_number.match?(/\A..-(lh0|lh1|lz4|lz5|lzs|lh\\40|lhd|lh2|lh3|lh4|lh5)-/n)
end

View File

@ -4,6 +4,10 @@ module UnpackStrategy
class LuaRock < Uncompressed
using Magic
def self.extensions
[".rock"]
end
def self.can_extract?(path)
return false unless Zip.can_extract?(path)

View File

@ -4,6 +4,10 @@ module UnpackStrategy
using Magic
def self.extensions
[".lz"]
end
def self.can_extract?(path)
path.magic_number.match?(/\ALZIP/n)
end

View File

@ -4,6 +4,10 @@ module UnpackStrategy
using Magic
def self.extensions
[".lzma"]
end
def self.can_extract?(path)
path.magic_number.match?(/\A\]\000\000\200\000/n)
end

View File

@ -4,6 +4,14 @@ module UnpackStrategy
class MicrosoftOfficeXml < Uncompressed
using Magic
def self.extensions
[
".doc", ".docx",
".ppt", ".pptx",
".xls", ".xlsx"
]
end
def self.can_extract?(path)
return false unless Zip.can_extract?(path)

View File

@ -4,6 +4,10 @@ module UnpackStrategy
class Otf < Uncompressed
using Magic
def self.extensions
[".otf"]
end
def self.can_extract?(path)
path.magic_number.match?(/\AOTTO/n)
end

View File

@ -4,6 +4,10 @@ module UnpackStrategy
using Magic
def self.extensions
[".7z"]
end
def self.can_extract?(path)
path.magic_number.match?(/\A7z\xBC\xAF\x27\x1C/n)
end

View File

@ -4,6 +4,10 @@ module UnpackStrategy
class Pkg < Uncompressed
using Magic
def self.extensions
[".pkg", ".mkpg"]
end
def self.can_extract?(path)
path.extname.match?(/\A.m?pkg\Z/) &&
(path.directory? || path.magic_number.match?(/\Axar!/n))

View File

@ -4,6 +4,10 @@ module UnpackStrategy
using Magic
def self.extensions
[".rar"]
end
def self.can_extract?(path)
path.magic_number.match?(/\ARar!/n)
end

View File

@ -4,10 +4,13 @@ module UnpackStrategy
class SelfExtractingExecutable < GenericUnar
using Magic
def self.can_extract?(path)
return false unless path.magic_number.match?(/\AMZ/n)
def self.extensions
[]
end
path.file_type.include?("self-extracting archive")
def self.can_extract?(path)
path.magic_number.match?(/\AMZ/n) &&
path.file_type.include?("self-extracting archive")
end
end
end

View File

@ -4,6 +4,10 @@ module UnpackStrategy
class Sit < GenericUnar
using Magic
def self.extensions
[".sit"]
end
def self.can_extract?(path)
path.magic_number.match?(/\AStuffIt/n)
end

View File

@ -4,6 +4,16 @@ module UnpackStrategy
using Magic
def self.extensions
[
".tar",
".tbz", ".tbz2", ".tar.bz2",
".tgz", ".tar.gz",
".tlz", ".tar.lz",
".txz", ".tar.xz"
]
end
def self.can_extract?(path)
return true if path.magic_number.match?(/\A.{257}ustar/n)

View File

@ -4,6 +4,10 @@ module UnpackStrategy
class Ttf < Uncompressed
using Magic
def self.extensions
[".ttc", ".ttf"]
end
def self.can_extract?(path)
# TrueType Font
path.magic_number.match?(/\A\000\001\000\000\000/n) ||

View File

@ -4,6 +4,10 @@ module UnpackStrategy
using Magic
def self.extensions
[".xar"]
end
def self.can_extract?(path)
path.magic_number.match?(/\Axar!/n)
end

View File

@ -4,6 +4,10 @@ module UnpackStrategy
using Magic
def self.extensions
[".xz"]
end
def self.can_extract?(path)
path.magic_number.match?(/\A\xFD7zXZ\x00/n)
end

View File

@ -4,6 +4,10 @@ module UnpackStrategy
using Magic
def self.extensions
[".zip"]
end
def self.can_extract?(path)
path.magic_number.match?(/\APK(\003\004|\005\006)/n)
end