Watch at Ease세상을 읽고, 일상의 답을 찾다.

기술 · 실용 가이드

zipfile.Path.is_symlink()가 항상 False인가요? 실행 버전과 저장된 유형 확인

로컬 검증 20개로 Python 3.12의 임시 구현, ZIP의 Unix 유형 표시, CRC 무결성, 표준 추출기가 실제 만드는 객체를 구분한다.

3.12 alias의 존재·파일·링크 판정과 Unix 유형 비트를 보여주는 오리지널 설명 일러스트.
오리지널 설명 일러스트: 실측3.12.14에서는 False와 저장된 링크 표시가 동시에 나타난다. Watch at Ease

CPython 3.12.14에서 Unix 심볼릭 링크로 표시한 합성 ZIP 멤버는 존재했고 zipfile.Path.is_file()도 True였지만 is_symlink()는 False였다. 저장된 모드로는 링크 표시를 확인할 수 있었다. False만으로 일반 파일만 든 아카이브라고 입증할 수 없다.

아카이브를 바꾸기 전에 실행 버전과 메타데이터 규칙을 확인한다. Linux에서 751바이트, 7개 멤버의 합성 ZIP으로 단언 검증 20개를 실행했다. CRC 통과, 추출 성공, 저장된 멤버 유형 확인은 서로 다른 질문에 대한 결과였다.

1. 메서드 존재가 아니라 구현 확인

sys.version을 출력하고 대상이 추출한 파일을 가리키는 pathlib.Path가 아닌 zipfile.Path인지 확인한다. 실제3.12.14에서 zipfile.Path.is_symlink 소스를 보면 단순히 False를 반환했다. 호출할 수 있으므로 속성 존재 확인만으로는 제한을 찾지 못한다.

Python 버전별 문서는3.13의 동작 변경을 기록하며 이전에는 무조건 False였다고 설명한다. 문서를 읽었지만3.13은 실행하지 않았다. 실제 배포 버전에서 알려진 무해한 링크 표시 표본으로 시험하고 최신 문서나 메서드 이름만으로 동작을 추정하지 않는다.

2. 명시한 메타데이터 규칙으로 각 멤버 확인

열린 아카이브의 infolist()를 순회하며 각 ZipInfo를 유지한다. filename, create_system과 info.external_attr >>16 모드를 기록한다. 이 검증의 Unix 호스트 규칙에서는 create_system==3을 먼저 요구한 뒤 stat.S_ISLNK, stat.S_ISREG, stat.S_ISDIR로 해석한다. 이는 저장된 유형 비트이지 현재 파일 시스템 검사가 아니다.

PKWARE는 외부 속성 의미가 호스트 시스템에 따라 다르다고 정의한다. 제한된 분류기는 비Unix 호스트와 식별할 유형이 없는 모드를 unknown으로 둔다. unknown은 일반 파일이나 문제없음이 아니다. 다른 생성기와 호스트 규칙은 별도 검증해야 하며 억지로 부정 판정하지 않는다.

3. 이름과 대상 텍스트, 유형 비트를 분리

표본의 alias와 dangling은 모두 링크로 표시돼 있었다. dangling 대상이 없어도 저장된 유형은 같았다. 읽으면 저장된 target.txt와 absent.txt 텍스트가 반환됐다. ordinary.link라는 일반 멤버는 명시적 Unix 유형 비트에 따라 일반 파일이었다. 확장자는 링크 유형의 증거가 아니다.

folder/는 디렉터리 형태 이름과 디렉터리 모드를 모두 가졌다. ZipInfo.is_dir는 이름 끝 슬래시를 사용하며 모든 Unix 유형 비트를 검사하는 것과 다르다. 권한만 있는 멤버는 식별 가능한 유형이 없어 unknown이었다. 권한 비트만으로 일반 파일이라고 판단하지 않았다.

4. 추출 결과를 별도로 측정

testzip()은 전체 표본에 None을 반환했고 멤버는 해당 CRC·헤더 검사를 통과했다. 링크 메타데이터는 그대로였다. 무결성 검사만으로 심볼릭 링크 여부나 다른 추출기가 복원할 객체를 알 수 없다.

표준 ZipFile.extract로 무해한 alias만 새 임시 디렉터리에 추출했다. 이번3.12.14/Linux 실행에서는 운영체제 심볼릭 링크가 아닌 target.txt 텍스트가 든 일반 파일이 만들어졌다. 외부 추출기는 실행하지 않았다. 다른 프로그램으로 일반화하거나 원하는 참·거짓을 얻으려고 메타데이터를 고치지 않는다.

5. 실제 전달 목적에 맞는 완료 기준

20개 검증은 메서드 존재, exists/is_file/is_symlink,7개 멤버 유형,끊긴 대상과 확장자 대조, unknown, CRC 통과,저장 텍스트,없는 멤버,추출 결과의 유형과 정확한 내용을 확인했다. 보고서에는 실행 버전,판정 함수 소스,스크립트·아카이브 해시를 남겼다.

자신의 흐름에서도 원본 아카이브와 작은 알려진 표본을 보존한다. 멤버 목록을 대조하고 규칙이 실제 지원하는 관례만 분류하며 unknown은 방침에 따라 조사하거나 거부한다. 이어서 사용할 추출기가 만든 객체 유형과 내용을 확인한다. 이는 멤버 유형 진단이며 신뢰할 수 없는 아카이브의 완전한 추출 검증기나 교차 플랫폼 호환 보장이 아니다.

멤버7개의 유형, unknown, CRC와 추출 결과를 구분하는 오리지널 설명 일러스트.
오리지널 설명 일러스트: 유형·무결성·추출은 별도 결과이며 unknown은 일반 파일을 뜻하지 않는다. Watch at Ease