Pinned fields
Click on the next to a field label to start pinning.
Details
Assignee
UnassignedUnassignedReporter
Quentin JaquierQuentin JaquierLabels
Components
Priority
Normal
Details
Details
Assignee
Unassigned
UnassignedReporter
Quentin Jaquier
Quentin JaquierLabels
Components
Priority

Sentry
Sentry
Sentry
Created February 12, 2021 at 2:15 PM
Updated June 20, 2024 at 10:02 AM
Reproducer:
public final class Test { private static final BigDecimal IDENTITY = BigDecimal.ZERO; // No issue when = new BigDecimal("123"); private static <T> T valueOrDefault(T value, T defaultValue) { return value == null ? defaultValue : value; } public static BigDecimal bigDecimalSum(Collection<BigDecimal> values) { BigDecimal sum = IDENTITY; for (BigDecimal v : values) { sum = valueOrDefault(sum, IDENTITY).add(v); // S2259 FP } return sum; } }
In this code, the issue raised is that if
IDENTITY
is null, this code will throw a NPE. The engine believes it is possible sincesum
is checked for null during the first iteration of the loop wheresum
is equal toIDENTITY
, meaning thatIDENTITY
can also be null. It misses the fact that the first checkvalue == null
will always be false and that it is only useful from the second iteration (if `add` returns null).In the end, we miss detecting that the initial value can never be null. Note that if
IDENTITY
is initialized withnew BigDecimal("123");
, the FP disappears.Another example (in the same file):
public class NpeEx { static final String SONAR_TEST = "sonar_test"; } class S2259Demo { public void someMethod(boolean cond) { String testString = null; if (cond) { testString = NpeEx.SONAR_TEST; } if (testString == null) { // Do something } if (NpeEx.SONAR_TEST.equals(testString)) { // FP, constant can not be nullable // Do something } } }
In this second example, if we move the constant to the same class, the issue disappears.
Thrid similar example in this community thread.
Another example from discuss, slightly different from this ticket’s main example