From 433609f8eadc05ec6aceeb2b71951cc6db318d81 Mon Sep 17 00:00:00 2001
From: jvoisin <julien.voisin@dustri.org>
Date: Sun, 3 Feb 2019 21:01:58 +0100
Subject: [PATCH] Implement .gif support

---
 libmat2/images.py     |  15 +++++++++++++++
 tests/data/dirty.gif  | Bin 0 -> 1127 bytes
 tests/test_libmat2.py |  24 ++++++++++++++++++++++++
 3 files changed, 39 insertions(+)
 create mode 100644 tests/data/dirty.gif

diff --git a/libmat2/images.py b/libmat2/images.py
index 153a83d..dd3be53 100644
--- a/libmat2/images.py
+++ b/libmat2/images.py
@@ -42,6 +42,21 @@ class PNGParser(exiftool.ExiftoolParser):
         return True
 
 
+class GIFParser(exiftool.ExiftoolParser):
+    mimetypes = {'image/gif'}
+    meta_whitelist = {'AnimationIterations', 'BackgroundColor', 'BitsPerPixel',
+                      'ColorResolutionDepth', 'Directory', 'Duration',
+                      'ExifToolVersion', 'FileAccessDate',
+                      'FileInodeChangeDate', 'FileModifyDate', 'FileName',
+                      'FilePermissions', 'FileSize', 'FileType',
+                      'FileTypeExtension', 'FrameCount', 'GIFVersion',
+                      'HasColorMap', 'ImageHeight', 'ImageSize', 'ImageWidth',
+                      'MIMEType', 'Megapixels', 'SourceFile',}
+
+    def remove_all(self) -> bool:
+        return self._lightweight_cleanup()
+
+
 class GdkPixbufAbstractParser(exiftool.ExiftoolParser):
     """ GdkPixbuf can handle a lot of surfaces, so we're rending images on it,
         this has the side-effect of completely removing metadata.
diff --git a/tests/data/dirty.gif b/tests/data/dirty.gif
new file mode 100644
index 0000000000000000000000000000000000000000..217f90998b05386a0a709727d72c5acc018de928
GIT binary patch
literal 1127
zcmZ?wbhEHbG-5Df_{75S|NqSYAdvQ-0R<@j=k{|A33hf2a5d61U}j`sU{L(Y!otPy
zpF#1TSV=}^u|j6CLZU)RYH^7|a(-@ZYF-J04#)_Q!3<2bJ^d?BzvW*%XUnbb&G+{F
z=5KrCG3{CBvR9|Jz2iRq$>;h(0sde6n6>z27+9Qx1uT5H3Kl6(;9z|*>s(yP$v+`$
zy<T3~{IqmqykAB6*J-BddLkKluNNKMQIoyj+Wc3+KK|qE6<^GEv?WG_b8t+nI5ABk
z$>XR;W%`wG!Kr~@x3Y3EurlbdG6*s#Gbl1JFy~9`x?`(%%5v3S<ISgcPK$j}+no`$
zq-fqtEvBo_%a{VV1I&uc<~Q#?eO8Q_O?z*YVbK<zLVI^%%NV<5N?h9(-%aX?du^&C
zS8e)4qvF<~WlXot_h{;$eHA2JcmDnF{|$}uEG?~V?Hz5BojtuQlANIMV&!6B0l9&P
zL5V?)fq^*->;^B88`huR*%$kwwksnlrC{EZU0Lg9AJuogey-PkSLSyyMlJR|3~eq8
z7&eIft2(2>5|U%I+;fHKY~7;Wt~0*>zOr<WW~lz&&W#6WY_IWKfBXH9Js>x{XK8F|
zZfVhM?dT9jvYv~9jX@R^H_SN_yY5^zIOMo`>W!@4oBv|i`lfg^U8?kZ^=j)A?&GK4
zu$lEfe{rt9Tb{LG<zEJ-l#?gC)u!*03Hr%lwmfw8m6=!1&1txDe#+|)R&lacvQfM5
zf7pR!{r`r>0#FdN7Pfb_NFX_Yhk=nnn!%8PfjLED*PhD;n;ch9y_nT|73zQsFb8~&
zx?Enz{_FVnIr9`&F!N|{n#IuIbFSx1`{Ohn(>(8&Tf?S4v9cGP(JD3j{EIDBXY)`T
zP%r$iA+MoP2xc)WgAT&t42fNL{u!L|T)lTj-<`Jq4_NyiyUcsqyl(!fb?1H?ZQ66C
zxZ(EiJDYdS{~#{I<aC(PVZ#@ZdY@&+J9F~p?SAo5Z4K8tu7zf1C7g=soPI2iccA!O
zo1>wzsZp%Ctw9jUazwCa!!5VSwk?xR&`3*)3`?tW%aY!d$9;68^X2<*jjYyv*(x8P
zCey~UzF{Maht_l^2a%l-d`oWl6<SQqn(vnLg?rni(_ynKx3x&B=6ChEe7OOQ_5Woo
zP0cN>t%7ZxoyhjHGQd(@F~a`Ww%cS9G^)BXX5Cu3=-R8cx39xKaWw?jaxv(a2+m#U
z&SKZ17SCVq($-<K?673ezaCyKj;h0YTQ;lBFqNIW`PoE^x2YR$=arrFVLrY^yvEIg
dYtOF+P^xR?X6fkc>h9?h?42-?MUa!h8UVax<SzgK

literal 0
HcmV?d00001

diff --git a/tests/test_libmat2.py b/tests/test_libmat2.py
index 9152b2f..9354286 100644
--- a/tests/test_libmat2.py
+++ b/tests/test_libmat2.py
@@ -171,6 +171,12 @@ class TestGetMeta(unittest.TestCase):
         meta = p.get_meta()
         self.assertEqual(meta['EncodingSettings'], 'Lavf52.103.0')
 
+    def test_gif(self):
+        p, mimetype = parser_factory.get_parser('./tests/data/dirty.gif')
+        self.assertEqual(mimetype, 'image/gif')
+        meta = p.get_meta()
+        self.assertEqual(meta['Comment'], 'this is a test comment')
+
 class TestRemovingThumbnails(unittest.TestCase):
     def test_odt(self):
         shutil.copy('./tests/data/revision.odt', './tests/data/clean.odt')
@@ -572,3 +578,21 @@ class TestCleaning(unittest.TestCase):
         os.remove('./tests/data/clean.wmv')
         os.remove('./tests/data/clean.cleaned.wmv')
         os.remove('./tests/data/clean.cleaned.cleaned.wmv')
+
+    def test_gif(self):
+        shutil.copy('./tests/data/dirty.gif', './tests/data/clean.gif')
+        p = images.GIFParser('./tests/data/clean.gif')
+
+        meta = p.get_meta()
+        self.assertEqual(meta['Comment'], 'this is a test comment')
+
+        ret = p.remove_all()
+        self.assertTrue(ret)
+
+        p = images.GIFParser('./tests/data/clean.cleaned.gif')
+        self.assertNotIn('EncodingSettings', p.get_meta())
+        self.assertTrue(p.remove_all())
+
+        os.remove('./tests/data/clean.gif')
+        os.remove('./tests/data/clean.cleaned.gif')
+        os.remove('./tests/data/clean.cleaned.cleaned.gif')
-- 
GitLab