-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathOutputWrite.qll
More file actions
86 lines (79 loc) · 2.33 KB
/
OutputWrite.qll
File metadata and controls
86 lines (79 loc) · 2.33 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
/**
* Provides classes for modeling output to standard output / standard error through various mechanisms such as `printf`, `puts` and `operator<<`.
*/
import cpp
import FileWrite
/**
* A function call that writes to standard output or standard error.
*/
class OutputWrite extends Expr {
OutputWrite() { outputWrite(this, _) }
/**
* Gets a source expression for this output.
*/
Expr getASource() { outputWrite(this, result) }
}
/**
* A standard output or standard error variable.
*/
private predicate outputVariable(Variable v) {
v.hasName([
// standard output
"cout", "wcout",
// standard error
"cerr", "clog", "wcerr", "wclog"
])
}
/**
* An expr representing standard output or standard error.
*/
private predicate outputExpr(ChainedOutputCall out) {
// output chain ending in an access to standard output / standard error
outputVariable(out.getEndDest().(VariableAccess).getTarget())
}
/**
* A file representing standard output or standard error.
*/
private predicate outputFile(Expr e) {
exists(string name |
(
name = e.(VariableAccess).getTarget().(GlobalVariable).toString() or
name = e.findRootCause().(Macro).getName()
) and
name = ["stdout", "stderr"]
)
}
/**
* Holds if the function call is a write to standard output or standard error from 'source'.
*/
private predicate outputWrite(Expr write, Expr source) {
exists(Function f, int arg |
f = write.(Call).getTarget() and source = write.(Call).getArgument(arg)
|
// printf / syslog
f.(FormattingFunction).isOutputGlobal() and
arg >= f.(FormattingFunction).getFormatParameterIndex()
or
// puts, putchar
f.hasGlobalOrStdName(["puts", "putchar"]) and
arg = 0
or
exists(Call wrappedCall, Expr wrappedSource |
// wrapped output call (recursive case)
outputWrite(wrappedCall, wrappedSource) and
wrappedCall.getEnclosingFunction() = f and
parameterUsePair(f.getParameter(arg), wrappedSource)
)
)
or
// output to standard output / standard error using operator<<, put or write
outputExpr(write) and
source = write.(ChainedOutputCall).getSource()
or
exists(FileWrite fileWrite |
// output to stdout, stderr as a file (using FileWrite.qll logic)
write = fileWrite and
outputFile(fileWrite.getDest()) and
source = fileWrite.getASource()
)
}