From f97b4d88f0254588d11b8760fc6714828af0ef28 Mon Sep 17 00:00:00 2001 From: jvoisin Date: Sat, 5 Oct 2013 20:46:24 +0100 Subject: mat is now able to check non-writables files This is an implementaion of this suggestion: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=721572 --- MAT/archive.py | 12 ++++++------ MAT/exiftool.py | 4 ++-- MAT/mat.py | 7 ++----- MAT/misc.py | 4 ++-- MAT/mutagenstripper.py | 4 ++-- MAT/office.py | 8 ++++---- MAT/parser.py | 3 ++- mat | 3 +++ mat-gui | 4 +++- test/clitest.py | 2 +- 10 files changed, 27 insertions(+), 24 deletions(-) diff --git a/MAT/archive.py b/MAT/archive.py index f7b5783..447f068 100644 --- a/MAT/archive.py +++ b/MAT/archive.py @@ -17,8 +17,8 @@ class GenericArchiveStripper(parser.GenericParser): ''' Represent a generic archive ''' - def __init__(self, filename, parser, mime, backup, **kwargs): - super(GenericArchiveStripper, self).__init__(filename, parser, mime, backup, **kwargs) + def __init__(self, filename, parser, mime, backup, is_writable, **kwargs): + super(GenericArchiveStripper, self).__init__(filename, parser, mime, backup, is_writable, **kwargs) self.compression = '' self.add2archive = kwargs['add2archive'] self.tempdir = tempfile.mkdtemp() @@ -251,8 +251,8 @@ class GzipStripper(TarStripper): ''' Represent a tar.gz archive ''' - def __init__(self, filename, parser, mime, backup, **kwargs): - super(GzipStripper, self).__init__(filename, parser, mime, backup, **kwargs) + def __init__(self, filename, parser, mime, backup, is_writable, **kwargs): + super(GzipStripper, self).__init__(filename, parser, mime, backup, is_writable, **kwargs) self.compression = ':gz' @@ -260,6 +260,6 @@ class Bzip2Stripper(TarStripper): ''' Represents a tar.bz2 archive ''' - def __init__(self, filename, parser, mime, backup, **kwargs): - super(Bzip2Stripper, self).__init__(filename, parser, mime, backup, **kwargs) + def __init__(self, filename, parser, mime, backup, is_writable, **kwargs): + super(Bzip2Stripper, self).__init__(filename, parser, mime, backup, is_writable, **kwargs) self.compression = ':bz2' diff --git a/MAT/exiftool.py b/MAT/exiftool.py index 16e383f..9803aa9 100644 --- a/MAT/exiftool.py +++ b/MAT/exiftool.py @@ -12,8 +12,8 @@ class ExiftoolStripper(parser.GenericParser): A generic stripper class using exiftool as backend ''' - def __init__(self, filename, parser, mime, backup, **kwargs): - super(ExiftoolStripper, self).__init__(filename, parser, mime, backup, **kwargs) + def __init__(self, filename, parser, mime, backup, is_writable, **kwargs): + super(ExiftoolStripper, self).__init__(filename, parser, mime, backup, is_writable, **kwargs) self.allowed = set(['ExifTool Version Number', 'File Name', 'Directory', 'File Size', 'File Modification Date/Time', 'File Access Date/Time', 'File Permissions', 'File Type', 'MIME Type', 'Image Width', 'Image Height', diff --git a/MAT/mat.py b/MAT/mat.py index c692a6a..ffe97ea 100644 --- a/MAT/mat.py +++ b/MAT/mat.py @@ -140,10 +140,7 @@ def create_class_file(name, backup, **kwargs): logging.error('%s is is not readable' % name) return None - if not os.access(name, os.W_OK): - #check write permission - logging.error('%s is not writable' % name) - return None + is_writable = os.access(name, os.W_OK) if not os.path.getsize(name): #check if the file is not empty (hachoir crash on empty files) @@ -178,4 +175,4 @@ def create_class_file(name, backup, **kwargs): logging.info('Don\'t have stripper for %s format' % mime) return None - return stripper_class(filename, parser, mime, backup, **kwargs) + return stripper_class(filename, parser, mime, backup, is_writable, **kwargs) diff --git a/MAT/misc.py b/MAT/misc.py index 4c104a8..e016d18 100644 --- a/MAT/misc.py +++ b/MAT/misc.py @@ -12,8 +12,8 @@ class TorrentStripper(parser.GenericParser): Represent a torrent file with the help of the bencode lib from Petru Paler ''' - def __init__(self, filename, parser, mime, backup, **kwargs): - super(TorrentStripper, self).__init__(filename, parser, mime, backup) + def __init__(self, filename, parser, mime, backup, is_writable, **kwargs): + super(TorrentStripper, self).__init__(filename, parser, mime, backup, is_writable, **kwargs) self.fields = ['comment', 'creation date', 'created by'] def is_clean(self): diff --git a/MAT/mutagenstripper.py b/MAT/mutagenstripper.py index 9d82a30..ebc6b91 100644 --- a/MAT/mutagenstripper.py +++ b/MAT/mutagenstripper.py @@ -3,8 +3,8 @@ import shutil class MutagenStripper(parser.GenericParser): - def __init__(self, filename, parser, mime, backup, **kwargs): - super(MutagenStripper, self).__init__(filename, parser, mime, backup, **kwargs) + def __init__(self, filename, parser, mime, backup, is_writable, **kwargs): + super(MutagenStripper, self).__init__(filename, parser, mime, backup, is_writable, **kwargs) self._create_mfile() def _create_mfile(self): diff --git a/MAT/office.py b/MAT/office.py index 50a4282..c44a52b 100644 --- a/MAT/office.py +++ b/MAT/office.py @@ -111,7 +111,7 @@ class OpenDocumentStripper(archive.GenericArchiveStripper): zipin.getinfo('meta.xml') except KeyError: # no meta.xml in the file czf = archive.ZipStripper(self.filename, self.parser, - 'application/zip', False, add2archive=self.add2archive) + 'application/zip', False, True, add2archive=self.add2archive) if czf.is_clean(): zipin.close() return True @@ -123,8 +123,8 @@ class PdfStripper(parser.GenericParser): ''' Represent a PDF file ''' - def __init__(self, filename, parser, mime, backup, **kwargs): - super(PdfStripper, self).__init__(filename, parser, mime, backup, **kwargs) + def __init__(self, filename, parser, mime, backup, is_writable, **kwargs): + super(PdfStripper, self).__init__(filename, parser, mime, backup, is_writable, **kwargs) uri = 'file://' + os.path.abspath(self.filename) self.password = None try: @@ -257,7 +257,7 @@ class OpenXmlStripper(archive.GenericArchiveStripper): return False zipin.close() czf = archive.ZipStripper(self.filename, self.parser, - 'application/zip', False, add2archive=self.add2archive) + 'application/zip', False, True, add2archive=self.add2archive) return czf.is_clean() def get_meta(self): diff --git a/MAT/parser.py b/MAT/parser.py index 949e24b..c57eb00 100644 --- a/MAT/parser.py +++ b/MAT/parser.py @@ -25,11 +25,12 @@ class GenericParser(object): ''' Parent class of all parsers ''' - def __init__(self, filename, parser, mime, backup, **kwargs): + def __init__(self, filename, parser, mime, backup, is_writable, **kwargs): self.filename = '' self.parser = parser self.mime = mime self.backup = backup + self.is_writable = is_writable self.editor = hachoir_editor.createEditor(parser) try: self.filename = hachoir_core.cmd_line.unicodeFilename(filename) diff --git a/mat b/mat index 60c6e5d..a22e3c5 100755 --- a/mat +++ b/mat @@ -88,6 +88,9 @@ def clean_meta(class_file, filename, force): ''' Clean the file 'filename' ''' + if not class_file.is_writable: + print('[-] %s is not writable' % filename) + return print('[+] Cleaning %s' % filename) if not force and class_file.is_clean(): print('%s is already clean' % filename) diff --git a/mat-gui b/mat-gui index 4371521..3ff9670 100755 --- a/mat-gui +++ b/mat-gui @@ -279,7 +279,9 @@ non-anonymised) file to output archive')) ''' cf = CFile(filename, add2archive=self.add2archive, low_pdf_quality=self.pdf_quality) - if cf.file: # if the file is supported by the mat + # if the file is supported by the mat, + # and is writable (for usability's sake). + if cf.file and cf.file.is_writable: self.liststore.append([cf, cf.file.basename, _('Unknown')]) return False return True diff --git a/test/clitest.py b/test/clitest.py index 31e9015..1e552ba 100644 --- a/test/clitest.py +++ b/test/clitest.py @@ -86,7 +86,7 @@ class TestFileAttributes(unittest.TestCase): proc = subprocess.Popen(['../mat', 'not_writtable'], stdout=subprocess.PIPE) stdout, _ = proc.communicate() - self.assertEqual(str(stdout).strip('\n'), 'Unable to process %s' % 'not_writtable') + self.assertEqual(str(stdout).strip('\n'), '[-] %s is not writable' % 'not_writtable') def test_not_exist(self): ''' test MAT's behaviour on non-existent file''' -- cgit v1.3