mirror of https://github.com/python/cpython
#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.)
This commit is contained in:
parent
d0a0e8e070
commit
7ef3ff3f2e
|
@ -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.
|
||||
|
||||
|
|
|
@ -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."""
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue