@@ -897,6 +897,7 @@ pub fn SetFilePointerEx_CURRENT_get(handle: HANDLE) SetFilePointerError!u64 {
897
897
}
898
898
899
899
pub const GetFinalPathNameByHandleError = error {
900
+ BadPathName ,
900
901
FileNotFound ,
901
902
NameTooLong ,
902
903
Unexpected ,
@@ -925,11 +926,11 @@ pub fn GetFinalPathNameByHandle(
925
926
) GetFinalPathNameByHandleError ! []u16 {
926
927
// Get normalized path; doesn't include volume name though.
927
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.. ]);
929
930
930
931
// Get NT volume name.
931
932
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.. ]);
933
934
934
935
const file_name = @ptrCast (* const FILE_NAME_INFORMATION , & path_buffer [0 ]);
935
936
const file_name_u16 = @ptrCast ([* ]const u16 , & file_name .FileName [0 ])[0 .. file_name .FileNameLength / 2 ];
@@ -1010,8 +1011,17 @@ pub fn GetFinalPathNameByHandle(
1010
1011
1011
1012
std .mem .copy (u16 , out_buffer [0.. ], drive_letter );
1012
1013
std .mem .copy (u16 , out_buffer [drive_letter .len .. ], file_name_u16 );
1014
+ const total_len = drive_letter .len + file_name_u16 .len ;
1013
1015
1014
- return out_buffer [0 .. drive_letter .len + file_name_u16 .len ];
1016
+ // Validate that DOS does not contain any spurious nul bytes.
1017
+ var iter = std .unicode .Utf16LeIterator .init (out_buffer [0.. total_len ]);
1018
+ var next = iter .nextCodepoint () catch return error .BadPathName ;
1019
+ while (next ) | cp | {
1020
+ if (cp == 0 ) return error .BadPathName ;
1021
+ next = iter .nextCodepoint () catch return error .BadPathName ;
1022
+ }
1023
+
1024
+ return out_buffer [0 .. total_len ];
1015
1025
}
1016
1026
}
1017
1027
@@ -1030,9 +1040,7 @@ pub fn QueryInformationFile(
1030
1040
out_buffer : []u8 ,
1031
1041
) QueryInformationFileError ! void {
1032
1042
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
- };
1043
+ const len_bytes = std .math .cast (u32 , out_buffer .len ) catch unreachable ;
1036
1044
const rc = ntdll .NtQueryInformationFile (handle , & io , out_buffer .ptr , len_bytes , info_class );
1037
1045
switch (rc ) {
1038
1046
.SUCCESS = > {},
0 commit comments