@@ -7144,7 +7144,7 @@ win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
71447144#if defined(MS_WINDOWS )
71457145
71467146/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7147- static DWORD (CALLBACK * Py_CreateSymbolicLinkW )(LPCWSTR , LPCWSTR , DWORD ) = NULL ;
7147+ static BOOLEAN (CALLBACK * Py_CreateSymbolicLinkW )(LPCWSTR , LPCWSTR , DWORD ) = NULL ;
71487148
71497149static int
71507150check_CreateSymbolicLink (void )
@@ -7159,47 +7159,51 @@ check_CreateSymbolicLink(void)
71597159 return Py_CreateSymbolicLinkW != NULL ;
71607160}
71617161
7162- /* Remove the last portion of the path */
7163- static void
7162+ /* Remove the last portion of the path - return 0 on success */
7163+ static int
71647164_dirnameW (WCHAR * path )
71657165{
71667166 WCHAR * ptr ;
7167+ size_t length = wcsnlen_s (path , MAX_PATH );
7168+ if (length == MAX_PATH ) {
7169+ return -1 ;
7170+ }
71677171
71687172 /* walk the path from the end until a backslash is encountered */
7169- for (ptr = path + wcslen ( path ) ; ptr != path ; ptr -- ) {
7170- if (* ptr == L'\\' || * ptr == L'/' )
7173+ for (ptr = path + length ; ptr != path ; ptr -- ) {
7174+ if (* ptr == L'\\' || * ptr == L'/' ) {
71717175 break ;
7176+ }
71727177 }
71737178 * ptr = 0 ;
7179+ return 0 ;
71747180}
71757181
71767182/* Is this path absolute? */
71777183static int
71787184_is_absW (const WCHAR * path )
71797185{
7180- return path [0 ] == L'\\' || path [0 ] == L'/' || path [ 1 ] == L':' ;
7181-
7186+ return path [0 ] == L'\\' || path [0 ] == L'/' ||
7187+ ( path [ 0 ] && path [ 1 ] == L':' );
71827188}
71837189
7184- /* join root and rest with a backslash */
7185- static void
7190+ /* join root and rest with a backslash - return 0 on success */
7191+ static int
71867192_joinW (WCHAR * dest_path , const WCHAR * root , const WCHAR * rest )
71877193{
7188- size_t root_len ;
7189-
71907194 if (_is_absW (rest )) {
7191- wcscpy (dest_path , rest );
7192- return ;
7195+ return wcscpy_s (dest_path , MAX_PATH , rest );
71937196 }
71947197
7195- root_len = wcslen (root );
7198+ if (wcscpy_s (dest_path , MAX_PATH , root )) {
7199+ return -1 ;
7200+ }
71967201
7197- wcscpy (dest_path , root );
7198- if (root_len ) {
7199- dest_path [root_len ] = L'\\' ;
7200- root_len ++ ;
7202+ if (dest_path [0 ] && wcscat_s (dest_path , MAX_PATH , L"\\" )) {
7203+ return -1 ;
72017204 }
7202- wcscpy (dest_path + root_len , rest );
7205+
7206+ return wcscat_s (dest_path , MAX_PATH , rest );
72037207}
72047208
72057209/* Return True if the path at src relative to dest is a directory */
@@ -7211,10 +7215,14 @@ _check_dirW(LPCWSTR src, LPCWSTR dest)
72117215 WCHAR src_resolved [MAX_PATH ] = L"" ;
72127216
72137217 /* dest_parent = os.path.dirname(dest) */
7214- wcscpy (dest_parent , dest );
7215- _dirnameW (dest_parent );
7218+ if (wcscpy_s (dest_parent , MAX_PATH , dest ) ||
7219+ _dirnameW (dest_parent )) {
7220+ return 0 ;
7221+ }
72167222 /* src_resolved = os.path.join(dest_parent, src) */
7217- _joinW (src_resolved , dest_parent , src );
7223+ if (_joinW (src_resolved , dest_parent , src )) {
7224+ return 0 ;
7225+ }
72187226 return (
72197227 GetFileAttributesExW (src_resolved , GetFileExInfoStandard , & src_info )
72207228 && src_info .dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
@@ -7270,26 +7278,28 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
72707278 }
72717279#endif
72727280
7273- if ((src -> narrow && dst -> wide ) || (src -> wide && dst -> narrow )) {
7274- PyErr_SetString (PyExc_ValueError ,
7275- "symlink: src and dst must be the same type" );
7276- return NULL ;
7277- }
7278-
72797281#ifdef MS_WINDOWS
72807282
72817283 Py_BEGIN_ALLOW_THREADS
7284+ _Py_BEGIN_SUPPRESS_IPH
72827285 /* if src is a directory, ensure target_is_directory==1 */
72837286 target_is_directory |= _check_dirW (src -> wide , dst -> wide );
72847287 result = Py_CreateSymbolicLinkW (dst -> wide , src -> wide ,
72857288 target_is_directory );
7289+ _Py_END_SUPPRESS_IPH
72867290 Py_END_ALLOW_THREADS
72877291
72887292 if (!result )
72897293 return path_error2 (src , dst );
72907294
72917295#else
72927296
7297+ if ((src -> narrow && dst -> wide ) || (src -> wide && dst -> narrow )) {
7298+ PyErr_SetString (PyExc_ValueError ,
7299+ "symlink: src and dst must be the same type" );
7300+ return NULL ;
7301+ }
7302+
72937303 Py_BEGIN_ALLOW_THREADS
72947304#if HAVE_SYMLINKAT
72957305 if (dir_fd != DEFAULT_DIR_FD )
0 commit comments