Skip to content

Commit

Permalink
SONARJAVA-4508 Rule S2110: Add lower threshold to the Date values che…
Browse files Browse the repository at this point in the history
…ck (#4540)
  • Loading branch information
kaufco authored Nov 20, 2023
1 parent 6893424 commit cf2b33d
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ int foo() {
Date d = new Date();
d.setDate(25);
d.setDate(32);// Noncompliant [[sc=15;ec=17]] {{"32" is not a valid value for "setDate" method.}}
d.setDate(0);// Noncompliant [[sc=15;ec=16]] {{"0" is not a valid value for "setDate" method.}}
d.setDate(-1);// Noncompliant [[sc=15;ec=17]] {{"-1" is not a valid value for "setDate" method.}}
d.setYear(2014);
d.setMonth(11);
d.setMonth(12); // Noncompliant {{"12" is not a valid value for "setMonth" method.}}
Expand Down Expand Up @@ -70,6 +72,8 @@ int foo() {
b = 31 == d.getDate();
b = foo() == d.getDate();
b = 32 == d.getDate(); // Noncompliant {{"32" is not a valid value for "getDate".}}
b = -1 == d.getDate(); // Noncompliant {{"-1" is not a valid value for "getDate".}}
b = 0 == d.getDate(); // Noncompliant {{"0" is not a valid value for "getDate".}}
b = d1.getSeconds() == -1;// Noncompliant {{"-1" is not a valid value for "getSeconds".}}
b = cal.get(Calendar.DST_OFFSET) == 0;
return 0;
Expand All @@ -90,5 +94,3 @@ class RollingCalendar extends GregorianCalendar {
}
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,7 @@ private static String getReferencedCalendarName(ExpressionTree argument) {
reference = ((IdentifierTree) argument).symbol();
}
if (reference != null &&
reference.owner().type().is(JAVA_UTIL_CALENDAR) &&
Threshold.getThreshold(reference.name()) != null) {
reference.owner().type().is(JAVA_UTIL_CALENDAR) && DateField.containsField(reference.name())) {
return reference.name();
}
return null;
Expand Down Expand Up @@ -180,7 +179,8 @@ private void checkArgument(ExpressionTree arg, String name, String message) {
}
if (literal != null) {
int argValue = Integer.parseInt(literal.value()) * sign;
if (argValue > Threshold.getThreshold(name) || argValue < 0) {
Range range = DateField.getFieldRange(name);
if (argValue > range.maxValue || argValue < range.minValue) {
reportIssue(arg, MessageFormat.format(message, argValue, name));
}
}
Expand All @@ -190,41 +190,54 @@ private static String getMethodName(MethodInvocationTree mit) {
return ExpressionUtils.methodName(mit).name();
}

private enum Threshold {
MONTH(11, "setMonth", "getMonth", "MONTH", "month"),
DATE(31, "setDate", "getDate", "DAY_OF_MONTH", "dayOfMonth"),
HOURS(23, "setHours", "getHours", "HOUR_OF_DAY", "hourOfDay"),
MINUTE(60, "setMinutes", "getMinutes", "MINUTE", "minute"),
SECOND(61, "setSeconds", "getSeconds", "SECOND", "second");
private enum DateField {
MONTH(new Range(0, 11), "setMonth", "getMonth", "MONTH", "month"),
DATE(new Range(1, 31), "setDate", "getDate", "DAY_OF_MONTH", "dayOfMonth"),
HOURS(new Range(0, 23), "setHours", "getHours", "HOUR_OF_DAY", "hourOfDay"),
MINUTE(new Range(0, 60), "setMinutes", "getMinutes", "MINUTE", "minute"),
SECOND(new Range(0, 61), "setSeconds", "getSeconds", "SECOND", "second");

private static Map<String, Integer> thresholdByName = new HashMap<>();
private static final Map<String, Range> rangeByName = new HashMap<>();

static {
for (Threshold value : Threshold.values()) {
thresholdByName.put(value.javaDateSetter, value.edgeValue);
thresholdByName.put(value.javaDateGetter, value.edgeValue);
thresholdByName.put(value.calendarConstant, value.edgeValue);
thresholdByName.put(value.gregorianParam, value.edgeValue);
for (DateField field : DateField.values()) {
rangeByName.put(field.javaDateSetter, field.range);
rangeByName.put(field.javaDateGetter, field.range);
rangeByName.put(field.calendarConstant, field.range);
rangeByName.put(field.gregorianParam, field.range);
}
}

private final int edgeValue;
private final Range range;
private final String javaDateSetter;
private final String javaDateGetter;
private final String calendarConstant;
private final String gregorianParam;

Threshold(int edgeValue, String javaDateSetter, String javaDateGetter, String calendarConstant, String gregorianParam) {
this.edgeValue = edgeValue;
DateField(Range range, String javaDateSetter, String javaDateGetter, String calendarConstant, String gregorianParam) {
this.range = range;
this.javaDateSetter = javaDateSetter;
this.javaDateGetter = javaDateGetter;
this.calendarConstant = calendarConstant;
this.gregorianParam = gregorianParam;
}

public static Integer getThreshold(String name) {
return thresholdByName.get(name);
public static Range getFieldRange(String name) {
return rangeByName.get(name);
}

public static boolean containsField(String name) {
return rangeByName.containsKey(name);
}
}

private static class Range {
public final int minValue;
public final int maxValue;

private Range(int minValue, int maxValue) {
this.minValue = minValue;
this.maxValue = maxValue;
}
}
}

0 comments on commit cf2b33d

Please sign in to comment.