From afa24d52b821c2020e0966f96a6205bca7db85e9 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Sun, 23 Jul 2023 05:28:35 -0700 Subject: [PATCH] [3.11] gh-106186: Don't report MultipartInvariantViolationDefect for valid multipart emails when parsing header only (GH-107016) (#107112) (cherry picked from commit c65592c4d6d7552fb6284442906a96a6874cb266) Co-authored-by: htsedebenham <31847376+htsedebenham@users.noreply.github.com> --- Lib/email/feedparser.py | 2 +- Lib/test/test_email/data/msg_47.txt | 14 ++++++++++++++ Lib/test/test_email/test_email.py | 10 ++++++++++ .../2023-07-22-13-09-28.gh-issue-106186.EIsUNG.rst | 3 +++ 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 Lib/test/test_email/data/msg_47.txt create mode 100644 Misc/NEWS.d/next/Library/2023-07-22-13-09-28.gh-issue-106186.EIsUNG.rst diff --git a/Lib/email/feedparser.py b/Lib/email/feedparser.py index 97d3f5144d606f..e400dc7fb89b05 100644 --- a/Lib/email/feedparser.py +++ b/Lib/email/feedparser.py @@ -189,7 +189,7 @@ def close(self): assert not self._msgstack # Look for final set of defects if root.get_content_maintype() == 'multipart' \ - and not root.is_multipart(): + and not root.is_multipart() and not self._headersonly: defect = errors.MultipartInvariantViolationDefect() self.policy.handle_defect(root, defect) return root diff --git a/Lib/test/test_email/data/msg_47.txt b/Lib/test/test_email/data/msg_47.txt new file mode 100644 index 00000000000000..bb48b47d96baf8 --- /dev/null +++ b/Lib/test/test_email/data/msg_47.txt @@ -0,0 +1,14 @@ +Date: 01 Jan 2001 00:01+0000 +From: arthur@example.example +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary=foo + +--foo +Content-Type: text/plain +bar + +--foo +Content-Type: text/html +

baz

+ +--foo-- \ No newline at end of file diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index ca8212825ffca4..2bb651609f572b 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -3696,6 +3696,16 @@ def test_bytes_header_parser(self): self.assertIsInstance(msg.get_payload(), str) self.assertIsInstance(msg.get_payload(decode=True), bytes) + def test_header_parser_multipart_is_valid(self): + # Don't flag valid multipart emails as having defects + with openfile('msg_47.txt', encoding="utf-8") as fp: + msgdata = fp.read() + + parser = email.parser.Parser(policy=email.policy.default) + parsed_msg = parser.parsestr(msgdata, headersonly=True) + + self.assertEqual(parsed_msg.defects, []) + def test_bytes_parser_does_not_close_file(self): with openfile('msg_02.txt', 'rb') as fp: email.parser.BytesParser().parse(fp) diff --git a/Misc/NEWS.d/next/Library/2023-07-22-13-09-28.gh-issue-106186.EIsUNG.rst b/Misc/NEWS.d/next/Library/2023-07-22-13-09-28.gh-issue-106186.EIsUNG.rst new file mode 100644 index 00000000000000..07fdcc96fa38a6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-07-22-13-09-28.gh-issue-106186.EIsUNG.rst @@ -0,0 +1,3 @@ +Do not report ``MultipartInvariantViolationDefect`` defect +when the :class:`email.parser.Parser` class is used +to parse emails with ``headersonly=True``.