Skip to content

gh-145968: fix base64.b64decode altchars translation in specific cases#145969

Merged
serhiy-storchaka merged 3 commits intopython:mainfrom
mayeut:base64-bad-translation
Mar 15, 2026
Merged

gh-145968: fix base64.b64decode altchars translation in specific cases#145969
serhiy-storchaka merged 3 commits intopython:mainfrom
mayeut:base64-bad-translation

Conversation

@mayeut
Copy link
Contributor

@mayeut mayeut commented Mar 15, 2026

When altchars overlaps with the standard ones, the translation does not always yield to the expected outcome.
This updates bytes.maketrans arguments to take those overlap cases into account.

…c cases

When `altchars` overlaps with the standard ones, the translation does not always yield to the expected outcome.
This commit updates `bytes.maketrans` arguments to take those overlap cases into account.
@python-cla-bot
Copy link

python-cla-bot bot commented Mar 15, 2026

All commit authors signed the Contributor License Agreement.

CLA signed

@mayeut
Copy link
Contributor Author

mayeut commented Mar 15, 2026

cc @serhiy-storchaka

Lib/base64.py Outdated
Comment on lines +103 to +113
altchars_out = (
altchars[0] if altchars[0] not in b'+/' else altchars[1],
altchars[1] if altchars[1] not in b'+/' else altchars[0],
)
trans_in = bytearray(altchars)
trans_out = bytearray(b'+/')
for b, b_out in zip(b'+/', altchars_out):
if b not in altchars:
trans_in.append(b)
trans_out.append(b_out)
trans = bytes.maketrans(trans_in, trans_out)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can be simply:

Suggested change
altchars_out = (
altchars[0] if altchars[0] not in b'+/' else altchars[1],
altchars[1] if altchars[1] not in b'+/' else altchars[0],
)
trans_in = bytearray(altchars)
trans_out = bytearray(b'+/')
for b, b_out in zip(b'+/', altchars_out):
if b not in altchars:
trans_in.append(b)
trans_out.append(b_out)
trans = bytes.maketrans(trans_in, trans_out)
trans = bytes.maketrans(altchars + bytes(set(b'+/') - set(altchars)),
b'+/' + bytes(set(altchars) - set(b'+/')))

Copy link
Contributor Author

@mayeut mayeut Mar 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I commited the suggestion but after further reflection, the sets are unordered and thus the translation might not be correct when altchars and standard ones do not overlap (although this might be hard to catch in tests ?).
I'll fix that later

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. What about the following?

trans_in = altchars
trans_out = b'+/'
if b'+' not in altchars and b'-' not in altchars:
    trans_in += b'+/'
    trans_out += altchars
elif b'+' not in altchars or b'-' not in altchars:
    trans_in += bytes(set(b'+/') - set(altchars))
    trans_out += bytes(set(altchars) - set(b'+/'))

You can also return your original code. #145981 also fixes this issue, so this code can be replaced, but your tests will remain.

mayeut and others added 2 commits March 15, 2026 11:36
Copy link
Member

@serhiy-storchaka serhiy-storchaka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. 👍

@serhiy-storchaka serhiy-storchaka merged commit ec5e3a5 into python:main Mar 15, 2026
51 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants