fix(rust): avoid char-boundary panic in parse_driver_uri - #40
Open
fornwall wants to merge 1 commit into
Open
Conversation
parse_driver_uri sliced the input URI by raw byte offsets computed from
the scheme colon index (`&uri[idx..idx + 2]`, `&uri[idx + 2..idx + 3]`,
etc.). When the character immediately after the scheme colon is multi-byte
UTF-8, `idx + 2` / `idx + 3` can land in the middle of a char, so the
slice panics (e.g. `parse_driver_uri("db:éxxx")` panicked with
"byte index 4 is not a char boundary"). This is reachable from the public
`ManagedDatabase::from_uri` / `from_uri_with_opts` API, where a parse
function is expected to return `Status::InvalidArguments` rather than panic.
Rewrite the slicing to be char-boundary-safe: the colon and the byte after
it are always valid boundaries, so operate on the remainder `&uri[idx..]`
using `starts_with(":/")` and `strip_prefix("://")` / `strip_prefix(":/")`.
Behavior for all valid ASCII inputs is preserved, including the bare
`profile://` edge case that keeps its trailing slash.
Add a unit test (`test_parse_driver_uri_non_ascii_no_panic`) covering
non-ASCII URIs (`db:éxxx`, `profile:/€x`) to ensure no panic.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XNCrC87g9MkppGpL4MDgh5
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.
Problem
parse_driver_uri(rust/driver_manager/src/search.rs) sliced the input URI by raw byte offsets derived from the scheme colon index —&uri[idx..idx + 2],&uri[idx + 2..idx + 3],&uri[idx + 3..],&uri[idx + 2..]. When the character right after the scheme colon is multi-byte UTF-8,idx + 2/idx + 3can land in the middle of a char, so the slice panics.Example:
parse_driver_uri("db:éxxx")→idx = 2,&uri[2..4]cuts the 2-byteé→panic: byte index 4 is not a char boundary.This is reachable from the public
ManagedDatabase::from_uri/from_uri_with_optsAPI. A parse function should returnStatus::InvalidArgumentson bad input, never panic.Fix
The colon (
idx) and the byte after it (idx + 1) are always valid char boundaries because:is a single byte, so the remainder&uri[idx..]is a valid slice. Rewrite the offset arithmetic using boundary-safe operations:&uri[idx..idx + 2] == ":/"→uri[idx..].starts_with(":/")"://"detection + remainder slices →strip_prefix("://")/strip_prefix(":/")on&uri[idx..]Behavior is preserved for all valid ASCII inputs, including the bare
profile://edge case (empty remainder after://) which keeps its trailing slash via the:/branch, matching the originaluri.len() > idx + 3guard. The Windowsstd::fs::existsbranch and the early length guard are untouched.Test
Adds
test_parse_driver_uri_non_ascii_no_panic, exercisingdb:éxxx(→DriverLocator::Uri("db", "éxxx")) andprofile:/€x(→DriverLocator::Profile("€x")), asserting no panic.cargo build -p adbc_driver_managerandcargo test -p adbc_driver_manager parse_driver_uriboth pass.🤖 Generated with Claude Code
https://claude.ai/code/session_01XNCrC87g9MkppGpL4MDgh5