serdect: check the decoded length on the hex path too - #2463
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
array::deserialize_hex_or_bin is documented to fail "if the buffer isn't the exact same size as the resulting array". The binary path (SliceVisitor) checks LengthCheck, but the hex path (StrIntoBufVisitor) only decoded into the buffer, which base16ct accepts when the input is shorter. So a human-readable format accepted a short hex string and left the rest of the array zeroed: HexLowerOrBin<16> from 15 bytes of hex, or crypto-bigint's U256 from "34" (= 0x34; its full encoding is 64 hex digits). Apply the same LengthCheck to the decoded length before decoding: exact for arrays, an upper bound for slices (unchanged behaviour there).
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.
array::deserialize_hex_or_binis documented to fail "if thebufferisn't the exact same size as the resulting array". The binary path (SliceVisitor) enforces that throughLengthCheck. The human-readable path (StrIntoBufVisitor) only decodes into the buffer, andbase16ct::mixed::decodeaccepts shorter input, so a short hex string is accepted and the rest of the array is left zeroed:Downstream,
crypto-bigint0.7 deserializesUint/Intthrough this function. With JSON:elliptic-curve(ScalarValue) andecdsa(Signature) use it the same way. A truncated value is read as a different number instead of being rejected. For signatures the later range checks happen to reject my examples, but nothing in serdect stops it.The fix applies the same
LengthCheckto the decoded length (v.len() / 2) before decoding, giving the same "invalid length" error as the binary path. For slices the check is the existing upper bound, soslice::deserialize_hex_or_binbehaves as before. Odd-length input still reports "an even number of hex digits".Test:
deserialize_array_wrong_lengthintests/serde_json.rschecks that short and long hex strings are rejected for arrays (typed wrapper anddeserialize_hex_or_bin), and that slices still accept shorter input and reject longer. It fails on master. Theserdect.ymlmatrix passed locally (powerset on stable and 1.85, thumbv7em), along withsec1all-features tests, fmt and clippy.This PR was produced by AI agents (Claude) and reviewed by me before submission.