0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-03 17:34:47 -05:00

fix(ext/web): webstorage has trap for symbol (#21090)

This commit is contained in:
Kenta Moriuchi 2023-11-14 15:01:15 +09:00 committed by GitHub
parent e54e8d4e22
commit 886652156e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 28 deletions

View file

@ -1,7 +1,7 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
// deno-lint-ignore-file no-explicit-any // 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() { Deno.test({ permissions: "none" }, function webStoragesReassignable() {
// Can reassign to web storages // Can reassign to web storages
@ -21,7 +21,7 @@ Deno.test(function webstorageSizeLimit() {
Error, Error,
"Exceeded maximum storage size", "Exceeded maximum storage size",
); );
assert(localStorage.getItem("k") === null); assertEquals(localStorage.getItem("k"), null);
assertThrows( assertThrows(
() => { () => {
localStorage.setItem("k".repeat(15 * 1024 * 1024), "v"); localStorage.setItem("k".repeat(15 * 1024 * 1024), "v");
@ -40,3 +40,13 @@ Deno.test(function webstorageSizeLimit() {
"Exceeded maximum storage size", "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);
});

View file

@ -7,12 +7,12 @@ const ops = core.ops;
import * as webidl from "ext:deno_webidl/00_webidl.js"; import * as webidl from "ext:deno_webidl/00_webidl.js";
const primordials = globalThis.__bootstrap.primordials; const primordials = globalThis.__bootstrap.primordials;
const { const {
SafeArrayIterator,
Symbol, Symbol,
SymbolFor, SymbolFor,
ObjectDefineProperty,
ObjectFromEntries, ObjectFromEntries,
ObjectEntries, ObjectEntries,
ReflectDefineProperty,
ReflectDeleteProperty,
ReflectGet, ReflectGet,
ReflectHas, ReflectHas,
Proxy, Proxy,
@ -83,51 +83,54 @@ function createStorage(persistent) {
const proxy = new Proxy(storage, { const proxy = new Proxy(storage, {
deleteProperty(target, key) { deleteProperty(target, key) {
if (typeof key == "symbol") { if (typeof key === "symbol") {
delete target[key]; return ReflectDeleteProperty(target, key);
} else {
target.removeItem(key);
} }
target.removeItem(key);
return true; return true;
}, },
defineProperty(target, key, descriptor) { defineProperty(target, key, descriptor) {
if (typeof key == "symbol") { if (typeof key === "symbol") {
ObjectDefineProperty(target, key, descriptor); return ReflectDefineProperty(target, key, descriptor);
} else {
target.setItem(key, descriptor.value);
} }
target.setItem(key, descriptor.value);
return true; return true;
}, },
get(target, key) {
if (typeof key == "symbol") return target[key]; get(target, key, receiver) {
if (ReflectHas(target, key)) { if (typeof key === "symbol") {
return ReflectGet(...new SafeArrayIterator(arguments)); return target[key];
} else {
return target.getItem(key) ?? undefined;
} }
if (ReflectHas(target, key)) {
return ReflectGet(target, key, receiver);
}
return target.getItem(key) ?? undefined;
}, },
set(target, key, value) { set(target, key, value) {
if (typeof key == "symbol") { if (typeof key === "symbol") {
ObjectDefineProperty(target, key, { return ReflectDefineProperty(target, key, {
value, value,
configurable: true, configurable: true,
}); });
} else {
target.setItem(key, value);
} }
target.setItem(key, value);
return true; return true;
}, },
has(target, p) {
return p === SymbolFor("Deno.customInspect") || has(target, key) {
(typeof target.getItem(p)) === "string"; if (ReflectHas(target, key)) {
return true;
}
return typeof key === "string" && typeof target.getItem(key) === "string";
}, },
ownKeys() { ownKeys() {
return ops.op_webstorage_iterate_keys(persistent); return ops.op_webstorage_iterate_keys(persistent);
}, },
getOwnPropertyDescriptor(target, key) { getOwnPropertyDescriptor(target, key) {
if (arguments.length === 1) {
return undefined;
}
if (ReflectHas(target, key)) { if (ReflectHas(target, key)) {
return undefined; return undefined;
} }