@@ -4451,9 +4451,15 @@ def test_sneaky_hardlink_fallback(self):
44514451 for filter in 'tar' , 'fully_trusted' :
44524452 with self .subTest (filter ), self .check_context (arc .open (), filter ):
44534453 if not os_helper .can_symlink ():
4454- self .expect_file ("a/t/dummy" )
4455- self .expect_file ("b/" )
4456- self .expect_file ("c/" )
4454+ if filter == 'tar' :
4455+ self .expect_exception (
4456+ tarfile .LinkFallbackError ,
4457+ "link 'boom' would be extracted as a copy of "
4458+ + "'c/escape', which was rejected" )
4459+ else :
4460+ self .expect_file ("a/t/dummy" )
4461+ self .expect_file ("b/" )
4462+ self .expect_file ("c/" )
44574463 else :
44584464 self .expect_file ("a/t/dummy" )
44594465 self .expect_file ("b/" )
@@ -4632,6 +4638,25 @@ def testing_filter(member, path):
46324638 if os_helper .can_chmod ():
46334639 self .assertFalse (path .stat ().st_mode & stat .S_IWUSR )
46344640
4641+ @symlink_test
4642+ def test_extract_filters_target_none (self ):
4643+ # Test that when extract() falls back to extracting (rather than
4644+ # linking) a hardlink target, the member is skipped if the filter
4645+ # returns None.
4646+ with ArchiveMaker () as arc :
4647+ arc .add ('a/b/s' , symlink_to = '../escape' )
4648+ arc .add ('q' , hardlink_to = 'a/b/s' )
4649+ def filter_unsafe_members (member , path ):
4650+ try :
4651+ return tarfile .data_filter (member , path )
4652+ except tarfile .FilterError as error :
4653+ return None
4654+ with self .check_context (arc .open (), filter_unsafe_members ):
4655+ if os_helper .can_symlink ():
4656+ self .expect_file ('a/b/s' , symlink_to = '../escape' )
4657+ else :
4658+ self .expect_file ('a/b/' ) # symlink is not extracted
4659+
46354660 def test_link_fallback_normalizes (self ):
46364661 # Make sure hardlink fallbacks work for non-normalized paths for all
46374662 # filters
0 commit comments