0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-10-30 09:08:00 -04: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 Yoshiya Hinosawa
parent ce44871e80
commit 8bf1437f48
No known key found for this signature in database
GPG key ID: 9017DB4559488785
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.
// 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);
});

View file

@ -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 {
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];
if (ReflectHas(target, key)) {
return ReflectGet(...new SafeArrayIterator(arguments));
} else {
return target.getItem(key) ?? undefined;
get(target, key, receiver) {
if (typeof key === "symbol") {
return target[key];
}
if (ReflectHas(target, key)) {
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;
}