Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c3b16a5

Browse files
committed
C++: Implement FormattingFunction isOutputStream, isOutputString so that subclasses don't need to be accessed for this information, and can be private.
1 parent 99b01e7 commit c3b16a5

4 files changed

Lines changed: 31 additions & 12 deletions

File tree

cpp/ql/src/semmle/code/cpp/models/implementations/Printf.qll

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import semmle.code.cpp.models.interfaces.Alias
1111
/**
1212
* The standard functions `printf`, `wprintf` and their glib variants.
1313
*/
14-
class Printf extends FormattingFunction, AliasFunction {
14+
private class Printf extends FormattingFunction, AliasFunction {
1515
Printf() {
1616
this instanceof TopLevelFunction and
1717
(
@@ -31,6 +31,8 @@ class Printf extends FormattingFunction, AliasFunction {
3131
hasGlobalName("wprintf_s")
3232
}
3333

34+
override predicate isOutputGlobal() { any() }
35+
3436
override predicate parameterNeverEscapes(int n) { n = 0 }
3537

3638
override predicate parameterEscapesOnlyViaReturn(int n) { none() }
@@ -41,7 +43,7 @@ class Printf extends FormattingFunction, AliasFunction {
4143
/**
4244
* The standard functions `fprintf`, `fwprintf` and their glib variants.
4345
*/
44-
class Fprintf extends FormattingFunction {
46+
private class Fprintf extends FormattingFunction {
4547
Fprintf() {
4648
this instanceof TopLevelFunction and
4749
(
@@ -57,6 +59,8 @@ class Fprintf extends FormattingFunction {
5759
deprecated override predicate isWideCharDefault() { hasGlobalOrStdName("fwprintf") }
5860

5961
override int getOutputParameterIndex() { result = 0 }
62+
63+
override predicate isOutputStream() { any() }
6064
}
6165

6266
/**
@@ -232,12 +236,14 @@ private class StringCchPrintf extends FormattingFunction {
232236
/**
233237
* The standard function `syslog`.
234238
*/
235-
class Syslog extends FormattingFunction {
239+
private class Syslog extends FormattingFunction {
236240
Syslog() {
237241
this instanceof TopLevelFunction and
238242
hasGlobalName("syslog") and
239243
not exists(getDefinition().getFile().getRelativePath())
240244
}
241245

242246
override int getFormatParameterIndex() { result = 1 }
247+
248+
override predicate isOutputGlobal() { any() }
243249
}

cpp/ql/src/semmle/code/cpp/models/interfaces/FormattingFunction.qll

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,24 @@ abstract class FormattingFunction extends ArrayFunction, TaintFunction {
109109
}
110110

111111
/**
112-
* Gets the position at which the output parameter, if any, occurs.
112+
* Gets the position at which the output parameter, if any, occurs. This may
113+
* be a buffer that characters are written to if this function behaves like
114+
* `sprintf`. Alternatively it may be a stream that is used for output if
115+
* this function behaves like `fprintf` (see `isOutputStream`).
113116
*/
114117
int getOutputParameterIndex() { none() }
118+
119+
/**
120+
* Holds if this function outputs to a global stream such as standard output,
121+
* standard error or a system log. For example `printf`.
122+
*/
123+
predicate isOutputGlobal() { none() }
124+
125+
/**
126+
* Holds if this function outputs to the stream indicated by
127+
* `getOutputParameterIndex()`, that is, this function behaves like `fprintf`.
128+
*/
129+
predicate isOutputStream() { none() }
115130

116131
/**
117132
* Gets the position of the first format argument, corresponding with

cpp/ql/src/semmle/code/cpp/security/FileWrite.qll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
*/
44

55
import cpp
6-
import semmle.code.cpp.models.implementations.Printf
76

87
/**
98
* A function call that writes to a file.
@@ -144,8 +143,9 @@ private predicate fileWrite(Call write, Expr source, Expr dest) {
144143
)
145144
or
146145
// fprintf
147-
s >= f.(Fprintf).getFormatParameterIndex() and
148-
d = f.(Fprintf).getOutputParameterIndex()
146+
f.(FormattingFunction).isOutputStream() and
147+
s >= f.(FormattingFunction).getFormatParameterIndex() and
148+
d = f.(FormattingFunction).getOutputParameterIndex()
149149
)
150150
or
151151
// file stream using '<<', 'put' or 'write'

cpp/ql/src/semmle/code/cpp/security/OutputWrite.qll

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,9 @@ private predicate outputWrite(Expr write, Expr source) {
5959
exists(Function f, int arg |
6060
f = write.(Call).getTarget() and source = write.(Call).getArgument(arg)
6161
|
62-
// printf
63-
arg >= f.(Printf).getFormatParameterIndex()
64-
or
65-
// syslog
66-
arg >= f.(Syslog).getFormatParameterIndex()
62+
// printf / syslog
63+
f.(FormattingFunction).isOutputGlobal() and
64+
arg >= f.(FormattingFunction).getFormatParameterIndex()
6765
or
6866
// puts, putchar
6967
(

0 commit comments

Comments
 (0)