]> granicus.if.org Git - python/commitdiff
#12515: email now registers a defect if the MIME end boundary is missing.
authorR David Murray <rdmurray@bitdance.com>
Mon, 28 May 2012 02:20:42 +0000 (22:20 -0400)
committerR David Murray <rdmurray@bitdance.com>
Mon, 28 May 2012 02:20:42 +0000 (22:20 -0400)
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.)

Doc/library/email.errors.rst
Lib/email/errors.py
Lib/email/feedparser.py
Lib/test/test_email/test_defect_handling.py
Misc/NEWS

index 2bc31646b52209584bc5eca0d8fc8dc32bda248c..acfa6b2c536afdf748a8375d7be9e5893ce61b5c 100644 (file)
@@ -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.
 
index aa836d49c77fb672b743921457944fe59b5a3a57..d80b5b93b5837227de938352e7ced3f68966b2e8 100644 (file)
@@ -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."""
 
index c3a67c0927ec9bf1bb979e34dd88c1e17d975533..56f50dff6d2442044cb91c395f891bfc02545ed0 100644 (file)
@@ -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:
index d3df1e4b470079f31ea399ca191006337936d56b..fe725998a54d4727575625f2e9786592969592b5 100644 (file)
@@ -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):
 
index 4b70d45e63bac4baa8986c3cc6e85e6447761f4d..3e4157ecfded0a3e72d94d3b5a1b2e7289b01ccd 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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.