Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't open files with '#' in their names when using immutable flag in sqlite #2460

Closed
uttarayan21 opened this issue Apr 18, 2023 · 1 comment · Fixed by #2655
Closed

Can't open files with '#' in their names when using immutable flag in sqlite #2460

uttarayan21 opened this issue Apr 18, 2023 · 1 comment · Fixed by #2655
Labels

Comments

@uttarayan21
Copy link
Contributor

uttarayan21 commented Apr 18, 2023

Bug Description

Cannot open sqlite database files when the immutable flag is used and the file name contains the '#' symbol

Minimal Reproduction

A small code snippet or a link to a Github repo or Gist, with instructions on reproducing the bug.

use core::str::FromStr;

use sqlite::*;
use sqlx::*;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    connect("fine.db".to_string()).await?;
    println!("Opens Fine");
    connect("error#.db".to_string()).await?;
    unreachable!();
    Ok(())
}

pub async fn connect(path: String) -> Result<(), Box<dyn std::error::Error>> {
    SqliteConnectOptions::from_str(&format!("sqlite://{path}"))?
        .immutable(true)
        .connect()
        .await?;
    Ok(())
}

The same happens when using SqliteCOnnectOptions::new().filename(path) as well

Info

  • SQLx version: 0.5.9 / 0.6.3 / 0.7.0-alpha.2
  • SQLx features enabled: sqlite+ runtime-tokio-native-tls / sqlite + runtime-tokio
  • Database server and version: [REQUIRED] (SQLite <x.y.z>) ( libsqlite3-sys v0.25.2 )
  • Operating system: MacOS Ventura 13.2
  • rustc --version: rustc 1.68.2 (9eb3afe9e 2023-03-27)
@spector-9
Copy link

spector-9 commented Apr 18, 2023

So after looking a little bit, the issues seems to be related to the query_params vec in establish.rs. Therefore the issue is not limited to immutable flag but related to the vector itself. Since we are formatting the file name like this only if the query_params has an element.

filename = format!("file:{}?{}", filename, query_params.join("&"));

So somehow this formatting is causing problem.

[/tmp/sqlx/sqlx-sqlite/src/connection/establish.rs:142] filename = "error#.db"

However this doesn't

[/tmp/sqlx/sqlx-sqlite/src/connection/establish.rs:142] filename = "file:error#.db?immutable=true"

EDIT

So I understand the problem now. The problem is that the file: parameter expect the pound symbol to be converted to url encoding however that's not possible due to this

[/tmp/sqlx/sqlx-sqlite/src/options/parse.rs:26] &*percent_decode_str(database).decode_utf8().map_err(Error::config)? = "error#.db"

Even if I manually convert hash to %23 it will convert it back to pound character and then the file: parameter will fail since it's expecting %23 and not a pound symbol.

A simple but not a great fix is

        if !query_params.is_empty() {
        // This line to encode the filename to url encoding in sqlx/sqlx-sqlite/src/connection/establish.rs line 103
            filename = urlencoding::encode(&filename).to_string();
            filename = format!("file:{}?{}", filename, query_params.join("&"));
            flags |= libsqlite3_sys::SQLITE_OPEN_URI;
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants