[issue34025] SMTP EmailPolicy not setting max_line_length as expected. RCF 2045 states 76 char, Default policy uses 78
Douglas Thor
report at bugs.python.org
Mon Jul 2 12:18:14 EDT 2018
New submission from Douglas Thor <doug.thor at gmail.com>:
It appears that the SMTP EmailPolicy object does not correctly set max_line_length.
RFC 2045 (https://www.ietf.org/rfc/rfc2045.txt) requires a max_line_length of 76 characters, while email._policybase.Policy sets it to 78 (which typically is correct).
This causes email attachments to be truncated/corrupted.
While the workaround is quite trivial, debugging the root cause was not as easy. Thus I think this should be fixed in at the std lib level, or at the very least mentioned in the docs.
This was tested on Python 3.5.2. I did not test on 3.7, but I did check the source code and it appears that the bug still exists.
To reproduce:
import smtplib
from email.message import EmailMessage
from email.policy import SMTP
msg = EmailMessage()
msg['Subject'] = "Test message"
msg['To'] = "to at valid_address.com"
msg['From'] = "from at valid_address.com"
content = "hello world, I should have an attachment"
msg.set_content(content)
maintype = 'image'
subtype = 'png'
test_file = './aaa.png'
with open(test_file, 'rb') as fp:
data = fp.read()
msg.add_attachment(data,
maintype=maintype,
subtype=subtype,
filename='aaa.png')
with smtplib.SMTP_SSL('smtp.address.com', port=465) as s:
s.ehlo()
user = 'smtp_user at valid_address.com'
pw = 'smtp_password'
s.login(user, pw)
s.send_message(msg)
Check the raw email message received. You'll see that lines have a length of 78 and are padded with "==" which makes the total length 80 chars:
...
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="===============1585876390557366757=="
--===============1585876390557366757==
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 7bit
hello world, I should have an attachment
--===============1585876390557366757==
Content-Type: image/png
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="aaa.png"
MIME-Version: 1.0
iVBORw0KGgoAAAANSUhEUgAABE0AAALFCAYAAAA2rB2uAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjw==
C/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAD/jklEQVR4Xg==
7P1rsHVJWecBvl4RFFAuIpcCEYQuLkUDBcgBoQsULLnJXaoaEApe5FLSTVFUC4JACQ1NiQdsQoFBAQ==
iW4aQSWEt4cQwwB6xqC+CPYHqX5jQno+jHyYCCMmZsKJmYjZs3/rnOe8uXNnrpW5LrlzrfVfVSfOeQ==
986Vl/+T678y//nkk9+3OXdu+78uISAEhIAQEAJCQAgIASEgBISAEBACQkAICIEdBBBN9CMM1AfUBw==
...
Next, modify the code with:
from email.policy import SMTP
smtp_pol = SMTP.clone(max_line_length=76)
msg = EmailMessage(policy=smtp_pol)
msg['Subject'] = ...
And check the raw email again. This time, lines are 76 chars long and have no padding. Data is the same, just wrapped differently as expected.
...
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="===============4874323426669347622=="
--===============4874323426669347622==
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 7bit
hello world, I should have an attachment
--===============4874323426669347622==
Content-Type: image/png
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="aaa.png"
MIME-Version: 1.0
iVBORw0KGgoAAAANSUhEUgAABE0AAALFCAYAAAA2rB2uAAAAAXNSR0IArs4c6QAAAARnQU1BAACx
jwv8YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAA/45JREFU
eF7s/WuwdUlZ5wG+XhEUUC4ilwIRhC4uRQMFyAGhCxQsucldqhoQCl7kUtJNUVQLgkAJDU2JB2xC
gUEBiW4aQSWEt4cQwwB6xqC+CPYHqX5jQno+jHyYCCMmZsKJmYjZs3/rnOe8uXNnrpW5LrlzrfVf
...
This fix *should* be extremely easy:
diff --git "a/policy.py" "b/policy.py"
index 6ac64a5..046b788 100644
--- "a/policy.py"
+++ "b/policy.py"
@@ -209,6 +209,6 @@ default = EmailPolicy()
# Make the default policy use the class default header_factory
del default.header_factory
strict = default.clone(raise_on_defect=True)
-SMTP = default.clone(linesep='\r\n')
+SMTP = default.clone(linesep='\r\n', max_line_length=76)
HTTP = default.clone(linesep='\r\n', max_line_length=None)
SMTPUTF8 = SMTP.clone(utf8=True)
----------
components: email
messages: 320898
nosy: Douglas Thor, barry, r.david.murray
priority: normal
severity: normal
status: open
title: SMTP EmailPolicy not setting max_line_length as expected. RCF 2045 states 76 char, Default policy uses 78
type: behavior
versions: Python 3.5
_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue34025>
_______________________________________
More information about the Python-bugs-list
mailing list