diff options
author | Kenta Moriuchi <moriken@kimamass.com> | 2023-11-14 15:01:15 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-14 07:01:15 +0100 |
commit | 886652156e0e548a44fd41b293916bf37594eaa3 (patch) | |
tree | 4d8c98e9a98519d9dddd78fc1e1a7aa83bb59722 | |
parent | e54e8d4e2246de13325114b930effa8647623795 (diff) |
fix(ext/web): webstorage has trap for symbol (#21090)
-rw-r--r-- | cli/tests/unit/webstorage_test.ts | 14 | ||||
-rw-r--r-- | ext/webstorage/01_webstorage.js | 53 |
2 files changed, 40 insertions, 27 deletions
diff --git a/cli/tests/unit/webstorage_test.ts b/cli/tests/unit/webstorage_test.ts index e6ca5bb88..9c71b6320 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, assertThrows } from "./test_util.ts"; +import { assert, assertEquals, assertThrows } from "./test_util.ts"; Deno.test({ permissions: "none" }, function webStoragesReassignable() { // Can reassign to web storages @@ -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"); @@ -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); +}); diff --git a/ext/webstorage/01_webstorage.js b/ext/webstorage/01_webstorage.js index 58c68c832..59abab1bf 100644 --- a/ext/webstorage/01_webstorage.js +++ b/ext/webstorage/01_webstorage.js @@ -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, @@ -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; } |