From c31e248351034e2576f31aee622ed9741c7245c9 Mon Sep 17 00:00:00 2001 From: Moonsik Park Date: Thu, 12 Oct 2023 00:46:08 +0900 Subject: [PATCH 1/2] keep running the loop and add seen set. --- Lib/ntpath.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Lib/ntpath.py b/Lib/ntpath.py index 3061a4a5ef4c56..50ea316bd8e7f0 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -605,7 +605,7 @@ def abspath(path): # realpath is a no-op on systems without _getfinalpathname support. realpath = abspath else: - def _readlink_deep(path): + def _readlink_deep(path, seen): # These error codes indicate that we should stop reading links and # return the path we currently have. # 1: ERROR_INVALID_FUNCTION @@ -622,7 +622,6 @@ def _readlink_deep(path): # 4393: ERROR_REPARSE_TAG_INVALID allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 67, 87, 4390, 4392, 4393 - seen = set() while normcase(path) not in seen: seen.add(normcase(path)) try: @@ -670,6 +669,7 @@ def _getfinalpathname_nonstrict(path): # Non-strict algorithm is to find as much of the target directory # as we can and join the rest. tail = path[:0] + seen = set() while path: try: path = _getfinalpathname(path) @@ -679,11 +679,13 @@ def _getfinalpathname_nonstrict(path): raise try: # The OS could not resolve this path fully, so we attempt - # to follow the link ourselves. If we succeed, join the tail - # and return. - new_path = _readlink_deep(path) - if new_path != path: + # to follow the link ourselves. If we succeed, keep running the loop. + new_path = _readlink_deep(path, seen) + if new_path in seen: return join(new_path, tail) if tail else new_path + else: + seen.add(new_path) + path = new_path except OSError: # If we fail to readlink(), let's keep traversing pass From 3ae56f073ba547ae2059d71f49917296368b817b Mon Sep 17 00:00:00 2001 From: Moonsik Park Date: Tue, 19 Mar 2024 14:41:15 +0900 Subject: [PATCH 2/2] normalize paths via `normcase()` before comparing or adding to `seen` set. --- Lib/ntpath.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/ntpath.py b/Lib/ntpath.py index 41df097515bb86..5d068123ed709c 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -710,10 +710,11 @@ def _getfinalpathname_nonstrict(path): # The OS could not resolve this path fully, so we attempt # to follow the link ourselves. If we succeed, keep running the loop. new_path = _readlink_deep(path, seen) - if new_path in seen: + new_path_normcase = normcase(new_path) + if new_path_normcase in seen: return join(new_path, tail) if tail else new_path else: - seen.add(new_path) + seen.add(new_path_normcase) path = new_path except OSError: # If we fail to readlink(), let's keep traversing