Skip to content

snappy/s2: Limit length of varint in decodedLen - #1148

Merged
klauspost merged 1 commit into
klauspost:masterfrom
eustas:limitVarInt
May 7, 2026
Merged

klauspost merged 1 commit into
klauspost:masterfrom
eustas:limitVarInt

Conversation

@eustas

@eustas eustas commented May 7, 2026

Copy link
Copy Markdown
Contributor

To match C++ implementation.

Summary by CodeRabbit

  • Bug Fixes

    • Stricter validation of compressed-data headers to better detect and reject malformed/overlong encodings, reducing risk of silent corruption.
  • Tests

    • Added test cases covering malformed length encodings to ensure decoding surfaces corruption errors consistently.

To match C++ implementation
@coderabbitai

coderabbitai Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR tightens varint length validation in the snapref and s2 decoders to reject overlong varint preambles (consuming >5 bytes). decodedLen now returns ErrCorrupt when binary.Uvarint reports n <= 0 or n > 5. Tests for overlong 8-byte varints were added.

Changes

Varint Length Validation

Layer / File(s) Summary
Validation Logic
internal/snapref/decode.go, s2/decode.go
decodedLen now treats varint results with n <= 0 or n > 5 as corrupt and returns ErrCorrupt; existing v > 0xffffffff check remains.
Test Coverage
s2/s2_test.go, snappy/snappy_test.go
TestInvalidVarint table extended with an overlong 8-byte varint case; tests assert DecodedLen and Decode return ErrCorrupt.

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and specifically describes the main change: adding stricter validation for varint length in the decodedLen function across snappy and s2 packages.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment thread s2/s2_test.go
@klauspost

Copy link
Copy Markdown
Owner

The go version uses the same mechanism.

I don't really see any reason to change it. If people want to waste bytes IMO they are free to do so.

@eustas

eustas commented May 7, 2026

Copy link
Copy Markdown
Contributor Author

I'll update go version soon (need to unarchive repo first).

The purpose is consistency: we want all decoders to produce the same output from the same input.

The "golden" behavior is the one from C++ implementation. There we decode only until "offset" is less than 32 (given 7-bit increment that is up to 5 bytes). In brotli we have even more strict check that disallows leading zero nibs, but I can imagine some hardware encoder might prefer to have fixed size preamble if the stream length is unknown upfront, so checking for leading zeros would be harmful for snappy.

Yes, that is not exactly what spec says; going to update it to clarify that as well.

@klauspost klauspost left a comment

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.

OK. I will revert at the first sign of problems.

@klauspost klauspost changed the title Limit length of varint in decodedLen snappy/s2: Limit length of varint in decodedLen May 7, 2026
@klauspost
klauspost merged commit 0434480 into klauspost:master May 7, 2026
22 checks passed
@eustas
eustas deleted the limitVarInt branch May 8, 2026 08:44
@thaJeztah

thaJeztah commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

I'll update go version soon (need to unarchive repo first).

To save others arriving here from finding the related changes; PR (pending) is here;

@eustas

eustas commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

Will poke the owner soon.

@klauspost

Copy link
Copy Markdown
Owner

It has been released as part of https://github.com/klauspost/compress/releases/tag/v1.19.0

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