Commit f3bd0565 authored by Arkadiusz Hiler's avatar Arkadiusz Hiler

mboxviews: Use QP for payloads with lines over 78 characters

RFC 5322 requires us to not have lines longer than 998 characters and
strongly suggests that we should impose even stricter limitation of 78
characters.

Let's follow that recommendation and use quoted-printable transfer
encoding if any line of payload is longer than 78 characters.
Reported-by: Petri Latvala's avatarPetri Latvala <petri.latvala@intel.com>
Signed-off-by: default avatarArkadiusz Hiler <arkadiusz.hiler@intel.com>
parent bc734cd9
Pipeline #136460 passed with stage
in 1 minute and 29 seconds
...@@ -365,3 +365,44 @@ class MboxCommentPostcriptUnchangedTest(TestCase): ...@@ -365,3 +365,44 @@ class MboxCommentPostcriptUnchangedTest(TestCase):
self.assertContains(response, self.txt) self.assertContains(response, self.txt)
self.txt += "\n" self.txt += "\n"
self.assertNotContains(response, self.txt) self.assertNotContains(response, self.txt)
class MboxEncoding(TestCase):
fixtures = ['default_states', 'default_events']
def create_patch(self, message, diff):
patch = Patch(project=defaults.project,
msgid='p1', name='testpatch',
submitter=self.person, content=diff)
patch.save()
comment = Comment(patch=patch, msgid='p1',
submitter=self.person,
content=message)
comment.save()
return patch
def setUp(self):
defaults.project.save()
self.person = defaults.patch_author_person
self.person.save()
def testQuotedPrintableIfLineOver78(self):
patch = self.create_patch("x", "y" * 79)
response = self.client.get('/patch/%d/mbox/' % patch.id)
self.assertContains(response,
'Content-Transfer-Encoding: quoted-printable')
def test7bitIfLine78orLess(self):
patch = self.create_patch("x", "y" * 78)
response = self.client.get('/patch/%d/mbox/' % patch.id)
self.assertContains(response,
'Content-Transfer-Encoding: 7bit')
def test8bitIfNonAscii(self):
patch = self.create_patch("x", "hą hą hą")
response = self.client.get('/patch/%d/mbox/' % patch.id)
self.assertContains(response,
'Content-Transfer-Encoding: 8bit')
...@@ -252,20 +252,20 @@ class APITest(APITestBase): ...@@ -252,20 +252,20 @@ class APITest(APITestBase):
# XXX: since Python 3 email module wrap header lines differently # XXX: since Python 3 email module wrap header lines differently
self.check_mbox("/series/%s/revisions/1/mbox/" % self.series.pk, self.check_mbox("/series/%s/revisions/1/mbox/" % self.series.pk,
'for_each_-intel_-crtc-v2.mbox', 'for_each_-intel_-crtc-v2.mbox',
'6d59b59dbf751064408249e18401275f') 'db5b40c95b673ce38102943eaa02de69')
def testMboxWithCoverLetter(self): def testMboxWithCoverLetter(self):
# XXX: since Python 3 email module wrap header lines differently # XXX: since Python 3 email module wrap header lines differently
self.check_mbox("/series/%s/revisions/1/mbox_with_cover/" % self.check_mbox("/series/%s/revisions/1/mbox_with_cover/" %
self.series.pk, self.series.pk,
'for_each_-intel_-crtc-v2.mbox', 'for_each_-intel_-crtc-v2.mbox',
'826f03a224083df013a2b373459527a3') 'dd990d02f7d744a0b3b067f1afa831a6')
def testCoverLetterMbox(self): def testCoverLetterMbox(self):
self.check_mbox("/series/%s/revisions/1/cover/" % self.check_mbox("/series/%s/revisions/1/cover/" %
self.series.pk, self.series.pk,
'for_each_-intel_-crtc-v2.mbox', 'for_each_-intel_-crtc-v2.mbox',
'462a3414aedd2710d3dfed8a651ecd10') 'b8cc8c1d04434cb12110e2562a963de9')
def testMboxAndMboxWithCoverShouldBeIdenticalForSeriesWithNoCL(self): def testMboxAndMboxWithCoverShouldBeIdenticalForSeriesWithNoCL(self):
mbox = self.client.get('/api/1.0' + mbox = self.client.get('/api/1.0' +
......
...@@ -21,7 +21,7 @@ from __future__ import absolute_import ...@@ -21,7 +21,7 @@ from __future__ import absolute_import
import datetime import datetime
import time import time
from email.encoders import encode_7or8bit from email.encoders import encode_7or8bit, encode_quopri
from email.header import Header from email.header import Header
from email.mime.nonmultipart import MIMENonMultipart from email.mime.nonmultipart import MIMENonMultipart
from email.parser import HeaderParser from email.parser import HeaderParser
...@@ -184,7 +184,11 @@ class PatchMbox(MIMENonMultipart): ...@@ -184,7 +184,11 @@ class PatchMbox(MIMENonMultipart):
MIMENonMultipart.__init__(self, 'text', 'plain', MIMENonMultipart.__init__(self, 'text', 'plain',
**{'charset': self.patch_charset}) **{'charset': self.patch_charset})
self.set_payload(_text.encode(self.patch_charset)) self.set_payload(_text.encode(self.patch_charset))
encode_7or8bit(self)
if max((len(line) for line in _text.splitlines()), default=0) > 78:
encode_quopri(self)
else:
encode_7or8bit(self)
def get_from(patch, charset): def get_from(patch, charset):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment