https://github.com/python/cpython/commit/408154d64a7b3d43b05f44ea5c4cdf781bdd1352
commit: 408154d64a7b3d43b05f44ea5c4cdf781bdd1352
branch: main
author: Gordon Messmer <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2025-09-29T09:03:06+03:00
summary:
gh-78319: Fix implementation of IMAP APPEND UTF8 (GH-9436)
Make UTF8 support for the IMAP APPEND command RFC 6855 compliant.
files:
A Misc/NEWS.d/next/Library/2023-02-13-20-34-52.gh-issue-78319.V1zzed.rst
M Lib/imaplib.py
M Lib/test/test_imaplib.py
diff --git a/Lib/imaplib.py b/Lib/imaplib.py
index 362d6a2dcf2573..cbe129b3e7c214 100644
--- a/Lib/imaplib.py
+++ b/Lib/imaplib.py
@@ -497,8 +497,6 @@ def append(self, mailbox, flags, date_time, message):
else:
date_time = None
literal = MapCRLF.sub(CRLF, message)
- if self.utf8_enabled:
- literal = b'UTF8 (' + literal + b')'
self.literal = literal
return self._simple_command(name, mailbox, flags, date_time)
@@ -1119,7 +1117,11 @@ def _command(self, name, *args):
literator = literal
else:
literator = None
- data = data + bytes(' {%s}' % len(literal), self._encoding)
+ if self.utf8_enabled:
+ data = data + bytes(' UTF8 (~{%s}' % len(literal),
self._encoding)
+ literal = literal + b')'
+ else:
+ data = data + bytes(' {%s}' % len(literal), self._encoding)
if __debug__:
if self.debug >= 4:
diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py
index 3507fc83b6a2ae..999e6e69ab41ea 100644
--- a/Lib/test/test_imaplib.py
+++ b/Lib/test/test_imaplib.py
@@ -372,7 +372,11 @@ def cmd_AUTHENTICATE(self, tag, args):
self._send_tagged(tag, 'OK', 'FAKEAUTH successful')
def cmd_APPEND(self, tag, args):
self._send_textline('+')
- self.server.response = yield
+ self.server.response = args
+ literal = yield
+ self.server.response.append(literal)
+ literal = yield
+ self.server.response.append(literal)
self._send_tagged(tag, 'OK', 'okay')
client, server = self._setup(UTF8AppendServer)
self.assertEqual(client._encoding, 'ascii')
@@ -383,10 +387,13 @@ def cmd_APPEND(self, tag, args):
self.assertEqual(code, 'OK')
self.assertEqual(client._encoding, 'utf-8')
msg_string = 'Subject: üñí©öðé'
- typ, data = client.append(None, None, None, msg_string.encode('utf-8'))
+ typ, data = client.append(
+ None, None, None, (msg_string + '\n').encode('utf-8'))
self.assertEqual(typ, 'OK')
self.assertEqual(server.response,
- ('UTF8 (%s)\r\n' % msg_string).encode('utf-8'))
+ ['INBOX', 'UTF8',
+ '(~{25}', ('%s\r\n' % msg_string).encode('utf-8'),
+ b')\r\n' ])
def test_search_disallows_charset_in_utf8_mode(self):
class UTF8Server(SimpleIMAPHandler):
@@ -881,7 +888,11 @@ def test_enable_UTF8_True_append(self):
class UTF8AppendServer(self.UTF8Server):
def cmd_APPEND(self, tag, args):
self._send_textline('+')
- self.server.response = yield
+ self.server.response = args
+ literal = yield
+ self.server.response.append(literal)
+ literal = yield
+ self.server.response.append(literal)
self._send_tagged(tag, 'OK', 'okay')
with self.reaped_pair(UTF8AppendServer) as (server, client):
@@ -895,12 +906,12 @@ def cmd_APPEND(self, tag, args):
self.assertEqual(client._encoding, 'utf-8')
msg_string = 'Subject: üñí©öðé'
typ, data = client.append(
- None, None, None, msg_string.encode('utf-8'))
+ None, None, None, (msg_string + '\n').encode('utf-8'))
self.assertEqual(typ, 'OK')
- self.assertEqual(
- server.response,
- ('UTF8 (%s)\r\n' % msg_string).encode('utf-8')
- )
+ self.assertEqual(server.response,
+ ['INBOX', 'UTF8',
+ '(~{25}', ('%s\r\n' % msg_string).encode('utf-8'),
+ b')\r\n' ])
# XXX also need a test that makes sure that the Literal and Untagged_status
# regexes uses unicode in UTF8 mode instead of the default ASCII.
diff --git
a/Misc/NEWS.d/next/Library/2023-02-13-20-34-52.gh-issue-78319.V1zzed.rst
b/Misc/NEWS.d/next/Library/2023-02-13-20-34-52.gh-issue-78319.V1zzed.rst
new file mode 100644
index 00000000000000..cc8a6e73942203
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-02-13-20-34-52.gh-issue-78319.V1zzed.rst
@@ -0,0 +1 @@
+UTF8 support for the IMAP APPEND command has been made RFC compliant.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]