diff options
author | R. David Murray <rdmurray@bitdance.com> | 2010-12-21 21:53:37 (GMT) |
---|---|---|
committer | R. David Murray <rdmurray@bitdance.com> | 2010-12-21 21:53:37 (GMT) |
commit | 8d855d83046dd8a55cd216e642470191e6eab55f (patch) | |
tree | 994b94cdb6b1bfda618c4754792ea0696da0fdbf /Lib | |
parent | 7f8f41808b82b5e4812bc2e2d484a6fc8f02295c (diff) | |
download | cpython-8d855d83046dd8a55cd216e642470191e6eab55f.zip cpython-8d855d83046dd8a55cd216e642470191e6eab55f.tar.gz cpython-8d855d83046dd8a55cd216e642470191e6eab55f.tar.bz2 |
#4871: check that zipfile password is bytes, and give useful error message.
Previously passing a string in as the password would fail either with
an assertion error or a TypeError with a confusing error message.
Note that a string can't be accepted since zipfile has no way to
guess what encoding should be used to turn it into bytes.
Patch by Victor Stinner.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/test/test_zipfile.py | 6 | ||||
-rw-r--r-- | Lib/zipfile.py | 14 |
2 files changed, 16 insertions, 4 deletions
diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index a0367e1..d90e771 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -1089,6 +1089,12 @@ class DecryptionTests(unittest.TestCase): self.zip2.setpassword(b"12345") self.assertEqual(self.zip2.read("zero"), self.plain2) + def test_unicode_password(self): + self.assertRaises(TypeError, self.zip.setpassword, "unicode") + self.assertRaises(TypeError, self.zip.read, "test.txt", "python") + self.assertRaises(TypeError, self.zip.open, "test.txt", pwd="python") + self.assertRaises(TypeError, self.zip.extract, "test.txt", pwd="python") + class TestsWithRandomBinaryFiles(unittest.TestCase): def setUp(self): diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 35bba73..197f0bc 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -877,8 +877,12 @@ class ZipFile: def setpassword(self, pwd): """Set default password for encrypted files.""" - assert isinstance(pwd, bytes) - self.pwd = pwd + if pwd and not isinstance(pwd, bytes): + raise TypeError("pwd: expected bytes, got %s" % type(pwd)) + if pwd: + self.pwd = pwd + else: + self.pwd = None def read(self, name, pwd=None): """Return file bytes (as a string) for name.""" @@ -889,6 +893,8 @@ class ZipFile: """Return file-like object for 'name'.""" if mode not in ("r", "U", "rU"): raise RuntimeError('open() requires mode "r", "U", or "rU"') + if pwd and not isinstance(pwd, bytes): + raise TypeError("pwd: expected bytes, got %s" % type(pwd)) if not self.fp: raise RuntimeError( "Attempt to read ZIP archive that was already closed") @@ -949,8 +955,8 @@ class ZipFile: # completely random, while the 12th contains the MSB of the CRC, # or the MSB of the file time depending on the header type # and is used to check the correctness of the password. - bytes = zef_file.read(12) - h = list(map(zd, bytes[0:12])) + header = zef_file.read(12) + h = list(map(zd, header[0:12])) if zinfo.flag_bits & 0x8: # compare against the file type from extended local headers check_byte = (zinfo._raw_time >> 8) & 0xff |