fix: avoid panic when truncating multi-byte DB error messages - #272
Open
MoneyBund wants to merge 1 commit into
Open
fix: avoid panic when truncating multi-byte DB error messages#272MoneyBund wants to merge 1 commit into
MoneyBund wants to merge 1 commit into
Conversation
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.
fix: avoid panic when truncating multi-byte DB error messages
Summary
sanitize_db_errortruncated over-long messages with&error[..500], a byteslice. When byte 500 lands in the middle of a multi-byte UTF-8 codepoint, that
slice panics with
byte index 500 is not a char boundary.The body of a PostgreSQL error is attacker-controlled: Postgres echoes the
offending literal back verbatim (
invalid input syntax for type bigint: "…").A caller can therefore craft a
/queryrequest whose resulting error message isjust over 500 bytes with a 2- or 4-byte character straddling the cut point, and
the request-handling task panics.
The router mounts only
CorsLayer+TraceLayer(noCatchPanicLayer) and thecrate builds with the default
panic = "unwind", so the panic unwinds theconnection task and the client's connection is reset with no HTTP response —
a trivially scriptable availability nuisance.
Reproduction (before)
Postgres returns a
>500-byte error; the slice lands mid-codepoint → panic →dropped connection instead of a clean
422.Fix
Truncate on a character boundary using
char_indices(), and cap by charactercount rather than byte length:
char_indices().nth(n)yields the byte offset of then-th character, which isalways a valid boundary, so the slice can never split a codepoint. The retained
prefix is unchanged for the common all-ASCII case.
Tests
Added
test_sanitize_truncates_multibyte_without_panic, which sweeps the padlength across the boundary (495..505) with 2-byte
éand a 4-byte emoji. Withoutthe fix these inputs panic. Existing sanitizer tests still pass (
cargo test --lib sanitize).