summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorMa Lin <animalize@users.noreply.github.com>2022-03-08 09:33:56 (GMT)
committerGitHub <noreply@github.com>2022-03-08 09:33:56 (GMT)
commit36dd7396fcd26d8bf9919d536d05d7000becbe5b (patch)
treedbe015f77179a20ed0d3ddae87a5dc3d75a3deee /Lib
parent591f6754b56cb7f6c31fce8c22528bdf0a99556c (diff)
downloadcpython-36dd7396fcd26d8bf9919d536d05d7000becbe5b.zip
cpython-36dd7396fcd26d8bf9919d536d05d7000becbe5b.tar.gz
cpython-36dd7396fcd26d8bf9919d536d05d7000becbe5b.tar.bz2
bpo-44439: _ZipWriteFile.write() handle buffer protocol correctly (GH-29468)
Co-authored-by: Marco Ribeiro <marcoffee@users.noreply.github.com>
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_zipfile.py9
-rw-r--r--Lib/zipfile.py9
2 files changed, 17 insertions, 1 deletions
diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py
index de2dd33..759a4ab 100644
--- a/Lib/test/test_zipfile.py
+++ b/Lib/test/test_zipfile.py
@@ -1,3 +1,4 @@
+import array
import contextlib
import importlib.util
import io
@@ -1121,6 +1122,14 @@ class AbstractWriterTests:
self.assertRaises(ValueError, w.write, b'')
self.assertEqual(zipf.read('test'), data)
+ def test_issue44439(self):
+ q = array.array('Q', [1, 2, 3, 4, 5])
+ LENGTH = len(q) * q.itemsize
+ with zipfile.ZipFile(io.BytesIO(), 'w', self.compression) as zip:
+ with zip.open('data', 'w') as data:
+ self.assertEqual(data.write(q), LENGTH)
+ self.assertEqual(zip.getinfo('data').file_size, LENGTH)
+
class StoredWriterTests(AbstractWriterTests, unittest.TestCase):
compression = zipfile.ZIP_STORED
diff --git a/Lib/zipfile.py b/Lib/zipfile.py
index 8e9325b..41bf49a 100644
--- a/Lib/zipfile.py
+++ b/Lib/zipfile.py
@@ -1147,8 +1147,15 @@ class _ZipWriteFile(io.BufferedIOBase):
def write(self, data):
if self.closed:
raise ValueError('I/O operation on closed file.')
- nbytes = len(data)
+
+ # Accept any data that supports the buffer protocol
+ if isinstance(data, (bytes, bytearray)):
+ nbytes = len(data)
+ else:
+ data = memoryview(data)
+ nbytes = data.nbytes
self._file_size += nbytes
+
self._crc = crc32(data, self._crc)
if self._compressor:
data = self._compressor.compress(data)