diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py index 3064346bc..6499ed7ab 100644 --- a/Lib/test/test_zlib.py +++ b/Lib/test/test_zlib.py @@ -187,8 +187,6 @@ class CompressTestCase(BaseCompressTestCase, unittest.TestCase): for ob in x, bytearray(x): self.assertEqual(zlib.decompress(ob), data) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_incomplete_stream(self): # A useful error message is given x = zlib.compress(HAMLET_SCENE) @@ -482,7 +480,6 @@ class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase): "mode=%i, level=%i") % (sync, level)) del obj - @unittest.skip("TODO: RUSTPYTHON, panics") @unittest.skipUnless(hasattr(zlib, 'Z_SYNC_FLUSH'), 'requires zlib.Z_SYNC_FLUSH') def test_odd_flush(self): @@ -746,7 +743,6 @@ class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase): # Memory use of the following functions takes into account overallocation - @unittest.skip("TODO: RUSTPYTHON, thread 'main' panicked at 'range start index 27394048 out of range for slice of length 10485760'") @bigmemtest(size=_1G + 1024 * 1024, memuse=3) def test_big_compress_buffer(self, size): c = zlib.compressobj(1) diff --git a/vm/src/stdlib/zlib.rs b/vm/src/stdlib/zlib.rs index ffa1b9a63..fd3637538 100644 --- a/vm/src/stdlib/zlib.rs +++ b/vm/src/stdlib/zlib.rs @@ -246,7 +246,10 @@ mod decl { if stream_end { Ok(buf) } else { - Err(new_zlib_error("incomplete or truncated stream", vm)) + Err(new_zlib_error( + "Error -5 while decompressing data: incomplete or truncated stream", + vm, + )) } }) }) @@ -477,34 +480,31 @@ mod decl { const CHUNKSIZE: usize = u32::MAX as usize; impl CompressInner { - fn save_unconsumed_input(&mut self, data: &[u8], orig_in: u64) { - let leftover = &data[(self.compress.total_in() - orig_in) as usize..]; - self.unconsumed.extend_from_slice(leftover); - } - fn compress(&mut self, data: &[u8], vm: &VirtualMachine) -> PyResult> { - let orig_in = self.compress.total_in(); + let orig_in = self.compress.total_in() as usize; + let mut cur_in = 0; let unconsumed = std::mem::take(&mut self.unconsumed); let mut buf = Vec::new(); 'outer: for chunk in unconsumed.chunks(CHUNKSIZE).chain(data.chunks(CHUNKSIZE)) { - loop { + while cur_in < chunk.len() { buf.reserve(DEF_BUF_SIZE); let status = self .compress - .compress_vec(chunk, &mut buf, FlushCompress::None) + .compress_vec(&chunk[cur_in..], &mut buf, FlushCompress::None) .map_err(|_| { - self.save_unconsumed_input(data, orig_in); + self.unconsumed.extend_from_slice(&data[cur_in..]); new_zlib_error("error while compressing", vm) })?; + cur_in = (self.compress.total_in() as usize) - orig_in; match status { - _ if buf.len() == buf.capacity() => continue, + Status::Ok => continue, Status::StreamEnd => break 'outer, _ => break, } } } - self.save_unconsumed_input(data, orig_in); + self.unconsumed.extend_from_slice(&data[cur_in..]); buf.shrink_to_fit(); Ok(buf)