authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2023-08-17 00:56:56-07:00
committergravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2023-08-17 00:59:19-07:00
log2b44961a208341e55969cca959608d80adcf3e0e
tree0f6ddebf6894c088d100c66e05767ec5f7273471
parent8c8f3cbd43df7748d6be712db392ed8502c2a84b

Fix ntToWin32Namespace and friends on big endian architectures


1 files changed, 18 insertions(+), 12 deletions(-)

lib/std/os/windows.zig+18-12
...@@ -2343,25 +2343,26 @@ pub const NamespacePrefix = enum {...@@ -2343,25 +2343,26 @@ pub const NamespacePrefix = enum {
2343 nt,2343 nt,
2344};2344};
23452345
2346/// If `T` is `u16`, then `path` should be encoded as UTF-16LE.
2346pub fn getNamespacePrefix(comptime T: type, path: []const T) NamespacePrefix {2347pub fn getNamespacePrefix(comptime T: type, path: []const T) NamespacePrefix {
2347 if (path.len < 4) return .none;2348 if (path.len < 4) return .none;
2348 var all_backslash = switch (path[0]) {2349 var all_backslash = switch (mem.littleToNative(T, path[0])) {
2349 '\\' => true,2350 '\\' => true,
2350 '/' => false,2351 '/' => false,
2351 else => return .none,2352 else => return .none,
2352 };2353 };
2353 all_backslash = all_backslash and switch (path[3]) {2354 all_backslash = all_backslash and switch (mem.littleToNative(T, path[3])) {
2354 '\\' => true,2355 '\\' => true,
2355 '/' => false,2356 '/' => false,
2356 else => return .none,2357 else => return .none,
2357 };2358 };
2358 switch (path[1]) {2359 switch (mem.littleToNative(T, path[1])) {
2359 '?' => if (path[2] == '?' and all_backslash) return .nt else return .none,2360 '?' => if (mem.littleToNative(T, path[2]) == '?' and all_backslash) return .nt else return .none,
2360 '\\' => {},2361 '\\' => {},
2361 '/' => all_backslash = false,2362 '/' => all_backslash = false,
2362 else => return .none,2363 else => return .none,
2363 }2364 }
2364 return switch (path[2]) {2365 return switch (mem.littleToNative(T, path[2])) {
2365 '?' => if (all_backslash) .verbatim else .fake_verbatim,2366 '?' => if (all_backslash) .verbatim else .fake_verbatim,
2366 '.' => .local_device,2367 '.' => .local_device,
2367 else => .none,2368 else => .none,
...@@ -2396,6 +2397,7 @@ pub const UnprefixedPathType = enum {...@@ -2396,6 +2397,7 @@ pub const UnprefixedPathType = enum {
23962397
2397/// Get the path type of a path that is known to not have any namespace prefixes2398/// Get the path type of a path that is known to not have any namespace prefixes
2398/// (`\\?\`, `\\.\`, `\??\`).2399/// (`\\?\`, `\\.\`, `\??\`).
2400/// If `T` is `u16`, then `path` should be encoded as UTF-16LE.
2399pub fn getUnprefixedPathType(comptime T: type, path: []const T) UnprefixedPathType {2401pub fn getUnprefixedPathType(comptime T: type, path: []const T) UnprefixedPathType {
2400 if (path.len < 1) return .relative;2402 if (path.len < 1) return .relative;
24012403
...@@ -2404,18 +2406,18 @@ pub fn getUnprefixedPathType(comptime T: type, path: []const T) UnprefixedPathTy...@@ -2404,18 +2406,18 @@ pub fn getUnprefixedPathType(comptime T: type, path: []const T) UnprefixedPathTy
2404 }2406 }
24052407
2406 const windows_path = std.fs.path.PathType.windows;2408 const windows_path = std.fs.path.PathType.windows;
2407 if (windows_path.isSep(T, path[0])) {2409 if (windows_path.isSep(T, mem.littleToNative(T, path[0]))) {
2408 // \x2410 // \x
2409 if (path.len < 2 or !windows_path.isSep(T, path[1])) return .rooted;2411 if (path.len < 2 or !windows_path.isSep(T, mem.littleToNative(T, path[1]))) return .rooted;
2410 // exactly \\. or \\? with nothing trailing2412 // exactly \\. or \\? with nothing trailing
2411 if (path.len == 3 and (path[2] == '.' or path[2] == '?')) return .root_local_device;2413 if (path.len == 3 and (mem.littleToNative(T, path[2]) == '.' or mem.littleToNative(T, path[2]) == '?')) return .root_local_device;
2412 // \\x2414 // \\x
2413 return .unc_absolute;2415 return .unc_absolute;
2414 } else {2416 } else {
2415 // x2417 // x
2416 if (path.len < 2 or path[1] != ':') return .relative;2418 if (path.len < 2 or mem.littleToNative(T, path[1]) != ':') return .relative;
2417 // x:\2419 // x:\
2418 if (path.len > 2 and windows_path.isSep(T, path[2])) return .drive_absolute;2420 if (path.len > 2 and windows_path.isSep(T, mem.littleToNative(T, path[2]))) return .drive_absolute;
2419 // x:2421 // x:
2420 return .drive_relative;2422 return .drive_relative;
2421 }2423 }
...@@ -2448,6 +2450,8 @@ test getUnprefixedPathType {...@@ -2448,6 +2450,8 @@ test getUnprefixedPathType {
2448///2450///
2449/// Functionality is based on the ReactOS test cases found here:2451/// Functionality is based on the ReactOS test cases found here:
2450/// https://github.com/reactos/reactos/blob/master/modules/rostests/apitests/ntdll/RtlNtPathNameToDosPathName.c2452/// https://github.com/reactos/reactos/blob/master/modules/rostests/apitests/ntdll/RtlNtPathNameToDosPathName.c
2453///
2454/// `path` should be encoded as UTF-16LE.
2451pub fn ntToWin32Namespace(path: []const u16) !PathSpace {2455pub fn ntToWin32Namespace(path: []const u16) !PathSpace {
2452 if (path.len > PATH_MAX_WIDE) return error.NameTooLong;2456 if (path.len > PATH_MAX_WIDE) return error.NameTooLong;
24532457
...@@ -2463,9 +2467,11 @@ pub fn ntToWin32Namespace(path: []const u16) !PathSpace {...@@ -2463,9 +2467,11 @@ pub fn ntToWin32Namespace(path: []const u16) !PathSpace {
2463 // it's unlikely to matter since most/all paths passed into this2467 // it's unlikely to matter since most/all paths passed into this
2464 // function will have come from the OS meaning it should have2468 // function will have come from the OS meaning it should have
2465 // the 'canonical' uppercase UNC.2469 // the 'canonical' uppercase UNC.
2466 const is_unc = after_prefix.len >= 4 and std.mem.eql(u16, after_prefix[0..3], std.unicode.utf8ToUtf16LeStringLiteral("UNC")) and std.fs.path.PathType.windows.isSep(u16, after_prefix[3]);2470 const is_unc = after_prefix.len >= 4 and
2471 std.mem.eql(u16, after_prefix[0..3], std.unicode.utf8ToUtf16LeStringLiteral("UNC")) and
2472 std.fs.path.PathType.windows.isSep(u16, std.mem.littleToNative(u16, after_prefix[3]));
2467 if (is_unc) {2473 if (is_unc) {
2468 path_space.data[0] = '\\';2474 path_space.data[0] = comptime std.mem.nativeToLittle(u16, '\\');
2469 dest_index += 1;2475 dest_index += 1;
2470 // We want to include the last `\` of `\??\UNC\`2476 // We want to include the last `\` of `\??\UNC\`
2471 after_prefix = path[7..];2477 after_prefix = path[7..];