def setUp(self): self.zipper = ZipFile(ZIP_TEMP_FILE) self.subfile = ZipSubFile(self.zipper, FILE_NAME) self.subfile.open() # create a file in memory for comparison self.compare = TemporaryFile(prefix='oletools-test-ZipSubFile-', suffix='.bin') self.compare.write(FILE_CONTENTS) self.compare.seek(0) # re-position to start self.assertEqual(self.subfile.tell(), 0) self.assertEqual(self.compare.tell(), 0) if DEBUG: print('created comparison file {0!r} in memory'.format( self.compare.name))
def setUp(self): self.zipper = ZipFile(ZIP_TEMP_FILE) self.subfile = ZipSubFile(self.zipper, FILE_NAME) self.subfile.open() # create a file in memory for comparison self.compare = TemporaryFile(prefix='oletools-test-ZipSubFile-', suffix='.bin') self.compare.write(FILE_CONTENTS) self.compare.seek(0) # re-position to start self.assertEqual(self.subfile.tell(), 0) self.assertEqual(self.compare.tell(), 0) if DEBUG: print('created comparison file {0!r} in memory' .format(self.compare.name))
def find_ole(filename, data): """ try to open somehow as zip/ole/rtf/... ; yield None if fail If data is given, filename is (mostly) ignored. yields embedded ole streams in form of OleFileIO. """ if data is not None: # isOleFile and is_ppt can work on data directly but zip need file # --> wrap data in a file-like object without copying data log.debug('working on data, file is not touched below') arg_for_ole = data arg_for_zip = FakeFile(data) else: # we only have a file name log.debug('working on file by name') arg_for_ole = filename arg_for_zip = filename ole = None try: if olefile.isOleFile(arg_for_ole): if is_ppt(arg_for_ole): log.info('is ppt file: ' + filename) for ole in find_ole_in_ppt(arg_for_ole): yield ole ole = None # is closed in find_ole_in_ppt # in any case: check for embedded stuff in non-sectored streams log.info('is ole file: ' + filename) ole = olefile.OleFileIO(arg_for_ole) yield ole elif is_zipfile(arg_for_zip): log.info('is zip file: ' + filename) zipper = ZipFile(arg_for_zip, 'r') for subfile in zipper.namelist(): head = b'' try: with zipper.open(subfile) as file_handle: head = file_handle.read(len(olefile.MAGIC)) except RuntimeError: log.error('zip is encrypted: ' + filename) yield None continue if head == olefile.MAGIC: log.info(' unzipping ole: ' + subfile) with ZipSubFile(zipper, subfile) as file_handle: try: ole = olefile.OleFileIO(file_handle) yield ole except IOError: log.warning('Error reading data from {0}/{1} or ' 'interpreting it as OLE object'.format( filename, subfile)) log.debug('', exc_info=True) finally: if ole is not None: ole.close() ole = None else: log.debug('unzip skip: ' + subfile) else: log.warning( 'open failed: {0} (or its data) is neither zip nor OLE'.format( filename)) yield None except Exception: log.error('Caught exception opening {0}'.format(filename), exc_info=True) yield None finally: if ole is not None: ole.close()
class TestZipSubFile(unittest.TestCase): """ Tests ZipSubFile """ def setUp(self): self.zipper = ZipFile(ZIP_TEMP_FILE) self.subfile = ZipSubFile(self.zipper, FILE_NAME) self.subfile.open() # create a file in memory for comparison self.compare = TemporaryFile(prefix='oletools-test-ZipSubFile-', suffix='.bin') self.compare.write(FILE_CONTENTS) self.compare.seek(0) # re-position to start self.assertEqual(self.subfile.tell(), 0) self.assertEqual(self.compare.tell(), 0) if DEBUG: print('created comparison file {0!r} in memory' .format(self.compare.name)) def tearDown(self): self.compare.close() self.subfile.close() self.zipper.close() if DEBUG: print('\nall files closed') def test_read(self): """ test reading """ # read from start self.assertEqual(self.subfile.read(4), self.compare.read(4)) self.assertEqual(self.subfile.tell(), self.compare.tell()) # read a bit more self.assertEqual(self.subfile.read(4), self.compare.read(4)) self.assertEqual(self.subfile.tell(), self.compare.tell()) # create difference self.subfile.read(1) self.assertNotEqual(self.subfile.read(4), self.compare.read(4)) self.compare.read(1) self.assertEqual(self.subfile.tell(), self.compare.tell()) # read all the rest self.assertEqual(self.subfile.read(), self.compare.read()) self.assertEqual(self.subfile.tell(), self.compare.tell()) def test_seek_forward(self): """ test seeking forward """ self.subfile.seek(10) self.compare.seek(10) self.assertEqual(self.subfile.read(1), self.compare.read(1)) self.assertEqual(self.subfile.tell(), self.compare.tell()) # seek 2 forward self.subfile.seek(2, os.SEEK_CUR) self.compare.seek(2, os.SEEK_CUR) self.assertEqual(self.subfile.read(1), self.compare.read(1)) self.assertEqual(self.subfile.tell(), self.compare.tell()) # seek backward (only implemented case: back to start) self.subfile.seek(-self.subfile.tell(), os.SEEK_CUR) self.compare.seek(-self.compare.tell(), os.SEEK_CUR) self.assertEqual(self.subfile.read(1), self.compare.read(1)) self.assertEqual(self.subfile.tell(), self.compare.tell()) # seek to end self.subfile.seek(0, os.SEEK_END) self.compare.seek(0, os.SEEK_END) self.assertEqual(self.subfile.tell(), self.compare.tell()) # seek back to start self.subfile.seek(0) self.compare.seek(0) self.assertEqual(self.subfile.tell(), self.compare.tell()) self.assertEqual(self.subfile.tell(), 0) def test_check_size(self): """ test usual size check: seek to end, tell, seek to start """ # seek to end self.subfile.seek(0, os.SEEK_END) self.assertEqual(self.subfile.tell(), len(FILE_CONTENTS)) # seek back to start self.subfile.seek(0) # read first few bytes self.assertEqual(self.subfile.read(10), FILE_CONTENTS[:10]) def test_error_read(self): """ test correct behaviour if read beyond end (no exception) """ self.subfile.seek(0, os.SEEK_END) self.compare.seek(0, os.SEEK_END) self.assertEquals(self.compare.read(10), self.subfile.read(10)) self.assertEquals(self.compare.tell(), self.subfile.tell()) self.subfile.seek(0) self.compare.seek(0) self.subfile.seek(len(FILE_CONTENTS) - 1) self.compare.seek(len(FILE_CONTENTS) - 1) self.assertEquals(self.compare.read(10), self.subfile.read(10)) self.assertEquals(self.compare.tell(), self.subfile.tell()) def test_error_seek(self): """ test correct behaviour if seek beyond end (no exception) """ self.subfile.seek(len(FILE_CONTENTS) + 10) self.compare.seek(len(FILE_CONTENTS) + 10)
class TestZipSubFile(unittest.TestCase): """ Tests ZipSubFile """ def setUp(self): self.zipper = ZipFile(ZIP_TEMP_FILE) self.subfile = ZipSubFile(self.zipper, FILE_NAME) self.subfile.open() # create a file in memory for comparison self.compare = TemporaryFile(prefix='oletools-test-ZipSubFile-', suffix='.bin') self.compare.write(FILE_CONTENTS) self.compare.seek(0) # re-position to start self.assertEqual(self.subfile.tell(), 0) self.assertEqual(self.compare.tell(), 0) if DEBUG: print('created comparison file {0!r} in memory'.format( self.compare.name)) def tearDown(self): self.compare.close() self.subfile.close() self.zipper.close() if DEBUG: print('\nall files closed') def test_read(self): """ test reading """ # read from start self.assertEqual(self.subfile.read(4), self.compare.read(4)) self.assertEqual(self.subfile.tell(), self.compare.tell()) # read a bit more self.assertEqual(self.subfile.read(4), self.compare.read(4)) self.assertEqual(self.subfile.tell(), self.compare.tell()) # create difference self.subfile.read(1) self.assertNotEqual(self.subfile.read(4), self.compare.read(4)) self.compare.read(1) self.assertEqual(self.subfile.tell(), self.compare.tell()) # read all the rest self.assertEqual(self.subfile.read(), self.compare.read()) self.assertEqual(self.subfile.tell(), self.compare.tell()) def test_seek_forward(self): """ test seeking forward """ self.subfile.seek(10) self.compare.seek(10) self.assertEqual(self.subfile.read(1), self.compare.read(1)) self.assertEqual(self.subfile.tell(), self.compare.tell()) # seek 2 forward self.subfile.seek(2, os.SEEK_CUR) self.compare.seek(2, os.SEEK_CUR) self.assertEqual(self.subfile.read(1), self.compare.read(1)) self.assertEqual(self.subfile.tell(), self.compare.tell()) # seek backward (only implemented case: back to start) self.subfile.seek(-self.subfile.tell(), os.SEEK_CUR) self.compare.seek(-self.compare.tell(), os.SEEK_CUR) self.assertEqual(self.subfile.read(1), self.compare.read(1)) self.assertEqual(self.subfile.tell(), self.compare.tell()) # seek to end self.subfile.seek(0, os.SEEK_END) self.compare.seek(0, os.SEEK_END) self.assertEqual(self.subfile.tell(), self.compare.tell()) # seek back to start self.subfile.seek(0) self.compare.seek(0) self.assertEqual(self.subfile.tell(), self.compare.tell()) self.assertEqual(self.subfile.tell(), 0) def test_check_size(self): """ test usual size check: seek to end, tell, seek to start """ # seek to end self.subfile.seek(0, os.SEEK_END) self.assertEqual(self.subfile.tell(), len(FILE_CONTENTS)) # seek back to start self.subfile.seek(0) # read first few bytes self.assertEqual(self.subfile.read(10), FILE_CONTENTS[:10]) def test_error_read(self): """ test correct behaviour if read beyond end (no exception) """ self.subfile.seek(0, os.SEEK_END) self.compare.seek(0, os.SEEK_END) self.assertEqual(self.compare.read(10), self.subfile.read(10)) self.assertEqual(self.compare.tell(), self.subfile.tell()) self.subfile.seek(0) self.compare.seek(0) self.subfile.seek(len(FILE_CONTENTS) - 1) self.compare.seek(len(FILE_CONTENTS) - 1) self.assertEqual(self.compare.read(10), self.subfile.read(10)) self.assertEqual(self.compare.tell(), self.subfile.tell()) def test_error_seek(self): """ test correct behaviour if seek beyond end (no exception) """ self.subfile.seek(len(FILE_CONTENTS) + 10) self.compare.seek(len(FILE_CONTENTS) + 10)