Skip to content

Commit

Permalink
Always convert / to \\ before passing though pathcch functions
Browse files Browse the repository at this point in the history
they don't seems to handle `/` as path separator correctly
  • Loading branch information
naveen521kk authored and lazka committed Jul 19, 2023
1 parent 477f7b3 commit 3b7cbbf
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 4 deletions.
2 changes: 2 additions & 0 deletions Include/pylifecycle.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ PyAPI_FUNC(char) Py_GetSepA(const char *);
PyAPI_FUNC(void) Py_NormalizeSepsW(wchar_t *);
PyAPI_FUNC(void) Py_NormalizeSepsA(char *);

PyAPI_FUNC(void) Py_NormalizeSepsPathcchW(wchar_t *);


/* Py_PyAtExit is for the atexit module, Py_AtExit is for low-level
* exit functions.
Expand Down
22 changes: 18 additions & 4 deletions Python/fileutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -2005,19 +2005,31 @@ int
_Py_isabs(const wchar_t *path)
{
#ifdef MS_WINDOWS
// create a copy of path and replace all forward slashes with backslashes
// pathccskiproot does not handle forward slashes
wchar_t *path_copy = _wcsdup(path);
if (path_copy == NULL) {
return 0;
}
Py_NormalizeSepsPathcchW(path_copy);

const wchar_t *tail;
HRESULT hr = PathCchSkipRoot(path, &tail);
if (FAILED(hr) || path == tail) {
HRESULT hr = PathCchSkipRoot(path_copy, &tail);
if (FAILED(hr) || path_copy == tail) {
free(path_copy);
return 0;
}
if (tail == &path[1] && (path[0] == SEP || path[0] == ALTSEP)) {
if (tail == &path_copy[1] && (path_copy[0] == SEP || path_copy[0] == ALTSEP)) {
// Exclude paths with leading SEP
free(path_copy);
return 0;
}
if (tail == &path[2] && path[1] == L':') {
if (tail == &path_copy[2] && path_copy[1] == L':') {
// Exclude drive-relative paths (e.g. C:filename.ext)
free(path_copy);
return 0;
}
free(path_copy);
return 1;
#else
return (path[0] == SEP);
Expand Down Expand Up @@ -2098,6 +2110,8 @@ join_relfile(wchar_t *buffer, size_t bufsize,
const wchar_t *dirname, const wchar_t *relfile)
{
#ifdef MS_WINDOWS
Py_NormalizeSepsPathcchW(dirname);
Py_NormalizeSepsPathcchW(relfile);
if (FAILED(PathCchCombineEx(buffer, bufsize, dirname, relfile,
PATHCCH_ALLOW_LONG_PATHS))) {
return -1;
Expand Down
16 changes: 16 additions & 0 deletions Python/pathconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,22 @@ Py_NormalizeSepsW(wchar_t *name)
}
}

void
Py_NormalizeSepsPathcchW(wchar_t *name)
{
#ifdef MS_WINDOWS
assert(name != NULL);
wchar_t sep = '\\';
wchar_t altsep = '/';
wchar_t* seps;
seps = wcschr(name, altsep);
while(seps) {
*seps = sep;
seps = wcschr(seps, altsep);
}
#endif
}

/* External interface */

/* Stored values set by C API functions */
Expand Down

0 comments on commit 3b7cbbf

Please sign in to comment.