-
Notifications
You must be signed in to change notification settings - Fork 27
[BUG] SQL LIKE wildcard characters in path prefix cause incorrect search results #175
Description
Project
vgrep
Description
The search_similar() function in src/core/db.rs does not escape SQL LIKE wildcard characters (_ and %) in path prefixes. This causes searches to return files from unintended directories when the path contains underscores.
Error Message
Debug Logs
System Information
## Operating System
ProductName: macOS
ProductVersion: 26.2
BuildVersion: 25C56
Arch: arm64
## Hardware
CPU: Apple M4 Pro
RAM: 24 GB
## Build Environment
Rust: rustc 1.92.0 (ded5c06cf 2025-12-08)
Target: aarch64Screenshots
No response
Steps to Reproduce
-
Create a project structure with similarly-named directories:
/home/user/my_project/main.rs /home/user/my-project/main.rs /home/user/myXproject/main.rs -
Index all directories with vgrep
-
Search with path prefix
/home/user/my_project:db.search_similar(&embedding, Path::new("/home/user/my_project"), 10);
-
Observe that files from
my-projectandmyXprojectare also returned
Minimal reproduction:
use rusqlite::{params, Connection};
fn main() {
let conn = Connection::open_in_memory().unwrap();
conn.execute_batch("CREATE TABLE files (path TEXT);").unwrap();
conn.execute("INSERT INTO files VALUES (?)", params!["/home/user/my_project/main.rs"]).unwrap();
conn.execute("INSERT INTO files VALUES (?)", params!["/home/user/my-project/main.rs"]).unwrap();
conn.execute("INSERT INTO files VALUES (?)", params!["/home/user/myXproject/main.rs"]).unwrap();
// This is what vgrep does at src/core/db.rs line 162
let pattern = format!("{}%", "/home/user/my_project");
let mut stmt = conn.prepare("SELECT path FROM files WHERE path LIKE ?").unwrap();
let paths: Vec<String> = stmt.query_map([&pattern], |r| r.get(0)).unwrap().filter_map(Result::ok).collect();
println!("Expected: 1 result, Got: {} results", paths.len());
// Output: Expected: 1 result, Got: 3 results
}Expected Behavior
Searching for path prefix /home/user/my_project should only return files under that exact directory:
/home/user/my_project/main.rs✓
Actual Behavior
Search returns files from unrelated directories because _ is a SQL LIKE wildcard matching any single character:
/home/user/my_project/main.rs✓ (correct)/home/user/my-project/main.rs✗ (unintended)/home/user/myXproject/main.rs✗ (unintended)
Additional Context
Root cause: Line 162 constructs the LIKE pattern without escaping:
let like_pattern = format!("{}%", path_prefix_str);Suggested fix:
fn escape_like_pattern(s: &str) -> String {
s.replace('\\', "\\\\").replace('%', "\\%").replace('_', "\\_")
}
let like_pattern = format!("{}%", escape_like_pattern(&path_prefix_str));And update the SQL query to include ESCAPE '\' clause.
Impact: Underscores are common in project names (node_modules, test_utils, my_app), making this bug likely to affect real users.