authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-08-10 12:30:24+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-08-10 16:39:02+02:00
log73b9f657460b040eaed4145a88f76db997d73987
treede97284473f92586a0deea00b4f1299610237419
parentcd8e6b66d046f73e4a9a4211557f52bdc1424de7

Validate DOS path before returning

And some other minor refactors which address more review comments.

1 files changed, 11 insertions(+), 6 deletions(-)

lib/std/os/windows.zig+11-6
......@@ -897,6 +897,7 @@ pub fn SetFilePointerEx_CURRENT_get(handle: HANDLE) SetFilePointerError!u64 {
897897}
898898
899899pub const GetFinalPathNameByHandleError = error{
900 BadPathName,
900901 FileNotFound,
901902 NameTooLong,
902903 Unexpected,
......@@ -925,11 +926,11 @@ pub fn GetFinalPathNameByHandle(
925926) GetFinalPathNameByHandleError![]u16 {
926927 // Get normalized path; doesn't include volume name though.
927928 var path_buffer: [@sizeOf(FILE_NAME_INFORMATION) + PATH_MAX_WIDE * 2]u8 align(@alignOf(FILE_NAME_INFORMATION)) = undefined;
928 try QueryInformationFile(hFile, FILE_INFORMATION_CLASS.FileNormalizedNameInformation, path_buffer[0..]);
929 try QueryInformationFile(hFile, .FileNormalizedNameInformation, path_buffer[0..]);
929930
930931 // Get NT volume name.
931932 var volume_buffer: [@sizeOf(FILE_NAME_INFORMATION) + MAX_PATH]u8 align(@alignOf(FILE_NAME_INFORMATION)) = undefined; // MAX_PATH bytes should be enough since it's Windows-defined name
932 try QueryInformationFile(hFile, FILE_INFORMATION_CLASS.FileVolumeNameInformation, volume_buffer[0..]);
933 try QueryInformationFile(hFile, .FileVolumeNameInformation, volume_buffer[0..]);
933934
934935 const file_name = @ptrCast(*const FILE_NAME_INFORMATION, &path_buffer[0]);
935936 const file_name_u16 = @ptrCast([*]const u16, &file_name.FileName[0])[0 .. file_name.FileNameLength / 2];
......@@ -1010,8 +1011,14 @@ pub fn GetFinalPathNameByHandle(
10101011
10111012 std.mem.copy(u16, out_buffer[0..], drive_letter);
10121013 std.mem.copy(u16, out_buffer[drive_letter.len..], file_name_u16);
1014 const total_len = drive_letter.len + file_name_u16.len;
10131015
1014 return out_buffer[0 .. drive_letter.len + file_name_u16.len];
1016 // Validate that DOS does not contain any spurious nul bytes.
1017 if (std.mem.indexOfScalar(u16, out_buffer[0..total_len], 0)) |_| {
1018 return error.BadPathName;
1019 }
1020
1021 return out_buffer[0..total_len];
10151022 }
10161023 }
10171024
......@@ -1030,9 +1037,7 @@ pub fn QueryInformationFile(
10301037 out_buffer: []u8,
10311038) QueryInformationFileError!void {
10321039 var io: IO_STATUS_BLOCK = undefined;
1033 const len_bytes = std.math.cast(u32, out_buffer.len) catch |err| switch (err) {
1034 error.Overflow => std.math.maxInt(u32), // If the provided buffer is larger than what we can handle, set size to max what we can handle
1035 };
1040 const len_bytes = std.math.cast(u32, out_buffer.len) catch unreachable;
10361041 const rc = ntdll.NtQueryInformationFile(handle, &io, out_buffer.ptr, len_bytes, info_class);
10371042 switch (rc) {
10381043 .SUCCESS => {},