mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-22 04:34:44 +00:00
new URL('about:blank');
Add correct handling for new URL('about:blank');
When a frame is navigated to about:blank (which happens often, since it happens
as soon as a dynamic iframe is created), we make sure to give window._location
a unique value. This prevents 2 frames from referencing the same
window._location object.
Fixes a WPT crash in: 0/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/iframe-nosrc.html
This commit is contained in:
@@ -441,6 +441,12 @@ pub fn navigate(self: *Page, request_url: [:0]const u8, opts: NavigateOpts) !voi
|
|||||||
if (is_about_blank or is_blob) {
|
if (is_about_blank or is_blob) {
|
||||||
self.url = if (is_about_blank) "about:blank" else try self.arena.dupeZ(u8, request_url);
|
self.url = if (is_about_blank) "about:blank" else try self.arena.dupeZ(u8, request_url);
|
||||||
|
|
||||||
|
// even though this might be the same _data_ as `default_location`, we
|
||||||
|
// have to do this to make sure window.location is at a unique _address_.
|
||||||
|
// If we don't do this, mulitple window._location will have the same
|
||||||
|
// address and thus be mapped to the same v8::Object in the identity map.
|
||||||
|
self.window._location = try Location.init(self.url, self);
|
||||||
|
|
||||||
if (is_blob) {
|
if (is_blob) {
|
||||||
// strip out blob:
|
// strip out blob:
|
||||||
self.origin = try URL.getOrigin(self.arena, request_url[5.. :0]);
|
self.origin = try URL.getOrigin(self.arena, request_url[5.. :0]);
|
||||||
|
|||||||
@@ -323,14 +323,22 @@ pub fn getPassword(raw: [:0]const u8) []const u8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getPathname(raw: [:0]const u8) []const u8 {
|
pub fn getPathname(raw: [:0]const u8) []const u8 {
|
||||||
const protocol_end = std.mem.indexOf(u8, raw, "://") orelse 0;
|
const protocol_end = std.mem.indexOf(u8, raw, "://");
|
||||||
const path_start = std.mem.indexOfScalarPos(u8, raw, if (protocol_end > 0) protocol_end + 3 else 0, '/') orelse raw.len;
|
|
||||||
|
// Handle scheme:path URLs like about:blank (no "://")
|
||||||
|
if (protocol_end == null) {
|
||||||
|
const colon_pos = std.mem.indexOfScalar(u8, raw, ':') orelse return "";
|
||||||
|
const path = raw[colon_pos + 1 ..];
|
||||||
|
const query_or_hash = std.mem.indexOfAny(u8, path, "?#") orelse path.len;
|
||||||
|
return path[0..query_or_hash];
|
||||||
|
}
|
||||||
|
|
||||||
|
const path_start = std.mem.indexOfScalarPos(u8, raw, protocol_end.? + 3, '/') orelse raw.len;
|
||||||
|
|
||||||
const query_or_hash_start = std.mem.indexOfAnyPos(u8, raw, path_start, "?#") orelse raw.len;
|
const query_or_hash_start = std.mem.indexOfAnyPos(u8, raw, path_start, "?#") orelse raw.len;
|
||||||
|
|
||||||
if (path_start >= query_or_hash_start) {
|
if (path_start >= query_or_hash_start) {
|
||||||
if (std.mem.indexOf(u8, raw, "://") != null) return "/";
|
return "/";
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return raw[path_start..query_or_hash_start];
|
return raw[path_start..query_or_hash_start];
|
||||||
|
|||||||
@@ -798,3 +798,19 @@
|
|||||||
testing.expectEqual(true, url2.startsWith('blob:'));
|
testing.expectEqual(true, url2.startsWith('blob:'));
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script id="about:blank">
|
||||||
|
{
|
||||||
|
const url = new URL('about:blank');
|
||||||
|
testing.expectEqual('about:blank', url.href);
|
||||||
|
testing.expectEqual('null', url.origin);
|
||||||
|
testing.expectEqual('about:', url.protocol);
|
||||||
|
testing.expectEqual('blank', url.pathname);
|
||||||
|
testing.expectEqual('', url.username);
|
||||||
|
testing.expectEqual('', url.password);
|
||||||
|
testing.expectEqual('', url.host);
|
||||||
|
testing.expectEqual('', url.hostname);
|
||||||
|
testing.expectEqual('', url.port);
|
||||||
|
testing.expectEqual('', url.search);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|||||||
@@ -37,6 +37,14 @@ pub const resolve = @import("../URL.zig").resolve;
|
|||||||
pub const eqlDocument = @import("../URL.zig").eqlDocument;
|
pub const eqlDocument = @import("../URL.zig").eqlDocument;
|
||||||
|
|
||||||
pub fn init(url: [:0]const u8, base_: ?[:0]const u8, page: *Page) !*URL {
|
pub fn init(url: [:0]const u8, base_: ?[:0]const u8, page: *Page) !*URL {
|
||||||
|
const arena = page.arena;
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, url, "about:blank")) {
|
||||||
|
return page._factory.create(URL{
|
||||||
|
._raw = "about:blank",
|
||||||
|
._arena = arena,
|
||||||
|
});
|
||||||
|
}
|
||||||
const url_is_absolute = @import("../URL.zig").isCompleteHTTPUrl(url);
|
const url_is_absolute = @import("../URL.zig").isCompleteHTTPUrl(url);
|
||||||
|
|
||||||
const base = if (base_) |b| blk: {
|
const base = if (base_) |b| blk: {
|
||||||
@@ -53,7 +61,6 @@ pub fn init(url: [:0]const u8, base_: ?[:0]const u8, page: *Page) !*URL {
|
|||||||
return error.TypeError;
|
return error.TypeError;
|
||||||
} else page.url;
|
} else page.url;
|
||||||
|
|
||||||
const arena = page.arena;
|
|
||||||
const raw = try resolve(arena, base, url, .{ .always_dupe = true });
|
const raw = try resolve(arena, base, url, .{ .always_dupe = true });
|
||||||
|
|
||||||
return page._factory.create(URL{
|
return page._factory.create(URL{
|
||||||
|
|||||||
Reference in New Issue
Block a user