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 {
23432343 nt,
23442344};
23452345
2346/// If `T` is `u16`, then `path` should be encoded as UTF-16LE.
23462347pub fn getNamespacePrefix(comptime T: type, path: []const T) NamespacePrefix {
23472348 if (path.len < 4) return .none;
2348 var all_backslash = switch (path[0]) {
2349 var all_backslash = switch (mem.littleToNative(T, path[0])) {
23492350 '\\' => true,
23502351 '/' => false,
23512352 else => return .none,
23522353 };
2353 all_backslash = all_backslash and switch (path[3]) {
2354 all_backslash = all_backslash and switch (mem.littleToNative(T, path[3])) {
23542355 '\\' => true,
23552356 '/' => false,
23562357 else => return .none,
23572358 };
2358 switch (path[1]) {
2359 '?' => if (path[2] == '?' and all_backslash) return .nt else return .none,
2359 switch (mem.littleToNative(T, path[1])) {
2360 '?' => if (mem.littleToNative(T, path[2]) == '?' and all_backslash) return .nt else return .none,
23602361 '\\' => {},
23612362 '/' => all_backslash = false,
23622363 else => return .none,
23632364 }
2364 return switch (path[2]) {
2365 return switch (mem.littleToNative(T, path[2])) {
23652366 '?' => if (all_backslash) .verbatim else .fake_verbatim,
23662367 '.' => .local_device,
23672368 else => .none,
......@@ -2396,6 +2397,7 @@ pub const UnprefixedPathType = enum {
23962397
23972398/// Get the path type of a path that is known to not have any namespace prefixes
23982399/// (`\\?\`, `\\.\`, `\??\`).
2400/// If `T` is `u16`, then `path` should be encoded as UTF-16LE.
23992401pub fn getUnprefixedPathType(comptime T: type, path: []const T) UnprefixedPathType {
24002402 if (path.len < 1) return .relative;
24012403
......@@ -2404,18 +2406,18 @@ pub fn getUnprefixedPathType(comptime T: type, path: []const T) UnprefixedPathTy
24042406 }
24052407
24062408 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]))) {
24082410 // \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;
24102412 // 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;
24122414 // \\x
24132415 return .unc_absolute;
24142416 } else {
24152417 // x
2416 if (path.len < 2 or path[1] != ':') return .relative;
2418 if (path.len < 2 or mem.littleToNative(T, path[1]) != ':') return .relative;
24172419 // 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;
24192421 // x:
24202422 return .drive_relative;
24212423 }
......@@ -2448,6 +2450,8 @@ test getUnprefixedPathType {
24482450///
24492451/// Functionality is based on the ReactOS test cases found here:
24502452/// https://github.com/reactos/reactos/blob/master/modules/rostests/apitests/ntdll/RtlNtPathNameToDosPathName.c
2453///
2454/// `path` should be encoded as UTF-16LE.
24512455pub fn ntToWin32Namespace(path: []const u16) !PathSpace {
24522456 if (path.len > PATH_MAX_WIDE) return error.NameTooLong;
24532457
......@@ -2463,9 +2467,11 @@ pub fn ntToWin32Namespace(path: []const u16) !PathSpace {
24632467 // it's unlikely to matter since most/all paths passed into this
24642468 // function will have come from the OS meaning it should have
24652469 // 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]));
24672473 if (is_unc) {
2468 path_space.data[0] = '\\';
2474 path_space.data[0] = comptime std.mem.nativeToLittle(u16, '\\');
24692475 dest_index += 1;
24702476 // We want to include the last `\` of `\??\UNC\`
24712477 after_prefix = path[7..];