Skip to content

fix(rust): avoid char-boundary panic in parse_driver_uri - #40

Open
fornwall wants to merge 1 commit into
mainfrom
fix/rust-parse-driver-uri-char-boundary
Open

fix(rust): avoid char-boundary panic in parse_driver_uri#40
fornwall wants to merge 1 commit into
mainfrom
fix/rust-parse-driver-uri-char-boundary

Conversation

@fornwall

Copy link
Copy Markdown
Owner

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 + 3 can 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_opts API. A parse function should return Status::InvalidArguments on 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 original uri.len() > idx + 3 guard. The Windows std::fs::exists branch and the early length guard are untouched.

Test

Adds test_parse_driver_uri_non_ascii_no_panic, exercising db:éxxx (→ DriverLocator::Uri("db", "éxxx")) and profile:/€x (→ DriverLocator::Profile("€x")), asserting no panic.

cargo build -p adbc_driver_manager and cargo test -p adbc_driver_manager parse_driver_uri both pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XNCrC87g9MkppGpL4MDgh5

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
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.

1 participant