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 {...@@ -897,6 +897,7 @@ pub fn SetFilePointerEx_CURRENT_get(handle: HANDLE) SetFilePointerError!u64 {
897}897}
898898
899pub const GetFinalPathNameByHandleError = error{899pub const GetFinalPathNameByHandleError = error{
900 BadPathName,
900 FileNotFound,901 FileNotFound,
901 NameTooLong,902 NameTooLong,
902 Unexpected,903 Unexpected,
...@@ -925,11 +926,11 @@ pub fn GetFinalPathNameByHandle(...@@ -925,11 +926,11 @@ pub fn GetFinalPathNameByHandle(
925) GetFinalPathNameByHandleError![]u16 {926) GetFinalPathNameByHandleError![]u16 {
926 // Get normalized path; doesn't include volume name though.927 // Get normalized path; doesn't include volume name though.
927 var path_buffer: [@sizeOf(FILE_NAME_INFORMATION) + PATH_MAX_WIDE * 2]u8 align(@alignOf(FILE_NAME_INFORMATION)) = undefined;928 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
930 // Get NT volume name.931 // Get NT volume name.
931 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 name932 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
934 const file_name = @ptrCast(*const FILE_NAME_INFORMATION, &path_buffer[0]);935 const file_name = @ptrCast(*const FILE_NAME_INFORMATION, &path_buffer[0]);
935 const file_name_u16 = @ptrCast([*]const u16, &file_name.FileName[0])[0 .. file_name.FileNameLength / 2];936 const file_name_u16 = @ptrCast([*]const u16, &file_name.FileName[0])[0 .. file_name.FileNameLength / 2];
...@@ -1010,8 +1011,14 @@ pub fn GetFinalPathNameByHandle(...@@ -1010,8 +1011,14 @@ pub fn GetFinalPathNameByHandle(
10101011
1011 std.mem.copy(u16, out_buffer[0..], drive_letter);1012 std.mem.copy(u16, out_buffer[0..], drive_letter);
1012 std.mem.copy(u16, out_buffer[drive_letter.len..], file_name_u16);1013 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];
1015 }1022 }
1016 }1023 }
10171024
...@@ -1030,9 +1037,7 @@ pub fn QueryInformationFile(...@@ -1030,9 +1037,7 @@ pub fn QueryInformationFile(
1030 out_buffer: []u8,1037 out_buffer: []u8,
1031) QueryInformationFileError!void {1038) QueryInformationFileError!void {
1032 var io: IO_STATUS_BLOCK = undefined;1039 var io: IO_STATUS_BLOCK = undefined;
1033 const len_bytes = std.math.cast(u32, out_buffer.len) catch |err| switch (err) {1040 const len_bytes = std.math.cast(u32, out_buffer.len) catch unreachable;
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 };
1036 const rc = ntdll.NtQueryInformationFile(handle, &io, out_buffer.ptr, len_bytes, info_class);1041 const rc = ntdll.NtQueryInformationFile(handle, &io, out_buffer.ptr, len_bytes, info_class);
1037 switch (rc) {1042 switch (rc) {
1038 .SUCCESS => {},1043 .SUCCESS => {},