@@ -1610,6 +1610,114 @@ def test_open_conflicting_handles(self):
1610
1610
self .assertEqual (zipf .read ('baz' ), msg3 )
1611
1611
self .assertEqual (zipf .namelist (), ['foo' , 'bar' , 'baz' ])
1612
1612
1613
+ def test_seek_tell (self ):
1614
+ # Test seek functionality
1615
+ txt = b"Where's Bruce?"
1616
+ bloc = txt .find (b"Bruce" )
1617
+ # Check seek on a file
1618
+ with zipfile .ZipFile (TESTFN , "w" ) as zipf :
1619
+ zipf .writestr ("foo.txt" , txt )
1620
+ with zipfile .ZipFile (TESTFN , "r" ) as zipf :
1621
+ with zipf .open ("foo.txt" , "r" ) as fp :
1622
+ fp .seek (bloc , os .SEEK_SET )
1623
+ self .assertEqual (fp .tell (), bloc )
1624
+ fp .seek (- bloc , os .SEEK_CUR )
1625
+ self .assertEqual (fp .tell (), 0 )
1626
+ fp .seek (bloc , os .SEEK_CUR )
1627
+ self .assertEqual (fp .tell (), bloc )
1628
+ self .assertEqual (fp .read (5 ), txt [bloc :bloc + 5 ])
1629
+ fp .seek (0 , os .SEEK_END )
1630
+ self .assertEqual (fp .tell (), len (txt ))
1631
+ fp .seek (0 , os .SEEK_SET )
1632
+ self .assertEqual (fp .tell (), 0 )
1633
+ # Check seek on memory file
1634
+ data = io .BytesIO ()
1635
+ with zipfile .ZipFile (data , mode = "w" ) as zipf :
1636
+ zipf .writestr ("foo.txt" , txt )
1637
+ with zipfile .ZipFile (data , mode = "r" ) as zipf :
1638
+ with zipf .open ("foo.txt" , "r" ) as fp :
1639
+ fp .seek (bloc , os .SEEK_SET )
1640
+ self .assertEqual (fp .tell (), bloc )
1641
+ fp .seek (- bloc , os .SEEK_CUR )
1642
+ self .assertEqual (fp .tell (), 0 )
1643
+ fp .seek (bloc , os .SEEK_CUR )
1644
+ self .assertEqual (fp .tell (), bloc )
1645
+ self .assertEqual (fp .read (5 ), txt [bloc :bloc + 5 ])
1646
+ fp .seek (0 , os .SEEK_END )
1647
+ self .assertEqual (fp .tell (), len (txt ))
1648
+ fp .seek (0 , os .SEEK_SET )
1649
+ self .assertEqual (fp .tell (), 0 )
1650
+
1651
+ @requires_bz2
1652
+ def test_decompress_without_3rd_party_library (self ):
1653
+ data = b'PK\x05 \x06 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 '
1654
+ zip_file = io .BytesIO (data )
1655
+ with zipfile .ZipFile (zip_file , 'w' , compression = zipfile .ZIP_BZIP2 ) as zf :
1656
+ zf .writestr ('a.txt' , b'a' )
1657
+ with mock .patch ('zipfile.bz2' , None ):
1658
+ with zipfile .ZipFile (zip_file ) as zf :
1659
+ self .assertRaises (RuntimeError , zf .extract , 'a.txt' )
1660
+
1661
+ @requires_zlib
1662
+ def test_full_overlap (self ):
1663
+ data = (
1664
+ b'PK\x03 \x04 \x14 \x00 \x00 \x00 \x08 \x00 \xa0 lH\x05 \xe2 \x1e '
1665
+ b'8\xbb \x10 \x00 \x00 \x00 \t \x04 \x00 \x00 \x01 \x00 \x00 \x00 a\xed '
1666
+ b'\xc0 \x81 \x08 \x00 \x00 \x00 \xc0 0\xd6 \xfb K\\ d\x0b `P'
1667
+ b'K\x01 \x02 \x14 \x00 \x14 \x00 \x00 \x00 \x08 \x00 \xa0 lH\x05 \xe2 '
1668
+ b'\x1e 8\xbb \x10 \x00 \x00 \x00 \t \x04 \x00 \x00 \x01 \x00 \x00 \x00 \x00 '
1669
+ b'\x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 aPK'
1670
+ b'\x01 \x02 \x14 \x00 \x14 \x00 \x00 \x00 \x08 \x00 \xa0 lH\x05 \xe2 \x1e '
1671
+ b'8\xbb \x10 \x00 \x00 \x00 \t \x04 \x00 \x00 \x01 \x00 \x00 \x00 \x00 \x00 '
1672
+ b'\x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 bPK\x05 '
1673
+ b'\x06 \x00 \x00 \x00 \x00 \x02 \x00 \x02 \x00 ^\x00 \x00 \x00 /\x00 \x00 '
1674
+ b'\x00 \x00 \x00 '
1675
+ )
1676
+ with zipfile .ZipFile (io .BytesIO (data ), 'r' ) as zipf :
1677
+ self .assertEqual (zipf .namelist (), ['a' , 'b' ])
1678
+ zi = zipf .getinfo ('a' )
1679
+ self .assertEqual (zi .header_offset , 0 )
1680
+ self .assertEqual (zi .compress_size , 16 )
1681
+ self .assertEqual (zi .file_size , 1033 )
1682
+ zi = zipf .getinfo ('b' )
1683
+ self .assertEqual (zi .header_offset , 0 )
1684
+ self .assertEqual (zi .compress_size , 16 )
1685
+ self .assertEqual (zi .file_size , 1033 )
1686
+ self .assertEqual (len (zipf .read ('a' )), 1033 )
1687
+ with self .assertRaisesRegex (zipfile .BadZipFile , 'File name.*differ' ):
1688
+ zipf .read ('b' )
1689
+
1690
+ @requires_zlib
1691
+ def test_quoted_overlap (self ):
1692
+ data = (
1693
+ b'PK\x03 \x04 \x14 \x00 \x00 \x00 \x08 \x00 \xa0 lH\x05 Y\xfc '
1694
+ b'8\x04 4\x00 \x00 \x00 (\x04 \x00 \x00 \x01 \x00 \x00 \x00 a\x00 '
1695
+ b'\x1f \x00 \xe0 \xff PK\x03 \x04 \x14 \x00 \x00 \x00 \x08 \x00 \xa0 l'
1696
+ b'H\x05 \xe2 \x1e 8\xbb \x10 \x00 \x00 \x00 \t \x04 \x00 \x00 \x01 \x00 '
1697
+ b'\x00 \x00 b\xed \xc0 \x81 \x08 \x00 \x00 \x00 \xc0 0\xd6 \xfb K\\ '
1698
+ b'd\x0b `PK\x01 \x02 \x14 \x00 \x14 \x00 \x00 \x00 \x08 \x00 \xa0 '
1699
+ b'lH\x05 Y\xfc 8\x04 4\x00 \x00 \x00 (\x04 \x00 \x00 \x01 '
1700
+ b'\x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 '
1701
+ b'\x00 aPK\x01 \x02 \x14 \x00 \x14 \x00 \x00 \x00 \x08 \x00 \xa0 l'
1702
+ b'H\x05 \xe2 \x1e 8\xbb \x10 \x00 \x00 \x00 \t \x04 \x00 \x00 \x01 \x00 '
1703
+ b'\x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 $\x00 \x00 \x00 '
1704
+ b'bPK\x05 \x06 \x00 \x00 \x00 \x00 \x02 \x00 \x02 \x00 ^\x00 \x00 '
1705
+ b'\x00 S\x00 \x00 \x00 \x00 \x00 '
1706
+ )
1707
+ with zipfile .ZipFile (io .BytesIO (data ), 'r' ) as zipf :
1708
+ self .assertEqual (zipf .namelist (), ['a' , 'b' ])
1709
+ zi = zipf .getinfo ('a' )
1710
+ self .assertEqual (zi .header_offset , 0 )
1711
+ self .assertEqual (zi .compress_size , 52 )
1712
+ self .assertEqual (zi .file_size , 1064 )
1713
+ zi = zipf .getinfo ('b' )
1714
+ self .assertEqual (zi .header_offset , 36 )
1715
+ self .assertEqual (zi .compress_size , 16 )
1716
+ self .assertEqual (zi .file_size , 1033 )
1717
+ with self .assertRaisesRegex (zipfile .BadZipFile , 'Overlapped entries' ):
1718
+ zipf .read ('a' )
1719
+ self .assertEqual (len (zipf .read ('b' )), 1033 )
1720
+
1613
1721
def tearDown (self ):
1614
1722
unlink (TESTFN )
1615
1723
unlink (TESTFN2 )
0 commit comments