diff options
author | R David Murray <rdmurray@bitdance.com> | 2012-05-28 02:20:42 (GMT) |
---|---|---|
committer | R David Murray <rdmurray@bitdance.com> | 2012-05-28 02:20:42 (GMT) |
commit | 7ef3ff3f2ea77f496f5386c3ede74f95001a6009 (patch) | |
tree | ab17160f5d03de8fa54f02ceb2b38e3f769156a1 | |
parent | d0a0e8e070f1c3c74905627380473f21f5457cfb (diff) | |
download | cpython-7ef3ff3f2ea77f496f5386c3ede74f95001a6009.zip cpython-7ef3ff3f2ea77f496f5386c3ede74f95001a6009.tar.gz cpython-7ef3ff3f2ea77f496f5386c3ede74f95001a6009.tar.bz2 |
#12515: email now registers a defect if the MIME end boundary is missing.
This commit also restores the news item for 167256 that it looks like
Terry inadvertently deleted. (Either that, or I don't understand
now merging works...which is equally possible.)
-rw-r--r-- | Doc/library/email.errors.rst | 5 | ||||
-rw-r--r-- | Lib/email/errors.py | 3 | ||||
-rw-r--r-- | Lib/email/feedparser.py | 14 | ||||
-rw-r--r-- | Lib/test/test_email/test_defect_handling.py | 33 | ||||
-rw-r--r-- | Misc/NEWS | 7 |
5 files changed, 59 insertions, 3 deletions
diff --git a/Doc/library/email.errors.rst b/Doc/library/email.errors.rst index 2bc3164..acfa6b2 100644 --- a/Doc/library/email.errors.rst +++ b/Doc/library/email.errors.rst @@ -73,6 +73,11 @@ this class is *not* an exception! * :class:`StartBoundaryNotFoundDefect` -- The start boundary claimed in the :mailheader:`Content-Type` header was never found. +* :class:`CloseBoundaryNotFoundDefect` -- A start boundary was found, but + no corresponding close boundary was ever found. + + .. versionadded: 3.3 + * :class:`FirstHeaderLineIsContinuationDefect` -- The message had a continuation line as its first header line. diff --git a/Lib/email/errors.py b/Lib/email/errors.py index aa836d4..d80b5b9 100644 --- a/Lib/email/errors.py +++ b/Lib/email/errors.py @@ -42,6 +42,9 @@ class NoBoundaryInMultipartDefect(MessageDefect): class StartBoundaryNotFoundDefect(MessageDefect): """The claimed start boundary was never found.""" +class CloseBoundaryNotFoundDefect(MessageDefect): + """A start boundary was found, but not the corresponding close boundary.""" + class FirstHeaderLineIsContinuationDefect(MessageDefect): """A message had a continuation line as its first header line.""" diff --git a/Lib/email/feedparser.py b/Lib/email/feedparser.py index c3a67c0..56f50df 100644 --- a/Lib/email/feedparser.py +++ b/Lib/email/feedparser.py @@ -324,6 +324,7 @@ class FeedParser: capturing_preamble = True preamble = [] linesep = False + close_boundary_seen = False while True: line = self._input.readline() if line is NeedMoreData: @@ -338,6 +339,7 @@ class FeedParser: # the closing boundary, then we need to initialize the # epilogue with the empty string (see below). if mo.group('end'): + close_boundary_seen = True linesep = mo.group('linesep') break # We saw an inter-part boundary. Were we in the preamble? @@ -406,7 +408,6 @@ class FeedParser: # We've seen either the EOF or the end boundary. If we're still # capturing the preamble, we never saw the start boundary. Note # that as a defect and store the captured text as the payload. - # Everything from here to the EOF is epilogue. if capturing_preamble: defect = errors.StartBoundaryNotFoundDefect() self.policy.handle_defect(self._cur, defect) @@ -418,8 +419,15 @@ class FeedParser: continue self._cur.epilogue = EMPTYSTRING.join(epilogue) return - # If the end boundary ended in a newline, we'll need to make sure - # the epilogue isn't None + # If we're not processing the preamble, then we might have seen + # EOF without seeing that end boundary...that is also a defect. + if not close_boundary_seen: + defect = errors.CloseBoundaryNotFoundDefect() + self.policy.handle_defect(self._cur, defect) + return + # Everything from here to the EOF is epilogue. If the end boundary + # ended in a newline, we'll need to make sure the epilogue isn't + # None if linesep: epilogue = [''] else: diff --git a/Lib/test/test_email/test_defect_handling.py b/Lib/test/test_email/test_defect_handling.py index d3df1e4..fe72599 100644 --- a/Lib/test/test_email/test_defect_handling.py +++ b/Lib/test/test_email/test_defect_handling.py @@ -278,6 +278,39 @@ class TestMessageDefectDetectionBase: with self.assertRaises(errors.InvalidBase64CharactersDefect): msg.get_payload(decode=True) + missing_ending_boundary = textwrap.dedent("""\ + To: 1@harrydomain4.com + Subject: Fwd: 1 + MIME-Version: 1.0 + Content-Type: multipart/alternative; + boundary="------------000101020201080900040301" + + --------------000101020201080900040301 + Content-Type: text/plain; charset=ISO-8859-1 + Content-Transfer-Encoding: 7bit + + Alternative 1 + + --------------000101020201080900040301 + Content-Type: text/html; charset=ISO-8859-1 + Content-Transfer-Encoding: 7bit + + Alternative 2 + + """) + + def test_missing_ending_boundary(self): + msg = self._str_msg(self.missing_ending_boundary) + self.assertEqual(len(msg.get_payload()), 2) + self.assertEqual(msg.get_payload(1).get_payload(), 'Alternative 2\n') + self.assertDefectsEqual(self.get_defects(msg), + [errors.CloseBoundaryNotFoundDefect]) + + def test_missing_ending_boundary_raise_on_defect(self): + with self.assertRaises(errors.CloseBoundaryNotFoundDefect): + self._str_msg(self.missing_ending_boundary, + policy=self.policy.clone(raise_on_defect=True)) + class TestMessageDefectDetection(TestMessageDefectDetectionBase, TestEmailBase): @@ -49,9 +49,16 @@ Core and Builtins Library ------- +- Issue #12515: email now registers a defect if it gets to EOF while parsing + a MIME part without seeing the closing MIME boundary. + - Issue12510: Attempting to get invalid tooltip no longer closes Idle. Original patch by Roger Serwy. +- Issue #1672568: email now always decodes base64 payloads, adding padding and + ignoring non-base64-alphabet characters if needed, and registering defects + for any such problems. + - Issue #14925: email now registers a defect when the parser decides that there is a missing header/body separator line. MalformedHeaderDefect, which the existing code would never actually generate, is deprecated. |