-
Notifications
You must be signed in to change notification settings - Fork 75
Expand file tree
/
Copy pathDoNotConfuseNarrowAndWideFunctions.ql
More file actions
67 lines (61 loc) · 2.28 KB
/
DoNotConfuseNarrowAndWideFunctions.ql
File metadata and controls
67 lines (61 loc) · 2.28 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
/**
* @id c/cert/do-not-confuse-narrow-and-wide-functions
* @name STR38-C: Do not confuse narrow and wide character strings and functions
* @description Mixing narrow and wide character strings may cause unpredictable program behavior.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/cert/id/str38-c
* correctness
* security
* external/cert/obligation/rule
*/
import cpp
import codingstandards.c.cert
class NarrowCharStringType extends DerivedType {
NarrowCharStringType() {
// Use the transitive closure to include cv qualified character strings
getBaseType+() instanceof CharType
or
// Use the transitive closure to include cv qualified character strings
getBaseType+() instanceof Char8Type
}
}
class WideCharStringType extends DerivedType {
WideCharStringType() {
// Use the transitive closure to include cv qualified character strings
getBaseType+() instanceof Char16Type
or
// Use the transitive closure to include cv qualified character strings
getBaseType+() instanceof Char32Type
or
// Use the transitive closure to include cv qualified character strings
// `wchar_t` can be a typedef so we use the class `Wchar_t`
getBaseType+() instanceof Wchar_t
}
}
class WideToNarrowCast extends Cast {
WideToNarrowCast() {
this.getType() instanceof NarrowCharStringType and
this.getExpr().getType() instanceof WideCharStringType
}
}
class NarrowToWideCast extends Cast {
NarrowToWideCast() {
this.getType() instanceof WideCharStringType and
this.getExpr().getType() instanceof NarrowCharStringType
}
}
from FunctionCall call, Expr arg, Parameter p, Cast c, string actual, string expected
where
exists(int i | call.getArgument(i) = arg and call.getTarget().getParameter(i) = p) and
// Use the transitive closure to handle arrays that are converted to pointers before other type conversions.
arg.getConversion+() = c and
(
c instanceof NarrowToWideCast and actual = "narrow" and expected = "wide"
or
c instanceof WideToNarrowCast and actual = "wide" and expected = "narrow"
)
select call,
"Call to function `" + call.getTarget().getName() + "` with a " + actual +
" character string $@ where a " + expected + " character string is expected.", arg, "argument"