Merge branch 'master' into multiple_encoding_support. Dropping patch
for "Included charset detection"
This commit is contained in:
commit
f71ef226bf
@ -310,12 +310,8 @@ class IMAPServer:
|
||||
# This is a behavior we got from pykerberos. First byte is one,
|
||||
# first four bytes are preserved (pykerberos calls this a length).
|
||||
# Any additional bytes are username.
|
||||
reply = []
|
||||
reply[0:4] = response.message[0:4]
|
||||
reply[0] = '\x01'
|
||||
if self.username:
|
||||
reply[5:] = self.username
|
||||
reply = ''.join(reply)
|
||||
reply = b'\x01' + response.message[1:4]
|
||||
reply += bytes(self.username, 'utf-8')
|
||||
|
||||
response = self.gss_vc.wrap(reply, response.encrypted)
|
||||
return response.message if response.message else ""
|
||||
|
@ -18,6 +18,7 @@
|
||||
import re
|
||||
import binascii
|
||||
import codecs
|
||||
from typing import Tuple
|
||||
from offlineimap.ui import getglobalui
|
||||
|
||||
# Globals
|
||||
@ -352,42 +353,45 @@ def decode_mailbox_name(name):
|
||||
|
||||
def IMAP_utf8(foldername):
|
||||
"""Convert IMAP4_utf_7 encoded string to utf-8"""
|
||||
return foldername.decode('imap4-utf-7').encode('utf-8')
|
||||
return codecs.decode(
|
||||
foldername.encode(),
|
||||
'imap4-utf-7'
|
||||
).encode('utf-8').decode()
|
||||
|
||||
|
||||
def utf8_IMAP(foldername):
|
||||
"""Convert utf-8 encoded string to IMAP4_utf_7"""
|
||||
return foldername.decode('utf-8').encode('imap4-utf-7')
|
||||
return codecs.decode(
|
||||
foldername.encode(),
|
||||
'utf-8'
|
||||
).encode('imap4-utf-7').decode()
|
||||
|
||||
|
||||
# Codec definition
|
||||
|
||||
def modified_base64(s):
|
||||
s = s.encode('utf-16be')
|
||||
return binascii.b2a_base64(s).rstrip('\n=').replace('/', ',')
|
||||
return binascii.b2a_base64(s).rstrip(b'\n=').replace(b'/', b',')
|
||||
|
||||
|
||||
def doB64(_in, r):
|
||||
if _in:
|
||||
r.append('&%s-' % modified_base64(''.join(_in)))
|
||||
r.append(b'&%s-' % modified_base64(''.join(_in)))
|
||||
del _in[:]
|
||||
|
||||
|
||||
def encoder(s):
|
||||
def utf7m_encode(text: str) -> Tuple[bytes, int]:
|
||||
r = []
|
||||
_in = []
|
||||
for c in s:
|
||||
ordC = ord(c)
|
||||
if 0x20 <= ordC <= 0x25 or 0x27 <= ordC <= 0x7e:
|
||||
|
||||
for c in text:
|
||||
if 0x20 <= ord(c) <= 0x7e:
|
||||
doB64(_in, r)
|
||||
r.append(c)
|
||||
elif c == '&':
|
||||
doB64(_in, r)
|
||||
r.append('&-')
|
||||
r.append(b'&-' if c == '&' else c.encode())
|
||||
else:
|
||||
_in.append(c)
|
||||
|
||||
doB64(_in, r)
|
||||
return str(''.join(r)), len(s)
|
||||
return b''.join(r), len(text)
|
||||
|
||||
|
||||
# decoding
|
||||
@ -396,10 +400,10 @@ def modified_unbase64(s):
|
||||
return str(b, 'utf-16be')
|
||||
|
||||
|
||||
def decoder(s):
|
||||
def utf7m_decode(binary: bytes) -> Tuple[str, int]:
|
||||
r = []
|
||||
decode = []
|
||||
for c in s:
|
||||
for c in binary.decode():
|
||||
if c == '&' and not decode:
|
||||
decode.append('&')
|
||||
elif c == '-' and decode:
|
||||
@ -415,26 +419,31 @@ def decoder(s):
|
||||
|
||||
if decode:
|
||||
r.append(modified_unbase64(''.join(decode[1:])))
|
||||
bin_str = ''.join(r)
|
||||
return bin_str, len(s)
|
||||
|
||||
return ''.join(r), len(binary)
|
||||
|
||||
|
||||
class StreamReader(codecs.StreamReader):
|
||||
def decode(self, s, errors='strict'):
|
||||
return decoder(s)
|
||||
return utf7m_decode(s)
|
||||
|
||||
|
||||
class StreamWriter(codecs.StreamWriter):
|
||||
def decode(self, s, errors='strict'):
|
||||
return encoder(s)
|
||||
return utf7m_encode(s)
|
||||
|
||||
|
||||
def imap4_utf_7(name):
|
||||
if name == 'imap4-utf-7':
|
||||
return encoder, decoder, StreamReader, StreamWriter
|
||||
def utf7m_search_function(name):
|
||||
return codecs.CodecInfo(
|
||||
utf7m_encode,
|
||||
utf7m_decode,
|
||||
StreamReader,
|
||||
StreamWriter,
|
||||
name='imap4-utf-7'
|
||||
)
|
||||
|
||||
|
||||
codecs.register(imap4_utf_7)
|
||||
codecs.register(utf7m_search_function)
|
||||
|
||||
|
||||
def foldername_to_imapname(folder_name):
|
||||
|
@ -206,12 +206,23 @@ class IMAPRepository(BaseRepository):
|
||||
Returns: Returns the remoteusereval or remoteuser or netrc user value.
|
||||
|
||||
"""
|
||||
localeval = self.localeval
|
||||
|
||||
if self.config.has_option(self.getsection(), 'remoteusereval'):
|
||||
user = self.getconf('remoteusereval')
|
||||
if user is not None:
|
||||
return localeval.eval(user).encode('UTF-8')
|
||||
l_user = self.localeval.eval(user)
|
||||
|
||||
# We need a str username
|
||||
if isinstance(l_user, bytes):
|
||||
return l_user.decode(encoding='utf-8')
|
||||
elif isinstance(l_user, str):
|
||||
return l_user
|
||||
|
||||
# If is not bytes or str, we have a problem
|
||||
raise OfflineImapError("Could not get a right username format for"
|
||||
" repository %s. Type found: %s. "
|
||||
"Please, open a bug." %
|
||||
(self.name, type(l_user)),
|
||||
OfflineImapError.ERROR.FOLDER)
|
||||
|
||||
if self.config.has_option(self.getsection(), 'remoteuser'):
|
||||
# Assume the configuration file to be UTF-8 encoded so we must not
|
||||
@ -590,7 +601,20 @@ class IMAPRepository(BaseRepository):
|
||||
encoding='utf-8')
|
||||
password = file_desc.readline().strip()
|
||||
file_desc.close()
|
||||
return password.encode('UTF-8')
|
||||
|
||||
# We need a str password
|
||||
if isinstance(password, bytes):
|
||||
return password.decode(encoding='utf-8')
|
||||
elif isinstance(password, str):
|
||||
return password
|
||||
|
||||
# If is not bytes or str, we have a problem
|
||||
raise OfflineImapError("Could not get a right password format for"
|
||||
" repository %s. Type found: %s. "
|
||||
"Please, open a bug." %
|
||||
(self.name, type(password)),
|
||||
OfflineImapError.ERROR.FOLDER)
|
||||
|
||||
# 4. Read password from ~/.netrc.
|
||||
try:
|
||||
netrcentry = netrc.netrc().authenticators(self.gethost())
|
||||
|
Loading…
Reference in New Issue
Block a user