diff --git a/src/browser/tests/storage.html b/src/browser/tests/storage.html index 7633293b..cb41bb3d 100644 --- a/src/browser/tests/storage.html +++ b/src/browser/tests/storage.html @@ -88,3 +88,12 @@ localStorage.clear(); testing.expectEqual(0, localStorage.length) + + diff --git a/src/browser/webapi/Crypto.zig b/src/browser/webapi/Crypto.zig index 89324695..a79fbc40 100644 --- a/src/browser/webapi/Crypto.zig +++ b/src/browser/webapi/Crypto.zig @@ -32,7 +32,7 @@ pub fn getRandomValues(_: *const Crypto, js_obj: js.Object) !js.Object { var into = try js_obj.toZig(RandomValues); const buf = into.asBuffer(); if (buf.len > 65_536) { - return error.QuotaExceededError; + return error.QuotaExceeded; } std.crypto.random.bytes(buf); return js_obj; @@ -82,7 +82,7 @@ pub const JsApi = struct { pub const empty_with_no_proto = true; }; - pub const getRandomValues = bridge.function(Crypto.getRandomValues, .{}); + pub const getRandomValues = bridge.function(Crypto.getRandomValues, .{ .dom_exception = true }); pub const randomUUID = bridge.function(Crypto.randomUUID, .{}); pub const subtle = bridge.accessor(Crypto.getSubtle, null, .{}); }; diff --git a/src/browser/webapi/storage/storage.zig b/src/browser/webapi/storage/storage.zig index 64dfae23..1787dfee 100644 --- a/src/browser/webapi/storage/storage.zig +++ b/src/browser/webapi/storage/storage.zig @@ -60,6 +60,9 @@ pub const Bucket = struct { local: Lookup = .{}, session: Lookup = .{} }; pub const Lookup = struct { _data: std.StringHashMapUnmanaged([]const u8) = .empty, + _size: usize = 0, + + const max_size = 5 * 1024 * 1024; pub fn getItem(self: *const Lookup, key_: ?[]const u8) ?[]const u8 { const k = key_ orelse return null; @@ -69,6 +72,11 @@ pub const Lookup = struct { pub fn setItem(self: *Lookup, key_: ?[]const u8, value: []const u8, page: *Page) !void { const k = key_ orelse return; + if (self._size + value.len > max_size) { + return error.QuotaExceeded; + } + defer self._size += value.len; + const key_owned = try page.dupeString(k); const value_owned = try page.dupeString(value); @@ -78,11 +86,15 @@ pub const Lookup = struct { pub fn removeItem(self: *Lookup, key_: ?[]const u8) void { const k = key_ orelse return; - _ = self._data.remove(k); + if (self._data.get(k)) |value| { + self._size -= value.len; + _ = self._data.remove(k); + } } pub fn clear(self: *Lookup) void { self._data.clearRetainingCapacity(); + self._size = 0; } pub fn key(self: *const Lookup, index: u32) ?[]const u8 { @@ -112,7 +124,7 @@ pub const Lookup = struct { pub const length = bridge.accessor(Lookup.getLength, null, .{}); pub const getItem = bridge.function(Lookup.getItem, .{}); - pub const setItem = bridge.function(Lookup.setItem, .{}); + pub const setItem = bridge.function(Lookup.setItem, .{ .dom_exception = true }); pub const removeItem = bridge.function(Lookup.removeItem, .{}); pub const clear = bridge.function(Lookup.clear, .{}); pub const key = bridge.function(Lookup.key, .{});