1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-05 13:59:01 -05:00

fix(ext/webstorage): check size of inputs before insert (#18087)

This commit is contained in:
Divy Srivastava 2023-03-09 17:58:51 +05:30 committed by Yoshiya Hinosawa
parent 9ebbd23ced
commit 716409e81e
2 changed files with 48 additions and 10 deletions

View file

@ -1,7 +1,7 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
// deno-lint-ignore-file no-explicit-any
import { assert } from "./test_util.ts";
import { assert, assertThrows } from "./test_util.ts";
Deno.test({ permissions: "none" }, function webStoragesReassignable() {
// Can reassign to web storages
@ -11,3 +11,32 @@ Deno.test({ permissions: "none" }, function webStoragesReassignable() {
assert(globalThis.localStorage instanceof globalThis.Storage);
assert(globalThis.sessionStorage instanceof globalThis.Storage);
});
Deno.test(function webstorageSizeLimit() {
localStorage.clear();
assertThrows(
() => {
localStorage.setItem("k", "v".repeat(15 * 1024 * 1024));
},
Error,
"Exceeded maximum storage size",
);
assert(localStorage.getItem("k") === null);
assertThrows(
() => {
localStorage.setItem("k".repeat(15 * 1024 * 1024), "v");
},
Error,
"Exceeded maximum storage size",
);
assertThrows(
() => {
localStorage.setItem(
"k".repeat(5 * 1024 * 1024),
"v".repeat(5 * 1024 * 1024),
);
},
Error,
"Exceeded maximum storage size",
);
});

View file

@ -19,7 +19,7 @@ pub use rusqlite;
#[derive(Clone)]
struct OriginStorageDir(PathBuf);
const MAX_STORAGE_BYTES: u32 = 10 * 1024 * 1024;
const MAX_STORAGE_BYTES: usize = 10 * 1024 * 1024;
pub fn init(origin_storage_dir: Option<PathBuf>) -> Extension {
Extension::builder_with_deps(env!("CARGO_PKG_NAME"), &["deno_webidl"])
@ -133,6 +133,20 @@ pub fn op_webstorage_key(
Ok(key)
}
#[inline]
fn size_check(input: usize) -> Result<(), AnyError> {
if input >= MAX_STORAGE_BYTES {
return Err(
deno_web::DomExceptionQuotaExceededError::new(
"Exceeded maximum storage size",
)
.into(),
);
}
Ok(())
}
#[op]
pub fn op_webstorage_set(
state: &mut OpState,
@ -142,18 +156,13 @@ pub fn op_webstorage_set(
) -> Result<(), AnyError> {
let conn = get_webstorage(state, persistent)?;
size_check(key.len() + value.len())?;
let mut stmt = conn
.prepare_cached("SELECT SUM(pgsize) FROM dbstat WHERE name = 'data'")?;
let size: u32 = stmt.query_row(params![], |row| row.get(0))?;
if size >= MAX_STORAGE_BYTES {
return Err(
deno_web::DomExceptionQuotaExceededError::new(
"Exceeded maximum storage size",
)
.into(),
);
}
size_check(size as usize)?;
let mut stmt = conn
.prepare_cached("INSERT OR REPLACE INTO data (key, value) VALUES (?, ?)")?;