Skip to content

Commit 2644d03

Browse files
committed
C++: Add a bunch of vararg related formatting functions that takes a 'va_list' parameter.
1 parent 6f293af commit 2644d03

1 file changed

Lines changed: 139 additions & 0 deletions

File tree

  • cpp/ql/lib/semmle/code/cpp/models/implementations

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

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,38 @@ private class Fprintf extends FormattingFunction, NonCppThrowingFunction instanc
6969
override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = true }
7070
}
7171

72+
/**
73+
* The standard functions `vprintf`, `vwprintf` and their Microsoft variants.
74+
*/
75+
private class Vprintf extends VaListFormattingFunction, NonCppThrowingFunction instanceof TopLevelFunction
76+
{
77+
Vprintf() {
78+
(
79+
this.hasGlobalOrStdOrBslName(["vprintf", "vwprintf"]) or
80+
this.hasGlobalName(["_vprintf_l", "_vwprintf_l"])
81+
) and
82+
not exists(this.getDefinition().getFile().getRelativePath())
83+
}
84+
85+
override predicate isOutputGlobal() { any() }
86+
}
87+
88+
/**
89+
* The standard functions `vfprintf`, `vfwprintf` and their Microsoft variants.
90+
*/
91+
private class Vfprintf extends VaListFormattingFunction, NonCppThrowingFunction instanceof TopLevelFunction
92+
{
93+
Vfprintf() {
94+
(
95+
this.hasGlobalOrStdOrBslName(["vfprintf", "vfwprintf"]) or
96+
this.hasGlobalName(["_vfprintf_l", "_vfwprintf_l"])
97+
) and
98+
not exists(this.getDefinition().getFile().getRelativePath())
99+
}
100+
101+
override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = true }
102+
}
103+
72104
/**
73105
* The standard function `sprintf` and its Microsoft and glib variants.
74106
*/
@@ -112,6 +144,25 @@ private class Sprintf extends FormattingFunction, NonCppThrowingFunction instanc
112144
}
113145
}
114146

147+
/**
148+
* The standard function `vsprintf` and its Microsoft variants.
149+
*/
150+
private class Vsprintf extends VaListFormattingFunction, NonCppThrowingFunction instanceof TopLevelFunction
151+
{
152+
Vsprintf() {
153+
(
154+
this.hasGlobalOrStdOrBslName("vsprintf") or // vsprintf(dst, format, va_list)
155+
this.hasGlobalName([
156+
"_vsprintf_l", // _vsprintf_l(dst, format, locale, va_list)
157+
"__vswprintf_l" // __vswprintf_l(dst, format, locale, va_list)
158+
])
159+
) and
160+
not exists(this.getDefinition().getFile().getRelativePath())
161+
}
162+
163+
override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = false }
164+
}
165+
115166
/**
116167
* Implements `Snprintf`.
117168
*/
@@ -185,6 +236,94 @@ private class SnprintfImpl extends Snprintf, AliasFunction, SideEffectFunction,
185236
}
186237
}
187238

