Fix BITFIELD signed 64-bit overflow detection for OVERFLOW SAT/FAIL#1968
Merged
Conversation
At bitCount == 64, CheckSignedBitfieldOverflow's overflow check masked against the wrong-width mask (mask == -1, so ~mask == 0), making the overflow condition always false regardless of the actual result. WRAP was unaffected since its output value already comes from plain two's-complement long addition, but OVERFLOW SAT silently wrapped instead of saturating, and OVERFLOW FAIL silently succeeded instead of rejecting the write, whenever a signed 64-bit BITFIELD INCRBY actually overflowed. Fixed by detecting the sign flip on the raw addition result directly at bitCount == 64, mirroring the SAT branch's existing bitCount == 64 special case for maxVal a few lines below. The test file's own duplicated reference implementations (CheckSignedBitfieldOverflow and CheckSignedBitfieldOverflowRedis, used as differential-testing oracles by several existing tests) had the identical bug and are updated to match, plus a new focused regression test covering SAT/FAIL at bitCount == 64 in both directions.
Contributor
There was a problem hiding this comment.
✅ Ready to approve
The change is narrowly scoped, fixes a clearly identified logic gap for i64 at 64 bits, and includes targeted regression coverage plus aligned test oracles.
Note: this review does not count toward required approvals for merging.
Pull request overview
Fixes incorrect overflow handling for BITFIELD ... OVERFLOW SAT|FAIL INCRBY i64 ... when the field width is 64 bits (full signed long), where the prior “extra high bits” check could never trigger and caused SAT to wrap and FAIL to incorrectly succeed.
Changes:
- Special-cases
bitCount == 64signed overflow detection using sign-flip behavior of two’s-complement addition. - Updates the test-side differential “oracle” overflow helpers to match the corrected production semantics at 64 bits.
- Adds a focused regression test covering both overflow and underflow for
i64withOVERFLOW SATandOVERFLOW FAIL.
File summaries
| File | Description |
|---|---|
| libs/server/Resp/Bitmap/BitmapManagerBitfield.cs | Corrects signed 64-bit overflow detection for BITFIELD OVERFLOW SAT/FAIL by handling bitCount == 64 explicitly. |
| test/standalone/Garnet.test.complexstring/GarnetBitmapTests.cs | Updates test overflow oracles for the 64-bit case and adds a regression test for SAT/FAIL overflow/underflow behavior on i64. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Low
Note
Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.
vazois
approved these changes
Jul 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
BITFIELD ... OVERFLOW SAT|FAIL INCRBY i64 ...silently fails to detect overflow.SATwraps instead of saturating;FAILsucceeds (and writes) instead of rejecting the write and returning nil.Root cause
In
CheckSignedBitfieldOverflow(libs/server/Resp/Bitmap/BitmapManagerBitfield.cs), the overflow check is:At
bitCount == 64,maskis set to-1(all bits set), so~mask == 0, makingresult & ~maskalways0— the condition can never be true, regardless of whether the addition actually overflowed.WRAPisn't affected by this, since its output value already comes from plain two's-complementlongaddition (result = value + incrBy) independent of theoverflowflag.Fix
Special-case
bitCount == 64, detecting overflow via the sign flip on the raw result instead — mirroring the existingbitCount == 64special case formaxVala few lines below in the same function'sSATbranch:Tests
test/standalone/Garnet.test.complexstring/GarnetBitmapTests.cshas two of its own duplicated copies of overflow-checking logic (CheckSignedBitfieldOverflowandCheckSignedBitfieldOverflowRedis) used as differential-testing oracles by several existing tests — they had the identical class of bug atbitCount == 64and are updated to match, otherwise several existing tests (e.g.BitmapBitfieldGrowingTest) would now fail by disagreeing with the corrected production code.Added
BitmapBitfieldSigned64OverflowTest, coveringSAT/FAILatbitCount == 64in both the overflow and underflow directions. Confirmed it fails against the pre-fix code (reproduces the silent-wrap/silent-success bug) and passes with the fix.Note: while testing
FAIL, I noticed the stored value is unconditionally overwritten even whenFAILrejects the operation (rather than left untouched, asOVERFLOW FAIL's "no operation is performed" semantics would suggest) — this appears to be a separate, pre-existing issue independent of bitCount, not something introduced or fixed here, so I left it out of scope and out of the new test's assertions.