Skip to content

Commit 3745388

Browse files
authored
Merge pull request #2602 from chrisgavin/suspicious-date-format
Java: Add a query for suspicious date format patterns.
2 parents 816a8d1 + 484333b commit 3745388

File tree

7 files changed

+75
-0
lines changed

7 files changed

+75
-0
lines changed

change-notes/1.24/analysis-java.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ The following changes in version 1.24 affect Java analysis in all applications.
1111
| **Query** | **Tags** | **Purpose** |
1212
|-----------------------------|-----------|--------------------------------------------------------------------|
1313
| Failure to use HTTPS or SFTP URL in Maven artifact upload/download (`java/maven/non-https-url`) | security, external/cwe/cwe-300, external/cwe/cwe-319, external/cwe/cwe-494, external/cwe/cwe-829 | Finds use of insecure protocols during Maven dependency resolution. Results are shown on LGTM by default. |
14+
| Suspicious date format (`java/suspicious-date-format`) | correctness | Finds date format patterns that use placeholders that are likely to be incorrect. |
1415

1516
## Changes to existing queries
1617

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
System.out.println(new SimpleDateFormat("YYYY-MM-dd").format(new Date()));
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<!DOCTYPE qhelp PUBLIC
2+
"-//Semmle//qhelp//EN"
3+
"qhelp.dtd">
4+
<qhelp>
5+
6+
7+
<overview>
8+
<p>
9+
The Java <code>SimpleDateFormat</code> class provides many placeholders so that you can define
10+
precisely the date format required. However, this also makes it easy to define a pattern that
11+
doesn't behave exactly as you intended. The most common mistake is to use the <code>Y</code>
12+
placeholder (which represents the ISO 8601 week year), rather than <code>y</code> (which
13+
represents the actual year). In this case, the date reported will appear correct until the end
14+
of the year, when the "week year" may differ from the actual year.
15+
</p>
16+
</overview>
17+
18+
<recommendation>
19+
<p>
20+
Ensure the format pattern's use of <code>Y</code> is correct, and if not replace it with <code>y</code>.
21+
</p>
22+
</recommendation>
23+
24+
<example>
25+
<p>
26+
The following example uses the date format <code>YYYY-MM-dd</code>.
27+
On the 30th of December 2019, this code will output "2020-12-30", rather than the intended "2019-12-30".
28+
</p>
29+
<sample src="SuspiciousDateFormat.java" />
30+
<p>
31+
The correct pattern in this case would be <code>yyyy-MM-dd</code> instead of <code>YYYY-MM-dd</code>.
32+
</p>
33+
</example>
34+
35+
<references>
36+
<li>
37+
Java Platform, Standard Edition 7, API Specification:
38+
<a href="https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat</a>.
39+
</li>
40+
</references>
41+
42+
</qhelp>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* @name Suspicious date format
3+
* @description Using a data format that includes both 'M' and 'Y' is likely to give unexpected results.
4+
* @kind problem
5+
* @problem.severity warning
6+
* @precision high
7+
* @id java/suspicious-date-format
8+
* @tags correctness
9+
*/
10+
11+
import java
12+
13+
from ConstructorCall c, string format
14+
where
15+
c.getConstructedType().hasQualifiedName("java.text", "SimpleDateFormat") and
16+
format = c.getArgument(0).(StringLiteral).getValue() and
17+
format.matches("%Y%") and
18+
format.matches("%M%")
19+
select c, "Date formatter is passed a suspicious pattern \"" + format + "\"."
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import java.text.SimpleDateFormat;
2+
import java.util.Date;
3+
4+
public class A {
5+
public static void main(String[] args) {
6+
System.out.println(new SimpleDateFormat("yyyy-MM-dd").format(new Date())); // OK
7+
System.out.println(new SimpleDateFormat("YYYY-ww").format(new Date())); // OK
8+
System.out.println(new SimpleDateFormat("YYYY-MM-dd").format(new Date())); // BAD
9+
}
10+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| A.java:8:22:8:55 | new SimpleDateFormat(...) | Date formatter is passed a suspicious pattern "YYYY-MM-dd". |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Likely Bugs/Likely Typos/SuspiciousDateFormat.ql

0 commit comments

Comments
 (0)