Skip to content

Commit a4650dc

Browse files
committed
[GR-75555] Preserve zlib copy input progress
1 parent 9abdaf9 commit a4650dc

2 files changed

Lines changed: 17 additions & 5 deletions

File tree

graalpython/com.oracle.graal.python.test/src/tests/test_zlib.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,16 @@ def test_zlib_decompress_copy_preserves_eof_after_max_length():
347347
assert not copied.eof
348348

349349

350+
def test_zlib_decompress_copy_preserves_consumed_input_without_output():
351+
compressed = zlib.compress(HAMLET_SCENE)
352+
decompressor = zlib.decompressobj()
353+
first = decompressor.decompress(compressed[:32])
354+
assert first == b""
355+
356+
copied = decompressor.copy()
357+
assert copied.decompress(compressed[32:]) + copied.flush() == HAMLET_SCENE
358+
359+
350360
def test_GR65704():
351361
contents = b"The quick brown fox jumped over the lazy dog"
352362
wbits = 27

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/JavaDecompress.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -313,15 +313,16 @@ private boolean setInflaterInput(byte[] data, int length, Node node) {
313313
return true;
314314
}
315315

316-
private static boolean needsReplay(DecompressStream stream, long bytesWritten, boolean finishInflater) {
317-
return stream.inflater.getBytesWritten() < bytesWritten || (finishInflater && !stream.inflater.finished());
316+
private static boolean needsReplay(DecompressStream stream, long bytesRead, long bytesWritten, boolean finishInflater) {
317+
return stream.inflater.getBytesRead() < bytesRead || stream.inflater.getBytesWritten() < bytesWritten ||
318+
(finishInflater && !stream.inflater.finished());
318319
}
319320

320-
private static void replayInflaterInput(JavaDecompress obj, long bytesWritten, boolean finishInflater, boolean isRAW)
321+
private static void replayInflaterInput(JavaDecompress obj, long bytesRead, long bytesWritten, boolean finishInflater, boolean isRAW)
321322
throws DataFormatException {
322323
byte[] result = new byte[ZLibModuleBuiltins.DEF_BUF_SIZE];
323324
boolean zdictIsSet = isRAW;
324-
while (needsReplay(obj.stream, bytesWritten, finishInflater) && !obj.stream.inflater.finished()) {
325+
while (needsReplay(obj.stream, bytesRead, bytesWritten, finishInflater) && !obj.stream.inflater.finished()) {
325326
long remainingBytes = bytesWritten - obj.stream.inflater.getBytesWritten();
326327
int len = remainingBytes > 0 ? (int) Math.min(result.length, remainingBytes) : result.length;
327328
int n = obj.stream.inflater.inflate(result, 0, len);
@@ -350,7 +351,8 @@ protected JavaDecompress copy(Node node) {
350351
if (!obj.setInflaterInput(inputData, inputLen, node)) {
351352
return obj;
352353
}
353-
replayInflaterInput(obj, stream.inflater.getBytesWritten(), stream.inflater.finished(), isRAW);
354+
replayInflaterInput(obj, stream.inflater.getBytesRead(), stream.inflater.getBytesWritten(), stream.inflater.finished(),
355+
isRAW);
354356
if (stream.gzip && stream.inflater.finished() && obj.stream.inflater.finished()) {
355357
int remaining = obj.stream.inflater.getRemaining();
356358
int remainingOffset = obj.stream.inputOffset + (inputLen - obj.stream.inputOffset - remaining);

0 commit comments

Comments
 (0)