@@ -7471,7 +7471,7 @@ win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7471
7471
#if defined(MS_WINDOWS )
7472
7472
7473
7473
/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7474
- static DWORD (CALLBACK * Py_CreateSymbolicLinkW )(LPCWSTR , LPCWSTR , DWORD ) = NULL ;
7474
+ static BOOLEAN (CALLBACK * Py_CreateSymbolicLinkW )(LPCWSTR , LPCWSTR , DWORD ) = NULL ;
7475
7475
7476
7476
static int
7477
7477
check_CreateSymbolicLink (void )
@@ -7486,47 +7486,51 @@ check_CreateSymbolicLink(void)
7486
7486
return Py_CreateSymbolicLinkW != NULL ;
7487
7487
}
7488
7488
7489
- /* Remove the last portion of the path */
7490
- static void
7489
+ /* Remove the last portion of the path - return 0 on success */
7490
+ static int
7491
7491
_dirnameW (WCHAR * path )
7492
7492
{
7493
7493
WCHAR * ptr ;
7494
+ size_t length = wcsnlen_s (path , MAX_PATH );
7495
+ if (length == MAX_PATH ) {
7496
+ return -1 ;
7497
+ }
7494
7498
7495
7499
/* walk the path from the end until a backslash is encountered */
7496
- for (ptr = path + wcslen ( path ) ; ptr != path ; ptr -- ) {
7497
- if (* ptr == L'\\' || * ptr == L'/' )
7500
+ for (ptr = path + length ; ptr != path ; ptr -- ) {
7501
+ if (* ptr == L'\\' || * ptr == L'/' ) {
7498
7502
break ;
7503
+ }
7499
7504
}
7500
7505
* ptr = 0 ;
7506
+ return 0 ;
7501
7507
}
7502
7508
7503
7509
/* Is this path absolute? */
7504
7510
static int
7505
7511
_is_absW (const WCHAR * path )
7506
7512
{
7507
- return path [0 ] == L'\\' || path [0 ] == L'/' || path [ 1 ] == L':' ;
7508
-
7513
+ return path [0 ] == L'\\' || path [0 ] == L'/' ||
7514
+ ( path [ 0 ] && path [ 1 ] == L':' );
7509
7515
}
7510
7516
7511
- /* join root and rest with a backslash */
7512
- static void
7517
+ /* join root and rest with a backslash - return 0 on success */
7518
+ static int
7513
7519
_joinW (WCHAR * dest_path , const WCHAR * root , const WCHAR * rest )
7514
7520
{
7515
- size_t root_len ;
7516
-
7517
7521
if (_is_absW (rest )) {
7518
- wcscpy (dest_path , rest );
7519
- return ;
7522
+ return wcscpy_s (dest_path , MAX_PATH , rest );
7520
7523
}
7521
7524
7522
- root_len = wcslen (root );
7525
+ if (wcscpy_s (dest_path , MAX_PATH , root )) {
7526
+ return -1 ;
7527
+ }
7523
7528
7524
- wcscpy (dest_path , root );
7525
- if (root_len ) {
7526
- dest_path [root_len ] = L'\\' ;
7527
- root_len ++ ;
7529
+ if (dest_path [0 ] && wcscat_s (dest_path , MAX_PATH , L"\\" )) {
7530
+ return -1 ;
7528
7531
}
7529
- wcscpy (dest_path + root_len , rest );
7532
+
7533
+ return wcscat_s (dest_path , MAX_PATH , rest );
7530
7534
}
7531
7535
7532
7536
/* Return True if the path at src relative to dest is a directory */
@@ -7538,10 +7542,14 @@ _check_dirW(LPCWSTR src, LPCWSTR dest)
7538
7542
WCHAR src_resolved [MAX_PATH ] = L"" ;
7539
7543
7540
7544
/* dest_parent = os.path.dirname(dest) */
7541
- wcscpy (dest_parent , dest );
7542
- _dirnameW (dest_parent );
7545
+ if (wcscpy_s (dest_parent , MAX_PATH , dest ) ||
7546
+ _dirnameW (dest_parent )) {
7547
+ return 0 ;
7548
+ }
7543
7549
/* src_resolved = os.path.join(dest_parent, src) */
7544
- _joinW (src_resolved , dest_parent , src );
7550
+ if (_joinW (src_resolved , dest_parent , src )) {
7551
+ return 0 ;
7552
+ }
7545
7553
return (
7546
7554
GetFileAttributesExW (src_resolved , GetFileExInfoStandard , & src_info )
7547
7555
&& src_info .dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
@@ -7597,26 +7605,28 @@ os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
7597
7605
}
7598
7606
#endif
7599
7607
7600
- if ((src -> narrow && dst -> wide ) || (src -> wide && dst -> narrow )) {
7601
- PyErr_SetString (PyExc_ValueError ,
7602
- "symlink: src and dst must be the same type" );
7603
- return NULL ;
7604
- }
7605
-
7606
7608
#ifdef MS_WINDOWS
7607
7609
7608
7610
Py_BEGIN_ALLOW_THREADS
7611
+ _Py_BEGIN_SUPPRESS_IPH
7609
7612
/* if src is a directory, ensure target_is_directory==1 */
7610
7613
target_is_directory |= _check_dirW (src -> wide , dst -> wide );
7611
7614
result = Py_CreateSymbolicLinkW (dst -> wide , src -> wide ,
7612
7615
target_is_directory );
7616
+ _Py_END_SUPPRESS_IPH
7613
7617
Py_END_ALLOW_THREADS
7614
7618
7615
7619
if (!result )
7616
7620
return path_error2 (src , dst );
7617
7621
7618
7622
#else
7619
7623
7624
+ if ((src -> narrow && dst -> wide ) || (src -> wide && dst -> narrow )) {
7625
+ PyErr_SetString (PyExc_ValueError ,
7626
+ "symlink: src and dst must be the same type" );
7627
+ return NULL ;
7628
+ }
7629
+
7620
7630
Py_BEGIN_ALLOW_THREADS
7621
7631
#if HAVE_SYMLINKAT
7622
7632
if (dir_fd != DEFAULT_DIR_FD )
0 commit comments