From 3a3ef67ab007a1a713dd71e72b50e706c290d641 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Mon, 29 Jun 2026 07:31:19 +0800 Subject: [PATCH] webapi: Fix move cookie accessor from HTMLDocument to Document Per spec, this should be accessible on the Document, not the HTMLDocument. I ran into a site that was doing: Object.getOwnPropertyDescriptor(Document.prototype, "cookie") and that was failing --- src/browser/webapi/Document.zig | 26 ++++++++++++++++++++++++++ src/browser/webapi/HTMLDocument.zig | 26 -------------------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/browser/webapi/Document.zig b/src/browser/webapi/Document.zig index 4b59c8e60..9f02ce08e 100644 --- a/src/browser/webapi/Document.zig +++ b/src/browser/webapi/Document.zig @@ -191,6 +191,31 @@ pub fn setDomain(self: *Document, value: []const u8) !void { try doc_frame.js.setOrigin(key); } +pub fn getCookie(_: *Document, frame: *Frame) ![]const u8 { + var buf: std.ArrayList(u8) = .empty; + try frame._session.cookie_jar.forRequest(frame.url, buf.writer(frame.call_arena), .{ + .is_http = false, + .is_navigation = true, + }); + return buf.items; +} + +pub fn setCookie(_: *Document, cookie_str: []const u8, frame: *Frame) ![]const u8 { + // we use the cookie jar's allocator to parse the cookie because it + // outlives the frame's arena. + const Cookie = @import("storage/Cookie.zig"); + const c = Cookie.parse(frame._session.cookie_jar.allocator, frame.url, cookie_str) catch { + // Invalid cookies should be silently ignored, not throw errors + return ""; + }; + if (c.http_only) { + c.deinit(); + return ""; // HttpOnly cookies cannot be set from JS + } + try frame._session.cookie_jar.add(c, std.time.timestamp(), false); + return cookie_str; +} + // Returns true if the requested domain is valid for the given host fn isRelaxableTo(host: []const u8, requested: []const u8) bool { if (requested.len == 0) { @@ -1254,6 +1279,7 @@ pub const JsApi = struct { pub const fonts = bridge.accessor(Document.getFonts, null, .{}); pub const contentType = bridge.accessor(Document.getContentType, null, .{}); pub const domain = bridge.accessor(Document.getDomain, Document.setDomain, .{ .dom_exception = true }); + pub const cookie = bridge.accessor(Document.getCookie, Document.setCookie, .{}); pub const createElement = bridge.function(Document.createElement, .{ .dom_exception = true }); pub const createElementNS = bridge.function(Document.createElementNS, .{ .dom_exception = true }); pub const createDocumentFragment = bridge.function(Document.createDocumentFragment, .{}); diff --git a/src/browser/webapi/HTMLDocument.zig b/src/browser/webapi/HTMLDocument.zig index ba4d39438..4d2ccb9c2 100644 --- a/src/browser/webapi/HTMLDocument.zig +++ b/src/browser/webapi/HTMLDocument.zig @@ -224,31 +224,6 @@ pub fn getAll(self: *HTMLDocument, frame: *Frame) !*collections.HTMLAllCollectio return frame._factory.create(collections.HTMLAllCollection.init(self.asNode(), frame)); } -pub fn getCookie(_: *HTMLDocument, frame: *Frame) ![]const u8 { - var buf: std.ArrayList(u8) = .empty; - try frame._session.cookie_jar.forRequest(frame.url, buf.writer(frame.call_arena), .{ - .is_http = false, - .is_navigation = true, - }); - return buf.items; -} - -pub fn setCookie(_: *HTMLDocument, cookie_str: []const u8, frame: *Frame) ![]const u8 { - // we use the cookie jar's allocator to parse the cookie because it - // outlives the frame's arena. - const Cookie = @import("storage/Cookie.zig"); - const c = Cookie.parse(frame._session.cookie_jar.allocator, frame.url, cookie_str) catch { - // Invalid cookies should be silently ignored, not throw errors - return ""; - }; - if (c.http_only) { - c.deinit(); - return ""; // HttpOnly cookies cannot be set from JS - } - try frame._session.cookie_jar.add(c, std.time.timestamp(), false); - return cookie_str; -} - pub fn getDocType(self: *HTMLDocument, frame: *Frame) !*DocumentType { if (self._document_type) |dt| { return dt; @@ -302,6 +277,5 @@ pub const JsApi = struct { pub const plugins = bridge.accessor(HTMLDocument.getEmbeds, null, .{}); pub const currentScript = bridge.accessor(HTMLDocument.getCurrentScript, null, .{}); pub const all = bridge.accessor(HTMLDocument.getAll, null, .{}); - pub const cookie = bridge.accessor(HTMLDocument.getCookie, HTMLDocument.setCookie, .{}); pub const doctype = bridge.accessor(HTMLDocument.getDocType, null, .{}); };