fix(ext/kv): don't request permissions for ":memory:" (#18346)

Currently `Deno.openKv(":memory:")` requests read+write permissions for
`./:memory:` even though no file is read or written. Also added some
guards for special sqlite paths that were unintentionally opted into.
This commit is contained in:
Nayeem Rahman 2023-03-22 10:49:29 +00:00 committed by GitHub
parent 92ebf4afe5
commit 5804d7434e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 2 deletions

View File

@ -7,6 +7,32 @@ import {
assertThrows,
} from "./test_util.ts";
Deno.test({
name: "openKv :memory: no permissions",
permissions: {},
async fn() {
const db = await Deno.openKv(":memory:");
await db.close();
},
});
Deno.test({
name: "openKv invalid filenames",
permissions: {},
async fn() {
await assertRejects(
async () => await Deno.openKv(""),
TypeError,
"Filename cannot be empty",
);
await assertRejects(
async () => await Deno.openKv(":foo"),
TypeError,
"Filename cannot start with ':' unless prefixed with './'",
);
},
});
function dbTest(name: string, fn: (db: Deno.Kv) => Promise<void>) {
Deno.test({
name,

View File

@ -12,6 +12,7 @@ use deno_core::error::type_error;
use deno_core::error::AnyError;
use deno_core::OpState;
use rusqlite::params;
use rusqlite::OpenFlags;
use rusqlite::OptionalExtension;
use rusqlite::Transaction;
@ -111,10 +112,18 @@ impl<P: SqliteDbHandlerPermissions> DatabaseHandler for SqliteDbHandler<P> {
path: Option<String>,
) -> Result<Self::DB, AnyError> {
let conn = match (path.as_deref(), &self.default_storage_dir) {
(Some(":memory:") | None, None) => {
(Some(":memory:"), _) | (None, None) => {
rusqlite::Connection::open_in_memory()?
}
(Some(path), _) => {
if path.is_empty() {
return Err(type_error("Filename cannot be empty"));
}
if path.starts_with(':') {
return Err(type_error(
"Filename cannot start with ':' unless prefixed with './'",
));
}
let path = Path::new(path);
{
let mut state = state.borrow_mut();
@ -122,7 +131,8 @@ impl<P: SqliteDbHandlerPermissions> DatabaseHandler for SqliteDbHandler<P> {
permissions.check_read(path, "Deno.openKv")?;
permissions.check_write(path, "Deno.openKv")?;
}
rusqlite::Connection::open(path)?
let flags = OpenFlags::default().difference(OpenFlags::SQLITE_OPEN_URI);
rusqlite::Connection::open_with_flags(path, flags)?
}
(None, Some(path)) => {
std::fs::create_dir_all(path)?;