Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit06a8c06

Browse files
[3.13]gh-133890: Handle UnicodeEncodeError in tarfile (GH-134147) (GH-134196)
UnicodeEncodeError is now handled the same way as OSError duringTarFile member extraction.(cherry picked from commit9983c7d)
1 parentea9c962 commit06a8c06

File tree

3 files changed

+49
-6
lines changed

3 files changed

+49
-6
lines changed

‎Lib/tarfile.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2376,7 +2376,7 @@ def _get_extract_tarinfo(self, member, filter_function, path):
23762376
unfiltered=tarinfo
23772377
try:
23782378
tarinfo=filter_function(tarinfo,path)
2379-
except (OSError,FilterError)ase:
2379+
except (OSError,UnicodeEncodeError,FilterError)ase:
23802380
self._handle_fatal_error(e)
23812381
exceptExtractErrorase:
23822382
self._handle_nonfatal_error(e)
@@ -2397,7 +2397,7 @@ def _extract_one(self, tarinfo, path, set_attrs, numeric_owner):
23972397
self._extract_member(tarinfo,os.path.join(path,tarinfo.name),
23982398
set_attrs=set_attrs,
23992399
numeric_owner=numeric_owner)
2400-
exceptOSErrorase:
2400+
except(OSError,UnicodeEncodeError)ase:
24012401
self._handle_fatal_error(e)
24022402
exceptExtractErrorase:
24032403
self._handle_nonfatal_error(e)

‎Lib/test/test_tarfile.py

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3457,11 +3457,12 @@ class ArchiveMaker:
34573457
with t.open() as tar:
34583458
... # `tar` is now a TarFile with 'filename' in it!
34593459
"""
3460-
def__init__(self):
3460+
def__init__(self,**kwargs):
34613461
self.bio=io.BytesIO()
3462+
self.tar_kwargs=dict(kwargs)
34623463

34633464
def__enter__(self):
3464-
self.tar_w=tarfile.TarFile(mode='w',fileobj=self.bio)
3465+
self.tar_w=tarfile.TarFile(mode='w',fileobj=self.bio,**self.tar_kwargs)
34653466
returnself
34663467

34673468
def__exit__(self,*exc):
@@ -4040,7 +4041,10 @@ def test_tar_filter(self):
40404041
# that in the test archive.)
40414042
withtarfile.TarFile.open(tarname)astar:
40424043
fortarinfointar.getmembers():
4043-
filtered=tarfile.tar_filter(tarinfo,'')
4044+
try:
4045+
filtered=tarfile.tar_filter(tarinfo,'')
4046+
exceptUnicodeEncodeError:
4047+
continue
40444048
self.assertIs(filtered.name,tarinfo.name)
40454049
self.assertIs(filtered.type,tarinfo.type)
40464050

@@ -4051,11 +4055,48 @@ def test_data_filter(self):
40514055
fortarinfointar.getmembers():
40524056
try:
40534057
filtered=tarfile.data_filter(tarinfo,'')
4054-
excepttarfile.FilterError:
4058+
except(tarfile.FilterError,UnicodeEncodeError):
40554059
continue
40564060
self.assertIs(filtered.name,tarinfo.name)
40574061
self.assertIs(filtered.type,tarinfo.type)
40584062

4063+
@unittest.skipIf(sys.platform=='win32','requires native bytes paths')
4064+
deftest_filter_unencodable(self):
4065+
# Sanity check using a valid path.
4066+
tarinfo=tarfile.TarInfo(os_helper.TESTFN)
4067+
filtered=tarfile.tar_filter(tarinfo,'')
4068+
self.assertIs(filtered.name,tarinfo.name)
4069+
filtered=tarfile.data_filter(tarinfo,'')
4070+
self.assertIs(filtered.name,tarinfo.name)
4071+
4072+
tarinfo=tarfile.TarInfo('test\x00')
4073+
self.assertRaises(ValueError,tarfile.tar_filter,tarinfo,'')
4074+
self.assertRaises(ValueError,tarfile.data_filter,tarinfo,'')
4075+
tarinfo=tarfile.TarInfo('\ud800')
4076+
self.assertRaises(UnicodeEncodeError,tarfile.tar_filter,tarinfo,'')
4077+
self.assertRaises(UnicodeEncodeError,tarfile.data_filter,tarinfo,'')
4078+
4079+
@unittest.skipIf(sys.platform=='win32','requires native bytes paths')
4080+
deftest_extract_unencodable(self):
4081+
# Create a member with name \xed\xa0\x80 which is UTF-8 encoded
4082+
# lone surrogate \ud800.
4083+
withArchiveMaker(encoding='ascii',errors='surrogateescape')asarc:
4084+
arc.add('\udced\udca0\udc80')
4085+
withos_helper.temp_cwd()astmp:
4086+
tar=arc.open(encoding='utf-8',errors='surrogatepass',
4087+
errorlevel=1)
4088+
self.assertEqual(tar.getnames(), ['\ud800'])
4089+
withself.assertRaises(UnicodeEncodeError):
4090+
tar.extractall(filter=tarfile.tar_filter)
4091+
self.assertEqual(os.listdir(), [])
4092+
4093+
tar=arc.open(encoding='utf-8',errors='surrogatepass',
4094+
errorlevel=0,debug=1)
4095+
withsupport.captured_stderr()asstderr:
4096+
tar.extractall(filter=tarfile.tar_filter)
4097+
self.assertEqual(os.listdir(), [])
4098+
self.assertIn('tarfile: UnicodeEncodeError ',stderr.getvalue())
4099+
40594100
deftest_default_filter_warns(self):
40604101
"""Ensure the default filter warns"""
40614102
withArchiveMaker()asarc:
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The:mod:`tarfile` module now handles:exc:`UnicodeEncodeError` in the same
2+
way as:exc:`OSError` when cannot extract a member.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp