''' filetype module, version 0.4.0 (c) 2003-2016,2019 Jan ONDREJ (SAL) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. String constants are based on Magdir/* from file package. Extended to better support sfx archives. Function returns an array of filetypes. For example for zip/sfx is returned: ['zip', 'exe'] in this order. ''' import re from avlib import safe class rsc: def __init__(self, ext, *res): self.ext = ext self.fx = [] for r in res: self.fx.append(re.compile(r, re.DOTALL)) def check(self, s): for i in self.fx: if i.search(s): return 1 return 0 class rsc_multipos(rsc): def __init__(self, ext, res, *pos): self.ext = ext a = len(res.strip(b'^.')) self.pos = list([x+a for x in pos]) self.pre, self.post = res.split(b'{}', 1) self.pre = re.compile(self.pre, re.DOTALL) self.post = re.compile(b'^'+self.post, re.DOTALL) def check(self, s): for i in self.pos: if self.pre.search(s) and self.post.search(s[i:]): return 1 return 0 type_table = [ rsc(b'Z', b'^\037\235'), rsc(b'gz', b'^\037\213'), rsc(b'bz2', b'^BZh'), rsc(b'bz', b'^BZ'), rsc(b'lzop', b'^\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a'), rsc(b'tar', b'^.{257}ustar(\0|\040\040\0)'), rsc(b'zip', b'^PK\003\004'), rsc(b'zoo', b'^.{20}\xdc\xa7\xc4\xfd'), rsc(b'rar', b'^Rar!'), rsc(b'arj', b'^\x60\xea'), rsc(b'lha', b'^..-l[hz].-'), rsc(b'uc2', b'^UC2\x1a'), rsc(b'cab', b'^MSCF\0\0\0\0'), rsc(b'deb', b'^!\ndebian'), rsc(b'cpio', b'^(07070[712]|\xc7\x71|\x71\xc7)'), rsc(b'arc', b'^\x1a[\x01\x02\x03\x04\x05\x06\x07\x08\x09]'), rsc(b'rpm', b'^\xab\xed\xdb\xee'), rsc(b'uu', b'^begin\040'), # Executables rsc_multipos(b'zip', b'^MZ.{}PK\003\004', 11694,13297,15588,15770,28374,25115,26331,47031,49845,69120), rsc_multipos(b'rar', b'^MZ.{}Rar!', 7193,38910,51710,95110), rsc(b'arj', b'^MZ.{28}RJSX\xff\xff'), rsc(b'lha', b'^MZ.{34}LHa\'s SFX', b'^MZ.{1636}-lh5-'), rsc(b'winpe', b'^.{128}PE\0\0'), rsc(b'exe', b'^[LM]Z'), rsc(b'elf', b'^\177ELF') ] def what(buffer): r = [] for f in type_table: if f.check(buffer): r.append(f.ext) return r def file(filename): return what(safe.open(filename, 'rb').read(99999))