@@ -538,8 +538,15 @@ def check_file(self, filename, content):
538538 with open (filename , 'rb' ) as f :
539539 self .assertEqual (f .read (), content )
540540
541- def test_extract_hackers_arcnames (self ):
542- hacknames = [
541+ def test_sanitize_windows_name (self ):
542+ san = zipfile .ZipFile ._sanitize_windows_name
543+ # Passing pathsep in allows this test to work regardless of platform.
544+ self .assertEqual (san (r',,?,C:,foo,bar/z' , ',' ), r'_,C_,foo,bar/z' )
545+ self .assertEqual (san (r'a\b,c<d>e|f"g?h*i' , ',' ), r'a\b,c_d_e_f_g_h_i' )
546+ self .assertEqual (san ('../../foo../../ba..r' , '/' ), r'foo/ba..r' )
547+
548+ def test_extract_hackers_arcnames_common_cases (self ):
549+ common_hacknames = [
543550 ('../foo/bar' , 'foo/bar' ),
544551 ('foo/../bar' , 'foo/bar' ),
545552 ('foo/../../bar' , 'foo/bar' ),
@@ -549,8 +556,12 @@ def test_extract_hackers_arcnames(self):
549556 ('/foo/../bar' , 'foo/bar' ),
550557 ('/foo/../../bar' , 'foo/bar' ),
551558 ]
552- if os .path .sep == '\\ ' : # Windows.
553- hacknames .extend ([
559+ self ._test_extract_hackers_arcnames (common_hacknames )
560+
561+ @unittest .skipIf (os .path .sep != '\\ ' , 'Requires \\ as path separator.' )
562+ def test_extract_hackers_arcnames_windows_only (self ):
563+ """Test combination of path fixing and windows name sanitization."""
564+ windows_hacknames = [
554565 (r'..\foo\bar' , 'foo/bar' ),
555566 (r'..\/foo\/bar' , 'foo/bar' ),
556567 (r'foo/\..\/bar' , 'foo/bar' ),
@@ -570,14 +581,19 @@ def test_extract_hackers_arcnames(self):
570581 (r'C:/../C:/foo/bar' , 'C_/foo/bar' ),
571582 (r'a:b\c<d>e|f"g?h*i' , 'b/c_d_e_f_g_h_i' ),
572583 ('../../foo../../ba..r' , 'foo/ba..r' ),
573- ])
574- else : # Unix
575- hacknames .extend ([
576- ('//foo/bar' , 'foo/bar' ),
577- ('../../foo../../ba..r' , 'foo../ba..r' ),
578- (r'foo/..\bar' , r'foo/..\bar' ),
579- ])
584+ ]
585+ self ._test_extract_hackers_arcnames (windows_hacknames )
586+
587+ @unittest .skipIf (os .path .sep != '/' , r'Requires / as path separator.' )
588+ def test_extract_hackers_arcnames_posix_only (self ):
589+ posix_hacknames = [
590+ ('//foo/bar' , 'foo/bar' ),
591+ ('../../foo../../ba..r' , 'foo../ba..r' ),
592+ (r'foo/..\bar' , r'foo/..\bar' ),
593+ ]
594+ self ._test_extract_hackers_arcnames (posix_hacknames )
580595
596+ def _test_extract_hackers_arcnames (self , hacknames ):
581597 for arcname , fixedname in hacknames :
582598 content = b'foobar' + arcname .encode ()
583599 with zipfile .ZipFile (TESTFN2 , 'w' , zipfile .ZIP_STORED ) as zipfp :
@@ -594,7 +610,8 @@ def test_extract_hackers_arcnames(self):
594610 with zipfile .ZipFile (TESTFN2 , 'r' ) as zipfp :
595611 writtenfile = zipfp .extract (arcname , targetpath )
596612 self .assertEqual (writtenfile , correctfile ,
597- msg = "extract %r" % arcname )
613+ msg = 'extract %r: %r != %r' %
614+ (arcname , writtenfile , correctfile ))
598615 self .check_file (correctfile , content )
599616 shutil .rmtree ('target' )
600617
0 commit comments