### 漏洞概述 该漏洞涉及在GNU长文件名处理期间,TarInfo DIRTYTYPE的规范化问题。具体而言,当处理包含GNU长文件名的tar文件时,如果文件名以`/`结尾,其类型会被错误地转换为DIRTYTYPE,导致后续处理出现问题。 ### 影响范围 - **受影响文件**:`Lib/tarfile.py` - **受影响函数**:`_frombuf` 和 `_fromtarfile` - **影响场景**:处理包含GNU长文件名的tar文件时,特别是文件名以`/`结尾的情况。 ### 修复方案 1. **修改 `_frombuf` 函数**: - 在 `_frombuf` 函数中,增加对 `dircheck` 参数的处理,确保在 `dircheck` 为 `True` 时,文件名以`/`结尾的AREGTYPE类型会被正确转换为DIRTYTYPE。 - 在 `_frombuf` 函数中,增加对 `dircheck` 参数的处理,确保在 `dircheck` 为 `False` 时,文件名以`/`结尾的AREGTYPE类型不会被转换为DIRTYTYPE。 2. **修改 `_fromtarfile` 函数**: - 在 `_fromtarfile` 函数中,增加对 `dircheck` 参数的传递,确保在调用 `_frombuf` 时,`dircheck` 参数能够正确传递。 3. **添加测试用例**: - 在 `Lib/test/test_tarfile.py` 中,添加测试用例 `test_longname_file_not_directory`,用于验证修复后的行为是否正确。 ### POC代码 ```python def test_longname_file_not_directory(self): # Test reading a longname file and ensure it is not handled as a directory # Issue #141707 buf = io.BytesIO() with tarfile.open(mode='w', fileobj=buf, format=self.format) as tar: ti = tarfile.TarInfo() ti.type = tarfile.AREGTYPE ti.name = ('a' * 99) + '/' + ('b' * 3) tar.addfile(ti) expected = (t.name, t.type for t in tar.getmembers()) buf.seek(0) with tarfile.open(mode='r', fileobj=buf) as tar: actual = (t.name, t.type for t in tar.getmembers()) self.assertEqual(expected, actual) ``` ### 总结 该修复方案通过调整 `_frombuf` 和 `_fromtarfile` 函数中的逻辑,确保在处理GNU长文件名时,文件名以`/`结尾的AREGTYPE类型能够被正确处理,避免了错误的DIRTYTYPE转换。同时,通过添加测试用例,验证了修复的有效性。