Skip to content

Commit

Permalink
fix(ext/web): webstorage has trap for symbol (denoland#21090)
Browse files Browse the repository at this point in the history
  • Loading branch information
petamoriken committed Nov 14, 2023
1 parent e54e8d4 commit 8866521
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 27 deletions.
14 changes: 12 additions & 2 deletions cli/tests/unit/webstorage_test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
// deno-lint-ignore-file no-explicit-any

import { assert, assertThrows } from "./test_util.ts";
import { assert, assertEquals, assertThrows } from "./test_util.ts";

Deno.test({ permissions: "none" }, function webStoragesReassignable() {
// Can reassign to web storages
Expand All @@ -21,7 +21,7 @@ Deno.test(function webstorageSizeLimit() {
Error,
"Exceeded maximum storage size",
);
assert(localStorage.getItem("k") === null);
assertEquals(localStorage.getItem("k"), null);
assertThrows(
() => {
localStorage.setItem("k".repeat(15 * 1024 * 1024), "v");
Expand All @@ -40,3 +40,13 @@ Deno.test(function webstorageSizeLimit() {
"Exceeded maximum storage size",
);
});

Deno.test(function webstorageProxy() {
localStorage.clear();
localStorage.foo = "foo";
assertEquals(localStorage.foo, "foo");
const symbol = Symbol("bar");
localStorage[symbol as any] = "bar";
assertEquals(localStorage[symbol as any], "bar");
assertEquals(symbol in localStorage, true);
});
53 changes: 28 additions & 25 deletions ext/webstorage/01_webstorage.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ const ops = core.ops;
import * as webidl from "ext:deno_webidl/00_webidl.js";
const primordials = globalThis.__bootstrap.primordials;
const {
SafeArrayIterator,
Symbol,
SymbolFor,
ObjectDefineProperty,
ObjectFromEntries,
ObjectEntries,
ReflectDefineProperty,
ReflectDeleteProperty,
ReflectGet,
ReflectHas,
Proxy,
Expand Down Expand Up @@ -83,51 +83,54 @@ function createStorage(persistent) {

const proxy = new Proxy(storage, {
deleteProperty(target, key) {
if (typeof key == "symbol") {
delete target[key];
} else {
target.removeItem(key);
if (typeof key === "symbol") {
return ReflectDeleteProperty(target, key);
}
target.removeItem(key);
return true;
},

defineProperty(target, key, descriptor) {
if (typeof key == "symbol") {
ObjectDefineProperty(target, key, descriptor);
} else {
target.setItem(key, descriptor.value);
if (typeof key === "symbol") {
return ReflectDefineProperty(target, key, descriptor);
}
target.setItem(key, descriptor.value);
return true;
},
get(target, key) {
if (typeof key == "symbol") return target[key];

get(target, key, receiver) {
if (typeof key === "symbol") {
return target[key];
}
if (ReflectHas(target, key)) {
return ReflectGet(...new SafeArrayIterator(arguments));
} else {
return target.getItem(key) ?? undefined;
return ReflectGet(target, key, receiver);
}
return target.getItem(key) ?? undefined;
},

set(target, key, value) {
if (typeof key == "symbol") {
ObjectDefineProperty(target, key, {
if (typeof key === "symbol") {
return ReflectDefineProperty(target, key, {
value,
configurable: true,
});
} else {
target.setItem(key, value);
}
target.setItem(key, value);
return true;
},
has(target, p) {
return p === SymbolFor("Deno.customInspect") ||
(typeof target.getItem(p)) === "string";

has(target, key) {
if (ReflectHas(target, key)) {
return true;
}
return typeof key === "string" && typeof target.getItem(key) === "string";
},

ownKeys() {
return ops.op_webstorage_iterate_keys(persistent);
},

getOwnPropertyDescriptor(target, key) {
if (arguments.length === 1) {
return undefined;
}
if (ReflectHas(target, key)) {
return undefined;
}
Expand Down

0 comments on commit 8866521

Please sign in to comment.