Skip to content

Commit c9bed99

Browse files
naveen521kklazka
authored andcommitted
Always convert / to \\ before passing though pathcch functions
they don't seems to handle `/` as path separator correctly
1 parent 7344544 commit c9bed99

File tree

3 files changed

+36
-4
lines changed

3 files changed

+36
-4
lines changed

Include/pylifecycle.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ PyAPI_FUNC(char) Py_GetSepA(const char *);
2828
PyAPI_FUNC(void) Py_NormalizeSepsW(wchar_t *);
2929
PyAPI_FUNC(void) Py_NormalizeSepsA(char *);
3030

31+
PyAPI_FUNC(void) Py_NormalizeSepsPathcchW(wchar_t *);
32+
3133

3234
/* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level
3335
* exit functions.

Python/fileutils.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2005,19 +2005,31 @@ int
20052005
_Py_isabs(const wchar_t *path)
20062006
{
20072007
#ifdef MS_WINDOWS
2008+
// create a copy of path and replace all forward slashes with backslashes
2009+
// pathccskiproot does not handle forward slashes
2010+
wchar_t *path_copy = _wcsdup(path);
2011+
if (path_copy == NULL) {
2012+
return 0;
2013+
}
2014+
Py_NormalizeSepsPathcchW(path_copy);
2015+
20082016
const wchar_t *tail;
2009-
HRESULT hr = PathCchSkipRoot(path, &tail);
2010-
if (FAILED(hr) || path == tail) {
2017+
HRESULT hr = PathCchSkipRoot(path_copy, &tail);
2018+
if (FAILED(hr) || path_copy == tail) {
2019+
free(path_copy);
20112020
return 0;
20122021
}
2013-
if (tail == &path[1] && (path[0] == SEP || path[0] == ALTSEP)) {
2022+
if (tail == &path_copy[1] && (path_copy[0] == SEP || path_copy[0] == ALTSEP)) {
20142023
// Exclude paths with leading SEP
2024+
free(path_copy);
20152025
return 0;
20162026
}
2017-
if (tail == &path[2] && path[1] == L':') {
2027+
if (tail == &path_copy[2] && path_copy[1] == L':') {
20182028
// Exclude drive-relative paths (e.g. C:filename.ext)
2029+
free(path_copy);
20192030
return 0;
20202031
}
2032+
free(path_copy);
20212033
return 1;
20222034
#else
20232035
return (path[0] == SEP);
@@ -2098,6 +2110,8 @@ join_relfile(wchar_t *buffer, size_t bufsize,
20982110
const wchar_t *dirname, const wchar_t *relfile)
20992111
{
21002112
#ifdef MS_WINDOWS
2113+
Py_NormalizeSepsPathcchW(dirname);
2114+
Py_NormalizeSepsPathcchW(relfile);
21012115
if (FAILED(PathCchCombineEx(buffer, bufsize, dirname, relfile,
21022116
PATHCCH_ALLOW_LONG_PATHS))) {
21032117
return -1;

Python/pathconfig.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,22 @@ Py_NormalizeSepsW(wchar_t *name)
155155
}
156156
}
157157

158+
void
159+
Py_NormalizeSepsPathcchW(wchar_t *name)
160+
{
161+
#ifdef MS_WINDOWS
162+
assert(name != NULL);
163+
wchar_t sep = '\\';
164+
wchar_t altsep = '/';
165+
wchar_t* seps;
166+
seps = wcschr(name, altsep);
167+
while(seps) {
168+
*seps = sep;
169+
seps = wcschr(seps, altsep);
170+
}
171+
#endif
172+
}
173+
158174
/* External interface */
159175

160176
/* Stored values set by C API functions */

0 commit comments

Comments
 (0)