Merge pull request #2073 from lightpanda-io/page-isSameOrigin

stricter Page.isSameOrigin
This commit is contained in:
Karl Seguin
2026-04-03 07:39:30 +08:00
committed by GitHub
2 changed files with 48 additions and 2 deletions

View File

@@ -438,7 +438,15 @@ pub fn releaseArena(self: *Page, allocator: Allocator) void {
pub fn isSameOrigin(self: *const Page, url: [:0]const u8) !bool {
const current_origin = self.origin orelse return false;
return std.mem.startsWith(u8, url, current_origin);
// fastpath
if (!std.mem.startsWith(u8, url, current_origin)) {
return false;
}
// Starting here, at least protocols are equals.
// Compare hosts (domain:port) strictly
return std.mem.eql(u8, URL.getHost(url), URL.getHost(current_origin));
}
/// Look up a blob URL in this page's registry.
@@ -3616,3 +3624,41 @@ test "WebApi: Frames" {
test "WebApi: Integration" {
try testing.htmlRunner("integration", .{});
}
test "Page: isSameOrigin" {
var arena = std.heap.ArenaAllocator.init(testing.allocator);
defer arena.deinit();
const allocator = arena.allocator();
var page: Page = undefined;
page.origin = null;
try testing.expectEqual(false, page.isSameOrigin("https://origin.com/"));
page.origin = try URL.getOrigin(allocator, "https://origin.com/foo/bar") orelse unreachable;
try testing.expectEqual(true, page.isSameOrigin("https://origin.com/foo/bar")); // exact same
try testing.expectEqual(true, page.isSameOrigin("https://origin.com/bar/bar")); // path differ
try testing.expectEqual(true, page.isSameOrigin("https://origin.com/")); // path differ
try testing.expectEqual(true, page.isSameOrigin("https://origin.com")); // no path
try testing.expectEqual(true, page.isSameOrigin("https://origin.com/foo?q=1"));
try testing.expectEqual(true, page.isSameOrigin("https://origin.com/foo#hash"));
try testing.expectEqual(true, page.isSameOrigin("https://origin.com/foo?q=1#hash"));
// FIXME try testing.expectEqual(true, page.isSameOrigin("https://foo:bar@origin.com"));
// FIXME try testing.expectEqual(true, page.isSameOrigin("https://origin.com:443/foo"));
try testing.expectEqual(false, page.isSameOrigin("http://origin.com/")); // another proto
try testing.expectEqual(false, page.isSameOrigin("https://origin.com:123/")); // another port
try testing.expectEqual(false, page.isSameOrigin("https://sub.origin.com/")); // another subdomain
try testing.expectEqual(false, page.isSameOrigin("https://target.com/")); // different domain
try testing.expectEqual(false, page.isSameOrigin("https://origin.com.target.com/")); // different domain
try testing.expectEqual(false, page.isSameOrigin("https://target.com/@origin.com"));
page.origin = try URL.getOrigin(allocator, "https://origin.com:8443/foo") orelse unreachable;
try testing.expectEqual(true, page.isSameOrigin("https://origin.com:8443/bar"));
try testing.expectEqual(false, page.isSameOrigin("https://origin.com/bar")); // missing port
try testing.expectEqual(false, page.isSameOrigin("https://origin.com:9999/bar")); // wrong port
try testing.expectEqual(false, page.isSameOrigin(""));
try testing.expectEqual(false, page.isSameOrigin("not-a-url"));
try testing.expectEqual(false, page.isSameOrigin("//origin.com/foo"));
}

View File

@@ -509,7 +509,7 @@ fn getUserInfo(raw: [:0]const u8) ?[]const u8 {
return raw[authority_start .. auth.host_start - 1];
}
pub fn getHost(raw: [:0]const u8) []const u8 {
pub fn getHost(raw: []const u8) []const u8 {
const auth = parseAuthority(raw) orelse return "";
return auth.getHost(raw);
}