Commit 2cc1f6d9 authored by Barry Warsaw's avatar Barry Warsaw

More email package related repairs. This fixes smtplib's import and use of

email.base64mime, but test_smtplib still has failures for me.  They are
timeout errors so think they're more related to my current wacky network setup
than bugs remaining in the code related to the email package.

This also r57693 that got clobbered with the sandbox sync, and fixes a couple
of other minor problems that cropped up.  I will kill the sandbox branch next.

The email package now has 11F/11E.
parent 5a23cc5a
......@@ -101,25 +101,19 @@ def body_encode(s, maxlinelen=76, eol=NL):
def decode(s, convert_eols=False):
def decode(string):
"""Decode a raw base64 string, returning a bytes object.
If convert_eols is set to a string value, all canonical email linefeeds,
e.g. "\\r\\n", in the decoded text will be converted to the value of
convert_eols. os.linesep is a good choice for convert_eols if you are
decoding a text attachment.
This function does not parse a full MIME header value encoded with
base64 (like =?iso-8895-1?b?bmloISBuaWgh?=) -- please use the high
level email.Header class for that functionality.
"""
if not s:
return s
dec = a2b_base64(s)
if convert_eols:
return dec.replace(CRLF, convert_eols)
return dec
if not string:
return bytes()
elif isinstance(string, str):
return a2b_base64(string.encode('raw-unicode-escape'))
else:
return a2b_base64(s)
# For convenience and backwards compatibility w/ standard base64 module
......
......@@ -341,10 +341,11 @@ class _ValueFormatter:
self._current_line = _Accumulator(headerlen)
def __str__(self):
# Remove the trailing TRANSITIONAL_SPACE
last_line = self._current_line.pop()
if last_line is not TRANSITIONAL_SPACE:
self._current_line.push(last_line)
# Remove any trailing TRANSITIONAL_SPACE
if len(self._current_line) > 0:
last_line = self._current_line.pop()
if last_line is not TRANSITIONAL_SPACE:
self._current_line.push(last_line)
self.newline()
return NL.join(self._lines)
......
......@@ -201,7 +201,8 @@ class Message:
# Incorrect padding
pass
elif cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'):
in_file = BytesIO(bytes(payload + '\n'))
payload += '\n'
in_file = BytesIO(payload.encode('raw-unicode-escape'))
out_file = BytesIO()
try:
uu.decode(in_file, out_file, quiet=True)
......@@ -752,7 +753,8 @@ class Message:
# LookupError will be raised if the charset isn't known to
# Python. UnicodeError will be raised if the encoded text
# contains a character not in the charset.
charset = str(bytes(charset[2]), pcharset)
as_bytes = charset[2].encode('raw-unicode-escape')
charset = str(as_bytes, pcharset)
except (LookupError, UnicodeError):
charset = charset[2]
# charset characters must be in us-ascii range
......
......@@ -58,7 +58,7 @@ _QUOPRI_HEADER_MAP = dict((c, '=%02X' % c) for c in range(256))
_QUOPRI_BODY_MAP = _QUOPRI_HEADER_MAP.copy()
# Safe header bytes which need no encoding.
for c in b'-!*+/' + bytes(ascii_letters, 'ascii') + bytes(digits, 'ascii'):
for c in b'-!*+/' + ascii_letters.encode('ascii') + digits.encode('ascii'):
_QUOPRI_HEADER_MAP[c] = chr(c)
# Headers have one other special encoding; spaces become underscores.
_QUOPRI_HEADER_MAP[ord(' ')] = '_'
......
......@@ -2538,10 +2538,8 @@ class TestBase64(unittest.TestCase):
def test_decode(self):
eq = self.assertEqual
eq(base64mime.decode(''), '')
eq(base64mime.decode(''), b'')
eq(base64mime.decode('aGVsbG8='), b'hello')
eq(base64mime.decode('aGVsbG8=', 'X'), b'hello')
eq(base64mime.decode('aGVsbG8NCndvcmxk\n', 'X'), b'helloXworld')
def test_encode(self):
eq = self.assertEqual
......
......@@ -46,7 +46,7 @@ import re
import email.utils
import base64
import hmac
from email.base64mime import encode as encode_base64
from email.base64mime import body_encode as encode_base64
from sys import stderr
__all__ = ["SMTPException","SMTPServerDisconnected","SMTPResponseException",
......@@ -529,10 +529,10 @@ class SMTP:
def encode_cram_md5(challenge, user, password):
challenge = base64.decodestring(challenge)
response = user + " " + hmac.HMAC(password, challenge).hexdigest()
return encode_base64(response, eol="")
return encode_base64(response)
def encode_plain(user, password):
return encode_base64("\0%s\0%s" % (user, password), eol="")
return encode_base64("\0%s\0%s" % (user, password))
AUTH_PLAIN = "PLAIN"
......@@ -574,10 +574,10 @@ class SMTP:
AUTH_PLAIN + " " + encode_plain(user, password))
elif authmethod == AUTH_LOGIN:
(code, resp) = self.docmd("AUTH",
"%s %s" % (AUTH_LOGIN, encode_base64(user, eol="")))
"%s %s" % (AUTH_LOGIN, encode_base64(user)))
if code != 334:
raise SMTPAuthenticationError(code, resp)
(code, resp) = self.docmd(encode_base64(password, eol=""))
(code, resp) = self.docmd(encode_base64(password))
elif authmethod is None:
raise SMTPException("No suitable authentication method found.")
if code not in (235, 503):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment