8000 gh-91133: tempfile.TemporaryDirectory: fix symlink bug in cleanup by kwi-dk · Pull Request #99930 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-91133: tempfile.TemporaryDirectory: fix symlink bug in cleanup #99930

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Dec 7, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Address review comments.
  • Loading branch information
serhiy-storchaka committed Dec 7, 2023
commit 0a05de044d57bd671327530d8788000b826403f5
32 changes: 16 additions & 16 deletions Lib/tempfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,20 @@ def _mkstemp_inner(dir, pre, suf, flags, output_type):
raise FileExistsError(_errno.EEXIST,
"No usable temporary file name found")

def _dont_follow_symlinks(func, path, *args):
# Pass follow_symlinks=False, unless not supported on this platform.
if func in _os.supports_follow_symlinks:
func(path, *args, follow_symlinks=False)
elif _os.name == 'nt' or not _os.path.islink(path):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why skipping the islink() test on Windows? The os.path.islink() function is available on Windows: https://docs.python.org/dev/library/os.path.html#os.path.islink

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because on Window os.chmod() changes the mode of the symlink.

func(path, *args)

def _resetperms(path):
try:
_dont_follow_symlinks(_os.chflags, path, 0)
except AttributeError:
pass
_dont_follow_symlinks(_os.chmod, path, 0o700)


# User visible interfaces.

Expand Down Expand Up @@ -874,26 +888,12 @@ def __init__(self, suffix=None, prefix=None, dir=None,

@classmethod
def _rmtree(cls, name, ignore_errors=False):
def without_following_symlinks(func, path, *args):
# Pass follow_symlinks=False, unless not supported on this platform.
if func in _os.supports_follow_symlinks:
func(path, *args, follow_symlinks=False)
elif _os.name == 'nt' or not _os.path.islink(path):
func(path, *args)

def resetperms(path):
try:
without_following_symlinks(_os.chflags, path, 0)
except AttributeError:
pass
without_following_symlinks(_os.chmod, path, 0o700)

def onexc(func, path, exc):
if isinstance(exc, PermissionError):
try:
if path != name:
resetperms(_os.path.dirname(path))
resetperms(path)
_resetperms(_os.path.dirname(path))
_resetperms(path)

try:
_os.unlink(path)
Expand Down
0