You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

535 lines
18 KiB

Change core system to improve performance and facilitate multi TV info sources. Change migrate core objects TVShow and TVEpisode and everywhere that these objects affect. Add message to logs and disable ui backlog buttons when no media provider has active and/or scheduled searching enabled. Change views for py3 compat. Change set default runtime of 5 mins if none is given for layout Day by Day. Add OpenSubtitles authentication support to config/Subtitles/Subtitles Plugin. Add "Enforce media hash match" to config/Subtitles Plugin/Opensubtitles for accurate subs if enabled, but if disabled, search failures will fallback to use less reliable subtitle results. Add Apprise 0.8.0 (6aa52c3). Add hachoir_py3 3.0a6 (5b9e05a). Add sgmllib3k 1.0.0 Update soupsieve 1.9.1 (24859cc) to soupsieve_py2 1.9.5 (6a38398) Add soupsieve_py3 2.0.0.dev (69194a2). Add Tornado_py3 Web Server 6.0.3 (ff985fe). Add xmlrpclib_to 0.1.1 (c37db9e). Remove ancient Growl lib 0.1 Remove xmltodict library. Change requirements.txt for Cheetah3 to minimum 3.2.4 Change update sabToSickBeard. Change update autoProcessTV. Change remove Twitter notifier. Update NZBGet Process Media extension, SickGear-NG 1.7 → 2.4 Update Kodi addon 1.0.3 → 1.0.4 Update ADBA for py3. Update Beautiful Soup 4.8.0 (r526) to 4.8.1 (r531). Update Send2Trash 1.3.0 (a568370) to 1.5.0 (66afce7). Update soupsieve 1.9.1 (24859cc) to 1.9.5 (6a38398). Change use GNTP (Growl Notification Transport Protocol) from Apprise. Change add multi host support to Growl notifier. Fix Growl notifier when using empty password. Change update links for Growl notifications. Change deprecate confg/Notifications/Growl password field as these are now stored with host setting. Fix prevent infinite memoryError from a particular jpg data structure. Change subliminal for py3. Change enzyme for py3. Change browser_ua for py3. Change feedparser for py3 (sgmlib is no longer available on py3 as standardlib so added ext lib) Fix Guessit. Fix parse_xml for py3. Fix name parser with multi eps for py3. Fix tvdb_api fixes for py3 (search show). Fix config/media process to only display "pattern is invalid" qtip on "Episode naming" tab if the associated field is actually visible. Also, if the field becomes hidden due to a setting change, hide any previously displayed qtip. Note for Javascript::getelementbyid (or $('tag[id="<name>"')) is required when an id is being searched in the dom due to ":" used in a shows id name. Change download anidb xml files to main cache folder and use adba lib folder as a last resort. Change create get anidb show groups as centralised helper func and consolidate dupe code. Change move anidb related functions to newly renamed anime.py (from blacklistandwhitelist.py). Change str encode hex no longer exits in py3, use codecs.encode(...) instead. Change fix b64decode on py3 returns bytestrings. Change use binary read when downloading log file via browser to prevent any encoding issues. Change add case insensitive ordering to anime black/whitelist. Fix anime groups list not excluding whitelisted stuff. Change add Windows utf8 fix ... see: ytdl-org/youtube-dl#820 Change if no qualities are wanted, exit manual search thread. Fix keepalive for py3 process media. Change add a once a month update of tvinfo show mappings to the daily updater. Change autocorrect ids of new shows by updating from -8 to 31 days of the airdate of episode one. Add next run time to Manage/Show Tasks/Daily show update. Change when fetching imdb data, if imdb id is an episode id then try to find and use real show id. Change delete diskcache db in imdbpie when value error (due to change in Python version). Change during startup, cleanup any _cleaner.pyc/o to prevent issues when switching python versions. Add .pyc cleaner if python version is switched. Change replace deprecated gettz_db_metadata() and gettz. Change rebrand "SickGear PostProcessing script" to "SickGear Process Media extension". Change improve setup guide to use the NZBGet version to minimise displayed text based on version. Change NZBGet versions prior to v17 now told to upgrade as those version are no longer supported - code has actually exit on start up for some time but docs were outdated. Change comment out code and unused option sg_base_path. Change supported Python version 2.7.9-2.7.18 inclusive expanded to 3.7.1-3.8.1 inclusive. Change pidfile creation under Linux 0o644. Make logger accept lists to output continuously using the log_lock instead of split up by other processes. Fix long path issues with Windows process media.
6 years ago
"""
Mach-O (Mac OS X executable file format) parser.
Resources:
- https://lowlevelbits.org/parsing-mach-o-files/
- OS X ABI Mach-O File Format Reference
(mirrored at https://github.com/aidansteele/osx-abi-macho-file-format-reference)
- https://llvm.org/svn/llvm-project/llvm/trunk/include/llvm/BinaryFormat/
Author: Robert Xiao
Creation date: February 11, 2015
Updated: January 13, 2017
"""
from hachoir_py3.parser import HachoirParser
from hachoir_py3.field import (RootSeekableFieldSet, FieldSet,
Bit, NullBits, String, CString,
RawBytes, Bytes, PaddingBytes,
Int32, UInt32, UInt64, Enum)
from hachoir_py3.core.text_handler import textHandler, hexadecimal
from hachoir_py3.core.endian import LITTLE_ENDIAN, BIG_ENDIAN
from hachoir_py3.core.bits import str2hex
CPU_ARCH_ABI64 = 0x01000000
CPU_TYPE = {
-1: 'Any',
1: 'VAX',
6: 'MC680x0',
7: 'i386',
7 | CPU_ARCH_ABI64: 'x86_64',
8: 'MIPS',
10: 'MC98000',
11: 'HPPA',
12: 'ARM',
12 | CPU_ARCH_ABI64: 'ARM64',
13: 'MC88000',
14: 'SPARC',
15: 'I860',
16: 'Alpha',
18: 'PowerPC',
18 | CPU_ARCH_ABI64: 'PowerPC64',
}
FILE_TYPE = {
1: 'Relocatable object',
2: 'Demand-paged executable',
3: 'Fixed VM shared library',
4: 'Core file',
5: 'Preloaded executable',
6: 'Dynamically bound shared library',
7: 'Dynamic link editor',
8: 'Dynamically bound bundle',
9: 'Shared library stub for static linking only',
10: 'Companion file with only debug sections',
11: 'x86_64 kext',
}
MACHO_MAGICS = {
b"\xfe\xed\xfa\xce": (0, BIG_ENDIAN), # 32-bit big endian
b"\xce\xfa\xed\xfe": (0, LITTLE_ENDIAN), # 32-bit little endian
b"\xfe\xed\xfa\xcf": (1, BIG_ENDIAN), # 64-bit big endian
b"\xcf\xfa\xed\xfe": (1, LITTLE_ENDIAN), # 64-bit little endian
}
class MachoHeader(FieldSet):
FLAGS = [
'NOUNDEFS', 'INCRLINK', 'DYLDLINK', 'BINDATLOAD',
'PREBOUND', 'SPLIT_SEGS', 'LAZY_INIT', 'TWOLEVEL',
'FORCE_FLAT', 'NOMULTIDEFS', 'NOFIXPREBINDING', 'PREBINDABLE',
'ALLMODSBOUND', 'SUBSECTIONS_VIA_SYMBOLS', 'CANONICAL', 'WEAK_DEFINES',
'BINDS_TO_WEAK', 'ALLOW_STACK_EXECUTION', 'ROOT_SAFE', 'SETUID_SAFE',
'NO_REEXPORTED_DYLIBS', 'PIE', 'DEAD_STRIPPABLE_DYLIB', 'HAS_TLV_DESCRIPTORS',
'NO_HEAP_EXECUTION',
]
def createFields(self):
yield Bytes(self, "magic", 4, "Mach-O signature")
yield Enum(Int32(self, "cputype"), CPU_TYPE)
yield Int32(self, "cpusubtype")
yield Enum(UInt32(self, "filetype"), FILE_TYPE)
yield UInt32(self, "ncmds", "Number of load commands")
yield UInt32(self, "sizeofcmds", "Total size of all load commands")
if self.endian == BIG_ENDIAN:
yield NullBits(self, "flags_reserved", 32 - len(self.FLAGS))
for flag in self.FLAGS[::-1]:
yield Bit(self, "flags_" + flag.lower())
else:
for flag in self.FLAGS:
yield Bit(self, "flags_" + flag.lower())
yield NullBits(self, "flags_reserved", 32 - len(self.FLAGS))
if self.parent.is64bit:
yield UInt32(self, "reserved")
def createDescription(self):
return "%s %s, %d load commands, <%s>" % (
self['cputype'].display, self['filetype'].display,
self['ncmds'].value,
'|'.join(f for f in self.FLAGS if self['flags_' + f.lower()].value))
class UuidCommand(FieldSet):
static_size = 16 * 8
def createFields(self):
yield RawBytes(self, "uuid", 16)
def createValue(self):
return self['uuid'].value
def createDisplay(self):
text = str2hex(self['uuid'].value, format=r"%02x")
return "%s-%s-%s-%s-%s" % (
text[:8], text[8:12], text[12:16], text[16:20], text[20:])
def createDescription(self):
return "UUID for corresponding dSYM file"
class SegmentCommand(FieldSet):
def createFields(self):
yield String(self, "segname", 16, strip="\0")
yield textHandler(UInt32(self, "vmaddr"), hexadecimal)
yield textHandler(UInt32(self, "vmsize"), hexadecimal)
yield textHandler(UInt32(self, "fileoff"), hexadecimal)
yield textHandler(UInt32(self, "filesize"), hexadecimal)
yield UInt32(self, "maxprot")
yield UInt32(self, "initprot")
yield UInt32(self, "nsects")
yield UInt32(self, "flags")
for i in range(self['nsects'].value):
yield MachoSection(self, "section[]")
def createValue(self):
return self['segname'].value
def createDescription(self):
return "Load segment %s" % (self['segname'].value)
class SegmentCommand64(FieldSet):
def createFields(self):
yield String(self, "segname", 16, strip="\0")
yield textHandler(UInt64(self, "vmaddr"), hexadecimal)
yield textHandler(UInt64(self, "vmsize"), hexadecimal)
yield textHandler(UInt64(self, "fileoff"), hexadecimal)
yield textHandler(UInt64(self, "filesize"), hexadecimal)
yield UInt32(self, "maxprot")
yield UInt32(self, "initprot")
yield UInt32(self, "nsects")
yield UInt32(self, "flags")
for i in range(self['nsects'].value):
yield MachoSection64(self, "section[]")
def createValue(self):
return self['segname'].value
def createDescription(self):
return "Load segment %s" % (self['segname'].value)
class SymtabCommand(FieldSet):
def createFields(self):
yield UInt32(self, "symoff")
yield UInt32(self, "nsyms")
yield UInt32(self, "stroff")
yield UInt32(self, "strsize")
class SymsegCommand(FieldSet):
def createFields(self):
yield UInt32(self, "offset")
yield UInt32(self, "size")
class DysymtabCommand(FieldSet):
def createFields(self):
yield UInt32(self, "ilocalsym")
yield UInt32(self, "nlocalsym")
yield UInt32(self, "iextdefsym")
yield UInt32(self, "nextdefsym")
yield UInt32(self, "iundefsym")
yield UInt32(self, "nundefsym")
yield UInt32(self, "tocoff")
yield UInt32(self, "ntoc")
yield UInt32(self, "modtaboff")
yield UInt32(self, "nmodtab")
yield UInt32(self, "extrefsymoff")
yield UInt32(self, "nextrefsyms")
yield UInt32(self, "indirectsymoff")
yield UInt32(self, "nindirectsyms")
yield UInt32(self, "extreloff")
yield UInt32(self, "nextrel")
yield UInt32(self, "locreloff")
yield UInt32(self, "nlocrel")
class DylinkerCommand(FieldSet):
def createFields(self):
yield UInt32(self, "offset")
yield CString(self, "name")
def createValue(self):
return self['name'].value
class VersionMinCommand(FieldSet):
def createFields(self):
yield UInt32(self, "version")
yield UInt32(self, "sdk")
def createDisplay(self):
version = self['version'].value
sdk = self['sdk'].value
return "%d.%d.%d sdk %d.%d.%d" % (
version >> 16, (version >> 8) & 0xff, version & 0xff,
sdk >> 16, (sdk >> 8) & 0xff, sdk & 0xff)
class DyldInfoCommand(FieldSet):
def createFields(self):
yield UInt32(self, "rebase_off")
yield UInt32(self, "rebase_size")
yield UInt32(self, "bind_off")
yield UInt32(self, "bind_size")
yield UInt32(self, "weak_bind_off")
yield UInt32(self, "weak_bind_size")
yield UInt32(self, "lazy_bind_off")
yield UInt32(self, "lazy_bind_size")
yield UInt32(self, "export_off")
yield UInt32(self, "export_size")
class DylibCommand(FieldSet):
def createFields(self):
yield UInt32(self, "offset")
yield UInt32(self, "timestamp")
yield UInt32(self, "current_version")
yield UInt32(self, "compatibility_version")
yield CString(self, "name")
def createValue(self):
return self['name'].value
class MachoSection(FieldSet):
def createFields(self):
yield String(self, "sectname", 16, strip="\0")
yield String(self, "segname", 16, strip="\0")
yield textHandler(UInt32(self, "addr"), hexadecimal)
yield textHandler(UInt32(self, "size"), hexadecimal)
yield textHandler(UInt32(self, "offset"), hexadecimal)
yield textHandler(UInt32(self, "align"), hexadecimal)
yield textHandler(UInt32(self, "reloff"), hexadecimal)
yield UInt32(self, "nreloc")
yield UInt32(self, "flags")
yield UInt32(self, "reserved1")
yield UInt32(self, "reserved2")
def createValue(self):
return self['segname'].value + ',' + self['sectname'].value
def createDescription(self):
return "Section %s,%s" % (self['segname'].value, self['sectname'].value)
class MachoSection64(FieldSet):
def createFields(self):
yield String(self, "sectname", 16, strip="\0")
yield String(self, "segname", 16, strip="\0")
yield textHandler(UInt64(self, "addr"), hexadecimal)
yield textHandler(UInt64(self, "size"), hexadecimal)
yield textHandler(UInt32(self, "offset"), hexadecimal)
yield textHandler(UInt32(self, "align"), hexadecimal)
yield textHandler(UInt32(self, "reloff"), hexadecimal)
yield UInt32(self, "nreloc")
yield UInt32(self, "flags")
yield UInt32(self, "reserved1")
yield UInt32(self, "reserved2")
yield RawBytes(self, "padding", 4)
def createValue(self):
return self['segname'].value + ',' + self['sectname'].value
def createDescription(self):
return "Section %s,%s" % (self['segname'].value, self['sectname'].value)
class MachoLoadCommand(FieldSet):
LC_REQ_DYLD = 0x80000000
LC_SEGMENT = 0x1
LC_SYMTAB = 0x2
LC_SYMSEG = 0x3
LC_THREAD = 0x4
LC_UNIXTHREAD = 0x5
LC_LOADFVMLIB = 0x6
LC_IDFVMLIB = 0x7
LC_IDENT = 0x8
LC_FVMFILE = 0x9
LC_PREPAGE = 0xa
LC_DYSYMTAB = 0xb
LC_LOAD_DYLIB = 0xc
LC_ID_DYLIB = 0xd
LC_LOAD_DYLINKER = 0xe
LC_ID_DYLINKER = 0xf
LC_PREBOUND_DYLIB = 0x10
LC_ROUTINES = 0x11
LC_SUB_FRAMEWORK = 0x12
LC_SUB_UMBRELLA = 0x13
LC_SUB_CLIENT = 0x14
LC_SUB_LIBRARY = 0x15
LC_TWOLEVEL_HINTS = 0x16
LC_PREBIND_CKSUM = 0x17
LC_LOAD_WEAK_DYLIB = 0x18 | LC_REQ_DYLD
LC_SEGMENT_64 = 0x19
LC_ROUTINES_64 = 0x1a
LC_UUID = 0x1b
LC_RPATH = 0x1c | LC_REQ_DYLD
LC_CODE_SIGNATURE = 0x1d
LC_SEGMENT_SPLIT_INFO = 0x1e
LC_REEXPORT_DYLIB = 0x1f | LC_REQ_DYLD
LC_LAZY_LOAD_DYLIB = 0x20
LC_ENCRYPTION_INFO = 0x21
LC_DYLD_INFO = 0x22
LC_DYLD_INFO_ONLY = 0x22 | LC_REQ_DYLD
LC_LOAD_UPWARD_DYLIB = 0x23 | LC_REQ_DYLD
LC_VERSION_MIN_MACOSX = 0x24
LC_VERSION_MIN_IPHONEOS = 0x25
LC_FUNCTION_STARTS = 0x26
LC_DYLD_ENVIRONMENT = 0x27
LC_MAIN = 0x28 | LC_REQ_DYLD
LC_DATA_IN_CODE = 0x29
LC_SOURCE_VERSION = 0x2a
LC_DYLIB_CODE_SIGN_DRS = 0x2b
LC_ENCRYPTION_INFO_64 = 0x2c
LC_LINKER_OPTION = 0x2d
LC_LINKER_OPTIMIZATION_HINT = 0x2e
LC_VERSION_MIN_TVOS = 0x2f
LC_VERSION_MIN_WATCHOS = 0x30
LC_NOTE = 0x31
LC_BUILD_VERSION = 0x32
LOAD_COMMANDS = {
LC_SEGMENT: ("Segment", SegmentCommand),
LC_SYMTAB: ("Symbol table", SymtabCommand),
LC_SYMSEG: ("Symbol segment", SymsegCommand),
LC_THREAD: ("Thread", None),
LC_UNIXTHREAD: ("UNIX thread", None),
LC_LOADFVMLIB: ("Load fixed VM library", None),
LC_IDFVMLIB: ("Fixed VM library identification", None),
LC_IDENT: ("Object identification", None),
LC_FVMFILE: ("Fixed VM file inclusion", None),
LC_PREPAGE: ("Prepage", None),
LC_DYSYMTAB: ("Dynamic symbol table", DysymtabCommand),
LC_LOAD_DYLIB: ("Load dynamic library", DylibCommand),
LC_ID_DYLIB: ("Dynamic library identification", None),
LC_LOAD_DYLINKER: ("Load dynamic linker", DylinkerCommand),
LC_ID_DYLINKER: ("Dynamic linker identification", None),
LC_PREBOUND_DYLIB: ("Prebound modules", None),
LC_ROUTINES: ("Image routines", None),
LC_SUB_FRAMEWORK: ("Sub-framework", None),
LC_SUB_UMBRELLA: ("Sub-umbrella", None),
LC_SUB_CLIENT: ("Sub-client", None),
LC_SUB_LIBRARY: ("Sub-library", None),
LC_TWOLEVEL_HINTS: ("Two-level lookup hints", None),
LC_PREBIND_CKSUM: ("Prebind checksum", None),
LC_LOAD_WEAK_DYLIB: ("Load dynamic library weakly", None),
LC_SEGMENT_64: ("64-bit segment", SegmentCommand64),
LC_ROUTINES_64: ("64-bit image routines", None),
LC_UUID: ("UUID", UuidCommand),
LC_RPATH: ("Runpath additions", None),
LC_CODE_SIGNATURE: ("Code signature", None),
LC_SEGMENT_SPLIT_INFO: ("Segment split info", None),
LC_REEXPORT_DYLIB: ("Load and re-export dylib", None),
LC_LAZY_LOAD_DYLIB: ("Lazy load dynamic library", None),
LC_ENCRYPTION_INFO: ("Encrypted segment information", None),
LC_DYLD_INFO: ("Compressed dyld info", DyldInfoCommand),
LC_DYLD_INFO_ONLY: ("Compressed dyld info", DyldInfoCommand),
LC_LOAD_UPWARD_DYLIB: ("Load upward dylib", None),
LC_VERSION_MIN_MACOSX: ("Minimum macOS version", VersionMinCommand),
LC_VERSION_MIN_IPHONEOS: ("Minimum iOS version", VersionMinCommand),
LC_FUNCTION_STARTS: ("Compressed function start address table", None),
LC_DYLD_ENVIRONMENT: ("dyld environment variables", None),
LC_MAIN: ("Main thread info", None),
LC_DATA_IN_CODE: ("Table of non-instructions in text segment", None),
LC_SOURCE_VERSION: ("Source code version info", None),
LC_DYLIB_CODE_SIGN_DRS: ("Code signing info from linked dylibs", None),
}
LOAD_COMMANDS_DISPLAY = {k: v[0] for k, v in LOAD_COMMANDS.items()}
def createFields(self):
yield Enum(UInt32(self, "cmd"), self.LOAD_COMMANDS_DISPLAY)
yield UInt32(self, "cmdsize")
self._size = self['cmdsize'].value * 8
desc, parser = self.LOAD_COMMANDS.get(self['cmd'].value, ("", None))
if parser:
yield parser(self, "data")
# data is word aligned
padding_length = self['cmdsize'].value - self.current_size // 8
if padding_length:
yield PaddingBytes(self, "padding", padding_length)
else:
yield RawBytes(self, "data",
self['cmdsize'].value - self.current_size // 8)
def createValue(self):
return self['cmd'].value
def createDisplay(self):
return self['cmd'].display + ': ' + self['data'].display
def createDescription(self):
return self['data'].description
class MachoFileBase(RootSeekableFieldSet):
def createFields(self):
baseaddr = self.absolute_address
# Choose size and endianness based on magic
magic = self.stream.readBytes(baseaddr, 4)
self.is64bit, self.endian = MACHO_MAGICS[magic]
yield MachoHeader(self, "header")
for i in range(self['header/ncmds'].value):
yield MachoLoadCommand(self, "load_command[]")
def createDescription(self):
return "Mach-O program/library: %s" % (self["header/cputype"].display)
class MachoFile(HachoirParser, MachoFileBase):
PARSER_TAGS = {
"id": "macho",
"category": "program",
"file_ext": ("dylib", "bundle", "o", ""),
"min_size": (28 + 56) * 8, # Header + one segment load command
"mime": (
"application/x-executable",
"application/x-object",
"application/x-sharedlib",
"application/x-executable-file",
"application/x-coredump"),
"magic": tuple((m, 0) for m in MACHO_MAGICS),
"description": "Mach-O program/library"
}
endian = BIG_ENDIAN
def __init__(self, stream, **args):
MachoFileBase.__init__(self, None, "root", stream,
None, stream.askSize(self))
HachoirParser.__init__(self, stream, **args)
def validate(self):
if self.stream.readBytes(0, 4) not in MACHO_MAGICS:
return "Invalid magic"
return True
class MachoFatArch(FieldSet):
def createFields(self):
yield Enum(Int32(self, "cputype"), CPU_TYPE)
yield Int32(self, "cpusubtype")
yield textHandler(UInt32(self, "offset"), hexadecimal)
yield UInt32(self, "size")
yield UInt32(self, "align")
self['align'].createDescription = lambda: str(1 << self['align'].value)
class MachoFatHeader(FieldSet):
def createFields(self):
yield Bytes(self, "magic", 4, "Mach-O signature")
yield UInt32(self, "nfat_arch", "Number of architectures in this fat file")
for i in range(self['nfat_arch'].value):
yield MachoFatArch(self, 'arch[]')
class MachoFatFile(HachoirParser, RootSeekableFieldSet):
MAGIC_BE = b"\xca\xfe\xba\xbe"
MAGIC_LE = b"\xbe\xba\xfe\xca"
PARSER_TAGS = {
"id": "macho_fat",
"category": "program",
"file_ext": ("dylib", "bundle", ""),
# One page + size for one arch
"min_size": 4096 * 8 + MachoFile.PARSER_TAGS['min_size'],
"mime": (
"application/x-executable",
"application/x-object",
"application/x-sharedlib",
"application/x-executable-file",
"application/x-coredump"),
"magic": ((MAGIC_LE, 0), (MAGIC_BE, 0)),
"description": "Mach-O fat program/library"
}
endian = BIG_ENDIAN
def __init__(self, stream, **args):
RootSeekableFieldSet.__init__(
self, None, "root", stream, None, stream.askSize(self))
HachoirParser.__init__(self, stream, **args)
def validate(self):
if self.stream.readBytes(0, 4) not in (self.MAGIC_LE, self.MAGIC_BE):
return "Invalid magic"
if self['header/nfat_arch'].value >= 16:
# This helps to distinguish mach-o from java.
return "Too many architectures"
return True
def createFields(self):
# Choose the right endian based on file magic
if self.stream.readBytes(0, 4) == self.MAGIC_LE:
self.endian = LITTLE_ENDIAN
else:
self.endian = BIG_ENDIAN
# Parse header and program headers
yield MachoFatHeader(self, "header", "Header")
for arch in self['header'].array('arch'):
self.seekByte(arch['offset'].value)
yield MachoFileBase(self, 'file[]', self.stream, None, arch['size'].value * 8)