Allocator.resize() does not adjust size of string allocated for URI to file path conversion (#806)

* fix missing backslash

* fix: zls escaping colon to %3A on URIs

ZLS escapes a colon char ":" as "%3A" when encoding file paths to URIs
When decoding, need to make the target string 2 character shorter
to compensate for length decrease when replacing %3A with :

* add new failing test because of resize()

* revert changes to %3A handling - problem seems to be with allocator.resize

* switch to realloc

* Fix test failures, revert errdefer->defer

* platform-specific URI tests

URI parsing is highly platform-specific
run Unix-style (file:///home/main.zig) on non-Windows test runners,
run Windows-style (file://c%3A/main.zig) on Windows test runners
This commit is contained in:
Joseph Stahl 2022-12-04 16:44:22 -05:00 committed by GitHub
parent 580469cd32
commit 887539ed1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 48 additions and 9 deletions

View File

@ -101,7 +101,7 @@ pub fn parse(allocator: std.mem.Allocator, str: []const u8) ![]u8 {
if (str.len < 7 or !std.mem.eql(u8, "file://", str[0..7])) return error.UriBadScheme; if (str.len < 7 or !std.mem.eql(u8, "file://", str[0..7])) return error.UriBadScheme;
var uri = try allocator.alloc(u8, str.len - (if (std.fs.path.sep == '\\') 8 else 7)); var uri = try allocator.alloc(u8, str.len - (if (std.fs.path.sep == '\\') 8 else 7));
defer allocator.free(uri); errdefer allocator.free(uri);
const path = if (std.fs.path.sep == '\\') str[8..] else str[7..]; const path = if (std.fs.path.sep == '\\') str[8..] else str[7..];
@ -125,5 +125,5 @@ pub fn parse(allocator: std.mem.Allocator, str: []const u8) ![]u8 {
i -= 1; i -= 1;
} }
return try allocator.dupe(u8, uri[0..i]); return allocator.realloc(uri, i);
} }

View File

@ -1,16 +1,55 @@
const std = @import("std"); const std = @import("std");
const builtin = @import("builtin");
const zls = @import("zls"); const zls = @import("zls");
const URI = zls.URI; const URI = zls.URI;
const allocator = std.testing.allocator; const allocator = std.testing.allocator;
test "uri - pathRelative" { test "uri - parse (Windows)" {
const join1 = try URI.pathRelative(allocator, "file://project/zig", "/src/main+.zig"); if (builtin.os.tag == .windows) {
defer allocator.free(join1); const parseWin = try URI.parse(allocator, "file:///c%3A/main.zig");
try std.testing.expectEqualStrings("file://project/zig/src/main%2B.zig", join1); defer allocator.free(parseWin);
try std.testing.expectEqualStrings("c:\\main.zig", parseWin);
const join2 = try URI.pathRelative(allocator, "file://project/zig/wow", "../]src]/]main.zig"); const parseWin2 = try URI.parse(allocator, "file:///c%3A/main%2B.zig");
defer allocator.free(join2); defer allocator.free(parseWin2);
try std.testing.expectEqualStrings("file://project/zig/%5Dsrc%5D/%5Dmain.zig", join2); try std.testing.expectEqualStrings("c:\\main+.zig", parseWin2);
}
}
test "uri - parse (Unix-style)" {
if (builtin.os.tag != .windows) {
const parseUnix = try URI.parse(allocator, "file:///home/main.zig");
defer allocator.free(parseUnix);
try std.testing.expectEqualStrings("/home/main.zig", parseUnix);
const parseUnix2 = try URI.parse(allocator, "file:///home/main%2B.zig");
defer allocator.free(parseUnix2);
try std.testing.expectEqualStrings("/home/main+.zig", parseUnix2);
}
}
test "uri - fromPath" {
if (builtin.os.tag == .windows) {
const fromPathWin = try URI.fromPath(allocator, "c:\\main.zig");
defer allocator.free(fromPathWin);
try std.testing.expectEqualStrings("file:///c%3A/main.zig", fromPathWin);
}
if (builtin.os.tag != .windows) {
const fromPathUnix = try URI.fromPath(allocator, "/home/main.zig");
defer allocator.free(fromPathUnix);
try std.testing.expectEqualStrings("file:///home/main.zig", fromPathUnix);
}
}
test "uri - pathRelative" {
const join1 = try URI.pathRelative(allocator, "file:///project/zig", "/src/main+.zig");
defer allocator.free(join1);
try std.testing.expectEqualStrings("file:///project/zig/src/main%2B.zig", join1);
const join2 = try URI.pathRelative(allocator, "file:///project/zig/wow", "../]src]/]main.zig");
defer allocator.free(join2);
try std.testing.expectEqualStrings("file:///project/zig/%5Dsrc%5D/%5Dmain.zig", join2);
} }