classification
Title: email.contentmanager raises error when policy.max_line_length==None or 0
Type: behavior Stage: patch review
Components: email Versions: Python 3.8, Python 3.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: barry, r.david.murray, silane, xtreak
Priority: normal Keywords: patch

Created on 2018-09-25 15:36 by silane, last changed 2018-09-25 20:24 by silane.

Pull Requests
URL Status Linked Edit
PR 9578 open silane, 2018-09-25 20:11
Messages (4)
msg326364 - (view) Author: silane (silane) * Date: 2018-09-25 15:36
The document of the email.policy.Policy says max_line_length=0 or None indicates that no line wrapping should be done at all.
But email.contentmanager doesn't handle this properly and raises error when calling set_content() with bytes or non-ascii str.


---Code to reproduce the bug---

from email.message import EmailMessage
from email.policy import default
msg=EmailMessage(default.clone(max_line_length=None)) # or max_line_length=0

msg.set_content('あ') # raise error
# or
msg.set_content(b'a',maintype='application',subtype='octet-stream') # raise error

---


This bug is caused by contentmanager._encode_text() and contentmanager.set_bytes_content().
These don't assume policy.max_line_length to be None or 0.

I tested this on python3.7 3.6 3.5, but probably 3.4 has the same bug.
msg326384 - (view) Author: Karthikeyan Singaravelan (xtreak) * (Python committer) Date: 2018-09-25 18:14
Thanks silane for the report and script. The case where max_line_length=0 causing ValueError was introduced with b938c8c25316b69f1d5df2c7880a9f6b87e7c2fa and the code at [0] has some comments regarding the minimum value to be 4 characters. There was another case where policy can have max_line_length=0 but it's with respect to folding issue33524. Maybe this behavior can be documented better for set_content method with respect to the minimum value ? 

[0] https://github.com/tirkarthi/cpython/blob/f6c8007a29b95b3ea3ca687a9b4924769a696328/Lib/email/quoprimime.py#L171


"""
    Each line will be wrapped at, at most, maxlinelen characters before the
    eol string (maxlinelen defaults to 76 characters, the maximum value
    permitted by RFC 2045).  Long lines will have the 'soft line break'
    quoted-printable character "=" appended to them, so the decoded text will
    be identical to the original text.

    The minimum maxlinelen is 4 to have room for a quoted character ("=XX")
    followed by a soft line break.  Smaller values will generate a
    ValueError.
"""

Hope this helps!
msg326399 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2018-09-25 19:23
An unlimited line length would certainly satisfy the required minimum.  As silane indicates, if max_line_length is 0 or None, the serializer is not supposed to wrap lines.  (In fact one would like to have the option to control this separately for the headers and the body, but currently the policy does not have knobs for that.)

So, this is a bug.
msg326403 - (view) Author: silane (silane) * Date: 2018-09-25 20:24
I've made a pull request.
Please look at it.
And this is my first pull request, so please let me know if something wrong.

https://github.com/python/cpython/pull/9578
History
Date User Action Args
2018-09-25 20:24:05silanesetmessages: + msg326403
2018-09-25 20:11:51silanesetkeywords: + patch
stage: patch review
pull_requests: + pull_request8980
2018-09-25 19:23:53r.david.murraysetmessages: + msg326399
versions: + Python 3.8, - Python 3.5, Python 3.6
2018-09-25 18:14:18xtreaksetmessages: + msg326384
2018-09-25 17:45:20xtreaksetnosy: + xtreak
2018-09-25 15:38:08silanesettype: behavior
2018-09-25 15:36:08silanecreate