From 2d87f5bf47ef56c1ec4f2bc4d2ea3ee2f50e78a3 Mon Sep 17 00:00:00 2001 From: dinisimys2018 Date: Tue, 31 Mar 2026 18:42:03 +0300 Subject: [PATCH] fix(browser-url): handle specific file scheme and change error InvalidURL to TypeError --- src/browser/URL.zig | 35 +++++++++++++++++++---------------- src/browser/webapi/Node.zig | 1 - 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/browser/URL.zig b/src/browser/URL.zig index 06700f36..579cd7f8 100644 --- a/src/browser/URL.zig +++ b/src/browser/URL.zig @@ -58,12 +58,12 @@ pub fn resolve(allocator: Allocator, base: [:0]const u8, source_path: anytype, c while (rest_start < path.len and (path[rest_start] == '/' or path[rest_start] == '\\')) { rest_start += 1; } - //special scheme need to any symbols after "://" - if (rest_start >= path.len) { - return error.InvalidURL; + // A special scheme (exclude "file") must contain at least anu chars after "://" + if (rest_start == path.len and !std.ascii.eqlIgnoreCase(scheme_path, "file")) { + return error.TypeError; } //File scheme allow empty host - const separator: []const u8 = if (std.ascii.eqlIgnoreCase(scheme_path, "file") and !has_double_slashas) ":///" else "://"; + const separator: []const u8 = if (!has_double_slashas and std.ascii.eqlIgnoreCase(scheme_path, "file")) ":///" else "://"; path = try std.mem.joinZ(allocator, "", &.{ scheme_path, separator, path[rest_start..] }); return processResolved(allocator, path, opts); @@ -1694,6 +1694,12 @@ test "URL: resolve path scheme" { .path = "file:/path/to/file", .expected = "file:///path/to/file", }, + //different schemes and path as absolute (path scheme=file, host is empty) + .{ + .base = "https://www.example.com/example", + .path = "file:/", + .expected = "file:///", + }, //different schemes without :// and normalize "file" scheme, absolute path .{ .base = "https://www.example.com/example", @@ -1712,13 +1718,13 @@ test "URL: resolve path scheme" { .path = "https:/http://relative/path/", .expected = "https://www.example.com/http://relative/path/", }, - //same schemes without :// in path , relative state + //same schemes without :// in path , relative state .{ .base = "http://www.example.com/example", .path = "http:relative:path", .expected = "http://www.example.com/relative:path", }, - //repeat different schemes in path + //repeat different schemes in path .{ .base = "http://www.example.com/example", .path = "http:http:/relative/path/", @@ -1770,15 +1776,12 @@ test "URL: resolve path scheme" { }; for (cases) |case| { - const result = resolve(testing.arena_allocator, case.base, case.path, .{}) catch |err| { - if (err == error.InvalidURL) { - try testing.expect(case.expected_error); - continue; - } - - return err; - }; - - try testing.expectString(case.expected, result); + if (case.expected_error) { + const result = resolve(testing.arena_allocator, case.base, case.path, .{}); + try testing.expectError(error.TypeError, result); + } else { + const result = try resolve(testing.arena_allocator, case.base, case.path, .{}); + try testing.expectString(case.expected, result); + } } } diff --git a/src/browser/webapi/Node.zig b/src/browser/webapi/Node.zig index 5b493ed5..0e7c2ffe 100644 --- a/src/browser/webapi/Node.zig +++ b/src/browser/webapi/Node.zig @@ -750,7 +750,6 @@ const CloneError = error{ TypeError, CompilationError, JsException, - InvalidURL, }; pub fn cloneNode(self: *Node, deep_: ?bool, page: *Page) CloneError!*Node { const deep = deep_ orelse false;