@@ -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,25 @@ 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 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+
6091/**
6192 * Holds if `f` is a function such as `vprintf` that has a format parameter
6293 * (at `formatParamIndex`) and a variable argument list of type `va_arg`.
@@ -78,6 +109,8 @@ class UserDefinedFormattingFunction extends FormattingFunction {
78109 UserDefinedFormattingFunction ( ) { isVarargs ( ) and callsVariadicFormatter ( this , _) }
79110
80111 override int getFormatParameterIndex ( ) { callsVariadicFormatter ( this , result ) }
112+
113+ override int getOutputParameterIndex ( ) { callsVariadicFormatterOutput ( this , result ) }
81114}
82115
83116/**
0 commit comments