Skip to content

Commit 23e29e9

Browse files
committed
C++: Split std::string::insert off in a separate class
The `insert` function has two different return types: `iterator` and `basic_string&`.
1 parent ecd8921 commit 23e29e9

File tree

1 file changed

+54
-4
lines changed

1 file changed

+54
-4
lines changed

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

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,13 +142,13 @@ private class StdStringPlus extends TaintFunction {
142142
}
143143

144144
/**
145-
* The `std::string` functions `operator+=`, `append`, `insert` and
146-
* `replace`. All of these functions combine the existing string
147-
* with a new string (or character) from one of the arguments.
145+
* The `std::string` functions `operator+=`, `append` and `replace`.
146+
* All of these functions combine the existing string with a new
147+
* string (or character) from one of the arguments.
148148
*/
149149
private class StdStringAppend extends TaintFunction {
150150
StdStringAppend() {
151-
this.getClassAndName(["operator+=", "append", "insert", "replace"]) instanceof StdBasicString
151+
this.getClassAndName(["operator+=", "append", "replace"]) instanceof StdBasicString
152152
}
153153

154154
/**
@@ -186,6 +186,56 @@ private class StdStringAppend extends TaintFunction {
186186
}
187187
}
188188

189+
/**
190+
* The `std::string` function `insert`.
191+
*/
192+
private class StdStringInsert extends TaintFunction {
193+
StdStringInsert() {
194+
this.getClassAndName("insert") instanceof StdBasicString
195+
}
196+
197+
/**
198+
* Gets the index of a parameter to this function that is a string (or
199+
* character).
200+
*/
201+
int getAStringParameterIndex() {
202+
this.getParameter(result).getType() instanceof PointerType or // e.g. `std::basic_string::CharT *`
203+
this.getParameter(result).getType() instanceof ReferenceType or // e.g. `std::basic_string &`
204+
this.getParameter(result).getUnspecifiedType() =
205+
this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT`
206+
}
207+
208+
/**
209+
* Gets the index of a parameter to this function that is an iterator.
210+
*/
211+
int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator }
212+
213+
/**
214+
* Holds if the return type is an iterator.
215+
*/
216+
predicate hasIteratorReturnValue() { this.getType() instanceof Iterator }
217+
218+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
219+
// flow from string and parameter to string (qualifier) and return value
220+
(
221+
input.isQualifierObject() or
222+
input.isParameterDeref(this.getAStringParameterIndex()) or
223+
input.isParameter(this.getAnIteratorParameterIndex())
224+
) and
225+
(
226+
output.isQualifierObject()
227+
or
228+
if this.hasIteratorReturnValue() then output.isReturnValue() else output.isReturnValueDeref()
229+
)
230+
or
231+
// reverse flow from returned reference to the qualifier (for writes to
232+
// the result)
233+
not this.hasIteratorReturnValue() and
234+
input.isReturnValueDeref() and
235+
output.isQualifierObject()
236+
}
237+
}
238+
189239
/**
190240
* The standard function `std::string.assign`.
191241
*/

0 commit comments

Comments
 (0)