Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d4cbb25

Browse files
committed
C++: Model std::string constructors and container constructors that use iterators.
1 parent 1ac0aa1 commit d4cbb25

7 files changed

Lines changed: 60 additions & 3 deletions

File tree

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,17 @@ class StdSequenceContainerConstructor extends Constructor, TaintFunction {
2727
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector<T>`
2828
}
2929

30+
/**
31+
* Gets the index of a parameter to this function that is an iterator.
32+
*/
33+
int getAnIteratorParameterIndex() { getParameter(result).getType() instanceof Iterator }
34+
3035
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
3136
// taint flow from any parameter of the value type to the returned object
32-
input.isParameterDeref(getAValueTypeParameterIndex()) and
37+
(
38+
input.isParameterDeref(getAValueTypeParameterIndex()) or
39+
input.isParameter(getAnIteratorParameterIndex())
40+
) and
3341
output.isReturnValue() // TODO: this should be `isQualifierObject` by our current definitions, but that flow is not yet supported.
3442
}
3543
}

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,43 @@ class StdBasicString extends TemplateClass {
1414
StdBasicString() { this.hasQualifiedName("std", "basic_string") }
1515
}
1616

17+
/**
18+
* Additional model for `std::string` constructors that reference the character
19+
* type of the container, or an iterator. For example construction from
20+
* iterators:
21+
* ```
22+
* std::string b(a.begin(), a.end());
23+
* ```
24+
*/
25+
class StdStringConstructor extends Constructor, TaintFunction {
26+
StdStringConstructor() { this.getDeclaringType().hasQualifiedName("std", "basic_string") }
27+
28+
/**
29+
* Gets the index of a parameter to this function that is a string (or
30+
* character).
31+
*/
32+
int getAStringParameterIndex() {
33+
getParameter(result).getType() instanceof PointerType or // e.g. `std::basic_string::CharT *`
34+
getParameter(result).getType() instanceof ReferenceType or // e.g. `std::basic_string &`
35+
getParameter(result).getUnspecifiedType() =
36+
getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. `std::basic_string::CharT`
37+
}
38+
39+
/**
40+
* Gets the index of a parameter to this function that is an iterator.
41+
*/
42+
int getAnIteratorParameterIndex() { getParameter(result).getType() instanceof Iterator }
43+
44+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
45+
// taint flow from any parameter of the value type to the returned object
46+
(
47+
input.isParameterDeref(getAStringParameterIndex()) or
48+
input.isParameter(getAnIteratorParameterIndex())
49+
) and
50+
output.isReturnValue() // TODO: this should be `isQualifierObject` by our current definitions, but that flow is not yet supported.
51+
}
52+
}
53+
1754
/**
1855
* The `std::string` function `c_str`.
1956
*/

cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,14 +1225,18 @@
12251225
| string.cpp:500:17:500:18 | ref arg s1 | string.cpp:503:7:503:8 | s1 | |
12261226
| string.cpp:500:17:500:18 | s1 | string.cpp:500:20:500:24 | call to begin | TAINT |
12271227
| string.cpp:500:17:500:37 | call to basic_string | string.cpp:505:7:505:8 | s3 | |
1228+
| string.cpp:500:20:500:24 | call to begin | string.cpp:500:17:500:37 | call to basic_string | TAINT |
12281229
| string.cpp:500:29:500:30 | ref arg s1 | string.cpp:503:7:503:8 | s1 | |
12291230
| string.cpp:500:29:500:30 | s1 | string.cpp:500:32:500:34 | call to end | TAINT |
1231+
| string.cpp:500:32:500:34 | call to end | string.cpp:500:17:500:37 | call to basic_string | TAINT |
12301232
| string.cpp:501:17:501:18 | ref arg s2 | string.cpp:501:29:501:30 | s2 | |
12311233
| string.cpp:501:17:501:18 | ref arg s2 | string.cpp:504:7:504:8 | s2 | |
12321234
| string.cpp:501:17:501:18 | s2 | string.cpp:501:20:501:24 | call to begin | TAINT |
12331235
| string.cpp:501:17:501:37 | call to basic_string | string.cpp:506:7:506:8 | s4 | |
1236+
| string.cpp:501:20:501:24 | call to begin | string.cpp:501:17:501:37 | call to basic_string | TAINT |
12341237
| string.cpp:501:29:501:30 | ref arg s2 | string.cpp:504:7:504:8 | s2 | |
12351238
| string.cpp:501:29:501:30 | s2 | string.cpp:501:32:501:34 | call to end | TAINT |
1239+
| string.cpp:501:32:501:34 | call to end | string.cpp:501:17:501:37 | call to basic_string | TAINT |
12361240
| stringstream.cpp:13:20:13:22 | call to basic_stringstream | stringstream.cpp:16:2:16:4 | ss1 | |
12371241
| stringstream.cpp:13:20:13:22 | call to basic_stringstream | stringstream.cpp:22:7:22:9 | ss1 | |
12381242
| stringstream.cpp:13:20:13:22 | call to basic_stringstream | stringstream.cpp:27:7:27:9 | ss1 | |
@@ -3030,18 +3034,22 @@
30303034
| vector.cpp:320:22:320:23 | v1 | vector.cpp:320:25:320:29 | call to begin | TAINT |
30313035
| vector.cpp:320:22:320:42 | call to vector | vector.cpp:325:7:325:8 | v3 | |
30323036
| vector.cpp:320:22:320:42 | call to vector | vector.cpp:327:1:327:1 | v3 | |
3037+
| vector.cpp:320:25:320:29 | call to begin | vector.cpp:320:22:320:42 | call to vector | TAINT |
30333038
| vector.cpp:320:34:320:35 | ref arg v1 | vector.cpp:323:7:323:8 | v1 | |
30343039
| vector.cpp:320:34:320:35 | ref arg v1 | vector.cpp:327:1:327:1 | v1 | |
30353040
| vector.cpp:320:34:320:35 | v1 | vector.cpp:320:37:320:39 | call to end | TAINT |
3041+
| vector.cpp:320:37:320:39 | call to end | vector.cpp:320:22:320:42 | call to vector | TAINT |
30363042
| vector.cpp:321:22:321:23 | ref arg v2 | vector.cpp:321:34:321:35 | v2 | |
30373043
| vector.cpp:321:22:321:23 | ref arg v2 | vector.cpp:324:7:324:8 | v2 | |
30383044
| vector.cpp:321:22:321:23 | ref arg v2 | vector.cpp:327:1:327:1 | v2 | |
30393045
| vector.cpp:321:22:321:23 | v2 | vector.cpp:321:25:321:29 | call to begin | TAINT |
30403046
| vector.cpp:321:22:321:42 | call to vector | vector.cpp:326:7:326:8 | v4 | |
30413047
| vector.cpp:321:22:321:42 | call to vector | vector.cpp:327:1:327:1 | v4 | |
3048+
| vector.cpp:321:25:321:29 | call to begin | vector.cpp:321:22:321:42 | call to vector | TAINT |
30423049
| vector.cpp:321:34:321:35 | ref arg v2 | vector.cpp:324:7:324:8 | v2 | |
30433050
| vector.cpp:321:34:321:35 | ref arg v2 | vector.cpp:327:1:327:1 | v2 | |
30443051
| vector.cpp:321:34:321:35 | v2 | vector.cpp:321:37:321:39 | call to end | TAINT |
3052+
| vector.cpp:321:37:321:39 | call to end | vector.cpp:321:22:321:42 | call to vector | TAINT |
30453053
| vector.cpp:323:7:323:8 | ref arg v1 | vector.cpp:327:1:327:1 | v1 | |
30463054
| vector.cpp:324:7:324:8 | ref arg v2 | vector.cpp:327:1:327:1 | v2 | |
30473055
| vector.cpp:325:7:325:8 | ref arg v3 | vector.cpp:327:1:327:1 | v3 | |

cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,5 +503,5 @@ void test_constructors_more() {
503503
sink(s1);
504504
sink(s2); // tainted
505505
sink(s3);
506-
sink(s4); // tainted [NOT DETECTED]
506+
sink(s4); // tainted
507507
}

cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@
137137
| string.cpp:488:8:488:8 | h | string.cpp:482:18:482:23 | call to source |
138138
| string.cpp:491:8:491:9 | s6 | string.cpp:482:18:482:23 | call to source |
139139
| string.cpp:504:7:504:8 | s2 | string.cpp:497:14:497:19 | call to source |
140+
| string.cpp:506:7:506:8 | s4 | string.cpp:497:14:497:19 | call to source |
140141
| structlikeclass.cpp:35:8:35:9 | s1 | structlikeclass.cpp:29:22:29:27 | call to source |
141142
| structlikeclass.cpp:36:8:36:9 | s2 | structlikeclass.cpp:30:24:30:29 | call to source |
142143
| structlikeclass.cpp:37:8:37:9 | s3 | structlikeclass.cpp:29:22:29:27 | call to source |
@@ -306,3 +307,4 @@
306307
| vector.cpp:311:9:311:14 | call to insert | vector.cpp:303:14:303:19 | call to source |
307308
| vector.cpp:312:7:312:7 | d | vector.cpp:303:14:303:19 | call to source |
308309
| vector.cpp:324:7:324:8 | v2 | vector.cpp:318:15:318:20 | call to source |
310+
| vector.cpp:326:7:326:8 | v4 | vector.cpp:318:15:318:20 | call to source |

cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
| string.cpp:488:8:488:8 | string.cpp:482:18:482:23 | AST only |
148148
| string.cpp:491:8:491:9 | string.cpp:482:18:482:23 | AST only |
149149
| string.cpp:504:7:504:8 | string.cpp:497:14:497:19 | AST only |
150+
| string.cpp:506:7:506:8 | string.cpp:497:14:497:19 | AST only |
150151
| structlikeclass.cpp:35:8:35:9 | structlikeclass.cpp:29:22:29:27 | AST only |
151152
| structlikeclass.cpp:36:8:36:9 | structlikeclass.cpp:30:24:30:29 | AST only |
152153
| structlikeclass.cpp:37:8:37:9 | structlikeclass.cpp:29:22:29:27 | AST only |
@@ -255,3 +256,4 @@
255256
| vector.cpp:311:9:311:14 | vector.cpp:303:14:303:19 | AST only |
256257
| vector.cpp:312:7:312:7 | vector.cpp:303:14:303:19 | AST only |
257258
| vector.cpp:324:7:324:8 | vector.cpp:318:15:318:20 | AST only |
259+
| vector.cpp:326:7:326:8 | vector.cpp:318:15:318:20 | AST only |

cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,5 +323,5 @@ void test_constructors_more() {
323323
sink(v1);
324324
sink(v2); // tainted
325325
sink(v3);
326-
sink(v4); // tainted [NOT DETECTED]
326+
sink(v4); // tainted
327327
}

0 commit comments

Comments
 (0)