summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2023-03-09 17:58:51 +0530
committerGitHub <noreply@github.com>2023-03-09 12:28:51 +0000
commit99da8a69e7260b72e55d7214ec96f6ac5e759f35 (patch)
treed4cf310d7d029176fb187c3a3707d2e480514197
parentc3cba7f22c49ca3a3f58df44d8ea4c85d8510bff (diff)
fix(ext/webstorage): check size of inputs before insert (#18087)
-rw-r--r--cli/tests/unit/webstorage_test.ts31
-rw-r--r--ext/webstorage/lib.rs27
2 files changed, 48 insertions, 10 deletions
diff --git a/cli/tests/unit/webstorage_test.ts b/cli/tests/unit/webstorage_test.ts
index 25813ac03..e6ca5bb88 100644
--- a/cli/tests/unit/webstorage_test.ts
+++ b/cli/tests/unit/webstorage_test.ts
@@ -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",
+ );
+});
diff --git a/ext/webstorage/lib.rs b/ext/webstorage/lib.rs
index e98b5da41..ca96b01bc 100644
--- a/ext/webstorage/lib.rs
+++ b/ext/webstorage/lib.rs
@@ -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 (?, ?)")?;