Skip to content

zlib: decode concatenated zstd frames#64748

Open
lazerg wants to merge 1 commit into
nodejs:mainfrom
lazerg:fix/issue-64741-zstd-concatenated-frames
Open

zlib: decode concatenated zstd frames#64748
lazerg wants to merge 1 commit into
nodejs:mainfrom
lazerg:fix/issue-64741-zstd-concatenated-frames

Conversation

@lazerg

@lazerg lazerg commented Jul 26, 2026

Copy link
Copy Markdown

When a single write held several concatenated zstd frames, decompression stopped after the first one and dropped the rest. The zstd format allows concatenated frames, and both zstdcat and gunzip decode them, so a stream should too.

ZstdDecompressContext::DoThreadPoolWork ran a single decode call per invocation. Once the first frame finished with input left over and output space still free, the processing loop read that as the end of the stream. It now keeps decoding across frame boundaries, the same way the gunzip path walks concatenated members. The existing rejectGarbageAfterEnd option is passed through to the zstd context, so trailing frames are still rejected when it is set.

Fixes: #64741

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. zlib Issues and PRs related to the zlib subsystem. labels Jul 26, 2026
ZstdDecompressContext::DoThreadPoolWork decoded a single frame per call,
so a stream that received several concatenated frames in one write kept
only the first frame and dropped the rest. Other codecs that support
concatenation, such as gunzip, already loop over the remaining input.

Keep decoding while a frame ends with input still pending and output
space available, and thread rejectGarbageAfterEnd through to the zstd
context so trailing frames are still rejected when that option is set.

Signed-off-by: Lazizbek Ergashev <lazerg2@gmail.com>
@lazerg
lazerg force-pushed the fix/issue-64741-zstd-concatenated-frames branch from f179d4f to f8088e7 Compare July 26, 2026 02:02
@codecov

codecov Bot commented Jul 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.47619% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.12%. Comparing base (2c4ea73) to head (f8088e7).
⚠️ Report is 7 commits behind head on main.

Files with missing lines Patch % Lines
src/node_zlib.cc 90.00% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #64748      +/-   ##
==========================================
- Coverage   90.15%   90.12%   -0.03%     
==========================================
  Files         743      743              
  Lines      242413   242427      +14     
  Branches    45657    45657              
==========================================
- Hits       218537   218484      -53     
- Misses      15362    15440      +78     
+ Partials     8514     8503      -11     
Files with missing lines Coverage Δ
lib/zlib.js 98.07% <100.00%> (+<0.01%) ⬆️
src/node_zlib.cc 79.04% <90.00%> (+0.20%) ⬆️

... and 35 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. zlib Issues and PRs related to the zlib subsystem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

zstd decoding complete frame in read stream halts stream

2 participants