diff --git a/HISTORY.rst b/HISTORY.rst index 832717249a..2ec23cd249 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -253,6 +253,9 @@ - Remove django-mathfilters from requirements. These tags are provided by default by Jinja2 template engine (http://jinja.pocoo.org/docs/2.10/templates/#math). +- Reject emails attachments of size 0. Thanks to Robert Schoeftner + (@robert.schoeftner)for the report and solution. GitLab issue #574. + 3.1.9 (2018-11-01) ================== diff --git a/mayan/apps/sources/models/email_sources.py b/mayan/apps/sources/models/email_sources.py index 7c83a9d22a..825ad4c55e 100644 --- a/mayan/apps/sources/models/email_sources.py +++ b/mayan/apps/sources/models/email_sources.py @@ -121,6 +121,11 @@ class EmailBaseModel(IntervalBaseModel): # Treat inlines as attachments, both are extracted and saved as # documents if message.is_attachment() or message.is_inline(): + + # Reject zero length attachments + if len(message.body) == 0: + return + label = message.detected_file_name or 'attachment-{}'.format(counter) with ContentFile(content=message.body, name=label) as file_object: if label == source.metadata_attachment_name: diff --git a/mayan/apps/sources/tests/literals.py b/mayan/apps/sources/tests/literals.py index 4efdfaeb6a..5ab77120db 100644 --- a/mayan/apps/sources/tests/literals.py +++ b/mayan/apps/sources/tests/literals.py @@ -109,6 +109,31 @@ AAALewAAC3sBSRnwgAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAALnSURB QCDLAIEsAwSyDBDIMkAgywCBLAMEsgwQyDJAIMsAgSwDBLIMEMgyQCDLAIEsAwSyDBDIMkAg6wK+ 4gU280YtuwAAAABJRU5ErkJggg== --089e0149bb0ea4e55c051712afb5--''' +TEST_EMAIL_ZERO_LENGTH_ATTACHMENT = '''From rosarior@localhost Tue Apr 2 23:40:26 2019 +Received: from rosarior (uid 1000) + (envelope-from rosarior@localhost) + id 2011e6 + by localhost (DragonFly Mail Agent v0.11); + Tue, 02 Apr 2019 23:40:26 -0400 +Message-ID: <22514.1554262827@localhost> +Mime-Version: 1.0 +To: rosarior@localhost +Subject: mpack +Content-Type: multipart/mixed; boundary="-" +Date: Tue, 02 Apr 2019 23:40:26 -0400 +From: + +This is a MIME encoded message. Decode it with "munpack" +or any other MIME reading software. Mpack/munpack is available +via anonymous FTP in ftp.andrew.cmu.edu:pub/mpack/ +--- +Content-Type: application/octet-stream; name="zero" +Content-Transfer-Encoding: base64 +Content-Disposition: inline; filename="zero" +Content-MD5: 1B2M2Y8AsgTpgAmY7PhCfg== + + +-----''' TEST_SOURCE_LABEL = 'test source' TEST_SOURCE_UNCOMPRESS_N = 'n' TEST_STAGING_PREVIEW_WIDTH = 640 diff --git a/mayan/apps/sources/tests/test_models.py b/mayan/apps/sources/tests/test_models.py index 9947edc461..8771027d01 100644 --- a/mayan/apps/sources/tests/test_models.py +++ b/mayan/apps/sources/tests/test_models.py @@ -26,7 +26,8 @@ from .literals import ( TEST_EMAIL_ATTACHMENT_AND_INLINE, TEST_EMAIL_BASE64_FILENAME, TEST_EMAIL_BASE64_FILENAME_FROM, TEST_EMAIL_BASE64_FILENAME_SUBJECT, TEST_EMAIL_INLINE_IMAGE, TEST_EMAIL_NO_CONTENT_TYPE, - TEST_EMAIL_NO_CONTENT_TYPE_STRING, TEST_WATCHFOLDER_SUBFOLDER + TEST_EMAIL_NO_CONTENT_TYPE_STRING, TEST_WATCHFOLDER_SUBFOLDER, + TEST_EMAIL_ZERO_LENGTH_ATTACHMENT ) @@ -105,6 +106,17 @@ class EmailFilenameDecodingTestCase(BaseTestCase): TEST_EMAIL_NO_CONTENT_TYPE_STRING in Document.objects.first().open().read() ) + def test_decode_email_zero_length_attachment(self): + self._create_email_source() + self.source.store_body=False + self.source.save() + + EmailBaseModel.process_message( + source=self.source, message_text=TEST_EMAIL_ZERO_LENGTH_ATTACHMENT + ) + + self.assertEqual(Document.objects.count(), 0) + def test_decode_email_with_inline_image(self): self._create_email_source() EmailBaseModel.process_message( @@ -130,7 +142,6 @@ class EmailFilenameDecodingTestCase(BaseTestCase): self.assertQuerysetEqual( ordered=False, qs=Document.objects.all(), values=( '', '', - '' ), ) @@ -175,8 +186,8 @@ class EmailFilenameDecodingTestCase(BaseTestCase): source=self.source, message_text=TEST_EMAIL_ATTACHMENT_AND_INLINE ) - # Only two attachments, no body document - self.assertEqual(2, Document.objects.count()) + # Only one attachment, no body document + self.assertEqual(1, Document.objects.count()) def test_document_upload_with_body(self): self._create_email_source() @@ -189,7 +200,7 @@ class EmailFilenameDecodingTestCase(BaseTestCase): ) # Only two attachments and a body document - self.assertEqual(3, Document.objects.count()) + self.assertEqual(2, Document.objects.count()) class POP3SourceTestCase(BaseTestCase):