Skip to content

Commit 408154d

Browse files
gh-78319: Fix implementation of IMAP APPEND UTF8 (GH-9436)
Make UTF8 support for the IMAP APPEND command RFC 6855 compliant.
1 parent d3e3b2b commit 408154d

File tree

3 files changed

+26
-12
lines changed

3 files changed

+26
-12
lines changed

Lib/imaplib.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -497,8 +497,6 @@ def append(self, mailbox, flags, date_time, message):
497497
else:
498498
date_time = None
499499
literal = MapCRLF.sub(CRLF, message)
500-
if self.utf8_enabled:
501-
literal = b'UTF8 (' + literal + b')'
502500
self.literal = literal
503501
return self._simple_command(name, mailbox, flags, date_time)
504502

@@ -1119,7 +1117,11 @@ def _command(self, name, *args):
11191117
literator = literal
11201118
else:
11211119
literator = None
1122-
data = data + bytes(' {%s}' % len(literal), self._encoding)
1120+
if self.utf8_enabled:
1121+
data = data + bytes(' UTF8 (~{%s}' % len(literal), self._encoding)
1122+
literal = literal + b')'
1123+
else:
1124+
data = data + bytes(' {%s}' % len(literal), self._encoding)
11231125

11241126
if __debug__:
11251127
if self.debug >= 4:

Lib/test/test_imaplib.py

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,11 @@ def cmd_AUTHENTICATE(self, tag, args):
372372
self._send_tagged(tag, 'OK', 'FAKEAUTH successful')
373373
def cmd_APPEND(self, tag, args):
374374
self._send_textline('+')
375-
self.server.response = yield
375+
self.server.response = args
376+
literal = yield
377+
self.server.response.append(literal)
378+
literal = yield
379+
self.server.response.append(literal)
376380
self._send_tagged(tag, 'OK', 'okay')
377381
client, server = self._setup(UTF8AppendServer)
378382
self.assertEqual(client._encoding, 'ascii')
@@ -383,10 +387,13 @@ def cmd_APPEND(self, tag, args):
383387
self.assertEqual(code, 'OK')
384388
self.assertEqual(client._encoding, 'utf-8')
385389
msg_string = 'Subject: üñí©öðé'
386-
typ, data = client.append(None, None, None, msg_string.encode('utf-8'))
390+
typ, data = client.append(
391+
None, None, None, (msg_string + '\n').encode('utf-8'))
387392
self.assertEqual(typ, 'OK')
388393
self.assertEqual(server.response,
389-
('UTF8 (%s)\r\n' % msg_string).encode('utf-8'))
394+
['INBOX', 'UTF8',
395+
'(~{25}', ('%s\r\n' % msg_string).encode('utf-8'),
396+
b')\r\n' ])
390397

391398
def test_search_disallows_charset_in_utf8_mode(self):
392399
class UTF8Server(SimpleIMAPHandler):
@@ -881,7 +888,11 @@ def test_enable_UTF8_True_append(self):
881888
class UTF8AppendServer(self.UTF8Server):
882889
def cmd_APPEND(self, tag, args):
883890
self._send_textline('+')
884-
self.server.response = yield
891+
self.server.response = args
892+
literal = yield
893+
self.server.response.append(literal)
894+
literal = yield
895+
self.server.response.append(literal)
885896
self._send_tagged(tag, 'OK', 'okay')
886897

887898
with self.reaped_pair(UTF8AppendServer) as (server, client):
@@ -895,12 +906,12 @@ def cmd_APPEND(self, tag, args):
895906
self.assertEqual(client._encoding, 'utf-8')
896907
msg_string = 'Subject: üñí©öðé'
897908
typ, data = client.append(
898-
None, None, None, msg_string.encode('utf-8'))
909+
None, None, None, (msg_string + '\n').encode('utf-8'))
899910
self.assertEqual(typ, 'OK')
900-
self.assertEqual(
901-
server.response,
902-
('UTF8 (%s)\r\n' % msg_string).encode('utf-8')
903-
)
911+
self.assertEqual(server.response,
912+
['INBOX', 'UTF8',
913+
'(~{25}', ('%s\r\n' % msg_string).encode('utf-8'),
914+
b')\r\n' ])
904915

905916
# XXX also need a test that makes sure that the Literal and Untagged_status
906917
# regexes uses unicode in UTF8 mode instead of the default ASCII.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
UTF8 support for the IMAP APPEND command has been made RFC compliant.

0 commit comments

Comments
 (0)