Skip to content

Conversation

@tonghuaroot
Copy link

@tonghuaroot tonghuaroot commented Jan 17, 2026

Closes gh-143968

[3.14] gh-143968: Prevent pathlib.Path.copy() from processing special files (FIFO, devices)

Description

This PR addresses an issue where pathlib.Path.copy() (introduced for 3.14) could indiscriminately attempt to open and read from special files like FIFOs (named pipes) or character devices (e.g., /dev/zero).

The Problem

  • FIFOs: Reading from a FIFO without a writer blocks indefinitely, causing the Python process to hang.
  • Infinite Sources: Reading from /dev/zero results in an infinite loop that continues until disk space is exhausted or the process is killed.

The Fix

The copy logic in _copy_from inside Lib/pathlib/__init__.py has been modified to explicitly check is_file() before attempting to copy content.

  • If the source is a regular file, it proceeds as normal.
  • If it is a directory (already handled), it recurses.
  • New Behavior: If it is a special file (but exists), it raises io.UnsupportedOperation.
    • This aligns with shutil.copyfile's philosophy of safely handling special files by refusing to copy them as streams.
  • Existing behavior for dangling symlinks (raising FileNotFoundError) is strictly preserved.

Tests

Added new test cases in Lib/test/test_pathlib/test_copy.py to cover these scenarios:

  • test_copy_fifo: Verifies that copying a FIFO (created via os.mkfifo) raises UnsupportedOperation immediately instead of blocking.
  • test_copy_char_device: Verifies that copying a character device (e.g., /dev/null) raises UnsupportedOperation.

Validation

  • Ran python -m test test_pathlib locally and all 1375 tests passed.

Previously, `pathlib.Path.copy()` would indiscriminately attempt to open and read from the source path if it wasn't a directory or symlink. This caused severe issues with special files:
1. Blocking indefinitely when reading from a FIFO (named pipe).
2. Entering an infinite loop when reading from zero-generators like `/dev/zero`.

This commit modifies the copy logic to explicitly verify that the source is a regular file using `is_file()` before attempting to copy its content. If the source exists but is a special file, `io.UnsupportedOperation` is now raised. This change aligns `pathlib`'s behavior with safety expectations and prevents resource exhaustion or hanging processes.

Existing behavior for dangling symlinks (raising FileNotFoundError) is preserved.

Tests added:
- `test_copy_fifo`: Ensures copying a FIFO raises UnsupportedOperation.
- `test_copy_char_device`: Ensures copying a character device (e.g. /dev/null) raises UnsupportedOperation.
@bedevere-app
Copy link

bedevere-app bot commented Jan 17, 2026

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@python-cla-bot
Copy link

python-cla-bot bot commented Jan 17, 2026

All commit authors signed the Contributor License Agreement.

CLA signed

@bedevere-app
Copy link

bedevere-app bot commented Jan 17, 2026

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@bedevere-app
Copy link

bedevere-app bot commented Jan 17, 2026

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@bedevere-app
Copy link

bedevere-app bot commented Jan 17, 2026

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@tonghuaroot tonghuaroot changed the title [3.14] Prevent pathlib.Path.copy() from processing special files (FIFO, devices) [3.14] gh-143968: Prevent pathlib.Path.copy() from processing special files (FIFO, devices) Jan 17, 2026
@StanFromIreland StanFromIreland changed the title [3.14] gh-143968: Prevent pathlib.Path.copy() from processing special files (FIFO, devices) gh-143968: Prevent pathlib.Path.copy() from processing special files (FIFO, devices) Jan 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pathlib.Path.copy() hangs on FIFO pipes and loops infinitely on /dev/zero

1 participant