python / python/cpython

shutil.copytree infinite recursion crash on Windows Directory Junctions (WinError 206)

Đang mở
#142,155 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

OS-windows stdlib type-bug
Ngôn ngữ chính
Python
Star
77.2k
Fork
35.9k
Chỉ số merge pull request
Chỉ số pull request đang chờ

Mô tả

Bug report

Bug description:

Bug Description

On Windows, shutil.copytree fails to detect recursive cycles when processing Directory Junctions.

In Lib/shutil.py, the code explicitly forces traversal into Windows Junctions by treating them as standard directories (is_symlink is forced to False). However, there is no cycle detection mechanism (e.g., checking st_ino / nFileIndex) for these traversed directories.

If a Junction points to a parent directory, shutil.copytree enters an infinite recursion loop until it hits the OS path length limit, causing the process to crash with WinError 206 (Path too long) or WinError 1921.

Reproduction Steps

Run the following script on Windows:

import os
import shutil
import subprocess
import tempfile

def test_junction_crash():
    base_temp = tempfile.mkdtemp()
    src = os.path.join(base_temp, "Source")
    dst = os.path.join(base_temp, "Dest")
    junction = os.path.join(src, "Loop")
    
    try:
        os.makedirs(src)
        # Create a recursive Junction: Source/Loop -> Source
        subprocess.run(f'mklink /J "{junction}" "{src}"', shell=True, check=True)
        
        print("Starting copytree (expecting crash)...")
        shutil.copytree(src, dst)
        
    except Exception as e:
        print(e)

if __name__ == "__main__":
    test_junction_crash()

Actual Behavior

The script crashes with an unhandled shutil.Error wrapping a WinError 206, showing a deeply nested path.

Traceback:

Traceback (most recent call last):
  ...
  File "C:\...\lib\shutil.py", line 559, in copytree
    return _copytree(entries=entries, src=src, dst=dst, symlinks=symlinks,
  File "C:\...\lib\shutil.py", line 513, in _copytree
    raise Error(errors)
shutil.Error: [('...\\Source\\Infinite_Loop\\Infinite_Loop\\Infinite_Loop...', '...', "[WinError 206] The filename or extension is too long")]

Expected Behavior

shutil.copytree should detect that the Junction points to a directory that has already been visited (cycle detection) and either raise a specific RecursionError / FileExistsError or skip it.

System Details

OS: Windows 10/11
Python Version: Verified on main branch

CPython versions tested on:

CPython main branch

Operating systems tested on:

Windows

Linked PRs
  • gh-142156

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Đọc Lib/shutil.py quanh copytree và tái hiện junction cycle đã được báo cáo trên Windows bằng script trong issue. Hoàn tất nghĩa là các junction đệ quy được xử lý mà không chạm đến path-length limit, với hành vi khớp với kết quả lỗi hoặc bỏ qua đã chọn; gh-142156 đã được liên kết với issue này.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
python
Lĩnh vực
operating-systems
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
25/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.