summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Erhardt <kolab@sicherha.de>2022-05-08 10:09:24 +0200
committerChristoph Erhardt <kolab@sicherha.de>2022-05-08 10:10:00 +0200
commit8add8bba35df98a087225bfa9f0c534702c3e51d (patch)
tree1b5186f518b68bc9be1f04f5c91c87d9ec47938e
parent87463ed0703e1fdb5793d5f5e4bd43ac298cad38 (diff)
downloadpykolab-8add8bba35df98a087225bfa9f0c534702c3e51d.tar.gz
[Python 3] imap4-utf-7 codec implementation to Python 3
Summary: Implementation of accepted twistedmatrix Python3 patch #6289 to pykolab/imap_utf7.py https://twistedmatrix.com/trac/attachment/ticket/6289/imap4.patch #6289 enhancement closed fixed (fixed) Port imap4-utf-7 codec implementation to Python 3 Tested with Debian 10 Python versions 2.7, 3.7 Reviewers: #pykolab_developers, sicherha Reviewed By: #pykolab_developers, sicherha Subscribers: sicherha Differential Revision: https://git.kolab.org/D3508
-rw-r--r--pykolab/imap_utf7.py52
1 files changed, 32 insertions, 20 deletions
diff --git a/pykolab/imap_utf7.py b/pykolab/imap_utf7.py
index 0ecb83c..152609c 100644
--- a/pykolab/imap_utf7.py
+++ b/pykolab/imap_utf7.py
@@ -22,58 +22,70 @@
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+# https://twistedmatrix.com/trac/attachment/ticket/6289/imap4.patch
+# #6289 enhancement closed fixed (fixed)
+# Port imap4-utf-7 codec implementation to Python 3
class FolderNameError(ValueError):
pass
+try:
+ unicode()
+except:
+ unicode = str
+
+memory_cast = getattr(memoryview, "cast", lambda *x: x[0])
+
def encode(s):
if isinstance(s, str) and sum(n for n in (ord(c) for c in s) if n > 127):
try:
- s = unicode(s, "UTF-8")
+ s = bytes(s, "UTF-8")
except Exception:
raise FolderNameError("%r contains characters not valid in a str folder name. "
- "Convert to unicode first?" % s)
+ "Convert to unicode first?" % s)
- r = []
+ r = bytearray()
_in = []
+ valid_chars = set(map(chr, range(0x20, 0x7f))) - {u"&"}
for c in s:
- if ord(c) in (range(0x20, 0x26) + range(0x27, 0x7f)):
+ if c in valid_chars:
if _in:
- r.extend(['&', modified_base64(''.join(_in)), '-'])
+ r += b'&' + modified_base64(''.join(_in)) + b'-'
del _in[:]
- r.append(str(c))
- elif c == '&':
+ r.append(ord(c))
+ elif c == u'&':
if _in:
- r.extend(['&', modified_base64(''.join(_in)), '-'])
+ r += b'&' + modified_base64(''.join(_in)) + b'-'
del _in[:]
- r.append('&-')
+ r += b'&-'
else:
_in.append(c)
if _in:
- r.extend(['&', modified_base64(''.join(_in)), '-'])
+ r.extend(b'&' + modified_base64(''.join(_in)) + b'-')
- return ''.join(r)
+ return bytes(r)
def decode(s):
r = []
decode = []
+ s = memory_cast(memoryview(s), 'c')
for c in s:
- if c == '&' and not decode:
- decode.append('&')
- elif c == '-' and decode:
+ if c == b'&' and not decode:
+ decode.append(u'&')
+ elif c == b'-' and decode:
if len(decode) == 1:
- r.append('&')
+ r.append(u'&')
else:
- r.append(modified_unbase64(''.join(decode[1:])))
+ r.append(modified_unbase64(b''.join(decode[1:])))
decode = []
elif decode:
decode.append(c)
else:
- r.append(c)
+ r.append(c.decode())
if decode:
- r.append(modified_unbase64(''.join(decode[1:])))
+ r.append(modified_unbase64(b''.join(decode[1:])))
out = ''.join(r)
if not isinstance(out, unicode):
@@ -83,9 +95,9 @@ def decode(s):
def modified_base64(s):
s_utf7 = s.encode('utf-7')
- return s_utf7[1:-1].replace('/', ',')
+ return s_utf7[1:-1].replace(b'/', b',')
def modified_unbase64(s):
- s_utf7 = '+' + s.replace(',', '/') + '-'
+ s_utf7 = b'+' + s.replace(b',', b'/') + b'-'
return s_utf7.decode('utf-7')