@@ -49,6 +49,18 @@ predicate primitiveVariadicFormatter(TopLevelFunction f, int formatParamIndex) {
49
49
)
50
50
}
51
51
52
+ /**
53
+ * A standard function such as `vsprintf` that has an output parameter
54
+ * and a variable argument list of type `va_arg`.
55
+ */
56
+ private predicate primitiveVariadicFormatterOutput ( TopLevelFunction f , int outputParamIndex ) {
57
+ // note: this might look like the regular expression in `primitiveVariadicFormatter`, but
58
+ // there is one important difference: the [fs] part is not optional, as these classify
59
+ // the `printf` variants that write to a buffer.
60
+ // Conveniently, these buffer parameters are all at index 0.
61
+ f .getName ( ) .regexpMatch ( "_?_?va?[fs]n?w?printf(_s)?(_p)?(_l)?" ) and outputParamIndex = 0
62
+ }
63
+
52
64
private predicate callsVariadicFormatter ( Function f , int formatParamIndex ) {
53
65
exists ( FunctionCall fc , int i |
54
66
variadicFormatter ( fc .getTarget ( ) , i ) and
@@ -57,6 +69,25 @@ private predicate callsVariadicFormatter(Function f, int formatParamIndex) {
57
69
)
58
70
}
59
71
72
+ private predicate callsVariadicFormatterOutput ( Function f , int outputParamIndex ) {
73
+ exists ( FunctionCall fc , int i |
74
+ fc .getEnclosingFunction ( ) = f and
75
+ variadicFormatterOutput ( fc .getTarget ( ) , i ) and
76
+ fc .getArgument ( i ) = f .getParameter ( outputParamIndex ) .getAnAccess ( )
77
+ )
78
+ }
79
+
80
+ /**
81
+ * Holds if `f` is a function such as `vprintf` that writes formatted
82
+ * output to buffer given as a parameter at index `outputParamIndex`, if any.
83
+ */
84
+ private predicate variadicFormatterOutput ( Function f , int outputParamIndex ) {
85
+ primitiveVariadicFormatterOutput ( f , outputParamIndex )
86
+ or
87
+ not f .isVarargs ( ) and
88
+ callsVariadicFormatterOutput ( f , outputParamIndex )
89
+ }
90
+
60
91
/**
61
92
* Holds if `f` is a function such as `vprintf` that has a format parameter
62
93
* (at `formatParamIndex`) and a variable argument list of type `va_arg`.
@@ -78,6 +109,8 @@ class UserDefinedFormattingFunction extends FormattingFunction {
78
109
UserDefinedFormattingFunction ( ) { isVarargs ( ) and callsVariadicFormatter ( this , _) }
79
110
80
111
override int getFormatParameterIndex ( ) { callsVariadicFormatter ( this , result ) }
112
+
113
+ override int getOutputParameterIndex ( ) { callsVariadicFormatterOutput ( this , result ) }
81
114
}
82
115
83
116
/**
0 commit comments