Skip to content

Return per-call read/write counts from zlib execute - #1422

Open
robknopf wants to merge 1 commit into
HaxeFoundation:masterfrom
robknopf:fix-zlib-per-call-counts
Open

robknopf wants to merge 1 commit into
HaxeFoundation:masterfrom
robknopf:fix-zlib-per-call-counts

Conversation

@robknopf

Copy link
Copy Markdown

Since the typed zip rewrite (#1277), ZLibCompress::execute and ZLibUncompress::execute return z_stream::total_in / total_out. Those totals accumulate across calls, but haxe.zip.Compress.execute / Uncompress.execute callers, including Uncompress.run, treat read / write as the progress of the current call.

As a result, haxe.zip.Uncompress.run(bytes) throws OutsideBounds once the decompressed output exceeds its 64K buffer. On the second iteration write reports the running total, so addBytes(tmp, 0, r.write) reads past tmp. Chunked execute loops also re-read input, because pos += r.read advances by the total.

Reproduction

final bytes = haxe.io.Bytes.alloc(300000);
for (i in 0...bytes.length) bytes.set(i, (i * 7 + (i >> 9)) & 0xff);
haxe.zip.Uncompress.run(haxe.zip.Compress.run(bytes, 9)); // Error : OutsideBounds

This works on haxelib hxcpp 4.3.2 and fails on releases from v4.3.106 onward. Single-call use (output under 64K) is unaffected, which is why the existing testCompress passes.

Change

execute now returns the per-call counts, src.length - avail_in and dst.length - avail_out, in both files. I also added testCompressMultipleBuffers to test/std, which round-trips 300 KB through Uncompress.run and through a chunked execute loop with a 4K output buffer.

Testing

On Linux x86_64 (GCC 13.3, Haxe 4.3.7), I ran the same assertions as a standalone program: Uncompress.run over 64K, chunked decode, chunked compress into 512-byte buffers, and a 1 MiB real-world asset. Before the change they fail with OutsideBounds; after it they pass. I couldn't run the full test/std suite locally because it doesn't compile against utest 1.13.2 (Assert.exception at Test.hx:452, unrelated to this change).

The typed zip rewrite (0b59d98) returned z_stream total_in/total_out,
which accumulate across calls, but haxe.zip Compress/Uncompress.execute
callers treat read/write as this call's progress. Uncompress.run threw
OutsideBounds once output exceeded its 64K buffer, and chunked callers
re-read input.

Add a multi-buffer round-trip test that exceeds the default buffer.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant