Skip to content

Fix #2081: Apply zstd compression level reliably across the documente…#2113

Merged
seladb merged 4 commits into
seladb:devfrom
MerinoSheep:fix/issue-2081-zstd-compression-level
Apr 30, 2026
Merged

Fix #2081: Apply zstd compression level reliably across the documente…#2113
seladb merged 4 commits into
seladb:devfrom
MerinoSheep:fix/issue-2081-zstd-compression-level

Conversation

@MerinoSheep
Copy link
Copy Markdown
Contributor

@MerinoSheep MerinoSheep commented Apr 25, 2026

Description

Fixes #2081.

The zstd compression level passed to PcapNgFileWriterDevice was not being
applied as documented. Two related defects in light_zstd_compression.c:

Root Cause

  1. ZSTD_CCtx_setParameter was wrapped in assert(), so the call (along
    with its side effect of actually setting the level) is stripped under
    NDEBUG. In Release builds the requested level was never set; zstd fell
    back to its default (3).
  2. The 0–10 input range documented for PcapNgFileWriterDevice was scaled
    into the context (* 2) but the original unscaled value was the one
    passed to zstd, and the scaling did not span zstd's 1–22 range.

Proposed Fix

  • Extract ZSTD_CCtx_setParameter into a named local so its side effect
    survives NDEBUG, and check the return value separately.
  • Map input 1..10 → zstd 3..21, preserve 0 as the documented
    "default compression" sentinel, and pass the same scaled value to zstd
    that is stored on the context.

Test

Adds TestPcapNgZstdCompressionLevels: writes the same input pcapng at
levels 1 and 10 and asserts the level-10 file is strictly smaller. With
either bug present the two files are the same size and the assertion
fires.

@MerinoSheep MerinoSheep requested a review from seladb as a code owner April 25, 2026 07:36
Copy link
Copy Markdown
Collaborator

@Dimi1010 Dimi1010 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The added unit test seems to fail?

Comment thread Tests/Pcap++Test/Tests/FileTests.cpp
@MerinoSheep MerinoSheep force-pushed the fix/issue-2081-zstd-compression-level branch 3 times, most recently from 309afec to 2b806ee Compare April 26, 2026 03:31
@MerinoSheep
Copy link
Copy Markdown
Contributor Author

I made some tweak to the test and forgot to run it again ill fix it up.

Comment thread Tests/Pcap++Test/Tests/FileTests.cpp Outdated
Comment on lines +1324 to +1325
int sizes[3] = { 0, 0, 0 };
const int levels[3] = { 1, 5, 10 };
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we can use std::array here

Comment on lines +1344 to +1345
PTF_ASSERT_GREATER_THAN(sizes[0], sizes[1]);
PTF_ASSERT_GREATER_THAN(sizes[1], sizes[2]);
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI is failing for almost all platforms, maybe this is not always true? 🤔
I asked Claude and it suggests checking the window size from the header. Compression levels 1, 5, and 10 should result with different windows sizes

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a look at .github/workflows/build_and_test.yml and it seems the only one that passes is the ubuntu container that has zstd configured on. From what I've seen if zstd is not available at run time the writer silently writes uncompressed files with the zstd extension.

Copy link
Copy Markdown
Collaborator

@Dimi1010 Dimi1010 Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That appears to be because the compression context in LightPcapNG is NULL if its compiled without zst. It effectively performs a silent fallback to uncompressed, since NULL is also used if no compression is requested.

I suppose we could catch that in the constructor or open call of the PcapNg writer.

PR #1962 does add some methods to detect if zst is detected at compile time, tho that one is still open.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the test can use the USE_Z_STD macro that is used in LighPcapNg, otherwise it can skip the test:

PTF_TEST_CASE(TestPcapNgZstdCompressionLevels)
{
#ifdef USE_Z_STD
	// The test...
#else
	PTF_SKIP_TEST("Zstd is not configured");
#endif
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passing now 😄

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 29, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.69%. Comparing base (3bad1dd) to head (48dc05a).
⚠️ Report is 1 commits behind head on dev.

Additional details and impacted files
@@           Coverage Diff           @@
##              dev    #2113   +/-   ##
=======================================
  Coverage   82.69%   82.69%           
=======================================
  Files         332      332           
  Lines       59688    59687    -1     
  Branches    12306    12287   -19     
=======================================
+ Hits        49359    49360    +1     
+ Misses       9005     8913   -92     
- Partials     1324     1414   +90     
Flag Coverage Δ
23.11.6 7.31% <0.00%> (+0.01%) ⬆️
24.11.5 7.31% <0.00%> (-0.02%) ⬇️
25.11.1 7.33% <0.00%> (-0.02%) ⬇️
alpine320 76.83% <100.00%> (+0.01%) ⬆️
fedora42 76.42% <100.00%> (+<0.01%) ⬆️
macos-14 82.20% <100.00%> (+<0.01%) ⬆️
macos-15 82.19% <100.00%> (+<0.01%) ⬆️
mingw32 71.00% <ø> (-0.02%) ⬇️
mingw64 70.99% <ø> (+0.08%) ⬆️
npcap ?
rhel94 76.21% <100.00%> (+<0.01%) ⬆️
ubuntu2204 76.22% <100.00%> (+<0.01%) ⬆️
ubuntu2204-icpx 59.27% <ø> (-0.05%) ⬇️
ubuntu2404 76.51% <100.00%> (+<0.01%) ⬆️
ubuntu2404-arm64 76.50% <100.00%> (-0.03%) ⬇️
ubuntu2604 76.43% <100.00%> (-0.02%) ⬇️
unittest 82.69% <100.00%> (+<0.01%) ⬆️
windows-2022 85.73% <ø> (+0.12%) ⬆️
windows-2025 85.77% <ø> (+0.11%) ⬆️
winpcap 85.77% <ø> (-0.08%) ⬇️
xdp 53.10% <0.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Liam Merino added 3 commits April 29, 2026 01:08
The test compared output sizes for levels 1 vs 10 on a 20KB pcap; on
inputs that small, zstd produces identical output for both levels, so
the GREATER_THAN assertion always failed. Switch to a larger input
(EXAMPLE2_PCAPNG_PATH, ~26KB) and widen the gap to levels 1 vs 22
(zstd's documented max), which produces a clear size delta.

Also brace the single-statement while body per review nit.
@MerinoSheep MerinoSheep force-pushed the fix/issue-2081-zstd-compression-level branch from 2744cfa to 6543a42 Compare April 29, 2026 08:08
Copy link
Copy Markdown
Collaborator

@Dimi1010 Dimi1010 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thank you for the effort!

Copy link
Copy Markdown
Owner

@seladb seladb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@seladb seladb merged commit 12cdbd5 into seladb:dev Apr 30, 2026
42 checks passed
@seladb
Copy link
Copy Markdown
Owner

seladb commented Apr 30, 2026

@MerinoSheep thank you so much for working on it, much appreciated! 🙏

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.

3 participants