Skip to content

Commit 36dd739

Browse files
Ma Linmarcoffee
Ma Lin
andauthored
bpo-44439: _ZipWriteFile.write() handle buffer protocol correctly (GH-29468)
Co-authored-by: Marco Ribeiro <marcoffee@users.noreply.github.com>
1 parent 591f675 commit 36dd739

File tree

3 files changed

+19
-1
lines changed

3 files changed

+19
-1
lines changed

Lib/test/test_zipfile.py

+9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import array
12
import contextlib
23
import importlib.util
34
import io
@@ -1121,6 +1122,14 @@ def test_write_after_close(self):
11211122
self.assertRaises(ValueError, w.write, b'')
11221123
self.assertEqual(zipf.read('test'), data)
11231124

1125+
def test_issue44439(self):
1126+
q = array.array('Q', [1, 2, 3, 4, 5])
1127+
LENGTH = len(q) * q.itemsize
1128+
with zipfile.ZipFile(io.BytesIO(), 'w', self.compression) as zip:
1129+
with zip.open('data', 'w') as data:
1130+
self.assertEqual(data.write(q), LENGTH)
1131+
self.assertEqual(zip.getinfo('data').file_size, LENGTH)
1132+
11241133
class StoredWriterTests(AbstractWriterTests, unittest.TestCase):
11251134
compression = zipfile.ZIP_STORED
11261135

Lib/zipfile.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -1147,8 +1147,15 @@ def writable(self):
11471147
def write(self, data):
11481148
if self.closed:
11491149
raise ValueError('I/O operation on closed file.')
1150-
nbytes = len(data)
1150+
1151+
# Accept any data that supports the buffer protocol
1152+
if isinstance(data, (bytes, bytearray)):
1153+
nbytes = len(data)
1154+
else:
1155+
data = memoryview(data)
1156+
nbytes = data.nbytes
11511157
self._file_size += nbytes
1158+
11521159
self._crc = crc32(data, self._crc)
11531160
if self._compressor:
11541161
data = self._compressor.compress(data)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix ``.write()`` method of a member file in ``ZipFile``, when the input data is
2+
an object that supports the buffer protocol, the file length may be wrong.

0 commit comments

Comments
 (0)