@@ -7144,7 +7144,7 @@ win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7144
7144
#if defined(MS_WINDOWS )
7145
7145
7146
7146
/* 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 ;
7148
7148
7149
7149
static int
7150
7150
check_CreateSymbolicLink (void )
@@ -7159,47 +7159,51 @@ check_CreateSymbolicLink(void)
7159
7159
return Py_CreateSymbolicLinkW != NULL ;
7160
7160
}
7161
7161
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
7164
7164
_dirnameW (WCHAR * path )
7165
7165
{
7166
7166
WCHAR * ptr ;
7167
+ size_t length = wcsnlen_s (path , MAX_PATH );
7168
+ if (length == MAX_PATH ) {
7169
+ return -1 ;
7170
+ }
7167
7171
7168
7172
/* 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'/' ) {
7171
7175
break ;
7176
+ }
7172
7177
}
7173
7178
* ptr = 0 ;
7179
+ return 0 ;
7174
7180
}
7175
7181
7176
7182
/* Is this path absolute? */
7177
7183
static int
7178
7184
_is_absW (const WCHAR * path )
7179
7185
{
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':' );
7182
7188
}
7183
7189
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
7186
7192
_joinW (WCHAR * dest_path , const WCHAR * root , const WCHAR * rest )
7187
7193
{
7188
- size_t root_len ;
7189
-
7190
7194
if (_is_absW (rest )) {
7191
- wcscpy (dest_path , rest );
7192
- return ;
7195
+ return wcscpy_s (dest_path , MAX_PATH , rest );
7193
7196
}
7194
7197
7195
- root_len = wcslen (root );
7198
+ if (wcscpy_s (dest_path , MAX_PATH , root )) {
7199
+ return -1 ;
7200
+ }
7196
7201
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 ;
7201
7204
}
7202
- wcscpy (dest_path + root_len , rest );
7205
+
7206
+ return wcscat_s (dest_path , MAX_PATH , rest );
7203
7207
}
7204
7208
7205
7209
/* Return True if the path at src relative to dest is a directory */
@@ -7211,10 +7215,14 @@ _check_dirW(LPCWSTR src, LPCWSTR dest)
7211
7215
WCHAR src_resolved [MAX_PATH ] = L"" ;
7212
7216
7213
7217
/* 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
+ }
7216
7222
/* 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
+ }
7218
7226
return (
7219
7227
GetFileAttributesExW (src_resolved , GetFileExInfoStandard , & src_info )
7220
7228
&& src_info .dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
@@ -7270,26 +7278,28 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
7270
7278
}
7271
7279
#endif
7272
7280
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
-
7279
7281
#ifdef MS_WINDOWS
7280
7282
7281
7283
Py_BEGIN_ALLOW_THREADS
7284
+ _Py_BEGIN_SUPPRESS_IPH
7282
7285
/* if src is a directory, ensure target_is_directory==1 */
7283
7286
target_is_directory |= _check_dirW (src -> wide , dst -> wide );
7284
7287
result = Py_CreateSymbolicLinkW (dst -> wide , src -> wide ,
7285
7288
target_is_directory );
7289
+ _Py_END_SUPPRESS_IPH
7286
7290
Py_END_ALLOW_THREADS
7287
7291
7288
7292
if (!result )
7289
7293
return path_error2 (src , dst );
7290
7294
7291
7295
#else
7292
7296
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
+
7293
7303
Py_BEGIN_ALLOW_THREADS
7294
7304
#if HAVE_SYMLINKAT
7295
7305
if (dir_fd != DEFAULT_DIR_FD )
0 commit comments