239+
/**
240+
* The standard function `vsnprintf`, and its Microsoft variants.
241+
*/
242+
private class VsnprintfImpl extends Snprintf, VaListFormattingFunction, AliasFunction,
243+
SideEffectFunction, NonCppThrowingFunction instanceof TopLevelFunction
244+
{
245+
VsnprintfImpl() {
246+
(
247+
this.hasGlobalOrStdOrBslName("vsnprintf") // vsnprintf(dst, count, format, va_list)
248+
or
249+
this.hasGlobalName([
250+
"vsnprintf_s", // vsnprintf_s(dst, size, count, format, va_list)
251+
"vsprintf_s", // vsprintf_s(dst, size, format, va_list)
252+
"vswprintf_s", // vswprintf_s(dst, size, format, va_list)
253+
"_vsnprintf", // _vsnprintf(dst, count, format, va_list)
254+
"_vsnprintf_l", // _vsnprintf_l(dst, count, format, locale, va_list)
255+
"_vsnprintf_s", // _vsnprintf_s(dst, size, count, format, va_list)
256+
"_vsnprintf_s_l", // _vsnprintf_s_l(dst, size, count, format, locale, va_list)
257+
"_vsnwprintf", // _vsnwprintf(dst, count, format, va_list)
258+
"_vsnwprintf_l", // _vsnwprintf_l(dst, count, format, locale, va_list)
259+
"_vsnwprintf_s", // _vsnwprintf_s(dst, size, count, format, va_list)
260+
"_vsnwprintf_s_l", // _vsnwprintf_s_l(dst, size, count, format, locale, va_list)
261+
"_vsprintf_p", // _vsprintf_p(dst, size, format, va_list)
262+
"_vsprintf_p_l", // _vsprintf_p_l(dst, size, format, locale, va_list)
263+
"_vsprintf_s_l", // _vsprintf_s_l(dst, size, format, locale, va_list)
264+
"_vswprintf_p", // _vswprintf_p(dst, count, format, va_list)
265+
"_vswprintf_p_l", // _vswprintf_p_l(dst, count, format, locale, va_list)
266+
"_vswprintf_s_l" // _vswprintf_s_l(dst, size, format, locale, va_list)
267+
])
268+
or
269+
this.hasGlobalOrStdOrBslName("vswprintf") and this.getNumberOfParameters() = 4
270+
or
271+
this.hasGlobalName("_vswprintf_l") and this.getNumberOfParameters() = 5
272+
) and
273+
not exists(this.getDefinition().getFile().getRelativePath())
274+
}
275+
276+
override int getOutputParameterIndex(boolean isStream) { result = 0 and isStream = false }
277+
278+
override int getSizeParameterIndex() { result = 1 }
279+
280+
override predicate returnsFullFormatLength() { this.hasName(["vsnprintf", "vsnprintf_s"]) }
281+
282+
override predicate parameterNeverEscapes(int index) {
283+
index =
284+
[
285+
this.getOutputParameterIndex(false), this.getFormatParameterIndex(),
286+
this.getVaListParameterIndex()
287+
]
288+
}
289+
290+
override predicate parameterEscapesOnlyViaReturn(int index) { none() }
291+
292+
override predicate parameterIsAlwaysReturned(int index) { none() }
293+
294+
override predicate hasOnlySpecificReadSideEffects() { any() }
295+
296+
override predicate hasOnlySpecificWriteSideEffects() { any() }
297+
298+
override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) {
299+
i = this.getOutputParameterIndex(false) and buffer = true and mustWrite = false
300+
or
301+
i = this.getVaListParameterIndex() and buffer = false and mustWrite = false
302+
}
303+
304+
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
305+
i = this.getFormatParameterIndex() and buffer = true
306+
or
307+
i = this.getVaListParameterIndex() and buffer = false
308+
}
309+
}
310+
311+
/**
312+
* The Microsoft `_vscprintf_p` functions and variants.
313+
*/
314+
private class Vscprintf extends VaListFormattingFunction, NonCppThrowingFunction instanceof TopLevelFunction
315+
{
316+
Vscprintf() {
317+
this.hasGlobalName([
318+
"_vscprintf_p", // _vscprintf_p(format, va_list)
319+
"_vscprintf_p_l", // _vscprintf_p_l(format, locale, va_list)
320+
"_vscwprintf_p", // _vscwprintf_p(format, va_list)
321+
"_vscwprintf_p_l" // _vscwprintf_p_l(format, locale, va_list)
322+
]) and
323+
not exists(this.getDefinition().getFile().getRelativePath())
324+
}
325+
}
326+
188327
/**
189328
* The Microsoft `StringCchPrintf` function and variants.
190329
* See: https://learn.microsoft.com/en-us/windows/win32/api/strsafe/

0 commit comments

Comments
 (0)