Skip to content

SONARJAVA-6786 Implement new rule S9346: Integer values should not be cast to long for use as timestamps - #5957

Merged
romainbrenguier merged 5 commits into
masterfrom
new-rule/SONARJAVA-6786-S9346
Aug 21, 2026
Merged

SONARJAVA-6786 Implement new rule S9346: Integer values should not be cast to long for use as timestamps#5957
romainbrenguier merged 5 commits into
masterfrom
new-rule/SONARJAVA-6786-S9346

Conversation

@romainbrenguier

Copy link
Copy Markdown
Contributor

Detect 32-bit or smaller integer values (int, short, byte, char) passed as arguments to timestamp-consuming APIs (Date, Timestamp, Instant, Calendar), where the narrow type causes overflow or data corruption.

@hashicorp-vault-sonar-prod

hashicorp-vault-sonar-prod Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

SONARJAVA-6786

@github-actions

Copy link
Copy Markdown
Contributor

Ruling needs updating. A fix PR has been created: #5958

Please review and merge it into your branch.

romainbrenguier pushed a commit that referenced this pull request Aug 19, 2026
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor

Ruling Diff Summary

Detected changes in 1 rule files: 0 issues removed, 2 issues added.

S9346 (java) on eclipse-jetty - 0 issues removed, 2 issues added - new ruling file

Added jetty-util-ajax/src/test/java/org/eclipse/jetty/util/ajax/JSONTest.java (line 366)

(source file not found at this revision: jetty-util-ajax/src/test/java/org/eclipse/jetty/util/ajax/JSONTest.java)

Added jetty-util-ajax/src/test/java/org/eclipse/jetty/util/ajax/JSONTest.java (line 433)

(source file not found at this revision: jetty-util-ajax/src/test/java/org/eclipse/jetty/util/ajax/JSONTest.java)

@romainbrenguier
romainbrenguier marked this pull request as ready for review August 20, 2026 13:42

@nathsou nathsou left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Request changes requested: preserve narrowing casts, regenerate the rule resources from the corrected RSPEC, and complete the literal exemption. Inline comments follow.


private void checkArgument(ExpressionTree argument) {
ExpressionTree arg = ExpressionUtils.skipParentheses(argument);
if (arg.is(Tree.Kind.TYPE_CAST)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P2] Preserve narrowing casts. This unwraps every TYPE_CAST, so new Date((int) millis) inspects millis as long and reports nothing, even though the argument has been truncated to int and then implicitly widened back to long. Only unwrap casts to long; otherwise inspect the cast expression type. Please add this case to the sample.

"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P2] Regenerate these generated resources from a corrected RSPEC. RSPEC PR 7897 specifies the pitfall and datetime tags plus the LOGICAL attribute, while this file contains no tags and COMPLETE. The resource directory README identifies RSPEC as the source of truth. Align the RSPEC example with the accepted direct-call scope, then regenerate HTML and JSON so the rule ships with the correct metadata.

if (arg.is(Tree.Kind.TYPE_CAST)) {
arg = ((TypeCastTree) arg).expression();
}
if (arg.is(Tree.Kind.INT_LITERAL)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[P3] Complete the literal exemption. new Date(0) is skipped, but equivalent literals such as new Date(-1) and new Date((long) (0)) still report because they are unary or parenthesized AST nodes. Skip parentheses after a long cast and recognize signed integer literals.

romainbrenguier and others added 4 commits August 21, 2026 14:08
Detect 32-bit or smaller integer values (int, short, byte, char) passed
as arguments to timestamp-consuming APIs (Date, Timestamp, Instant,
Calendar), where the narrow type causes overflow or data corruption.
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
- Fix secondary location marker alignment in test sample (off by one space)
- Exclude int literal arguments (e.g., `new Date(0)`) from detection to
  reduce false positives on intentional small values
- Update HTML noncompliant example to show patterns the rule actually
  detects (direct int arg and explicit cast) instead of the variable
  indirection pattern which is not detected

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous commit excluded int literals from S9346, which means
the eclipse-jetty findings at JSONTest.java lines 366 and 433 are
no longer raised.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@nathsou
nathsou force-pushed the new-rule/SONARJAVA-6786-S9346 branch from 0f0799c to 79b5cb1 Compare August 21, 2026 12:09
@datadog-sonarsource

This comment has been minimized.

…d literals, update metadata

- Only unwrap casts to long in checkArgument; narrowing casts (e.g. (int)) are
  now correctly reported as noncompliant
- Recognize negative/positive unary integer literals (-1, +1) as exempt
- Strip parentheses after unwrapping long cast for literal check
- Update S9346.json: set tags to [pitfall, datetime] and attribute to LOGICAL
- Add test cases for narrowing casts and signed/parenthesized literals

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gitar-bot

gitar-bot Bot commented Aug 21, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 2 resolved / 2 findings

Implements rule S9346 to detect integer values cast to long for use as timestamps, addressing noisy int/long-literal timestamps and missed cases involving stored casts.

✅ 2 resolved
Edge Case: Rule flags legitimate int/long-literal timestamps causing noise

📄 java-checks/src/main/java/org/sonar/java/checks/IntegerToLongTimestampCastCheck.java:80-94 📄 java-checks-test-sources/default/src/main/java/checks/IntegerToLongTimestampCastCheckSample.java:75-77
The check reports any narrow-int argument including plain literals such as new Date(0) and int constants that represent valid timestamps within the int range (e.g. seconds fitting before 2038). In real codebases new Date(0) (epoch) and small constants are common and intentional, so this may generate a high volume of false positives. Consider excluding constant/literal arguments or those provably within a safe range, or documenting this behavior explicitly in the RSPEC.

Bug: Rule misses documented case: int cast stored in long variable

📄 java-checks/src/main/java/org/sonar/java/checks/IntegerToLongTimestampCastCheck.java:80-92 📄 sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S9346.html:14-18
The canonical Noncompliant example in S9346.html stores (long) timestamp in a long variable and then passes that variable to new Date(epochMillis). The implementation's checkArgument only inspects the direct argument at the call site (skipping parentheses and unwrapping a single TypeCast), so a long-typed variable argument yields a non-narrow type and is never reported. The primary documented pattern is therefore a false negative and is not covered by the sample test file. Either narrow the documentation example to match what the check detects (cast/int directly in the call), or extend the check to trace the argument's initializer when it is a local variable assigned from a narrow-int cast, and add a corresponding test case.

Implementation Status ✅ 1 / 1 issues implemented
SONARJAVA-6786 — 1 / 1 objectives

The PR successfully implements the new rule S9346 to check that integer values are not cast to long for use as timestamps.

✅ 1 complete
  • ✅ Implement new rule S9346: Integer values should not be cast to long for use as timestamps
Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@sonarqube-next

Copy link
Copy Markdown
Contributor

@romainbrenguier
romainbrenguier merged commit 3f13e22 into master Aug 21, 2026
19 checks passed
@romainbrenguier
romainbrenguier deleted the new-rule/SONARJAVA-6786-S9346 branch August 21, 2026 15:39
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.

2 participants