Skip to content

Commit 9db1961

Browse files
committed
C++: Reuse logic from commons/Scanf.
1 parent 27b41c2 commit 9db1961

File tree

2 files changed

+28
-36
lines changed

2 files changed

+28
-36
lines changed

cpp/ql/src/semmle/code/cpp/commons/Scanf.qll

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ class Snscanf extends ScanfFunction {
9292
this instanceof TopLevelFunction and
9393
(
9494
hasName("_snscanf") or // _snscanf(src, max_amount, format, args...)
95-
hasName("_snwscanf") // _snwscanf(src, max_amount, format, args...)
95+
hasName("_snwscanf") or // _snwscanf(src, max_amount, format, args...)
96+
hasName("_snscanf_l") or // _snscanf_l(src, max_amount, format, locale, args...)
97+
hasName("_snwscanf_l") // _snwscanf_l(src, max_amount, format, locale, args...)
9698
// note that the max_amount is not a limit on the output length, it's an input length
9799
// limit used with non null-terminated strings.
98100
)
@@ -101,6 +103,12 @@ class Snscanf extends ScanfFunction {
101103
override int getInputParameterIndex() { result = 0 }
102104

103105
override int getFormatParameterIndex() { result = 2 }
106+
107+
/**
108+
* Gets the position at which the maximum number of characters in the
109+
* input string is specified.
110+
*/
111+
int getInputLengthParameterIndex() { result = 1 }
104112
}
105113

106114
/**

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

Lines changed: 19 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55

66
import semmle.code.cpp.Function
7+
import semmle.code.cpp.commons.Scanf
78
import semmle.code.cpp.models.interfaces.ArrayFunction
89
import semmle.code.cpp.models.interfaces.Taint
910
import semmle.code.cpp.models.interfaces.Alias
@@ -12,53 +13,32 @@ import semmle.code.cpp.models.interfaces.SideEffect
1213
/**
1314
* The standard function `sscanf`, `fscanf` and its assorted variants
1415
*/
15-
private class Sscanf extends ArrayFunction, TaintFunction, AliasFunction, SideEffectFunction {
16-
Sscanf() {
17-
this.hasGlobalOrStdName([
18-
"sscanf", // sscanf(src, format, args...)
19-
"swscanf", // swscanf(src, format, args...)
20-
"fscanf", // fscanf(src_stream, format, args...)
21-
"fwscanf" // fwscanf(src_stream, format, args...)
22-
]) or
23-
this.hasGlobalName([
24-
"_sscanf_l", // _sscanf_l(src, format, locale, args...)
25-
"_swscanf_l", // _swscanf_l(src, format, locale, args...)
26-
"_snscanf", // _snscanf(src, length, format, args...)
27-
"_snscanf_l", // _snscanf_l(src, length, format, locale, args...)
28-
"_snwscanf", // _snwscanf(src, length, format, args...)
29-
"_snwscanf_l", // _snwscanf_l(src, length, format, locale, args...)
30-
"_fscanf_l", // _fscanf_l(src_stream, format, locale, args...)
31-
"_fwscanf_l" // _fwscanf_l(src_stream, format, locale, args...)
32-
])
33-
}
34-
35-
private predicate isSscanf() { this.getName().regexpMatch(".*sn?w?scanf.*") }
16+
private class SscanfModel extends ArrayFunction, TaintFunction, AliasFunction, SideEffectFunction {
17+
SscanfModel() { this instanceof Sscanf or this instanceof Fscanf or this instanceof Snscanf }
3618

3719
override predicate hasArrayWithNullTerminator(int bufParam) {
38-
bufParam = getFormatPosition()
20+
bufParam = this.(ScanfFunction).getFormatParameterIndex()
3921
or
40-
isSscanf() and
41-
bufParam = 0
22+
bufParam = this.(Sscanf).getInputParameterIndex()
4223
}
4324

4425
override predicate hasArrayInput(int bufParam) { hasArrayWithNullTerminator(bufParam) }
4526

46-
private int getLengthPosition() {
47-
this.getName().matches("\\_sn%") and
48-
result = 1
49-
}
27+
private int getLengthParameterIndex() { result = this.(Snscanf).getInputLengthParameterIndex() }
5028

51-
private int getLocalePosition() {
29+
private int getLocaleParameterIndex() {
5230
this.getName().matches("%\\_l") and
53-
(if exists(getLengthPosition()) then result = getLengthPosition() + 2 else result = 2)
31+
(
32+
if exists(getLengthParameterIndex())
33+
then result = getLengthParameterIndex() + 2
34+
else result = 2
35+
)
5436
}
5537

56-
private int getFormatPosition() { if exists(getLengthPosition()) then result = 2 else result = 1 }
57-
5838
private int getArgsStartPosition() {
5939
exists(int nLength, int nLocale |
60-
(if exists(getLocalePosition()) then nLocale = 1 else nLocale = 0) and
61-
(if exists(getLengthPosition()) then nLength = 1 else nLength = 0) and
40+
(if exists(getLocaleParameterIndex()) then nLocale = 1 else nLocale = 0) and
41+
(if exists(getLengthParameterIndex()) then nLength = 1 else nLength = 0) and
6242
result = 2 + nLocale + nLength
6343
)
6444
}
@@ -88,6 +68,10 @@ private class Sscanf extends ArrayFunction, TaintFunction, AliasFunction, SideEf
8868

8969
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
9070
buffer = true and
91-
i = [0, getFormatPosition(), getLocalePosition()]
71+
i =
72+
[
73+
this.(ScanfFunction).getFormatParameterIndex(),
74+
this.(ScanfFunction).getFormatParameterIndex(), getLocaleParameterIndex()
75+
]
9276
}
9377
}

0 commit comments

Comments
 (0)