-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
bpo-27321: email: don't try to replace headers that aren't set #1977
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@kyrias, thanks for your PR! By analyzing the history of the files in this pull request, we identified @bitdancer, @serhiy-storchaka and @ezio-melotti to be potential reviewers. |
Lib/email/generator.py
Outdated
if msg.get('content-transfer-encoding') is not None: | ||
msg.replace_header('content-transfer-encoding', munge_cte[0]) | ||
if msg.get('content-type') is not None: | ||
msg.replace_header('content-type', munge_cte[1]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The CTE is munged only when (a) we are translating to ASCII-only strings (Generator and not BytesGenerator) and (b) we have a non-None 'charset', which means we have a content-type header. So the content-type header should be set unconditionally so that if someone changes (b) we might notice. Which means we should also have a test that has non-ascii and neither header...which might find a new error :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original bug report https://bugs.python.org/issue27321 was for a message which had a Content-Type: but no Content-Transfer-Encoding:.
Based on @bitdancer comment, perhaps the code should be:
msg.replace_header('content-type', munge_cte[1])
if msg.get('content-transfer-encoding') is not None:
msg.replace_header('content-transfer-encoding', munge_cte[0]
else:
msg['Content-Transfer-Encoding'] = munge_cte[0]
Of course, a test with a non-ascii message with neither header wouldn't hurt in any case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that looks good.
Lib/test/test_email/data/msg_47.txt
Outdated
|
||
Test if UTF-8 messages with no Content-Transfer-Encoding set can be as_string'd: | ||
Föö bär | ||
------5F0D91A9C8C24D91AF71E1D7F2F7877E-- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to have the message text encoded in the test file rather than introduce a new file in the data directory. I think it makes the tests easier to read and understand. You'll find a number of other tests where I've done that elsewhere in the file.
This problem is affecting me. What's the status? |
Someone needs to address my review comments. It doesn't have to be the original PR author, although that would be ideal. |
@bitdancer Hey, sorry it took so long, not had any time to work on stuff lately. |
Lib/test/test_email/test_email.py
Outdated
@@ -311,6 +311,34 @@ def test_as_string_policy(self): | |||
g.flatten(msg) | |||
self.assertEqual(fullrepr, s.getvalue()) | |||
|
|||
def test_nonascii_as_string_without_cte(self): | |||
m = """\ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use textwrap.dedent here to indent the message. Then wrap the content lines so the whole thing still stays under 80 characters (that isn't always possible, but looks to be so in this case).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, just copied the first inline tests I saw, sorry.
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
Signed-off-by: Johannes Löthberg <[email protected]>
Signed-off-by: Johannes Löthberg <[email protected]>
Signed-off-by: Johannes Löthberg <[email protected]>
I have made the requested changes; please review again |
Thanks for making the requested changes! @bitdancer: please review the changes made to this pull request. |
@bitdancer Ping |
This bug causes coddingtonbear/django-mailbox#136. It would be very helpful if this review were completed. Thanks! |
cc @maxking |
I would love to see this review completed as well ! @bitdancer If I understand correctly ? |
msg.replace_header('content-type', munge_cte[1]) | ||
if msg.get('content-transfer-encoding') is not None: | ||
msg.replace_header('content-transfer-encoding', munge_cte[0]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you set the header if it doesn't already exists?
See #1977 (comment)
@kyrias, please address the code review request. Thank you! |
This PR should be considered obsolete and closed in favor of #18074 |
@msapiro, thank you! |
GH-18074) This PR replaces #1977. The reason for the replacement is two-fold. The fix itself is different is that if the CTE header doesn't exist in the original message, it is inserted. This is important because the new CTE could be quoted-printable whereas the original is implicit 8bit. Also the tests are different. The test_nonascii_as_string_without_cte test in #1977 doesn't actually test the issue in that it passes without the fix. The test_nonascii_as_string_without_content_type_and_cte test is improved here, and even though it doesn't fail without the fix, it is included for completeness. Automerge-Triggered-By: @warsaw
pythonGH-18074) This PR replaces pythonGH-1977. The reason for the replacement is two-fold. The fix itself is different is that if the CTE header doesn't exist in the original message, it is inserted. This is important because the new CTE could be quoted-printable whereas the original is implicit 8bit. Also the tests are different. The test_nonascii_as_string_without_cte test in pythonGH-1977 doesn't actually test the issue in that it passes without the fix. The test_nonascii_as_string_without_content_type_and_cte test is improved here, and even though it doesn't fail without the fix, it is included for completeness. Automerge-Triggered-By: @warsaw (cherry picked from commit bf83822) Co-authored-by: Mark Sapiro <[email protected]>
pythonGH-18074) This PR replaces pythonGH-1977. The reason for the replacement is two-fold. The fix itself is different is that if the CTE header doesn't exist in the original message, it is inserted. This is important because the new CTE could be quoted-printable whereas the original is implicit 8bit. Also the tests are different. The test_nonascii_as_string_without_cte test in pythonGH-1977 doesn't actually test the issue in that it passes without the fix. The test_nonascii_as_string_without_content_type_and_cte test is improved here, and even though it doesn't fail without the fix, it is included for completeness. Automerge-Triggered-By: @warsaw (cherry picked from commit bf83822) Co-authored-by: Mark Sapiro <[email protected]>
GH-18074) This PR replaces GH-1977. The reason for the replacement is two-fold. The fix itself is different is that if the CTE header doesn't exist in the original message, it is inserted. This is important because the new CTE could be quoted-printable whereas the original is implicit 8bit. Also the tests are different. The test_nonascii_as_string_without_cte test in GH-1977 doesn't actually test the issue in that it passes without the fix. The test_nonascii_as_string_without_content_type_and_cte test is improved here, and even though it doesn't fail without the fix, it is included for completeness. Automerge-Triggered-By: @warsaw (cherry picked from commit bf83822) Co-authored-by: Mark Sapiro <[email protected]>
GH-18074) This PR replaces GH-1977. The reason for the replacement is two-fold. The fix itself is different is that if the CTE header doesn't exist in the original message, it is inserted. This is important because the new CTE could be quoted-printable whereas the original is implicit 8bit. Also the tests are different. The test_nonascii_as_string_without_cte test in GH-1977 doesn't actually test the issue in that it passes without the fix. The test_nonascii_as_string_without_content_type_and_cte test is improved here, and even though it doesn't fail without the fix, it is included for completeness. Automerge-Triggered-By: @warsaw (cherry picked from commit bf83822) Co-authored-by: Mark Sapiro <[email protected]>
pythonGH-18074) This PR replaces python#1977. The reason for the replacement is two-fold. The fix itself is different is that if the CTE header doesn't exist in the original message, it is inserted. This is important because the new CTE could be quoted-printable whereas the original is implicit 8bit. Also the tests are different. The test_nonascii_as_string_without_cte test in python#1977 doesn't actually test the issue in that it passes without the fix. The test_nonascii_as_string_without_content_type_and_cte test is improved here, and even though it doesn't fail without the fix, it is included for completeness. Automerge-Triggered-By: @warsaw
This PR replaces pythonGH-1977. The reason for the replacement is two-fold. The fix itself is different is that if the CTE header doesn't exist in the original message, it is inserted. This is important because the new CTE could be quoted-printable whereas the original is implicit 8bit. Also the tests are different. The test_nonascii_as_string_without_cte test in pythongh-1977 doesn't actually test the issue in that it passes without the fix. The test_nonascii_as_string_without_content_type_and_cte test is improved here, and even though it doesn't fail without the fix, it is included for completeness. Fixed KeyError exception when flattening an email to a string attempts to replace a non-existent Content-Transfer-Encoding header. Code is originally from gh#python/cpython@371146a, it was released upstream in 3.8.7 Co-authored-by: Mark Sapiro <[email protected]> Date: Mon, 19 Oct 2020 16:11:37 -0700 Fixes: bsc#1208443 Patch: bpo27321-email-no-replace-header.patch
This PR replaces pythonGH-1977. The reason for the replacement is two-fold. The fix itself is different is that if the CTE header doesn't exist in the original message, it is inserted. This is important because the new CTE could be quoted-printable whereas the original is implicit 8bit. Also the tests are different. The test_nonascii_as_string_without_cte test in pythongh-1977 doesn't actually test the issue in that it passes without the fix. The test_nonascii_as_string_without_content_type_and_cte test is improved here, and even though it doesn't fail without the fix, it is included for completeness. Fixed KeyError exception when flattening an email to a string attempts to replace a non-existent Content-Transfer-Encoding header. Code is originally from gh#python/cpython@371146a, it was released upstream in 3.8.7 Co-authored-by: Mark Sapiro <[email protected]> Date: Mon, 19 Oct 2020 16:11:37 -0700 Fixes: bsc#1208443 Patch: bpo27321-email-no-replace-header.patch
This PR replaces pythonGH-1977. The reason for the replacement is two-fold. The fix itself is different is that if the CTE header doesn't exist in the original message, it is inserted. This is important because the new CTE could be quoted-printable whereas the original is implicit 8bit. Also the tests are different. The test_nonascii_as_string_without_cte test in pythongh-1977 doesn't actually test the issue in that it passes without the fix. The test_nonascii_as_string_without_content_type_and_cte test is improved here, and even though it doesn't fail without the fix, it is included for completeness. Fixed KeyError exception when flattening an email to a string attempts to replace a non-existent Content-Transfer-Encoding header. Code is originally from gh#python/cpython@371146a, it was released upstream in 3.8.7 Co-authored-by: Mark Sapiro <[email protected]> Date: Mon, 19 Oct 2020 16:11:37 -0700 Fixes: bsc#1208443 Patch: bpo27321-email-no-replace-header.patch
This PR replaces pythonGH-1977. The reason for the replacement is two-fold. The fix itself is different is that if the CTE header doesn't exist in the original message, it is inserted. This is important because the new CTE could be quoted-printable whereas the original is implicit 8bit. Also the tests are different. The test_nonascii_as_string_without_cte test in pythongh-1977 doesn't actually test the issue in that it passes without the fix. The test_nonascii_as_string_without_content_type_and_cte test is improved here, and even though it doesn't fail without the fix, it is included for completeness. Fixed KeyError exception when flattening an email to a string attempts to replace a non-existent Content-Transfer-Encoding header. Code is originally from gh#python/cpython@371146a, it was released upstream in 3.8.7 Co-authored-by: Mark Sapiro <[email protected]> Date: Mon, 19 Oct 2020 16:11:37 -0700 Fixes: bsc#1208443 Patch: bpo27321-email-no-replace-header.patch
This PR replaces pythonGH-1977. The reason for the replacement is two-fold. The fix itself is different is that if the CTE header doesn't exist in the original message, it is inserted. This is important because the new CTE could be quoted-printable whereas the original is implicit 8bit. Also the tests are different. The test_nonascii_as_string_without_cte test in pythongh-1977 doesn't actually test the issue in that it passes without the fix. The test_nonascii_as_string_without_content_type_and_cte test is improved here, and even though it doesn't fail without the fix, it is included for completeness. Fixed KeyError exception when flattening an email to a string attempts to replace a non-existent Content-Transfer-Encoding header. Code is originally from gh#python/cpython@371146a, it was released upstream in 3.8.7 Co-authored-by: Mark Sapiro <[email protected]> Date: Mon, 19 Oct 2020 16:11:37 -0700 Fixes: bsc#1208443 Patch: bpo27321-email-no-replace-header.patch
This PR replaces pythonGH-1977. The reason for the replacement is two-fold. The fix itself is different is that if the CTE header doesn't exist in the original message, it is inserted. This is important because the new CTE could be quoted-printable whereas the original is implicit 8bit. Also the tests are different. The test_nonascii_as_string_without_cte test in pythongh-1977 doesn't actually test the issue in that it passes without the fix. The test_nonascii_as_string_without_content_type_and_cte test is improved here, and even though it doesn't fail without the fix, it is included for completeness. Fixed KeyError exception when flattening an email to a string attempts to replace a non-existent Content-Transfer-Encoding header. Code is originally from gh#python/cpython@371146a, it was released upstream in 3.8.7 Co-authored-by: Mark Sapiro <[email protected]> Date: Mon, 19 Oct 2020 16:11:37 -0700 Fixes: bsc#1208443 Patch: bpo27321-email-no-replace-header.patch
Currently the email module sometimes blows up on emails that don't contain e.g. a Content-Transfer-Encoding header, even though it doesn't need to exist. Fix this by only replacing it if it's already set.
https://bugs.python.org/issue27321
https://bugs.python.org/issue27321