Skip to content

Check KLL, REQ and Quantiles images when deserializing - #568

Merged
leerho merged 5 commits into
masterfrom
deserialize-checks-master
Nov 6, 2026
Merged

leerho merged 5 commits into
masterfrom
deserialize-checks-master

Conversation

@leerho

@leerho leerho commented Nov 6, 2026

Copy link
Copy Markdown
Member

Brings these commits from the 5.3.x branch to master, so development continues on the same checks that are in 5.3.1:

  • KLL: deserialize() checks k, the number of levels and the levels array.
  • REQ: deserialize() checks k and the compactor headers.
  • Quantiles: the bytes overload checks the input size before the serial version 1 field.
  • NOTICE: the ASF copyright line is 2019-2026, and the Yahoo line is 2021-2025.

One commit is new here. The REQ test for the smallest section size now sets the k = 6 header directly, so it no longer depends on how far a sketch's section size shrinks.

Tested with all 17 test suites under ASan and UBSan.

🤖 Generated with Claude Code

leerho and others added 5 commits November 6, 2026 14:22
…izing

deserialize() used the serialized levels array without checking it. A
level beyond the capacity, or a level that starts before the previous
one, put level boundaries outside the items buffer, and the bytes
overload read the levels array without checking the input size.

Both overloads now check that k >= MIN_K, that there is at least one
level, that the input holds the levels array, and that each level starts
at or after the previous one and no later than the capacity.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
deserialize() used the compactor header fields without checking them.
A section size or number of sections of zero gave a nominal capacity of
zero, so the buffer did not grow on the next update. The bytes overload
checked 8 of the 20 header bytes. Large lg_weight and number of
sections values made shifts undefined, and a non-empty sketch with no
items read past the end of its only compactor.

Both overloads now check:
- k is even and in [MIN_K, MAX_K]
- a non-empty sketch has at least one level, and exactly one with raw
  items, and a single level holds at least one item
- compactor i has lg_weight i
- the section size rounds to an even value in [MIN_K, k]
- the number of sections is in [1, 64], and the raw section size,
  rounded to an integer, times the number of sections is at most k * k,
  as in datasketches-java
The bytes overload checks the input holds the full compactor header.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The bytes overload of deserialize() read the unused 8-byte field of
serial version 1 images without checking that the input holds it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The test relied on a real sketch shrinking its raw section size to 3.
Setting the header tests the same image without depending on how far
the section size shrinks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@leerho
leerho requested review from proost and tisonkun November 6, 2026 22:28
@coveralls

Copy link
Copy Markdown

Coverage Report for CI Build 42304902839

Coverage increased (+0.06%) to 82.461%

Details

  • Coverage increased (+0.06%) from the base build.
  • Patch coverage: 59 of 59 lines across 4 files are fully covered (100%).
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 21575
Covered Lines: 17791
Line Coverage: 82.46%
Coverage Strength: 1380290.06 hits per line

💛 - Coveralls

@leerho
leerho merged commit c22f2b1 into master Nov 6, 2026
35 checks passed
@leerho
leerho deleted the deserialize-checks-master branch November 6, 2026 23:55
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