base64ct: decode_in_place rejects non-zero trailing bits like decode - #2459
Open
yuxi-liu-wired wants to merge 1 commit into
Open
yuxi-liu-wired wants to merge 1 commit into
yuxi-liu-wired wants to merge 1 commit into
Conversation
`decode` checks that the last block round-trips (`validate_last_block`, added in RustCrypto#680 for RustCrypto#679), so an encoding with non-zero trailing bits such as "AB==" (canonical: "AA==" for 0x00) is rejected. `decode_in_place` never got that check: it accepted "AB==", "Mi" (unpadded) and similar, returning the same bytes as the canonical form. So two different strings decoded to the same output, and `decode` and `decode_in_place` disagreed on what is valid Base64. Save the last input block (at most 4 bytes) before it is overwritten and validate it against the decoded output, as `decode` does. Test: a proptest that `decode_in_place` and `decode_vec` accept the same inputs with the same output, and a regression test for "AB==" / "AB".
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Encoding::decodechecks that the last block round-trips (validate_last_block, added in #680 for #679), so an encoding with non-zero trailing bits is rejected.decode_in_placenever got that check:So
decodeanddecode_in_placedisagree on which strings are valid Base64, and withdecode_in_placeseveral different strings decode to the same bytes. That is exactly what #679 fixed fordecode.The input buffer is overwritten while decoding, so this PR saves its last block (at most 4 bytes, including padding) first, then runs the same
validate_last_blockon the result.Tests in
tests/proptests.rs:decode_in_place_equiv: a proptest thatdecode_in_placeaccepts exactly whatdecode_vecaccepts, with the same output, forBase64andBase64Unpadded.decode_in_place_rejects_trailing_bits: a regression test for"AB=="/"AB", and a check that"AA=="still decodes.Both fail on master (minimal failing input:
"++").This PR was produced by AI agents (Claude) while fuzzing
base64ctagainst thebase64crate.