-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathNumberFormatException.ql
More file actions
91 lines (81 loc) · 2.96 KB
/
NumberFormatException.ql
File metadata and controls
91 lines (81 loc) · 2.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/**
* @name Missing catch of NumberFormatException
* @description Calling a string to number conversion method without handling
* 'NumberFormatException'.
* @kind problem
* @problem.severity recommendation
* @precision high
* @id java/uncaught-number-format-exception
* @tags reliability
* external/cwe/cwe-248
*/
import java
private class SpecialMethodAccess extends MethodAccess {
predicate isValueOfMethod(string klass) {
this.getMethod().getName() = "valueOf" and
this.getQualifier().getType().(RefType).hasQualifiedName("java.lang", klass) and
this.getAnArgument().getType().(RefType).hasQualifiedName("java.lang", "String")
}
predicate isParseMethod(string klass, string name) {
this.getMethod().getName() = name and
this.getQualifier().getType().(RefType).hasQualifiedName("java.lang", klass)
}
predicate throwsNFE() {
this.isParseMethod("Byte", "parseByte") or
this.isParseMethod("Short", "parseShort") or
this.isParseMethod("Integer", "parseInt") or
this.isParseMethod("Long", "parseLong") or
this.isParseMethod("Float", "parseFloat") or
this.isParseMethod("Double", "parseDouble") or
this.isParseMethod("Byte", "decode") or
this.isParseMethod("Short", "decode") or
this.isParseMethod("Integer", "decode") or
this.isParseMethod("Long", "decode") or
this.isValueOfMethod("Byte") or
this.isValueOfMethod("Short") or
this.isValueOfMethod("Integer") or
this.isValueOfMethod("Long") or
this.isValueOfMethod("Float") or
this.isValueOfMethod("Double")
}
}
private class SpecialClassInstanceExpr extends ClassInstanceExpr {
predicate isStringConstructor(string klass) {
this.getType().(RefType).hasQualifiedName("java.lang", klass) and
this.getAnArgument().getType().(RefType).hasQualifiedName("java.lang", "String") and
this.getNumArgument() = 1
}
predicate throwsNFE() {
this.isStringConstructor("Byte") or
this.isStringConstructor("Short") or
this.isStringConstructor("Integer") or
this.isStringConstructor("Long") or
this.isStringConstructor("Float") or
this.isStringConstructor("Double")
}
}
class NumberFormatException extends RefType {
NumberFormatException() { this.hasQualifiedName("java.lang", "NumberFormatException") }
}
private predicate catchesNFE(TryStmt t) {
exists(CatchClause cc, LocalVariableDeclExpr v |
t.getACatchClause() = cc and
cc.getVariable() = v and
v.getType().(RefType).getASubtype*() instanceof NumberFormatException
)
}
private predicate throwsNFE(Expr e) {
e.(SpecialClassInstanceExpr).throwsNFE() or e.(SpecialMethodAccess).throwsNFE()
}
from Expr e
where
throwsNFE(e) and
not exists(TryStmt t |
t.getBlock() = e.getEnclosingStmt().getParent*() and
catchesNFE(t)
) and
not exists(Callable c |
e.getEnclosingCallable() = c and
c.getAThrownExceptionType().getASubtype*() instanceof NumberFormatException
)
select e, "Potential uncaught 'java.lang.NumberFormatException'."