Fix and clean up constant comparisons flagged by CodeQL java/constant-comparison#226
Open
vharseko wants to merge 2 commits into
Open
Conversation
…-comparison Fix 2 real defects and remove 12 provably-constant (dead) comparisons across commons and persistit. The dead-comparison removals are behaviour-identical and clear the alerts at the source rather than by annotation. Real bugs: - ManagementTableModel: the column-removal loop was "for (i = _displayedColumnCount; --i >= count;)" inside "if (count > _displayedColumnCount)", so its body never ran and surplus table columns were never removed. The two bounds were swapped. - json-schema Main: verbose validation checked "valid.length == 0" (a boolean[1], so always false) and never set the flag true, so "OK - Object is valid!" was never printed. Initialise the flag to true and test valid[0]. Dead / redundant comparisons removed (behaviour-identical): - TransactionPlayer: the replay loop re-checked "type != TX.TYPE" but never re-read type, so the check was dead. Re-read type on each continuation record so the re-validation is live and consistent with the recordSize check. - LongRecordHelper: an "if (count > MAX_LONG_RECORD_CHAIN)" was nested inside an identical one - flatten the duplicate. - KeyParser.matchQuotedStringTail: the "else" branch re-tested "if (c == '\\')", which is unreachable there (backslash is handled above). Drop the dead branch. - Key.nextElementIndex: "return i < _size ? i + 1 : -1" - i < _size always holds inside the loop, so return i + 1. - Key.appendDisplayableStKey (BigInteger encode): removed "if (index < 0) break;" inside a "for (...; index >= 0; ...)" loop. - JsonValue.get(int) (util and legacy fluent): dropped "&& index >= 0" after the preceding "if (index < 0) throw". - AdminUIBufferPanel: dropped "_bufferPoolIndex >= 0 &&" after the code normalises a negative index to 0 two lines above. - IOMeter.dump: dropped "op >= 0 &&" after "if (op == -1) break". - FastIndex: removed the vestigial faultAt variable and its "if (faultAt < 0)" guards (assigned then immediately returned, never read). - Buffer (diagnostic dump): removed a dead "if (keep < TAILBLOCK_HDR_SIZE_DATA && keep > tbSize)" clamp (the condition can never hold and the fill loop already handles keep > tbSize). Remaining alerts for this rule are dismissed as "won't fix": intentional defensive assertions/bounds (LongRecordHelper, Key.maxStorableKeySize, Buffer page checks), a provable invariant on the hot key-search path, and the explicit HTTP status-family range ladder in Status.
a9ec6cd to
c523e38
Compare
maximthomas
approved these changes
Jul 8, 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
Resolves the 19 open
java/constant-comparisonCodeQL alerts: 2 real defectsfixed, 12 provably-constant (dead) comparisons removed in code
(behaviour-identical, so the alerts are cleared at the source), and 5 dismissed
as
won't fix(intentional defensive/readable code).Real bugs (2)
persistit/uiManagementTableModelfor (i = _displayedColumnCount; --i >= count;)insideif (count > _displayedColumnCount)— body never executed, so surplus table columns were never removed. Bounds were swapped.json-schema/cliMainvalid.length == 0(aboolean[1], always false) and never set the flag true → "OK - Object is valid!" never printed. Init flag totrue, testvalid[0].Dead / redundant comparisons removed (12, behaviour-identical)
persistit/coreTransactionPlayertype != TX.TYPEwithout re-readingtype. Now re-readstypeper continuation record so the check is live and consistent with therecordSizecheck.persistit/coreLongRecordHelperif (count > MAX_LONG_RECORD_CHAIN)nested inside an identical one — flattened.persistit/coreKeyParserelse-branch re-testedif (c == '\\'), unreachable there (backslash handled above).persistit/coreKeyreturn i < _size ? i + 1 : -1→i < _sizealways true →return i + 1.persistit/coreKeyif (index < 0) break;inside afor (…; index >= 0; …)loop.commons/utilJsonValue&& index >= 0after the precedingif (index < 0) throw.commons/json-fluentJsonValue&& index >= 0(legacy copy).persistit/uiAdminUIBufferPanel_bufferPoolIndex >= 0 &&after the index is normalised to0two lines above.persistit/coreIOMeterop >= 0 &&afterif (op == -1) break.persistit/coreFastIndexfaultAtvar and itsif (faultAt < 0)guards (assigned then immediately returned, never read).persistit/coreBufferif (keep < TAILBLOCK_HDR_SIZE_DATA && keep > tbSize)(never holds; fill loop already handleskeep > tbSize).Behaviour
Only two behaviours change, both to fix the bugs above (columns now removed; verbose
success now printed). Everything else is behaviour-identical removal of
provably-constant sub-expressions.
TransactionPlayernow re-readstypeon eachcontinuation record — a live re-validation that was previously dead; every record is
already type-validated in the first pass, so this only tightens defence-in-depth.
Not in this PR (dismissed as
won't fix, 5)Intentional code where the constant sub-expression is deliberate:
LongRecordHelperandKey.maxStorableKeySizedefensive assertions/clamps,Bufferpage-integrity bounds and a provable invariant on the hot key-search path,and the explicit HTTP status-family range ladder in
Status.Testing
mvn -o -pl persistit/core,persistit/ui,commons/json-schema/cli,commons/util/util,commons/json-fluent compile— all modules compile.commons/utilJsonValueTest+JsonValueFunctionsTest(96) andjson-fluentJsonValueTest(5) pass, covering theget(int)change. (persistit unit tests are skipped in the offline build environment.)