def test_7zextract_bytesio(self): """Test 7z file extraction from object""" from fuglu.extensions.filearchives import Archivehandle, SEVENZIP_AVAILABLE if not SEVENZIP_AVAILABLE > 0: print( "=============================================================" ) print( "== WARNING ==" ) print( "== Skipping 7z extract test since library is not installed ==" ) print( "=============================================================" ) return archive_filename = join(unittestsetup.TESTDATADIR, "test.7z") # -- # use BytesIO as done in attachment manager # -- with open(archive_filename, 'rb') as f: buffer = f.read() buffer = BytesIO(buffer) print("Type of buffer sent to Archivehandler is: %s" % type(buffer)) handle = Archivehandle('7z', buffer) self.runArchiveChecks(handle) handle.close()
def test_7zextract_filename(self): """Test 7z file extraction from filename""" from fuglu.extensions.filearchives import Archivehandle, SEVENZIP_AVAILABLE if not SEVENZIP_AVAILABLE > 0: print( "=============================================================" ) print( "== WARNING ==" ) print( "== Skipping 7z extract test since library is not installed ==" ) print( "=============================================================" ) return # -- # use filename # -- archive_filename = join(unittestsetup.TESTDATADIR, "test.7z") handle = Archivehandle('7z', archive_filename) self.runArchiveChecks(handle) handle.close()
def test_7zextract_fileobject(self): """Test 7z file extraction from object""" from fuglu.extensions.filearchives import Archivehandle, SEVENZIP_AVAILABLE if not SEVENZIP_AVAILABLE > 0: print( "=============================================================" ) print( "== WARNING ==" ) print( "== Skipping 7z extract test since library is not installed ==" ) print( "=============================================================" ) return archive_filename = join(unittestsetup.TESTDATADIR, "test.7z") # -- # use file descriptor # -- f = open(archive_filename, 'rb') try: handle = Archivehandle('7z', f) self.runArchiveChecks(handle) handle.close() finally: f.close()
def test_rarfileextract_unicode_password2(self): """Test rar file extraction for encrypted (files and filelist) rar""" from fuglu.extensions.filearchives import Archivehandle, RARFILE_AVAILABLE if not RARFILE_AVAILABLE > 0: print( "==============================================================" ) print( "== WARNING ==" ) print( "== Skipping rar extract test since library is not installed ==" ) print( "==============================================================" ) return archive_filename = join(unittestsetup.TESTDATADIR, "password2.rar") # -- # use filename # -- handle = Archivehandle('rar', archive_filename) archive_flist = handle.namelist() self.assertEqual([], archive_flist) handle.close()
def lint_archivetypes(self): if not Archivehandle.avail('rar'): print("rarfile library not found, RAR support disabled") if not Archivehandle.avail('7z'): print("pylzma/py7zlip library not found, 7z support disabled") print("Archive scan, available file extensions: %s" % (",".join(sorted(Archivehandle.avail_archive_extensions_list)))) print("Archive scan, active file extensions: %s" % (",".join(sorted(self.active_archive_extensions.keys())))) return True
def test_7zextract_bytesio_fullyencrypted(self): """Test 7z file extraction from object (encrypted including filenames)""" from fuglu.extensions.filearchives import Archivehandle, SEVENZIP_AVAILABLE if not SEVENZIP_AVAILABLE > 0: print("================================================") print("== WARNING ==") print("== Skipping 7z bytesio encrypted extract test ==") print("== since library is not installed ==") print("================================================") return from py7zlib import NoPasswordGivenError archive_filename = join(unittestsetup.TESTDATADIR, "test.enc_filenames.p_is_secret.7z") # -- # use BytesIO as done in attachment manager # -- with open(archive_filename, 'rb') as f: buffer = f.read() buffer = BytesIO(buffer) # 7z a test.enc_filenames.p_is_secret.7z -psecret -mhe test.txt # compresses *.txt files to archive .7 z using password "secret". It also encrypts archive headers(-mhe switch), # so filenames will be encrypted. This raises an exception already when creating the handle. with self.assertRaises(NoPasswordGivenError): _ = Archivehandle('7z', buffer)
def archive_handle(self): """ (Cached Property-Getter) Create an archive handle to check, extract, ... files in the buffered archive. Internal: - archive_type: The archive type (already detected) - buffer: The file buffer containing the archive Returns: (Archivehandle) : The handle to work with the archive """ # make sure there's no buffered archive object when # the archive handle is created (or overwritten) self._buffer_archobj = {} handle = None if self.buffer is not None: try: handle = Archivehandle(self.archive_type, BytesIO(self.buffer), archivename=self.filename) except Exception as e: self.logger.error( "%s, Problem creating Archivehandle for file: " "%s using archive handler %s (message: %s) -> ignore" % (self.fugluid, self.filename, str( self.archive_type), force_uString(e))) return handle
def archive_type(self): """ (Cached Property-Getter) Stores the archive type stored in this object. Internal member dependencies: - contenttype: File content type - filename: Filename (Extension might be used to detect archive type) Returns: (str): Archive type if object is an archive, None otherwise """ self._arext = None # try guessing the archive type based on magic content type first archive_type = Archivehandle.archive_type_from_content_type( self.contenttype) # if it didn't work, try to guess by the filename extension, if it is enabled if archive_type is None: # sort by length, so tar.gz is checked before .gz for arext in Archivehandle.avail_archive_extensions_list: if self.filename.lower().endswith('.%s' % arext): archive_type = Archivehandle.avail_archive_extensions[ arext] # store archive extension for internal use self._arext = arext break return archive_type
def test_7z_unavailable(self): """Tests what happens if 7z is not available""" # patch system modules import dict to make sure importing py7zlib module fails with patch.dict('sys.modules', {'py7zlib': None}): from fuglu.extensions.filearchives import Archivehandle self.assertFalse( Archivehandle.avail('7z'), "7z archive should be unavailable!%s" % importMockingMessage) #-----------# # extension # #-----------# extensionsHandles = ["7z"] # archive extensions for ext in extensionsHandles: self.assertFalse( ext in Archivehandle.avail_archive_extensions_list, "archives with ending '%s' can not be handled (%s)!" % (ext, Archivehandle.avail_archive_extensions_list)) #---------# # content # #---------# contentHandles = ['^application\/x-7z-compressed'] # mail content regex as used in attachment for cnt in contentHandles: self.assertFalse( cnt in Archivehandle.avail_archive_ctypes_list, "content regex '%s' can not be handled (%s)" % (cnt, Archivehandle.avail_archive_ctypes_list))
def test_rarfileextract_emptydir(self): """Test rar file extraction for encrypted (only files and not filelist) rar""" from fuglu.extensions.filearchives import Archivehandle, RARFILE_AVAILABLE if not RARFILE_AVAILABLE > 0: print( "==============================================================" ) print( "== WARNING ==" ) print( "== Skipping rar extract test since library is not installed ==" ) print( "==============================================================" ) return archive_filename = join(unittestsetup.TESTDATADIR, "EmptyDir.rar") # -- # use filename # -- handle = Archivehandle('rar', archive_filename) archive_flist = handle.namelist() self.assertEqual([u"EmptyDir"], archive_flist) with self.assertRaises(TypeError): handle.extract(archive_flist[0], None) handle.close()
def test_rarfileextract_unicode_password(self): """Test rar file extraction for encrypted (only files and not filelist) rar""" from fuglu.extensions.filearchives import Archivehandle, RARFILE_AVAILABLE if not RARFILE_AVAILABLE > 0: print( "==============================================================" ) print( "== WARNING ==" ) print( "== Skipping rar extract test since library is not installed ==" ) print( "==============================================================" ) return import rarfile archive_filename = join(unittestsetup.TESTDATADIR, "password.rar") # -- # use filename # -- handle = Archivehandle('rar', archive_filename) archive_flist = handle.namelist() self.assertEqual([u"One Földer/Hélö Wörld.txt", u"One Földer"], archive_flist) with self.assertRaises(rarfile.PasswordRequired): handle.extract(archive_flist[0], None) handle.close()
def test_7zextract_bytesio_encrypted(self): """Test 7z file extraction from object (encrypted)""" from fuglu.extensions.filearchives import Archivehandle, SEVENZIP_AVAILABLE if not SEVENZIP_AVAILABLE > 0: print("================================================") print("== WARNING ==") print("== Skipping 7z bytesio encrypted extract test ==") print("== since library is not installed ==") print("================================================") return from py7zlib import NoPasswordGivenError archive_filename = join(unittestsetup.TESTDATADIR, "test.p_is_secret.7z") # -- # use BytesIO as done in attachment manager # -- with open(archive_filename, 'rb') as f: buffer = f.read() buffer = BytesIO(buffer) handle = Archivehandle('7z', buffer) # even though the file is password protected, the filelist is not # so it's possible to extract the file list without an exception archive_flist = handle.namelist() self.assertEqual(["test.txt"], archive_flist) # it is however not possible to extract the file with self.assertRaises(NoPasswordGivenError): extracted = handle.extract(archive_flist[0], 500000) handle.close()
def test_7z_available(self): """Tests if '7z' archive is correctly detected and assigned to file extension/content""" # patch system modules import dict to make sure importing "py7zlib" module is success # ("py7zlib" is just a mock, but only successful import is needed for this test...) mock = MagicMock() with patch.dict('sys.modules', {'py7zlib': mock}): from fuglu.extensions.filearchives import Archivehandle self.assertTrue( Archivehandle.avail('7z'), "7z archive should unavailable!%s" % importMockingMessage) #-----------# # extension # #-----------# extensionsHandles = ["7z"] # archive extensions for ext in extensionsHandles: self.assertTrue( ext in Archivehandle.avail_archive_extensions_list, "archives with ending '%s' has to be handled (%s)!" % (ext, Archivehandle.avail_archive_extensions_list)) # archive extension assignment to '7z' for ext in extensionsHandles: self.assertEqual( "7z", Archivehandle.avail_archive_extensions[ext], "'%s' file endings has to be handled by '7z' archive" % ext) #---------# # content # #---------# contentHandles = ['^application\/x-7z-compressed'] # mail content regex as used in attachment for cnt in contentHandles: self.assertTrue( cnt in Archivehandle.avail_archive_ctypes_list, "content regex '%s' has to be handled (%s)" % (cnt, Archivehandle.avail_archive_ctypes_list)) # mail content regex assigned to 'rar' as used in attachment for cnt in contentHandles: self.assertEqual( "7z", Archivehandle.avail_archive_ctypes[cnt], "'%s' content regex has to be handled by 'rar' archive" % cnt)
def test_rarfileextract(self): """Test rar file extraction""" from fuglu.extensions.filearchives import Archivehandle, RARFILE_AVAILABLE if not RARFILE_AVAILABLE > 0: print( "==============================================================" ) print( "== WARNING ==" ) print( "== Skipping rar extract test since library is not installed ==" ) print( "==============================================================" ) return archive_filename = join(unittestsetup.TESTDATADIR, "test.rar") # -- # use filename # -- handle = Archivehandle('rar', archive_filename) self.runArchiveChecks(handle) handle.close() # -- # use file descriptor # -- f = open(archive_filename, 'rb') try: handle = Archivehandle('rar', f) self.runArchiveChecks(handle) handle.close() finally: f.close()
def test_tarfileextract_bz2(self): """Test rar file extraction""" from fuglu.extensions.filearchives import Archivehandle # -- # use filename # -- archive_filename = join(unittestsetup.TESTDATADIR, "test.tar.bz2") handle = Archivehandle('tar', archive_filename) self.runArchiveChecks(handle) handle.close() # -- # use file descriptor # -- f = open(archive_filename, 'rb') try: handle = Archivehandle('tar', f) self.runArchiveChecks(handle) handle.close() finally: f.close()
def test_rarfileextract_unicode(self): """Test rar file extraction""" from fuglu.extensions.filearchives import Archivehandle, RARFILE_AVAILABLE if not RARFILE_AVAILABLE > 0: print( "==============================================================" ) print( "== WARNING ==" ) print( "== Skipping rar extract test since library is not installed ==" ) print( "==============================================================" ) return fsystemencoding = sys.getfilesystemencoding().lower() if not fsystemencoding == "utf-8": # with gitlab-runner (at least locally) the filesystem is "ascii" and this test # fails because of the filename being unicode print( "==================================================================" ) print( "== WARNING ==" ) print( "== Skipping rar extract unicode test because the file ==" ) print( "== is not unicode: %s ==" % fsystemencoding) print( "== Test will only run if: ==" ) print( "== \"python -c \"import sys; print(sys.getfilesystemencoding())\"\" ==" ) print( "== returns utf-8 ==" ) print( "==================================================================" ) return archive_filename = force_uString( join(unittestsetup.TESTDATADIR, u"One Földer.rar")) # -- # use filename # -- print(u"filesystem encoding support: %s" % sys.getfilesystemencoding()) print(u"file %s exists: %s" % (archive_filename, exists(archive_filename))) handle = Archivehandle('rar', archive_filename) archive_flist = handle.namelist() self.assertEqual([u"One Földer/Hélö Wörld.txt", u"One Földer"], archive_flist) extracted = handle.extract(archive_flist[0], None) self.assertEqual(u"bla bla bla\n", force_uString(extracted)) handle.close()