@@ -49,6 +49,18 @@ predicate primitiveVariadicFormatter(TopLevelFunction f, int formatParamIndex) {
4949 )
5050}
5151
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+
5264private predicate callsVariadicFormatter ( Function f , int formatParamIndex ) {
5365 exists ( FunctionCall fc , int i |
5466 variadicFormatter ( fc .getTarget ( ) , i ) and
@@ -57,6 +69,26 @@ private predicate callsVariadicFormatter(Function f, int formatParamIndex) {
5769 )
5870}
5971
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 takes variable argument list
82+ * of type `va_arg` and writes formatted output to a buffer given as a parameter at
83+ * index `outputParamIndex`, if any.
84+ */
85+ private predicate variadicFormatterOutput ( Function f , int outputParamIndex ) {
86+ primitiveVariadicFormatterOutput ( f , outputParamIndex )
87+ or
88+ not f .isVarargs ( ) and
89+ callsVariadicFormatterOutput ( f , outputParamIndex )
90+ }
91+
6092/**
6193 * Holds if `f` is a function such as `vprintf` that has a format parameter
6294 * (at `formatParamIndex`) and a variable argument list of type `va_arg`.
@@ -78,6 +110,8 @@ class UserDefinedFormattingFunction extends FormattingFunction {
78110 UserDefinedFormattingFunction ( ) { isVarargs ( ) and callsVariadicFormatter ( this , _) }
79111
80112 override int getFormatParameterIndex ( ) { callsVariadicFormatter ( this , result ) }
113+
114+ override int getOutputParameterIndex ( ) { callsVariadicFormatterOutput ( this , result ) }
81115}
82116
83117/**
0 commit comments