From c461c601ef809f986ed5b6df68dfec41384661c1 Mon Sep 17 00:00:00 2001
From: Naveen M K <naveen521kk@gmail.com>
Date: Sun, 25 Jun 2023 17:24:11 +0530
Subject: [PATCH 091/N] Always convert `/` to `\\` before passing though
 pathcch functions

they don't seems to handle `/` as path separator correctly
---
 Include/pylifecycle.h |  2 ++
 Python/fileutils.c    | 22 ++++++++++++++++++----
 Python/pathconfig.c   | 16 ++++++++++++++++
 3 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h
index 6eb171d..2963239 100644
--- a/Include/pylifecycle.h
+++ b/Include/pylifecycle.h
@@ -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.
diff --git a/Python/fileutils.c b/Python/fileutils.c
index a6e43e7..00f1e6a 100644
--- a/Python/fileutils.c
+++ b/Python/fileutils.c
@@ -2141,19 +2141,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);
@@ -2393,6 +2405,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;
diff --git a/Python/pathconfig.c b/Python/pathconfig.c
index 96b50b1..466a791 100644
--- a/Python/pathconfig.c
+++ b/Python/pathconfig.c
@@ -153,6 +153,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 */
