Kaydet (Commit) 7ef3ff3f authored tarafından R David Murray's avatar R David Murray

#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.)
üst d0a0e8e0
...@@ -73,6 +73,11 @@ this class is *not* an exception! ...@@ -73,6 +73,11 @@ this class is *not* an exception!
* :class:`StartBoundaryNotFoundDefect` -- The start boundary claimed in the * :class:`StartBoundaryNotFoundDefect` -- The start boundary claimed in the
:mailheader:`Content-Type` header was never found. :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 * :class:`FirstHeaderLineIsContinuationDefect` -- The message had a continuation
line as its first header line. line as its first header line.
......
...@@ -42,6 +42,9 @@ class NoBoundaryInMultipartDefect(MessageDefect): ...@@ -42,6 +42,9 @@ class NoBoundaryInMultipartDefect(MessageDefect):
class StartBoundaryNotFoundDefect(MessageDefect): class StartBoundaryNotFoundDefect(MessageDefect):
"""The claimed start boundary was never found.""" """The claimed start boundary was never found."""
class CloseBoundaryNotFoundDefect(MessageDefect):
"""A start boundary was found, but not the corresponding close boundary."""
class FirstHeaderLineIsContinuationDefect(MessageDefect): class FirstHeaderLineIsContinuationDefect(MessageDefect):
"""A message had a continuation line as its first header line.""" """A message had a continuation line as its first header line."""
......
...@@ -324,6 +324,7 @@ class FeedParser: ...@@ -324,6 +324,7 @@ class FeedParser:
capturing_preamble = True capturing_preamble = True
preamble = [] preamble = []
linesep = False linesep = False
close_boundary_seen = False
while True: while True:
line = self._input.readline() line = self._input.readline()
if line is NeedMoreData: if line is NeedMoreData:
...@@ -338,6 +339,7 @@ class FeedParser: ...@@ -338,6 +339,7 @@ class FeedParser:
# the closing boundary, then we need to initialize the # the closing boundary, then we need to initialize the
# epilogue with the empty string (see below). # epilogue with the empty string (see below).
if mo.group('end'): if mo.group('end'):
close_boundary_seen = True
linesep = mo.group('linesep') linesep = mo.group('linesep')
break break
# We saw an inter-part boundary. Were we in the preamble? # We saw an inter-part boundary. Were we in the preamble?
...@@ -406,7 +408,6 @@ class FeedParser: ...@@ -406,7 +408,6 @@ class FeedParser:
# We've seen either the EOF or the end boundary. If we're still # We've seen either the EOF or the end boundary. If we're still
# capturing the preamble, we never saw the start boundary. Note # capturing the preamble, we never saw the start boundary. Note
# that as a defect and store the captured text as the payload. # that as a defect and store the captured text as the payload.
# Everything from here to the EOF is epilogue.
if capturing_preamble: if capturing_preamble:
defect = errors.StartBoundaryNotFoundDefect() defect = errors.StartBoundaryNotFoundDefect()
self.policy.handle_defect(self._cur, defect) self.policy.handle_defect(self._cur, defect)
...@@ -418,8 +419,15 @@ class FeedParser: ...@@ -418,8 +419,15 @@ class FeedParser:
continue continue
self._cur.epilogue = EMPTYSTRING.join(epilogue) self._cur.epilogue = EMPTYSTRING.join(epilogue)
return return
# If the end boundary ended in a newline, we'll need to make sure # If we're not processing the preamble, then we might have seen
# the epilogue isn't None # 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: if linesep:
epilogue = [''] epilogue = ['']
else: else:
......
...@@ -278,6 +278,39 @@ class TestMessageDefectDetectionBase: ...@@ -278,6 +278,39 @@ class TestMessageDefectDetectionBase:
with self.assertRaises(errors.InvalidBase64CharactersDefect): with self.assertRaises(errors.InvalidBase64CharactersDefect):
msg.get_payload(decode=True) 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): class TestMessageDefectDetection(TestMessageDefectDetectionBase, TestEmailBase):
......
...@@ -49,9 +49,16 @@ Core and Builtins ...@@ -49,9 +49,16 @@ Core and Builtins
Library 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. - Issue12510: Attempting to get invalid tooltip no longer closes Idle.
Original patch by Roger Serwy. 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 - Issue #14925: email now registers a defect when the parser decides that there
is a missing header/body separator line. MalformedHeaderDefect, which the is a missing header/body separator line. MalformedHeaderDefect, which the
existing code would never actually generate, is deprecated. existing code would never actually generate, is deprecated.
......
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