I have found these related issues/pull requests
#4192, #4193 are both UTF-8 related bug, but not the same one.
Description
SqliteConnectOptions::collation() and LockedSqliteHandle::create_collation() expose a safe callback signature Fn(&str, &str) -> Ordering, but the SQLite callback implementation currently converts raw SQLite bytes to &str with std::str::from_utf8_unchecked.
SQLite explicitly documents that invalid UTF may be passed into application-defined collating sequences. That means a database containing invalid UTF-8 text can reach this callback and cause SQLx to construct invalid &str values inside a safe API.
Reproduction steps
use std::str::FromStr;
use sqlx::sqlite::SqliteConnectOptions;
use sqlx::ConnectOptions;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let opts = SqliteConnectOptions::from_str("sqlite::memory:")?
.collation("bug", |a, b| a.cmp(b));
let mut conn = opts.connect().await?;
sqlx::query("CREATE TABLE t (s TEXT NOT NULL)")
.execute(&mut conn)
.await?;
// Stores a TEXT value containing invalid UTF-8.
sqlx::query("INSERT INTO t (s) VALUES ('a'), (CAST(x'80' AS TEXT))")
.execute(&mut conn)
.await?;
// Triggers the custom collation callback on the invalid TEXT value.
let _rows = sqlx::query("SELECT hex(s) FROM t ORDER BY s COLLATE bug")
.fetch_all(&mut conn)
.await?;
Ok(())
}
SQLx version
main branch
Enabled SQLx features
default
Database server and version
SQLite
Operating system
MacOS
Rust version
1.94.0 (4a4ef493e 2026-03-02)