8000 bpo-31116: Add Z85 variant to base64 by matan1008 · Pull Request #30598 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

bpo-31116: Add Z85 variant to base64 #30598

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Feb 25, 2024
Prev Previous commit
Next Next commit
bpo-31116: Handle z85 errors
  • Loading branch information
matan1008 committed Feb 25, 2024
commit c87c77ec1fb02238ced2bb6d995240b87417901d
13 changes: 11 additions & 2 deletions Lib/base64.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,13 @@ def b85decode(b):

_z85alphabet = (b'0123456789abcdefghijklmnopqrstuvwxyz'
b'ABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/*?&<>()[]{}@%$#')
_z85_decode_translation = bytes.maketrans(_z85alphabet, _b85alphabet)
# Translating b85 valid but z85 invalid chars to b'\x00' is required
# to prevent them from being decoded as b85 valid chars.
_z85_b85_decode_diff = b';_`|~'
_z85_decode_translation = bytes.maketrans(
_z85alphabet + _z85_b85_decode_diff,
_b85alphabet + b'\x00' * len(_z85_b85_decode_diff)
)
_z85_encode_translation = bytes.maketrans(_b85alphabet, _z85alphabet)

def z85encode(s):
Expand All @@ -513,7 +519,10 @@ def z85decode(s):
"""
s = _bytes_from_decode_data(s)
s = s.translate(_z85_decode_translation)
return b85decode(s)
try:
return b85decode(s)
except ValueError as e:
raise ValueError(e.args[0].replace('base85', 'z85')) from None

# Legacy interface. This code could be cleaned up since I don't believe
# binascii has any line length limitations. It just doesn't seem worth it
Expand Down
15 changes: 15 additions & 0 deletions Lib/test/test_base64.py
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,21 @@ def test_b85decode_errors(self):
self.assertRaises(ValueError, base64.b85decode, b'|NsC')
self.assertRaises(ValueError, base64.b85decode, b'|NsC1')

def test_z85decode_errors(self):
illegal = list(range(33)) + \
list(b'"\',;_`|\\~') + \
list(range(128, 256))
for c in illegal:
with self.assertRaises(ValueError, msg=bytes([c])):
base64.z85decode(b'0000' + bytes([c]))

# b'\xff\xff\xff\xff' encodes to b'%nSc0', the following will overflow:
self.assertRaises(ValueError, base64.z85decode, b'%')
self.assertRaises(ValueError, base64.z85decode, b'%n')
self.assertRaises(ValueError, base64.z85decode, b'%nS')
self.assertRaises(ValueError, base64.z85decode, b'%nSc')
self.assertRaises(ValueError, base64.z85decode, b'%nSc1')

def test_decode_nonascii_str(self):
decode_funcs = (base64.b64decode,
base64.standard_b64decode,
Expand Down
0