python/cpython

os.path.realpath() RecursionError

Opened this issue · 5 comments

os.path.realpath() attempts to detect symlink loops, but this is not bulletproof;
it's possible to make it fall into infinite recursion.

Reproducer:

import os
import tempfile

with tempfile.TemporaryDirectory() as tmpdir:
    os.chdir(tmpdir)
    os.symlink('../' * (1 + tmpdir.count('/')) + f'{tmpdir}/d', 'd')
    os.path.realpath('d')

Traceback:

Traceback (most recent call last):
  File ".../recursiverealpath.py", line 7, in <module>
    os.path.realpath('d')
  File "<frozen posixpath>", line 427, in realpath
  File "<frozen posixpath>", line 487, in _joinrealpath
  File "<frozen posixpath>", line 487, in _joinrealpath
  File "<frozen posixpath>", line 487, in _joinrealpath
  [Previous line repeated 993 more times]
  File "<frozen posixpath>", line 442, in _joinrealpath
  File "<frozen posixpath>", line 63, in isabs
RecursionError: maximum recursion depth exceeded

Tested with Python 3.12.8.

This issue no longer reproduces in the the latest version (Python 3.14.0a3+ (heads/main:f802c8bf87, Jan 7 2025, 08:12:30) [GCC 12.2.0] on linux).

And in my opinion it seems to be an issue with os.symlink as it doesn't handle illegal paths...

This issue no longer reproduces in the the latest version

Looks like this was indeed fixed in abfa16b ("GH-114847: Speed up posixpath.realpath() (#114848)").

in my opinion it seems to be an issue with os.symlink as it doesn't handle illegal paths...

No, os.symlink() works as expected.

@barneygale Should we backport gh-114848 to fix the issue or is there something else we should do for 3.12 and 3.13?

I think #114848 landed in 3.13 already? Not sure about backporting to 3.12 - it's close to EOL and the fix is invasive

Ok, yes indeed it landed in 3.13.0a6. I think we can close this one as wont fix for 3.12 and completed for 3.13+.