Skip to content

gh-160863: Restore tarfile data filter's resolved destination check - #24

Draft
gpshead wants to merge 1 commit into
mainfrom
gh-160863-minimal
Draft

gpshead wants to merge 1 commit into
mainfrom
gh-160863-minimal

Conversation

@gpshead

@gpshead gpshead commented Oct 29, 2026

Copy link
Copy Markdown
Owner

This is the minimal fix proposed in pythongh-160863, an alternative to the broader fix in #23.

python#160098 (for pythongh-160097) moved data_filter's check for link members that resolve to the destination directory into the code shared with tar_filter. A later commit in that PR made the shared check lexical: it now looks only at whether the member's normalised name is .. As a result, link members that reach the destination any other way pass filter='data', which has been the default since 3.14:

Archive members (filter='data') main today This PR
../dest → dest RecursionError OutsideDestinationError
d/, s → ., hard link s/. → d completes; the destination's own mode is changed OutsideDestinationError
first.txt, ../current → real, later.txt, extracted into an existing symlink current → real completes; current is replaced and later.txt is written outside the destination OutsideDestinationError

Change

Lib/tarfile.py: puts back the five lines that python#160098 removed from the 'data' link checks (if target_path == dest_path: raise OutsideDestinationError, with their comment). The six-line lexical check that tar_filter gained is kept. data_filter behaves exactly as it did before pythongh-160097.

Lib/test/test_tarfile.py: test_link_resolving_to_destination covers the three reproducers from the issue under filter='data'.

No doc change: the data_filter docs did not describe this check before pythongh-160097 either.

Compared with #23

This PR is smaller and only restores old behaviour, so it is the safer one to backport. It leaves two things as they were before pythongh-160097, and #23 fixes both:

Testing

Run on a Linux --with-pydebug build:

  • ./python -m test test_tarfile test_shutil -u all passes (1,032 run, 162 skipped).
  • Without the tarfile.py change, the new test fails in all three cases: one RecursionError and two "OutsideDestinationError not raised".
  • Windows and macOS have not been run.

Generated by Claude Code

…ion check

pythongh-160097 moved data_filter's check for link members that resolve to
the destination directory into the code shared with tar_filter, then
made the shared check lexical (the member's normalised name is '.').
Link members reaching the destination any other way then passed even
filter='data':

* '../dest' raised RecursionError instead of OutsideDestinationError;
* 's' -> '.' followed by a hard link 's/.' changed the destination
  directory's own mode;
* '../current', where 'current' is an existing symlink outside the
  destination pointing at it, replaced that symlink and wrote later
  members outside the destination.

Put the removed 'target_path == dest_path' check back in the 'data'
link checks, keeping the lexical check that tar_filter gained.  This
restores data_filter's pre-pythongh-160097 behaviour exactly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019EeY1aVDfL7Y3eMxYWdYgc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant