Skip to content

Commit d0e40f5

Browse files
committed
Extend ascii-code-point-written-as-int-literal.ql to cover comparisons
1 parent e24e79b commit d0e40f5

File tree

1 file changed

+37
-5
lines changed

1 file changed

+37
-5
lines changed

codeql-custom-queries-java/queries/error-prone/ascii-code-point-written-as-int-literal.ql

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,47 @@
88
* return c >= 97 && c <= 122;
99
* }
1010
* ```
11+
*
12+
* @kind problem
13+
* @id TODO
1114
*/
1215

1316
import java
1417
import semmle.code.java.Conversions
1518

19+
predicate isUsedAsChar(IntegerLiteral intLiteral) {
20+
intLiteral.(ConversionSite).getConversionTarget() instanceof CharacterType and
21+
// Ignore if used in arithmetic operation; probably only have to consider AssignOp (e.g. `+=`) because for
22+
// other arithmetic operations implicit conversion to greater numeric type (e.g. `int`) occurs (?)
23+
not any(AssignOp a).getRhs() = intLiteral
24+
or
25+
// Or comparing with a char value
26+
exists(BinaryExpr comp |
27+
comp instanceof EqualityTest
28+
or
29+
comp instanceof ComparisonExpr and
30+
// But only consider when comparing with an alpha-numeric char (a-z, A-Z, 0-9)
31+
// Control code checks such as `c < 0x20` might be easier to understand than `c < ' '`
32+
exists(int codePoint | codePoint = intLiteral.getIntValue() |
33+
codePoint = [97 .. 122] or codePoint = [65 .. 90] or codePoint = [48 .. 57]
34+
)
35+
|
36+
comp.getAnOperand() = intLiteral and comp.getAnOperand().getType() instanceof CharacterType
37+
)
38+
or
39+
// Or calling `Character.equals`
40+
exists(MethodAccess equalsCall |
41+
equalsCall.getMethod() instanceof EqualsMethod and
42+
equalsCall.getQualifier().getType().(RefType).hasQualifiedName("java.lang", "Character") and
43+
equalsCall.getArgument(0) = intLiteral
44+
)
45+
}
46+
1647
from IntegerLiteral intLiteral, int codePoint, string asciiChar
1748
where
18-
intLiteral.(ConversionSite).getConversionTarget() instanceof CharacterType
19-
and codePoint = intLiteral.getIntValue()
20-
and codePoint in [32 .. 126]
21-
and asciiChar = codePoint.toUnicode()
22-
select intLiteral, "Uses int literal instead of char literal for printable ASCII char '" + asciiChar + "'"
49+
isUsedAsChar(intLiteral) and
50+
codePoint = intLiteral.getIntValue() and
51+
codePoint in [32 .. 126] and
52+
asciiChar = codePoint.toUnicode()
53+
select intLiteral,
54+
"Uses int literal instead of char literal for printable ASCII char '" + asciiChar + "'"

0 commit comments

Comments
 (0)