From 983f54f11a74736eed61075c24229032131d09a2 Mon Sep 17 00:00:00 2001
From: Robert Marsh
Date: Tue, 25 Aug 2020 15:21:16 -0700
Subject: [PATCH 001/411] C++: simple tests for vector output iterators
---
.../dataflow/taint-tests/localTaint.expected | 82 +++++++++++++++++++
.../dataflow/taint-tests/vector.cpp | 27 ++++++
2 files changed, 109 insertions(+)
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
index 9a9fca0cd59..bca6b6299ad 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
@@ -3173,3 +3173,85 @@
| vector.cpp:324:7:324:8 | ref arg v2 | vector.cpp:327:1:327:1 | v2 | |
| vector.cpp:325:7:325:8 | ref arg v3 | vector.cpp:327:1:327:1 | v3 | |
| vector.cpp:326:7:326:8 | ref arg v4 | vector.cpp:327:1:327:1 | v4 | |
+| vector.cpp:329:62:329:65 | iter | vector.cpp:330:3:330:6 | iter | |
+| vector.cpp:330:2:330:17 | ... = ... | vector.cpp:330:2:330:2 | call to operator* [post update] | |
+| vector.cpp:330:3:330:6 | iter | vector.cpp:330:2:330:2 | call to operator* | TAINT |
+| vector.cpp:330:10:330:15 | call to source | vector.cpp:330:2:330:17 | ... = ... | |
+| vector.cpp:334:22:334:24 | call to vector | vector.cpp:336:34:336:35 | v1 | |
+| vector.cpp:334:22:334:24 | call to vector | vector.cpp:338:7:338:8 | v1 | |
+| vector.cpp:334:22:334:24 | call to vector | vector.cpp:354:1:354:1 | v1 | |
+| vector.cpp:334:30:334:32 | call to vector | vector.cpp:340:38:340:39 | v2 | |
+| vector.cpp:334:30:334:32 | call to vector | vector.cpp:340:56:340:57 | v2 | |
+| vector.cpp:334:30:334:32 | call to vector | vector.cpp:343:7:343:8 | v2 | |
+| vector.cpp:334:30:334:32 | call to vector | vector.cpp:354:1:354:1 | v2 | |
+| vector.cpp:334:38:334:40 | call to vector | vector.cpp:345:15:345:16 | v3 | |
+| vector.cpp:334:38:334:40 | call to vector | vector.cpp:348:7:348:8 | v3 | |
+| vector.cpp:334:38:334:40 | call to vector | vector.cpp:354:1:354:1 | v3 | |
+| vector.cpp:334:46:334:48 | call to vector | vector.cpp:350:38:350:39 | v4 | |
+| vector.cpp:334:46:334:48 | call to vector | vector.cpp:350:56:350:57 | v4 | |
+| vector.cpp:334:46:334:48 | call to vector | vector.cpp:353:7:353:8 | v4 | |
+| vector.cpp:334:46:334:48 | call to vector | vector.cpp:354:1:354:1 | v4 | |
+| vector.cpp:336:34:336:35 | ref arg v1 | vector.cpp:338:7:338:8 | v1 | |
+| vector.cpp:336:34:336:35 | ref arg v1 | vector.cpp:354:1:354:1 | v1 | |
+| vector.cpp:336:34:336:35 | v1 | vector.cpp:336:37:336:41 | call to begin | TAINT |
+| vector.cpp:336:37:336:41 | call to begin | vector.cpp:337:3:337:4 | i1 | |
+| vector.cpp:337:2:337:15 | ... = ... | vector.cpp:337:2:337:2 | call to operator* [post update] | |
+| vector.cpp:337:3:337:4 | i1 | vector.cpp:337:2:337:2 | call to operator* | TAINT |
+| vector.cpp:337:8:337:13 | call to source | vector.cpp:337:2:337:15 | ... = ... | |
+| vector.cpp:338:7:338:8 | ref arg v1 | vector.cpp:354:1:354:1 | v1 | |
+| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:340:56:340:57 | v2 | |
+| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:343:7:343:8 | v2 | |
+| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:354:1:354:1 | v2 | |
+| vector.cpp:340:38:340:39 | v2 | vector.cpp:340:41:340:45 | call to begin | TAINT |
+| vector.cpp:340:41:340:45 | call to begin | vector.cpp:340:50:340:51 | it | |
+| vector.cpp:340:41:340:45 | call to begin | vector.cpp:340:68:340:69 | it | |
+| vector.cpp:340:41:340:45 | call to begin | vector.cpp:341:4:341:5 | it | |
+| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:340:56:340:57 | v2 | |
+| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:343:7:343:8 | v2 | |
+| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:354:1:354:1 | v2 | |
+| vector.cpp:340:56:340:57 | v2 | vector.cpp:340:59:340:61 | call to end | TAINT |
+| vector.cpp:340:68:340:69 | it | vector.cpp:340:66:340:66 | call to operator++ | TAINT |
+| vector.cpp:340:68:340:69 | ref arg it | vector.cpp:340:50:340:51 | it | |
+| vector.cpp:340:68:340:69 | ref arg it | vector.cpp:340:68:340:69 | it | |
+| vector.cpp:340:68:340:69 | ref arg it | vector.cpp:341:4:341:5 | it | |
+| vector.cpp:341:3:341:16 | ... = ... | vector.cpp:341:3:341:3 | call to operator* [post update] | |
+| vector.cpp:341:4:341:5 | it | vector.cpp:341:3:341:3 | call to operator* | TAINT |
+| vector.cpp:341:9:341:14 | call to source | vector.cpp:341:3:341:16 | ... = ... | |
+| vector.cpp:343:7:343:8 | ref arg v2 | vector.cpp:354:1:354:1 | v2 | |
+| vector.cpp:345:15:345:15 | (__begin) | vector.cpp:345:15:345:15 | call to operator* | TAINT |
+| vector.cpp:345:15:345:15 | (__begin) | vector.cpp:345:15:345:15 | call to operator++ | TAINT |
+| vector.cpp:345:15:345:15 | (__end) | vector.cpp:345:15:345:15 | call to iterator | |
+| vector.cpp:345:15:345:15 | (__range) | vector.cpp:345:15:345:15 | call to begin | TAINT |
+| vector.cpp:345:15:345:15 | (__range) | vector.cpp:345:15:345:15 | call to end | TAINT |
+| vector.cpp:345:15:345:15 | call to begin | vector.cpp:345:15:345:15 | (__begin) | |
+| vector.cpp:345:15:345:15 | call to begin | vector.cpp:345:15:345:15 | (__begin) | |
+| vector.cpp:345:15:345:15 | call to begin | vector.cpp:345:15:345:15 | (__begin) | |
+| vector.cpp:345:15:345:15 | call to end | vector.cpp:345:15:345:15 | (__end) | |
+| vector.cpp:345:15:345:15 | ref arg (__begin) | vector.cpp:345:15:345:15 | (__begin) | |
+| vector.cpp:345:15:345:15 | ref arg (__begin) | vector.cpp:345:15:345:15 | (__begin) | |
+| vector.cpp:345:15:345:15 | ref arg (__begin) | vector.cpp:345:15:345:15 | (__begin) | |
+| vector.cpp:345:15:345:15 | ref arg (__range) | vector.cpp:345:15:345:15 | (__range) | |
+| vector.cpp:345:15:345:16 | v3 | vector.cpp:345:15:345:15 | (__range) | |
+| vector.cpp:345:15:345:16 | v3 | vector.cpp:345:15:345:15 | (__range) | |
+| vector.cpp:345:15:345:16 | v3 | vector.cpp:345:15:345:15 | call to operator* | TAINT |
+| vector.cpp:346:7:346:12 | call to source | vector.cpp:346:3:346:14 | ... = ... | |
+| vector.cpp:348:7:348:8 | ref arg v3 | vector.cpp:354:1:354:1 | v3 | |
+| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:350:56:350:57 | v4 | |
+| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:353:7:353:8 | v4 | |
+| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:354:1:354:1 | v4 | |
+| vector.cpp:350:38:350:39 | v4 | vector.cpp:350:41:350:45 | call to begin | TAINT |
+| vector.cpp:350:41:350:45 | call to begin | vector.cpp:350:50:350:51 | it | |
+| vector.cpp:350:41:350:45 | call to begin | vector.cpp:350:68:350:69 | it | |
+| vector.cpp:350:41:350:45 | call to begin | vector.cpp:351:4:351:5 | it | |
+| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:350:56:350:57 | v4 | |
+| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:353:7:353:8 | v4 | |
+| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:354:1:354:1 | v4 | |
+| vector.cpp:350:56:350:57 | v4 | vector.cpp:350:59:350:61 | call to end | TAINT |
+| vector.cpp:350:68:350:69 | it | vector.cpp:350:66:350:66 | call to operator++ | TAINT |
+| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:50:350:51 | it | |
+| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:68:350:69 | it | |
+| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:351:4:351:5 | it | |
+| vector.cpp:351:3:351:16 | ... = ... | vector.cpp:351:3:351:3 | call to operator* [post update] | |
+| vector.cpp:351:4:351:5 | it | vector.cpp:351:3:351:3 | call to operator* | TAINT |
+| vector.cpp:351:9:351:14 | call to source | vector.cpp:351:3:351:16 | ... = ... | |
+| vector.cpp:353:7:353:8 | ref arg v4 | vector.cpp:354:1:354:1 | v4 | |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
index e2d12bed6c1..6360438663a 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
@@ -325,3 +325,30 @@ void test_constructors_more() {
sink(v3);
sink(v4); // tainted
}
+
+void taint_vector_output_iterator(std::vector::iterator iter) {
+ *iter = source();
+}
+
+void test_vector_output_iterator() {
+ std::vector v1(10), v2(10), v3(10), v4(10);
+
+ std::vector::iterator i1 = v1.begin();
+ *i1 = source();
+ sink(v1); // tainted [NOT DETECTED]
+
+ for(std::vector::iterator it = v2.begin(); it != v2.end(); ++it) {
+ *it = source(); // tainted [NOT DETECTED]
+ }
+ sink(v2);
+
+ for(int& x : v3) {
+ x = source();
+ }
+ sink(v3); // tainted [NOT DETECTED]
+
+ for(std::vector::iterator it = v4.begin(); it != v4.end(); ++it) {
+ *it = source();
+ }
+ sink(v4); // tainted [NOT DETECTED]
+}
From 703db0b9a6ffdb53af4cef150cf1ae6f10ca4517 Mon Sep 17 00:00:00 2001
From: Robert Marsh
Date: Tue, 25 Aug 2020 15:26:18 -0700
Subject: [PATCH 002/411] C++: noisy output iterators in AST taint tracking
---
.../dataflow/internal/TaintTrackingUtil.qll | 31 +++++++++++++++++++
.../cpp/models/implementations/Iterator.qll | 12 +++++++
.../dataflow/taint-tests/localTaint.expected | 11 +++++++
.../dataflow/taint-tests/taint.expected | 3 ++
.../dataflow/taint-tests/test_diff.expected | 3 ++
.../dataflow/taint-tests/vector.cpp | 10 +++---
6 files changed, 65 insertions(+), 5 deletions(-)
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll
index a3f0c435e16..c15f39c0c15 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll
@@ -10,6 +10,7 @@
private import semmle.code.cpp.models.interfaces.DataFlow
private import semmle.code.cpp.models.interfaces.Taint
+private import semmle.code.cpp.models.implementations.Iterator
private module DataFlow {
import semmle.code.cpp.dataflow.internal.DataFlowUtil
@@ -186,6 +187,12 @@ private predicate exprToExprStep(Expr exprIn, Expr exprOut) {
exprIn = call.getQualifier()
)
)
+ or
+ exists(Variable iterator, Variable collection |
+ assignmentViaIterator(iterator, exprIn) and
+ isIteratorForCollection(iterator, collection) and
+ collection.getAnAccess() = exprOut
+ )
}
private predicate exprToDefinitionByReferenceStep(Expr exprIn, Expr argOut) {
@@ -249,3 +256,27 @@ private predicate exprToPartialDefinitionStep(Expr exprIn, Expr exprOut) {
)
)
}
+
+private predicate isIteratorForCollection(Variable iterator, Variable collection) {
+ exists(Call beginOrEnd |
+ beginOrEnd.getTarget() instanceof BeginOrEndFunction and
+ beginOrEnd.getQualifier() = collection.getAnAccess() and
+ iterator.getAnAssignedValue() = beginOrEnd
+ )
+}
+
+private predicate assignmentViaIterator(Variable iterator, Expr rvalue) {
+ exists(Assignment a, Call c |
+ c.getTarget() instanceof IteratorArrayMemberOperator and
+ c.getQualifier() = iterator.getAnAccess()
+ or
+ c.getTarget() instanceof IteratorPointerDereferenceMemberOperator and
+ c.getQualifier() = iterator.getAnAccess()
+ or
+ c.getTarget() instanceof IteratorPointerDereferenceOperator and
+ c.getArgument(0) = iterator.getAnAccess()
+ |
+ c = a.getLValue() and
+ rvalue = a.getRValue()
+ )
+}
diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll
index 2ad464d1634..758d093bedc 100644
--- a/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll
+++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll
@@ -271,3 +271,15 @@ class IteratorArrayMemberOperator extends MemberFunction, TaintFunction {
output.isReturnValue()
}
}
+
+class BeginOrEndFunction extends MemberFunction, TaintFunction {
+ BeginOrEndFunction() {
+ this.hasName(["begin", "cbegin", "rbegin", "crbegin", "end", "cend", "rend", "crend"]) and
+ this.getType().getUnspecifiedType() instanceof Iterator
+ }
+
+ override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
+ input.isQualifierObject() and
+ output.isReturnValue()
+ }
+}
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
index bca6b6299ad..0c0362206e1 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
@@ -3197,7 +3197,10 @@
| vector.cpp:336:37:336:41 | call to begin | vector.cpp:337:3:337:4 | i1 | |
| vector.cpp:337:2:337:15 | ... = ... | vector.cpp:337:2:337:2 | call to operator* [post update] | |
| vector.cpp:337:3:337:4 | i1 | vector.cpp:337:2:337:2 | call to operator* | TAINT |
+| vector.cpp:337:8:337:13 | call to source | vector.cpp:336:34:336:35 | v1 | TAINT |
| vector.cpp:337:8:337:13 | call to source | vector.cpp:337:2:337:15 | ... = ... | |
+| vector.cpp:337:8:337:13 | call to source | vector.cpp:338:7:338:8 | v1 | TAINT |
+| vector.cpp:337:8:337:13 | call to source | vector.cpp:354:1:354:1 | v1 | TAINT |
| vector.cpp:338:7:338:8 | ref arg v1 | vector.cpp:354:1:354:1 | v1 | |
| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:340:56:340:57 | v2 | |
| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:343:7:343:8 | v2 | |
@@ -3216,7 +3219,11 @@
| vector.cpp:340:68:340:69 | ref arg it | vector.cpp:341:4:341:5 | it | |
| vector.cpp:341:3:341:16 | ... = ... | vector.cpp:341:3:341:3 | call to operator* [post update] | |
| vector.cpp:341:4:341:5 | it | vector.cpp:341:3:341:3 | call to operator* | TAINT |
+| vector.cpp:341:9:341:14 | call to source | vector.cpp:340:38:340:39 | v2 | TAINT |
+| vector.cpp:341:9:341:14 | call to source | vector.cpp:340:56:340:57 | v2 | TAINT |
| vector.cpp:341:9:341:14 | call to source | vector.cpp:341:3:341:16 | ... = ... | |
+| vector.cpp:341:9:341:14 | call to source | vector.cpp:343:7:343:8 | v2 | TAINT |
+| vector.cpp:341:9:341:14 | call to source | vector.cpp:354:1:354:1 | v2 | TAINT |
| vector.cpp:343:7:343:8 | ref arg v2 | vector.cpp:354:1:354:1 | v2 | |
| vector.cpp:345:15:345:15 | (__begin) | vector.cpp:345:15:345:15 | call to operator* | TAINT |
| vector.cpp:345:15:345:15 | (__begin) | vector.cpp:345:15:345:15 | call to operator++ | TAINT |
@@ -3253,5 +3260,9 @@
| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:351:4:351:5 | it | |
| vector.cpp:351:3:351:16 | ... = ... | vector.cpp:351:3:351:3 | call to operator* [post update] | |
| vector.cpp:351:4:351:5 | it | vector.cpp:351:3:351:3 | call to operator* | TAINT |
+| vector.cpp:351:9:351:14 | call to source | vector.cpp:350:38:350:39 | v4 | TAINT |
+| vector.cpp:351:9:351:14 | call to source | vector.cpp:350:56:350:57 | v4 | TAINT |
| vector.cpp:351:9:351:14 | call to source | vector.cpp:351:3:351:16 | ... = ... | |
+| vector.cpp:351:9:351:14 | call to source | vector.cpp:353:7:353:8 | v4 | TAINT |
+| vector.cpp:351:9:351:14 | call to source | vector.cpp:354:1:354:1 | v4 | TAINT |
| vector.cpp:353:7:353:8 | ref arg v4 | vector.cpp:354:1:354:1 | v4 | |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
index 15744c35716..6697e57e4a3 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
@@ -326,3 +326,6 @@
| vector.cpp:312:7:312:7 | d | vector.cpp:303:14:303:19 | call to source |
| vector.cpp:324:7:324:8 | v2 | vector.cpp:318:15:318:20 | call to source |
| vector.cpp:326:7:326:8 | v4 | vector.cpp:318:15:318:20 | call to source |
+| vector.cpp:338:7:338:8 | v1 | vector.cpp:337:8:337:13 | call to source |
+| vector.cpp:343:7:343:8 | v2 | vector.cpp:341:9:341:14 | call to source |
+| vector.cpp:353:7:353:8 | v4 | vector.cpp:351:9:351:14 | call to source |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected
index d4383d4e900..7533d079093 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected
@@ -275,3 +275,6 @@
| vector.cpp:312:7:312:7 | vector.cpp:303:14:303:19 | AST only |
| vector.cpp:324:7:324:8 | vector.cpp:318:15:318:20 | AST only |
| vector.cpp:326:7:326:8 | vector.cpp:318:15:318:20 | AST only |
+| vector.cpp:338:7:338:8 | vector.cpp:337:8:337:13 | AST only |
+| vector.cpp:343:7:343:8 | vector.cpp:341:9:341:14 | AST only |
+| vector.cpp:353:7:353:8 | vector.cpp:351:9:351:14 | AST only |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
index 6360438663a..f1cf4e91457 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
@@ -21,7 +21,7 @@ void test_range_based_for_loop_vector(int source1) {
}
for(std::vector::iterator it = v.begin(); it != v.end(); ++it) {
- sink(*it); // tainted
+ sink(*it); // tainted [NOT DETECTED by IR]
}
for(int& x : v) {
@@ -335,12 +335,12 @@ void test_vector_output_iterator() {
std::vector::iterator i1 = v1.begin();
*i1 = source();
- sink(v1); // tainted [NOT DETECTED]
+ sink(v1); // tainted [NOT DETECTED by IR]
for(std::vector::iterator it = v2.begin(); it != v2.end(); ++it) {
- *it = source(); // tainted [NOT DETECTED]
+ *it = source();
}
- sink(v2);
+ sink(v2); // tainted [NOT DETECTED by IR]
for(int& x : v3) {
x = source();
@@ -350,5 +350,5 @@ void test_vector_output_iterator() {
for(std::vector::iterator it = v4.begin(); it != v4.end(); ++it) {
*it = source();
}
- sink(v4); // tainted [NOT DETECTED]
+ sink(v4); // tainted [NOT DETECTED by IR]
}
From c8cdf68bf9b8881faae02f89ca3cb5091ec1c926 Mon Sep 17 00:00:00 2001
From: Robert Marsh
Date: Tue, 25 Aug 2020 16:34:36 -0700
Subject: [PATCH 003/411] C++: Remove StdStringBeginEnd
---
.../cpp/models/implementations/Iterator.qll | 4 ++++
.../cpp/models/implementations/StdString.qll | 17 -----------------
2 files changed, 4 insertions(+), 17 deletions(-)
diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll
index 758d093bedc..93a04d5ef90 100644
--- a/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll
+++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll
@@ -272,6 +272,10 @@ class IteratorArrayMemberOperator extends MemberFunction, TaintFunction {
}
}
+/**
+ * A `begin` or `end` member function, or a related member function, that
+ * returns an iterator.
+ */
class BeginOrEndFunction extends MemberFunction, TaintFunction {
BeginOrEndFunction() {
this.hasName(["begin", "cbegin", "rbegin", "crbegin", "end", "cend", "rend", "crend"]) and
diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/StdString.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/StdString.qll
index 8e7cb24be73..3a2c914eb4c 100644
--- a/cpp/ql/src/semmle/code/cpp/models/implementations/StdString.qll
+++ b/cpp/ql/src/semmle/code/cpp/models/implementations/StdString.qll
@@ -212,23 +212,6 @@ class StdStringAssign extends TaintFunction {
}
}
-/**
- * The standard functions `std::string.begin` and `std::string.end` and their
- * variants.
- */
-class StdStringBeginEnd extends TaintFunction {
- StdStringBeginEnd() {
- this
- .hasQualifiedName("std", "basic_string",
- ["begin", "cbegin", "rbegin", "crbegin", "end", "cend", "rend", "crend"])
- }
-
- override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
- input.isQualifierObject() and
- output.isReturnValue()
- }
-}
-
/**
* The standard function `std::string.copy`.
*/
From 13c45b6664a6b4fcad59a60a096236cb702d21b0 Mon Sep 17 00:00:00 2001
From: Robert Marsh
Date: Thu, 27 Aug 2020 15:09:01 -0700
Subject: [PATCH 004/411] C++: remove unnecessary parameter in FlowVar.qll
---
.../code/cpp/dataflow/internal/FlowVar.qll | 25 ++++++++-----------
1 file changed, 11 insertions(+), 14 deletions(-)
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
index 6dc5da2f20b..83941140fa6 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
@@ -240,7 +240,7 @@ module FlowVar_internal {
(
initializer(v, sbb.getANode())
or
- assignmentLikeOperation(sbb, v, _, _)
+ assignmentLikeOperation(sbb, v, _)
or
exists(PartialDefinition p | p.partiallyDefinesVariableAt(v, sbb))
or
@@ -359,7 +359,7 @@ module FlowVar_internal {
}
override predicate definedByExpr(Expr e, ControlFlowNode node) {
- assignmentLikeOperation(node, v, _, e) and
+ assignmentLikeOperation(node, v, e) and
node = sbb
or
// We pick the defining `ControlFlowNode` of an `Initializer` to be its
@@ -449,7 +449,7 @@ module FlowVar_internal {
pragma[noinline]
private Variable getAVariableAssignedInLoop() {
exists(BasicBlock bbAssign |
- assignmentLikeOperation(bbAssign.getANode(), result, _, _) and
+ assignmentLikeOperation(bbAssign.getANode(), result, _) and
this.bbInLoop(bbAssign)
)
}
@@ -487,7 +487,7 @@ module FlowVar_internal {
pragma[noinline]
private predicate assignsToVar(BasicBlock bb, Variable v) {
- assignmentLikeOperation(bb.getANode(), v, _, _) and
+ assignmentLikeOperation(bb.getANode(), v, _) and
exists(AlwaysTrueUponEntryLoop loop | v = loop.getARelevantVariable())
}
@@ -524,7 +524,7 @@ module FlowVar_internal {
result = mid.getASuccessor() and
variableLiveInSBB(result, v) and
forall(AlwaysTrueUponEntryLoop loop | skipLoop(mid, result, v, loop) | loop.sbbInLoop(sbbDef)) and
- not assignmentLikeOperation(result, v, _, _)
+ not assignmentLikeOperation(result, v, _)
)
}
@@ -566,7 +566,7 @@ module FlowVar_internal {
* Holds if liveness of `v` should stop propagating backwards from `sbb`.
*/
private predicate variableNotLiveBefore(SubBasicBlock sbb, Variable v) {
- assignmentLikeOperation(sbb, v, _, _)
+ assignmentLikeOperation(sbb, v, _)
or
// Liveness of `v` is killed when going backwards from a block that declares it
exists(DeclStmt ds | ds.getADeclaration().(LocalVariable) = v and sbb.contains(ds))
@@ -687,20 +687,18 @@ module FlowVar_internal {
* predicate.
*/
predicate assignmentLikeOperation(
- ControlFlowNode node, Variable v, VariableAccess va, Expr assignedExpr
+ ControlFlowNode node, Variable v, Expr assignedExpr
) {
// Together, the two following cases cover `Assignment`
node =
any(AssignExpr ae |
- va = ae.getLValue() and
- v = va.getTarget() and
+ v.getAnAccess() = ae.getLValue() and
assignedExpr = ae.getRValue()
)
or
node =
any(AssignOperation ao |
- va = ao.getLValue() and
- v = va.getTarget() and
+ v.getAnAccess() = ao.getLValue() and
// Here and in the `PrefixCrementOperation` case, we say that the assigned
// expression is the operation itself. For example, we say that `x += 1`
// assigns `x += 1` to `x`. The justification is that after this operation,
@@ -712,8 +710,7 @@ module FlowVar_internal {
// `PrefixCrementOperation` is itself a source
node =
any(CrementOperation op |
- va = op.getOperand() and
- v = va.getTarget() and
+ v.getAnAccess() = op.getOperand() and
assignedExpr = op
)
}
@@ -749,7 +746,7 @@ module FlowVar_internal {
class DataFlowSubBasicBlockCutNode extends SubBasicBlockCutNode {
DataFlowSubBasicBlockCutNode() {
exists(Variable v | not fullySupportedSsaVariable(v) |
- assignmentLikeOperation(this, v, _, _)
+ assignmentLikeOperation(this, v, _)
or
exists(PartialDefinition p | p.partiallyDefinesVariableAt(v, this))
// It is not necessary to cut the basic blocks at `Initializer` nodes
From eab1557e27cfefef7b826960e3840e5ba79279e1 Mon Sep 17 00:00:00 2001
From: Robert Marsh
Date: Tue, 8 Sep 2020 14:09:57 -0700
Subject: [PATCH 005/411] C++: output iterator flow via FlowVar
---
.../cpp/dataflow/internal/DataFlowUtil.qll | 20 ++-
.../code/cpp/dataflow/internal/FlowVar.qll | 98 +++++++++--
.../dataflow/internal/TaintTrackingUtil.qll | 34 +---
.../dataflow/taint-tests/localTaint.expected | 160 +++++++++++++++---
.../dataflow/taint-tests/taint.expected | 8 +
.../dataflow/taint-tests/test_diff.expected | 8 +
.../dataflow/taint-tests/vector.cpp | 32 +++-
7 files changed, 287 insertions(+), 73 deletions(-)
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
index 6647dda4072..9705ca492ce 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
@@ -283,12 +283,12 @@ abstract class PostUpdateNode extends Node {
override Location getLocation() { result = getPreUpdateNode().getLocation() }
}
-private class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNode {
+private abstract class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNode {
PartialDefinition pd;
- PartialDefinitionNode() { this = TPartialDefinitionNode(pd) }
-
- override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) }
+ PartialDefinitionNode() {
+ this = TPartialDefinitionNode(pd)
+ }
override Location getLocation() { result = pd.getActualLocation() }
@@ -297,6 +297,18 @@ private class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNo
override string toString() { result = getPreUpdateNode().toString() + " [post update]" }
}
+private class VariablePartialDefinitionNode extends PartialDefinitionNode {
+ override VariablePartialDefinition pd;
+
+ override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) }
+}
+
+private class IteratorPartialDefinitionNode extends PartialDefinitionNode {
+ override IteratorPartialDefinition pd;
+
+ override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) }
+}
+
/**
* A post-update node on the `e->f` in `f(&e->f)` (and other forms).
*/
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
index 83941140fa6..cb2cdd68f08 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
@@ -6,6 +6,7 @@ import cpp
private import semmle.code.cpp.controlflow.SSA
private import semmle.code.cpp.dataflow.internal.SubBasicBlocks
private import semmle.code.cpp.dataflow.internal.AddressFlow
+private import semmle.code.cpp.models.implementations.Iterator
/**
* A conceptual variable that is assigned only once, like an SSA variable. This
@@ -109,20 +110,16 @@ class FlowVar extends TFlowVar {
*/
private module PartialDefinitions {
class PartialDefinition extends Expr {
- Expr innerDefinedExpr;
ControlFlowNode node;
PartialDefinition() {
- exists(Expr convertedInner |
- valueToUpdate(convertedInner, this.getFullyConverted(), node) and
- innerDefinedExpr = convertedInner.getUnconverted() and
- not this instanceof Conversion
- )
+ valueToUpdate(_, this.getFullyConverted(), node) and
+ not this instanceof Conversion
}
- deprecated predicate partiallyDefines(Variable v) { innerDefinedExpr = v.getAnAccess() }
+ deprecated predicate partiallyDefines(Variable v) { none() }
- deprecated predicate partiallyDefinesThis(ThisExpr e) { innerDefinedExpr = e }
+ deprecated predicate partiallyDefinesThis(ThisExpr e) { none() }
/**
* Gets the subBasicBlock where this `PartialDefinition` is defined.
@@ -133,10 +130,9 @@ private module PartialDefinitions {
* Holds if this `PartialDefinition` defines variable `v` at control-flow
* node `cfn`.
*/
- pragma[noinline]
+ pragma[noinline] // does this work with a dispred?
predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) {
- innerDefinedExpr = v.getAnAccess() and
- cfn = node
+ none()
}
/**
@@ -147,10 +143,7 @@ private module PartialDefinitions {
* - `inner` = `... .x`, `outer` = `&...`
* - `inner` = `a`, `outer` = `*`
*/
- predicate definesExpressions(Expr inner, Expr outer) {
- inner = innerDefinedExpr and
- outer = this
- }
+ predicate definesExpressions(Expr inner, Expr outer) { none() }
/**
* Gets the location of this element, adjusted to avoid unknown locations
@@ -166,6 +159,68 @@ private module PartialDefinitions {
}
}
+ class IteratorPartialDefinition extends PartialDefinition {
+ Variable collection;
+ Call innerDefinedExpr;
+
+ IteratorPartialDefinition() {
+ exists(Expr convertedInner |
+ valueToUpdate(convertedInner, this.getFullyConverted(), node) and
+ innerDefinedExpr = convertedInner.getUnconverted() and
+ innerDefinedExpr.getQualifier() = getAnIteratorAccess(collection) and
+ innerDefinedExpr.getTarget() instanceof IteratorPointerDereferenceMemberOperator
+ )
+ }
+
+ deprecated override predicate partiallyDefines(Variable v) { v = collection }
+
+ deprecated override predicate partiallyDefinesThis(ThisExpr e) { none() }
+
+ override predicate definesExpressions(Expr inner, Expr outer) {
+ inner = innerDefinedExpr and
+ outer = this
+ }
+
+ override predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) {
+ v = collection and
+ cfn = node
+ }
+ }
+
+ class VariablePartialDefinition extends PartialDefinition {
+ Expr innerDefinedExpr;
+
+ VariablePartialDefinition() {
+ exists(Expr convertedInner |
+ valueToUpdate(convertedInner, this.getFullyConverted(), node) and
+ innerDefinedExpr = convertedInner.getUnconverted() and
+ not this instanceof Conversion
+ )
+ }
+
+ deprecated override predicate partiallyDefines(Variable v) { innerDefinedExpr = v.getAnAccess() }
+
+ deprecated override predicate partiallyDefinesThis(ThisExpr e) { innerDefinedExpr = e }
+
+ /**
+ * Holds if this partial definition may modify `inner` (or what it points
+ * to) through `outer`. These expressions will never be `Conversion`s.
+ *
+ * For example, in `f(& (*a).x)`, there are two results:
+ * - `inner` = `... .x`, `outer` = `&...`
+ * - `inner` = `a`, `outer` = `*`
+ */
+ override predicate definesExpressions(Expr inner, Expr outer) {
+ inner = innerDefinedExpr and
+ outer = this
+ }
+
+ override predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) {
+ innerDefinedExpr = v.getAnAccess() and
+ cfn = node
+ }
+ }
+
/**
* A partial definition that's a definition by reference.
*/
@@ -686,9 +741,7 @@ module FlowVar_internal {
* `node instanceof Initializer` is covered by `initializer` instead of this
* predicate.
*/
- predicate assignmentLikeOperation(
- ControlFlowNode node, Variable v, Expr assignedExpr
- ) {
+ predicate assignmentLikeOperation(ControlFlowNode node, Variable v, Expr assignedExpr) {
// Together, the two following cases cover `Assignment`
node =
any(AssignExpr ae |
@@ -715,6 +768,15 @@ module FlowVar_internal {
)
}
+ Expr getAnIteratorAccess(Variable collection) {
+ exists(Call c, SsaDefinition def, Variable iterator |
+ c.getQualifier() = collection.getAnAccess() and
+ c.getTarget() instanceof BeginOrEndFunction and
+ def.getAnUltimateDefiningValue(iterator) = c and
+ result = def.getAUse(iterator)
+ )
+ }
+
/**
* Holds if `v` is initialized to have value `assignedExpr`.
*/
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll
index c15f39c0c15..c8d963866a1 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll
@@ -187,12 +187,6 @@ private predicate exprToExprStep(Expr exprIn, Expr exprOut) {
exprIn = call.getQualifier()
)
)
- or
- exists(Variable iterator, Variable collection |
- assignmentViaIterator(iterator, exprIn) and
- isIteratorForCollection(iterator, collection) and
- collection.getAnAccess() = exprOut
- )
}
private predicate exprToDefinitionByReferenceStep(Expr exprIn, Expr argOut) {
@@ -255,28 +249,18 @@ private predicate exprToPartialDefinitionStep(Expr exprIn, Expr exprOut) {
exprIn = call.getArgument(argInIndex)
)
)
-}
-
-private predicate isIteratorForCollection(Variable iterator, Variable collection) {
- exists(Call beginOrEnd |
- beginOrEnd.getTarget() instanceof BeginOrEndFunction and
- beginOrEnd.getQualifier() = collection.getAnAccess() and
- iterator.getAnAssignedValue() = beginOrEnd
+ or
+ exists(Assignment a |
+ iteratorDereference(exprOut) and
+ a.getLValue() = exprOut and
+ a.getRValue() = exprIn
)
}
-private predicate assignmentViaIterator(Variable iterator, Expr rvalue) {
- exists(Assignment a, Call c |
- c.getTarget() instanceof IteratorArrayMemberOperator and
- c.getQualifier() = iterator.getAnAccess()
+private predicate iteratorDereference(Call c) {
+ c.getTarget() instanceof IteratorArrayMemberOperator
or
- c.getTarget() instanceof IteratorPointerDereferenceMemberOperator and
- c.getQualifier() = iterator.getAnAccess()
+ c.getTarget() instanceof IteratorPointerDereferenceMemberOperator
or
- c.getTarget() instanceof IteratorPointerDereferenceOperator and
- c.getArgument(0) = iterator.getAnAccess()
- |
- c = a.getLValue() and
- rvalue = a.getRValue()
- )
+ c.getTarget() instanceof IteratorPointerDereferenceOperator
}
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
index 0c0362206e1..c0f34638554 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
@@ -3176,55 +3176,75 @@
| vector.cpp:329:62:329:65 | iter | vector.cpp:330:3:330:6 | iter | |
| vector.cpp:330:2:330:17 | ... = ... | vector.cpp:330:2:330:2 | call to operator* [post update] | |
| vector.cpp:330:3:330:6 | iter | vector.cpp:330:2:330:2 | call to operator* | TAINT |
+| vector.cpp:330:10:330:15 | call to source | vector.cpp:330:2:330:2 | call to operator* [post update] | TAINT |
| vector.cpp:330:10:330:15 | call to source | vector.cpp:330:2:330:17 | ... = ... | |
+| vector.cpp:333:38:333:38 | b | vector.cpp:368:5:368:5 | b | |
| vector.cpp:334:22:334:24 | call to vector | vector.cpp:336:34:336:35 | v1 | |
| vector.cpp:334:22:334:24 | call to vector | vector.cpp:338:7:338:8 | v1 | |
-| vector.cpp:334:22:334:24 | call to vector | vector.cpp:354:1:354:1 | v1 | |
+| vector.cpp:334:22:334:24 | call to vector | vector.cpp:382:1:382:1 | v1 | |
| vector.cpp:334:30:334:32 | call to vector | vector.cpp:340:38:340:39 | v2 | |
| vector.cpp:334:30:334:32 | call to vector | vector.cpp:340:56:340:57 | v2 | |
| vector.cpp:334:30:334:32 | call to vector | vector.cpp:343:7:343:8 | v2 | |
-| vector.cpp:334:30:334:32 | call to vector | vector.cpp:354:1:354:1 | v2 | |
+| vector.cpp:334:30:334:32 | call to vector | vector.cpp:382:1:382:1 | v2 | |
| vector.cpp:334:38:334:40 | call to vector | vector.cpp:345:15:345:16 | v3 | |
| vector.cpp:334:38:334:40 | call to vector | vector.cpp:348:7:348:8 | v3 | |
-| vector.cpp:334:38:334:40 | call to vector | vector.cpp:354:1:354:1 | v3 | |
+| vector.cpp:334:38:334:40 | call to vector | vector.cpp:382:1:382:1 | v3 | |
| vector.cpp:334:46:334:48 | call to vector | vector.cpp:350:38:350:39 | v4 | |
| vector.cpp:334:46:334:48 | call to vector | vector.cpp:350:56:350:57 | v4 | |
| vector.cpp:334:46:334:48 | call to vector | vector.cpp:353:7:353:8 | v4 | |
-| vector.cpp:334:46:334:48 | call to vector | vector.cpp:354:1:354:1 | v4 | |
+| vector.cpp:334:46:334:48 | call to vector | vector.cpp:382:1:382:1 | v4 | |
+| vector.cpp:334:54:334:56 | call to vector | vector.cpp:355:34:355:35 | v5 | |
+| vector.cpp:334:54:334:56 | call to vector | vector.cpp:357:7:357:8 | v5 | |
+| vector.cpp:334:54:334:56 | call to vector | vector.cpp:359:7:359:8 | v5 | |
+| vector.cpp:334:54:334:56 | call to vector | vector.cpp:382:1:382:1 | v5 | |
+| vector.cpp:334:62:334:64 | call to vector | vector.cpp:361:34:361:35 | v6 | |
+| vector.cpp:334:62:334:64 | call to vector | vector.cpp:363:7:363:8 | v6 | |
+| vector.cpp:334:62:334:64 | call to vector | vector.cpp:364:2:364:3 | v6 | |
+| vector.cpp:334:62:334:64 | call to vector | vector.cpp:365:7:365:8 | v6 | |
+| vector.cpp:334:62:334:64 | call to vector | vector.cpp:382:1:382:1 | v6 | |
+| vector.cpp:334:70:334:72 | call to vector | vector.cpp:367:34:367:35 | v7 | |
+| vector.cpp:334:70:334:72 | call to vector | vector.cpp:370:8:370:9 | v7 | |
+| vector.cpp:334:70:334:72 | call to vector | vector.cpp:373:8:373:9 | v7 | |
+| vector.cpp:334:70:334:72 | call to vector | vector.cpp:375:7:375:8 | v7 | |
+| vector.cpp:334:70:334:72 | call to vector | vector.cpp:382:1:382:1 | v7 | |
+| vector.cpp:334:78:334:80 | call to vector | vector.cpp:377:34:377:35 | v8 | |
+| vector.cpp:334:78:334:80 | call to vector | vector.cpp:379:7:379:8 | v8 | |
+| vector.cpp:334:78:334:80 | call to vector | vector.cpp:381:7:381:8 | v8 | |
+| vector.cpp:334:78:334:80 | call to vector | vector.cpp:382:1:382:1 | v8 | |
| vector.cpp:336:34:336:35 | ref arg v1 | vector.cpp:338:7:338:8 | v1 | |
-| vector.cpp:336:34:336:35 | ref arg v1 | vector.cpp:354:1:354:1 | v1 | |
+| vector.cpp:336:34:336:35 | ref arg v1 | vector.cpp:382:1:382:1 | v1 | |
| vector.cpp:336:34:336:35 | v1 | vector.cpp:336:37:336:41 | call to begin | TAINT |
| vector.cpp:336:37:336:41 | call to begin | vector.cpp:337:3:337:4 | i1 | |
+| vector.cpp:337:2:337:2 | call to operator* [post update] | vector.cpp:338:7:338:8 | v1 | |
+| vector.cpp:337:2:337:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v1 | |
| vector.cpp:337:2:337:15 | ... = ... | vector.cpp:337:2:337:2 | call to operator* [post update] | |
| vector.cpp:337:3:337:4 | i1 | vector.cpp:337:2:337:2 | call to operator* | TAINT |
-| vector.cpp:337:8:337:13 | call to source | vector.cpp:336:34:336:35 | v1 | TAINT |
+| vector.cpp:337:8:337:13 | call to source | vector.cpp:337:2:337:2 | call to operator* [post update] | TAINT |
| vector.cpp:337:8:337:13 | call to source | vector.cpp:337:2:337:15 | ... = ... | |
-| vector.cpp:337:8:337:13 | call to source | vector.cpp:338:7:338:8 | v1 | TAINT |
-| vector.cpp:337:8:337:13 | call to source | vector.cpp:354:1:354:1 | v1 | TAINT |
-| vector.cpp:338:7:338:8 | ref arg v1 | vector.cpp:354:1:354:1 | v1 | |
+| vector.cpp:338:7:338:8 | ref arg v1 | vector.cpp:382:1:382:1 | v1 | |
| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:340:56:340:57 | v2 | |
| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:343:7:343:8 | v2 | |
-| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:354:1:354:1 | v2 | |
+| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:382:1:382:1 | v2 | |
| vector.cpp:340:38:340:39 | v2 | vector.cpp:340:41:340:45 | call to begin | TAINT |
| vector.cpp:340:41:340:45 | call to begin | vector.cpp:340:50:340:51 | it | |
| vector.cpp:340:41:340:45 | call to begin | vector.cpp:340:68:340:69 | it | |
| vector.cpp:340:41:340:45 | call to begin | vector.cpp:341:4:341:5 | it | |
| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:340:56:340:57 | v2 | |
| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:343:7:343:8 | v2 | |
-| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:354:1:354:1 | v2 | |
+| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:382:1:382:1 | v2 | |
| vector.cpp:340:56:340:57 | v2 | vector.cpp:340:59:340:61 | call to end | TAINT |
| vector.cpp:340:68:340:69 | it | vector.cpp:340:66:340:66 | call to operator++ | TAINT |
| vector.cpp:340:68:340:69 | ref arg it | vector.cpp:340:50:340:51 | it | |
| vector.cpp:340:68:340:69 | ref arg it | vector.cpp:340:68:340:69 | it | |
| vector.cpp:340:68:340:69 | ref arg it | vector.cpp:341:4:341:5 | it | |
+| vector.cpp:341:3:341:3 | call to operator* [post update] | vector.cpp:340:56:340:57 | v2 | |
+| vector.cpp:341:3:341:3 | call to operator* [post update] | vector.cpp:343:7:343:8 | v2 | |
+| vector.cpp:341:3:341:3 | call to operator* [post update] | vector.cpp:382:1:382:1 | v2 | |
| vector.cpp:341:3:341:16 | ... = ... | vector.cpp:341:3:341:3 | call to operator* [post update] | |
| vector.cpp:341:4:341:5 | it | vector.cpp:341:3:341:3 | call to operator* | TAINT |
-| vector.cpp:341:9:341:14 | call to source | vector.cpp:340:38:340:39 | v2 | TAINT |
-| vector.cpp:341:9:341:14 | call to source | vector.cpp:340:56:340:57 | v2 | TAINT |
+| vector.cpp:341:9:341:14 | call to source | vector.cpp:341:3:341:3 | call to operator* [post update] | TAINT |
| vector.cpp:341:9:341:14 | call to source | vector.cpp:341:3:341:16 | ... = ... | |
-| vector.cpp:341:9:341:14 | call to source | vector.cpp:343:7:343:8 | v2 | TAINT |
-| vector.cpp:341:9:341:14 | call to source | vector.cpp:354:1:354:1 | v2 | TAINT |
-| vector.cpp:343:7:343:8 | ref arg v2 | vector.cpp:354:1:354:1 | v2 | |
+| vector.cpp:343:7:343:8 | ref arg v2 | vector.cpp:382:1:382:1 | v2 | |
| vector.cpp:345:15:345:15 | (__begin) | vector.cpp:345:15:345:15 | call to operator* | TAINT |
| vector.cpp:345:15:345:15 | (__begin) | vector.cpp:345:15:345:15 | call to operator++ | TAINT |
| vector.cpp:345:15:345:15 | (__end) | vector.cpp:345:15:345:15 | call to iterator | |
@@ -3242,27 +3262,119 @@
| vector.cpp:345:15:345:16 | v3 | vector.cpp:345:15:345:15 | (__range) | |
| vector.cpp:345:15:345:16 | v3 | vector.cpp:345:15:345:15 | call to operator* | TAINT |
| vector.cpp:346:7:346:12 | call to source | vector.cpp:346:3:346:14 | ... = ... | |
-| vector.cpp:348:7:348:8 | ref arg v3 | vector.cpp:354:1:354:1 | v3 | |
+| vector.cpp:348:7:348:8 | ref arg v3 | vector.cpp:382:1:382:1 | v3 | |
| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:350:56:350:57 | v4 | |
| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:353:7:353:8 | v4 | |
-| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:354:1:354:1 | v4 | |
+| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:382:1:382:1 | v4 | |
| vector.cpp:350:38:350:39 | v4 | vector.cpp:350:41:350:45 | call to begin | TAINT |
| vector.cpp:350:41:350:45 | call to begin | vector.cpp:350:50:350:51 | it | |
| vector.cpp:350:41:350:45 | call to begin | vector.cpp:350:68:350:69 | it | |
| vector.cpp:350:41:350:45 | call to begin | vector.cpp:351:4:351:5 | it | |
| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:350:56:350:57 | v4 | |
| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:353:7:353:8 | v4 | |
-| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:354:1:354:1 | v4 | |
+| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:382:1:382:1 | v4 | |
| vector.cpp:350:56:350:57 | v4 | vector.cpp:350:59:350:61 | call to end | TAINT |
| vector.cpp:350:68:350:69 | it | vector.cpp:350:66:350:66 | call to operator++ | TAINT |
| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:50:350:51 | it | |
| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:68:350:69 | it | |
| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:351:4:351:5 | it | |
+| vector.cpp:351:3:351:3 | call to operator* [post update] | vector.cpp:350:56:350:57 | v4 | |
+| vector.cpp:351:3:351:3 | call to operator* [post update] | vector.cpp:353:7:353:8 | v4 | |
+| vector.cpp:351:3:351:3 | call to operator* [post update] | vector.cpp:382:1:382:1 | v4 | |
| vector.cpp:351:3:351:16 | ... = ... | vector.cpp:351:3:351:3 | call to operator* [post update] | |
| vector.cpp:351:4:351:5 | it | vector.cpp:351:3:351:3 | call to operator* | TAINT |
-| vector.cpp:351:9:351:14 | call to source | vector.cpp:350:38:350:39 | v4 | TAINT |
-| vector.cpp:351:9:351:14 | call to source | vector.cpp:350:56:350:57 | v4 | TAINT |
+| vector.cpp:351:9:351:14 | call to source | vector.cpp:351:3:351:3 | call to operator* [post update] | TAINT |
| vector.cpp:351:9:351:14 | call to source | vector.cpp:351:3:351:16 | ... = ... | |
-| vector.cpp:351:9:351:14 | call to source | vector.cpp:353:7:353:8 | v4 | TAINT |
-| vector.cpp:351:9:351:14 | call to source | vector.cpp:354:1:354:1 | v4 | TAINT |
-| vector.cpp:353:7:353:8 | ref arg v4 | vector.cpp:354:1:354:1 | v4 | |
+| vector.cpp:353:7:353:8 | ref arg v4 | vector.cpp:382:1:382:1 | v4 | |
+| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:357:7:357:8 | v5 | |
+| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:359:7:359:8 | v5 | |
+| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:382:1:382:1 | v5 | |
+| vector.cpp:355:34:355:35 | v5 | vector.cpp:355:37:355:41 | call to begin | TAINT |
+| vector.cpp:355:37:355:41 | call to begin | vector.cpp:356:3:356:4 | i5 | |
+| vector.cpp:355:37:355:41 | call to begin | vector.cpp:358:3:358:4 | i5 | |
+| vector.cpp:356:2:356:2 | call to operator* [post update] | vector.cpp:357:7:357:8 | v5 | |
+| vector.cpp:356:2:356:2 | call to operator* [post update] | vector.cpp:359:7:359:8 | v5 | |
+| vector.cpp:356:2:356:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v5 | |
+| vector.cpp:356:2:356:15 | ... = ... | vector.cpp:356:2:356:2 | call to operator* [post update] | |
+| vector.cpp:356:3:356:4 | i5 | vector.cpp:356:2:356:2 | call to operator* | TAINT |
+| vector.cpp:356:8:356:13 | call to source | vector.cpp:356:2:356:2 | call to operator* [post update] | TAINT |
+| vector.cpp:356:8:356:13 | call to source | vector.cpp:356:2:356:15 | ... = ... | |
+| vector.cpp:357:7:357:8 | ref arg v5 | vector.cpp:359:7:359:8 | v5 | |
+| vector.cpp:357:7:357:8 | ref arg v5 | vector.cpp:382:1:382:1 | v5 | |
+| vector.cpp:358:2:358:2 | call to operator* [post update] | vector.cpp:359:7:359:8 | v5 | |
+| vector.cpp:358:2:358:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v5 | |
+| vector.cpp:358:2:358:8 | ... = ... | vector.cpp:358:2:358:2 | call to operator* [post update] | |
+| vector.cpp:358:3:358:4 | i5 | vector.cpp:358:2:358:2 | call to operator* | TAINT |
+| vector.cpp:358:8:358:8 | 1 | vector.cpp:358:2:358:2 | call to operator* [post update] | TAINT |
+| vector.cpp:358:8:358:8 | 1 | vector.cpp:358:2:358:8 | ... = ... | |
+| vector.cpp:359:7:359:8 | ref arg v5 | vector.cpp:382:1:382:1 | v5 | |
+| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:363:7:363:8 | v6 | |
+| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:364:2:364:3 | v6 | |
+| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:365:7:365:8 | v6 | |
+| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:382:1:382:1 | v6 | |
+| vector.cpp:361:34:361:35 | v6 | vector.cpp:361:37:361:41 | call to begin | TAINT |
+| vector.cpp:361:37:361:41 | call to begin | vector.cpp:362:3:362:4 | i6 | |
+| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:363:7:363:8 | v6 | |
+| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:364:2:364:3 | v6 | |
+| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:365:7:365:8 | v6 | |
+| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v6 | |
+| vector.cpp:362:2:362:15 | ... = ... | vector.cpp:362:2:362:2 | call to operator* [post update] | |
+| vector.cpp:362:3:362:4 | i6 | vector.cpp:362:2:362:2 | call to operator* | TAINT |
+| vector.cpp:362:8:362:13 | call to source | vector.cpp:362:2:362:2 | call to operator* [post update] | TAINT |
+| vector.cpp:362:8:362:13 | call to source | vector.cpp:362:2:362:15 | ... = ... | |
+| vector.cpp:363:7:363:8 | ref arg v6 | vector.cpp:364:2:364:3 | v6 | |
+| vector.cpp:363:7:363:8 | ref arg v6 | vector.cpp:365:7:365:8 | v6 | |
+| vector.cpp:363:7:363:8 | ref arg v6 | vector.cpp:382:1:382:1 | v6 | |
+| vector.cpp:364:2:364:3 | ref arg v6 | vector.cpp:365:7:365:8 | v6 | |
+| vector.cpp:364:2:364:3 | ref arg v6 | vector.cpp:382:1:382:1 | v6 | |
+| vector.cpp:364:7:364:26 | call to vector | vector.cpp:364:2:364:3 | ref arg v6 | TAINT |
+| vector.cpp:364:7:364:26 | call to vector | vector.cpp:364:5:364:5 | call to operator= | TAINT |
+| vector.cpp:365:7:365:8 | ref arg v6 | vector.cpp:382:1:382:1 | v6 | |
+| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:370:8:370:9 | v7 | |
+| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:373:8:373:9 | v7 | |
+| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:375:7:375:8 | v7 | |
+| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:382:1:382:1 | v7 | |
+| vector.cpp:367:34:367:35 | v7 | vector.cpp:367:37:367:41 | call to begin | TAINT |
+| vector.cpp:367:37:367:41 | call to begin | vector.cpp:369:4:369:5 | i7 | |
+| vector.cpp:367:37:367:41 | call to begin | vector.cpp:372:4:372:5 | i7 | |
+| vector.cpp:369:3:369:3 | call to operator* [post update] | vector.cpp:370:8:370:9 | v7 | |
+| vector.cpp:369:3:369:3 | call to operator* [post update] | vector.cpp:375:7:375:8 | v7 | |
+| vector.cpp:369:3:369:3 | call to operator* [post update] | vector.cpp:382:1:382:1 | v7 | |
+| vector.cpp:369:3:369:16 | ... = ... | vector.cpp:369:3:369:3 | call to operator* [post update] | |
+| vector.cpp:369:4:369:5 | i7 | vector.cpp:369:3:369:3 | call to operator* | TAINT |
+| vector.cpp:369:9:369:14 | call to source | vector.cpp:369:3:369:3 | call to operator* [post update] | TAINT |
+| vector.cpp:369:9:369:14 | call to source | vector.cpp:369:3:369:16 | ... = ... | |
+| vector.cpp:370:8:370:9 | ref arg v7 | vector.cpp:375:7:375:8 | v7 | |
+| vector.cpp:370:8:370:9 | ref arg v7 | vector.cpp:382:1:382:1 | v7 | |
+| vector.cpp:372:3:372:3 | call to operator* [post update] | vector.cpp:373:8:373:9 | v7 | |
+| vector.cpp:372:3:372:3 | call to operator* [post update] | vector.cpp:375:7:375:8 | v7 | |
+| vector.cpp:372:3:372:3 | call to operator* [post update] | vector.cpp:382:1:382:1 | v7 | |
+| vector.cpp:372:3:372:9 | ... = ... | vector.cpp:372:3:372:3 | call to operator* [post update] | |
+| vector.cpp:372:4:372:5 | i7 | vector.cpp:372:3:372:3 | call to operator* | TAINT |
+| vector.cpp:372:9:372:9 | 1 | vector.cpp:372:3:372:3 | call to operator* [post update] | TAINT |
+| vector.cpp:372:9:372:9 | 1 | vector.cpp:372:3:372:9 | ... = ... | |
+| vector.cpp:373:8:373:9 | ref arg v7 | vector.cpp:375:7:375:8 | v7 | |
+| vector.cpp:373:8:373:9 | ref arg v7 | vector.cpp:382:1:382:1 | v7 | |
+| vector.cpp:375:7:375:8 | ref arg v7 | vector.cpp:382:1:382:1 | v7 | |
+| vector.cpp:377:34:377:35 | ref arg v8 | vector.cpp:379:7:379:8 | v8 | |
+| vector.cpp:377:34:377:35 | ref arg v8 | vector.cpp:381:7:381:8 | v8 | |
+| vector.cpp:377:34:377:35 | ref arg v8 | vector.cpp:382:1:382:1 | v8 | |
+| vector.cpp:377:34:377:35 | v8 | vector.cpp:377:37:377:41 | call to begin | TAINT |
+| vector.cpp:377:37:377:41 | call to begin | vector.cpp:378:3:378:4 | i8 | |
+| vector.cpp:377:37:377:41 | call to begin | vector.cpp:380:3:380:4 | i8 | |
+| vector.cpp:378:2:378:2 | call to operator* [post update] | vector.cpp:379:7:379:8 | v8 | |
+| vector.cpp:378:2:378:2 | call to operator* [post update] | vector.cpp:381:7:381:8 | v8 | |
+| vector.cpp:378:2:378:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v8 | |
+| vector.cpp:378:2:378:15 | ... = ... | vector.cpp:378:2:378:2 | call to operator* [post update] | |
+| vector.cpp:378:3:378:4 | i8 | vector.cpp:378:2:378:2 | call to operator* | TAINT |
+| vector.cpp:378:8:378:13 | call to source | vector.cpp:378:2:378:2 | call to operator* [post update] | TAINT |
+| vector.cpp:378:8:378:13 | call to source | vector.cpp:378:2:378:15 | ... = ... | |
+| vector.cpp:379:7:379:8 | ref arg v8 | vector.cpp:381:7:381:8 | v8 | |
+| vector.cpp:379:7:379:8 | ref arg v8 | vector.cpp:382:1:382:1 | v8 | |
+| vector.cpp:380:2:380:2 | call to operator* [post update] | vector.cpp:381:7:381:8 | v8 | |
+| vector.cpp:380:2:380:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v8 | |
+| vector.cpp:380:2:380:8 | ... = ... | vector.cpp:380:2:380:2 | call to operator* [post update] | |
+| vector.cpp:380:3:380:4 | i8 | vector.cpp:380:2:380:2 | call to operator* | TAINT |
+| vector.cpp:380:8:380:8 | 1 | vector.cpp:380:2:380:2 | call to operator* [post update] | TAINT |
+| vector.cpp:380:8:380:8 | 1 | vector.cpp:380:2:380:8 | ... = ... | |
+| vector.cpp:381:7:381:8 | ref arg v8 | vector.cpp:382:1:382:1 | v8 | |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
index 6697e57e4a3..c8ed520e639 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
@@ -329,3 +329,11 @@
| vector.cpp:338:7:338:8 | v1 | vector.cpp:337:8:337:13 | call to source |
| vector.cpp:343:7:343:8 | v2 | vector.cpp:341:9:341:14 | call to source |
| vector.cpp:353:7:353:8 | v4 | vector.cpp:351:9:351:14 | call to source |
+| vector.cpp:357:7:357:8 | v5 | vector.cpp:356:8:356:13 | call to source |
+| vector.cpp:359:7:359:8 | v5 | vector.cpp:356:8:356:13 | call to source |
+| vector.cpp:363:7:363:8 | v6 | vector.cpp:362:8:362:13 | call to source |
+| vector.cpp:365:7:365:8 | v6 | vector.cpp:362:8:362:13 | call to source |
+| vector.cpp:370:8:370:9 | v7 | vector.cpp:369:9:369:14 | call to source |
+| vector.cpp:375:7:375:8 | v7 | vector.cpp:369:9:369:14 | call to source |
+| vector.cpp:379:7:379:8 | v8 | vector.cpp:378:8:378:13 | call to source |
+| vector.cpp:381:7:381:8 | v8 | vector.cpp:378:8:378:13 | call to source |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected
index 7533d079093..94f4cf9d2fe 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected
@@ -278,3 +278,11 @@
| vector.cpp:338:7:338:8 | vector.cpp:337:8:337:13 | AST only |
| vector.cpp:343:7:343:8 | vector.cpp:341:9:341:14 | AST only |
| vector.cpp:353:7:353:8 | vector.cpp:351:9:351:14 | AST only |
+| vector.cpp:357:7:357:8 | vector.cpp:356:8:356:13 | AST only |
+| vector.cpp:359:7:359:8 | vector.cpp:356:8:356:13 | AST only |
+| vector.cpp:363:7:363:8 | vector.cpp:362:8:362:13 | AST only |
+| vector.cpp:365:7:365:8 | vector.cpp:362:8:362:13 | AST only |
+| vector.cpp:370:8:370:9 | vector.cpp:369:9:369:14 | AST only |
+| vector.cpp:375:7:375:8 | vector.cpp:369:9:369:14 | AST only |
+| vector.cpp:379:7:379:8 | vector.cpp:378:8:378:13 | AST only |
+| vector.cpp:381:7:381:8 | vector.cpp:378:8:378:13 | AST only |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
index f1cf4e91457..35145c3d815 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
@@ -330,8 +330,8 @@ void taint_vector_output_iterator(std::vector::iterator iter) {
*iter = source();
}
-void test_vector_output_iterator() {
- std::vector v1(10), v2(10), v3(10), v4(10);
+void test_vector_output_iterator(int b) {
+ std::vector v1(10), v2(10), v3(10), v4(10), v5(10), v6(10), v7(10), v8(10);
std::vector::iterator i1 = v1.begin();
*i1 = source();
@@ -351,4 +351,32 @@ void test_vector_output_iterator() {
*it = source();
}
sink(v4); // tainted [NOT DETECTED by IR]
+
+ std::vector::iterator i5 = v5.begin();
+ *i5 = source();
+ sink(v5); // tainted [NOT DETECTED by IR]
+ *i5 = 1;
+ sink(v5); // tainted [NOT DETECTED by IR]
+
+ std::vector::iterator i6 = v6.begin();
+ *i6 = source();
+ sink(v6); // tainted [NOT DETECTED by IR]
+ v6 = std::vector(10);
+ sink(v6); // [FALSE POSITIVE in AST]
+
+ std::vector::iterator i7 = v7.begin();
+ if(b) {
+ *i7 = source();
+ sink(v7); // tainted [NOT DETECTED by IR]
+ } else {
+ *i7 = 1;
+ sink(v7);
+ }
+ sink(v7); // tainted [NOT DETECTED by IR]
+
+ std::vector::iterator i8 = v8.begin();
+ *i8 = source();
+ sink(v8); // tainted [NOT DETECTED by IR]
+ *i8 = 1;
+ sink(v8);
}
From 2e187a51ae6db786322ed979e6fa449e494352a7 Mon Sep 17 00:00:00 2001
From: Robert Marsh
Date: Wed, 9 Sep 2020 12:45:06 -0700
Subject: [PATCH 006/411] C++: test for interprocedurl iterator flow
---
.../dataflow/taint-tests/localTaint.expected | 12 +++---------
.../dataflow/taint-tests/taint.expected | 1 -
.../dataflow/taint-tests/test_diff.expected | 1 -
.../library-tests/dataflow/taint-tests/vector.cpp | 2 +-
4 files changed, 4 insertions(+), 12 deletions(-)
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
index c0f34638554..13d38363b35 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
@@ -3269,7 +3269,7 @@
| vector.cpp:350:38:350:39 | v4 | vector.cpp:350:41:350:45 | call to begin | TAINT |
| vector.cpp:350:41:350:45 | call to begin | vector.cpp:350:50:350:51 | it | |
| vector.cpp:350:41:350:45 | call to begin | vector.cpp:350:68:350:69 | it | |
-| vector.cpp:350:41:350:45 | call to begin | vector.cpp:351:4:351:5 | it | |
+| vector.cpp:350:41:350:45 | call to begin | vector.cpp:351:32:351:33 | it | |
| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:350:56:350:57 | v4 | |
| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:353:7:353:8 | v4 | |
| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:382:1:382:1 | v4 | |
@@ -3277,14 +3277,8 @@
| vector.cpp:350:68:350:69 | it | vector.cpp:350:66:350:66 | call to operator++ | TAINT |
| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:50:350:51 | it | |
| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:68:350:69 | it | |
-| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:351:4:351:5 | it | |
-| vector.cpp:351:3:351:3 | call to operator* [post update] | vector.cpp:350:56:350:57 | v4 | |
-| vector.cpp:351:3:351:3 | call to operator* [post update] | vector.cpp:353:7:353:8 | v4 | |
-| vector.cpp:351:3:351:3 | call to operator* [post update] | vector.cpp:382:1:382:1 | v4 | |
-| vector.cpp:351:3:351:16 | ... = ... | vector.cpp:351:3:351:3 | call to operator* [post update] | |
-| vector.cpp:351:4:351:5 | it | vector.cpp:351:3:351:3 | call to operator* | TAINT |
-| vector.cpp:351:9:351:14 | call to source | vector.cpp:351:3:351:3 | call to operator* [post update] | TAINT |
-| vector.cpp:351:9:351:14 | call to source | vector.cpp:351:3:351:16 | ... = ... | |
+| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:351:32:351:33 | it | |
+| vector.cpp:351:32:351:33 | it | vector.cpp:351:32:351:33 | call to iterator | |
| vector.cpp:353:7:353:8 | ref arg v4 | vector.cpp:382:1:382:1 | v4 | |
| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:357:7:357:8 | v5 | |
| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:359:7:359:8 | v5 | |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
index c8ed520e639..6759dd90d60 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
@@ -328,7 +328,6 @@
| vector.cpp:326:7:326:8 | v4 | vector.cpp:318:15:318:20 | call to source |
| vector.cpp:338:7:338:8 | v1 | vector.cpp:337:8:337:13 | call to source |
| vector.cpp:343:7:343:8 | v2 | vector.cpp:341:9:341:14 | call to source |
-| vector.cpp:353:7:353:8 | v4 | vector.cpp:351:9:351:14 | call to source |
| vector.cpp:357:7:357:8 | v5 | vector.cpp:356:8:356:13 | call to source |
| vector.cpp:359:7:359:8 | v5 | vector.cpp:356:8:356:13 | call to source |
| vector.cpp:363:7:363:8 | v6 | vector.cpp:362:8:362:13 | call to source |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected
index 94f4cf9d2fe..8fbeb0c246c 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected
@@ -277,7 +277,6 @@
| vector.cpp:326:7:326:8 | vector.cpp:318:15:318:20 | AST only |
| vector.cpp:338:7:338:8 | vector.cpp:337:8:337:13 | AST only |
| vector.cpp:343:7:343:8 | vector.cpp:341:9:341:14 | AST only |
-| vector.cpp:353:7:353:8 | vector.cpp:351:9:351:14 | AST only |
| vector.cpp:357:7:357:8 | vector.cpp:356:8:356:13 | AST only |
| vector.cpp:359:7:359:8 | vector.cpp:356:8:356:13 | AST only |
| vector.cpp:363:7:363:8 | vector.cpp:362:8:362:13 | AST only |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
index 35145c3d815..153385a202d 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
@@ -348,7 +348,7 @@ void test_vector_output_iterator(int b) {
sink(v3); // tainted [NOT DETECTED]
for(std::vector::iterator it = v4.begin(); it != v4.end(); ++it) {
- *it = source();
+ taint_vector_output_iterator(it);
}
sink(v4); // tainted [NOT DETECTED by IR]
From 10633019a6081ee9b169d3a022d2132789e057af Mon Sep 17 00:00:00 2001
From: Robert Marsh
Date: Wed, 9 Sep 2020 12:45:17 -0700
Subject: [PATCH 007/411] C++: autoformat
---
.../semmle/code/cpp/dataflow/internal/FlowVar.qll | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
index cb2cdd68f08..c6929358543 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
@@ -130,10 +130,9 @@ private module PartialDefinitions {
* Holds if this `PartialDefinition` defines variable `v` at control-flow
* node `cfn`.
*/
- pragma[noinline] // does this work with a dispred?
- predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) {
- none()
- }
+ // does this work with a dispred?
+ pragma[noinline]
+ predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) { none() }
/**
* Holds if this partial definition may modify `inner` (or what it points
@@ -180,7 +179,7 @@ private module PartialDefinitions {
inner = innerDefinedExpr and
outer = this
}
-
+
override predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) {
v = collection and
cfn = node
@@ -198,7 +197,9 @@ private module PartialDefinitions {
)
}
- deprecated override predicate partiallyDefines(Variable v) { innerDefinedExpr = v.getAnAccess() }
+ deprecated override predicate partiallyDefines(Variable v) {
+ innerDefinedExpr = v.getAnAccess()
+ }
deprecated override predicate partiallyDefinesThis(ThisExpr e) { innerDefinedExpr = e }
@@ -214,7 +215,7 @@ private module PartialDefinitions {
inner = innerDefinedExpr and
outer = this
}
-
+
override predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) {
innerDefinedExpr = v.getAnAccess() and
cfn = node
From eb5782d90822bcf6f3551aa599c4e0a0dde0fd93 Mon Sep 17 00:00:00 2001
From: "lcartey@github.com"
Date: Fri, 11 Sep 2020 17:12:10 +0100
Subject: [PATCH 008/411] C++: Support customizable ranges for
RangeSsaDefinitions.
---
.../interfaces/SimpleRangeAnalysisDef.qll | 34 +++++++++++++++++++
.../cpp/rangeanalysis/SimpleRangeAnalysis.qll | 10 ++++++
2 files changed, 44 insertions(+)
create mode 100644 cpp/ql/src/experimental/semmle/code/cpp/models/interfaces/SimpleRangeAnalysisDef.qll
diff --git a/cpp/ql/src/experimental/semmle/code/cpp/models/interfaces/SimpleRangeAnalysisDef.qll b/cpp/ql/src/experimental/semmle/code/cpp/models/interfaces/SimpleRangeAnalysisDef.qll
new file mode 100644
index 00000000000..c2647e2bebc
--- /dev/null
+++ b/cpp/ql/src/experimental/semmle/code/cpp/models/interfaces/SimpleRangeAnalysisDef.qll
@@ -0,0 +1,34 @@
+/**
+ * EXPERIMENTAL: The API of this module may change without notice.
+ *
+ * Provides a class for modeling `RangeSsaDefinition`s with a restricted range.
+ */
+
+import cpp
+import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
+
+/**
+ * EXPERIMENTAL: The API of this class may change without notice.
+ *
+ * An SSA definition for which a range can be deduced. Extend this class to add
+ * functionality to the range analysis library.
+ */
+abstract class SimpleRangeAnalysisDefinition extends RangeSsaDefinition {
+ /**
+ * Gets the lower bound of the defomotopn.
+ *
+ * Implementations of this predicate should use
+ * `getFullyConvertedLowerBounds` and `getFullyConvertedUpperBounds` for
+ * recursive calls to get the bounds of their children.
+ */
+ abstract float getLowerBounds();
+
+ /**
+ * Gets the upper bound of the definition.
+ *
+ * Implementations of this predicate should use
+ * `getFullyConvertedLowerBounds` and `getFullyConvertedUpperBounds` for
+ * recursive calls to get the bounds of their children.
+ */
+ abstract float getUpperBounds();
+}
\ No newline at end of file
diff --git a/cpp/ql/src/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll b/cpp/ql/src/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll
index c8a6e70ce1f..4c61c06c829 100644
--- a/cpp/ql/src/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll
+++ b/cpp/ql/src/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll
@@ -45,6 +45,7 @@
import cpp
private import RangeAnalysisUtils
private import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisExpr
+private import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisDef
import RangeSSA
import SimpleRangeAnalysisCached
private import NanAnalysis
@@ -492,6 +493,9 @@ private predicate analyzableDef(RangeSsaDefinition def, StackVariable v) {
v = def.getAVariable()
or
phiDependsOnDef(def, v, _, _)
+ or
+ // A modeled def for range analysis
+ def.(SimpleRangeAnalysisDefinition).getAVariable() =v
}
/**
@@ -1211,6 +1215,9 @@ private float getDefLowerBoundsImpl(RangeSsaDefinition def, StackVariable v) {
// Phi nodes.
result = getPhiLowerBounds(v, def)
or
+ // A modeled def for range analysis
+ result = def.(SimpleRangeAnalysisDefinition).getLowerBounds()
+ or
// Unanalyzable definitions.
unanalyzableDefBounds(def, v, result, _)
}
@@ -1244,6 +1251,9 @@ private float getDefUpperBoundsImpl(RangeSsaDefinition def, StackVariable v) {
// Phi nodes.
result = getPhiUpperBounds(v, def)
or
+ // A modeled def for range analysis
+ result = def.(SimpleRangeAnalysisDefinition).getUpperBounds()
+ or
// Unanalyzable definitions.
unanalyzableDefBounds(def, v, _, result)
}
From 826fc0a630cb4742875221c31ee3d9ab269b76ca Mon Sep 17 00:00:00 2001
From: Faten Healy <5361987+fatenhealy@users.noreply.github.com>
Date: Sun, 13 Sep 2020 21:04:07 +1000
Subject: [PATCH 009/411] Update BrokenCryptoAlgorithm - Blowfish to AES
---
python/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.qhelp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/python/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.qhelp b/python/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.qhelp
index 1b4031b1cc5..ba5ab4d10c1 100644
--- a/python/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.qhelp
+++ b/python/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.qhelp
@@ -33,7 +33,7 @@
pycrypto you must specify the encryption
algorithm to use. The first example uses DES, which is an
older algorithm that is now considered weak. The second
- example uses Blowfish, which is a stronger more modern algorithm.
+ example uses AES, which is a stronger modern algorithm.
From 6f20516f8433bdab89610c805a360d5b0b9eb3ca Mon Sep 17 00:00:00 2001
From: Faten Healy <5361987+fatenhealy@users.noreply.github.com>
Date: Sun, 13 Sep 2020 21:07:28 +1000
Subject: [PATCH 010/411] Update broken_crypto.py to AES instead of Blowfish
---
python/ql/src/Security/CWE-327/examples/broken_crypto.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/python/ql/src/Security/CWE-327/examples/broken_crypto.py b/python/ql/src/Security/CWE-327/examples/broken_crypto.py
index ef9fc75e889..690ed0096b1 100644
--- a/python/ql/src/Security/CWE-327/examples/broken_crypto.py
+++ b/python/ql/src/Security/CWE-327/examples/broken_crypto.py
@@ -6,7 +6,7 @@ def send_encrypted(channel, message):
channel.send(cipher.encrypt(message)) # BAD: weak encryption
-cipher = Blowfish.new(SECRET_KEY)
+cipher = AES.new(SECRET_KEY)
def send_encrypted(channel, message):
channel.send(cipher.encrypt(message)) # GOOD: strong encryption
From d3653b3030954d82488ac06e5c3d752e805d5d0e Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Wed, 9 Sep 2020 15:23:31 +0200
Subject: [PATCH 011/411] add support for re-exports using the spread operator
for NodeJS exports
---
javascript/ql/src/semmle/javascript/NodeJS.qll | 16 ++++++++++++++++
.../library-tests/NodeJS/ModuleAccess.expected | 2 ++
.../NodeJS/Module_getAnExportedSymbol.expected | 3 +++
.../NodeJS/Module_getAnImport.expected | 1 +
.../NodeJS/Module_getAnImportedModule.expected | 1 +
.../test/library-tests/NodeJS/Modules.expected | 2 ++
.../NodeJS/NodeModule_exports.expected | 3 +++
.../test/library-tests/NodeJS/Require.expected | 1 +
.../library-tests/NodeJS/RequireImport.expected | 1 +
.../ql/test/library-tests/NodeJS/reexport/a.js | 3 +++
.../ql/test/library-tests/NodeJS/reexport/b.js | 6 ++++++
11 files changed, 39 insertions(+)
create mode 100644 javascript/ql/test/library-tests/NodeJS/reexport/a.js
create mode 100644 javascript/ql/test/library-tests/NodeJS/reexport/b.js
diff --git a/javascript/ql/src/semmle/javascript/NodeJS.qll b/javascript/ql/src/semmle/javascript/NodeJS.qll
index 72aebbea6f7..e4557ca077a 100644
--- a/javascript/ql/src/semmle/javascript/NodeJS.qll
+++ b/javascript/ql/src/semmle/javascript/NodeJS.qll
@@ -55,6 +55,22 @@ class NodeModule extends Module {
name = pwn.getPropertyName()
)
or
+ // a re-export using spread-operator. E.g. `const foo = require("./foo"); module.exports = {bar: bar, ...foo};`
+ exists(ObjectExpr obj | obj.analyze().getAValue() = getAModuleExportsValue() |
+ obj
+ .getAProperty()
+ .(SpreadProperty)
+ .getInit()
+ .(SpreadElement)
+ .getOperand()
+ .flow()
+ .getALocalSource()
+ .asExpr()
+ .(Import)
+ .getImportedModule()
+ .exports(name, export)
+ )
+ or
// an externs definition (where appropriate)
exists(PropAccess pacc | export = pacc |
pacc.getBase().analyze().getAValue() = getAModuleExportsValue() and
diff --git a/javascript/ql/test/library-tests/NodeJS/ModuleAccess.expected b/javascript/ql/test/library-tests/NodeJS/ModuleAccess.expected
index 81fd8a8a0d0..214373771a9 100644
--- a/javascript/ql/test/library-tests/NodeJS/ModuleAccess.expected
+++ b/javascript/ql/test/library-tests/NodeJS/ModuleAccess.expected
@@ -1,2 +1,4 @@
| b.js:7:22:7:27 | module |
| d.js:3:1:3:6 | module |
+| reexport/a.js:1:1:1:6 | module |
+| reexport/b.js:3:1:3:6 | module |
diff --git a/javascript/ql/test/library-tests/NodeJS/Module_getAnExportedSymbol.expected b/javascript/ql/test/library-tests/NodeJS/Module_getAnExportedSymbol.expected
index 5b7c6130a6a..45cdeb20853 100644
--- a/javascript/ql/test/library-tests/NodeJS/Module_getAnExportedSymbol.expected
+++ b/javascript/ql/test/library-tests/NodeJS/Module_getAnExportedSymbol.expected
@@ -1,4 +1,7 @@
| b.js:1:1:8:0 | | sneaky |
| d.js:1:1:7:15 | | baz |
+| reexport/a.js:1:1:3:1 | | foo |
+| reexport/b.js:1:1:6:1 | | bar |
+| reexport/b.js:1:1:6:1 | | foo |
| sub/c.js:1:1:4:0 | | foo |
| sub/f.js:1:1:4:17 | | bar |
diff --git a/javascript/ql/test/library-tests/NodeJS/Module_getAnImport.expected b/javascript/ql/test/library-tests/NodeJS/Module_getAnImport.expected
index d1cc2576141..4694ebca20b 100644
--- a/javascript/ql/test/library-tests/NodeJS/Module_getAnImport.expected
+++ b/javascript/ql/test/library-tests/NodeJS/Module_getAnImport.expected
@@ -15,4 +15,5 @@
| mjs-files/require-from-js.js:1:1:4:0 | | mjs-files/require-from-js.js:1:12:1:36 | require ... on-me') |
| mjs-files/require-from-js.js:1:1:4:0 | | mjs-files/require-from-js.js:2:12:2:39 | require ... me.js') |
| mjs-files/require-from-js.js:1:1:4:0 | | mjs-files/require-from-js.js:3:12:3:40 | require ... e.mjs') |
+| reexport/b.js:1:1:6:1 | | reexport/b.js:1:11:1:24 | require("./a") |
| sub/c.js:1:1:4:0 | | sub/c.js:1:1:1:15 | require('../a') |
diff --git a/javascript/ql/test/library-tests/NodeJS/Module_getAnImportedModule.expected b/javascript/ql/test/library-tests/NodeJS/Module_getAnImportedModule.expected
index 0fa0e65f359..7eca17b3bc8 100644
--- a/javascript/ql/test/library-tests/NodeJS/Module_getAnImportedModule.expected
+++ b/javascript/ql/test/library-tests/NodeJS/Module_getAnImportedModule.expected
@@ -8,4 +8,5 @@
| index.js:1:1:3:0 | | b.js:1:1:8:0 | |
| mjs-files/require-from-js.js:1:1:4:0 | | mjs-files/depend-on-me.js:1:1:8:0 | |
| mjs-files/require-from-js.js:1:1:4:0 | | mjs-files/depend-on-me.mjs:1:1:7:1 | |
+| reexport/b.js:1:1:6:1 | | reexport/a.js:1:1:3:1 | |
| sub/c.js:1:1:4:0 | | a.js:1:1:14:0 | |
diff --git a/javascript/ql/test/library-tests/NodeJS/Modules.expected b/javascript/ql/test/library-tests/NodeJS/Modules.expected
index 1ef82d0328e..3d834490e60 100644
--- a/javascript/ql/test/library-tests/NodeJS/Modules.expected
+++ b/javascript/ql/test/library-tests/NodeJS/Modules.expected
@@ -4,5 +4,7 @@
| e.js:1:1:6:0 | | e.js:0:0:0:0 | e.js | e.js | e |
| index.js:1:1:3:0 | | index.js:0:0:0:0 | index.js | index.js | index |
| mjs-files/require-from-js.js:1:1:4:0 | | mjs-files/require-from-js.js:0:0:0:0 | mjs-files/require-from-js.js | mjs-files/require-from-js.js | require-from-js |
+| reexport/a.js:1:1:3:1 | | reexport/a.js:0:0:0:0 | reexport/a.js | reexport/a.js | a |
+| reexport/b.js:1:1:6:1 | | reexport/b.js:0:0:0:0 | reexport/b.js | reexport/b.js | b |
| sub/c.js:1:1:4:0 | | sub/c.js:0:0:0:0 | sub/c.js | sub/c.js | c |
| sub/f.js:1:1:4:17 | | sub/f.js:0:0:0:0 | sub/f.js | sub/f.js | f |
diff --git a/javascript/ql/test/library-tests/NodeJS/NodeModule_exports.expected b/javascript/ql/test/library-tests/NodeJS/NodeModule_exports.expected
index 0c2384a6999..d73a69441af 100644
--- a/javascript/ql/test/library-tests/NodeJS/NodeModule_exports.expected
+++ b/javascript/ql/test/library-tests/NodeJS/NodeModule_exports.expected
@@ -2,5 +2,8 @@
| d.js:1:1:7:15 | | baz | d.js:4:2:4:8 | baz: 42 |
| mjs-files/depend-on-me.js:1:1:8:0 | | add | mjs-files/depend-on-me.js:5:1:7:1 | export ... + y;\\n} |
| mjs-files/depend-on-me.mjs:1:1:7:1 | | add | mjs-files/depend-on-me.mjs:5:1:7:1 | export ... + y;\\n} |
+| reexport/a.js:1:1:3:1 | | foo | reexport/a.js:2:5:2:26 | foo: fu ... oo() {} |
+| reexport/b.js:1:1:6:1 | | bar | reexport/b.js:4:5:4:26 | bar: fu ... ar() {} |
+| reexport/b.js:1:1:6:1 | | foo | reexport/a.js:2:5:2:26 | foo: fu ... oo() {} |
| sub/c.js:1:1:4:0 | | foo | sub/c.js:3:1:3:11 | exports.foo |
| sub/f.js:1:1:4:17 | | bar | sub/f.js:4:1:4:11 | exports.bar |
diff --git a/javascript/ql/test/library-tests/NodeJS/Require.expected b/javascript/ql/test/library-tests/NodeJS/Require.expected
index 364ad6fe99d..67bc4fb1df8 100644
--- a/javascript/ql/test/library-tests/NodeJS/Require.expected
+++ b/javascript/ql/test/library-tests/NodeJS/Require.expected
@@ -19,4 +19,5 @@
| mjs-files/require-from-js.js:1:12:1:36 | require ... on-me') |
| mjs-files/require-from-js.js:2:12:2:39 | require ... me.js') |
| mjs-files/require-from-js.js:3:12:3:40 | require ... e.mjs') |
+| reexport/b.js:1:11:1:24 | require("./a") |
| sub/c.js:1:1:1:15 | require('../a') |
diff --git a/javascript/ql/test/library-tests/NodeJS/RequireImport.expected b/javascript/ql/test/library-tests/NodeJS/RequireImport.expected
index fe43bdcd3bd..04c897ce0c0 100644
--- a/javascript/ql/test/library-tests/NodeJS/RequireImport.expected
+++ b/javascript/ql/test/library-tests/NodeJS/RequireImport.expected
@@ -11,4 +11,5 @@
| mjs-files/require-from-js.js:1:12:1:36 | require ... on-me') | ./depend-on-me | mjs-files/depend-on-me.mjs:1:1:7:1 | |
| mjs-files/require-from-js.js:2:12:2:39 | require ... me.js') | ./depend-on-me.js | mjs-files/depend-on-me.js:1:1:8:0 | |
| mjs-files/require-from-js.js:3:12:3:40 | require ... e.mjs') | ./depend-on-me.mjs | mjs-files/depend-on-me.mjs:1:1:7:1 | |
+| reexport/b.js:1:11:1:24 | require("./a") | ./a | reexport/a.js:1:1:3:1 | |
| sub/c.js:1:1:1:15 | require('../a') | ../a | a.js:1:1:14:0 | |
diff --git a/javascript/ql/test/library-tests/NodeJS/reexport/a.js b/javascript/ql/test/library-tests/NodeJS/reexport/a.js
new file mode 100644
index 00000000000..ab33553c7cd
--- /dev/null
+++ b/javascript/ql/test/library-tests/NodeJS/reexport/a.js
@@ -0,0 +1,3 @@
+module.exports = {
+ foo: function foo() {}
+}
\ No newline at end of file
diff --git a/javascript/ql/test/library-tests/NodeJS/reexport/b.js b/javascript/ql/test/library-tests/NodeJS/reexport/b.js
new file mode 100644
index 00000000000..59a34a4c7e2
--- /dev/null
+++ b/javascript/ql/test/library-tests/NodeJS/reexport/b.js
@@ -0,0 +1,6 @@
+const a = require("./a");
+
+module.exports = {
+ bar: function bar() {},
+ ...a
+}
\ No newline at end of file
From 61f6580d1ec6a9e3b0980839e2ed062c7a2ccba1 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Wed, 9 Sep 2020 23:18:12 +0200
Subject: [PATCH 012/411] add API in `PackageExports.qll` for getting a value
exported under a name
---
.../src/semmle/javascript/PackageExports.qll | 20 +++++++++++++++----
.../library-tests/PackageExports/lib1/baz.js | 5 +++++
.../PackageExports/tests.expected | 9 +++++++++
.../library-tests/PackageExports/tests.ql | 4 ++++
4 files changed, 34 insertions(+), 4 deletions(-)
create mode 100644 javascript/ql/test/library-tests/PackageExports/lib1/baz.js
diff --git a/javascript/ql/src/semmle/javascript/PackageExports.qll b/javascript/ql/src/semmle/javascript/PackageExports.qll
index b0d185b746c..b54f0b48351 100644
--- a/javascript/ql/src/semmle/javascript/PackageExports.qll
+++ b/javascript/ql/src/semmle/javascript/PackageExports.qll
@@ -40,7 +40,7 @@ DataFlow::Node getAValueExportedBy(PackageJSON packageJSON) {
exists(DataFlow::SourceNode callee |
callee = getAValueExportedBy(packageJSON).(DataFlow::NewNode).getCalleeNode().getALocalSource()
|
- result = callee.getAPropertyRead("prototype").getAPropertyWrite()
+ result = callee.getAPropertyRead("prototype").getAPropertyWrite().getRhs()
or
result = callee.(DataFlow::ClassNode).getAnInstanceMethod()
)
@@ -68,10 +68,22 @@ DataFlow::Node getAValueExportedBy(PackageJSON packageJSON) {
private DataFlow::Node getAnExportFromModule(Module mod) {
result.analyze().getAValue() = mod.(NodeModule).getAModuleExportsValue()
or
- exists(ASTNode export | result.getEnclosingExpr() = export | mod.exports(_, export))
+ result = getAnExportedValue(mod, _)
+}
+
+/**
+ * Gets a value exported from `mod` under `name`.
+ */
+DataFlow::Node getAnExportedValue(Module mod, string name) {
+ exists(Property export | result.asExpr() = export.getInit() | mod.exports(name, export))
+ or
+ result =
+ DataFlow::valueNode(any(ASTNode export | mod.exports(name, export)))
+ .(DataFlow::PropWrite)
+ .getRhs()
or
exists(ExportDeclaration export |
- result = export.getSourceNode(_) and
- mod = export.getTopLevel()
+ result = export.getSourceNode(name) and
+ mod = export.getEnclosingModule()
)
}
diff --git a/javascript/ql/test/library-tests/PackageExports/lib1/baz.js b/javascript/ql/test/library-tests/PackageExports/lib1/baz.js
new file mode 100644
index 00000000000..6ed47ee1a69
--- /dev/null
+++ b/javascript/ql/test/library-tests/PackageExports/lib1/baz.js
@@ -0,0 +1,5 @@
+module.exports = {
+ // not imported from anywhere
+ foo: function foo() {},
+ bar: function bar() {}
+}
\ No newline at end of file
diff --git a/javascript/ql/test/library-tests/PackageExports/tests.expected b/javascript/ql/test/library-tests/PackageExports/tests.expected
index 1bd02d82385..f6b6083517e 100644
--- a/javascript/ql/test/library-tests/PackageExports/tests.expected
+++ b/javascript/ql/test/library-tests/PackageExports/tests.expected
@@ -34,3 +34,12 @@ getAValueExportedBy
| lib1/sublib/package.json:1:1:3:1 | {\\n " ... b.js"\\n} | lib1/sublib/sublib.js:1:1:1:0 | this |
| lib1/sublib/package.json:1:1:3:1 | {\\n " ... b.js"\\n} | lib1/sublib/sublib.js:1:1:1:73 | module. ... rt() {} |
| lib1/sublib/package.json:1:1:3:1 | {\\n " ... b.js"\\n} | lib1/sublib/sublib.js:1:18:1:73 | functio ... rt() {} |
+getAnExportedValue
+| absent_main/index.js:1:1:2:0 | | foo | absent_main/index.js:1:22:1:34 | function() {} |
+| esmodules/main.js:1:1:4:0 | | exported | esmodules/main.js:1:8:1:29 | functio ... ed() {} |
+| lib1/baz.js:1:1:5:1 | | bar | lib1/baz.js:4:10:4:26 | function bar() {} |
+| lib1/baz.js:1:1:5:1 | | foo | lib1/baz.js:3:10:3:26 | function foo() {} |
+| lib1/foo.js:1:1:3:47 | | foo | lib1/foo.js:3:22:3:47 | functio ... ed() {} |
+| lib1/main.js:1:1:17:30 | | Baz | lib1/main.js:17:22:17:30 | new Baz() |
+| lib1/main.js:1:1:17:30 | | bar | lib1/main.js:5:22:9:1 | class B ... () {}\\n} |
+| lib1/main.js:1:1:17:30 | | foo | lib1/main.js:3:22:3:40 | require("./foo.js") |
diff --git a/javascript/ql/test/library-tests/PackageExports/tests.ql b/javascript/ql/test/library-tests/PackageExports/tests.ql
index 71b269cf8cd..49e47ad79d0 100644
--- a/javascript/ql/test/library-tests/PackageExports/tests.ql
+++ b/javascript/ql/test/library-tests/PackageExports/tests.ql
@@ -6,3 +6,7 @@ query PackageJSON getTopmostPackageJSON() { result = Exports::getTopmostPackageJ
query DataFlow::Node getAValueExportedBy(PackageJSON json) {
result = Exports::getAValueExportedBy(json)
}
+
+query DataFlow::Node getAnExportedValue(Module mod, string name) {
+ result = Exports::getAnExportedValue(mod, name)
+}
\ No newline at end of file
From 29457c52dc0b8b79f3866461f490ecf3628fb552 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Wed, 9 Sep 2020 23:37:45 +0200
Subject: [PATCH 013/411] add reexported test to PackageExports test
---
.../PackageExports/lib1/reexport/a.js | 3 +++
.../PackageExports/lib1/reexport/b.js | 6 ++++++
.../library-tests/PackageExports/tests.expected | 15 +++++++++++++++
.../ql/test/library-tests/PackageExports/tests.ql | 4 +++-
4 files changed, 27 insertions(+), 1 deletion(-)
create mode 100644 javascript/ql/test/library-tests/PackageExports/lib1/reexport/a.js
create mode 100644 javascript/ql/test/library-tests/PackageExports/lib1/reexport/b.js
diff --git a/javascript/ql/test/library-tests/PackageExports/lib1/reexport/a.js b/javascript/ql/test/library-tests/PackageExports/lib1/reexport/a.js
new file mode 100644
index 00000000000..554e1f29c54
--- /dev/null
+++ b/javascript/ql/test/library-tests/PackageExports/lib1/reexport/a.js
@@ -0,0 +1,3 @@
+module.exports = {
+ reexported: function reexported() {}
+}
\ No newline at end of file
diff --git a/javascript/ql/test/library-tests/PackageExports/lib1/reexport/b.js b/javascript/ql/test/library-tests/PackageExports/lib1/reexport/b.js
new file mode 100644
index 00000000000..5c3b111edb5
--- /dev/null
+++ b/javascript/ql/test/library-tests/PackageExports/lib1/reexport/b.js
@@ -0,0 +1,6 @@
+const a = require("./a");
+
+module.exports = {
+ base: function base() {},
+ ...a
+}
\ No newline at end of file
diff --git a/javascript/ql/test/library-tests/PackageExports/tests.expected b/javascript/ql/test/library-tests/PackageExports/tests.expected
index f6b6083517e..83ae0c2d2ad 100644
--- a/javascript/ql/test/library-tests/PackageExports/tests.expected
+++ b/javascript/ql/test/library-tests/PackageExports/tests.expected
@@ -43,3 +43,18 @@ getAnExportedValue
| lib1/main.js:1:1:17:30 | | Baz | lib1/main.js:17:22:17:30 | new Baz() |
| lib1/main.js:1:1:17:30 | | bar | lib1/main.js:5:22:9:1 | class B ... () {}\\n} |
| lib1/main.js:1:1:17:30 | | foo | lib1/main.js:3:22:3:40 | require("./foo.js") |
+| lib1/reexport/a.js:1:1:3:1 | | reexported | lib1/reexport/a.js:2:17:2:40 | functio ... ed() {} |
+| lib1/reexport/b.js:1:1:6:1 | | base | lib1/reexport/b.js:4:11:4:28 | function base() {} |
+| lib1/reexport/b.js:1:1:6:1 | | reexported | lib1/reexport/a.js:2:17:2:40 | functio ... ed() {} |
+exports
+| Baz | lib1/main.js:17:1:17:18 | module.exports.Baz | lib1/main.js:1:1:17:30 | |
+| bar | lib1/baz.js:4:5:4:26 | bar: fu ... ar() {} | lib1/baz.js:1:1:5:1 | |
+| bar | lib1/main.js:5:1:5:18 | module.exports.bar | lib1/main.js:1:1:17:30 | |
+| base | lib1/reexport/b.js:4:5:4:28 | base: f ... se() {} | lib1/reexport/b.js:1:1:6:1 | |
+| exported | esmodules/main.js:1:1:1:29 | export ... ed() {} | esmodules/main.js:1:1:4:0 | |
+| foo | absent_main/index.js:1:1:1:18 | module.exports.foo | absent_main/index.js:1:1:2:0 | |
+| foo | lib1/baz.js:3:5:3:26 | foo: fu ... oo() {} | lib1/baz.js:1:1:5:1 | |
+| foo | lib1/foo.js:3:1:3:18 | module.exports.foo | lib1/foo.js:1:1:3:47 | |
+| foo | lib1/main.js:3:1:3:18 | module.exports.foo | lib1/main.js:1:1:17:30 | |
+| reexported | lib1/reexport/a.js:2:5:2:40 | reexpor ... ed() {} | lib1/reexport/a.js:1:1:3:1 | |
+| reexported | lib1/reexport/a.js:2:5:2:40 | reexpor ... ed() {} | lib1/reexport/b.js:1:1:6:1 | |
diff --git a/javascript/ql/test/library-tests/PackageExports/tests.ql b/javascript/ql/test/library-tests/PackageExports/tests.ql
index 49e47ad79d0..efbc708a538 100644
--- a/javascript/ql/test/library-tests/PackageExports/tests.ql
+++ b/javascript/ql/test/library-tests/PackageExports/tests.ql
@@ -9,4 +9,6 @@ query DataFlow::Node getAValueExportedBy(PackageJSON json) {
query DataFlow::Node getAnExportedValue(Module mod, string name) {
result = Exports::getAnExportedValue(mod, name)
-}
\ No newline at end of file
+}
+
+query Module exports(string name, ASTNode export) { result.exports(name, export) }
From f2ecb63e5ae7209c2a9fd1c215c46ccbfdf22ae5 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Thu, 10 Sep 2020 00:05:39 +0200
Subject: [PATCH 014/411] add a direct Export step as a PreCallGraphStep
---
.../src/semmle/javascript/frameworks/NodeJSLib.qll | 14 ++++++++++++++
.../TypeTracking/PredicateStyle.expected | 5 +++++
.../library-tests/TypeTracking/PredicateStyle.ql | 12 ++++++++++++
.../test/library-tests/TypeTracking/reexport/a.js | 3 +++
.../test/library-tests/TypeTracking/reexport/b.js | 6 ++++++
.../library-tests/TypeTracking/reexport/test.js | 4 ++++
6 files changed, 44 insertions(+)
create mode 100644 javascript/ql/test/library-tests/TypeTracking/reexport/a.js
create mode 100644 javascript/ql/test/library-tests/TypeTracking/reexport/b.js
create mode 100644 javascript/ql/test/library-tests/TypeTracking/reexport/test.js
diff --git a/javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll b/javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll
index 53a5f18c0d4..e9dbe9980c8 100644
--- a/javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll
+++ b/javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll
@@ -638,6 +638,20 @@ module NodeJSLib {
}
}
+ private import semmle.javascript.PackageExports as Exports
+
+ /**
+ * A direct step from an named export to a property-read reading the exported value.
+ */
+ private class ExportsStep extends PreCallGraphStep {
+ override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
+ exists(Import imp, string name |
+ succ = DataFlow::valueNode(imp).(DataFlow::SourceNode).getAPropertyRead(name) and
+ pred = Exports::getAnExportedValue(imp.getImportedModule(), name)
+ )
+ }
+ }
+
/**
* A call to a method from module `child_process`.
*/
diff --git a/javascript/ql/test/library-tests/TypeTracking/PredicateStyle.expected b/javascript/ql/test/library-tests/TypeTracking/PredicateStyle.expected
index 53bbd6ec126..61d1675e794 100644
--- a/javascript/ql/test/library-tests/TypeTracking/PredicateStyle.expected
+++ b/javascript/ql/test/library-tests/TypeTracking/PredicateStyle.expected
@@ -70,3 +70,8 @@ dataValue
| tst.js:51:30:51:33 | data |
| tst.js:58:16:58:16 | x |
| tst.js:68:16:68:19 | data |
+reexport
+| reexport/a.js:2:10:2:26 | function foo() {} | reexport/a.js:2:10:2:26 | function foo() {} |
+| reexport/a.js:2:10:2:26 | function foo() {} | reexport/test.js:3:13:3:17 | b.foo |
+| reexport/b.js:4:10:4:26 | function bar() {} | reexport/b.js:4:10:4:26 | function bar() {} |
+| reexport/b.js:4:10:4:26 | function bar() {} | reexport/test.js:4:13:4:17 | b.bar |
diff --git a/javascript/ql/test/library-tests/TypeTracking/PredicateStyle.ql b/javascript/ql/test/library-tests/TypeTracking/PredicateStyle.ql
index eaac73bc55c..6e0859cb8e7 100644
--- a/javascript/ql/test/library-tests/TypeTracking/PredicateStyle.ql
+++ b/javascript/ql/test/library-tests/TypeTracking/PredicateStyle.ql
@@ -46,3 +46,15 @@ DataFlow::SourceNode dataValue(DataFlow::TypeTracker t) {
}
query DataFlow::SourceNode dataValue() { result = dataValue(DataFlow::TypeTracker::end()) }
+
+DataFlow::SourceNode reexport(DataFlow::TypeTracker t, DataFlow::FunctionNode func) {
+ t.start() and
+ func = result and
+ func.getFile().getParentContainer().getBaseName() = "reexport"
+ or
+ exists(DataFlow::TypeTracker t2 | result = reexport(t2, func).track(t2, t))
+}
+
+query DataFlow::SourceNode reexport(DataFlow::FunctionNode func) {
+ result = reexport(DataFlow::TypeTracker::end(), func)
+}
diff --git a/javascript/ql/test/library-tests/TypeTracking/reexport/a.js b/javascript/ql/test/library-tests/TypeTracking/reexport/a.js
new file mode 100644
index 00000000000..ab33553c7cd
--- /dev/null
+++ b/javascript/ql/test/library-tests/TypeTracking/reexport/a.js
@@ -0,0 +1,3 @@
+module.exports = {
+ foo: function foo() {}
+}
\ No newline at end of file
diff --git a/javascript/ql/test/library-tests/TypeTracking/reexport/b.js b/javascript/ql/test/library-tests/TypeTracking/reexport/b.js
new file mode 100644
index 00000000000..8b5f1a246c6
--- /dev/null
+++ b/javascript/ql/test/library-tests/TypeTracking/reexport/b.js
@@ -0,0 +1,6 @@
+const a = require("./a");
+
+module.exports = {
+ bar: function bar() {}, // name: bar
+ ...a
+}
\ No newline at end of file
diff --git a/javascript/ql/test/library-tests/TypeTracking/reexport/test.js b/javascript/ql/test/library-tests/TypeTracking/reexport/test.js
new file mode 100644
index 00000000000..c22470f14e9
--- /dev/null
+++ b/javascript/ql/test/library-tests/TypeTracking/reexport/test.js
@@ -0,0 +1,4 @@
+const b = require("./b");
+
+const foo = b.foo;
+const bar = b.bar;
\ No newline at end of file
From c1cb19abd7ddc37e5e0688862bc8a7fc3f7a30d5 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Thu, 10 Sep 2020 00:32:35 +0200
Subject: [PATCH 015/411] add level PreCallGrapSteps to the callgraph
---
.../src/semmle/javascript/dataflow/internal/CallGraphs.qll | 5 +++++
.../library-tests/CallGraphs/AnnotatedTest/reexport/a.js | 4 ++++
.../library-tests/CallGraphs/AnnotatedTest/reexport/b.js | 7 +++++++
.../CallGraphs/AnnotatedTest/reexport/import.js | 7 +++++++
4 files changed, 23 insertions(+)
create mode 100644 javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/reexport/a.js
create mode 100644 javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/reexport/b.js
create mode 100644 javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/reexport/import.js
diff --git a/javascript/ql/src/semmle/javascript/dataflow/internal/CallGraphs.qll b/javascript/ql/src/semmle/javascript/dataflow/internal/CallGraphs.qll
index a1877de45e0..5b596dfb727 100644
--- a/javascript/ql/src/semmle/javascript/dataflow/internal/CallGraphs.qll
+++ b/javascript/ql/src/semmle/javascript/dataflow/internal/CallGraphs.qll
@@ -4,6 +4,7 @@
private import javascript
private import semmle.javascript.dataflow.internal.StepSummary
+private import semmle.javascript.dataflow.internal.PreCallGraphStep
cached
module CallGraph {
@@ -48,6 +49,10 @@ module CallGraph {
t.start() and
AccessPath::step(function, result)
or
+ t.start() and
+ imprecision = 0 and
+ PreCallGraphStep::step(any(DataFlow::Node n | function.flowsTo(n)), result)
+ or
imprecision = 0 and
exists(DataFlow::ClassNode cls |
exists(string name |
diff --git a/javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/reexport/a.js b/javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/reexport/a.js
new file mode 100644
index 00000000000..b6e65ec9d17
--- /dev/null
+++ b/javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/reexport/a.js
@@ -0,0 +1,4 @@
+module.exports = {
+ /** name:reexport.foo */
+ foo: function foo() {}
+}
\ No newline at end of file
diff --git a/javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/reexport/b.js b/javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/reexport/b.js
new file mode 100644
index 00000000000..f29148bf79b
--- /dev/null
+++ b/javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/reexport/b.js
@@ -0,0 +1,7 @@
+const a = require("./a");
+
+module.exports = {
+ /** name:reexport.bar */
+ bar: function bar() {},
+ ...a
+}
\ No newline at end of file
diff --git a/javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/reexport/import.js b/javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/reexport/import.js
new file mode 100644
index 00000000000..e20e4a0c00f
--- /dev/null
+++ b/javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/reexport/import.js
@@ -0,0 +1,7 @@
+const b = require("./b.js");
+
+/** calls:reexport.foo */
+b.foo();
+
+/** calls:reexport.bar */
+b.bar();
\ No newline at end of file
From c5b5a4fd558ca3527bac46100be1b48a72aaa8cd Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Mon, 14 Sep 2020 20:39:51 +0200
Subject: [PATCH 016/411] improve performance of NodeJS::NodeModule::exports
---
.../ql/src/semmle/javascript/NodeJS.qll | 24 ++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
diff --git a/javascript/ql/src/semmle/javascript/NodeJS.qll b/javascript/ql/src/semmle/javascript/NodeJS.qll
index e4557ca077a..a4c1c0cbe70 100644
--- a/javascript/ql/src/semmle/javascript/NodeJS.qll
+++ b/javascript/ql/src/semmle/javascript/NodeJS.qll
@@ -42,6 +42,24 @@ class NodeModule extends Module {
)
}
+ /**
+ * Gets an expression that is an alias for `module.exports`.
+ * For performance this predicate only computes relevant expressions.
+ * So if using this predicate - consider expanding the list of relevant expressions.
+ */
+ pragma[noinline]
+ private DataFlow::Node getAModuleExportsNode() {
+ (
+ // A bit of manual magic
+ result = any(DataFlow::PropWrite w | exists(w.getPropertyName())).getBase()
+ or
+ result = DataFlow::valueNode(any(PropAccess p | exists(p.getPropertyName())).getBase())
+ or
+ result = DataFlow::valueNode(any(ObjectExpr obj))
+ ) and
+ result.analyze().getAValue() = getAModuleExportsValue()
+ }
+
/** Gets a symbol exported by this module. */
override string getAnExportedSymbol() {
result = super.getAnExportedSymbol() or
@@ -51,12 +69,12 @@ class NodeModule extends Module {
override predicate exports(string name, ASTNode export) {
// a property write whose base is `exports` or `module.exports`
exists(DataFlow::PropWrite pwn | export = pwn.getAstNode() |
- pwn.getBase().analyze().getAValue() = getAModuleExportsValue() and
+ pwn.getBase() = getAModuleExportsNode() and
name = pwn.getPropertyName()
)
or
// a re-export using spread-operator. E.g. `const foo = require("./foo"); module.exports = {bar: bar, ...foo};`
- exists(ObjectExpr obj | obj.analyze().getAValue() = getAModuleExportsValue() |
+ exists(ObjectExpr obj | obj = getAModuleExportsNode().asExpr() |
obj
.getAProperty()
.(SpreadProperty)
@@ -73,7 +91,7 @@ class NodeModule extends Module {
or
// an externs definition (where appropriate)
exists(PropAccess pacc | export = pacc |
- pacc.getBase().analyze().getAValue() = getAModuleExportsValue() and
+ pacc.getBase() = getAModuleExportsNode().asExpr() and
name = pacc.getPropertyName() and
isExterns() and
exists(pacc.getDocumentation())
From 5f2cafc4f5571f06928b43cbb37d97b5a7044640 Mon Sep 17 00:00:00 2001
From: Robert Marsh
Date: Mon, 14 Sep 2020 14:36:19 -0700
Subject: [PATCH 017/411] C++: Interprocedural iterator flow
---
.../code/cpp/dataflow/internal/FlowVar.qll | 43 ++++++++++++++++---
.../dataflow/taint-tests/localTaint.expected | 17 ++++++++
.../dataflow/taint-tests/taint.expected | 1 +
.../dataflow/taint-tests/test_diff.expected | 1 +
4 files changed, 56 insertions(+), 6 deletions(-)
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
index c6929358543..0163d1e0ce7 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
@@ -109,11 +109,10 @@ class FlowVar extends TFlowVar {
* ```
*/
private module PartialDefinitions {
- class PartialDefinition extends Expr {
+ abstract class PartialDefinition extends Expr {
ControlFlowNode node;
PartialDefinition() {
- valueToUpdate(_, this.getFullyConverted(), node) and
not this instanceof Conversion
}
@@ -160,14 +159,39 @@ private module PartialDefinitions {
class IteratorPartialDefinition extends PartialDefinition {
Variable collection;
- Call innerDefinedExpr;
+ Expr innerDefinedExpr;
IteratorPartialDefinition() {
exists(Expr convertedInner |
valueToUpdate(convertedInner, this.getFullyConverted(), node) and
innerDefinedExpr = convertedInner.getUnconverted() and
- innerDefinedExpr.getQualifier() = getAnIteratorAccess(collection) and
- innerDefinedExpr.getTarget() instanceof IteratorPointerDereferenceMemberOperator
+ (
+ innerDefinedExpr.(Call).getQualifier() = getAnIteratorAccess(collection)
+ or
+ innerDefinedExpr.(Call).getQualifier() = collection.getAnAccess() and
+ collection instanceof IteratorParameter
+ ) and
+ innerDefinedExpr.(Call).getTarget() instanceof IteratorPointerDereferenceMemberOperator
+ )
+ or
+ // iterators passed by value without a copy constructor
+ exists(Call call |
+ call = node and
+ call.getAnArgument() = innerDefinedExpr and
+ innerDefinedExpr = this and
+ this = getAnIteratorAccess(collection) and
+ not call.getTarget() instanceof IteratorPointerDereferenceMemberOperator
+ )
+ or
+ // iterators passed by value with a copy constructor
+ exists(Call call, ConstructorCall copy |
+ copy.getTarget() instanceof CopyConstructor and
+ call = node and
+ call.getAnArgument() = copy and
+ copy.getArgument(0) = getAnIteratorAccess(collection) and
+ innerDefinedExpr = this and
+ this = copy and
+ not call.getTarget() instanceof IteratorPointerDereferenceMemberOperator
)
}
@@ -267,7 +291,8 @@ module FlowVar_internal {
// The SSA library has a theoretically accurate treatment of reference types,
// treating them as immutable, but for data flow it gives better results in
// practice to make the variable synonymous with its contents.
- not v.getUnspecifiedType() instanceof ReferenceType
+ not v.getUnspecifiedType() instanceof ReferenceType and
+ not v instanceof IteratorParameter
}
/**
@@ -616,6 +641,8 @@ module FlowVar_internal {
refType = p.getUnderlyingType() and
not refType.getBaseType().isConst()
)
+ or
+ p instanceof IteratorParameter
}
/**
@@ -778,6 +805,10 @@ module FlowVar_internal {
)
}
+ class IteratorParameter extends Parameter {
+ IteratorParameter() { this.getUnspecifiedType() instanceof Iterator }
+ }
+
/**
* Holds if `v` is initialized to have value `assignedExpr`.
*/
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
index 13d38363b35..396fecf212f 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
@@ -439,23 +439,29 @@
| movableclass.cpp:65:13:65:18 | call to source | movableclass.cpp:65:13:65:20 | call to MyMovableClass | TAINT |
| movableclass.cpp:65:13:65:20 | call to MyMovableClass | movableclass.cpp:65:8:65:9 | ref arg s3 | TAINT |
| movableclass.cpp:65:13:65:20 | call to MyMovableClass | movableclass.cpp:65:11:65:11 | call to operator= | TAINT |
+| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:39:45:39:51 | source1 | |
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:40:11:40:17 | source1 | |
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:41:12:41:18 | source1 | |
| standalone_iterators.cpp:39:45:39:51 | source1 | standalone_iterators.cpp:42:14:42:20 | source1 | |
| standalone_iterators.cpp:40:11:40:17 | source1 | standalone_iterators.cpp:40:10:40:10 | call to operator* | TAINT |
+| standalone_iterators.cpp:41:12:41:18 | ref arg source1 | standalone_iterators.cpp:39:45:39:51 | source1 | |
| standalone_iterators.cpp:41:12:41:18 | ref arg source1 | standalone_iterators.cpp:42:14:42:20 | source1 | |
| standalone_iterators.cpp:41:12:41:18 | source1 | standalone_iterators.cpp:41:19:41:19 | call to operator++ | TAINT |
| standalone_iterators.cpp:41:19:41:19 | call to operator++ | standalone_iterators.cpp:41:10:41:10 | call to operator* | TAINT |
| standalone_iterators.cpp:42:12:42:12 | call to operator++ | standalone_iterators.cpp:42:10:42:10 | call to operator* | TAINT |
+| standalone_iterators.cpp:42:14:42:20 | ref arg source1 | standalone_iterators.cpp:39:45:39:51 | source1 | |
| standalone_iterators.cpp:42:14:42:20 | source1 | standalone_iterators.cpp:42:12:42:12 | call to operator++ | TAINT |
+| standalone_iterators.cpp:45:39:45:45 | source1 | standalone_iterators.cpp:45:39:45:45 | source1 | |
| standalone_iterators.cpp:45:39:45:45 | source1 | standalone_iterators.cpp:46:11:46:17 | source1 | |
| standalone_iterators.cpp:45:39:45:45 | source1 | standalone_iterators.cpp:47:12:47:18 | source1 | |
| standalone_iterators.cpp:45:39:45:45 | source1 | standalone_iterators.cpp:48:14:48:20 | source1 | |
| standalone_iterators.cpp:46:11:46:17 | source1 | standalone_iterators.cpp:46:10:46:10 | call to operator* | TAINT |
+| standalone_iterators.cpp:47:12:47:18 | ref arg source1 | standalone_iterators.cpp:45:39:45:45 | source1 | |
| standalone_iterators.cpp:47:12:47:18 | ref arg source1 | standalone_iterators.cpp:48:14:48:20 | source1 | |
| standalone_iterators.cpp:47:12:47:18 | source1 | standalone_iterators.cpp:47:19:47:19 | call to operator++ | TAINT |
| standalone_iterators.cpp:47:19:47:19 | call to operator++ | standalone_iterators.cpp:47:10:47:10 | call to operator* | TAINT |
| standalone_iterators.cpp:48:12:48:12 | call to operator++ | standalone_iterators.cpp:48:10:48:10 | call to operator* | TAINT |
+| standalone_iterators.cpp:48:14:48:20 | ref arg source1 | standalone_iterators.cpp:45:39:45:45 | source1 | |
| standalone_iterators.cpp:48:14:48:20 | source1 | standalone_iterators.cpp:48:12:48:12 | call to operator++ | TAINT |
| standalone_iterators.cpp:51:37:51:43 | source1 | standalone_iterators.cpp:52:11:52:17 | source1 | |
| standalone_iterators.cpp:51:37:51:43 | source1 | standalone_iterators.cpp:53:12:53:18 | source1 | |
@@ -2967,10 +2973,13 @@
| vector.cpp:255:3:255:4 | ref arg v6 | vector.cpp:262:2:262:2 | v6 | |
| vector.cpp:255:13:255:14 | call to iterator | vector.cpp:255:3:255:4 | ref arg v6 | TAINT |
| vector.cpp:255:13:255:14 | i1 | vector.cpp:255:13:255:14 | call to iterator | |
+| vector.cpp:255:13:255:14 | ref arg call to iterator | vector.cpp:277:1:277:1 | v3 | |
+| vector.cpp:255:13:255:14 | ref arg i1 | vector.cpp:277:1:277:1 | v3 | |
| vector.cpp:255:17:255:18 | call to iterator | vector.cpp:255:3:255:4 | ref arg v6 | TAINT |
| vector.cpp:255:17:255:18 | i2 | vector.cpp:255:17:255:18 | call to iterator | |
| vector.cpp:257:8:257:9 | ref arg v4 | vector.cpp:262:2:262:2 | v4 | |
| vector.cpp:258:8:258:9 | ref arg v5 | vector.cpp:262:2:262:2 | v5 | |
+| vector.cpp:259:8:259:9 | ref arg i1 | vector.cpp:277:1:277:1 | v3 | |
| vector.cpp:261:8:261:9 | ref arg v6 | vector.cpp:262:2:262:2 | v6 | |
| vector.cpp:265:22:265:23 | call to vector | vector.cpp:269:3:269:4 | v7 | |
| vector.cpp:265:22:265:23 | call to vector | vector.cpp:273:8:273:9 | v7 | |
@@ -3173,7 +3182,9 @@
| vector.cpp:324:7:324:8 | ref arg v2 | vector.cpp:327:1:327:1 | v2 | |
| vector.cpp:325:7:325:8 | ref arg v3 | vector.cpp:327:1:327:1 | v3 | |
| vector.cpp:326:7:326:8 | ref arg v4 | vector.cpp:327:1:327:1 | v4 | |
+| vector.cpp:329:62:329:65 | iter | vector.cpp:329:62:329:65 | iter | |
| vector.cpp:329:62:329:65 | iter | vector.cpp:330:3:330:6 | iter | |
+| vector.cpp:330:2:330:2 | call to operator* [post update] | vector.cpp:329:62:329:65 | iter | |
| vector.cpp:330:2:330:17 | ... = ... | vector.cpp:330:2:330:2 | call to operator* [post update] | |
| vector.cpp:330:3:330:6 | iter | vector.cpp:330:2:330:2 | call to operator* | TAINT |
| vector.cpp:330:10:330:15 | call to source | vector.cpp:330:2:330:2 | call to operator* [post update] | TAINT |
@@ -3279,6 +3290,12 @@
| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:68:350:69 | it | |
| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:351:32:351:33 | it | |
| vector.cpp:351:32:351:33 | it | vector.cpp:351:32:351:33 | call to iterator | |
+| vector.cpp:351:32:351:33 | ref arg call to iterator | vector.cpp:350:56:350:57 | v4 | |
+| vector.cpp:351:32:351:33 | ref arg call to iterator | vector.cpp:353:7:353:8 | v4 | |
+| vector.cpp:351:32:351:33 | ref arg call to iterator | vector.cpp:382:1:382:1 | v4 | |
+| vector.cpp:351:32:351:33 | ref arg it | vector.cpp:350:56:350:57 | v4 | |
+| vector.cpp:351:32:351:33 | ref arg it | vector.cpp:353:7:353:8 | v4 | |
+| vector.cpp:351:32:351:33 | ref arg it | vector.cpp:382:1:382:1 | v4 | |
| vector.cpp:353:7:353:8 | ref arg v4 | vector.cpp:382:1:382:1 | v4 | |
| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:357:7:357:8 | v5 | |
| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:359:7:359:8 | v5 | |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
index 6759dd90d60..889e1da17e6 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
@@ -328,6 +328,7 @@
| vector.cpp:326:7:326:8 | v4 | vector.cpp:318:15:318:20 | call to source |
| vector.cpp:338:7:338:8 | v1 | vector.cpp:337:8:337:13 | call to source |
| vector.cpp:343:7:343:8 | v2 | vector.cpp:341:9:341:14 | call to source |
+| vector.cpp:353:7:353:8 | v4 | vector.cpp:330:10:330:15 | call to source |
| vector.cpp:357:7:357:8 | v5 | vector.cpp:356:8:356:13 | call to source |
| vector.cpp:359:7:359:8 | v5 | vector.cpp:356:8:356:13 | call to source |
| vector.cpp:363:7:363:8 | v6 | vector.cpp:362:8:362:13 | call to source |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected
index 8fbeb0c246c..0f6b7a574a5 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected
@@ -277,6 +277,7 @@
| vector.cpp:326:7:326:8 | vector.cpp:318:15:318:20 | AST only |
| vector.cpp:338:7:338:8 | vector.cpp:337:8:337:13 | AST only |
| vector.cpp:343:7:343:8 | vector.cpp:341:9:341:14 | AST only |
+| vector.cpp:353:7:353:8 | vector.cpp:330:10:330:15 | AST only |
| vector.cpp:357:7:357:8 | vector.cpp:356:8:356:13 | AST only |
| vector.cpp:359:7:359:8 | vector.cpp:356:8:356:13 | AST only |
| vector.cpp:363:7:363:8 | vector.cpp:362:8:362:13 | AST only |
From fa0e27b2de6c9fa8d9fbe500b4ba7accda8b0cbe Mon Sep 17 00:00:00 2001
From: Robert Marsh
Date: Wed, 16 Sep 2020 12:34:52 -0700
Subject: [PATCH 018/411] C++: move interprocedural iterator flow to taint
---
.../code/cpp/dataflow/internal/DataFlowUtil.qll | 6 +++---
.../semmle/code/cpp/dataflow/internal/FlowVar.qll | 12 ++++++++----
.../cpp/dataflow/internal/TaintTrackingUtil.qll | 15 ++++++++++-----
.../library-tests/dataflow/taint-tests/vector.cpp | 9 ++++++++-
4 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
index 9705ca492ce..1103e50ce16 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
@@ -303,7 +303,7 @@ private class VariablePartialDefinitionNode extends PartialDefinitionNode {
override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) }
}
-private class IteratorPartialDefinitionNode extends PartialDefinitionNode {
+class IteratorPartialDefinitionNode extends PartialDefinitionNode {
override IteratorPartialDefinition pd;
override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) }
@@ -546,10 +546,10 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
or
// In `f(&x->a)`, this step provides the flow from post-`&` to post-`x->a`,
// from which there is field flow to `x` via reverse read.
- exists(PartialDefinition def, Expr inner, Expr outer |
+ exists(VariablePartialDefinition def, Expr inner, Expr outer |
def.definesExpressions(inner, outer) and
inner = nodeTo.(InnerPartialDefinitionNode).getPreUpdateNode().asExpr() and
- outer = nodeFrom.(PartialDefinitionNode).getPreUpdateNode().asExpr()
+ outer = nodeFrom.(VariablePartialDefinitionNode).getPreUpdateNode().asExpr()
)
or
// Reverse flow: data that flows from the post-update node of a reference
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
index 0163d1e0ce7..d4c264184d7 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
@@ -109,7 +109,7 @@ class FlowVar extends TFlowVar {
* ```
*/
private module PartialDefinitions {
- abstract class PartialDefinition extends Expr {
+ class PartialDefinition extends Expr {
ControlFlowNode node;
PartialDefinition() {
@@ -216,8 +216,7 @@ private module PartialDefinitions {
VariablePartialDefinition() {
exists(Expr convertedInner |
valueToUpdate(convertedInner, this.getFullyConverted(), node) and
- innerDefinedExpr = convertedInner.getUnconverted() and
- not this instanceof Conversion
+ innerDefinedExpr = convertedInner.getUnconverted()
)
}
@@ -249,11 +248,16 @@ private module PartialDefinitions {
/**
* A partial definition that's a definition by reference.
*/
- class DefinitionByReference extends PartialDefinition {
+ class DefinitionByReference extends VariablePartialDefinition {
DefinitionByReference() { exists(Call c | this = c.getAnArgument() or this = c.getQualifier()) }
}
}
+predicate quickTest(PartialDefinition pd) {
+ pd instanceof DefinitionByReference and
+ pd instanceof IteratorPartialDefinition
+}
+
import PartialDefinitions
private import FlowVar_internal
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll
index c8d963866a1..f52c3cddf7e 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll
@@ -31,6 +31,11 @@ predicate localTaintStep(DataFlow::Node src, DataFlow::Node sink) {
*/
predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
localAdditionalTaintStep(src, sink)
+ or
+ exists(FunctionCall call, int i |
+ sink.(DataFlow::IteratorPartialDefinitionNode).getPartialDefinition().definesExpressions(_, call.getArgument(i)) and
+ src.(DataFlow::RefParameterFinalValueNode).getParameter() = call.getTarget().getParameter(i)
+ )
}
/**
@@ -258,9 +263,9 @@ private predicate exprToPartialDefinitionStep(Expr exprIn, Expr exprOut) {
}
private predicate iteratorDereference(Call c) {
- c.getTarget() instanceof IteratorArrayMemberOperator
- or
- c.getTarget() instanceof IteratorPointerDereferenceMemberOperator
- or
- c.getTarget() instanceof IteratorPointerDereferenceOperator
+ c.getTarget() instanceof IteratorArrayMemberOperator
+ or
+ c.getTarget() instanceof IteratorPointerDereferenceMemberOperator
+ or
+ c.getTarget() instanceof IteratorPointerDereferenceOperator
}
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
index 153385a202d..4fc63acbad2 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
@@ -331,7 +331,7 @@ void taint_vector_output_iterator(std::vector::iterator iter) {
}
void test_vector_output_iterator(int b) {
- std::vector v1(10), v2(10), v3(10), v4(10), v5(10), v6(10), v7(10), v8(10);
+ std::vector v1(10), v2(10), v3(10), v4(10), v5(10), v6(10), v7(10), v8(10), v9(10);
std::vector::iterator i1 = v1.begin();
*i1 = source();
@@ -379,4 +379,11 @@ void test_vector_output_iterator(int b) {
sink(v8); // tainted [NOT DETECTED by IR]
*i8 = 1;
sink(v8);
+
+ std::vector::iterator i9 = v9.begin();
+
+ *i9 = source();
+ taint_vector_output_iterator(i9);
+
+ sink(v9);
}
From 086d074a26e55d45ff6e7c70a91124eee0c3fac7 Mon Sep 17 00:00:00 2001
From: Robert Marsh
Date: Wed, 16 Sep 2020 12:48:38 -0700
Subject: [PATCH 019/411] C++: make PartialDefinition abstract
---
.../src/semmle/code/cpp/dataflow/internal/FlowVar.qll | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
index d4c264184d7..45a537f8049 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
@@ -109,16 +109,16 @@ class FlowVar extends TFlowVar {
* ```
*/
private module PartialDefinitions {
- class PartialDefinition extends Expr {
+ abstract class PartialDefinition extends Expr {
ControlFlowNode node;
PartialDefinition() {
not this instanceof Conversion
}
- deprecated predicate partiallyDefines(Variable v) { none() }
+ deprecated abstract predicate partiallyDefines(Variable v);
- deprecated predicate partiallyDefinesThis(ThisExpr e) { none() }
+ deprecated abstract predicate partiallyDefinesThis(ThisExpr e);
/**
* Gets the subBasicBlock where this `PartialDefinition` is defined.
@@ -131,7 +131,7 @@ private module PartialDefinitions {
*/
// does this work with a dispred?
pragma[noinline]
- predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn) { none() }
+ abstract predicate partiallyDefinesVariableAt(Variable v, ControlFlowNode cfn);
/**
* Holds if this partial definition may modify `inner` (or what it points
@@ -141,7 +141,7 @@ private module PartialDefinitions {
* - `inner` = `... .x`, `outer` = `&...`
* - `inner` = `a`, `outer` = `*`
*/
- predicate definesExpressions(Expr inner, Expr outer) { none() }
+ abstract predicate definesExpressions(Expr inner, Expr outer);
/**
* Gets the location of this element, adjusted to avoid unknown locations
From 44c5233459a67643a405200398fb5dc70c60fea2 Mon Sep 17 00:00:00 2001
From: Robert Marsh
Date: Wed, 16 Sep 2020 12:49:15 -0700
Subject: [PATCH 020/411] C++: accept test output
---
.../dataflow/taint-tests/localTaint.expected | 116 ++++++++++--------
.../dataflow/taint-tests/taint.expected | 2 +
.../dataflow/taint-tests/test_diff.expected | 2 +
3 files changed, 72 insertions(+), 48 deletions(-)
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
index 396fecf212f..e5e4905e395 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
@@ -2972,9 +2972,9 @@
| vector.cpp:255:3:255:4 | ref arg v6 | vector.cpp:261:8:261:9 | v6 | |
| vector.cpp:255:3:255:4 | ref arg v6 | vector.cpp:262:2:262:2 | v6 | |
| vector.cpp:255:13:255:14 | call to iterator | vector.cpp:255:3:255:4 | ref arg v6 | TAINT |
+| vector.cpp:255:13:255:14 | call to iterator [post update] | vector.cpp:277:1:277:1 | v3 | |
| vector.cpp:255:13:255:14 | i1 | vector.cpp:255:13:255:14 | call to iterator | |
-| vector.cpp:255:13:255:14 | ref arg call to iterator | vector.cpp:277:1:277:1 | v3 | |
-| vector.cpp:255:13:255:14 | ref arg i1 | vector.cpp:277:1:277:1 | v3 | |
+| vector.cpp:255:13:255:14 | i1 [post update] | vector.cpp:277:1:277:1 | v3 | |
| vector.cpp:255:17:255:18 | call to iterator | vector.cpp:255:3:255:4 | ref arg v6 | TAINT |
| vector.cpp:255:17:255:18 | i2 | vector.cpp:255:17:255:18 | call to iterator | |
| vector.cpp:257:8:257:9 | ref arg v4 | vector.cpp:262:2:262:2 | v4 | |
@@ -3192,57 +3192,60 @@
| vector.cpp:333:38:333:38 | b | vector.cpp:368:5:368:5 | b | |
| vector.cpp:334:22:334:24 | call to vector | vector.cpp:336:34:336:35 | v1 | |
| vector.cpp:334:22:334:24 | call to vector | vector.cpp:338:7:338:8 | v1 | |
-| vector.cpp:334:22:334:24 | call to vector | vector.cpp:382:1:382:1 | v1 | |
+| vector.cpp:334:22:334:24 | call to vector | vector.cpp:389:1:389:1 | v1 | |
| vector.cpp:334:30:334:32 | call to vector | vector.cpp:340:38:340:39 | v2 | |
| vector.cpp:334:30:334:32 | call to vector | vector.cpp:340:56:340:57 | v2 | |
| vector.cpp:334:30:334:32 | call to vector | vector.cpp:343:7:343:8 | v2 | |
-| vector.cpp:334:30:334:32 | call to vector | vector.cpp:382:1:382:1 | v2 | |
+| vector.cpp:334:30:334:32 | call to vector | vector.cpp:389:1:389:1 | v2 | |
| vector.cpp:334:38:334:40 | call to vector | vector.cpp:345:15:345:16 | v3 | |
| vector.cpp:334:38:334:40 | call to vector | vector.cpp:348:7:348:8 | v3 | |
-| vector.cpp:334:38:334:40 | call to vector | vector.cpp:382:1:382:1 | v3 | |
+| vector.cpp:334:38:334:40 | call to vector | vector.cpp:389:1:389:1 | v3 | |
| vector.cpp:334:46:334:48 | call to vector | vector.cpp:350:38:350:39 | v4 | |
| vector.cpp:334:46:334:48 | call to vector | vector.cpp:350:56:350:57 | v4 | |
| vector.cpp:334:46:334:48 | call to vector | vector.cpp:353:7:353:8 | v4 | |
-| vector.cpp:334:46:334:48 | call to vector | vector.cpp:382:1:382:1 | v4 | |
+| vector.cpp:334:46:334:48 | call to vector | vector.cpp:389:1:389:1 | v4 | |
| vector.cpp:334:54:334:56 | call to vector | vector.cpp:355:34:355:35 | v5 | |
| vector.cpp:334:54:334:56 | call to vector | vector.cpp:357:7:357:8 | v5 | |
| vector.cpp:334:54:334:56 | call to vector | vector.cpp:359:7:359:8 | v5 | |
-| vector.cpp:334:54:334:56 | call to vector | vector.cpp:382:1:382:1 | v5 | |
+| vector.cpp:334:54:334:56 | call to vector | vector.cpp:389:1:389:1 | v5 | |
| vector.cpp:334:62:334:64 | call to vector | vector.cpp:361:34:361:35 | v6 | |
| vector.cpp:334:62:334:64 | call to vector | vector.cpp:363:7:363:8 | v6 | |
| vector.cpp:334:62:334:64 | call to vector | vector.cpp:364:2:364:3 | v6 | |
| vector.cpp:334:62:334:64 | call to vector | vector.cpp:365:7:365:8 | v6 | |
-| vector.cpp:334:62:334:64 | call to vector | vector.cpp:382:1:382:1 | v6 | |
+| vector.cpp:334:62:334:64 | call to vector | vector.cpp:389:1:389:1 | v6 | |
| vector.cpp:334:70:334:72 | call to vector | vector.cpp:367:34:367:35 | v7 | |
| vector.cpp:334:70:334:72 | call to vector | vector.cpp:370:8:370:9 | v7 | |
| vector.cpp:334:70:334:72 | call to vector | vector.cpp:373:8:373:9 | v7 | |
| vector.cpp:334:70:334:72 | call to vector | vector.cpp:375:7:375:8 | v7 | |
-| vector.cpp:334:70:334:72 | call to vector | vector.cpp:382:1:382:1 | v7 | |
+| vector.cpp:334:70:334:72 | call to vector | vector.cpp:389:1:389:1 | v7 | |
| vector.cpp:334:78:334:80 | call to vector | vector.cpp:377:34:377:35 | v8 | |
| vector.cpp:334:78:334:80 | call to vector | vector.cpp:379:7:379:8 | v8 | |
| vector.cpp:334:78:334:80 | call to vector | vector.cpp:381:7:381:8 | v8 | |
-| vector.cpp:334:78:334:80 | call to vector | vector.cpp:382:1:382:1 | v8 | |
+| vector.cpp:334:78:334:80 | call to vector | vector.cpp:389:1:389:1 | v8 | |
+| vector.cpp:334:86:334:88 | call to vector | vector.cpp:383:34:383:35 | v9 | |
+| vector.cpp:334:86:334:88 | call to vector | vector.cpp:388:7:388:8 | v9 | |
+| vector.cpp:334:86:334:88 | call to vector | vector.cpp:389:1:389:1 | v9 | |
| vector.cpp:336:34:336:35 | ref arg v1 | vector.cpp:338:7:338:8 | v1 | |
-| vector.cpp:336:34:336:35 | ref arg v1 | vector.cpp:382:1:382:1 | v1 | |
+| vector.cpp:336:34:336:35 | ref arg v1 | vector.cpp:389:1:389:1 | v1 | |
| vector.cpp:336:34:336:35 | v1 | vector.cpp:336:37:336:41 | call to begin | TAINT |
| vector.cpp:336:37:336:41 | call to begin | vector.cpp:337:3:337:4 | i1 | |
| vector.cpp:337:2:337:2 | call to operator* [post update] | vector.cpp:338:7:338:8 | v1 | |
-| vector.cpp:337:2:337:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v1 | |
+| vector.cpp:337:2:337:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v1 | |
| vector.cpp:337:2:337:15 | ... = ... | vector.cpp:337:2:337:2 | call to operator* [post update] | |
| vector.cpp:337:3:337:4 | i1 | vector.cpp:337:2:337:2 | call to operator* | TAINT |
| vector.cpp:337:8:337:13 | call to source | vector.cpp:337:2:337:2 | call to operator* [post update] | TAINT |
| vector.cpp:337:8:337:13 | call to source | vector.cpp:337:2:337:15 | ... = ... | |
-| vector.cpp:338:7:338:8 | ref arg v1 | vector.cpp:382:1:382:1 | v1 | |
+| vector.cpp:338:7:338:8 | ref arg v1 | vector.cpp:389:1:389:1 | v1 | |
| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:340:56:340:57 | v2 | |
| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:343:7:343:8 | v2 | |
-| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:382:1:382:1 | v2 | |
+| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:389:1:389:1 | v2 | |
| vector.cpp:340:38:340:39 | v2 | vector.cpp:340:41:340:45 | call to begin | TAINT |
| vector.cpp:340:41:340:45 | call to begin | vector.cpp:340:50:340:51 | it | |
| vector.cpp:340:41:340:45 | call to begin | vector.cpp:340:68:340:69 | it | |
| vector.cpp:340:41:340:45 | call to begin | vector.cpp:341:4:341:5 | it | |
| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:340:56:340:57 | v2 | |
| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:343:7:343:8 | v2 | |
-| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:382:1:382:1 | v2 | |
+| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:389:1:389:1 | v2 | |
| vector.cpp:340:56:340:57 | v2 | vector.cpp:340:59:340:61 | call to end | TAINT |
| vector.cpp:340:68:340:69 | it | vector.cpp:340:66:340:66 | call to operator++ | TAINT |
| vector.cpp:340:68:340:69 | ref arg it | vector.cpp:340:50:340:51 | it | |
@@ -3250,12 +3253,12 @@
| vector.cpp:340:68:340:69 | ref arg it | vector.cpp:341:4:341:5 | it | |
| vector.cpp:341:3:341:3 | call to operator* [post update] | vector.cpp:340:56:340:57 | v2 | |
| vector.cpp:341:3:341:3 | call to operator* [post update] | vector.cpp:343:7:343:8 | v2 | |
-| vector.cpp:341:3:341:3 | call to operator* [post update] | vector.cpp:382:1:382:1 | v2 | |
+| vector.cpp:341:3:341:3 | call to operator* [post update] | vector.cpp:389:1:389:1 | v2 | |
| vector.cpp:341:3:341:16 | ... = ... | vector.cpp:341:3:341:3 | call to operator* [post update] | |
| vector.cpp:341:4:341:5 | it | vector.cpp:341:3:341:3 | call to operator* | TAINT |
| vector.cpp:341:9:341:14 | call to source | vector.cpp:341:3:341:3 | call to operator* [post update] | TAINT |
| vector.cpp:341:9:341:14 | call to source | vector.cpp:341:3:341:16 | ... = ... | |
-| vector.cpp:343:7:343:8 | ref arg v2 | vector.cpp:382:1:382:1 | v2 | |
+| vector.cpp:343:7:343:8 | ref arg v2 | vector.cpp:389:1:389:1 | v2 | |
| vector.cpp:345:15:345:15 | (__begin) | vector.cpp:345:15:345:15 | call to operator* | TAINT |
| vector.cpp:345:15:345:15 | (__begin) | vector.cpp:345:15:345:15 | call to operator++ | TAINT |
| vector.cpp:345:15:345:15 | (__end) | vector.cpp:345:15:345:15 | call to iterator | |
@@ -3273,119 +3276,136 @@
| vector.cpp:345:15:345:16 | v3 | vector.cpp:345:15:345:15 | (__range) | |
| vector.cpp:345:15:345:16 | v3 | vector.cpp:345:15:345:15 | call to operator* | TAINT |
| vector.cpp:346:7:346:12 | call to source | vector.cpp:346:3:346:14 | ... = ... | |
-| vector.cpp:348:7:348:8 | ref arg v3 | vector.cpp:382:1:382:1 | v3 | |
+| vector.cpp:348:7:348:8 | ref arg v3 | vector.cpp:389:1:389:1 | v3 | |
| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:350:56:350:57 | v4 | |
| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:353:7:353:8 | v4 | |
-| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:382:1:382:1 | v4 | |
+| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:389:1:389:1 | v4 | |
| vector.cpp:350:38:350:39 | v4 | vector.cpp:350:41:350:45 | call to begin | TAINT |
| vector.cpp:350:41:350:45 | call to begin | vector.cpp:350:50:350:51 | it | |
| vector.cpp:350:41:350:45 | call to begin | vector.cpp:350:68:350:69 | it | |
| vector.cpp:350:41:350:45 | call to begin | vector.cpp:351:32:351:33 | it | |
| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:350:56:350:57 | v4 | |
| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:353:7:353:8 | v4 | |
-| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:382:1:382:1 | v4 | |
+| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:389:1:389:1 | v4 | |
| vector.cpp:350:56:350:57 | v4 | vector.cpp:350:59:350:61 | call to end | TAINT |
| vector.cpp:350:68:350:69 | it | vector.cpp:350:66:350:66 | call to operator++ | TAINT |
| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:50:350:51 | it | |
| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:68:350:69 | it | |
| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:351:32:351:33 | it | |
+| vector.cpp:351:32:351:33 | call to iterator [post update] | vector.cpp:350:56:350:57 | v4 | |
+| vector.cpp:351:32:351:33 | call to iterator [post update] | vector.cpp:353:7:353:8 | v4 | |
+| vector.cpp:351:32:351:33 | call to iterator [post update] | vector.cpp:389:1:389:1 | v4 | |
| vector.cpp:351:32:351:33 | it | vector.cpp:351:32:351:33 | call to iterator | |
-| vector.cpp:351:32:351:33 | ref arg call to iterator | vector.cpp:350:56:350:57 | v4 | |
-| vector.cpp:351:32:351:33 | ref arg call to iterator | vector.cpp:353:7:353:8 | v4 | |
-| vector.cpp:351:32:351:33 | ref arg call to iterator | vector.cpp:382:1:382:1 | v4 | |
-| vector.cpp:351:32:351:33 | ref arg it | vector.cpp:350:56:350:57 | v4 | |
-| vector.cpp:351:32:351:33 | ref arg it | vector.cpp:353:7:353:8 | v4 | |
-| vector.cpp:351:32:351:33 | ref arg it | vector.cpp:382:1:382:1 | v4 | |
-| vector.cpp:353:7:353:8 | ref arg v4 | vector.cpp:382:1:382:1 | v4 | |
+| vector.cpp:351:32:351:33 | it [post update] | vector.cpp:350:56:350:57 | v4 | |
+| vector.cpp:351:32:351:33 | it [post update] | vector.cpp:353:7:353:8 | v4 | |
+| vector.cpp:351:32:351:33 | it [post update] | vector.cpp:389:1:389:1 | v4 | |
+| vector.cpp:353:7:353:8 | ref arg v4 | vector.cpp:389:1:389:1 | v4 | |
| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:357:7:357:8 | v5 | |
| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:359:7:359:8 | v5 | |
-| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:382:1:382:1 | v5 | |
+| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:389:1:389:1 | v5 | |
| vector.cpp:355:34:355:35 | v5 | vector.cpp:355:37:355:41 | call to begin | TAINT |
| vector.cpp:355:37:355:41 | call to begin | vector.cpp:356:3:356:4 | i5 | |
| vector.cpp:355:37:355:41 | call to begin | vector.cpp:358:3:358:4 | i5 | |
| vector.cpp:356:2:356:2 | call to operator* [post update] | vector.cpp:357:7:357:8 | v5 | |
| vector.cpp:356:2:356:2 | call to operator* [post update] | vector.cpp:359:7:359:8 | v5 | |
-| vector.cpp:356:2:356:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v5 | |
+| vector.cpp:356:2:356:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v5 | |
| vector.cpp:356:2:356:15 | ... = ... | vector.cpp:356:2:356:2 | call to operator* [post update] | |
| vector.cpp:356:3:356:4 | i5 | vector.cpp:356:2:356:2 | call to operator* | TAINT |
| vector.cpp:356:8:356:13 | call to source | vector.cpp:356:2:356:2 | call to operator* [post update] | TAINT |
| vector.cpp:356:8:356:13 | call to source | vector.cpp:356:2:356:15 | ... = ... | |
| vector.cpp:357:7:357:8 | ref arg v5 | vector.cpp:359:7:359:8 | v5 | |
-| vector.cpp:357:7:357:8 | ref arg v5 | vector.cpp:382:1:382:1 | v5 | |
+| vector.cpp:357:7:357:8 | ref arg v5 | vector.cpp:389:1:389:1 | v5 | |
| vector.cpp:358:2:358:2 | call to operator* [post update] | vector.cpp:359:7:359:8 | v5 | |
-| vector.cpp:358:2:358:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v5 | |
+| vector.cpp:358:2:358:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v5 | |
| vector.cpp:358:2:358:8 | ... = ... | vector.cpp:358:2:358:2 | call to operator* [post update] | |
| vector.cpp:358:3:358:4 | i5 | vector.cpp:358:2:358:2 | call to operator* | TAINT |
| vector.cpp:358:8:358:8 | 1 | vector.cpp:358:2:358:2 | call to operator* [post update] | TAINT |
| vector.cpp:358:8:358:8 | 1 | vector.cpp:358:2:358:8 | ... = ... | |
-| vector.cpp:359:7:359:8 | ref arg v5 | vector.cpp:382:1:382:1 | v5 | |
+| vector.cpp:359:7:359:8 | ref arg v5 | vector.cpp:389:1:389:1 | v5 | |
| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:363:7:363:8 | v6 | |
| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:364:2:364:3 | v6 | |
| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:365:7:365:8 | v6 | |
-| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:382:1:382:1 | v6 | |
+| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:389:1:389:1 | v6 | |
| vector.cpp:361:34:361:35 | v6 | vector.cpp:361:37:361:41 | call to begin | TAINT |
| vector.cpp:361:37:361:41 | call to begin | vector.cpp:362:3:362:4 | i6 | |
| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:363:7:363:8 | v6 | |
| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:364:2:364:3 | v6 | |
| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:365:7:365:8 | v6 | |
-| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v6 | |
+| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v6 | |
| vector.cpp:362:2:362:15 | ... = ... | vector.cpp:362:2:362:2 | call to operator* [post update] | |
| vector.cpp:362:3:362:4 | i6 | vector.cpp:362:2:362:2 | call to operator* | TAINT |
| vector.cpp:362:8:362:13 | call to source | vector.cpp:362:2:362:2 | call to operator* [post update] | TAINT |
| vector.cpp:362:8:362:13 | call to source | vector.cpp:362:2:362:15 | ... = ... | |
| vector.cpp:363:7:363:8 | ref arg v6 | vector.cpp:364:2:364:3 | v6 | |
| vector.cpp:363:7:363:8 | ref arg v6 | vector.cpp:365:7:365:8 | v6 | |
-| vector.cpp:363:7:363:8 | ref arg v6 | vector.cpp:382:1:382:1 | v6 | |
+| vector.cpp:363:7:363:8 | ref arg v6 | vector.cpp:389:1:389:1 | v6 | |
| vector.cpp:364:2:364:3 | ref arg v6 | vector.cpp:365:7:365:8 | v6 | |
-| vector.cpp:364:2:364:3 | ref arg v6 | vector.cpp:382:1:382:1 | v6 | |
+| vector.cpp:364:2:364:3 | ref arg v6 | vector.cpp:389:1:389:1 | v6 | |
| vector.cpp:364:7:364:26 | call to vector | vector.cpp:364:2:364:3 | ref arg v6 | TAINT |
| vector.cpp:364:7:364:26 | call to vector | vector.cpp:364:5:364:5 | call to operator= | TAINT |
-| vector.cpp:365:7:365:8 | ref arg v6 | vector.cpp:382:1:382:1 | v6 | |
+| vector.cpp:365:7:365:8 | ref arg v6 | vector.cpp:389:1:389:1 | v6 | |
| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:370:8:370:9 | v7 | |
| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:373:8:373:9 | v7 | |
| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:375:7:375:8 | v7 | |
-| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:382:1:382:1 | v7 | |
+| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:389:1:389:1 | v7 | |
| vector.cpp:367:34:367:35 | v7 | vector.cpp:367:37:367:41 | call to begin | TAINT |
| vector.cpp:367:37:367:41 | call to begin | vector.cpp:369:4:369:5 | i7 | |
| vector.cpp:367:37:367:41 | call to begin | vector.cpp:372:4:372:5 | i7 | |
| vector.cpp:369:3:369:3 | call to operator* [post update] | vector.cpp:370:8:370:9 | v7 | |
| vector.cpp:369:3:369:3 | call to operator* [post update] | vector.cpp:375:7:375:8 | v7 | |
-| vector.cpp:369:3:369:3 | call to operator* [post update] | vector.cpp:382:1:382:1 | v7 | |
+| vector.cpp:369:3:369:3 | call to operator* [post update] | vector.cpp:389:1:389:1 | v7 | |
| vector.cpp:369:3:369:16 | ... = ... | vector.cpp:369:3:369:3 | call to operator* [post update] | |
| vector.cpp:369:4:369:5 | i7 | vector.cpp:369:3:369:3 | call to operator* | TAINT |
| vector.cpp:369:9:369:14 | call to source | vector.cpp:369:3:369:3 | call to operator* [post update] | TAINT |
| vector.cpp:369:9:369:14 | call to source | vector.cpp:369:3:369:16 | ... = ... | |
| vector.cpp:370:8:370:9 | ref arg v7 | vector.cpp:375:7:375:8 | v7 | |
-| vector.cpp:370:8:370:9 | ref arg v7 | vector.cpp:382:1:382:1 | v7 | |
+| vector.cpp:370:8:370:9 | ref arg v7 | vector.cpp:389:1:389:1 | v7 | |
| vector.cpp:372:3:372:3 | call to operator* [post update] | vector.cpp:373:8:373:9 | v7 | |
| vector.cpp:372:3:372:3 | call to operator* [post update] | vector.cpp:375:7:375:8 | v7 | |
-| vector.cpp:372:3:372:3 | call to operator* [post update] | vector.cpp:382:1:382:1 | v7 | |
+| vector.cpp:372:3:372:3 | call to operator* [post update] | vector.cpp:389:1:389:1 | v7 | |
| vector.cpp:372:3:372:9 | ... = ... | vector.cpp:372:3:372:3 | call to operator* [post update] | |
| vector.cpp:372:4:372:5 | i7 | vector.cpp:372:3:372:3 | call to operator* | TAINT |
| vector.cpp:372:9:372:9 | 1 | vector.cpp:372:3:372:3 | call to operator* [post update] | TAINT |
| vector.cpp:372:9:372:9 | 1 | vector.cpp:372:3:372:9 | ... = ... | |
| vector.cpp:373:8:373:9 | ref arg v7 | vector.cpp:375:7:375:8 | v7 | |
-| vector.cpp:373:8:373:9 | ref arg v7 | vector.cpp:382:1:382:1 | v7 | |
-| vector.cpp:375:7:375:8 | ref arg v7 | vector.cpp:382:1:382:1 | v7 | |
+| vector.cpp:373:8:373:9 | ref arg v7 | vector.cpp:389:1:389:1 | v7 | |
+| vector.cpp:375:7:375:8 | ref arg v7 | vector.cpp:389:1:389:1 | v7 | |
| vector.cpp:377:34:377:35 | ref arg v8 | vector.cpp:379:7:379:8 | v8 | |
| vector.cpp:377:34:377:35 | ref arg v8 | vector.cpp:381:7:381:8 | v8 | |
-| vector.cpp:377:34:377:35 | ref arg v8 | vector.cpp:382:1:382:1 | v8 | |
+| vector.cpp:377:34:377:35 | ref arg v8 | vector.cpp:389:1:389:1 | v8 | |
| vector.cpp:377:34:377:35 | v8 | vector.cpp:377:37:377:41 | call to begin | TAINT |
| vector.cpp:377:37:377:41 | call to begin | vector.cpp:378:3:378:4 | i8 | |
| vector.cpp:377:37:377:41 | call to begin | vector.cpp:380:3:380:4 | i8 | |
| vector.cpp:378:2:378:2 | call to operator* [post update] | vector.cpp:379:7:379:8 | v8 | |
| vector.cpp:378:2:378:2 | call to operator* [post update] | vector.cpp:381:7:381:8 | v8 | |
-| vector.cpp:378:2:378:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v8 | |
+| vector.cpp:378:2:378:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v8 | |
| vector.cpp:378:2:378:15 | ... = ... | vector.cpp:378:2:378:2 | call to operator* [post update] | |
| vector.cpp:378:3:378:4 | i8 | vector.cpp:378:2:378:2 | call to operator* | TAINT |
| vector.cpp:378:8:378:13 | call to source | vector.cpp:378:2:378:2 | call to operator* [post update] | TAINT |
| vector.cpp:378:8:378:13 | call to source | vector.cpp:378:2:378:15 | ... = ... | |
| vector.cpp:379:7:379:8 | ref arg v8 | vector.cpp:381:7:381:8 | v8 | |
-| vector.cpp:379:7:379:8 | ref arg v8 | vector.cpp:382:1:382:1 | v8 | |
+| vector.cpp:379:7:379:8 | ref arg v8 | vector.cpp:389:1:389:1 | v8 | |
| vector.cpp:380:2:380:2 | call to operator* [post update] | vector.cpp:381:7:381:8 | v8 | |
-| vector.cpp:380:2:380:2 | call to operator* [post update] | vector.cpp:382:1:382:1 | v8 | |
+| vector.cpp:380:2:380:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v8 | |
| vector.cpp:380:2:380:8 | ... = ... | vector.cpp:380:2:380:2 | call to operator* [post update] | |
| vector.cpp:380:3:380:4 | i8 | vector.cpp:380:2:380:2 | call to operator* | TAINT |
| vector.cpp:380:8:380:8 | 1 | vector.cpp:380:2:380:2 | call to operator* [post update] | TAINT |
| vector.cpp:380:8:380:8 | 1 | vector.cpp:380:2:380:8 | ... = ... | |
-| vector.cpp:381:7:381:8 | ref arg v8 | vector.cpp:382:1:382:1 | v8 | |
+| vector.cpp:381:7:381:8 | ref arg v8 | vector.cpp:389:1:389:1 | v8 | |
+| vector.cpp:383:34:383:35 | ref arg v9 | vector.cpp:388:7:388:8 | v9 | |
+| vector.cpp:383:34:383:35 | ref arg v9 | vector.cpp:389:1:389:1 | v9 | |
+| vector.cpp:383:34:383:35 | v9 | vector.cpp:383:37:383:41 | call to begin | TAINT |
+| vector.cpp:383:37:383:41 | call to begin | vector.cpp:385:3:385:4 | i9 | |
+| vector.cpp:383:37:383:41 | call to begin | vector.cpp:386:31:386:32 | i9 | |
+| vector.cpp:385:2:385:2 | call to operator* [post update] | vector.cpp:388:7:388:8 | v9 | |
+| vector.cpp:385:2:385:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v9 | |
+| vector.cpp:385:2:385:15 | ... = ... | vector.cpp:385:2:385:2 | call to operator* [post update] | |
+| vector.cpp:385:3:385:4 | i9 | vector.cpp:385:2:385:2 | call to operator* | TAINT |
+| vector.cpp:385:8:385:13 | call to source | vector.cpp:385:2:385:2 | call to operator* [post update] | TAINT |
+| vector.cpp:385:8:385:13 | call to source | vector.cpp:385:2:385:15 | ... = ... | |
+| vector.cpp:386:31:386:32 | call to iterator [post update] | vector.cpp:388:7:388:8 | v9 | |
+| vector.cpp:386:31:386:32 | call to iterator [post update] | vector.cpp:389:1:389:1 | v9 | |
+| vector.cpp:386:31:386:32 | i9 | vector.cpp:386:31:386:32 | call to iterator | |
+| vector.cpp:386:31:386:32 | i9 [post update] | vector.cpp:388:7:388:8 | v9 | |
+| vector.cpp:386:31:386:32 | i9 [post update] | vector.cpp:389:1:389:1 | v9 | |
+| vector.cpp:388:7:388:8 | ref arg v9 | vector.cpp:389:1:389:1 | v9 | |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
index 889e1da17e6..01ef2e1a494 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
@@ -337,3 +337,5 @@
| vector.cpp:375:7:375:8 | v7 | vector.cpp:369:9:369:14 | call to source |
| vector.cpp:379:7:379:8 | v8 | vector.cpp:378:8:378:13 | call to source |
| vector.cpp:381:7:381:8 | v8 | vector.cpp:378:8:378:13 | call to source |
+| vector.cpp:388:7:388:8 | v9 | vector.cpp:330:10:330:15 | call to source |
+| vector.cpp:388:7:388:8 | v9 | vector.cpp:385:8:385:13 | call to source |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected
index 0f6b7a574a5..173bb28f831 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected
@@ -286,3 +286,5 @@
| vector.cpp:375:7:375:8 | vector.cpp:369:9:369:14 | AST only |
| vector.cpp:379:7:379:8 | vector.cpp:378:8:378:13 | AST only |
| vector.cpp:381:7:381:8 | vector.cpp:378:8:378:13 | AST only |
+| vector.cpp:388:7:388:8 | vector.cpp:330:10:330:15 | AST only |
+| vector.cpp:388:7:388:8 | vector.cpp:385:8:385:13 | AST only |
From 107e9770da5ebde3e06ba7fefd5952a0154ed105 Mon Sep 17 00:00:00 2001
From: Robert Marsh
Date: Fri, 18 Sep 2020 14:12:33 -0700
Subject: [PATCH 021/411] C++: remove accidentally committed test code
---
cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll | 5 -----
1 file changed, 5 deletions(-)
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
index 45a537f8049..b9e5eadfcf5 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
@@ -253,11 +253,6 @@ private module PartialDefinitions {
}
}
-predicate quickTest(PartialDefinition pd) {
- pd instanceof DefinitionByReference and
- pd instanceof IteratorPartialDefinition
-}
-
import PartialDefinitions
private import FlowVar_internal
From b84bf5e9bb5a3a4562592a558290d476b68f83d3 Mon Sep 17 00:00:00 2001
From: Robert Marsh
Date: Fri, 18 Sep 2020 14:18:38 -0700
Subject: [PATCH 022/411] C++: QLDoc for IteratorPartialDefinitionNode
---
.../src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
index faa242aec64..d71b3a4ad62 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
@@ -304,6 +304,12 @@ private class VariablePartialDefinitionNode extends PartialDefinitionNode {
override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) }
}
+/**
+ * INTERNAL: do not use.
+ *
+ * A synthetic data flow node used for flow into a collection when an iterator
+ * write occurs in a callee.
+ */
class IteratorPartialDefinitionNode extends PartialDefinitionNode {
override IteratorPartialDefinition pd;
From bd7f5a41d1016b001fa1f8dbf3988fac6d93cfb1 Mon Sep 17 00:00:00 2001
From: Robert Marsh
Date: Fri, 18 Sep 2020 14:19:29 -0700
Subject: [PATCH 023/411] C++: autoformat
---
.../semmle/code/cpp/dataflow/internal/DataFlowUtil.qll | 8 +++-----
cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll | 8 +++-----
2 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
index d71b3a4ad62..963f1a17826 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
@@ -284,12 +284,10 @@ abstract class PostUpdateNode extends Node {
override Location getLocation() { result = getPreUpdateNode().getLocation() }
}
-private abstract class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNode {
+abstract private class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNode {
PartialDefinition pd;
- PartialDefinitionNode() {
- this = TPartialDefinitionNode(pd)
- }
+ PartialDefinitionNode() { this = TPartialDefinitionNode(pd) }
override Location getLocation() { result = pd.getActualLocation() }
@@ -306,7 +304,7 @@ private class VariablePartialDefinitionNode extends PartialDefinitionNode {
/**
* INTERNAL: do not use.
- *
+ *
* A synthetic data flow node used for flow into a collection when an iterator
* write occurs in a callee.
*/
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
index b9e5eadfcf5..13f11f8b275 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
@@ -112,13 +112,11 @@ private module PartialDefinitions {
abstract class PartialDefinition extends Expr {
ControlFlowNode node;
- PartialDefinition() {
- not this instanceof Conversion
- }
+ PartialDefinition() { not this instanceof Conversion }
- deprecated abstract predicate partiallyDefines(Variable v);
+ abstract deprecated predicate partiallyDefines(Variable v);
- deprecated abstract predicate partiallyDefinesThis(ThisExpr e);
+ abstract deprecated predicate partiallyDefinesThis(ThisExpr e);
/**
* Gets the subBasicBlock where this `PartialDefinition` is defined.
From 913881b17b869602b45e37d5044949e1ba72bde8 Mon Sep 17 00:00:00 2001
From: Robert Marsh
Date: Mon, 21 Sep 2020 16:10:37 -0700
Subject: [PATCH 024/411] C++: Add test for iterator false positive
---
.../dataflow/taint-tests/localTaint.expected | 476 ++++++++++--------
.../dataflow/taint-tests/taint.expected | 28 +-
.../dataflow/taint-tests/test_diff.expected | 28 +-
.../dataflow/taint-tests/vector.cpp | 14 +-
4 files changed, 298 insertions(+), 248 deletions(-)
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
index ae2bc9b563e..365216bce3c 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
@@ -3701,224 +3701,258 @@
| vector.cpp:330:3:330:6 | iter | vector.cpp:330:2:330:2 | call to operator* | TAINT |
| vector.cpp:330:10:330:15 | call to source | vector.cpp:330:2:330:2 | call to operator* [post update] | TAINT |
| vector.cpp:330:10:330:15 | call to source | vector.cpp:330:2:330:17 | ... = ... | |
-| vector.cpp:333:38:333:38 | b | vector.cpp:368:5:368:5 | b | |
-| vector.cpp:334:22:334:24 | call to vector | vector.cpp:336:34:336:35 | v1 | |
-| vector.cpp:334:22:334:24 | call to vector | vector.cpp:338:7:338:8 | v1 | |
-| vector.cpp:334:22:334:24 | call to vector | vector.cpp:389:1:389:1 | v1 | |
-| vector.cpp:334:30:334:32 | call to vector | vector.cpp:340:38:340:39 | v2 | |
-| vector.cpp:334:30:334:32 | call to vector | vector.cpp:340:56:340:57 | v2 | |
-| vector.cpp:334:30:334:32 | call to vector | vector.cpp:343:7:343:8 | v2 | |
-| vector.cpp:334:30:334:32 | call to vector | vector.cpp:389:1:389:1 | v2 | |
-| vector.cpp:334:38:334:40 | call to vector | vector.cpp:345:15:345:16 | v3 | |
-| vector.cpp:334:38:334:40 | call to vector | vector.cpp:348:7:348:8 | v3 | |
-| vector.cpp:334:38:334:40 | call to vector | vector.cpp:389:1:389:1 | v3 | |
-| vector.cpp:334:46:334:48 | call to vector | vector.cpp:350:38:350:39 | v4 | |
-| vector.cpp:334:46:334:48 | call to vector | vector.cpp:350:56:350:57 | v4 | |
-| vector.cpp:334:46:334:48 | call to vector | vector.cpp:353:7:353:8 | v4 | |
-| vector.cpp:334:46:334:48 | call to vector | vector.cpp:389:1:389:1 | v4 | |
-| vector.cpp:334:54:334:56 | call to vector | vector.cpp:355:34:355:35 | v5 | |
-| vector.cpp:334:54:334:56 | call to vector | vector.cpp:357:7:357:8 | v5 | |
-| vector.cpp:334:54:334:56 | call to vector | vector.cpp:359:7:359:8 | v5 | |
-| vector.cpp:334:54:334:56 | call to vector | vector.cpp:389:1:389:1 | v5 | |
-| vector.cpp:334:62:334:64 | call to vector | vector.cpp:361:34:361:35 | v6 | |
-| vector.cpp:334:62:334:64 | call to vector | vector.cpp:363:7:363:8 | v6 | |
-| vector.cpp:334:62:334:64 | call to vector | vector.cpp:364:2:364:3 | v6 | |
-| vector.cpp:334:62:334:64 | call to vector | vector.cpp:365:7:365:8 | v6 | |
-| vector.cpp:334:62:334:64 | call to vector | vector.cpp:389:1:389:1 | v6 | |
-| vector.cpp:334:70:334:72 | call to vector | vector.cpp:367:34:367:35 | v7 | |
-| vector.cpp:334:70:334:72 | call to vector | vector.cpp:370:8:370:9 | v7 | |
-| vector.cpp:334:70:334:72 | call to vector | vector.cpp:373:8:373:9 | v7 | |
-| vector.cpp:334:70:334:72 | call to vector | vector.cpp:375:7:375:8 | v7 | |
-| vector.cpp:334:70:334:72 | call to vector | vector.cpp:389:1:389:1 | v7 | |
-| vector.cpp:334:78:334:80 | call to vector | vector.cpp:377:34:377:35 | v8 | |
-| vector.cpp:334:78:334:80 | call to vector | vector.cpp:379:7:379:8 | v8 | |
-| vector.cpp:334:78:334:80 | call to vector | vector.cpp:381:7:381:8 | v8 | |
-| vector.cpp:334:78:334:80 | call to vector | vector.cpp:389:1:389:1 | v8 | |
-| vector.cpp:334:86:334:88 | call to vector | vector.cpp:383:34:383:35 | v9 | |
-| vector.cpp:334:86:334:88 | call to vector | vector.cpp:388:7:388:8 | v9 | |
-| vector.cpp:334:86:334:88 | call to vector | vector.cpp:389:1:389:1 | v9 | |
-| vector.cpp:336:34:336:35 | ref arg v1 | vector.cpp:338:7:338:8 | v1 | |
-| vector.cpp:336:34:336:35 | ref arg v1 | vector.cpp:389:1:389:1 | v1 | |
-| vector.cpp:336:34:336:35 | v1 | vector.cpp:336:37:336:41 | call to begin | TAINT |
-| vector.cpp:336:37:336:41 | call to begin | vector.cpp:337:3:337:4 | i1 | |
-| vector.cpp:337:2:337:2 | call to operator* [post update] | vector.cpp:338:7:338:8 | v1 | |
-| vector.cpp:337:2:337:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v1 | |
-| vector.cpp:337:2:337:15 | ... = ... | vector.cpp:337:2:337:2 | call to operator* [post update] | |
-| vector.cpp:337:3:337:4 | i1 | vector.cpp:337:2:337:2 | call to operator* | TAINT |
-| vector.cpp:337:8:337:13 | call to source | vector.cpp:337:2:337:2 | call to operator* [post update] | TAINT |
-| vector.cpp:337:8:337:13 | call to source | vector.cpp:337:2:337:15 | ... = ... | |
-| vector.cpp:338:7:338:8 | ref arg v1 | vector.cpp:389:1:389:1 | v1 | |
-| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:340:56:340:57 | v2 | |
-| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:343:7:343:8 | v2 | |
-| vector.cpp:340:38:340:39 | ref arg v2 | vector.cpp:389:1:389:1 | v2 | |
-| vector.cpp:340:38:340:39 | v2 | vector.cpp:340:41:340:45 | call to begin | TAINT |
-| vector.cpp:340:41:340:45 | call to begin | vector.cpp:340:50:340:51 | it | |
-| vector.cpp:340:41:340:45 | call to begin | vector.cpp:340:68:340:69 | it | |
-| vector.cpp:340:41:340:45 | call to begin | vector.cpp:341:4:341:5 | it | |
-| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:340:56:340:57 | v2 | |
-| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:343:7:343:8 | v2 | |
-| vector.cpp:340:56:340:57 | ref arg v2 | vector.cpp:389:1:389:1 | v2 | |
-| vector.cpp:340:56:340:57 | v2 | vector.cpp:340:59:340:61 | call to end | TAINT |
-| vector.cpp:340:68:340:69 | it | vector.cpp:340:66:340:66 | call to operator++ | |
-| vector.cpp:340:68:340:69 | ref arg it | vector.cpp:340:50:340:51 | it | |
-| vector.cpp:340:68:340:69 | ref arg it | vector.cpp:340:68:340:69 | it | |
-| vector.cpp:340:68:340:69 | ref arg it | vector.cpp:341:4:341:5 | it | |
-| vector.cpp:341:3:341:3 | call to operator* [post update] | vector.cpp:340:56:340:57 | v2 | |
-| vector.cpp:341:3:341:3 | call to operator* [post update] | vector.cpp:343:7:343:8 | v2 | |
-| vector.cpp:341:3:341:3 | call to operator* [post update] | vector.cpp:389:1:389:1 | v2 | |
-| vector.cpp:341:3:341:16 | ... = ... | vector.cpp:341:3:341:3 | call to operator* [post update] | |
-| vector.cpp:341:4:341:5 | it | vector.cpp:341:3:341:3 | call to operator* | TAINT |
-| vector.cpp:341:9:341:14 | call to source | vector.cpp:341:3:341:3 | call to operator* [post update] | TAINT |
-| vector.cpp:341:9:341:14 | call to source | vector.cpp:341:3:341:16 | ... = ... | |
-| vector.cpp:343:7:343:8 | ref arg v2 | vector.cpp:389:1:389:1 | v2 | |
-| vector.cpp:345:15:345:15 | (__begin) | vector.cpp:345:15:345:15 | call to operator* | TAINT |
-| vector.cpp:345:15:345:15 | (__begin) | vector.cpp:345:15:345:15 | call to operator++ | |
-| vector.cpp:345:15:345:15 | (__end) | vector.cpp:345:15:345:15 | call to iterator | |
-| vector.cpp:345:15:345:15 | (__range) | vector.cpp:345:15:345:15 | call to begin | TAINT |
-| vector.cpp:345:15:345:15 | (__range) | vector.cpp:345:15:345:15 | call to end | TAINT |
-| vector.cpp:345:15:345:15 | call to begin | vector.cpp:345:15:345:15 | (__begin) | |
-| vector.cpp:345:15:345:15 | call to begin | vector.cpp:345:15:345:15 | (__begin) | |
-| vector.cpp:345:15:345:15 | call to begin | vector.cpp:345:15:345:15 | (__begin) | |
-| vector.cpp:345:15:345:15 | call to end | vector.cpp:345:15:345:15 | (__end) | |
-| vector.cpp:345:15:345:15 | ref arg (__begin) | vector.cpp:345:15:345:15 | (__begin) | |
-| vector.cpp:345:15:345:15 | ref arg (__begin) | vector.cpp:345:15:345:15 | (__begin) | |
-| vector.cpp:345:15:345:15 | ref arg (__begin) | vector.cpp:345:15:345:15 | (__begin) | |
-| vector.cpp:345:15:345:15 | ref arg (__range) | vector.cpp:345:15:345:15 | (__range) | |
-| vector.cpp:345:15:345:16 | v3 | vector.cpp:345:15:345:15 | (__range) | |
-| vector.cpp:345:15:345:16 | v3 | vector.cpp:345:15:345:15 | (__range) | |
-| vector.cpp:345:15:345:16 | v3 | vector.cpp:345:15:345:15 | call to operator* | TAINT |
-| vector.cpp:346:3:346:14 | ... = ... | vector.cpp:346:3:346:3 | x [post update] | |
-| vector.cpp:346:7:346:12 | call to source | vector.cpp:346:3:346:14 | ... = ... | |
-| vector.cpp:348:7:348:8 | ref arg v3 | vector.cpp:389:1:389:1 | v3 | |
-| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:350:56:350:57 | v4 | |
-| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:353:7:353:8 | v4 | |
-| vector.cpp:350:38:350:39 | ref arg v4 | vector.cpp:389:1:389:1 | v4 | |
-| vector.cpp:350:38:350:39 | v4 | vector.cpp:350:41:350:45 | call to begin | TAINT |
-| vector.cpp:350:41:350:45 | call to begin | vector.cpp:350:50:350:51 | it | |
-| vector.cpp:350:41:350:45 | call to begin | vector.cpp:350:68:350:69 | it | |
-| vector.cpp:350:41:350:45 | call to begin | vector.cpp:351:32:351:33 | it | |
-| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:350:56:350:57 | v4 | |
-| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:353:7:353:8 | v4 | |
-| vector.cpp:350:56:350:57 | ref arg v4 | vector.cpp:389:1:389:1 | v4 | |
-| vector.cpp:350:56:350:57 | v4 | vector.cpp:350:59:350:61 | call to end | TAINT |
-| vector.cpp:350:68:350:69 | it | vector.cpp:350:66:350:66 | call to operator++ | |
-| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:50:350:51 | it | |
-| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:350:68:350:69 | it | |
-| vector.cpp:350:68:350:69 | ref arg it | vector.cpp:351:32:351:33 | it | |
-| vector.cpp:351:32:351:33 | call to iterator [post update] | vector.cpp:350:56:350:57 | v4 | |
-| vector.cpp:351:32:351:33 | call to iterator [post update] | vector.cpp:353:7:353:8 | v4 | |
-| vector.cpp:351:32:351:33 | call to iterator [post update] | vector.cpp:389:1:389:1 | v4 | |
-| vector.cpp:351:32:351:33 | it | vector.cpp:351:32:351:33 | call to iterator | |
-| vector.cpp:351:32:351:33 | it [post update] | vector.cpp:350:56:350:57 | v4 | |
-| vector.cpp:351:32:351:33 | it [post update] | vector.cpp:353:7:353:8 | v4 | |
-| vector.cpp:351:32:351:33 | it [post update] | vector.cpp:389:1:389:1 | v4 | |
-| vector.cpp:353:7:353:8 | ref arg v4 | vector.cpp:389:1:389:1 | v4 | |
-| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:357:7:357:8 | v5 | |
-| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:359:7:359:8 | v5 | |
-| vector.cpp:355:34:355:35 | ref arg v5 | vector.cpp:389:1:389:1 | v5 | |
-| vector.cpp:355:34:355:35 | v5 | vector.cpp:355:37:355:41 | call to begin | TAINT |
-| vector.cpp:355:37:355:41 | call to begin | vector.cpp:356:3:356:4 | i5 | |
-| vector.cpp:355:37:355:41 | call to begin | vector.cpp:358:3:358:4 | i5 | |
-| vector.cpp:356:2:356:2 | call to operator* [post update] | vector.cpp:357:7:357:8 | v5 | |
-| vector.cpp:356:2:356:2 | call to operator* [post update] | vector.cpp:359:7:359:8 | v5 | |
-| vector.cpp:356:2:356:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v5 | |
-| vector.cpp:356:2:356:15 | ... = ... | vector.cpp:356:2:356:2 | call to operator* [post update] | |
-| vector.cpp:356:3:356:4 | i5 | vector.cpp:356:2:356:2 | call to operator* | TAINT |
-| vector.cpp:356:8:356:13 | call to source | vector.cpp:356:2:356:2 | call to operator* [post update] | TAINT |
-| vector.cpp:356:8:356:13 | call to source | vector.cpp:356:2:356:15 | ... = ... | |
-| vector.cpp:357:7:357:8 | ref arg v5 | vector.cpp:359:7:359:8 | v5 | |
-| vector.cpp:357:7:357:8 | ref arg v5 | vector.cpp:389:1:389:1 | v5 | |
-| vector.cpp:358:2:358:2 | call to operator* [post update] | vector.cpp:359:7:359:8 | v5 | |
-| vector.cpp:358:2:358:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v5 | |
-| vector.cpp:358:2:358:8 | ... = ... | vector.cpp:358:2:358:2 | call to operator* [post update] | |
-| vector.cpp:358:3:358:4 | i5 | vector.cpp:358:2:358:2 | call to operator* | TAINT |
-| vector.cpp:358:8:358:8 | 1 | vector.cpp:358:2:358:2 | call to operator* [post update] | TAINT |
-| vector.cpp:358:8:358:8 | 1 | vector.cpp:358:2:358:8 | ... = ... | |
-| vector.cpp:359:7:359:8 | ref arg v5 | vector.cpp:389:1:389:1 | v5 | |
-| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:363:7:363:8 | v6 | |
-| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:364:2:364:3 | v6 | |
-| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:365:7:365:8 | v6 | |
-| vector.cpp:361:34:361:35 | ref arg v6 | vector.cpp:389:1:389:1 | v6 | |
-| vector.cpp:361:34:361:35 | v6 | vector.cpp:361:37:361:41 | call to begin | TAINT |
-| vector.cpp:361:37:361:41 | call to begin | vector.cpp:362:3:362:4 | i6 | |
-| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:363:7:363:8 | v6 | |
-| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:364:2:364:3 | v6 | |
-| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:365:7:365:8 | v6 | |
-| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v6 | |
-| vector.cpp:362:2:362:15 | ... = ... | vector.cpp:362:2:362:2 | call to operator* [post update] | |
-| vector.cpp:362:3:362:4 | i6 | vector.cpp:362:2:362:2 | call to operator* | TAINT |
-| vector.cpp:362:8:362:13 | call to source | vector.cpp:362:2:362:2 | call to operator* [post update] | TAINT |
-| vector.cpp:362:8:362:13 | call to source | vector.cpp:362:2:362:15 | ... = ... | |
-| vector.cpp:363:7:363:8 | ref arg v6 | vector.cpp:364:2:364:3 | v6 | |
-| vector.cpp:363:7:363:8 | ref arg v6 | vector.cpp:365:7:365:8 | v6 | |
-| vector.cpp:363:7:363:8 | ref arg v6 | vector.cpp:389:1:389:1 | v6 | |
-| vector.cpp:364:2:364:3 | ref arg v6 | vector.cpp:365:7:365:8 | v6 | |
-| vector.cpp:364:2:364:3 | ref arg v6 | vector.cpp:389:1:389:1 | v6 | |
-| vector.cpp:364:7:364:26 | call to vector | vector.cpp:364:2:364:3 | ref arg v6 | TAINT |
-| vector.cpp:364:7:364:26 | call to vector | vector.cpp:364:5:364:5 | call to operator= | TAINT |
-| vector.cpp:365:7:365:8 | ref arg v6 | vector.cpp:389:1:389:1 | v6 | |
-| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:370:8:370:9 | v7 | |
-| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:373:8:373:9 | v7 | |
-| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:375:7:375:8 | v7 | |
-| vector.cpp:367:34:367:35 | ref arg v7 | vector.cpp:389:1:389:1 | v7 | |
-| vector.cpp:367:34:367:35 | v7 | vector.cpp:367:37:367:41 | call to begin | TAINT |
-| vector.cpp:367:37:367:41 | call to begin | vector.cpp:369:4:369:5 | i7 | |
-| vector.cpp:367:37:367:41 | call to begin | vector.cpp:372:4:372:5 | i7 | |
-| vector.cpp:369:3:369:3 | call to operator* [post update] | vector.cpp:370:8:370:9 | v7 | |
-| vector.cpp:369:3:369:3 | call to operator* [post update] | vector.cpp:375:7:375:8 | v7 | |
-| vector.cpp:369:3:369:3 | call to operator* [post update] | vector.cpp:389:1:389:1 | v7 | |
-| vector.cpp:369:3:369:16 | ... = ... | vector.cpp:369:3:369:3 | call to operator* [post update] | |
-| vector.cpp:369:4:369:5 | i7 | vector.cpp:369:3:369:3 | call to operator* | TAINT |
-| vector.cpp:369:9:369:14 | call to source | vector.cpp:369:3:369:3 | call to operator* [post update] | TAINT |
-| vector.cpp:369:9:369:14 | call to source | vector.cpp:369:3:369:16 | ... = ... | |
-| vector.cpp:370:8:370:9 | ref arg v7 | vector.cpp:375:7:375:8 | v7 | |
-| vector.cpp:370:8:370:9 | ref arg v7 | vector.cpp:389:1:389:1 | v7 | |
-| vector.cpp:372:3:372:3 | call to operator* [post update] | vector.cpp:373:8:373:9 | v7 | |
-| vector.cpp:372:3:372:3 | call to operator* [post update] | vector.cpp:375:7:375:8 | v7 | |
-| vector.cpp:372:3:372:3 | call to operator* [post update] | vector.cpp:389:1:389:1 | v7 | |
-| vector.cpp:372:3:372:9 | ... = ... | vector.cpp:372:3:372:3 | call to operator* [post update] | |
-| vector.cpp:372:4:372:5 | i7 | vector.cpp:372:3:372:3 | call to operator* | TAINT |
-| vector.cpp:372:9:372:9 | 1 | vector.cpp:372:3:372:3 | call to operator* [post update] | TAINT |
-| vector.cpp:372:9:372:9 | 1 | vector.cpp:372:3:372:9 | ... = ... | |
-| vector.cpp:373:8:373:9 | ref arg v7 | vector.cpp:375:7:375:8 | v7 | |
-| vector.cpp:373:8:373:9 | ref arg v7 | vector.cpp:389:1:389:1 | v7 | |
-| vector.cpp:375:7:375:8 | ref arg v7 | vector.cpp:389:1:389:1 | v7 | |
-| vector.cpp:377:34:377:35 | ref arg v8 | vector.cpp:379:7:379:8 | v8 | |
-| vector.cpp:377:34:377:35 | ref arg v8 | vector.cpp:381:7:381:8 | v8 | |
-| vector.cpp:377:34:377:35 | ref arg v8 | vector.cpp:389:1:389:1 | v8 | |
-| vector.cpp:377:34:377:35 | v8 | vector.cpp:377:37:377:41 | call to begin | TAINT |
-| vector.cpp:377:37:377:41 | call to begin | vector.cpp:378:3:378:4 | i8 | |
-| vector.cpp:377:37:377:41 | call to begin | vector.cpp:380:3:380:4 | i8 | |
-| vector.cpp:378:2:378:2 | call to operator* [post update] | vector.cpp:379:7:379:8 | v8 | |
-| vector.cpp:378:2:378:2 | call to operator* [post update] | vector.cpp:381:7:381:8 | v8 | |
-| vector.cpp:378:2:378:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v8 | |
-| vector.cpp:378:2:378:15 | ... = ... | vector.cpp:378:2:378:2 | call to operator* [post update] | |
-| vector.cpp:378:3:378:4 | i8 | vector.cpp:378:2:378:2 | call to operator* | TAINT |
-| vector.cpp:378:8:378:13 | call to source | vector.cpp:378:2:378:2 | call to operator* [post update] | TAINT |
-| vector.cpp:378:8:378:13 | call to source | vector.cpp:378:2:378:15 | ... = ... | |
-| vector.cpp:379:7:379:8 | ref arg v8 | vector.cpp:381:7:381:8 | v8 | |
-| vector.cpp:379:7:379:8 | ref arg v8 | vector.cpp:389:1:389:1 | v8 | |
-| vector.cpp:380:2:380:2 | call to operator* [post update] | vector.cpp:381:7:381:8 | v8 | |
-| vector.cpp:380:2:380:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v8 | |
-| vector.cpp:380:2:380:8 | ... = ... | vector.cpp:380:2:380:2 | call to operator* [post update] | |
-| vector.cpp:380:3:380:4 | i8 | vector.cpp:380:2:380:2 | call to operator* | TAINT |
-| vector.cpp:380:8:380:8 | 1 | vector.cpp:380:2:380:2 | call to operator* [post update] | TAINT |
-| vector.cpp:380:8:380:8 | 1 | vector.cpp:380:2:380:8 | ... = ... | |
-| vector.cpp:381:7:381:8 | ref arg v8 | vector.cpp:389:1:389:1 | v8 | |
-| vector.cpp:383:34:383:35 | ref arg v9 | vector.cpp:388:7:388:8 | v9 | |
-| vector.cpp:383:34:383:35 | ref arg v9 | vector.cpp:389:1:389:1 | v9 | |
-| vector.cpp:383:34:383:35 | v9 | vector.cpp:383:37:383:41 | call to begin | TAINT |
-| vector.cpp:383:37:383:41 | call to begin | vector.cpp:385:3:385:4 | i9 | |
-| vector.cpp:383:37:383:41 | call to begin | vector.cpp:386:31:386:32 | i9 | |
-| vector.cpp:385:2:385:2 | call to operator* [post update] | vector.cpp:388:7:388:8 | v9 | |
-| vector.cpp:385:2:385:2 | call to operator* [post update] | vector.cpp:389:1:389:1 | v9 | |
-| vector.cpp:385:2:385:15 | ... = ... | vector.cpp:385:2:385:2 | call to operator* [post update] | |
-| vector.cpp:385:3:385:4 | i9 | vector.cpp:385:2:385:2 | call to operator* | TAINT |
-| vector.cpp:385:8:385:13 | call to source | vector.cpp:385:2:385:2 | call to operator* [post update] | TAINT |
-| vector.cpp:385:8:385:13 | call to source | vector.cpp:385:2:385:15 | ... = ... | |
-| vector.cpp:386:31:386:32 | call to iterator [post update] | vector.cpp:388:7:388:8 | v9 | |
-| vector.cpp:386:31:386:32 | call to iterator [post update] | vector.cpp:389:1:389:1 | v9 | |
-| vector.cpp:386:31:386:32 | i9 | vector.cpp:386:31:386:32 | call to iterator | |
-| vector.cpp:386:31:386:32 | i9 [post update] | vector.cpp:388:7:388:8 | v9 | |
-| vector.cpp:386:31:386:32 | i9 [post update] | vector.cpp:389:1:389:1 | v9 | |
-| vector.cpp:388:7:388:8 | ref arg v9 | vector.cpp:389:1:389:1 | v9 | |
+| vector.cpp:333:64:333:67 | iter | vector.cpp:333:64:333:67 | iter | |
+| vector.cpp:333:64:333:67 | iter | vector.cpp:334:3:334:6 | iter | |
+| vector.cpp:333:74:333:74 | i | vector.cpp:334:10:334:10 | i | |
+| vector.cpp:334:2:334:2 | call to operator* [post update] | vector.cpp:333:64:333:67 | iter | |
+| vector.cpp:334:2:334:10 | ... = ... | vector.cpp:334:2:334:2 | call to operator* [post update] | |
+| vector.cpp:334:3:334:6 | iter | vector.cpp:334:2:334:2 | call to operator* | TAINT |
+| vector.cpp:334:10:334:10 | i | vector.cpp:334:2:334:2 | call to operator* [post update] | TAINT |
+| vector.cpp:334:10:334:10 | i | vector.cpp:334:2:334:10 | ... = ... | |
+| vector.cpp:337:38:337:38 | b | vector.cpp:372:5:372:5 | b | |
+| vector.cpp:338:22:338:24 | call to vector | vector.cpp:340:34:340:35 | v1 | |
+| vector.cpp:338:22:338:24 | call to vector | vector.cpp:342:7:342:8 | v1 | |
+| vector.cpp:338:22:338:24 | call to vector | vector.cpp:401:1:401:1 | v1 | |
+| vector.cpp:338:30:338:32 | call to vector | vector.cpp:344:38:344:39 | v2 | |
+| vector.cpp:338:30:338:32 | call to vector | vector.cpp:344:56:344:57 | v2 | |
+| vector.cpp:338:30:338:32 | call to vector | vector.cpp:347:7:347:8 | v2 | |
+| vector.cpp:338:30:338:32 | call to vector | vector.cpp:401:1:401:1 | v2 | |
+| vector.cpp:338:38:338:40 | call to vector | vector.cpp:349:15:349:16 | v3 | |
+| vector.cpp:338:38:338:40 | call to vector | vector.cpp:352:7:352:8 | v3 | |
+| vector.cpp:338:38:338:40 | call to vector | vector.cpp:401:1:401:1 | v3 | |
+| vector.cpp:338:46:338:48 | call to vector | vector.cpp:354:38:354:39 | v4 | |
+| vector.cpp:338:46:338:48 | call to vector | vector.cpp:354:56:354:57 | v4 | |
+| vector.cpp:338:46:338:48 | call to vector | vector.cpp:357:7:357:8 | v4 | |
+| vector.cpp:338:46:338:48 | call to vector | vector.cpp:401:1:401:1 | v4 | |
+| vector.cpp:338:54:338:56 | call to vector | vector.cpp:359:34:359:35 | v5 | |
+| vector.cpp:338:54:338:56 | call to vector | vector.cpp:361:7:361:8 | v5 | |
+| vector.cpp:338:54:338:56 | call to vector | vector.cpp:363:7:363:8 | v5 | |
+| vector.cpp:338:54:338:56 | call to vector | vector.cpp:401:1:401:1 | v5 | |
+| vector.cpp:338:62:338:64 | call to vector | vector.cpp:365:34:365:35 | v6 | |
+| vector.cpp:338:62:338:64 | call to vector | vector.cpp:367:7:367:8 | v6 | |
+| vector.cpp:338:62:338:64 | call to vector | vector.cpp:368:2:368:3 | v6 | |
+| vector.cpp:338:62:338:64 | call to vector | vector.cpp:369:7:369:8 | v6 | |
+| vector.cpp:338:62:338:64 | call to vector | vector.cpp:401:1:401:1 | v6 | |
+| vector.cpp:338:70:338:72 | call to vector | vector.cpp:371:34:371:35 | v7 | |
+| vector.cpp:338:70:338:72 | call to vector | vector.cpp:374:8:374:9 | v7 | |
+| vector.cpp:338:70:338:72 | call to vector | vector.cpp:377:8:377:9 | v7 | |
+| vector.cpp:338:70:338:72 | call to vector | vector.cpp:379:7:379:8 | v7 | |
+| vector.cpp:338:70:338:72 | call to vector | vector.cpp:401:1:401:1 | v7 | |
+| vector.cpp:338:78:338:80 | call to vector | vector.cpp:381:34:381:35 | v8 | |
+| vector.cpp:338:78:338:80 | call to vector | vector.cpp:383:7:383:8 | v8 | |
+| vector.cpp:338:78:338:80 | call to vector | vector.cpp:385:7:385:8 | v8 | |
+| vector.cpp:338:78:338:80 | call to vector | vector.cpp:401:1:401:1 | v8 | |
+| vector.cpp:338:86:338:88 | call to vector | vector.cpp:387:34:387:35 | v9 | |
+| vector.cpp:338:86:338:88 | call to vector | vector.cpp:392:7:392:8 | v9 | |
+| vector.cpp:338:86:338:88 | call to vector | vector.cpp:401:1:401:1 | v9 | |
+| vector.cpp:338:95:338:97 | call to vector | vector.cpp:394:35:394:37 | v10 | |
+| vector.cpp:338:95:338:97 | call to vector | vector.cpp:396:7:396:9 | v10 | |
+| vector.cpp:338:95:338:97 | call to vector | vector.cpp:401:1:401:1 | v10 | |
+| vector.cpp:338:104:338:106 | call to vector | vector.cpp:398:35:398:37 | v11 | |
+| vector.cpp:338:104:338:106 | call to vector | vector.cpp:400:7:400:9 | v11 | |
+| vector.cpp:338:104:338:106 | call to vector | vector.cpp:401:1:401:1 | v11 | |
+| vector.cpp:340:34:340:35 | ref arg v1 | vector.cpp:342:7:342:8 | v1 | |
+| vector.cpp:340:34:340:35 | ref arg v1 | vector.cpp:401:1:401:1 | v1 | |
+| vector.cpp:340:34:340:35 | v1 | vector.cpp:340:37:340:41 | call to begin | TAINT |
+| vector.cpp:340:37:340:41 | call to begin | vector.cpp:341:3:341:4 | i1 | |
+| vector.cpp:341:2:341:2 | call to operator* [post update] | vector.cpp:342:7:342:8 | v1 | |
+| vector.cpp:341:2:341:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v1 | |
+| vector.cpp:341:2:341:15 | ... = ... | vector.cpp:341:2:341:2 | call to operator* [post update] | |
+| vector.cpp:341:3:341:4 | i1 | vector.cpp:341:2:341:2 | call to operator* | TAINT |
+| vector.cpp:341:8:341:13 | call to source | vector.cpp:341:2:341:2 | call to operator* [post update] | TAINT |
+| vector.cpp:341:8:341:13 | call to source | vector.cpp:341:2:341:15 | ... = ... | |
+| vector.cpp:342:7:342:8 | ref arg v1 | vector.cpp:401:1:401:1 | v1 | |
+| vector.cpp:344:38:344:39 | ref arg v2 | vector.cpp:344:56:344:57 | v2 | |
+| vector.cpp:344:38:344:39 | ref arg v2 | vector.cpp:347:7:347:8 | v2 | |
+| vector.cpp:344:38:344:39 | ref arg v2 | vector.cpp:401:1:401:1 | v2 | |
+| vector.cpp:344:38:344:39 | v2 | vector.cpp:344:41:344:45 | call to begin | TAINT |
+| vector.cpp:344:41:344:45 | call to begin | vector.cpp:344:50:344:51 | it | |
+| vector.cpp:344:41:344:45 | call to begin | vector.cpp:344:68:344:69 | it | |
+| vector.cpp:344:41:344:45 | call to begin | vector.cpp:345:4:345:5 | it | |
+| vector.cpp:344:56:344:57 | ref arg v2 | vector.cpp:344:56:344:57 | v2 | |
+| vector.cpp:344:56:344:57 | ref arg v2 | vector.cpp:347:7:347:8 | v2 | |
+| vector.cpp:344:56:344:57 | ref arg v2 | vector.cpp:401:1:401:1 | v2 | |
+| vector.cpp:344:56:344:57 | v2 | vector.cpp:344:59:344:61 | call to end | TAINT |
+| vector.cpp:344:68:344:69 | it | vector.cpp:344:66:344:66 | call to operator++ | |
+| vector.cpp:344:68:344:69 | ref arg it | vector.cpp:344:50:344:51 | it | |
+| vector.cpp:344:68:344:69 | ref arg it | vector.cpp:344:68:344:69 | it | |
+| vector.cpp:344:68:344:69 | ref arg it | vector.cpp:345:4:345:5 | it | |
+| vector.cpp:345:3:345:3 | call to operator* [post update] | vector.cpp:344:56:344:57 | v2 | |
+| vector.cpp:345:3:345:3 | call to operator* [post update] | vector.cpp:347:7:347:8 | v2 | |
+| vector.cpp:345:3:345:3 | call to operator* [post update] | vector.cpp:401:1:401:1 | v2 | |
+| vector.cpp:345:3:345:16 | ... = ... | vector.cpp:345:3:345:3 | call to operator* [post update] | |
+| vector.cpp:345:4:345:5 | it | vector.cpp:345:3:345:3 | call to operator* | TAINT |
+| vector.cpp:345:9:345:14 | call to source | vector.cpp:345:3:345:3 | call to operator* [post update] | TAINT |
+| vector.cpp:345:9:345:14 | call to source | vector.cpp:345:3:345:16 | ... = ... | |
+| vector.cpp:347:7:347:8 | ref arg v2 | vector.cpp:401:1:401:1 | v2 | |
+| vector.cpp:349:15:349:15 | (__begin) | vector.cpp:349:15:349:15 | call to operator* | TAINT |
+| vector.cpp:349:15:349:15 | (__begin) | vector.cpp:349:15:349:15 | call to operator++ | |
+| vector.cpp:349:15:349:15 | (__end) | vector.cpp:349:15:349:15 | call to iterator | |
+| vector.cpp:349:15:349:15 | (__range) | vector.cpp:349:15:349:15 | call to begin | TAINT |
+| vector.cpp:349:15:349:15 | (__range) | vector.cpp:349:15:349:15 | call to end | TAINT |
+| vector.cpp:349:15:349:15 | call to begin | vector.cpp:349:15:349:15 | (__begin) | |
+| vector.cpp:349:15:349:15 | call to begin | vector.cpp:349:15:349:15 | (__begin) | |
+| vector.cpp:349:15:349:15 | call to begin | vector.cpp:349:15:349:15 | (__begin) | |
+| vector.cpp:349:15:349:15 | call to end | vector.cpp:349:15:349:15 | (__end) | |
+| vector.cpp:349:15:349:15 | ref arg (__begin) | vector.cpp:349:15:349:15 | (__begin) | |
+| vector.cpp:349:15:349:15 | ref arg (__begin) | vector.cpp:349:15:349:15 | (__begin) | |
+| vector.cpp:349:15:349:15 | ref arg (__begin) | vector.cpp:349:15:349:15 | (__begin) | |
+| vector.cpp:349:15:349:15 | ref arg (__range) | vector.cpp:349:15:349:15 | (__range) | |
+| vector.cpp:349:15:349:16 | v3 | vector.cpp:349:15:349:15 | (__range) | |
+| vector.cpp:349:15:349:16 | v3 | vector.cpp:349:15:349:15 | (__range) | |
+| vector.cpp:349:15:349:16 | v3 | vector.cpp:349:15:349:15 | call to operator* | TAINT |
+| vector.cpp:350:3:350:14 | ... = ... | vector.cpp:350:3:350:3 | x [post update] | |
+| vector.cpp:350:7:350:12 | call to source | vector.cpp:350:3:350:14 | ... = ... | |
+| vector.cpp:352:7:352:8 | ref arg v3 | vector.cpp:401:1:401:1 | v3 | |
+| vector.cpp:354:38:354:39 | ref arg v4 | vector.cpp:354:56:354:57 | v4 | |
+| vector.cpp:354:38:354:39 | ref arg v4 | vector.cpp:357:7:357:8 | v4 | |
+| vector.cpp:354:38:354:39 | ref arg v4 | vector.cpp:401:1:401:1 | v4 | |
+| vector.cpp:354:38:354:39 | v4 | vector.cpp:354:41:354:45 | call to begin | TAINT |
+| vector.cpp:354:41:354:45 | call to begin | vector.cpp:354:50:354:51 | it | |
+| vector.cpp:354:41:354:45 | call to begin | vector.cpp:354:68:354:69 | it | |
+| vector.cpp:354:41:354:45 | call to begin | vector.cpp:355:32:355:33 | it | |
+| vector.cpp:354:56:354:57 | ref arg v4 | vector.cpp:354:56:354:57 | v4 | |
+| vector.cpp:354:56:354:57 | ref arg v4 | vector.cpp:357:7:357:8 | v4 | |
+| vector.cpp:354:56:354:57 | ref arg v4 | vector.cpp:401:1:401:1 | v4 | |
+| vector.cpp:354:56:354:57 | v4 | vector.cpp:354:59:354:61 | call to end | TAINT |
+| vector.cpp:354:68:354:69 | it | vector.cpp:354:66:354:66 | call to operator++ | |
+| vector.cpp:354:68:354:69 | ref arg it | vector.cpp:354:50:354:51 | it | |
+| vector.cpp:354:68:354:69 | ref arg it | vector.cpp:354:68:354:69 | it | |
+| vector.cpp:354:68:354:69 | ref arg it | vector.cpp:355:32:355:33 | it | |
+| vector.cpp:355:32:355:33 | call to iterator [post update] | vector.cpp:354:56:354:57 | v4 | |
+| vector.cpp:355:32:355:33 | call to iterator [post update] | vector.cpp:357:7:357:8 | v4 | |
+| vector.cpp:355:32:355:33 | call to iterator [post update] | vector.cpp:401:1:401:1 | v4 | |
+| vector.cpp:355:32:355:33 | it | vector.cpp:355:32:355:33 | call to iterator | |
+| vector.cpp:355:32:355:33 | it [post update] | vector.cpp:354:56:354:57 | v4 | |
+| vector.cpp:355:32:355:33 | it [post update] | vector.cpp:357:7:357:8 | v4 | |
+| vector.cpp:355:32:355:33 | it [post update] | vector.cpp:401:1:401:1 | v4 | |
+| vector.cpp:357:7:357:8 | ref arg v4 | vector.cpp:401:1:401:1 | v4 | |
+| vector.cpp:359:34:359:35 | ref arg v5 | vector.cpp:361:7:361:8 | v5 | |
+| vector.cpp:359:34:359:35 | ref arg v5 | vector.cpp:363:7:363:8 | v5 | |
+| vector.cpp:359:34:359:35 | ref arg v5 | vector.cpp:401:1:401:1 | v5 | |
+| vector.cpp:359:34:359:35 | v5 | vector.cpp:359:37:359:41 | call to begin | TAINT |
+| vector.cpp:359:37:359:41 | call to begin | vector.cpp:360:3:360:4 | i5 | |
+| vector.cpp:359:37:359:41 | call to begin | vector.cpp:362:3:362:4 | i5 | |
+| vector.cpp:360:2:360:2 | call to operator* [post update] | vector.cpp:361:7:361:8 | v5 | |
+| vector.cpp:360:2:360:2 | call to operator* [post update] | vector.cpp:363:7:363:8 | v5 | |
+| vector.cpp:360:2:360:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v5 | |
+| vector.cpp:360:2:360:15 | ... = ... | vector.cpp:360:2:360:2 | call to operator* [post update] | |
+| vector.cpp:360:3:360:4 | i5 | vector.cpp:360:2:360:2 | call to operator* | TAINT |
+| vector.cpp:360:8:360:13 | call to source | vector.cpp:360:2:360:2 | call to operator* [post update] | TAINT |
+| vector.cpp:360:8:360:13 | call to source | vector.cpp:360:2:360:15 | ... = ... | |
+| vector.cpp:361:7:361:8 | ref arg v5 | vector.cpp:363:7:363:8 | v5 | |
+| vector.cpp:361:7:361:8 | ref arg v5 | vector.cpp:401:1:401:1 | v5 | |
+| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:363:7:363:8 | v5 | |
+| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v5 | |
+| vector.cpp:362:2:362:8 | ... = ... | vector.cpp:362:2:362:2 | call to operator* [post update] | |
+| vector.cpp:362:3:362:4 | i5 | vector.cpp:362:2:362:2 | call to operator* | TAINT |
+| vector.cpp:362:8:362:8 | 1 | vector.cpp:362:2:362:2 | call to operator* [post update] | TAINT |
+| vector.cpp:362:8:362:8 | 1 | vector.cpp:362:2:362:8 | ... = ... | |
+| vector.cpp:363:7:363:8 | ref arg v5 | vector.cpp:401:1:401:1 | v5 | |
+| vector.cpp:365:34:365:35 | ref arg v6 | vector.cpp:367:7:367:8 | v6 | |
+| vector.cpp:365:34:365:35 | ref arg v6 | vector.cpp:368:2:368:3 | v6 | |
+| vector.cpp:365:34:365:35 | ref arg v6 | vector.cpp:369:7:369:8 | v6 | |
+| vector.cpp:365:34:365:35 | ref arg v6 | vector.cpp:401:1:401:1 | v6 | |
+| vector.cpp:365:34:365:35 | v6 | vector.cpp:365:37:365:41 | call to begin | TAINT |
+| vector.cpp:365:37:365:41 | call to begin | vector.cpp:366:3:366:4 | i6 | |
+| vector.cpp:366:2:366:2 | call to operator* [post update] | vector.cpp:367:7:367:8 | v6 | |
+| vector.cpp:366:2:366:2 | call to operator* [post update] | vector.cpp:368:2:368:3 | v6 | |
+| vector.cpp:366:2:366:2 | call to operator* [post update] | vector.cpp:369:7:369:8 | v6 | |
+| vector.cpp:366:2:366:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v6 | |
+| vector.cpp:366:2:366:15 | ... = ... | vector.cpp:366:2:366:2 | call to operator* [post update] | |
+| vector.cpp:366:3:366:4 | i6 | vector.cpp:366:2:366:2 | call to operator* | TAINT |
+| vector.cpp:366:8:366:13 | call to source | vector.cpp:366:2:366:2 | call to operator* [post update] | TAINT |
+| vector.cpp:366:8:366:13 | call to source | vector.cpp:366:2:366:15 | ... = ... | |
+| vector.cpp:367:7:367:8 | ref arg v6 | vector.cpp:368:2:368:3 | v6 | |
+| vector.cpp:367:7:367:8 | ref arg v6 | vector.cpp:369:7:369:8 | v6 | |
+| vector.cpp:367:7:367:8 | ref arg v6 | vector.cpp:401:1:401:1 | v6 | |
+| vector.cpp:368:2:368:3 | ref arg v6 | vector.cpp:369:7:369:8 | v6 | |
+| vector.cpp:368:2:368:3 | ref arg v6 | vector.cpp:401:1:401:1 | v6 | |
+| vector.cpp:368:7:368:26 | call to vector | vector.cpp:368:2:368:3 | ref arg v6 | TAINT |
+| vector.cpp:368:7:368:26 | call to vector | vector.cpp:368:5:368:5 | call to operator= | TAINT |
+| vector.cpp:369:7:369:8 | ref arg v6 | vector.cpp:401:1:401:1 | v6 | |
+| vector.cpp:371:34:371:35 | ref arg v7 | vector.cpp:374:8:374:9 | v7 | |
+| vector.cpp:371:34:371:35 | ref arg v7 | vector.cpp:377:8:377:9 | v7 | |
+| vector.cpp:371:34:371:35 | ref arg v7 | vector.cpp:379:7:379:8 | v7 | |
+| vector.cpp:371:34:371:35 | ref arg v7 | vector.cpp:401:1:401:1 | v7 | |
+| vector.cpp:371:34:371:35 | v7 | vector.cpp:371:37:371:41 | call to begin | TAINT |
+| vector.cpp:371:37:371:41 | call to begin | vector.cpp:373:4:373:5 | i7 | |
+| vector.cpp:371:37:371:41 | call to begin | vector.cpp:376:4:376:5 | i7 | |
+| vector.cpp:373:3:373:3 | call to operator* [post update] | vector.cpp:374:8:374:9 | v7 | |
+| vector.cpp:373:3:373:3 | call to operator* [post update] | vector.cpp:379:7:379:8 | v7 | |
+| vector.cpp:373:3:373:3 | call to operator* [post update] | vector.cpp:401:1:401:1 | v7 | |
+| vector.cpp:373:3:373:16 | ... = ... | vector.cpp:373:3:373:3 | call to operator* [post update] | |
+| vector.cpp:373:4:373:5 | i7 | vector.cpp:373:3:373:3 | call to operator* | TAINT |
+| vector.cpp:373:9:373:14 | call to source | vector.cpp:373:3:373:3 | call to operator* [post update] | TAINT |
+| vector.cpp:373:9:373:14 | call to source | vector.cpp:373:3:373:16 | ... = ... | |
+| vector.cpp:374:8:374:9 | ref arg v7 | vector.cpp:379:7:379:8 | v7 | |
+| vector.cpp:374:8:374:9 | ref arg v7 | vector.cpp:401:1:401:1 | v7 | |
+| vector.cpp:376:3:376:3 | call to operator* [post update] | vector.cpp:377:8:377:9 | v7 | |
+| vector.cpp:376:3:376:3 | call to operator* [post update] | vector.cpp:379:7:379:8 | v7 | |
+| vector.cpp:376:3:376:3 | call to operator* [post update] | vector.cpp:401:1:401:1 | v7 | |
+| vector.cpp:376:3:376:9 | ... = ... | vector.cpp:376:3:376:3 | call to operator* [post update] | |
+| vector.cpp:376:4:376:5 | i7 | vector.cpp:376:3:376:3 | call to operator* | TAINT |
+| vector.cpp:376:9:376:9 | 1 | vector.cpp:376:3:376:3 | call to operator* [post update] | TAINT |
+| vector.cpp:376:9:376:9 | 1 | vector.cpp:376:3:376:9 | ... = ... | |
+| vector.cpp:377:8:377:9 | ref arg v7 | vector.cpp:379:7:379:8 | v7 | |
+| vector.cpp:377:8:377:9 | ref arg v7 | vector.cpp:401:1:401:1 | v7 | |
+| vector.cpp:379:7:379:8 | ref arg v7 | vector.cpp:401:1:401:1 | v7 | |
+| vector.cpp:381:34:381:35 | ref arg v8 | vector.cpp:383:7:383:8 | v8 | |
+| vector.cpp:381:34:381:35 | ref arg v8 | vector.cpp:385:7:385:8 | v8 | |
+| vector.cpp:381:34:381:35 | ref arg v8 | vector.cpp:401:1:401:1 | v8 | |
+| vector.cpp:381:34:381:35 | v8 | vector.cpp:381:37:381:41 | call to begin | TAINT |
+| vector.cpp:381:37:381:41 | call to begin | vector.cpp:382:3:382:4 | i8 | |
+| vector.cpp:381:37:381:41 | call to begin | vector.cpp:384:3:384:4 | i8 | |
+| vector.cpp:382:2:382:2 | call to operator* [post update] | vector.cpp:383:7:383:8 | v8 | |
+| vector.cpp:382:2:382:2 | call to operator* [post update] | vector.cpp:385:7:385:8 | v8 | |
+| vector.cpp:382:2:382:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v8 | |
+| vector.cpp:382:2:382:15 | ... = ... | vector.cpp:382:2:382:2 | call to operator* [post update] | |
+| vector.cpp:382:3:382:4 | i8 | vector.cpp:382:2:382:2 | call to operator* | TAINT |
+| vector.cpp:382:8:382:13 | call to source | vector.cpp:382:2:382:2 | call to operator* [post update] | TAINT |
+| vector.cpp:382:8:382:13 | call to source | vector.cpp:382:2:382:15 | ... = ... | |
+| vector.cpp:383:7:383:8 | ref arg v8 | vector.cpp:385:7:385:8 | v8 | |
+| vector.cpp:383:7:383:8 | ref arg v8 | vector.cpp:401:1:401:1 | v8 | |
+| vector.cpp:384:2:384:2 | call to operator* [post update] | vector.cpp:385:7:385:8 | v8 | |
+| vector.cpp:384:2:384:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v8 | |
+| vector.cpp:384:2:384:8 | ... = ... | vector.cpp:384:2:384:2 | call to operator* [post update] | |
+| vector.cpp:384:3:384:4 | i8 | vector.cpp:384:2:384:2 | call to operator* | TAINT |
+| vector.cpp:384:8:384:8 | 1 | vector.cpp:384:2:384:2 | call to operator* [post update] | TAINT |
+| vector.cpp:384:8:384:8 | 1 | vector.cpp:384:2:384:8 | ... = ... | |
+| vector.cpp:385:7:385:8 | ref arg v8 | vector.cpp:401:1:401:1 | v8 | |
+| vector.cpp:387:34:387:35 | ref arg v9 | vector.cpp:392:7:392:8 | v9 | |
+| vector.cpp:387:34:387:35 | ref arg v9 | vector.cpp:401:1:401:1 | v9 | |
+| vector.cpp:387:34:387:35 | v9 | vector.cpp:387:37:387:41 | call to begin | TAINT |
+| vector.cpp:387:37:387:41 | call to begin | vector.cpp:389:3:389:4 | i9 | |
+| vector.cpp:387:37:387:41 | call to begin | vector.cpp:390:31:390:32 | i9 | |
+| vector.cpp:389:2:389:2 | call to operator* [post update] | vector.cpp:392:7:392:8 | v9 | |
+| vector.cpp:389:2:389:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v9 | |
+| vector.cpp:389:2:389:15 | ... = ... | vector.cpp:389:2:389:2 | call to operator* [post update] | |
+| vector.cpp:389:3:389:4 | i9 | vector.cpp:389:2:389:2 | call to operator* | TAINT |
+| vector.cpp:389:8:389:13 | call to source | vector.cpp:389:2:389:2 | call to operator* [post update] | TAINT |
+| vector.cpp:389:8:389:13 | call to source | vector.cpp:389:2:389:15 | ... = ... | |
+| vector.cpp:390:31:390:32 | call to iterator [post update] | vector.cpp:392:7:392:8 | v9 | |
+| vector.cpp:390:31:390:32 | call to iterator [post update] | vector.cpp:401:1:401:1 | v9 | |
+| vector.cpp:390:31:390:32 | i9 | vector.cpp:390:31:390:32 | call to iterator | |
+| vector.cpp:390:31:390:32 | i9 [post update] | vector.cpp:392:7:392:8 | v9 | |
+| vector.cpp:390:31:390:32 | i9 [post update] | vector.cpp:401:1:401:1 | v9 | |
+| vector.cpp:392:7:392:8 | ref arg v9 | vector.cpp:401:1:401:1 | v9 | |
+| vector.cpp:394:35:394:37 | ref arg v10 | vector.cpp:396:7:396:9 | v10 | |
+| vector.cpp:394:35:394:37 | ref arg v10 | vector.cpp:401:1:401:1 | v10 | |
+| vector.cpp:394:35:394:37 | v10 | vector.cpp:394:39:394:43 | call to begin | TAINT |
+| vector.cpp:394:39:394:43 | call to begin | vector.cpp:395:33:395:35 | i10 | |
+| vector.cpp:395:33:395:35 | call to iterator [post update] | vector.cpp:396:7:396:9 | v10 | |
+| vector.cpp:395:33:395:35 | call to iterator [post update] | vector.cpp:401:1:401:1 | v10 | |
+| vector.cpp:395:33:395:35 | i10 | vector.cpp:395:33:395:35 | call to iterator | |
+| vector.cpp:395:33:395:35 | i10 [post update] | vector.cpp:396:7:396:9 | v10 | |
+| vector.cpp:395:33:395:35 | i10 [post update] | vector.cpp:401:1:401:1 | v10 | |
+| vector.cpp:396:7:396:9 | ref arg v10 | vector.cpp:401:1:401:1 | v10 | |
+| vector.cpp:398:35:398:37 | ref arg v11 | vector.cpp:400:7:400:9 | v11 | |
+| vector.cpp:398:35:398:37 | ref arg v11 | vector.cpp:401:1:401:1 | v11 | |
+| vector.cpp:398:35:398:37 | v11 | vector.cpp:398:39:398:43 | call to begin | TAINT |
+| vector.cpp:398:39:398:43 | call to begin | vector.cpp:399:33:399:35 | i11 | |
+| vector.cpp:399:33:399:35 | call to iterator [post update] | vector.cpp:400:7:400:9 | v11 | |
+| vector.cpp:399:33:399:35 | call to iterator [post update] | vector.cpp:401:1:401:1 | v11 | |
+| vector.cpp:399:33:399:35 | i11 | vector.cpp:399:33:399:35 | call to iterator | |
+| vector.cpp:399:33:399:35 | i11 [post update] | vector.cpp:400:7:400:9 | v11 | |
+| vector.cpp:399:33:399:35 | i11 [post update] | vector.cpp:401:1:401:1 | v11 | |
+| vector.cpp:400:7:400:9 | ref arg v11 | vector.cpp:401:1:401:1 | v11 | |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
index 2eca13801c6..f91b718bdda 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
@@ -375,16 +375,18 @@
| vector.cpp:312:7:312:7 | d | vector.cpp:303:14:303:19 | call to source |
| vector.cpp:324:7:324:8 | v2 | vector.cpp:318:15:318:20 | call to source |
| vector.cpp:326:7:326:8 | v4 | vector.cpp:318:15:318:20 | call to source |
-| vector.cpp:338:7:338:8 | v1 | vector.cpp:337:8:337:13 | call to source |
-| vector.cpp:343:7:343:8 | v2 | vector.cpp:341:9:341:14 | call to source |
-| vector.cpp:353:7:353:8 | v4 | vector.cpp:330:10:330:15 | call to source |
-| vector.cpp:357:7:357:8 | v5 | vector.cpp:356:8:356:13 | call to source |
-| vector.cpp:359:7:359:8 | v5 | vector.cpp:356:8:356:13 | call to source |
-| vector.cpp:363:7:363:8 | v6 | vector.cpp:362:8:362:13 | call to source |
-| vector.cpp:365:7:365:8 | v6 | vector.cpp:362:8:362:13 | call to source |
-| vector.cpp:370:8:370:9 | v7 | vector.cpp:369:9:369:14 | call to source |
-| vector.cpp:375:7:375:8 | v7 | vector.cpp:369:9:369:14 | call to source |
-| vector.cpp:379:7:379:8 | v8 | vector.cpp:378:8:378:13 | call to source |
-| vector.cpp:381:7:381:8 | v8 | vector.cpp:378:8:378:13 | call to source |
-| vector.cpp:388:7:388:8 | v9 | vector.cpp:330:10:330:15 | call to source |
-| vector.cpp:388:7:388:8 | v9 | vector.cpp:385:8:385:13 | call to source |
+| vector.cpp:342:7:342:8 | v1 | vector.cpp:341:8:341:13 | call to source |
+| vector.cpp:347:7:347:8 | v2 | vector.cpp:345:9:345:14 | call to source |
+| vector.cpp:357:7:357:8 | v4 | vector.cpp:330:10:330:15 | call to source |
+| vector.cpp:361:7:361:8 | v5 | vector.cpp:360:8:360:13 | call to source |
+| vector.cpp:363:7:363:8 | v5 | vector.cpp:360:8:360:13 | call to source |
+| vector.cpp:367:7:367:8 | v6 | vector.cpp:366:8:366:13 | call to source |
+| vector.cpp:369:7:369:8 | v6 | vector.cpp:366:8:366:13 | call to source |
+| vector.cpp:374:8:374:9 | v7 | vector.cpp:373:9:373:14 | call to source |
+| vector.cpp:379:7:379:8 | v7 | vector.cpp:373:9:373:14 | call to source |
+| vector.cpp:383:7:383:8 | v8 | vector.cpp:382:8:382:13 | call to source |
+| vector.cpp:385:7:385:8 | v8 | vector.cpp:382:8:382:13 | call to source |
+| vector.cpp:392:7:392:8 | v9 | vector.cpp:330:10:330:15 | call to source |
+| vector.cpp:392:7:392:8 | v9 | vector.cpp:389:8:389:13 | call to source |
+| vector.cpp:396:7:396:9 | v10 | vector.cpp:399:38:399:43 | call to source |
+| vector.cpp:400:7:400:9 | v11 | vector.cpp:399:38:399:43 | call to source |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected
index db6bf0f3cf0..6397c1d7830 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected
@@ -300,16 +300,18 @@
| vector.cpp:312:7:312:7 | vector.cpp:303:14:303:19 | AST only |
| vector.cpp:324:7:324:8 | vector.cpp:318:15:318:20 | AST only |
| vector.cpp:326:7:326:8 | vector.cpp:318:15:318:20 | AST only |
-| vector.cpp:338:7:338:8 | vector.cpp:337:8:337:13 | AST only |
-| vector.cpp:343:7:343:8 | vector.cpp:341:9:341:14 | AST only |
-| vector.cpp:353:7:353:8 | vector.cpp:330:10:330:15 | AST only |
-| vector.cpp:357:7:357:8 | vector.cpp:356:8:356:13 | AST only |
-| vector.cpp:359:7:359:8 | vector.cpp:356:8:356:13 | AST only |
-| vector.cpp:363:7:363:8 | vector.cpp:362:8:362:13 | AST only |
-| vector.cpp:365:7:365:8 | vector.cpp:362:8:362:13 | AST only |
-| vector.cpp:370:8:370:9 | vector.cpp:369:9:369:14 | AST only |
-| vector.cpp:375:7:375:8 | vector.cpp:369:9:369:14 | AST only |
-| vector.cpp:379:7:379:8 | vector.cpp:378:8:378:13 | AST only |
-| vector.cpp:381:7:381:8 | vector.cpp:378:8:378:13 | AST only |
-| vector.cpp:388:7:388:8 | vector.cpp:330:10:330:15 | AST only |
-| vector.cpp:388:7:388:8 | vector.cpp:385:8:385:13 | AST only |
+| vector.cpp:342:7:342:8 | vector.cpp:341:8:341:13 | AST only |
+| vector.cpp:347:7:347:8 | vector.cpp:345:9:345:14 | AST only |
+| vector.cpp:357:7:357:8 | vector.cpp:330:10:330:15 | AST only |
+| vector.cpp:361:7:361:8 | vector.cpp:360:8:360:13 | AST only |
+| vector.cpp:363:7:363:8 | vector.cpp:360:8:360:13 | AST only |
+| vector.cpp:367:7:367:8 | vector.cpp:366:8:366:13 | AST only |
+| vector.cpp:369:7:369:8 | vector.cpp:366:8:366:13 | AST only |
+| vector.cpp:374:8:374:9 | vector.cpp:373:9:373:14 | AST only |
+| vector.cpp:379:7:379:8 | vector.cpp:373:9:373:14 | AST only |
+| vector.cpp:383:7:383:8 | vector.cpp:382:8:382:13 | AST only |
+| vector.cpp:385:7:385:8 | vector.cpp:382:8:382:13 | AST only |
+| vector.cpp:392:7:392:8 | vector.cpp:330:10:330:15 | AST only |
+| vector.cpp:392:7:392:8 | vector.cpp:389:8:389:13 | AST only |
+| vector.cpp:396:7:396:9 | vector.cpp:399:38:399:43 | AST only |
+| vector.cpp:400:7:400:9 | vector.cpp:399:38:399:43 | AST only |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
index 92cd5f4c9f5..0cc6570a175 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
@@ -330,8 +330,12 @@ void taint_vector_output_iterator(std::vector::iterator iter) {
*iter = source();
}
+void vector_iterator_assign_wrapper(std::vector::iterator iter, int i) {
+ *iter = i;
+}
+
void test_vector_output_iterator(int b) {
- std::vector v1(10), v2(10), v3(10), v4(10), v5(10), v6(10), v7(10), v8(10), v9(10);
+ std::vector v1(10), v2(10), v3(10), v4(10), v5(10), v6(10), v7(10), v8(10), v9(10), v10(10), v11(10);
std::vector::iterator i1 = v1.begin();
*i1 = source();
@@ -386,4 +390,12 @@ void test_vector_output_iterator(int b) {
taint_vector_output_iterator(i9);
sink(v9);
+
+ std::vector::iterator i10 = v10.begin();
+ vector_iterator_assign_wrapper(i10, 10);
+ sink(v10); // FALSE POSITIVE
+
+ std::vector::iterator i11 = v11.begin();
+ vector_iterator_assign_wrapper(i11, source());
+ sink(v11); // tainted [NOT DETECTED by IR]
}
From 9e3bfe1968c3c39339bf638ce47a709c9a1effc4 Mon Sep 17 00:00:00 2001
From: Robert Marsh
Date: Mon, 21 Sep 2020 16:17:16 -0700
Subject: [PATCH 025/411] C++: Fix iterator flow context sensitivity
---
.../cpp/dataflow/internal/DataFlowPrivate.qll | 6 ++-
.../cpp/dataflow/internal/DataFlowUtil.qll | 42 ++++++++++++-------
.../code/cpp/dataflow/internal/FlowVar.qll | 7 ++++
.../dataflow/internal/TaintTrackingUtil.qll | 5 ---
.../dataflow/taint-tests/taint.expected | 1 -
.../dataflow/taint-tests/test_diff.expected | 1 -
6 files changed, 37 insertions(+), 25 deletions(-)
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll
index 42c31bca69c..e737f8b2d94 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll
@@ -1,6 +1,8 @@
private import cpp
private import DataFlowUtil
private import DataFlowDispatch
+private import FlowVar
+
/** Gets the instance argument of a non-static call. */
private Node getInstanceArgument(Call call) {
@@ -106,7 +108,7 @@ private class ExprOutNode extends OutNode, ExprNode {
override DataFlowCall getCall() { result = this.getExpr() }
}
-private class RefOutNode extends OutNode, DefinitionByReferenceNode {
+private class RefOutNode extends OutNode, DefinitionByReferenceOrIteratorNode {
/** Gets the underlying call. */
override DataFlowCall getCall() { result = this.getArgument().getParent() }
}
@@ -120,7 +122,7 @@ OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) {
kind = TNormalReturnKind()
or
exists(int i |
- result.asDefiningArgument() = call.getArgument(i) and
+ result.(DefinitionByReferenceOrIteratorNode).getArgument() = call.getArgument(i) and
kind = TRefReturnKind(i)
)
}
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
index 963f1a17826..25a37f9db0f 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll
@@ -182,29 +182,23 @@ class ImplicitParameterNode extends ParameterNode, TInstanceParameterNode {
override predicate isParameterOf(Function fun, int i) { f = fun and i = -1 }
}
-/**
- * A node that represents the value of a variable after a function call that
- * may have changed the variable because it's passed by reference.
- *
- * A typical example would be a call `f(&x)`. Firstly, there will be flow into
- * `x` from previous definitions of `x`. Secondly, there will be a
- * `DefinitionByReferenceNode` to represent the value of `x` after the call has
- * returned. This node will have its `getArgument()` equal to `&x`.
- */
-class DefinitionByReferenceNode extends PartialDefinitionNode {
+class DefinitionByReferenceOrIteratorNode extends PartialDefinitionNode {
Expr inner;
Expr argument;
- DefinitionByReferenceNode() {
- this.getPartialDefinition().(DefinitionByReference).definesExpressions(inner, argument)
+ DefinitionByReferenceOrIteratorNode() {
+ this.getPartialDefinition().definesExpressions(inner, argument) and
+ (
+ this.getPartialDefinition() instanceof DefinitionByReference
+ or
+ this.getPartialDefinition() instanceof DefinitionByIterator
+ )
}
override Function getFunction() { result = inner.getEnclosingFunction() }
override Type getType() { result = inner.getType() }
- override string toString() { result = "ref arg " + argument.toString() }
-
override Location getLocation() { result = argument.getLocation() }
override ExprNode getPreUpdateNode() { result.getExpr() = argument }
@@ -221,6 +215,22 @@ class DefinitionByReferenceNode extends PartialDefinitionNode {
}
}
+
+/**
+ * A node that represents the value of a variable after a function call that
+ * may have changed the variable because it's passed by reference.
+ *
+ * A typical example would be a call `f(&x)`. Firstly, there will be flow into
+ * `x` from previous definitions of `x`. Secondly, there will be a
+ * `DefinitionByReferenceNode` to represent the value of `x` after the call has
+ * returned. This node will have its `getArgument()` equal to `&x`.
+ */
+class DefinitionByReferenceNode extends DefinitionByReferenceOrIteratorNode {
+ override VariablePartialDefinition pd;
+
+ override string toString() { result = "ref arg " + argument.toString() }
+}
+
/**
* The value of an uninitialized local variable, viewed as a node in a data
* flow graph.
@@ -551,10 +561,10 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
or
// In `f(&x->a)`, this step provides the flow from post-`&` to post-`x->a`,
// from which there is field flow to `x` via reverse read.
- exists(VariablePartialDefinition def, Expr inner, Expr outer |
+ exists(PartialDefinition def, Expr inner, Expr outer |
def.definesExpressions(inner, outer) and
inner = nodeTo.(InnerPartialDefinitionNode).getPreUpdateNode().asExpr() and
- outer = nodeFrom.(VariablePartialDefinitionNode).getPreUpdateNode().asExpr()
+ outer = nodeFrom.(PartialDefinitionNode).getPreUpdateNode().asExpr()
)
or
// Reverse flow: data that flows from the post-update node of a reference
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
index 13f11f8b275..15c15595c4f 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/FlowVar.qll
@@ -243,6 +243,13 @@ private module PartialDefinitions {
}
}
+ /**
+ * A partial definition that's a definition by reference.
+ */
+ class DefinitionByIterator extends IteratorPartialDefinition {
+ DefinitionByIterator() { exists(Call c | this = c.getAnArgument() or this = c.getQualifier()) }
+ }
+
/**
* A partial definition that's a definition by reference.
*/
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll
index 3190d3e9eba..17cb9b88104 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll
@@ -31,11 +31,6 @@ predicate localTaintStep(DataFlow::Node src, DataFlow::Node sink) {
*/
predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
localAdditionalTaintStep(src, sink)
- or
- exists(FunctionCall call, int i |
- sink.(DataFlow::IteratorPartialDefinitionNode).getPartialDefinition().definesExpressions(_, call.getArgument(i)) and
- src.(DataFlow::RefParameterFinalValueNode).getParameter() = call.getTarget().getParameter(i)
- )
}
/**
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
index f91b718bdda..033cd47145b 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
@@ -388,5 +388,4 @@
| vector.cpp:385:7:385:8 | v8 | vector.cpp:382:8:382:13 | call to source |
| vector.cpp:392:7:392:8 | v9 | vector.cpp:330:10:330:15 | call to source |
| vector.cpp:392:7:392:8 | v9 | vector.cpp:389:8:389:13 | call to source |
-| vector.cpp:396:7:396:9 | v10 | vector.cpp:399:38:399:43 | call to source |
| vector.cpp:400:7:400:9 | v11 | vector.cpp:399:38:399:43 | call to source |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected
index 6397c1d7830..3dc9b717e07 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_diff.expected
@@ -313,5 +313,4 @@
| vector.cpp:385:7:385:8 | vector.cpp:382:8:382:13 | AST only |
| vector.cpp:392:7:392:8 | vector.cpp:330:10:330:15 | AST only |
| vector.cpp:392:7:392:8 | vector.cpp:389:8:389:13 | AST only |
-| vector.cpp:396:7:396:9 | vector.cpp:399:38:399:43 | AST only |
| vector.cpp:400:7:400:9 | vector.cpp:399:38:399:43 | AST only |
From 772a51508f09f8b8b7d2e256db11dab0fbfd33f6 Mon Sep 17 00:00:00 2001
From: Robert Marsh
Date: Mon, 21 Sep 2020 16:19:41 -0700
Subject: [PATCH 026/411] C++: Update test comment
---
cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
index 0cc6570a175..b5dad811998 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp
@@ -393,7 +393,7 @@ void test_vector_output_iterator(int b) {
std::vector::iterator i10 = v10.begin();
vector_iterator_assign_wrapper(i10, 10);
- sink(v10); // FALSE POSITIVE
+ sink(v10);
std::vector::iterator i11 = v11.begin();
vector_iterator_assign_wrapper(i11, source());
From e836bae20ffaacd925a1f6d999452fa266f4d8db Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 18 Sep 2020 10:45:27 +0100
Subject: [PATCH 027/411] C++: Tidy up test stl.h a little.
---
cpp/ql/test/library-tests/dataflow/taint-tests/stl.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h b/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h
index f04eb5a01d4..a2ac49148fb 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h
@@ -128,7 +128,12 @@ namespace std
template basic_string operator+(const basic_string& lhs, const charT* rhs);
typedef basic_string string;
+}
+// --- istring / ostream / stringstream ---
+
+namespace std
+{
template >
class basic_istream /*: virtual public basic_ios - not needed for this test */ {
public:
From 7dce4d0a6e5944cf349277c6da6f8d4311df4159 Mon Sep 17 00:00:00 2001
From: Jonas Jensen
Date: Tue, 22 Sep 2020 13:39:22 +0200
Subject: [PATCH 028/411] C++: Rename: name the file the same as the class
---
...leRangeAnalysisDef.qll => SimpleRangeAnalysisDefinition.qll} | 0
.../src/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll | 2 +-
2 files changed, 1 insertion(+), 1 deletion(-)
rename cpp/ql/src/experimental/semmle/code/cpp/models/interfaces/{SimpleRangeAnalysisDef.qll => SimpleRangeAnalysisDefinition.qll} (100%)
diff --git a/cpp/ql/src/experimental/semmle/code/cpp/models/interfaces/SimpleRangeAnalysisDef.qll b/cpp/ql/src/experimental/semmle/code/cpp/models/interfaces/SimpleRangeAnalysisDefinition.qll
similarity index 100%
rename from cpp/ql/src/experimental/semmle/code/cpp/models/interfaces/SimpleRangeAnalysisDef.qll
rename to cpp/ql/src/experimental/semmle/code/cpp/models/interfaces/SimpleRangeAnalysisDefinition.qll
diff --git a/cpp/ql/src/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll b/cpp/ql/src/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll
index 05c2e519b46..d6e7d62435c 100644
--- a/cpp/ql/src/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll
+++ b/cpp/ql/src/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll
@@ -45,7 +45,7 @@
import cpp
private import RangeAnalysisUtils
private import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisExpr
-private import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisDef
+private import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisDefinition
import RangeSSA
import SimpleRangeAnalysisCached
private import NanAnalysis
From 8065bf15ad865d50ebed795dd12eb6f6079a8921 Mon Sep 17 00:00:00 2001
From: Jonas Jensen
Date: Tue, 22 Sep 2020 13:37:24 +0200
Subject: [PATCH 029/411] C++: Per-variable overrides
Without these changes, there was no way to tell which variables were
overridden by a given instance of `SimpleRangeAnalysisDefinition`. All
four overrides are needed because they fit into different mutual
recursions of the `SimpleRangeAnalysis` implementation.
---
.../SimpleRangeAnalysisDefinition.qll | 53 ++++++++++++++-----
.../cpp/rangeanalysis/SimpleRangeAnalysis.qll | 11 ++--
2 files changed, 49 insertions(+), 15 deletions(-)
diff --git a/cpp/ql/src/experimental/semmle/code/cpp/models/interfaces/SimpleRangeAnalysisDefinition.qll b/cpp/ql/src/experimental/semmle/code/cpp/models/interfaces/SimpleRangeAnalysisDefinition.qll
index c2647e2bebc..e1d64dfcf5a 100644
--- a/cpp/ql/src/experimental/semmle/code/cpp/models/interfaces/SimpleRangeAnalysisDefinition.qll
+++ b/cpp/ql/src/experimental/semmle/code/cpp/models/interfaces/SimpleRangeAnalysisDefinition.qll
@@ -10,25 +10,54 @@ import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
/**
* EXPERIMENTAL: The API of this class may change without notice.
*
- * An SSA definition for which a range can be deduced. Extend this class to add
- * functionality to the range analysis library.
+ * An SSA definition for which a range can be deduced. As with
+ * `RangeSsaDefinition` and `SsaDefinition`, instances of this class
+ * correspond to points in the program where one or more variables are defined
+ * or have their value constrained in some way.
+ *
+ * Extend this class to add functionality to the range analysis library.
*/
abstract class SimpleRangeAnalysisDefinition extends RangeSsaDefinition {
- /**
- * Gets the lower bound of the defomotopn.
+ /**
+ * Holds if this `SimpleRangeAnalysisDefinition` adds range information for
+ * `v`. Because a `SimpleRangeAnalysisDefinition` is just a point in the
+ * program, it's possible that more than one variable might be defined at
+ * this point. This predicate clarifies which variable(s) should get range
+ * information from `this`.
*
- * Implementations of this predicate should use
- * `getFullyConvertedLowerBounds` and `getFullyConvertedUpperBounds` for
- * recursive calls to get the bounds of their children.
+ * This predicate **must be overridden** to hold for any `v` that can show
+ * up in the other members of `SimpleRangeAnalysisDefinition`. Conversely,
+ * the other members **must be accurate** for any `v` in this predicate.
*/
- abstract float getLowerBounds();
+ abstract predicate hasRangeInformationFor(StackVariable v);
/**
- * Gets the upper bound of the definition.
+ * Holds if `(this, v)` depends on the range of the unconverted expression
+ * `e`. This information is used to inform the range analysis about cyclic
+ * dependencies. Without this information, range analysis might work for
+ * simple cases but will go into infinite loops on complex code.
+ *
+ * For example, when modelling the definition by reference in a call to an
+ * overloaded `operator=`, written as `v = e`, the definition of `(this, v)`
+ * depends on `e`.
+ */
+ abstract predicate dependsOnExpr(StackVariable v, Expr e);
+
+ /**
+ * Gets the lower bound of the variable `v` defined by this definition.
*
* Implementations of this predicate should use
* `getFullyConvertedLowerBounds` and `getFullyConvertedUpperBounds` for
- * recursive calls to get the bounds of their children.
+ * recursive calls to get the bounds of their dependencies.
*/
- abstract float getUpperBounds();
-}
\ No newline at end of file
+ abstract float getLowerBounds(StackVariable v);
+
+ /**
+ * Gets the upper bound of the variable `v` defined by this definition.
+ *
+ * Implementations of this predicate should use
+ * `getFullyConvertedLowerBounds` and `getFullyConvertedUpperBounds` for
+ * recursive calls to get the bounds of their dependencies.
+ */
+ abstract float getUpperBounds(StackVariable v);
+}
diff --git a/cpp/ql/src/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll b/cpp/ql/src/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll
index d6e7d62435c..886c6347622 100644
--- a/cpp/ql/src/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll
+++ b/cpp/ql/src/semmle/code/cpp/rangeanalysis/SimpleRangeAnalysis.qll
@@ -336,6 +336,11 @@ private predicate defDependsOnDef(
or
// Phi nodes.
phiDependsOnDef(def, v, srcDef, srcVar)
+ or
+ // Extensions
+ exists(Expr expr | def.(SimpleRangeAnalysisDefinition).dependsOnExpr(v, expr) |
+ exprDependsOnDef(expr, srcDef, srcVar)
+ )
}
/**
@@ -495,7 +500,7 @@ private predicate analyzableDef(RangeSsaDefinition def, StackVariable v) {
phiDependsOnDef(def, v, _, _)
or
// A modeled def for range analysis
- def.(SimpleRangeAnalysisDefinition).getAVariable() =v
+ def.(SimpleRangeAnalysisDefinition).hasRangeInformationFor(v)
}
/**
@@ -1220,7 +1225,7 @@ private float getDefLowerBoundsImpl(RangeSsaDefinition def, StackVariable v) {
result = getPhiLowerBounds(v, def)
or
// A modeled def for range analysis
- result = def.(SimpleRangeAnalysisDefinition).getLowerBounds()
+ result = def.(SimpleRangeAnalysisDefinition).getLowerBounds(v)
or
// Unanalyzable definitions.
unanalyzableDefBounds(def, v, result, _)
@@ -1256,7 +1261,7 @@ private float getDefUpperBoundsImpl(RangeSsaDefinition def, StackVariable v) {
result = getPhiUpperBounds(v, def)
or
// A modeled def for range analysis
- result = def.(SimpleRangeAnalysisDefinition).getUpperBounds()
+ result = def.(SimpleRangeAnalysisDefinition).getUpperBounds(v)
or
// Unanalyzable definitions.
unanalyzableDefBounds(def, v, _, result)
From d1f453be368103541800393a669e6014edac1092 Mon Sep 17 00:00:00 2001
From: Jonas Jensen
Date: Tue, 22 Sep 2020 13:40:27 +0200
Subject: [PATCH 030/411] C++: import SimpleRangeAnalysisInternal
This ensures that `getFullyConverted{Lower,Upper}Bounds` are available
where they need to be called.
---
.../cpp/models/interfaces/SimpleRangeAnalysisDefinition.qll | 2 ++
1 file changed, 2 insertions(+)
diff --git a/cpp/ql/src/experimental/semmle/code/cpp/models/interfaces/SimpleRangeAnalysisDefinition.qll b/cpp/ql/src/experimental/semmle/code/cpp/models/interfaces/SimpleRangeAnalysisDefinition.qll
index e1d64dfcf5a..0cf570a72b4 100644
--- a/cpp/ql/src/experimental/semmle/code/cpp/models/interfaces/SimpleRangeAnalysisDefinition.qll
+++ b/cpp/ql/src/experimental/semmle/code/cpp/models/interfaces/SimpleRangeAnalysisDefinition.qll
@@ -61,3 +61,5 @@ abstract class SimpleRangeAnalysisDefinition extends RangeSsaDefinition {
*/
abstract float getUpperBounds(StackVariable v);
}
+
+import SimpleRangeAnalysisInternal
From 826632d6a96b636f54ce674a3e0a1b8e755c71b8 Mon Sep 17 00:00:00 2001
From: Jonas Jensen
Date: Tue, 22 Sep 2020 14:02:14 +0200
Subject: [PATCH 031/411] C++: Add a test of def overrides
The def used in this test is not overridden yet.
---
.../rangeanalysis/extensibility/extensibility.c | 7 ++++++-
.../rangeanalysis/extensibility/extensibility.expected | 2 ++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/cpp/ql/test/experimental/library-tests/rangeanalysis/extensibility/extensibility.c b/cpp/ql/test/experimental/library-tests/rangeanalysis/extensibility/extensibility.c
index afdde0b615c..288b68a0bd7 100644
--- a/cpp/ql/test/experimental/library-tests/rangeanalysis/extensibility/extensibility.c
+++ b/cpp/ql/test/experimental/library-tests/rangeanalysis/extensibility/extensibility.c
@@ -11,4 +11,9 @@ int test_extensibility_add(int x) {
int test_overridability_sub(int x) {
int result = x - x; // Returns 0 due to custom modeling in QL
return result; // 0
-}
\ No newline at end of file
+}
+
+void test_parameter_override(int magic_name_at_most_10, int magic_name_at_most_20) {
+ magic_name_at_most_10;
+ magic_name_at_most_20;
+}
diff --git a/cpp/ql/test/experimental/library-tests/rangeanalysis/extensibility/extensibility.expected b/cpp/ql/test/experimental/library-tests/rangeanalysis/extensibility/extensibility.expected
index ad97d9b2df5..4ae1961c247 100644
--- a/cpp/ql/test/experimental/library-tests/rangeanalysis/extensibility/extensibility.expected
+++ b/cpp/ql/test/experimental/library-tests/rangeanalysis/extensibility/extensibility.expected
@@ -5,3 +5,5 @@
| extensibility.c:12:16:12:16 | x | -2.147483648E9 | 2.147483647E9 |
| extensibility.c:12:20:12:20 | x | -2.147483648E9 | 2.147483647E9 |
| extensibility.c:13:10:13:15 | result | 0.0 | 0.0 |
+| extensibility.c:17:3:17:23 | magic_name_at_most_10 | -2.147483648E9 | 2.147483647E9 |
+| extensibility.c:18:3:18:23 | magic_name_at_most_20 | -2.147483648E9 | 2.147483647E9 |
From 9fd8b0431ae8e58ddadce0b68cab4cd7c7befcad Mon Sep 17 00:00:00 2001
From: Jonas Jensen
Date: Tue, 22 Sep 2020 15:45:17 +0200
Subject: [PATCH 032/411] C++: Add a SimpleRangeAnalysisDefinition test def
---
.../extensibility/extensibility.expected | 4 +--
.../extensibility/extensibility.ql | 36 +++++++++++++++++++
2 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/cpp/ql/test/experimental/library-tests/rangeanalysis/extensibility/extensibility.expected b/cpp/ql/test/experimental/library-tests/rangeanalysis/extensibility/extensibility.expected
index 4ae1961c247..cc8508a7858 100644
--- a/cpp/ql/test/experimental/library-tests/rangeanalysis/extensibility/extensibility.expected
+++ b/cpp/ql/test/experimental/library-tests/rangeanalysis/extensibility/extensibility.expected
@@ -5,5 +5,5 @@
| extensibility.c:12:16:12:16 | x | -2.147483648E9 | 2.147483647E9 |
| extensibility.c:12:20:12:20 | x | -2.147483648E9 | 2.147483647E9 |
| extensibility.c:13:10:13:15 | result | 0.0 | 0.0 |
-| extensibility.c:17:3:17:23 | magic_name_at_most_10 | -2.147483648E9 | 2.147483647E9 |
-| extensibility.c:18:3:18:23 | magic_name_at_most_20 | -2.147483648E9 | 2.147483647E9 |
+| extensibility.c:17:3:17:23 | magic_name_at_most_10 | -2.147483648E9 | 10.0 |
+| extensibility.c:18:3:18:23 | magic_name_at_most_20 | -2.147483648E9 | 20.0 |
diff --git a/cpp/ql/test/experimental/library-tests/rangeanalysis/extensibility/extensibility.ql b/cpp/ql/test/experimental/library-tests/rangeanalysis/extensibility/extensibility.ql
index a007a5d4dab..841fe2c8e6c 100644
--- a/cpp/ql/test/experimental/library-tests/rangeanalysis/extensibility/extensibility.ql
+++ b/cpp/ql/test/experimental/library-tests/rangeanalysis/extensibility/extensibility.ql
@@ -1,5 +1,7 @@
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
+import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils // for typeLowerBound
import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisExpr
+import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisDefinition
class CustomAddFunctionCall extends SimpleRangeAnalysisExpr, FunctionCall {
CustomAddFunctionCall() { this.getTarget().hasGlobalName("custom_add_function") }
@@ -37,6 +39,40 @@ class SelfSub extends SimpleRangeAnalysisExpr, SubExpr {
override predicate dependsOnChild(Expr child) { child = this.getAnOperand() }
}
+/**
+ * A definition for test purposes of a parameter `p` that starts with a
+ * special prefix. This class is written to exploit how QL behaves when class
+ * fields are not functionally determined by `this`. When multiple parameters
+ * of the same function have the special prefix, there is still only one
+ * instance of this class.
+ */
+class MagicParameterName extends SimpleRangeAnalysisDefinition {
+ Parameter p;
+ float value;
+
+ MagicParameterName() {
+ this.definedByParameter(p) and
+ value = p.getName().regexpCapture("magic_name_at_most_(\\d+)", 1).toFloat()
+ }
+
+ override predicate hasRangeInformationFor(StackVariable v) { v = p }
+
+ override predicate dependsOnExpr(StackVariable v, Expr e) {
+ // No dependencies. This sample class yields constant values.
+ none()
+ }
+
+ override float getLowerBounds(StackVariable var) {
+ var = p and
+ result = typeLowerBound(p.getUnspecifiedType())
+ }
+
+ override float getUpperBounds(StackVariable var) {
+ var = p and
+ result = value
+ }
+}
+
from VariableAccess expr, float lower, float upper
where
lower = lowerBound(expr) and
From 4faeede5cd60ea2ec114b5865ca1f62798400801 Mon Sep 17 00:00:00 2001
From: Jonas Jensen
Date: Tue, 22 Sep 2020 16:55:25 +0200
Subject: [PATCH 033/411] C++: Remove unnecessary comment on import
---
.../library-tests/rangeanalysis/extensibility/extensibility.ql | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cpp/ql/test/experimental/library-tests/rangeanalysis/extensibility/extensibility.ql b/cpp/ql/test/experimental/library-tests/rangeanalysis/extensibility/extensibility.ql
index 841fe2c8e6c..4fbfed1706d 100644
--- a/cpp/ql/test/experimental/library-tests/rangeanalysis/extensibility/extensibility.ql
+++ b/cpp/ql/test/experimental/library-tests/rangeanalysis/extensibility/extensibility.ql
@@ -1,5 +1,5 @@
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
-import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils // for typeLowerBound
+import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisExpr
import experimental.semmle.code.cpp.models.interfaces.SimpleRangeAnalysisDefinition
From 252f8aa89d8a7df958805540ab827ed517cb2a8b Mon Sep 17 00:00:00 2001
From: Arthur Baars
Date: Tue, 22 Sep 2020 15:20:40 +0200
Subject: [PATCH 034/411] Java: add Spring::MultipartRequest as taint source
---
...-09-23-spring-multipart-request-sources.md | 3 +++
.../semmle/code/java/dataflow/FlowSources.qll | 21 ++++++++++++++++++-
.../taintsources/SpringMultiPart.java | 10 +++++++++
.../dataflow/taintsources/remote.expected | 18 ++++++++++------
4 files changed, 45 insertions(+), 7 deletions(-)
create mode 100644 java/change-notes/2020-09-23-spring-multipart-request-sources.md
diff --git a/java/change-notes/2020-09-23-spring-multipart-request-sources.md b/java/change-notes/2020-09-23-spring-multipart-request-sources.md
new file mode 100644
index 00000000000..4e5f7740b85
--- /dev/null
+++ b/java/change-notes/2020-09-23-spring-multipart-request-sources.md
@@ -0,0 +1,3 @@
+lgtm,codescanning
+* The methods of the [Spring Web MultipartRequest](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/multipart/MultipartRequest.html)
+ class have been added as sources of remote user input, which may lead to more results from the security queries.
diff --git a/java/ql/src/semmle/code/java/dataflow/FlowSources.qll b/java/ql/src/semmle/code/java/dataflow/FlowSources.qll
index b6d367bc32c..fb2a0345b8b 100644
--- a/java/ql/src/semmle/code/java/dataflow/FlowSources.qll
+++ b/java/ql/src/semmle/code/java/dataflow/FlowSources.qll
@@ -106,12 +106,31 @@ private class MessageBodyReaderParameterSource extends RemoteFlowSource {
override string getSourceType() { result = "MessageBodyReader parameter" }
}
+private class SpringMultipartRequestSource extends RemoteFlowSource {
+ SpringMultipartRequestSource() {
+ exists(MethodAccess ma, Method m |
+ ma = this.asExpr() and
+ m = ma.getMethod() and
+ m
+ .getDeclaringType()
+ .getASourceSupertype*()
+ .hasQualifiedName("org.springframework.web.multipart", "MultipartRequest") and
+ m.getName().matches("get%")
+ )
+ }
+
+ override string getSourceType() { result = "Spring MultipartRequest getter" }
+}
+
private class SpringMultipartFileSource extends RemoteFlowSource {
SpringMultipartFileSource() {
exists(MethodAccess ma, Method m |
ma = this.asExpr() and
m = ma.getMethod() and
- m.getDeclaringType().hasQualifiedName("org.springframework.web.multipart", "MultipartFile") and
+ m
+ .getDeclaringType()
+ .getASourceSupertype*()
+ .hasQualifiedName("org.springframework.web.multipart", "MultipartFile") and
m.getName().matches("get%")
)
}
diff --git a/java/ql/test/library-tests/dataflow/taintsources/SpringMultiPart.java b/java/ql/test/library-tests/dataflow/taintsources/SpringMultiPart.java
index da5352dcde4..6702059ab70 100644
--- a/java/ql/test/library-tests/dataflow/taintsources/SpringMultiPart.java
+++ b/java/ql/test/library-tests/dataflow/taintsources/SpringMultiPart.java
@@ -1,4 +1,5 @@
import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartRequest;
public class SpringMultiPart {
MultipartFile file;
@@ -12,4 +13,13 @@ public class SpringMultiPart {
file.getContentType();
file.getOriginalFilename();
}
+
+ public void test(MultipartRequest request) {
+ request.getFile("name");
+ request.getFileMap();
+ request.getFileNames();
+ request.getFiles("name");
+ request.getMultiFileMap();
+ request.getMultipartContentType("name");
+ }
}
diff --git a/java/ql/test/library-tests/dataflow/taintsources/remote.expected b/java/ql/test/library-tests/dataflow/taintsources/remote.expected
index bd2b3ac4296..21403e9f01b 100644
--- a/java/ql/test/library-tests/dataflow/taintsources/remote.expected
+++ b/java/ql/test/library-tests/dataflow/taintsources/remote.expected
@@ -9,9 +9,15 @@
| RmiFlowImpl.java:4:30:4:40 | path | RmiFlowImpl.java:5:20:5:31 | ... + ... |
| RmiFlowImpl.java:4:30:4:40 | path | RmiFlowImpl.java:5:28:5:31 | path |
| RmiFlowImpl.java:4:30:4:40 | path | RmiFlowImpl.java:6:29:6:35 | command |
-| SpringMultiPart.java:7:3:7:17 | getBytes(...) | SpringMultiPart.java:7:3:7:17 | getBytes(...) |
-| SpringMultiPart.java:9:3:9:23 | getInputStream(...) | SpringMultiPart.java:9:3:9:23 | getInputStream(...) |
-| SpringMultiPart.java:10:3:10:20 | getResource(...) | SpringMultiPart.java:10:3:10:20 | getResource(...) |
-| SpringMultiPart.java:11:3:11:16 | getName(...) | SpringMultiPart.java:11:3:11:16 | getName(...) |
-| SpringMultiPart.java:12:3:12:23 | getContentType(...) | SpringMultiPart.java:12:3:12:23 | getContentType(...) |
-| SpringMultiPart.java:13:3:13:28 | getOriginalFilename(...) | SpringMultiPart.java:13:3:13:28 | getOriginalFilename(...) |
+| SpringMultiPart.java:8:3:8:17 | getBytes(...) | SpringMultiPart.java:8:3:8:17 | getBytes(...) |
+| SpringMultiPart.java:10:3:10:23 | getInputStream(...) | SpringMultiPart.java:10:3:10:23 | getInputStream(...) |
+| SpringMultiPart.java:11:3:11:20 | getResource(...) | SpringMultiPart.java:11:3:11:20 | getResource(...) |
+| SpringMultiPart.java:12:3:12:16 | getName(...) | SpringMultiPart.java:12:3:12:16 | getName(...) |
+| SpringMultiPart.java:13:3:13:23 | getContentType(...) | SpringMultiPart.java:13:3:13:23 | getContentType(...) |
+| SpringMultiPart.java:14:3:14:28 | getOriginalFilename(...) | SpringMultiPart.java:14:3:14:28 | getOriginalFilename(...) |
+| SpringMultiPart.java:18:3:18:25 | getFile(...) | SpringMultiPart.java:18:3:18:25 | getFile(...) |
+| SpringMultiPart.java:19:3:19:22 | getFileMap(...) | SpringMultiPart.java:19:3:19:22 | getFileMap(...) |
+| SpringMultiPart.java:20:3:20:24 | getFileNames(...) | SpringMultiPart.java:20:3:20:24 | getFileNames(...) |
+| SpringMultiPart.java:21:3:21:26 | getFiles(...) | SpringMultiPart.java:21:3:21:26 | getFiles(...) |
+| SpringMultiPart.java:22:3:22:27 | getMultiFileMap(...) | SpringMultiPart.java:22:3:22:27 | getMultiFileMap(...) |
+| SpringMultiPart.java:23:3:23:41 | getMultipartContentType(...) | SpringMultiPart.java:23:3:23:41 | getMultipartContentType(...) |
From ec2b3f0b6ca6d07613b0b68cb13d89fc80e6f9f4 Mon Sep 17 00:00:00 2001
From: Erik Krogh Kristensen
Date: Tue, 22 Sep 2020 21:02:26 +0200
Subject: [PATCH 035/411] better join-order fix in HTTP
---
.../ql/src/semmle/javascript/frameworks/HTTP.qll | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/javascript/ql/src/semmle/javascript/frameworks/HTTP.qll b/javascript/ql/src/semmle/javascript/frameworks/HTTP.qll
index 0f224ff060f..b3faa55501a 100644
--- a/javascript/ql/src/semmle/javascript/frameworks/HTTP.qll
+++ b/javascript/ql/src/semmle/javascript/frameworks/HTTP.qll
@@ -253,21 +253,20 @@ module HTTP {
private predicate isDecoratedCall(DataFlow::CallNode call, DataFlow::FunctionNode decoratee) {
// indirect route-handler `result` is given to function `outer`, which returns function `inner` which calls the function `pred`.
exists(int i, DataFlow::FunctionNode outer, HTTP::RouteHandlerCandidate inner |
+ inner = outer.getAReturn().getALocalSource() and
decoratee = call.getArgument(i).getALocalSource() and
outer.getFunction() = call.getACallee() and
- returnsRouteHandler(outer, inner) and
- isAForwardingRouteHandlerCall(outer.getParameter(i), inner)
+ hasForwardingHandlerParameter(i, outer, inner)
)
}
/**
- * Holds if `fun` returns the route-handler-candidate `routeHandler`.
+ * Holds if the `i`th parameter of `outer` has a call that `inner` forwards its parameters to.
*/
- pragma[noinline]
- private predicate returnsRouteHandler(
- DataFlow::FunctionNode fun, HTTP::RouteHandlerCandidate routeHandler
+ private predicate hasForwardingHandlerParameter(
+ int i, DataFlow::FunctionNode outer, HTTP::RouteHandlerCandidate inner
) {
- routeHandler = fun.getAReturn().getALocalSource()
+ isAForwardingRouteHandlerCall(outer.getParameter(i), inner)
}
/**
From 2868d5bf34648dddcf29ffa3f0d4107e08013740 Mon Sep 17 00:00:00 2001
From: Tamas Vajk
Date: Tue, 22 Sep 2020 10:54:25 +0200
Subject: [PATCH 036/411] C#: Add pointer cast test cases
---
.../conversion/pointer/Pointer.cs | 28 +++++++++++++++++++
.../conversion/pointer/Pointer.expected | 11 ++++++++
.../conversion/pointer/Pointer.ql | 5 ++++
3 files changed, 44 insertions(+)
create mode 100644 csharp/ql/test/library-tests/conversion/pointer/Pointer.cs
create mode 100644 csharp/ql/test/library-tests/conversion/pointer/Pointer.expected
create mode 100644 csharp/ql/test/library-tests/conversion/pointer/Pointer.ql
diff --git a/csharp/ql/test/library-tests/conversion/pointer/Pointer.cs b/csharp/ql/test/library-tests/conversion/pointer/Pointer.cs
new file mode 100644
index 00000000000..c7e12ac39b4
--- /dev/null
+++ b/csharp/ql/test/library-tests/conversion/pointer/Pointer.cs
@@ -0,0 +1,28 @@
+using System;
+
+class C
+{
+ unsafe static void M1(int[] arr)
+ {
+ fixed (int* i1 = arr)
+ {
+ }
+
+ fixed (int* i2 = &arr[0])
+ {
+ int* i3 = i2;
+ i3 = i3 + 1;
+ *i2 = *i2 + 1;
+ void* v2 = i2;
+ }
+
+ int* i4 = null;
+
+ int number = 1024;
+ byte* p = (byte*)&number;
+
+ var s = "some string";
+ fixed (char* c1 = s)
+ { }
+ }
+}
diff --git a/csharp/ql/test/library-tests/conversion/pointer/Pointer.expected b/csharp/ql/test/library-tests/conversion/pointer/Pointer.expected
new file mode 100644
index 00000000000..7db63e5ef9f
--- /dev/null
+++ b/csharp/ql/test/library-tests/conversion/pointer/Pointer.expected
@@ -0,0 +1,11 @@
+| Pointer.cs:7:21:7:28 | Pointer.cs:7:21:7:28 | Int32* | Int32[] | access to parameter arr |
+| Pointer.cs:11:21:11:32 | Pointer.cs:11:21:11:32 | Int32* | Int32* | &... |
+| Pointer.cs:13:18:13:24 | Pointer.cs:13:18:13:24 | Int32* | Int32* | access to local variable i2 |
+| Pointer.cs:14:13:14:23 | Pointer.cs:14:13:14:23 | Int32* | Int32* | ... + ... |
+| Pointer.cs:15:13:15:25 | Pointer.cs:15:13:15:25 | Int32 | Int32 | ... + ... |
+| Pointer.cs:16:19:16:25 | Pointer.cs:16:19:16:25 | Void* | Void* | (...) ... |
+| Pointer.cs:19:14:19:22 | Pointer.cs:19:14:19:22 | Int32* | null | null |
+| Pointer.cs:21:13:21:25 | Pointer.cs:21:13:21:25 | Int32 | Int32 | 1024 |
+| Pointer.cs:22:15:22:32 | Pointer.cs:22:15:22:32 | Byte* | Byte* | (...) ... |
+| Pointer.cs:24:13:24:29 | Pointer.cs:24:13:24:29 | String | String | "some string" |
+| Pointer.cs:25:22:25:27 | Pointer.cs:25:22:25:27 | Char* | String | access to local variable s |
diff --git a/csharp/ql/test/library-tests/conversion/pointer/Pointer.ql b/csharp/ql/test/library-tests/conversion/pointer/Pointer.ql
new file mode 100644
index 00000000000..69e7db8c1cf
--- /dev/null
+++ b/csharp/ql/test/library-tests/conversion/pointer/Pointer.ql
@@ -0,0 +1,5 @@
+import csharp
+
+from Assignment a
+select a.getLocation(), a.getLValue().getType().toString(), a.getRValue().getType().toString(),
+ a.getRValue().toString()
From 48bf6d55aa3cb2807ea7776101e9e175588c936a Mon Sep 17 00:00:00 2001
From: Tamas Vajk
Date: Wed, 23 Sep 2020 12:19:42 +0200
Subject: [PATCH 037/411] C#: Add implicit cast from array to pointer
---
.../Entities/Expressions/ImplicitCast.cs | 9 +++++++++
csharp/ql/test/experimental/ir/ir/PrintAst.expected | 3 ++-
csharp/ql/test/experimental/ir/ir/raw_ir.expected | 4 ++--
.../controlflow/graph/BasicBlock.expected | 2 +-
.../controlflow/graph/Dominance.expected | 12 ++++++++----
.../controlflow/graph/EnclosingCallable.expected | 2 ++
.../controlflow/graph/EntryElement.expected | 2 ++
.../controlflow/graph/ExitElement.expected | 2 ++
.../controlflow/graph/NodeGraph.expected | 6 ++++--
.../conversion/pointer/Pointer.expected | 4 ++--
.../dataflow/signanalysis/MissingSign.expected | 3 ---
.../ql/test/library-tests/unsafe/PrintAst.expected | 3 ++-
12 files changed, 36 insertions(+), 16 deletions(-)
diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitCast.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitCast.cs
index d8d8c80cf75..299c3aa8f72 100644
--- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitCast.cs
+++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/ImplicitCast.cs
@@ -86,6 +86,15 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
return new ImplicitCast(info);
}
+ if (conversion.IsIdentity && conversion.IsImplicit &&
+ convertedType.Symbol is IPointerTypeSymbol &&
+ !(resolvedType.Symbol is IPointerTypeSymbol))
+ {
+ // int[] -> int*
+ // string -> char*
+ return new ImplicitCast(info);
+ }
+
// Default: Just create the expression without a conversion.
return Factory.Create(info);
}
diff --git a/csharp/ql/test/experimental/ir/ir/PrintAst.expected b/csharp/ql/test/experimental/ir/ir/PrintAst.expected
index 0ba7be8a584..25ea10bc476 100644
--- a/csharp/ql/test/experimental/ir/ir/PrintAst.expected
+++ b/csharp/ql/test/experimental/ir/ir/PrintAst.expected
@@ -762,7 +762,8 @@ pointers.cs:
# 5| 1: [LocalVariableAccess] access to local variable length
# 6| 1: [FixedStmt] fixed(...) { ... }
# 6| -1: [LocalVariableDeclAndInitExpr] Int32* b = ...
-# 6| 0: [ParameterAccess] access to parameter arr
+# 6| 0: [CastExpr] (...) ...
+# 6| 0: [ParameterAccess] access to parameter arr
# 6| 1: [LocalVariableAccess] access to local variable b
# 7| 0: [BlockStmt] {...}
# 8| 0: [LocalVariableDeclStmt] ... ...;
diff --git a/csharp/ql/test/experimental/ir/ir/raw_ir.expected b/csharp/ql/test/experimental/ir/ir/raw_ir.expected
index 785f3872787..e426955f9da 100644
--- a/csharp/ql/test/experimental/ir/ir/raw_ir.expected
+++ b/csharp/ql/test/experimental/ir/ir/raw_ir.expected
@@ -1327,8 +1327,8 @@ pointers.cs:
# 6| r6_1(glval) = VariableAddress[b] :
# 6| r6_2(glval) = VariableAddress[arr] :
# 6| r6_3(Int32[]) = Load : &:r6_2, ~m?
-# 6| r6_4(Int32*) = Convert : r6_3
-# 6| mu6_5(Int32*) = Store : &:r6_1, r6_3
+# 6| r6_4(Int32*) = CheckedConvertOrThrow : r6_3
+# 6| mu6_5(Int32*) = Store : &:r6_1, r6_4
# 8| r8_1(glval) = VariableAddress[p] :
# 8| r8_2(glval) = VariableAddress[b] :
# 8| r8_3(Int32*) = Load : &:r8_2, ~m?
diff --git a/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected b/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected
index cf6a34b5ba7..d7ca5bdd073 100644
--- a/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected
+++ b/csharp/ql/test/library-tests/controlflow/graph/BasicBlock.expected
@@ -725,7 +725,7 @@
| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:7:13:7:22 | ... is ... | 14 |
| TypeAccesses.cs:7:25:7:25 | ; | TypeAccesses.cs:7:25:7:25 | ; | 1 |
| TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:3:10:3:10 | exit M | 4 |
-| VarDecls.cs:5:18:5:19 | enter M1 | VarDecls.cs:5:18:5:19 | exit M1 | 16 |
+| VarDecls.cs:5:18:5:19 | enter M1 | VarDecls.cs:5:18:5:19 | exit M1 | 18 |
| VarDecls.cs:13:12:13:13 | enter M2 | VarDecls.cs:13:12:13:13 | exit M2 | 12 |
| VarDecls.cs:19:7:19:8 | enter M3 | VarDecls.cs:25:20:25:20 | access to parameter b | 12 |
| VarDecls.cs:25:13:25:29 | return ...; | VarDecls.cs:19:7:19:8 | exit M3 | 2 |
diff --git a/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected b/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected
index 9faece057e1..773e3cd0204 100644
--- a/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected
+++ b/csharp/ql/test/library-tests/controlflow/graph/Dominance.expected
@@ -2568,11 +2568,13 @@ dominance
| VarDecls.cs:7:9:10:9 | fixed(...) { ... } | VarDecls.cs:7:27:7:33 | access to parameter strings |
| VarDecls.cs:7:22:7:36 | Char* c1 = ... | VarDecls.cs:7:44:7:50 | access to parameter strings |
| VarDecls.cs:7:27:7:33 | access to parameter strings | VarDecls.cs:7:35:7:35 | 0 |
-| VarDecls.cs:7:27:7:36 | access to array element | VarDecls.cs:7:22:7:36 | Char* c1 = ... |
+| VarDecls.cs:7:27:7:36 | (...) ... | VarDecls.cs:7:22:7:36 | Char* c1 = ... |
+| VarDecls.cs:7:27:7:36 | access to array element | VarDecls.cs:7:27:7:36 | (...) ... |
| VarDecls.cs:7:35:7:35 | 0 | VarDecls.cs:7:27:7:36 | access to array element |
| VarDecls.cs:7:39:7:53 | Char* c2 = ... | VarDecls.cs:8:9:10:9 | {...} |
| VarDecls.cs:7:44:7:50 | access to parameter strings | VarDecls.cs:7:52:7:52 | 1 |
-| VarDecls.cs:7:44:7:53 | access to array element | VarDecls.cs:7:39:7:53 | Char* c2 = ... |
+| VarDecls.cs:7:44:7:53 | (...) ... | VarDecls.cs:7:39:7:53 | Char* c2 = ... |
+| VarDecls.cs:7:44:7:53 | access to array element | VarDecls.cs:7:44:7:53 | (...) ... |
| VarDecls.cs:7:52:7:52 | 1 | VarDecls.cs:7:44:7:53 | access to array element |
| VarDecls.cs:8:9:10:9 | {...} | VarDecls.cs:9:27:9:28 | access to local variable c1 |
| VarDecls.cs:9:13:9:29 | return ...; | VarDecls.cs:5:18:5:19 | exit M1 |
@@ -5703,12 +5705,14 @@ postDominance
| VarDecls.cs:5:18:5:19 | exit M1 | VarDecls.cs:9:13:9:29 | return ...; |
| VarDecls.cs:6:5:11:5 | {...} | VarDecls.cs:5:18:5:19 | enter M1 |
| VarDecls.cs:7:9:10:9 | fixed(...) { ... } | VarDecls.cs:6:5:11:5 | {...} |
-| VarDecls.cs:7:22:7:36 | Char* c1 = ... | VarDecls.cs:7:27:7:36 | access to array element |
+| VarDecls.cs:7:22:7:36 | Char* c1 = ... | VarDecls.cs:7:27:7:36 | (...) ... |
| VarDecls.cs:7:27:7:33 | access to parameter strings | VarDecls.cs:7:9:10:9 | fixed(...) { ... } |
+| VarDecls.cs:7:27:7:36 | (...) ... | VarDecls.cs:7:27:7:36 | access to array element |
| VarDecls.cs:7:27:7:36 | access to array element | VarDecls.cs:7:35:7:35 | 0 |
| VarDecls.cs:7:35:7:35 | 0 | VarDecls.cs:7:27:7:33 | access to parameter strings |
-| VarDecls.cs:7:39:7:53 | Char* c2 = ... | VarDecls.cs:7:44:7:53 | access to array element |
+| VarDecls.cs:7:39:7:53 | Char* c2 = ... | VarDecls.cs:7:44:7:53 | (...) ... |
| VarDecls.cs:7:44:7:50 | access to parameter strings | VarDecls.cs:7:22:7:36 | Char* c1 = ... |
+| VarDecls.cs:7:44:7:53 | (...) ... | VarDecls.cs:7:44:7:53 | access to array element |
| VarDecls.cs:7:44:7:53 | access to array element | VarDecls.cs:7:52:7:52 | 1 |
| VarDecls.cs:7:52:7:52 | 1 | VarDecls.cs:7:44:7:50 | access to parameter strings |
| VarDecls.cs:8:9:10:9 | {...} | VarDecls.cs:7:39:7:53 | Char* c2 = ... |
diff --git a/csharp/ql/test/library-tests/controlflow/graph/EnclosingCallable.expected b/csharp/ql/test/library-tests/controlflow/graph/EnclosingCallable.expected
index 6dbf1e568b0..10afd142066 100644
--- a/csharp/ql/test/library-tests/controlflow/graph/EnclosingCallable.expected
+++ b/csharp/ql/test/library-tests/controlflow/graph/EnclosingCallable.expected
@@ -2931,10 +2931,12 @@ nodeEnclosing
| VarDecls.cs:7:9:10:9 | fixed(...) { ... } | VarDecls.cs:5:18:5:19 | M1 |
| VarDecls.cs:7:22:7:36 | Char* c1 = ... | VarDecls.cs:5:18:5:19 | M1 |
| VarDecls.cs:7:27:7:33 | access to parameter strings | VarDecls.cs:5:18:5:19 | M1 |
+| VarDecls.cs:7:27:7:36 | (...) ... | VarDecls.cs:5:18:5:19 | M1 |
| VarDecls.cs:7:27:7:36 | access to array element | VarDecls.cs:5:18:5:19 | M1 |
| VarDecls.cs:7:35:7:35 | 0 | VarDecls.cs:5:18:5:19 | M1 |
| VarDecls.cs:7:39:7:53 | Char* c2 = ... | VarDecls.cs:5:18:5:19 | M1 |
| VarDecls.cs:7:44:7:50 | access to parameter strings | VarDecls.cs:5:18:5:19 | M1 |
+| VarDecls.cs:7:44:7:53 | (...) ... | VarDecls.cs:5:18:5:19 | M1 |
| VarDecls.cs:7:44:7:53 | access to array element | VarDecls.cs:5:18:5:19 | M1 |
| VarDecls.cs:7:52:7:52 | 1 | VarDecls.cs:5:18:5:19 | M1 |
| VarDecls.cs:8:9:10:9 | {...} | VarDecls.cs:5:18:5:19 | M1 |
diff --git a/csharp/ql/test/library-tests/controlflow/graph/EntryElement.expected b/csharp/ql/test/library-tests/controlflow/graph/EntryElement.expected
index 8751b4d35f7..cf3a8c054eb 100644
--- a/csharp/ql/test/library-tests/controlflow/graph/EntryElement.expected
+++ b/csharp/ql/test/library-tests/controlflow/graph/EntryElement.expected
@@ -2064,10 +2064,12 @@
| VarDecls.cs:7:9:10:9 | fixed(...) { ... } | VarDecls.cs:7:9:10:9 | fixed(...) { ... } |
| VarDecls.cs:7:22:7:36 | Char* c1 = ... | VarDecls.cs:7:27:7:33 | access to parameter strings |
| VarDecls.cs:7:27:7:33 | access to parameter strings | VarDecls.cs:7:27:7:33 | access to parameter strings |
+| VarDecls.cs:7:27:7:36 | (...) ... | VarDecls.cs:7:27:7:33 | access to parameter strings |
| VarDecls.cs:7:27:7:36 | access to array element | VarDecls.cs:7:27:7:33 | access to parameter strings |
| VarDecls.cs:7:35:7:35 | 0 | VarDecls.cs:7:35:7:35 | 0 |
| VarDecls.cs:7:39:7:53 | Char* c2 = ... | VarDecls.cs:7:44:7:50 | access to parameter strings |
| VarDecls.cs:7:44:7:50 | access to parameter strings | VarDecls.cs:7:44:7:50 | access to parameter strings |
+| VarDecls.cs:7:44:7:53 | (...) ... | VarDecls.cs:7:44:7:50 | access to parameter strings |
| VarDecls.cs:7:44:7:53 | access to array element | VarDecls.cs:7:44:7:50 | access to parameter strings |
| VarDecls.cs:7:52:7:52 | 1 | VarDecls.cs:7:52:7:52 | 1 |
| VarDecls.cs:8:9:10:9 | {...} | VarDecls.cs:8:9:10:9 | {...} |
diff --git a/csharp/ql/test/library-tests/controlflow/graph/ExitElement.expected b/csharp/ql/test/library-tests/controlflow/graph/ExitElement.expected
index 96165e8fe19..428ddfeca24 100644
--- a/csharp/ql/test/library-tests/controlflow/graph/ExitElement.expected
+++ b/csharp/ql/test/library-tests/controlflow/graph/ExitElement.expected
@@ -2770,10 +2770,12 @@
| VarDecls.cs:7:9:10:9 | fixed(...) { ... } | VarDecls.cs:9:13:9:29 | return ...; | return |
| VarDecls.cs:7:22:7:36 | Char* c1 = ... | VarDecls.cs:7:22:7:36 | Char* c1 = ... | normal |
| VarDecls.cs:7:27:7:33 | access to parameter strings | VarDecls.cs:7:27:7:33 | access to parameter strings | normal |
+| VarDecls.cs:7:27:7:36 | (...) ... | VarDecls.cs:7:27:7:36 | (...) ... | normal |
| VarDecls.cs:7:27:7:36 | access to array element | VarDecls.cs:7:27:7:36 | access to array element | normal |
| VarDecls.cs:7:35:7:35 | 0 | VarDecls.cs:7:35:7:35 | 0 | normal |
| VarDecls.cs:7:39:7:53 | Char* c2 = ... | VarDecls.cs:7:39:7:53 | Char* c2 = ... | normal |
| VarDecls.cs:7:44:7:50 | access to parameter strings | VarDecls.cs:7:44:7:50 | access to parameter strings | normal |
+| VarDecls.cs:7:44:7:53 | (...) ... | VarDecls.cs:7:44:7:53 | (...) ... | normal |
| VarDecls.cs:7:44:7:53 | access to array element | VarDecls.cs:7:44:7:53 | access to array element | normal |
| VarDecls.cs:7:52:7:52 | 1 | VarDecls.cs:7:52:7:52 | 1 | normal |
| VarDecls.cs:8:9:10:9 | {...} | VarDecls.cs:9:13:9:29 | return ...; | return |
diff --git a/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected b/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected
index 03cbc257d26..7feee30c18b 100644
--- a/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected
+++ b/csharp/ql/test/library-tests/controlflow/graph/NodeGraph.expected
@@ -2937,11 +2937,13 @@
| VarDecls.cs:7:9:10:9 | fixed(...) { ... } | VarDecls.cs:7:27:7:33 | access to parameter strings | semmle.label | successor |
| VarDecls.cs:7:22:7:36 | Char* c1 = ... | VarDecls.cs:7:44:7:50 | access to parameter strings | semmle.label | successor |
| VarDecls.cs:7:27:7:33 | access to parameter strings | VarDecls.cs:7:35:7:35 | 0 | semmle.label | successor |
-| VarDecls.cs:7:27:7:36 | access to array element | VarDecls.cs:7:22:7:36 | Char* c1 = ... | semmle.label | successor |
+| VarDecls.cs:7:27:7:36 | (...) ... | VarDecls.cs:7:22:7:36 | Char* c1 = ... | semmle.label | successor |
+| VarDecls.cs:7:27:7:36 | access to array element | VarDecls.cs:7:27:7:36 | (...) ... | semmle.label | successor |
| VarDecls.cs:7:35:7:35 | 0 | VarDecls.cs:7:27:7:36 | access to array element | semmle.label | successor |
| VarDecls.cs:7:39:7:53 | Char* c2 = ... | VarDecls.cs:8:9:10:9 | {...} | semmle.label | successor |
| VarDecls.cs:7:44:7:50 | access to parameter strings | VarDecls.cs:7:52:7:52 | 1 | semmle.label | successor |
-| VarDecls.cs:7:44:7:53 | access to array element | VarDecls.cs:7:39:7:53 | Char* c2 = ... | semmle.label | successor |
+| VarDecls.cs:7:44:7:53 | (...) ... | VarDecls.cs:7:39:7:53 | Char* c2 = ... | semmle.label | successor |
+| VarDecls.cs:7:44:7:53 | access to array element | VarDecls.cs:7:44:7:53 | (...) ... | semmle.label | successor |
| VarDecls.cs:7:52:7:52 | 1 | VarDecls.cs:7:44:7:53 | access to array element | semmle.label | successor |
| VarDecls.cs:8:9:10:9 | {...} | VarDecls.cs:9:27:9:28 | access to local variable c1 | semmle.label | successor |
| VarDecls.cs:9:13:9:29 | return ...; | VarDecls.cs:5:18:5:19 | exit M1 | semmle.label | return |
diff --git a/csharp/ql/test/library-tests/conversion/pointer/Pointer.expected b/csharp/ql/test/library-tests/conversion/pointer/Pointer.expected
index 7db63e5ef9f..5aca5582d14 100644
--- a/csharp/ql/test/library-tests/conversion/pointer/Pointer.expected
+++ b/csharp/ql/test/library-tests/conversion/pointer/Pointer.expected
@@ -1,4 +1,4 @@
-| Pointer.cs:7:21:7:28 | Pointer.cs:7:21:7:28 | Int32* | Int32[] | access to parameter arr |
+| Pointer.cs:7:21:7:28 | Pointer.cs:7:21:7:28 | Int32* | Int32* | (...) ... |
| Pointer.cs:11:21:11:32 | Pointer.cs:11:21:11:32 | Int32* | Int32* | &... |
| Pointer.cs:13:18:13:24 | Pointer.cs:13:18:13:24 | Int32* | Int32* | access to local variable i2 |
| Pointer.cs:14:13:14:23 | Pointer.cs:14:13:14:23 | Int32* | Int32* | ... + ... |
@@ -8,4 +8,4 @@
| Pointer.cs:21:13:21:25 | Pointer.cs:21:13:21:25 | Int32 | Int32 | 1024 |
| Pointer.cs:22:15:22:32 | Pointer.cs:22:15:22:32 | Byte* | Byte* | (...) ... |
| Pointer.cs:24:13:24:29 | Pointer.cs:24:13:24:29 | String | String | "some string" |
-| Pointer.cs:25:22:25:27 | Pointer.cs:25:22:25:27 | Char* | String | access to local variable s |
+| Pointer.cs:25:22:25:27 | Pointer.cs:25:22:25:27 | Char* | Char* | (...) ... |
diff --git a/csharp/ql/test/library-tests/dataflow/signanalysis/MissingSign.expected b/csharp/ql/test/library-tests/dataflow/signanalysis/MissingSign.expected
index 72f1bdadeda..2fd751f77e0 100644
--- a/csharp/ql/test/library-tests/dataflow/signanalysis/MissingSign.expected
+++ b/csharp/ql/test/library-tests/dataflow/signanalysis/MissingSign.expected
@@ -1,4 +1 @@
| SignAnalysis.cs:428:23:428:24 | access to constant A |
-| SignAnalysis.cs:448:22:448:29 | Byte* to = ... |
-| SignAnalysis.cs:450:38:450:44 | (...) ... |
-| SignAnalysis.cs:450:43:450:44 | access to local variable to |
diff --git a/csharp/ql/test/library-tests/unsafe/PrintAst.expected b/csharp/ql/test/library-tests/unsafe/PrintAst.expected
index b4e9ce56c64..079719907c7 100644
--- a/csharp/ql/test/library-tests/unsafe/PrintAst.expected
+++ b/csharp/ql/test/library-tests/unsafe/PrintAst.expected
@@ -109,7 +109,8 @@ unsafe.cs:
# 36| 1: [LocalVariableAccess] access to local variable data
# 37| 1: [FixedStmt] fixed(...) { ... }
# 37| -1: [LocalVariableDeclAndInitExpr] Int32* p = ...
-# 37| 0: [LocalVariableAccess] access to local variable data
+# 37| 0: [CastExpr] (...) ...
+# 37| 0: [LocalVariableAccess] access to local variable data
# 37| 1: [LocalVariableAccess] access to local variable p
# 38| 0: [BlockStmt] {...}
# 44| 2: [Class] SafeClass
From 71a605b7d9b691ecee102e7226d1b4944815e726 Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Fri, 18 Sep 2020 10:11:34 +0100
Subject: [PATCH 038/411] C++: Add tests for std::pair.
---
.../dataflow/taint-tests/localTaint.expected | 161 +++++++++++++++++-
.../dataflow/taint-tests/map.cpp | 93 ++++++++++
.../library-tests/dataflow/taint-tests/stl.h | 22 ++-
.../dataflow/taint-tests/taint.expected | 2 +
.../dataflow/taint-tests/test_ir.expected | 2 +
5 files changed, 273 insertions(+), 7 deletions(-)
create mode 100644 cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
index 87e4566b2d8..b571ac46520 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
@@ -260,6 +260,7 @@
| file://:0:0:0:0 | p#0 | file://:0:0:0:0 | p#0 | |
| file://:0:0:0:0 | p#0 | file://:0:0:0:0 | p#0 | |
| file://:0:0:0:0 | p#0 | file://:0:0:0:0 | p#0 | |
+| file://:0:0:0:0 | p#0 | file://:0:0:0:0 | p#0 | |
| format.cpp:16:21:16:21 | s | format.cpp:22:22:22:22 | s | |
| format.cpp:16:31:16:31 | n | format.cpp:22:25:22:25 | n | |
| format.cpp:16:46:16:51 | format | format.cpp:22:28:22:33 | format | |
@@ -390,6 +391,144 @@
| format.cpp:158:13:158:18 | call to wcslen | format.cpp:158:13:158:26 | ... / ... | TAINT |
| format.cpp:158:13:158:26 | ... / ... | format.cpp:158:7:158:27 | ... + ... | TAINT |
| format.cpp:158:26:158:26 | 2 | format.cpp:158:13:158:26 | ... / ... | TAINT |
+| map.cpp:14:28:14:28 | call to pair | map.cpp:16:2:16:2 | a | |
+| map.cpp:14:28:14:28 | call to pair | map.cpp:17:7:17:7 | a | |
+| map.cpp:14:28:14:28 | call to pair | map.cpp:18:7:18:7 | a | |
+| map.cpp:14:28:14:28 | call to pair | map.cpp:19:7:19:7 | a | |
+| map.cpp:14:31:14:31 | call to pair | map.cpp:21:2:21:2 | b | |
+| map.cpp:14:31:14:31 | call to pair | map.cpp:22:7:22:7 | b | |
+| map.cpp:14:31:14:31 | call to pair | map.cpp:23:7:23:7 | b | |
+| map.cpp:14:31:14:31 | call to pair | map.cpp:24:7:24:7 | b | |
+| map.cpp:14:34:14:34 | call to pair | map.cpp:26:2:26:2 | c | |
+| map.cpp:14:34:14:34 | call to pair | map.cpp:27:7:27:7 | c | |
+| map.cpp:14:34:14:34 | call to pair | map.cpp:28:7:28:7 | c | |
+| map.cpp:14:34:14:34 | call to pair | map.cpp:29:7:29:7 | c | |
+| map.cpp:16:2:16:2 | a [post update] | map.cpp:17:7:17:7 | a | |
+| map.cpp:16:2:16:2 | a [post update] | map.cpp:18:7:18:7 | a | |
+| map.cpp:16:2:16:2 | a [post update] | map.cpp:19:7:19:7 | a | |
+| map.cpp:16:2:16:16 | ... = ... | map.cpp:16:4:16:8 | first [post update] | |
+| map.cpp:16:2:16:16 | ... = ... | map.cpp:17:9:17:13 | first | |
+| map.cpp:16:12:16:16 | 123 | map.cpp:16:2:16:16 | ... = ... | |
+| map.cpp:17:7:17:7 | a [post update] | map.cpp:18:7:18:7 | a | |
+| map.cpp:17:7:17:7 | a [post update] | map.cpp:19:7:19:7 | a | |
+| map.cpp:18:7:18:7 | a [post update] | map.cpp:19:7:19:7 | a | |
+| map.cpp:21:2:21:2 | b [post update] | map.cpp:22:7:22:7 | b | |
+| map.cpp:21:2:21:2 | b [post update] | map.cpp:23:7:23:7 | b | |
+| map.cpp:21:2:21:2 | b [post update] | map.cpp:24:7:24:7 | b | |
+| map.cpp:21:2:21:19 | ... = ... | map.cpp:21:4:21:8 | first [post update] | |
+| map.cpp:21:2:21:19 | ... = ... | map.cpp:22:9:22:13 | first | |
+| map.cpp:21:12:21:17 | call to source | map.cpp:21:2:21:19 | ... = ... | |
+| map.cpp:22:7:22:7 | b [post update] | map.cpp:23:7:23:7 | b | |
+| map.cpp:22:7:22:7 | b [post update] | map.cpp:24:7:24:7 | b | |
+| map.cpp:23:7:23:7 | b [post update] | map.cpp:24:7:24:7 | b | |
+| map.cpp:26:2:26:2 | c [post update] | map.cpp:27:7:27:7 | c | |
+| map.cpp:26:2:26:2 | c [post update] | map.cpp:28:7:28:7 | c | |
+| map.cpp:26:2:26:2 | c [post update] | map.cpp:29:7:29:7 | c | |
+| map.cpp:26:2:26:20 | ... = ... | map.cpp:26:4:26:9 | second [post update] | |
+| map.cpp:26:2:26:20 | ... = ... | map.cpp:28:9:28:14 | second | |
+| map.cpp:26:13:26:18 | call to source | map.cpp:26:2:26:20 | ... = ... | |
+| map.cpp:27:7:27:7 | c [post update] | map.cpp:28:7:28:7 | c | |
+| map.cpp:27:7:27:7 | c [post update] | map.cpp:29:7:29:7 | c | |
+| map.cpp:28:7:28:7 | c [post update] | map.cpp:29:7:29:7 | c | |
+| map.cpp:31:30:31:42 | call to pair | map.cpp:32:7:32:7 | d | |
+| map.cpp:31:30:31:42 | call to pair | map.cpp:33:7:33:7 | d | |
+| map.cpp:31:30:31:42 | call to pair | map.cpp:34:7:34:7 | d | |
+| map.cpp:32:7:32:7 | d [post update] | map.cpp:33:7:33:7 | d | |
+| map.cpp:32:7:32:7 | d [post update] | map.cpp:34:7:34:7 | d | |
+| map.cpp:33:7:33:7 | d [post update] | map.cpp:34:7:34:7 | d | |
+| map.cpp:36:30:36:45 | call to pair | map.cpp:37:7:37:7 | e | |
+| map.cpp:36:30:36:45 | call to pair | map.cpp:38:7:38:7 | e | |
+| map.cpp:36:30:36:45 | call to pair | map.cpp:39:7:39:7 | e | |
+| map.cpp:37:7:37:7 | e [post update] | map.cpp:38:7:38:7 | e | |
+| map.cpp:37:7:37:7 | e [post update] | map.cpp:39:7:39:7 | e | |
+| map.cpp:38:7:38:7 | e [post update] | map.cpp:39:7:39:7 | e | |
+| map.cpp:41:30:41:45 | call to pair | map.cpp:42:7:42:7 | f | |
+| map.cpp:41:30:41:45 | call to pair | map.cpp:43:7:43:7 | f | |
+| map.cpp:41:30:41:45 | call to pair | map.cpp:44:7:44:7 | f | |
+| map.cpp:41:30:41:45 | call to pair | map.cpp:46:30:46:30 | f | |
+| map.cpp:41:30:41:45 | call to pair | map.cpp:47:7:47:7 | f | |
+| map.cpp:41:30:41:45 | call to pair | map.cpp:48:7:48:7 | f | |
+| map.cpp:41:30:41:45 | call to pair | map.cpp:49:7:49:7 | f | |
+| map.cpp:41:30:41:45 | call to pair | map.cpp:52:6:52:6 | f | |
+| map.cpp:42:7:42:7 | f [post update] | map.cpp:43:7:43:7 | f | |
+| map.cpp:42:7:42:7 | f [post update] | map.cpp:44:7:44:7 | f | |
+| map.cpp:42:7:42:7 | f [post update] | map.cpp:46:30:46:30 | f | |
+| map.cpp:42:7:42:7 | f [post update] | map.cpp:47:7:47:7 | f | |
+| map.cpp:42:7:42:7 | f [post update] | map.cpp:48:7:48:7 | f | |
+| map.cpp:42:7:42:7 | f [post update] | map.cpp:49:7:49:7 | f | |
+| map.cpp:42:7:42:7 | f [post update] | map.cpp:52:6:52:6 | f | |
+| map.cpp:43:7:43:7 | f [post update] | map.cpp:44:7:44:7 | f | |
+| map.cpp:43:7:43:7 | f [post update] | map.cpp:46:30:46:30 | f | |
+| map.cpp:43:7:43:7 | f [post update] | map.cpp:47:7:47:7 | f | |
+| map.cpp:43:7:43:7 | f [post update] | map.cpp:48:7:48:7 | f | |
+| map.cpp:43:7:43:7 | f [post update] | map.cpp:49:7:49:7 | f | |
+| map.cpp:43:7:43:7 | f [post update] | map.cpp:52:6:52:6 | f | |
+| map.cpp:47:7:47:7 | f [post update] | map.cpp:48:7:48:7 | f | |
+| map.cpp:47:7:47:7 | f [post update] | map.cpp:49:7:49:7 | f | |
+| map.cpp:47:7:47:7 | f [post update] | map.cpp:52:6:52:6 | f | |
+| map.cpp:48:7:48:7 | f [post update] | map.cpp:49:7:49:7 | f | |
+| map.cpp:48:7:48:7 | f [post update] | map.cpp:52:6:52:6 | f | |
+| map.cpp:52:6:52:6 | f | map.cpp:52:2:52:6 | ... = ... | |
+| map.cpp:52:6:52:6 | f | map.cpp:53:7:53:7 | h | |
+| map.cpp:52:6:52:6 | f | map.cpp:54:7:54:7 | h | |
+| map.cpp:52:6:52:6 | f | map.cpp:55:7:55:7 | h | |
+| map.cpp:53:7:53:7 | h [post update] | map.cpp:54:7:54:7 | h | |
+| map.cpp:53:7:53:7 | h [post update] | map.cpp:55:7:55:7 | h | |
+| map.cpp:54:7:54:7 | h [post update] | map.cpp:55:7:55:7 | h | |
+| map.cpp:57:30:57:42 | call to pair | map.cpp:61:3:61:3 | i | |
+| map.cpp:57:30:57:42 | call to pair | map.cpp:63:7:63:7 | i | |
+| map.cpp:57:30:57:42 | call to pair | map.cpp:64:7:64:7 | i | |
+| map.cpp:57:30:57:42 | call to pair | map.cpp:65:7:65:7 | i | |
+| map.cpp:58:30:58:45 | call to pair | map.cpp:61:10:61:10 | j | |
+| map.cpp:58:30:58:45 | call to pair | map.cpp:66:7:66:7 | j | |
+| map.cpp:58:30:58:45 | call to pair | map.cpp:67:7:67:7 | j | |
+| map.cpp:58:30:58:45 | call to pair | map.cpp:68:7:68:7 | j | |
+| map.cpp:59:30:59:45 | call to pair | map.cpp:62:2:62:2 | k | |
+| map.cpp:59:30:59:45 | call to pair | map.cpp:69:7:69:7 | k | |
+| map.cpp:59:30:59:45 | call to pair | map.cpp:70:7:70:7 | k | |
+| map.cpp:59:30:59:45 | call to pair | map.cpp:71:7:71:7 | k | |
+| map.cpp:60:30:60:42 | call to pair | map.cpp:62:9:62:9 | l | |
+| map.cpp:60:30:60:42 | call to pair | map.cpp:72:7:72:7 | l | |
+| map.cpp:60:30:60:42 | call to pair | map.cpp:73:7:73:7 | l | |
+| map.cpp:60:30:60:42 | call to pair | map.cpp:74:7:74:7 | l | |
+| map.cpp:61:3:61:3 | ref arg i | map.cpp:63:7:63:7 | i | |
+| map.cpp:61:3:61:3 | ref arg i | map.cpp:64:7:64:7 | i | |
+| map.cpp:61:3:61:3 | ref arg i | map.cpp:65:7:65:7 | i | |
+| map.cpp:61:10:61:10 | ref arg j | map.cpp:66:7:66:7 | j | |
+| map.cpp:61:10:61:10 | ref arg j | map.cpp:67:7:67:7 | j | |
+| map.cpp:61:10:61:10 | ref arg j | map.cpp:68:7:68:7 | j | |
+| map.cpp:62:2:62:2 | ref arg k | map.cpp:69:7:69:7 | k | |
+| map.cpp:62:2:62:2 | ref arg k | map.cpp:70:7:70:7 | k | |
+| map.cpp:62:2:62:2 | ref arg k | map.cpp:71:7:71:7 | k | |
+| map.cpp:62:9:62:9 | ref arg l | map.cpp:72:7:72:7 | l | |
+| map.cpp:62:9:62:9 | ref arg l | map.cpp:73:7:73:7 | l | |
+| map.cpp:62:9:62:9 | ref arg l | map.cpp:74:7:74:7 | l | |
+| map.cpp:63:7:63:7 | i [post update] | map.cpp:64:7:64:7 | i | |
+| map.cpp:63:7:63:7 | i [post update] | map.cpp:65:7:65:7 | i | |
+| map.cpp:64:7:64:7 | i [post update] | map.cpp:65:7:65:7 | i | |
+| map.cpp:66:7:66:7 | j [post update] | map.cpp:67:7:67:7 | j | |
+| map.cpp:66:7:66:7 | j [post update] | map.cpp:68:7:68:7 | j | |
+| map.cpp:67:7:67:7 | j [post update] | map.cpp:68:7:68:7 | j | |
+| map.cpp:69:7:69:7 | k [post update] | map.cpp:70:7:70:7 | k | |
+| map.cpp:69:7:69:7 | k [post update] | map.cpp:71:7:71:7 | k | |
+| map.cpp:70:7:70:7 | k [post update] | map.cpp:71:7:71:7 | k | |
+| map.cpp:72:7:72:7 | l [post update] | map.cpp:73:7:73:7 | l | |
+| map.cpp:72:7:72:7 | l [post update] | map.cpp:74:7:74:7 | l | |
+| map.cpp:73:7:73:7 | l [post update] | map.cpp:74:7:74:7 | l | |
+| map.cpp:76:7:76:15 | call to make_pair | map.cpp:76:7:76:29 | call to pair | TAINT |
+| map.cpp:79:7:79:15 | call to make_pair | map.cpp:79:7:79:32 | call to pair | TAINT |
+| map.cpp:82:7:82:15 | call to make_pair | map.cpp:82:7:82:32 | call to pair | TAINT |
+| map.cpp:87:6:87:14 | call to make_pair | map.cpp:87:6:87:49 | call to pair | TAINT |
+| map.cpp:87:6:87:49 | call to pair | map.cpp:87:2:87:49 | ... = ... | |
+| map.cpp:87:6:87:49 | call to pair | map.cpp:88:7:88:7 | m | |
+| map.cpp:87:6:87:49 | call to pair | map.cpp:89:7:89:7 | m | |
+| map.cpp:87:6:87:49 | call to pair | map.cpp:90:7:90:7 | m | |
+| map.cpp:87:6:87:49 | call to pair | map.cpp:91:7:91:7 | m | |
+| map.cpp:87:6:87:49 | call to pair | map.cpp:92:7:92:7 | m | |
+| map.cpp:88:7:88:7 | m | map.cpp:88:7:88:7 | call to pair | TAINT |
+| map.cpp:90:7:90:7 | m [post update] | map.cpp:91:7:91:7 | m | |
+| map.cpp:90:7:90:7 | m [post update] | map.cpp:92:7:92:7 | m | |
+| map.cpp:91:7:91:7 | m [post update] | map.cpp:92:7:92:7 | m | |
| movableclass.cpp:8:2:8:15 | this | movableclass.cpp:8:27:8:31 | constructor init of field v [pre-this] | |
| movableclass.cpp:8:21:8:22 | _v | movableclass.cpp:8:29:8:30 | _v | |
| movableclass.cpp:8:29:8:30 | _v | movableclass.cpp:8:27:8:31 | constructor init of field v | TAINT |
@@ -514,12 +653,22 @@
| standalone_iterators.cpp:51:37:51:43 | source1 | standalone_iterators.cpp:53:12:53:18 | source1 | |
| standalone_iterators.cpp:51:37:51:43 | source1 | standalone_iterators.cpp:54:14:54:20 | source1 | |
| standalone_iterators.cpp:53:12:53:18 | ref arg source1 | standalone_iterators.cpp:54:14:54:20 | source1 | |
-| stl.h:216:30:216:40 | call to allocator | stl.h:216:21:216:41 | noexcept(...) | TAINT |
-| stl.h:216:30:216:40 | call to allocator | stl.h:216:21:216:41 | noexcept(...) | TAINT |
-| stl.h:216:30:216:40 | call to allocator | stl.h:216:21:216:41 | noexcept(...) | TAINT |
-| stl.h:216:30:216:40 | call to allocator | stl.h:216:21:216:41 | noexcept(...) | TAINT |
-| stl.h:216:30:216:40 | call to allocator | stl.h:216:21:216:41 | noexcept(...) | TAINT |
-| stl.h:216:53:216:63 | 0 | stl.h:216:46:216:64 | (no string representation) | TAINT |
+| stl.h:221:30:221:40 | call to allocator | stl.h:221:21:221:41 | noexcept(...) | TAINT |
+| stl.h:221:30:221:40 | call to allocator | stl.h:221:21:221:41 | noexcept(...) | TAINT |
+| stl.h:221:30:221:40 | call to allocator | stl.h:221:21:221:41 | noexcept(...) | TAINT |
+| stl.h:221:30:221:40 | call to allocator | stl.h:221:21:221:41 | noexcept(...) | TAINT |
+| stl.h:221:30:221:40 | call to allocator | stl.h:221:21:221:41 | noexcept(...) | TAINT |
+| stl.h:221:53:221:63 | 0 | stl.h:221:46:221:64 | (no string representation) | TAINT |
+| stl.h:314:9:314:9 | Unknown literal | stl.h:314:9:314:9 | constructor init of field first | TAINT |
+| stl.h:314:9:314:9 | Unknown literal | stl.h:314:9:314:9 | constructor init of field first | TAINT |
+| stl.h:314:9:314:9 | Unknown literal | stl.h:314:9:314:9 | constructor init of field second | TAINT |
+| stl.h:314:9:314:9 | Unknown literal | stl.h:314:9:314:9 | constructor init of field second | TAINT |
+| stl.h:314:9:314:9 | constructor init of field first [post-this] | stl.h:314:9:314:9 | constructor init of field second [pre-this] | |
+| stl.h:314:9:314:9 | constructor init of field first [post-this] | stl.h:314:9:314:9 | constructor init of field second [pre-this] | |
+| stl.h:314:9:314:9 | constructor init of field first [pre-this] | stl.h:314:9:314:9 | constructor init of field second [pre-this] | |
+| stl.h:314:9:314:9 | constructor init of field first [pre-this] | stl.h:314:9:314:9 | constructor init of field second [pre-this] | |
+| stl.h:314:9:314:9 | this | stl.h:314:9:314:9 | constructor init of field first [pre-this] | |
+| stl.h:314:9:314:9 | this | stl.h:314:9:314:9 | constructor init of field first [pre-this] | |
| string.cpp:24:12:24:17 | call to source | string.cpp:28:7:28:7 | a | |
| string.cpp:25:16:25:20 | 123 | string.cpp:25:16:25:21 | call to basic_string | TAINT |
| string.cpp:25:16:25:21 | call to basic_string | string.cpp:29:7:29:7 | b | |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp
new file mode 100644
index 00000000000..0da7369cda2
--- /dev/null
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp
@@ -0,0 +1,93 @@
+
+#include "stl.h"
+
+using namespace std;
+
+char *source();
+
+void sink(char *);
+void sink(const char *);
+void sink(std::pair);
+
+void test_pair()
+{
+ std::pair a, b, c;
+
+ a.first = "123";
+ sink(a.first);
+ sink(a.second);
+ sink(a);
+
+ b.first = source();
+ sink(b.first); // tainted
+ sink(b.second);
+ sink(b); // tainted [NOT DETECTED]
+
+ c.second = source();
+ sink(c.first);
+ sink(c.second); // tainted
+ sink(c); // tainted [NOT DETECTED]
+
+ std::pair d("123", "456");
+ sink(d.first);
+ sink(d.second);
+ sink(d);
+
+ std::pair e(source(), "456");
+ sink(e.first); // tainted [NOT DETECTED]
+ sink(e.second);
+ sink(e); // tainted [NOT DETECTED]
+
+ std::pair f("123", source());
+ sink(f.first);
+ sink(f.second); // tainted [NOT DETECTED]
+ sink(f); // tainted [NOT DETECTED]
+
+ std::pair g(f);
+ sink(f.first);
+ sink(f.second); // tainted [NOT DETECTED]
+ sink(f); // tainted [NOT DETECTED]
+
+ std::pair h;
+ h = f;
+ sink(h.first);
+ sink(h.second); // tainted [NOT DETECTED]
+ sink(h); // tainted [NOT DETECTED]
+
+ std::pair i("123", "456");
+ std::pair j("123", source());
+ std::pair k("123", source());
+ std::pair l("123", "456");
+ i.swap(j);
+ k.swap(l);
+ sink(i.first);
+ sink(i.second); // tainted [NOT DETECTED]
+ sink(i); // tainted [NOT DETECTED]
+ sink(j.first);
+ sink(j.second);
+ sink(j);
+ sink(k.first);
+ sink(k.second);
+ sink(k);
+ sink(l.first);
+ sink(l.second); // tainted [NOT DETECTED]
+ sink(l); // tainted [NOT DETECTED]
+
+ sink(make_pair("123", "456"));
+ sink(make_pair("123", "456").first);
+ sink(make_pair("123", "456").second);
+ sink(make_pair(source(), "456")); // tainted [NOT DETECTED]
+ sink(make_pair(source(), "456").first); // tainted [NOT DETECTED]
+ sink(make_pair(source(), "456").second);
+ sink(make_pair("123", source())); // tainted [NOT DETECTED]
+ sink(make_pair("123", source()).first);
+ sink(make_pair("123", source()).second); // tainted [NOT DETECTED]
+
+ std::pair, char *> m;
+ m = make_pair(make_pair("123", source()), "789");
+ sink(m); // tainted [NOT DETECTED]
+ sink(m.first); // tainted [NOT DETECTED]
+ sink(m.first.first);
+ sink(m.first.second); // tainted [NOT DETECTED]
+ sink(m.second);
+}
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h b/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h
index a2ac49148fb..c6b2150510f 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h
@@ -305,4 +305,24 @@ namespace std {
template unique_ptr make_unique(Args&&...);
template shared_ptr make_shared(Args&&...);
-}
\ No newline at end of file
+}
+
+// --- pair ---
+
+namespace std {
+ template
+ struct pair {
+ typedef T1 first_type;
+ typedef T2 second_type;
+
+ T1 first;
+ T2 second;
+ pair();
+ pair(const T1& x, const T2& y);
+ template pair(const pair &p);
+
+ void swap(pair& p) /*noexcept(...)*/;
+ };
+
+ template pair make_pair(T1, T2);
+}
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
index 69d57d3bab0..7032d498666 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected
@@ -33,6 +33,8 @@
| format.cpp:115:8:115:13 | buffer | format.cpp:114:37:114:50 | call to source |
| format.cpp:157:7:157:22 | access to array | format.cpp:147:12:147:25 | call to source |
| format.cpp:158:7:158:27 | ... + ... | format.cpp:148:16:148:30 | call to source |
+| map.cpp:22:9:22:13 | first | map.cpp:21:12:21:17 | call to source |
+| map.cpp:28:9:28:14 | second | map.cpp:26:13:26:18 | call to source |
| movableclass.cpp:44:8:44:9 | s1 | movableclass.cpp:39:21:39:26 | call to source |
| movableclass.cpp:45:8:45:9 | s2 | movableclass.cpp:40:23:40:28 | call to source |
| movableclass.cpp:46:8:46:9 | s3 | movableclass.cpp:42:8:42:13 | call to source |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/test_ir.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/test_ir.expected
index 07aa8b78d1d..ce708a75747 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/test_ir.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/test_ir.expected
@@ -42,6 +42,8 @@
| format.cpp:115:8:115:13 | Argument 0 indirection | format.cpp:114:37:114:50 | call to source |
| format.cpp:157:7:157:22 | access to array | format.cpp:147:12:147:25 | call to source |
| format.cpp:158:7:158:27 | ... + ... | format.cpp:148:16:148:30 | call to source |
+| map.cpp:22:9:22:13 | first | map.cpp:21:12:21:17 | call to source |
+| map.cpp:28:9:28:14 | second | map.cpp:26:13:26:18 | call to source |
| movableclass.cpp:44:8:44:9 | s1 | movableclass.cpp:39:21:39:26 | call to source |
| movableclass.cpp:45:8:45:9 | s2 | movableclass.cpp:40:23:40:28 | call to source |
| movableclass.cpp:46:8:46:9 | s3 | movableclass.cpp:42:8:42:13 | call to source |
From 774dcc7c5292696d69e3b5a1726b7aa164028450 Mon Sep 17 00:00:00 2001
From: Robert Marsh
Date: Wed, 23 Sep 2020 15:29:37 -0700
Subject: [PATCH 039/411] C++: New model class for iterator op* and op[]
---
.../dataflow/internal/TaintTrackingUtil.qll | 10 ++--------
.../cpp/models/implementations/Iterator.qll | 14 +++++++++++---
.../code/cpp/models/interfaces/Iterator.qll | 19 +++++++++++++++++++
3 files changed, 32 insertions(+), 11 deletions(-)
create mode 100644 cpp/ql/src/semmle/code/cpp/models/interfaces/Iterator.qll
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll
index 17cb9b88104..1ef340c4f21 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/TaintTrackingUtil.qll
@@ -10,7 +10,7 @@
private import semmle.code.cpp.models.interfaces.DataFlow
private import semmle.code.cpp.models.interfaces.Taint
-private import semmle.code.cpp.models.implementations.Iterator
+private import semmle.code.cpp.models.interfaces.Iterator
private module DataFlow {
import semmle.code.cpp.dataflow.internal.DataFlowUtil
@@ -264,10 +264,4 @@ private predicate exprToPartialDefinitionStep(Expr exprIn, Expr exprOut) {
)
}
-private predicate iteratorDereference(Call c) {
- c.getTarget() instanceof IteratorArrayMemberOperator
- or
- c.getTarget() instanceof IteratorPointerDereferenceMemberOperator
- or
- c.getTarget() instanceof IteratorPointerDereferenceOperator
-}
+private predicate iteratorDereference(Call c) { c.getTarget() instanceof IteratorReferenceFunction }
diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll
index 93a04d5ef90..c1b8e24e7db 100644
--- a/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll
+++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Iterator.qll
@@ -8,6 +8,7 @@
import cpp
import semmle.code.cpp.models.interfaces.Taint
import semmle.code.cpp.models.interfaces.DataFlow
+import semmle.code.cpp.models.interfaces.Iterator
/**
* An instantiation of the `std::iterator_traits` template.
@@ -80,7 +81,7 @@ private FunctionInput getIteratorArgumentInput(Operator op, int index) {
/**
* A non-member prefix `operator*` function for an iterator type.
*/
-class IteratorPointerDereferenceOperator extends Operator, TaintFunction {
+class IteratorPointerDereferenceOperator extends Operator, TaintFunction, IteratorReferenceFunction {
FunctionInput iteratorInput;
IteratorPointerDereferenceOperator() {
@@ -92,6 +93,8 @@ class IteratorPointerDereferenceOperator extends Operator, TaintFunction {
input = iteratorInput and
output.isReturnValue()
}
+
+ override FunctionInput getIteratorInput() { result = iteratorInput }
}
/**
@@ -169,12 +172,15 @@ class IteratorAssignArithmeticOperator extends Operator, DataFlowFunction, Taint
/**
* A prefix `operator*` member function for an iterator type.
*/
-class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunction {
+class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunction,
+ IteratorReferenceFunction {
IteratorPointerDereferenceMemberOperator() {
this.hasName("operator*") and
this.getDeclaringType() instanceof Iterator
}
+ override FunctionInput getIteratorInput() { result.isQualifierObject() }
+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and
output.isReturnValue()
@@ -260,7 +266,7 @@ class IteratorAssignArithmeticMemberOperator extends MemberFunction, DataFlowFun
/**
* An `operator[]` member function of an iterator class.
*/
-class IteratorArrayMemberOperator extends MemberFunction, TaintFunction {
+class IteratorArrayMemberOperator extends MemberFunction, TaintFunction, IteratorReferenceFunction {
IteratorArrayMemberOperator() {
this.hasName("operator[]") and
this.getDeclaringType() instanceof Iterator
@@ -270,6 +276,8 @@ class IteratorArrayMemberOperator extends MemberFunction, TaintFunction {
input.isQualifierObject() and
output.isReturnValue()
}
+
+ override FunctionInput getIteratorInput() { result.isQualifierObject() }
}
/**
diff --git a/cpp/ql/src/semmle/code/cpp/models/interfaces/Iterator.qll b/cpp/ql/src/semmle/code/cpp/models/interfaces/Iterator.qll
new file mode 100644
index 00000000000..ea9ce04e530
--- /dev/null
+++ b/cpp/ql/src/semmle/code/cpp/models/interfaces/Iterator.qll
@@ -0,0 +1,19 @@
+/**
+ * Provides an abstract class for accurate modeling of flow through output
+ * iterators. To use this QL library, create a QL class extending
+ * `IteratorReferenceFunction` with a characteristic predicate that selects the
+ * function or set of functions you are modeling. Within that class, override
+ * the predicates provided by `AliasFunction` to match the flow within that
+ * function.
+ */
+
+import cpp
+import semmle.code.cpp.models.Models
+
+/**
+ * A function which takes an iterator argument and returns a reference that
+ * can be used to write to the iterator's underlying collection.
+ */
+abstract class IteratorReferenceFunction extends Function {
+ abstract FunctionInput getIteratorInput();
+}
From 89332ca3037ac3b8c0c664cfe0ad90f9e44a421c Mon Sep 17 00:00:00 2001
From: Robert Marsh
Date: Wed, 23 Sep 2020 15:29:51 -0700
Subject: [PATCH 040/411] C++: autoformat
---
cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll | 1 -
1 file changed, 1 deletion(-)
diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll
index e737f8b2d94..4562eb3fd19 100644
--- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll
+++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll
@@ -3,7 +3,6 @@ private import DataFlowUtil
private import DataFlowDispatch
private import FlowVar
-
/** Gets the instance argument of a non-static call. */
private Node getInstanceArgument(Call call) {
result.asExpr() = call.getQualifier()
From 45651cf1236a6aa2c4aeb723c7b49a664d63baa4 Mon Sep 17 00:00:00 2001
From: Joe
Date: Wed, 23 Sep 2020 16:58:35 +0100
Subject: [PATCH 041/411] Java: PrintAst: Add a synthetic node for the
initialisers of for statements
---
java/ql/src/semmle/code/java/PrintAst.qll | 31 ++++++++++++++++++++++-
1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/java/ql/src/semmle/code/java/PrintAst.qll b/java/ql/src/semmle/code/java/PrintAst.qll
index a3f4807661d..b26db2704ee 100644
--- a/java/ql/src/semmle/code/java/PrintAst.qll
+++ b/java/ql/src/semmle/code/java/PrintAst.qll
@@ -113,6 +113,7 @@ private predicate locationSortKeys(Element ast, string file, int line, int colum
*/
private newtype TPrintAstNode =
TElementNode(Element el) { shouldPrint(el, _) } or
+ TForInitNode(ForStmt fs) { shouldPrint(fs, _) and exists(fs.getAnInit()) } or
TAnnotationsNode(Annotatable ann) {
shouldPrint(ann, _) and ann.hasAnnotation() and not partOfAnnotation(ann)
} or
@@ -248,7 +249,11 @@ final class ExprStmtNode extends ElementNode {
override PrintAstNode getChild(int childIndex) {
exists(Element el | result.(ElementNode).getElement() = el |
el.(Expr).isNthChildOf(element, childIndex) and
- not partOfAnnotation(element)
+ not partOfAnnotation(element) and
+ not (
+ element instanceof ForStmt and
+ childIndex <= 0
+ )
or
el.(Stmt).isNthChildOf(element, childIndex)
or
@@ -271,6 +276,9 @@ final class ExprStmtNode extends ElementNode {
childIndex = -2 and
el = element.(LocalVariableDeclExpr).getVariable()
)
+ or
+ childIndex = 0 and
+ result.(ForInitNode).getForStmt() = element
}
}
@@ -432,6 +440,27 @@ final class TypeVariableNode extends ElementNode {
}
}
+/**
+ * A node representing the initializers of a `ForStmt`.
+ */
+final class ForInitNode extends PrintAstNode, TForInitNode {
+ ForStmt fs;
+
+ ForInitNode() { this = TForInitNode(fs) }
+
+ override string toString() { result = "(For Initializers) "}
+
+ override ElementNode getChild(int childIndex) {
+ childIndex >= 0 and
+ result.getElement().(Expr).isNthChildOf(fs, -childIndex)
+ }
+
+ /**
+ * Gets the underlying `ForStmt`.
+ */
+ ForStmt getForStmt() {result = fs}
+}
+
/**
* A node representing the annotations of an `Annotatable`.
* Only rendered if there is at least one annotation.
From 1f9960762425b676b64a9a150ded4015a6ff9606 Mon Sep 17 00:00:00 2001
From: Joe
Date: Wed, 23 Sep 2020 17:11:20 +0100
Subject: [PATCH 042/411] Java: PrintAst: Improve test
---
java/ql/test/library-tests/printAst/A.java | 6 ++
.../library-tests/printAst/PrintAst.expected | 77 +++++++++++++------
2 files changed, 61 insertions(+), 22 deletions(-)
diff --git a/java/ql/test/library-tests/printAst/A.java b/java/ql/test/library-tests/printAst/A.java
index b0eeb9276a1..c3176cc14f3 100644
--- a/java/ql/test/library-tests/printAst/A.java
+++ b/java/ql/test/library-tests/printAst/A.java
@@ -18,6 +18,12 @@ class A {
/** Does something */
@Deprecated
static int doSomething(@SuppressWarnings("all") String text) {
+ int i=0, j=1;
+
+ for(i=0, j=1; i<3; i++) {}
+
+ for(int m=0, n=1; m<3; m++) {}
+
return 0;
}
diff --git a/java/ql/test/library-tests/printAst/PrintAst.expected b/java/ql/test/library-tests/printAst/PrintAst.expected
index b23ed34ea82..c8f22de6950 100644
--- a/java/ql/test/library-tests/printAst/PrintAst.expected
+++ b/java/ql/test/library-tests/printAst/PrintAst.expected
@@ -31,26 +31,59 @@ A.java:
# 20| 1: [StringLiteral] "all"
# 20| 0: [TypeAccess] String
# 20| 5: [BlockStmt] stmt
-# 21| 0: [ReturnStmt] stmt
-# 21| 0: [IntegerLiteral] 0
-# 24| 6: [FieldDeclaration] int counter, ...;
-# 24| -1: [TypeAccess] int
-# 24| 0: [IntegerLiteral] 1
-# 26| 7: [BlockStmt] stmt
-# 27| 0: [ExprStmt] stmt
-# 27| 0: [AssignExpr] ...=...
-# 27| 0: [VarAccess] counter
-# 27| 1: [MethodAccess] doSomething(...)
-# 27| 0: [StringLiteral] "hi"
-# 36| 8: [Method] doSomethingElse
+# 21| 0: [LocalVariableDeclStmt] stmt
+# 21| 0: [TypeAccess] int
+# 21| 1: [LocalVariableDeclExpr] i
+# 21| 0: [IntegerLiteral] 0
+# 21| 2: [LocalVariableDeclExpr] j
+# 21| 0: [IntegerLiteral] 1
+# 23| 1: [ForStmt] stmt
+#-----| 0: (For Initializers)
+# 23| 1: [AssignExpr] ...=...
+# 23| 0: [VarAccess] i
+# 23| 1: [IntegerLiteral] 0
+# 23| 2: [AssignExpr] ...=...
+# 23| 0: [VarAccess] j
+# 23| 1: [IntegerLiteral] 1
+# 23| 1: [LTExpr] ... < ...
+# 23| 0: [VarAccess] i
+# 23| 1: [IntegerLiteral] 3
+# 23| 2: [BlockStmt] stmt
+# 23| 3: [PostIncExpr] ...++
+# 23| 0: [VarAccess] i
+# 25| 2: [ForStmt] stmt
+#-----| 0: (For Initializers)
+# 25| 0: [TypeAccess] int
+# 25| 1: [LocalVariableDeclExpr] m
+# 25| 0: [IntegerLiteral] 0
+# 25| 2: [LocalVariableDeclExpr] n
+# 25| 0: [IntegerLiteral] 1
+# 25| 1: [LTExpr] ... < ...
+# 25| 0: [VarAccess] m
+# 25| 1: [IntegerLiteral] 3
+# 25| 2: [BlockStmt] stmt
+# 25| 3: [PostIncExpr] ...++
+# 25| 0: [VarAccess] m
+# 27| 3: [ReturnStmt] stmt
+# 27| 0: [IntegerLiteral] 0
+# 30| 6: [FieldDeclaration] int counter, ...;
+# 30| -1: [TypeAccess] int
+# 30| 0: [IntegerLiteral] 1
+# 32| 7: [BlockStmt] stmt
+# 33| 0: [ExprStmt] stmt
+# 33| 0: [AssignExpr] ...=...
+# 33| 0: [VarAccess] counter
+# 33| 1: [MethodAccess] doSomething(...)
+# 33| 0: [StringLiteral] "hi"
+# 42| 8: [Method] doSomethingElse
#-----| 1: (Annotations)
-# 30| 1: [Annotation] Ann1
-# 31| 1: [StringLiteral] "a"
-# 32| 2: [ArrayInit] {...}
-# 33| 1: [Annotation] Ann2
-# 34| 2: [Annotation] Ann2
-# 34| 1: [IntegerLiteral] 7
-# 36| 3: [TypeAccess] String
-# 36| 5: [BlockStmt] stmt
-# 36| 0: [ReturnStmt] stmt
-# 36| 0: [StringLiteral] "c"
+# 36| 1: [Annotation] Ann1
+# 37| 1: [StringLiteral] "a"
+# 38| 2: [ArrayInit] {...}
+# 39| 1: [Annotation] Ann2
+# 40| 2: [Annotation] Ann2
+# 40| 1: [IntegerLiteral] 7
+# 42| 3: [TypeAccess] String
+# 42| 5: [BlockStmt] stmt
+# 42| 0: [ReturnStmt] stmt
+# 42| 0: [StringLiteral] "c"
From 3e960c1e0bdac2062fbe047152acc9d73f75f30c Mon Sep 17 00:00:00 2001
From: Joe
Date: Wed, 23 Sep 2020 17:53:30 +0100
Subject: [PATCH 043/411] Java: PrintAst: Refactor exceptions to the usual AST
of expressions and statements using dispatch
---
java/ql/src/semmle/code/java/PrintAst.qll | 132 +++++++++++++++-------
1 file changed, 90 insertions(+), 42 deletions(-)
diff --git a/java/ql/src/semmle/code/java/PrintAst.qll b/java/ql/src/semmle/code/java/PrintAst.qll
index b26db2704ee..08b108c8e47 100644
--- a/java/ql/src/semmle/code/java/PrintAst.qll
+++ b/java/ql/src/semmle/code/java/PrintAst.qll
@@ -222,6 +222,24 @@ abstract class ElementNode extends PrintAstNode, TElementNode {
final Element getElement() { result = element }
}
+/**
+ * A node representing an `Expr` or a `Stmt`.
+ */
+class ExprStmtNode extends ElementNode {
+ ExprStmtNode() { element instanceof ExprOrStmt }
+
+ override PrintAstNode getChild(int childIndex) {
+ exists(Element el | result.(ElementNode).getElement() = el |
+ el.(Expr).isNthChildOf(element, childIndex)
+ or
+ el.(Stmt).isNthChildOf(element, childIndex)
+ )
+ }
+}
+
+/**
+ * Holds if the given expression is part of an annotation.
+ */
private predicate partOfAnnotation(Expr e) {
e instanceof Annotation
or
@@ -229,53 +247,83 @@ private predicate partOfAnnotation(Expr e) {
partOfAnnotation(e.getParent())
}
-private Expr getAnAnnotationChild(Expr e) {
- partOfAnnotation(e) and
- (
- result = e.(Annotation).getValue(_)
- or
- result = e.(ArrayInit).getAnInit()
- or
- result = e.(ArrayInit).(Annotatable).getAnAnnotation()
- )
+/**
+ * A node representing an `Expr` that is part of an annotation.
+ */
+final class AnnotationPartNode extends ExprStmtNode {
+ AnnotationPartNode() { partOfAnnotation(element) }
+
+ override ElementNode getChild(int childIndex) {
+ result.getElement() =
+ rank[childIndex](Element ch, string file, int line, int column |
+ ch = getAnAnnotationChild() and locationSortKeys(ch, file, line, column)
+ |
+ ch order by file, line, column
+ )
+ }
+
+ private Expr getAnAnnotationChild() {
+ (
+ result = element.(Annotation).getValue(_)
+ or
+ result = element.(ArrayInit).getAnInit()
+ or
+ result = element.(ArrayInit).(Annotatable).getAnAnnotation()
+ )
+ }
}
/**
- * An node representing an `Expr` or a `Stmt`.
+ * A node representing a `LocalVariableDeclExpr`.
*/
-final class ExprStmtNode extends ElementNode {
- ExprStmtNode() { element instanceof ExprOrStmt }
+final class LocalVarDeclExprNode extends ExprStmtNode {
+ LocalVarDeclExprNode() { element instanceof LocalVariableDeclExpr }
override PrintAstNode getChild(int childIndex) {
- exists(Element el | result.(ElementNode).getElement() = el |
- el.(Expr).isNthChildOf(element, childIndex) and
- not partOfAnnotation(element) and
- not (
- element instanceof ForStmt and
- childIndex <= 0
- )
- or
- el.(Stmt).isNthChildOf(element, childIndex)
- or
- childIndex = -4 and
- el = element.(ClassInstanceExpr).getAnonymousClass()
- or
- childIndex = 0 and
- el = element.(LocalClassDeclStmt).getLocalClass()
- or
- partOfAnnotation(element) and
- el =
- rank[childIndex](Element ch, string file, int line, int column |
- ch = getAnAnnotationChild(element) and locationSortKeys(ch, file, line, column)
- |
- ch order by file, line, column
- )
- )
+ result = super.getChild(childIndex)
or
- exists(Element el | result.(AnnotationsNode).getAnnotated() = el |
- childIndex = -2 and
- el = element.(LocalVariableDeclExpr).getVariable()
- )
+ childIndex = -2 and
+ result.(AnnotationsNode).getAnnotated() = element.(LocalVariableDeclExpr).getVariable()
+ }
+}
+
+/**
+ * A node representing a `ClassInstanceExpr`.
+ */
+final class ClassInstanceExprNode extends ExprStmtNode {
+ ClassInstanceExprNode() { element instanceof ClassInstanceExpr }
+
+ override ElementNode getChild(int childIndex) {
+ result = super.getChild(childIndex)
+ or
+ childIndex = -4 and
+ result.getElement() = element.(ClassInstanceExpr).getAnonymousClass()
+ }
+}
+
+/**
+ * A node representing a `LocalClassDeclStmt`.
+ */
+final class LocalClassDeclStmtNode extends ExprStmtNode {
+ LocalClassDeclStmtNode() { element instanceof LocalClassDeclStmt }
+
+ override ElementNode getChild(int childIndex) {
+ result = super.getChild(childIndex)
+ or
+ childIndex = 0 and
+ result.getElement() = element.(LocalClassDeclStmt).getLocalClass()
+ }
+}
+
+/**
+ * A node representing a `ForStmt`.
+ */
+final class ForStmtNode extends ExprStmtNode {
+ ForStmtNode() { element instanceof ForStmt }
+
+ override PrintAstNode getChild(int childIndex) {
+ childIndex >= 1 and
+ result = super.getChild(childIndex)
or
childIndex = 0 and
result.(ForInitNode).getForStmt() = element
@@ -448,7 +496,7 @@ final class ForInitNode extends PrintAstNode, TForInitNode {
ForInitNode() { this = TForInitNode(fs) }
- override string toString() { result = "(For Initializers) "}
+ override string toString() { result = "(For Initializers) " }
override ElementNode getChild(int childIndex) {
childIndex >= 0 and
@@ -458,7 +506,7 @@ final class ForInitNode extends PrintAstNode, TForInitNode {
/**
* Gets the underlying `ForStmt`.
*/
- ForStmt getForStmt() {result = fs}
+ ForStmt getForStmt() { result = fs }
}
/**
From 9c8a4682377ea2a65985552531754e27ebfda030 Mon Sep 17 00:00:00 2001
From: Joe
Date: Thu, 24 Sep 2020 12:12:28 +0100
Subject: [PATCH 044/411] Java: PrintAst: Add synthetic nodes for other
declarations
---
java/ql/src/semmle/code/java/PrintAst.qll | 67 +++++++++++++++++++
.../java7/MultiCatch/PrintAst.expected | 23 ++++---
2 files changed, 80 insertions(+), 10 deletions(-)
diff --git a/java/ql/src/semmle/code/java/PrintAst.qll b/java/ql/src/semmle/code/java/PrintAst.qll
index 08b108c8e47..ca1daf6c2a4 100644
--- a/java/ql/src/semmle/code/java/PrintAst.qll
+++ b/java/ql/src/semmle/code/java/PrintAst.qll
@@ -114,6 +114,9 @@ private predicate locationSortKeys(Element ast, string file, int line, int colum
private newtype TPrintAstNode =
TElementNode(Element el) { shouldPrint(el, _) } or
TForInitNode(ForStmt fs) { shouldPrint(fs, _) and exists(fs.getAnInit()) } or
+ TLocalVarDeclNode(LocalVariableDeclExpr lvde) {
+ shouldPrint(lvde, _) and lvde.getParent() instanceof LocalVarDeclParent
+ } or
TAnnotationsNode(Annotatable ann) {
shouldPrint(ann, _) and ann.hasAnnotation() and not partOfAnnotation(ann)
} or
@@ -330,6 +333,46 @@ final class ForStmtNode extends ExprStmtNode {
}
}
+/**
+ * An element that can be the parent of a `LocalVariableDeclExpr` for which we want
+ * to use a synthetic node to hold the variable declaration and its `TypeAccess`.
+ */
+private class LocalVarDeclParent extends ExprOrStmt {
+ LocalVarDeclParent() {
+ this instanceof EnhancedForStmt or
+ this instanceof CatchClause or
+ this.(InstanceOfExpr).isPattern()
+ }
+
+ /** Gets the variable declaration that this element contains */
+ LocalVariableDeclExpr getVariable() { result.getParent() = this }
+
+ /** Gets the type access of the variable */
+ Expr getTypeAccess() { result = getVariable().getTypeAccess() }
+}
+
+/**
+ * A node representing an element that can be the parent of a `LocalVariableDeclExpr` for which we
+ * want to use a synthetic node to variable declaration and its type access.
+ *
+ * Excludes:
+ * - `LocalVariableDeclStmt` because a synthetic node isn't needed
+ * - `ForStmt` becasue a different synthetic node is already used
+ */
+final class LocalVarDeclParentNode extends ExprStmtNode {
+ LocalVarDeclParent lvdp;
+
+ LocalVarDeclParentNode() { lvdp = element }
+
+ override PrintAstNode getChild(int childIndex) {
+ result = super.getChild(childIndex) and
+ not result.(ElementNode).getElement() = [lvdp.getVariable(), lvdp.getTypeAccess()]
+ or
+ childIndex = lvdp.getVariable().getIndex() and
+ result.(LocalVarDeclSynthNode).getVariable() = lvdp.getVariable()
+ }
+}
+
/**
* A node representing a `Callable`, such as method declaration.
*/
@@ -509,6 +552,30 @@ final class ForInitNode extends PrintAstNode, TForInitNode {
ForStmt getForStmt() { result = fs }
}
+/**
+ * A synthetic node holding a `LocalVariableDeclExpr` and its type access.
+ */
+final class LocalVarDeclSynthNode extends PrintAstNode, TLocalVarDeclNode {
+ LocalVariableDeclExpr lvde;
+
+ LocalVarDeclSynthNode() { this = TLocalVarDeclNode(lvde) }
+
+ override string toString() { result = "(Local Variable Declaration)" }
+
+ override ElementNode getChild(int childIndex) {
+ childIndex = 0 and
+ result.getElement() = lvde.getTypeAccess()
+ or
+ childIndex = 1 and
+ result.getElement() = lvde
+ }
+
+ /**
+ * Gets the underlying `LocalVariableDeclExpr`
+ */
+ LocalVariableDeclExpr getVariable() { result = lvde }
+}
+
/**
* A node representing the annotations of an `Annotatable`.
* Only rendered if there is at least one annotation.
diff --git a/java/ql/test/library-tests/java7/MultiCatch/PrintAst.expected b/java/ql/test/library-tests/java7/MultiCatch/PrintAst.expected
index 8b8fe959628..98172ceff75 100644
--- a/java/ql/test/library-tests/java7/MultiCatch/PrintAst.expected
+++ b/java/ql/test/library-tests/java7/MultiCatch/PrintAst.expected
@@ -21,10 +21,11 @@ MultiCatch.java:
# 14| 0: [ClassInstanceExpr] new SQLException(...)
# 14| -3: [TypeAccess] SQLException
# 15| 0: [CatchClause] stmt
-# 15| -1: [UnionTypeAccess] ...|...
-# 15| 0: [TypeAccess] IOException
-# 15| 1: [TypeAccess] SQLException
-# 15| 0: [LocalVariableDeclExpr] e
+#-----| 0: (Local Variable Declaration)
+# 15| 0: [UnionTypeAccess] ...|...
+# 15| 0: [TypeAccess] IOException
+# 15| 1: [TypeAccess] SQLException
+# 15| 1: [LocalVariableDeclExpr] e
# 16| 1: [BlockStmt] stmt
# 17| 0: [ExprStmt] stmt
# 17| 0: [MethodAccess] printStackTrace(...)
@@ -55,10 +56,11 @@ MultiCatch.java:
# 30| 0: [ClassInstanceExpr] new Exception(...)
# 30| -3: [TypeAccess] Exception
# 31| 0: [CatchClause] stmt
-# 31| -1: [UnionTypeAccess] ...|...
-# 31| 0: [TypeAccess] IOException
-# 31| 1: [TypeAccess] SQLException
-# 31| 0: [LocalVariableDeclExpr] e
+#-----| 0: (Local Variable Declaration)
+# 31| 0: [UnionTypeAccess] ...|...
+# 31| 0: [TypeAccess] IOException
+# 31| 1: [TypeAccess] SQLException
+# 31| 1: [LocalVariableDeclExpr] e
# 32| 1: [BlockStmt] stmt
# 35| 4: [Method] ordinaryCatch
# 35| 3: [TypeAccess] void
@@ -69,6 +71,7 @@ MultiCatch.java:
# 39| 0: [ClassInstanceExpr] new IOException(...)
# 39| -3: [TypeAccess] IOException
# 40| 0: [CatchClause] stmt
-# 40| -1: [TypeAccess] Exception
-# 40| 0: [LocalVariableDeclExpr] e
+#-----| 0: (Local Variable Declaration)
+# 40| 0: [TypeAccess] Exception
+# 40| 1: [LocalVariableDeclExpr] e
# 41| 1: [BlockStmt] stmt
From 49f9a76c547bbfe86c2f84a03375c81d58c4fb9c Mon Sep 17 00:00:00 2001
From: Geoffrey White <40627776+geoffw0@users.noreply.github.com>
Date: Tue, 22 Sep 2020 13:21:17 +0100
Subject: [PATCH 045/411] C++: Add tests for std::map and std::unordered_map.
---
.../dataflow/taint-tests/localTaint.expected | 1369 +++++++++++++++--
.../dataflow/taint-tests/map.cpp | 311 +++-
.../library-tests/dataflow/taint-tests/stl.h | 135 ++
.../dataflow/taint-tests/taint.expected | 8 +-
.../dataflow/taint-tests/test_ir.expected | 8 +-
5 files changed, 1671 insertions(+), 160 deletions(-)
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
index b571ac46520..18e8a873303 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected
@@ -391,144 +391,1207 @@
| format.cpp:158:13:158:18 | call to wcslen | format.cpp:158:13:158:26 | ... / ... | TAINT |
| format.cpp:158:13:158:26 | ... / ... | format.cpp:158:7:158:27 | ... + ... | TAINT |
| format.cpp:158:26:158:26 | 2 | format.cpp:158:13:158:26 | ... / ... | TAINT |
-| map.cpp:14:28:14:28 | call to pair | map.cpp:16:2:16:2 | a | |
-| map.cpp:14:28:14:28 | call to pair | map.cpp:17:7:17:7 | a | |
-| map.cpp:14:28:14:28 | call to pair | map.cpp:18:7:18:7 | a | |
-| map.cpp:14:28:14:28 | call to pair | map.cpp:19:7:19:7 | a | |
-| map.cpp:14:31:14:31 | call to pair | map.cpp:21:2:21:2 | b | |
-| map.cpp:14:31:14:31 | call to pair | map.cpp:22:7:22:7 | b | |
-| map.cpp:14:31:14:31 | call to pair | map.cpp:23:7:23:7 | b | |
-| map.cpp:14:31:14:31 | call to pair | map.cpp:24:7:24:7 | b | |
-| map.cpp:14:34:14:34 | call to pair | map.cpp:26:2:26:2 | c | |
-| map.cpp:14:34:14:34 | call to pair | map.cpp:27:7:27:7 | c | |
-| map.cpp:14:34:14:34 | call to pair | map.cpp:28:7:28:7 | c | |
-| map.cpp:14:34:14:34 | call to pair | map.cpp:29:7:29:7 | c | |
-| map.cpp:16:2:16:2 | a [post update] | map.cpp:17:7:17:7 | a | |
-| map.cpp:16:2:16:2 | a [post update] | map.cpp:18:7:18:7 | a | |
-| map.cpp:16:2:16:2 | a [post update] | map.cpp:19:7:19:7 | a | |
-| map.cpp:16:2:16:16 | ... = ... | map.cpp:16:4:16:8 | first [post update] | |
-| map.cpp:16:2:16:16 | ... = ... | map.cpp:17:9:17:13 | first | |
-| map.cpp:16:12:16:16 | 123 | map.cpp:16:2:16:16 | ... = ... | |
-| map.cpp:17:7:17:7 | a [post update] | map.cpp:18:7:18:7 | a | |
-| map.cpp:17:7:17:7 | a [post update] | map.cpp:19:7:19:7 | a | |
-| map.cpp:18:7:18:7 | a [post update] | map.cpp:19:7:19:7 | a | |
-| map.cpp:21:2:21:2 | b [post update] | map.cpp:22:7:22:7 | b | |
-| map.cpp:21:2:21:2 | b [post update] | map.cpp:23:7:23:7 | b | |
-| map.cpp:21:2:21:2 | b [post update] | map.cpp:24:7:24:7 | b | |
-| map.cpp:21:2:21:19 | ... = ... | map.cpp:21:4:21:8 | first [post update] | |
-| map.cpp:21:2:21:19 | ... = ... | map.cpp:22:9:22:13 | first | |
-| map.cpp:21:12:21:17 | call to source | map.cpp:21:2:21:19 | ... = ... | |
-| map.cpp:22:7:22:7 | b [post update] | map.cpp:23:7:23:7 | b | |
-| map.cpp:22:7:22:7 | b [post update] | map.cpp:24:7:24:7 | b | |
-| map.cpp:23:7:23:7 | b [post update] | map.cpp:24:7:24:7 | b | |
-| map.cpp:26:2:26:2 | c [post update] | map.cpp:27:7:27:7 | c | |
-| map.cpp:26:2:26:2 | c [post update] | map.cpp:28:7:28:7 | c | |
-| map.cpp:26:2:26:2 | c [post update] | map.cpp:29:7:29:7 | c | |
-| map.cpp:26:2:26:20 | ... = ... | map.cpp:26:4:26:9 | second [post update] | |
-| map.cpp:26:2:26:20 | ... = ... | map.cpp:28:9:28:14 | second | |
-| map.cpp:26:13:26:18 | call to source | map.cpp:26:2:26:20 | ... = ... | |
-| map.cpp:27:7:27:7 | c [post update] | map.cpp:28:7:28:7 | c | |
-| map.cpp:27:7:27:7 | c [post update] | map.cpp:29:7:29:7 | c | |
-| map.cpp:28:7:28:7 | c [post update] | map.cpp:29:7:29:7 | c | |
-| map.cpp:31:30:31:42 | call to pair | map.cpp:32:7:32:7 | d | |
-| map.cpp:31:30:31:42 | call to pair | map.cpp:33:7:33:7 | d | |
-| map.cpp:31:30:31:42 | call to pair | map.cpp:34:7:34:7 | d | |
-| map.cpp:32:7:32:7 | d [post update] | map.cpp:33:7:33:7 | d | |
-| map.cpp:32:7:32:7 | d [post update] | map.cpp:34:7:34:7 | d | |
-| map.cpp:33:7:33:7 | d [post update] | map.cpp:34:7:34:7 | d | |
-| map.cpp:36:30:36:45 | call to pair | map.cpp:37:7:37:7 | e | |
-| map.cpp:36:30:36:45 | call to pair | map.cpp:38:7:38:7 | e | |
-| map.cpp:36:30:36:45 | call to pair | map.cpp:39:7:39:7 | e | |
-| map.cpp:37:7:37:7 | e [post update] | map.cpp:38:7:38:7 | e | |
-| map.cpp:37:7:37:7 | e [post update] | map.cpp:39:7:39:7 | e | |
-| map.cpp:38:7:38:7 | e [post update] | map.cpp:39:7:39:7 | e | |
-| map.cpp:41:30:41:45 | call to pair | map.cpp:42:7:42:7 | f | |
-| map.cpp:41:30:41:45 | call to pair | map.cpp:43:7:43:7 | f | |
-| map.cpp:41:30:41:45 | call to pair | map.cpp:44:7:44:7 | f | |
-| map.cpp:41:30:41:45 | call to pair | map.cpp:46:30:46:30 | f | |
-| map.cpp:41:30:41:45 | call to pair | map.cpp:47:7:47:7 | f | |
-| map.cpp:41:30:41:45 | call to pair | map.cpp:48:7:48:7 | f | |
-| map.cpp:41:30:41:45 | call to pair | map.cpp:49:7:49:7 | f | |
-| map.cpp:41:30:41:45 | call to pair | map.cpp:52:6:52:6 | f | |
-| map.cpp:42:7:42:7 | f [post update] | map.cpp:43:7:43:7 | f | |
-| map.cpp:42:7:42:7 | f [post update] | map.cpp:44:7:44:7 | f | |
-| map.cpp:42:7:42:7 | f [post update] | map.cpp:46:30:46:30 | f | |
-| map.cpp:42:7:42:7 | f [post update] | map.cpp:47:7:47:7 | f | |
-| map.cpp:42:7:42:7 | f [post update] | map.cpp:48:7:48:7 | f | |
-| map.cpp:42:7:42:7 | f [post update] | map.cpp:49:7:49:7 | f | |
-| map.cpp:42:7:42:7 | f [post update] | map.cpp:52:6:52:6 | f | |
-| map.cpp:43:7:43:7 | f [post update] | map.cpp:44:7:44:7 | f | |
-| map.cpp:43:7:43:7 | f [post update] | map.cpp:46:30:46:30 | f | |
-| map.cpp:43:7:43:7 | f [post update] | map.cpp:47:7:47:7 | f | |
-| map.cpp:43:7:43:7 | f [post update] | map.cpp:48:7:48:7 | f | |
-| map.cpp:43:7:43:7 | f [post update] | map.cpp:49:7:49:7 | f | |
-| map.cpp:43:7:43:7 | f [post update] | map.cpp:52:6:52:6 | f | |
+| map.cpp:18:28:18:28 | call to pair | map.cpp:20:2:20:2 | a | |
+| map.cpp:18:28:18:28 | call to pair | map.cpp:21:7:21:7 | a | |
+| map.cpp:18:28:18:28 | call to pair | map.cpp:22:7:22:7 | a | |
+| map.cpp:18:28:18:28 | call to pair | map.cpp:23:7:23:7 | a | |
+| map.cpp:18:31:18:31 | call to pair | map.cpp:25:2:25:2 | b | |
+| map.cpp:18:31:18:31 | call to pair | map.cpp:26:7:26:7 | b | |
+| map.cpp:18:31:18:31 | call to pair | map.cpp:27:7:27:7 | b | |
+| map.cpp:18:31:18:31 | call to pair | map.cpp:28:7:28:7 | b | |
+| map.cpp:18:34:18:34 | call to pair | map.cpp:30:2:30:2 | c | |
+| map.cpp:18:34:18:34 | call to pair | map.cpp:31:7:31:7 | c | |
+| map.cpp:18:34:18:34 | call to pair | map.cpp:32:7:32:7 | c | |
+| map.cpp:18:34:18:34 | call to pair | map.cpp:33:7:33:7 | c | |
+| map.cpp:20:2:20:2 | a [post update] | map.cpp:21:7:21:7 | a | |
+| map.cpp:20:2:20:2 | a [post update] | map.cpp:22:7:22:7 | a | |
+| map.cpp:20:2:20:2 | a [post update] | map.cpp:23:7:23:7 | a | |
+| map.cpp:20:2:20:16 | ... = ... | map.cpp:20:4:20:8 | first [post update] | |
+| map.cpp:20:2:20:16 | ... = ... | map.cpp:21:9:21:13 | first | |
+| map.cpp:20:12:20:16 | 123 | map.cpp:20:2:20:16 | ... = ... | |
+| map.cpp:21:7:21:7 | a [post update] | map.cpp:22:7:22:7 | a | |
+| map.cpp:21:7:21:7 | a [post update] | map.cpp:23:7:23:7 | a | |
+| map.cpp:22:7:22:7 | a [post update] | map.cpp:23:7:23:7 | a | |
+| map.cpp:25:2:25:2 | b [post update] | map.cpp:26:7:26:7 | b | |
+| map.cpp:25:2:25:2 | b [post update] | map.cpp:27:7:27:7 | b | |
+| map.cpp:25:2:25:2 | b [post update] | map.cpp:28:7:28:7 | b | |
+| map.cpp:25:2:25:19 | ... = ... | map.cpp:25:4:25:8 | first [post update] | |
+| map.cpp:25:2:25:19 | ... = ... | map.cpp:26:9:26:13 | first | |
+| map.cpp:25:12:25:17 | call to source | map.cpp:25:2:25:19 | ... = ... | |
+| map.cpp:26:7:26:7 | b [post update] | map.cpp:27:7:27:7 | b | |
+| map.cpp:26:7:26:7 | b [post update] | map.cpp:28:7:28:7 | b | |
+| map.cpp:27:7:27:7 | b [post update] | map.cpp:28:7:28:7 | b | |
+| map.cpp:30:2:30:2 | c [post update] | map.cpp:31:7:31:7 | c | |
+| map.cpp:30:2:30:2 | c [post update] | map.cpp:32:7:32:7 | c | |
+| map.cpp:30:2:30:2 | c [post update] | map.cpp:33:7:33:7 | c | |
+| map.cpp:30:2:30:20 | ... = ... | map.cpp:30:4:30:9 | second [post update] | |
+| map.cpp:30:2:30:20 | ... = ... | map.cpp:32:9:32:14 | second | |
+| map.cpp:30:13:30:18 | call to source | map.cpp:30:2:30:20 | ... = ... | |
+| map.cpp:31:7:31:7 | c [post update] | map.cpp:32:7:32:7 | c | |
+| map.cpp:31:7:31:7 | c [post update] | map.cpp:33:7:33:7 | c | |
+| map.cpp:32:7:32:7 | c [post update] | map.cpp:33:7:33:7 | c | |
+| map.cpp:35:30:35:42 | call to pair | map.cpp:36:7:36:7 | d | |
+| map.cpp:35:30:35:42 | call to pair | map.cpp:37:7:37:7 | d | |
+| map.cpp:35:30:35:42 | call to pair | map.cpp:38:7:38:7 | d | |
+| map.cpp:36:7:36:7 | d [post update] | map.cpp:37:7:37:7 | d | |
+| map.cpp:36:7:36:7 | d [post update] | map.cpp:38:7:38:7 | d | |
+| map.cpp:37:7:37:7 | d [post update] | map.cpp:38:7:38:7 | d | |
+| map.cpp:40:30:40:45 | call to pair | map.cpp:41:7:41:7 | e | |
+| map.cpp:40:30:40:45 | call to pair | map.cpp:42:7:42:7 | e | |
+| map.cpp:40:30:40:45 | call to pair | map.cpp:43:7:43:7 | e | |
+| map.cpp:41:7:41:7 | e [post update] | map.cpp:42:7:42:7 | e | |
+| map.cpp:41:7:41:7 | e [post update] | map.cpp:43:7:43:7 | e | |
+| map.cpp:42:7:42:7 | e [post update] | map.cpp:43:7:43:7 | e | |
+| map.cpp:45:30:45:45 | call to pair | map.cpp:46:7:46:7 | f | |
+| map.cpp:45:30:45:45 | call to pair | map.cpp:47:7:47:7 | f | |
+| map.cpp:45:30:45:45 | call to pair | map.cpp:48:7:48:7 | f | |
+| map.cpp:45:30:45:45 | call to pair | map.cpp:50:30:50:30 | f | |
+| map.cpp:45:30:45:45 | call to pair | map.cpp:56:6:56:6 | f | |
+| map.cpp:46:7:46:7 | f [post update] | map.cpp:47:7:47:7 | f | |
+| map.cpp:46:7:46:7 | f [post update] | map.cpp:48:7:48:7 | f | |
+| map.cpp:46:7:46:7 | f [post update] | map.cpp:50:30:50:30 | f | |
+| map.cpp:46:7:46:7 | f [post update] | map.cpp:56:6:56:6 | f | |
| map.cpp:47:7:47:7 | f [post update] | map.cpp:48:7:48:7 | f | |
-| map.cpp:47:7:47:7 | f [post update] | map.cpp:49:7:49:7 | f | |
-| map.cpp:47:7:47:7 | f [post update] | map.cpp:52:6:52:6 | f | |
-| map.cpp:48:7:48:7 | f [post update] | map.cpp:49:7:49:7 | f | |
-| map.cpp:48:7:48:7 | f [post update] | map.cpp:52:6:52:6 | f | |
-| map.cpp:52:6:52:6 | f | map.cpp:52:2:52:6 | ... = ... | |
-| map.cpp:52:6:52:6 | f | map.cpp:53:7:53:7 | h | |
-| map.cpp:52:6:52:6 | f | map.cpp:54:7:54:7 | h | |
-| map.cpp:52:6:52:6 | f | map.cpp:55:7:55:7 | h | |
-| map.cpp:53:7:53:7 | h [post update] | map.cpp:54:7:54:7 | h | |
-| map.cpp:53:7:53:7 | h [post update] | map.cpp:55:7:55:7 | h | |
-| map.cpp:54:7:54:7 | h [post update] | map.cpp:55:7:55:7 | h | |
-| map.cpp:57:30:57:42 | call to pair | map.cpp:61:3:61:3 | i | |
-| map.cpp:57:30:57:42 | call to pair | map.cpp:63:7:63:7 | i | |
-| map.cpp:57:30:57:42 | call to pair | map.cpp:64:7:64:7 | i | |
-| map.cpp:57:30:57:42 | call to pair | map.cpp:65:7:65:7 | i | |
-| map.cpp:58:30:58:45 | call to pair | map.cpp:61:10:61:10 | j | |
-| map.cpp:58:30:58:45 | call to pair | map.cpp:66:7:66:7 | j | |
-| map.cpp:58:30:58:45 | call to pair | map.cpp:67:7:67:7 | j | |
-| map.cpp:58:30:58:45 | call to pair | map.cpp:68:7:68:7 | j | |
-| map.cpp:59:30:59:45 | call to pair | map.cpp:62:2:62:2 | k | |
-| map.cpp:59:30:59:45 | call to pair | map.cpp:69:7:69:7 | k | |
-| map.cpp:59:30:59:45 | call to pair | map.cpp:70:7:70:7 | k | |
-| map.cpp:59:30:59:45 | call to pair | map.cpp:71:7:71:7 | k | |
-| map.cpp:60:30:60:42 | call to pair | map.cpp:62:9:62:9 | l | |
-| map.cpp:60:30:60:42 | call to pair | map.cpp:72:7:72:7 | l | |
-| map.cpp:60:30:60:42 | call to pair | map.cpp:73:7:73:7 | l | |
-| map.cpp:60:30:60:42 | call to pair | map.cpp:74:7:74:7 | l | |
-| map.cpp:61:3:61:3 | ref arg i | map.cpp:63:7:63:7 | i | |
-| map.cpp:61:3:61:3 | ref arg i | map.cpp:64:7:64:7 | i | |
-| map.cpp:61:3:61:3 | ref arg i | map.cpp:65:7:65:7 | i | |
-| map.cpp:61:10:61:10 | ref arg j | map.cpp:66:7:66:7 | j | |
-| map.cpp:61:10:61:10 | ref arg j | map.cpp:67:7:67:7 | j | |
-| map.cpp:61:10:61:10 | ref arg j | map.cpp:68:7:68:7 | j | |
-| map.cpp:62:2:62:2 | ref arg k | map.cpp:69:7:69:7 | k | |
-| map.cpp:62:2:62:2 | ref arg k | map.cpp:70:7:70:7 | k | |
-| map.cpp:62:2:62:2 | ref arg k | map.cpp:71:7:71:7 | k | |
-| map.cpp:62:9:62:9 | ref arg l | map.cpp:72:7:72:7 | l | |
-| map.cpp:62:9:62:9 | ref arg l | map.cpp:73:7:73:7 | l | |
-| map.cpp:62:9:62:9 | ref arg l | map.cpp:74:7:74:7 | l | |
-| map.cpp:63:7:63:7 | i [post update] | map.cpp:64:7:64:7 | i | |
-| map.cpp:63:7:63:7 | i [post update] | map.cpp:65:7:65:7 | i | |
-| map.cpp:64:7:64:7 | i [post update] | map.cpp:65:7:65:7 | i | |
-| map.cpp:66:7:66:7 | j [post update] | map.cpp:67:7:67:7 | j | |
-| map.cpp:66:7:66:7 | j [post update] | map.cpp:68:7:68:7 | j | |
-| map.cpp:67:7:67:7 | j [post update] | map.cpp:68:7:68:7 | j | |
-| map.cpp:69:7:69:7 | k [post update] | map.cpp:70:7:70:7 | k | |
-| map.cpp:69:7:69:7 | k [post update] | map.cpp:71:7:71:7 | k | |
-| map.cpp:70:7:70:7 | k [post update] | map.cpp:71:7:71:7 | k | |
-| map.cpp:72:7:72:7 | l [post update] | map.cpp:73:7:73:7 | l | |
-| map.cpp:72:7:72:7 | l [post update] | map.cpp:74:7:74:7 | l | |
-| map.cpp:73:7:73:7 | l [post update] | map.cpp:74:7:74:7 | l | |
-| map.cpp:76:7:76:15 | call to make_pair | map.cpp:76:7:76:29 | call to pair | TAINT |
-| map.cpp:79:7:79:15 | call to make_pair | map.cpp:79:7:79:32 | call to pair | TAINT |
-| map.cpp:82:7:82:15 | call to make_pair | map.cpp:82:7:82:32 | call to pair | TAINT |
-| map.cpp:87:6:87:14 | call to make_pair | map.cpp:87:6:87:49 | call to pair | TAINT |
-| map.cpp:87:6:87:49 | call to pair | map.cpp:87:2:87:49 | ... = ... | |
-| map.cpp:87:6:87:49 | call to pair | map.cpp:88:7:88:7 | m | |
-| map.cpp:87:6:87:49 | call to pair | map.cpp:89:7:89:7 | m | |
-| map.cpp:87:6:87:49 | call to pair | map.cpp:90:7:90:7 | m | |
-| map.cpp:87:6:87:49 | call to pair | map.cpp:91:7:91:7 | m | |
-| map.cpp:87:6:87:49 | call to pair | map.cpp:92:7:92:7 | m | |
-| map.cpp:88:7:88:7 | m | map.cpp:88:7:88:7 | call to pair | TAINT |
-| map.cpp:90:7:90:7 | m [post update] | map.cpp:91:7:91:7 | m | |
-| map.cpp:90:7:90:7 | m [post update] | map.cpp:92:7:92:7 | m | |
-| map.cpp:91:7:91:7 | m [post update] | map.cpp:92:7:92:7 | m | |
+| map.cpp:47:7:47:7 | f [post update] | map.cpp:50:30:50:30 | f | |
+| map.cpp:47:7:47:7 | f [post update] | map.cpp:56:6:56:6 | f | |
+| map.cpp:50:30:50:30 | f | map.cpp:51:7:51:7 | g | |
+| map.cpp:50:30:50:30 | f | map.cpp:52:7:52:7 | g | |
+| map.cpp:50:30:50:30 | f | map.cpp:53:7:53:7 | g | |
+| map.cpp:51:7:51:7 | g [post update] | map.cpp:52:7:52:7 | g | |
+| map.cpp:51:7:51:7 | g [post update] | map.cpp:53:7:53:7 | g | |
+| map.cpp:52:7:52:7 | g [post update] | map.cpp:53:7:53:7 | g | |
+| map.cpp:56:6:56:6 | f | map.cpp:56:2:56:6 | ... = ... | |
+| map.cpp:56:6:56:6 | f | map.cpp:57:7:57:7 | h | |
+| map.cpp:56:6:56:6 | f | map.cpp:58:7:58:7 | h | |
+| map.cpp:56:6:56:6 | f | map.cpp:59:7:59:7 | h | |
+| map.cpp:57:7:57:7 | h [post update] | map.cpp:58:7:58:7 | h | |
+| map.cpp:57:7:57:7 | h [post update] | map.cpp:59:7:59:7 | h | |
+| map.cpp:58:7:58:7 | h [post update] | map.cpp:59:7:59:7 | h | |
+| map.cpp:61:30:61:42 | call to pair | map.cpp:65:3:65:3 | i | |
+| map.cpp:61:30:61:42 | call to pair | map.cpp:67:7:67:7 | i | |
+| map.cpp:61:30:61:42 | call to pair | map.cpp:68:7:68:7 | i | |
+| map.cpp:61:30:61:42 | call to pair | map.cpp:69:7:69:7 | i | |
+| map.cpp:62:30:62:45 | call to pair | map.cpp:65:10:65:10 | j | |
+| map.cpp:62:30:62:45 | call to pair | map.cpp:70:7:70:7 | j | |
+| map.cpp:62:30:62:45 | call to pair | map.cpp:71:7:71:7 | j | |
+| map.cpp:62:30:62:45 | call to pair | map.cpp:72:7:72:7 | j | |
+| map.cpp:63:30:63:45 | call to pair | map.cpp:66:2:66:2 | k | |
+| map.cpp:63:30:63:45 | call to pair | map.cpp:73:7:73:7 | k | |
+| map.cpp:63:30:63:45 | call to pair | map.cpp:74:7:74:7 | k | |
+| map.cpp:63:30:63:45 | call to pair | map.cpp:75:7:75:7 | k | |
+| map.cpp:64:30:64:42 | call to pair | map.cpp:66:9:66:9 | l | |
+| map.cpp:64:30:64:42 | call to pair | map.cpp:76:7:76:7 | l | |
+| map.cpp:64:30:64:42 | call to pair | map.cpp:77:7:77:7 | l | |
+| map.cpp:64:30:64:42 | call to pair | map.cpp:78:7:78:7 | l | |
+| map.cpp:65:3:65:3 | ref arg i | map.cpp:67:7:67:7 | i | |
+| map.cpp:65:3:65:3 | ref arg i | map.cpp:68:7:68:7 | i | |
+| map.cpp:65:3:65:3 | ref arg i | map.cpp:69:7:69:7 | i | |
+| map.cpp:65:10:65:10 | ref arg j | map.cpp:70:7:70:7 | j | |
+| map.cpp:65:10:65:10 | ref arg j | map.cpp:71:7:71:7 | j | |
+| map.cpp:65:10:65:10 | ref arg j | map.cpp:72:7:72:7 | j | |
+| map.cpp:66:2:66:2 | ref arg k | map.cpp:73:7:73:7 | k | |
+| map.cpp:66:2:66:2 | ref arg k | map.cpp:74:7:74:7 | k | |
+| map.cpp:66:2:66:2 | ref arg k | map.cpp:75:7:75:7 | k | |
+| map.cpp:66:9:66:9 | ref arg l | map.cpp:76:7:76:7 | l | |
+| map.cpp:66:9:66:9 | ref arg l | map.cpp:77:7:77:7 | l | |
+| map.cpp:66:9:66:9 | ref arg l | map.cpp:78:7:78:7 | l | |
+| map.cpp:67:7:67:7 | i [post update] | map.cpp:68:7:68:7 | i | |
+| map.cpp:67:7:67:7 | i [post update] | map.cpp:69:7:69:7 | i | |
+| map.cpp:68:7:68:7 | i [post update] | map.cpp:69:7:69:7 | i | |
+| map.cpp:70:7:70:7 | j [post update] | map.cpp:71:7:71:7 | j | |
+| map.cpp:70:7:70:7 | j [post update] | map.cpp:72:7:72:7 | j | |
+| map.cpp:71:7:71:7 | j [post update] | map.cpp:72:7:72:7 | j | |
+| map.cpp:73:7:73:7 | k [post update] | map.cpp:74:7:74:7 | k | |
+| map.cpp:73:7:73:7 | k [post update] | map.cpp:75:7:75:7 | k | |
+| map.cpp:74:7:74:7 | k [post update] | map.cpp:75:7:75:7 | k | |
+| map.cpp:76:7:76:7 | l [post update] | map.cpp:77:7:77:7 | l | |
+| map.cpp:76:7:76:7 | l [post update] | map.cpp:78:7:78:7 | l | |
+| map.cpp:77:7:77:7 | l [post update] | map.cpp:78:7:78:7 | l | |
+| map.cpp:80:7:80:15 | call to make_pair | map.cpp:80:7:80:29 | call to pair | TAINT |
+| map.cpp:83:7:83:15 | call to make_pair | map.cpp:83:7:83:32 | call to pair | TAINT |
+| map.cpp:86:7:86:15 | call to make_pair | map.cpp:86:7:86:32 | call to pair | TAINT |
+| map.cpp:91:6:91:14 | call to make_pair | map.cpp:91:6:91:49 | call to pair | TAINT |
+| map.cpp:91:6:91:49 | call to pair | map.cpp:91:2:91:49 | ... = ... | |
+| map.cpp:91:6:91:49 | call to pair | map.cpp:92:7:92:7 | m | |
+| map.cpp:91:6:91:49 | call to pair | map.cpp:93:7:93:7 | m | |
+| map.cpp:91:6:91:49 | call to pair | map.cpp:94:7:94:7 | m | |
+| map.cpp:91:6:91:49 | call to pair | map.cpp:95:7:95:7 | m | |
+| map.cpp:91:6:91:49 | call to pair | map.cpp:96:7:96:7 | m | |
+| map.cpp:92:7:92:7 | m | map.cpp:92:7:92:7 | call to pair | TAINT |
+| map.cpp:94:7:94:7 | m [post update] | map.cpp:95:7:95:7 | m | |
+| map.cpp:94:7:94:7 | m [post update] | map.cpp:96:7:96:7 | m | |
+| map.cpp:95:7:95:7 | m [post update] | map.cpp:96:7:96:7 | m | |
+| map.cpp:102:27:102:28 | call to map | map.cpp:104:7:104:8 | m1 | |
+| map.cpp:102:27:102:28 | call to map | map.cpp:110:7:110:8 | m1 | |
+| map.cpp:102:27:102:28 | call to map | map.cpp:116:7:116:8 | m1 | |
+| map.cpp:102:27:102:28 | call to map | map.cpp:122:7:122:8 | m1 | |
+| map.cpp:102:27:102:28 | call to map | map.cpp:143:12:143:13 | m1 | |
+| map.cpp:102:27:102:28 | call to map | map.cpp:143:30:143:31 | m1 | |
+| map.cpp:102:27:102:28 | call to map | map.cpp:249:1:249:1 | m1 | |
+| map.cpp:102:31:102:32 | call to map | map.cpp:105:7:105:8 | m2 | |
+| map.cpp:102:31:102:32 | call to map | map.cpp:111:7:111:8 | m2 | |
+| map.cpp:102:31:102:32 | call to map | map.cpp:117:7:117:8 | m2 | |
+| map.cpp:102:31:102:32 | call to map | map.cpp:123:7:123:8 | m2 | |
+| map.cpp:102:31:102:32 | call to map | map.cpp:130:30:130:31 | m2 | |
+| map.cpp:102:31:102:32 | call to map | map.cpp:131:32:131:33 | m2 | |
+| map.cpp:102:31:102:32 | call to map | map.cpp:133:7:133:8 | m2 | |
+| map.cpp:102:31:102:32 | call to map | map.cpp:149:12:149:13 | m2 | |
+| map.cpp:102:31:102:32 | call to map | map.cpp:149:30:149:31 | m2 | |
+| map.cpp:102:31:102:32 | call to map | map.cpp:179:7:179:8 | m2 | |
+| map.cpp:102:31:102:32 | call to map | map.cpp:180:7:180:8 | m2 | |
+| map.cpp:102:31:102:32 | call to map | map.cpp:181:7:181:8 | m2 | |
+| map.cpp:102:31:102:32 | call to map | map.cpp:182:7:182:8 | m2 | |
+| map.cpp:102:31:102:32 | call to map | map.cpp:183:7:183:8 | m2 | |
+| map.cpp:102:31:102:32 | call to map | map.cpp:184:7:184:8 | m2 | |
+| map.cpp:102:31:102:32 | call to map | map.cpp:249:1:249:1 | m2 | |
+| map.cpp:102:35:102:36 | call to map | map.cpp:106:7:106:8 | m3 | |
+| map.cpp:102:35:102:36 | call to map | map.cpp:112:7:112:8 | m3 | |
+| map.cpp:102:35:102:36 | call to map | map.cpp:118:7:118:8 | m3 | |
+| map.cpp:102:35:102:36 | call to map | map.cpp:124:7:124:8 | m3 | |
+| map.cpp:102:35:102:36 | call to map | map.cpp:155:12:155:13 | m3 | |
+| map.cpp:102:35:102:36 | call to map | map.cpp:155:30:155:31 | m3 | |
+| map.cpp:102:35:102:36 | call to map | map.cpp:249:1:249:1 | m3 | |
+| map.cpp:102:39:102:40 | call to map | map.cpp:107:7:107:8 | m4 | |
+| map.cpp:102:39:102:40 | call to map | map.cpp:107:17:107:18 | m4 | |
+| map.cpp:102:39:102:40 | call to map | map.cpp:113:7:113:8 | m4 | |
+| map.cpp:102:39:102:40 | call to map | map.cpp:119:7:119:8 | m4 | |
+| map.cpp:102:39:102:40 | call to map | map.cpp:125:7:125:8 | m4 | |
+| map.cpp:102:39:102:40 | call to map | map.cpp:249:1:249:1 | m4 | |
+| map.cpp:102:43:102:44 | call to map | map.cpp:108:7:108:8 | m5 | |
+| map.cpp:102:43:102:44 | call to map | map.cpp:114:7:114:8 | m5 | |
+| map.cpp:102:43:102:44 | call to map | map.cpp:120:7:120:8 | m5 | |
+| map.cpp:102:43:102:44 | call to map | map.cpp:126:7:126:8 | m5 | |
+| map.cpp:102:43:102:44 | call to map | map.cpp:249:1:249:1 | m5 | |
+| map.cpp:102:47:102:48 | call to map | map.cpp:109:7:109:8 | m6 | |
+| map.cpp:102:47:102:48 | call to map | map.cpp:109:27:109:28 | m6 | |
+| map.cpp:102:47:102:48 | call to map | map.cpp:115:7:115:8 | m6 | |
+| map.cpp:102:47:102:48 | call to map | map.cpp:121:7:121:8 | m6 | |
+| map.cpp:102:47:102:48 | call to map | map.cpp:127:7:127:8 | m6 | |
+| map.cpp:102:47:102:48 | call to map | map.cpp:249:1:249:1 | m6 | |
+| map.cpp:104:7:104:8 | ref arg m1 | map.cpp:110:7:110:8 | m1 | |
+| map.cpp:104:7:104:8 | ref arg m1 | map.cpp:116:7:116:8 | m1 | |
+| map.cpp:104:7:104:8 | ref arg m1 | map.cpp:122:7:122:8 | m1 | |
+| map.cpp:104:7:104:8 | ref arg m1 | map.cpp:143:12:143:13 | m1 | |
+| map.cpp:104:7:104:8 | ref arg m1 | map.cpp:143:30:143:31 | m1 | |
+| map.cpp:104:7:104:8 | ref arg m1 | map.cpp:249:1:249:1 | m1 | |
+| map.cpp:104:17:104:30 | call to make_pair | map.cpp:104:17:104:44 | call to pair | TAINT |
+| map.cpp:104:47:104:51 | first | map.cpp:104:7:104:51 | call to iterator | |
+| map.cpp:105:7:105:8 | ref arg m2 | map.cpp:111:7:111:8 | m2 | |
+| map.cpp:105:7:105:8 | ref arg m2 | map.cpp:117:7:117:8 | m2 | |
+| map.cpp:105:7:105:8 | ref arg m2 | map.cpp:123:7:123:8 | m2 | |
+| map.cpp:105:7:105:8 | ref arg m2 | map.cpp:130:30:130:31 | m2 | |
+| map.cpp:105:7:105:8 | ref arg m2 | map.cpp:131:32:131:33 | m2 | |
+| map.cpp:105:7:105:8 | ref arg m2 | map.cpp:133:7:133:8 | m2 | |
+| map.cpp:105:7:105:8 | ref arg m2 | map.cpp:149:12:149:13 | m2 | |
+| map.cpp:105:7:105:8 | ref arg m2 | map.cpp:149:30:149:31 | m2 | |
+| map.cpp:105:7:105:8 | ref arg m2 | map.cpp:179:7:179:8 | m2 | |
+| map.cpp:105:7:105:8 | ref arg m2 | map.cpp:180:7:180:8 | m2 | |
+| map.cpp:105:7:105:8 | ref arg m2 | map.cpp:181:7:181:8 | m2 | |
+| map.cpp:105:7:105:8 | ref arg m2 | map.cpp:182:7:182:8 | m2 | |
+| map.cpp:105:7:105:8 | ref arg m2 | map.cpp:183:7:183:8 | m2 | |
+| map.cpp:105:7:105:8 | ref arg m2 | map.cpp:184:7:184:8 | m2 | |
+| map.cpp:105:7:105:8 | ref arg m2 | map.cpp:249:1:249:1 | m2 | |
+| map.cpp:105:17:105:30 | call to make_pair | map.cpp:105:17:105:47 | call to pair | TAINT |
+| map.cpp:105:50:105:54 | first | map.cpp:105:7:105:54 | call to iterator | |
+| map.cpp:106:7:106:8 | ref arg m3 | map.cpp:112:7:112:8 | m3 | |
+| map.cpp:106:7:106:8 | ref arg m3 | map.cpp:118:7:118:8 | m3 | |
+| map.cpp:106:7:106:8 | ref arg m3 | map.cpp:124:7:124:8 | m3 | |
+| map.cpp:106:7:106:8 | ref arg m3 | map.cpp:155:12:155:13 | m3 | |
+| map.cpp:106:7:106:8 | ref arg m3 | map.cpp:155:30:155:31 | m3 | |
+| map.cpp:106:7:106:8 | ref arg m3 | map.cpp:249:1:249:1 | m3 | |
+| map.cpp:106:17:106:30 | call to make_pair | map.cpp:106:17:106:47 | call to pair | TAINT |
+| map.cpp:106:50:106:54 | first | map.cpp:106:7:106:54 | call to iterator | |
+| map.cpp:107:7:107:8 | ref arg m4 | map.cpp:113:7:113:8 | m4 | |
+| map.cpp:107:7:107:8 | ref arg m4 | map.cpp:119:7:119:8 | m4 | |
+| map.cpp:107:7:107:8 | ref arg m4 | map.cpp:125:7:125:8 | m4 | |
+| map.cpp:107:7:107:8 | ref arg m4 | map.cpp:249:1:249:1 | m4 | |
+| map.cpp:107:17:107:18 | ref arg m4 | map.cpp:107:7:107:8 | m4 | |
+| map.cpp:107:17:107:18 | ref arg m4 | map.cpp:113:7:113:8 | m4 | |
+| map.cpp:107:17:107:18 | ref arg m4 | map.cpp:119:7:119:8 | m4 | |
+| map.cpp:107:17:107:18 | ref arg m4 | map.cpp:125:7:125:8 | m4 | |
+| map.cpp:107:17:107:18 | ref arg m4 | map.cpp:249:1:249:1 | m4 | |
+| map.cpp:107:20:107:24 | call to begin | map.cpp:107:17:107:26 | call to iterator | TAINT |
+| map.cpp:107:29:107:70 | call to pair | map.cpp:107:29:107:70 | call to pair | TAINT |
+| map.cpp:108:7:108:8 | ref arg m5 | map.cpp:114:7:114:8 | m5 | |
+| map.cpp:108:7:108:8 | ref arg m5 | map.cpp:120:7:120:8 | m5 | |
+| map.cpp:108:7:108:8 | ref arg m5 | map.cpp:126:7:126:8 | m5 | |
+| map.cpp:108:7:108:8 | ref arg m5 | map.cpp:249:1:249:1 | m5 | |
+| map.cpp:108:44:108:48 | first | map.cpp:108:7:108:48 | call to iterator | |
+| map.cpp:109:7:109:8 | ref arg m6 | map.cpp:115:7:115:8 | m6 | |
+| map.cpp:109:7:109:8 | ref arg m6 | map.cpp:121:7:121:8 | m6 | |
+| map.cpp:109:7:109:8 | ref arg m6 | map.cpp:127:7:127:8 | m6 | |
+| map.cpp:109:7:109:8 | ref arg m6 | map.cpp:249:1:249:1 | m6 | |
+| map.cpp:109:27:109:28 | ref arg m6 | map.cpp:109:7:109:8 | m6 | |
+| map.cpp:109:27:109:28 | ref arg m6 | map.cpp:115:7:115:8 | m6 | |
+| map.cpp:109:27:109:28 | ref arg m6 | map.cpp:121:7:121:8 | m6 | |
+| map.cpp:109:27:109:28 | ref arg m6 | map.cpp:127:7:127:8 | m6 | |
+| map.cpp:109:27:109:28 | ref arg m6 | map.cpp:249:1:249:1 | m6 | |
+| map.cpp:109:30:109:34 | call to begin | map.cpp:109:27:109:36 | call to iterator | TAINT |
+| map.cpp:110:7:110:8 | m1 | map.cpp:110:7:110:8 | call to map | |
+| map.cpp:111:7:111:8 | m2 | map.cpp:111:7:111:8 | call to map | |
+| map.cpp:112:7:112:8 | m3 | map.cpp:112:7:112:8 | call to map | |
+| map.cpp:113:7:113:8 | m4 | map.cpp:113:7:113:8 | call to map | |
+| map.cpp:114:7:114:8 | m5 | map.cpp:114:7:114:8 | call to map | |
+| map.cpp:115:7:115:8 | m6 | map.cpp:115:7:115:8 | call to map | |
+| map.cpp:116:7:116:8 | ref arg m1 | map.cpp:122:7:122:8 | m1 | |
+| map.cpp:116:7:116:8 | ref arg m1 | map.cpp:143:12:143:13 | m1 | |
+| map.cpp:116:7:116:8 | ref arg m1 | map.cpp:143:30:143:31 | m1 | |
+| map.cpp:116:7:116:8 | ref arg m1 | map.cpp:249:1:249:1 | m1 | |
+| map.cpp:117:7:117:8 | ref arg m2 | map.cpp:123:7:123:8 | m2 | |
+| map.cpp:117:7:117:8 | ref arg m2 | map.cpp:130:30:130:31 | m2 | |
+| map.cpp:117:7:117:8 | ref arg m2 | map.cpp:131:32:131:33 | m2 | |
+| map.cpp:117:7:117:8 | ref arg m2 | map.cpp:133:7:133:8 | m2 | |
+| map.cpp:117:7:117:8 | ref arg m2 | map.cpp:149:12:149:13 | m2 | |
+| map.cpp:117:7:117:8 | ref arg m2 | map.cpp:149:30:149:31 | m2 | |
+| map.cpp:117:7:117:8 | ref arg m2 | map.cpp:179:7:179:8 | m2 | |
+| map.cpp:117:7:117:8 | ref arg m2 | map.cpp:180:7:180:8 | m2 | |
+| map.cpp:117:7:117:8 | ref arg m2 | map.cpp:181:7:181:8 | m2 | |
+| map.cpp:117:7:117:8 | ref arg m2 | map.cpp:182:7:182:8 | m2 | |
+| map.cpp:117:7:117:8 | ref arg m2 | map.cpp:183:7:183:8 | m2 | |
+| map.cpp:117:7:117:8 | ref arg m2 | map.cpp:184:7:184:8 | m2 | |
+| map.cpp:117:7:117:8 | ref arg m2 | map.cpp:249:1:249:1 | m2 | |
+| map.cpp:118:7:118:8 | ref arg m3 | map.cpp:124:7:124:8 | m3 | |
+| map.cpp:118:7:118:8 | ref arg m3 | map.cpp:155:12:155:13 | m3 | |
+| map.cpp:118:7:118:8 | ref arg m3 | map.cpp:155:30:155:31 | m3 | |
+| map.cpp:118:7:118:8 | ref arg m3 | map.cpp:249:1:249:1 | m3 | |
+| map.cpp:119:7:119:8 | ref arg m4 | map.cpp:125:7:125:8 | m4 | |
+| map.cpp:119:7:119:8 | ref arg m4 | map.cpp:249:1:249:1 | m4 | |
+| map.cpp:120:7:120:8 | ref arg m5 | map.cpp:126:7:126:8 | m5 | |
+| map.cpp:120:7:120:8 | ref arg m5 | map.cpp:249:1:249:1 | m5 | |
+| map.cpp:121:7:121:8 | ref arg m6 | map.cpp:127:7:127:8 | m6 | |
+| map.cpp:121:7:121:8 | ref arg m6 | map.cpp:249:1:249:1 | m6 | |
+| map.cpp:122:7:122:8 | ref arg m1 | map.cpp:143:12:143:13 | m1 | |
+| map.cpp:122:7:122:8 | ref arg m1 | map.cpp:143:30:143:31 | m1 | |
+| map.cpp:122:7:122:8 | ref arg m1 | map.cpp:249:1:249:1 | m1 | |
+| map.cpp:123:7:123:8 | ref arg m2 | map.cpp:130:30:130:31 | m2 | |
+| map.cpp:123:7:123:8 | ref arg m2 | map.cpp:131:32:131:33 | m2 | |
+| map.cpp:123:7:123:8 | ref arg m2 | map.cpp:133:7:133:8 | m2 | |
+| map.cpp:123:7:123:8 | ref arg m2 | map.cpp:149:12:149:13 | m2 | |
+| map.cpp:123:7:123:8 | ref arg m2 | map.cpp:149:30:149:31 | m2 | |
+| map.cpp:123:7:123:8 | ref arg m2 | map.cpp:179:7:179:8 | m2 | |
+| map.cpp:123:7:123:8 | ref arg m2 | map.cpp:180:7:180:8 | m2 | |
+| map.cpp:123:7:123:8 | ref arg m2 | map.cpp:181:7:181:8 | m2 | |
+| map.cpp:123:7:123:8 | ref arg m2 | map.cpp:182:7:182:8 | m2 | |
+| map.cpp:123:7:123:8 | ref arg m2 | map.cpp:183:7:183:8 | m2 | |
+| map.cpp:123:7:123:8 | ref arg m2 | map.cpp:184:7:184:8 | m2 | |
+| map.cpp:123:7:123:8 | ref arg m2 | map.cpp:249:1:249:1 | m2 | |
+| map.cpp:124:7:124:8 | ref arg m3 | map.cpp:155:12:155:13 | m3 | |
+| map.cpp:124:7:124:8 | ref arg m3 | map.cpp:155:30:155:31 | m3 | |
+| map.cpp:124:7:124:8 | ref arg m3 | map.cpp:249:1:249:1 | m3 | |
+| map.cpp:125:7:125:8 | ref arg m4 | map.cpp:249:1:249:1 | m4 | |
+| map.cpp:126:7:126:8 | ref arg m5 | map.cpp:249:1:249:1 | m5 | |
+| map.cpp:127:7:127:8 | ref arg m6 | map.cpp:249:1:249:1 | m6 | |
+| map.cpp:130:30:130:31 | m2 | map.cpp:130:30:130:32 | call to map | |
+| map.cpp:130:30:130:32 | call to map | map.cpp:134:7:134:8 | m7 | |
+| map.cpp:130:30:130:32 | call to map | map.cpp:137:7:137:8 | m7 | |
+| map.cpp:130:30:130:32 | call to map | map.cpp:249:1:249:1 | m7 | |
+| map.cpp:131:31:131:33 | call to map | map.cpp:135:7:135:8 | m8 | |
+| map.cpp:131:31:131:33 | call to map | map.cpp:138:7:138:8 | m8 | |
+| map.cpp:131:31:131:33 | call to map | map.cpp:249:1:249:1 | m8 | |
+| map.cpp:131:32:131:33 | m2 | map.cpp:131:31:131:33 | call to map | |
+| map.cpp:132:27:132:28 | call to map | map.cpp:133:2:133:3 | m9 | |
+| map.cpp:132:27:132:28 | call to map | map.cpp:136:7:136:8 | m9 | |
+| map.cpp:132:27:132:28 | call to map | map.cpp:139:7:139:8 | m9 | |
+| map.cpp:132:27:132:28 | call to map | map.cpp:249:1:249:1 | m9 | |
+| map.cpp:133:2:133:3 | ref arg m9 | map.cpp:136:7:136:8 | m9 | |
+| map.cpp:133:2:133:3 | ref arg m9 | map.cpp:139:7:139:8 | m9 | |
+| map.cpp:133:2:133:3 | ref arg m9 | map.cpp:249:1:249:1 | m9 | |
+| map.cpp:133:7:133:8 | m2 | map.cpp:133:2:133:3 | ref arg m9 | TAINT |
+| map.cpp:133:7:133:8 | m2 | map.cpp:133:5:133:5 | call to operator= | TAINT |
+| map.cpp:134:7:134:8 | m7 | map.cpp:134:7:134:8 | call to map | |
+| map.cpp:135:7:135:8 | m8 | map.cpp:135:7:135:8 | call to map | |
+| map.cpp:136:7:136:8 | m9 | map.cpp:136:7:136:8 | call to map | |
+| map.cpp:137:7:137:8 | ref arg m7 | map.cpp:249:1:249:1 | m7 | |
+| map.cpp:138:7:138:8 | ref arg m8 | map.cpp:249:1:249:1 | m8 | |
+| map.cpp:139:7:139:8 | ref arg m9 | map.cpp:249:1:249:1 | m9 | |
+| map.cpp:143:12:143:13 | ref arg m1 | map.cpp:143:30:143:31 | m1 | |
+| map.cpp:143:12:143:13 | ref arg m1 | map.cpp:249:1:249:1 | m1 | |
+| map.cpp:143:15:143:19 | call to begin | map.cpp:143:7:143:21 | ... = ... | |
+| map.cpp:143:15:143:19 | call to begin | map.cpp:143:24:143:25 | i1 | |
+| map.cpp:143:15:143:19 | call to begin | map.cpp:143:40:143:41 | i1 | |
+| map.cpp:143:15:143:19 | call to begin | map.cpp:145:9:145:10 | i1 | |
+| map.cpp:143:15:143:19 | call to begin | map.cpp:146:8:146:9 | i1 | |
+| map.cpp:143:15:143:19 | call to begin | map.cpp:147:8:147:9 | i1 | |
+| map.cpp:143:30:143:31 | ref arg m1 | map.cpp:143:30:143:31 | m1 | |
+| map.cpp:143:30:143:31 | ref arg m1 | map.cpp:249:1:249:1 | m1 | |
+| map.cpp:143:40:143:41 | i1 | map.cpp:143:42:143:42 | call to operator++ | |
+| map.cpp:143:40:143:41 | ref arg i1 | map.cpp:143:24:143:25 | i1 | |
+| map.cpp:143:40:143:41 | ref arg i1 | map.cpp:143:40:143:41 | i1 | |
+| map.cpp:143:40:143:41 | ref arg i1 | map.cpp:145:9:145:10 | i1 | |
+| map.cpp:143:40:143:41 | ref arg i1 | map.cpp:146:8:146:9 | i1 | |
+| map.cpp:143:40:143:41 | ref arg i1 | map.cpp:147:8:147:9 | i1 | |
+| map.cpp:145:8:145:8 | call to operator* | map.cpp:145:8:145:10 | call to pair | TAINT |
+| map.cpp:145:9:145:10 | i1 | map.cpp:145:8:145:8 | call to operator* | TAINT |
+| map.cpp:146:8:146:9 | i1 | map.cpp:146:10:146:10 | call to operator-> | TAINT |
+| map.cpp:147:8:147:9 | i1 | map.cpp:147:10:147:10 | call to operator-> | TAINT |
+| map.cpp:149:12:149:13 | ref arg m2 | map.cpp:149:30:149:31 | m2 | |
+| map.cpp:149:12:149:13 | ref arg m2 | map.cpp:179:7:179:8 | m2 | |
+| map.cpp:149:12:149:13 | ref arg m2 | map.cpp:180:7:180:8 | m2 | |
+| map.cpp:149:12:149:13 | ref arg m2 | map.cpp:181:7:181:8 | m2 | |
+| map.cpp:149:12:149:13 | ref arg m2 | map.cpp:182:7:182:8 | m2 | |
+| map.cpp:149:12:149:13 | ref arg m2 | map.cpp:183:7:183:8 | m2 | |
+| map.cpp:149:12:149:13 | ref arg m2 | map.cpp:184:7:184:8 | m2 | |
+| map.cpp:149:12:149:13 | ref arg m2 | map.cpp:249:1:249:1 | m2 | |
+| map.cpp:149:15:149:19 | call to begin | map.cpp:149:7:149:21 | ... = ... | |
+| map.cpp:149:15:149:19 | call to begin | map.cpp:149:24:149:25 | i2 | |
+| map.cpp:149:15:149:19 | call to begin | map.cpp:149:40:149:41 | i2 | |
+| map.cpp:149:15:149:19 | call to begin | map.cpp:151:9:151:10 | i2 | |
+| map.cpp:149:15:149:19 | call to begin | map.cpp:152:8:152:9 | i2 | |
+| map.cpp:149:15:149:19 | call to begin | map.cpp:153:8:153:9 | i2 | |
+| map.cpp:149:15:149:19 | call to begin | map.cpp:158:8:158:9 | i2 | |
+| map.cpp:149:15:149:19 | call to begin | map.cpp:159:8:159:9 | i2 | |
+| map.cpp:149:30:149:31 | ref arg m2 | map.cpp:149:30:149:31 | m2 | |
+| map.cpp:149:30:149:31 | ref arg m2 | map.cpp:179:7:179:8 | m2 | |
+| map.cpp:149:30:149:31 | ref arg m2 | map.cpp:180:7:180:8 | m2 | |
+| map.cpp:149:30:149:31 | ref arg m2 | map.cpp:181:7:181:8 | m2 | |
+| map.cpp:149:30:149:31 | ref arg m2 | map.cpp:182:7:182:8 | m2 | |
+| map.cpp:149:30:149:31 | ref arg m2 | map.cpp:183:7:183:8 | m2 | |
+| map.cpp:149:30:149:31 | ref arg m2 | map.cpp:184:7:184:8 | m2 | |
+| map.cpp:149:30:149:31 | ref arg m2 | map.cpp:249:1:249:1 | m2 | |
+| map.cpp:149:40:149:41 | i2 | map.cpp:149:42:149:42 | call to operator++ | |
+| map.cpp:149:40:149:41 | ref arg i2 | map.cpp:149:24:149:25 | i2 | |
+| map.cpp:149:40:149:41 | ref arg i2 | map.cpp:149:40:149:41 | i2 | |
+| map.cpp:149:40:149:41 | ref arg i2 | map.cpp:151:9:151:10 | i2 | |
+| map.cpp:149:40:149:41 | ref arg i2 | map.cpp:152:8:152:9 | i2 | |
+| map.cpp:149:40:149:41 | ref arg i2 | map.cpp:153:8:153:9 | i2 | |
+| map.cpp:149:40:149:41 | ref arg i2 | map.cpp:158:8:158:9 | i2 | |
+| map.cpp:149:40:149:41 | ref arg i2 | map.cpp:159:8:159:9 | i2 | |
+| map.cpp:151:8:151:8 | call to operator* | map.cpp:151:8:151:10 | call to pair | TAINT |
+| map.cpp:151:9:151:10 | i2 | map.cpp:151:8:151:8 | call to operator* | TAINT |
+| map.cpp:152:8:152:9 | i2 | map.cpp:152:10:152:10 | call to operator-> | TAINT |
+| map.cpp:153:8:153:9 | i2 | map.cpp:153:10:153:10 | call to operator-> | TAINT |
+| map.cpp:155:12:155:13 | ref arg m3 | map.cpp:155:30:155:31 | m3 | |
+| map.cpp:155:12:155:13 | ref arg m3 | map.cpp:249:1:249:1 | m3 | |
+| map.cpp:155:15:155:19 | call to begin | map.cpp:155:7:155:21 | ... = ... | |
+| map.cpp:155:15:155:19 | call to begin | map.cpp:155:24:155:25 | i3 | |
+| map.cpp:155:15:155:19 | call to begin | map.cpp:155:40:155:41 | i3 | |
+| map.cpp:155:15:155:19 | call to begin | map.cpp:157:9:157:10 | i3 | |
+| map.cpp:155:30:155:31 | ref arg m3 | map.cpp:155:30:155:31 | m3 | |
+| map.cpp:155:30:155:31 | ref arg m3 | map.cpp:249:1:249:1 | m3 | |
+| map.cpp:155:40:155:41 | i3 | map.cpp:155:42:155:42 | call to operator++ | |
+| map.cpp:155:40:155:41 | ref arg i3 | map.cpp:155:24:155:25 | i3 | |
+| map.cpp:155:40:155:41 | ref arg i3 | map.cpp:155:40:155:41 | i3 | |
+| map.cpp:155:40:155:41 | ref arg i3 | map.cpp:157:9:157:10 | i3 | |
+| map.cpp:157:8:157:8 | call to operator* | map.cpp:157:8:157:10 | call to pair | TAINT |
+| map.cpp:157:9:157:10 | i3 | map.cpp:157:8:157:8 | call to operator* | TAINT |
+| map.cpp:158:8:158:9 | i2 | map.cpp:158:10:158:10 | call to operator-> | TAINT |
+| map.cpp:159:8:159:9 | i2 | map.cpp:159:10:159:10 | call to operator-> | TAINT |
+| map.cpp:163:27:163:29 | call to map | map.cpp:164:7:164:9 | m10 | |
+| map.cpp:163:27:163:29 | call to map | map.cpp:168:7:168:9 | m10 | |
+| map.cpp:163:27:163:29 | call to map | map.cpp:249:1:249:1 | m10 | |
+| map.cpp:163:32:163:34 | call to map | map.cpp:165:7:165:9 | m11 | |
+| map.cpp:163:32:163:34 | call to map | map.cpp:169:7:169:9 | m11 | |
+| map.cpp:163:32:163:34 | call to map | map.cpp:249:1:249:1 | m11 | |
+| map.cpp:163:37:163:39 | call to map | map.cpp:166:7:166:9 | m12 | |
+| map.cpp:163:37:163:39 | call to map | map.cpp:170:7:170:9 | m12 | |
+| map.cpp:163:37:163:39 | call to map | map.cpp:249:1:249:1 | m12 | |
+| map.cpp:163:42:163:44 | call to map | map.cpp:167:7:167:9 | m13 | |
+| map.cpp:163:42:163:44 | call to map | map.cpp:171:7:171:9 | m13 | |
+| map.cpp:163:42:163:44 | call to map | map.cpp:249:1:249:1 | m13 | |
+| map.cpp:164:7:164:9 | ref arg m10 | map.cpp:168:7:168:9 | m10 | |
+| map.cpp:164:7:164:9 | ref arg m10 | map.cpp:249:1:249:1 | m10 | |
+| map.cpp:164:7:164:24 | ... = ... | map.cpp:164:10:164:10 | call to operator[] [post update] | |
+| map.cpp:164:20:164:24 | def | map.cpp:164:7:164:24 | ... = ... | |
+| map.cpp:165:7:165:9 | ref arg m11 | map.cpp:169:7:169:9 | m11 | |
+| map.cpp:165:7:165:9 | ref arg m11 | map.cpp:249:1:249:1 | m11 | |
+| map.cpp:165:7:165:27 | ... = ... | map.cpp:165:10:165:10 | call to operator[] [post update] | |
+| map.cpp:165:20:165:25 | call to source | map.cpp:165:7:165:27 | ... = ... | |
+| map.cpp:166:7:166:9 | ref arg m12 | map.cpp:170:7:170:9 | m12 | |
+| map.cpp:166:7:166:9 | ref arg m12 | map.cpp:249:1:249:1 | m12 | |
+| map.cpp:166:7:166:27 | ... = ... | map.cpp:166:11:166:12 | call to at [post update] | |
+| map.cpp:166:23:166:27 | def | map.cpp:166:7:166:27 | ... = ... | |
+| map.cpp:167:7:167:9 | ref arg m13 | map.cpp:171:7:171:9 | m13 | |
+| map.cpp:167:7:167:9 | ref arg m13 | map.cpp:249:1:249:1 | m13 | |
+| map.cpp:167:7:167:30 | ... = ... | map.cpp:167:11:167:12 | call to at [post update] | |
+| map.cpp:167:23:167:28 | call to source | map.cpp:167:7:167:30 | ... = ... | |
+| map.cpp:168:7:168:9 | ref arg m10 | map.cpp:249:1:249:1 | m10 | |
+| map.cpp:169:7:169:9 | ref arg m11 | map.cpp:249:1:249:1 | m11 | |
+| map.cpp:170:7:170:9 | ref arg m12 | map.cpp:249:1:249:1 | m12 | |
+| map.cpp:171:7:171:9 | ref arg m13 | map.cpp:249:1:249:1 | m13 | |
+| map.cpp:174:27:174:29 | call to map | map.cpp:175:2:175:4 | m14 | |
+| map.cpp:174:27:174:29 | call to map | map.cpp:176:2:176:4 | m14 | |
+| map.cpp:174:27:174:29 | call to map | map.cpp:177:2:177:4 | m14 | |
+| map.cpp:174:27:174:29 | call to map | map.cpp:178:2:178:4 | m14 | |
+| map.cpp:174:27:174:29 | call to map | map.cpp:249:1:249:1 | m14 | |
+| map.cpp:175:2:175:4 | ref arg m14 | map.cpp:176:2:176:4 | m14 | |
+| map.cpp:175:2:175:4 | ref arg m14 | map.cpp:177:2:177:4 | m14 | |
+| map.cpp:175:2:175:4 | ref arg m14 | map.cpp:178:2:178:4 | m14 | |
+| map.cpp:175:2:175:4 | ref arg m14 | map.cpp:249:1:249:1 | m14 | |
+| map.cpp:175:13:175:26 | call to make_pair | map.cpp:175:13:175:36 | call to pair | TAINT |
+| map.cpp:176:2:176:4 | ref arg m14 | map.cpp:177:2:177:4 | m14 | |
+| map.cpp:176:2:176:4 | ref arg m14 | map.cpp:178:2:178:4 | m14 | |
+| map.cpp:176:2:176:4 | ref arg m14 | map.cpp:249:1:249:1 | m14 | |
+| map.cpp:176:13:176:26 | call to make_pair | map.cpp:176:13:176:41 | call to pair | TAINT |
+| map.cpp:177:2:177:4 | ref arg m14 | map.cpp:178:2:178:4 | m14 | |
+| map.cpp:177:2:177:4 | ref arg m14 | map.cpp:249:1:249:1 | m14 | |
+| map.cpp:177:13:177:26 | call to make_pair | map.cpp:177:13:177:41 | call to pair | TAINT |
+| map.cpp:178:2:178:4 | ref arg m14 | map.cpp:249:1:249:1 | m14 | |
+| map.cpp:178:13:178:26 | call to make_pair | map.cpp:178:13:178:36 | call to pair | TAINT |
+| map.cpp:179:7:179:8 | ref arg m2 | map.cpp:180:7:180:8 | m2 | |
+| map.cpp:179:7:179:8 | ref arg m2 | map.cpp:181:7:181:8 | m2 | |
+| map.cpp:179:7:179:8 | ref arg m2 | map.cpp:182:7:182:8 | m2 | |
+| map.cpp:179:7:179:8 | ref arg m2 | map.cpp:183:7:183:8 | m2 | |
+| map.cpp:179:7:179:8 | ref arg m2 | map.cpp:184:7:184:8 | m2 | |
+| map.cpp:179:7:179:8 | ref arg m2 | map.cpp:249:1:249:1 | m2 | |
+| map.cpp:180:7:180:8 | ref arg m2 | map.cpp:181:7:181:8 | m2 | |
+| map.cpp:180:7:180:8 | ref arg m2 | map.cpp:182:7:182:8 | m2 | |
+| map.cpp:180:7:180:8 | ref arg m2 | map.cpp:183:7:183:8 | m2 | |
+| map.cpp:180:7:180:8 | ref arg m2 | map.cpp:184:7:184:8 | m2 | |
+| map.cpp:180:7:180:8 | ref arg m2 | map.cpp:249:1:249:1 | m2 | |
+| map.cpp:181:7:181:8 | ref arg m2 | map.cpp:182:7:182:8 | m2 | |
+| map.cpp:181:7:181:8 | ref arg m2 | map.cpp:183:7:183:8 | m2 | |
+| map.cpp:181:7:181:8 | ref arg m2 | map.cpp:184:7:184:8 | m2 | |
+| map.cpp:181:7:181:8 | ref arg m2 | map.cpp:249:1:249:1 | m2 | |
+| map.cpp:181:27:181:31 | first | map.cpp:181:7:181:31 | call to iterator | |
+| map.cpp:182:7:182:8 | ref arg m2 | map.cpp:183:7:183:8 | m2 | |
+| map.cpp:182:7:182:8 | ref arg m2 | map.cpp:184:7:184:8 | m2 | |
+| map.cpp:182:7:182:8 | ref arg m2 | map.cpp:249:1:249:1 | m2 | |
+| map.cpp:182:27:182:32 | second | map.cpp:182:7:182:32 | call to iterator | |
+| map.cpp:183:7:183:8 | ref arg m2 | map.cpp:184:7:184:8 | m2 | |
+| map.cpp:183:7:183:8 | ref arg m2 | map.cpp:249:1:249:1 | m2 | |
+| map.cpp:184:7:184:8 | ref arg m2 | map.cpp:249:1:249:1 | m2 | |
+| map.cpp:184:27:184:32 | second | map.cpp:184:7:184:32 | call to iterator | |
+| map.cpp:187:27:187:29 | call to map | map.cpp:188:2:188:4 | m15 | |
+| map.cpp:187:27:187:29 | call to map | map.cpp:190:7:190:9 | m15 | |
+| map.cpp:187:27:187:29 | call to map | map.cpp:194:2:194:4 | m15 | |
+| map.cpp:187:27:187:29 | call to map | map.cpp:196:7:196:9 | m15 | |
+| map.cpp:187:27:187:29 | call to map | map.cpp:211:2:211:4 | m15 | |
+| map.cpp:187:27:187:29 | call to map | map.cpp:249:1:249:1 | m15 | |
+| map.cpp:187:32:187:34 | call to map | map.cpp:191:7:191:9 | m16 | |
+| map.cpp:187:32:187:34 | call to map | map.cpp:194:11:194:13 | m16 | |
+| map.cpp:187:32:187:34 | call to map | map.cpp:197:7:197:9 | m16 | |
+| map.cpp:187:32:187:34 | call to map | map.cpp:211:12:211:14 | m16 | |
+| map.cpp:187:32:187:34 | call to map | map.cpp:249:1:249:1 | m16 | |
+| map.cpp:187:37:187:39 | call to map | map.cpp:192:7:192:9 | m17 | |
+| map.cpp:187:37:187:39 | call to map | map.cpp:195:2:195:4 | m17 | |
+| map.cpp:187:37:187:39 | call to map | map.cpp:198:7:198:9 | m17 | |
+| map.cpp:187:37:187:39 | call to map | map.cpp:212:2:212:4 | m17 | |
+| map.cpp:187:37:187:39 | call to map | map.cpp:249:1:249:1 | m17 | |
+| map.cpp:187:42:187:44 | call to map | map.cpp:189:2:189:4 | m18 | |
+| map.cpp:187:42:187:44 | call to map | map.cpp:193:7:193:9 | m18 | |
+| map.cpp:187:42:187:44 | call to map | map.cpp:195:11:195:13 | m18 | |
+| map.cpp:187:42:187:44 | call to map | map.cpp:199:7:199:9 | m18 | |
+| map.cpp:187:42:187:44 | call to map | map.cpp:212:12:212:14 | m18 | |
+| map.cpp:187:42:187:44 | call to map | map.cpp:249:1:249:1 | m18 | |
+| map.cpp:188:2:188:4 | ref arg m15 | map.cpp:190:7:190:9 | m15 | |
+| map.cpp:188:2:188:4 | ref arg m15 | map.cpp:194:2:194:4 | m15 | |
+| map.cpp:188:2:188:4 | ref arg m15 | map.cpp:196:7:196:9 | m15 | |
+| map.cpp:188:2:188:4 | ref arg m15 | map.cpp:211:2:211:4 | m15 | |
+| map.cpp:188:2:188:4 | ref arg m15 | map.cpp:249:1:249:1 | m15 | |
+| map.cpp:188:13:188:57 | call to pair | map.cpp:188:13:188:57 | call to pair | TAINT |
+| map.cpp:189:2:189:4 | ref arg m18 | map.cpp:193:7:193:9 | m18 | |
+| map.cpp:189:2:189:4 | ref arg m18 | map.cpp:195:11:195:13 | m18 | |
+| map.cpp:189:2:189:4 | ref arg m18 | map.cpp:199:7:199:9 | m18 | |
+| map.cpp:189:2:189:4 | ref arg m18 | map.cpp:212:12:212:14 | m18 | |
+| map.cpp:189:2:189:4 | ref arg m18 | map.cpp:249:1:249:1 | m18 | |
+| map.cpp:189:13:189:57 | call to pair | map.cpp:189:13:189:57 | call to pair | TAINT |
+| map.cpp:190:7:190:9 | m15 | map.cpp:190:7:190:9 | call to map | |
+| map.cpp:191:7:191:9 | m16 | map.cpp:191:7:191:9 | call to map | |
+| map.cpp:192:7:192:9 | m17 | map.cpp:192:7:192:9 | call to map | |
+| map.cpp:193:7:193:9 | m18 | map.cpp:193:7:193:9 | call to map | |
+| map.cpp:194:2:194:4 | ref arg m15 | map.cpp:196:7:196:9 | m15 | |
+| map.cpp:194:2:194:4 | ref arg m15 | map.cpp:211:2:211:4 | m15 | |
+| map.cpp:194:2:194:4 | ref arg m15 | map.cpp:249:1:249:1 | m15 | |
+| map.cpp:194:11:194:13 | ref arg m16 | map.cpp:197:7:197:9 | m16 | |
+| map.cpp:194:11:194:13 | ref arg m16 | map.cpp:211:12:211:14 | m16 | |
+| map.cpp:194:11:194:13 | ref arg m16 | map.cpp:249:1:249:1 | m16 | |
+| map.cpp:195:2:195:4 | ref arg m17 | map.cpp:198:7:198:9 | m17 | |
+| map.cpp:195:2:195:4 | ref arg m17 | map.cpp:212:2:212:4 | m17 | |
+| map.cpp:195:2:195:4 | ref arg m17 | map.cpp:249:1:249:1 | m17 | |
+| map.cpp:195:11:195:13 | ref arg m18 | map.cpp:199:7:199:9 | m18 | |
+| map.cpp:195:11:195:13 | ref arg m18 | map.cpp:212:12:212:14 | m18 | |
+| map.cpp:195:11:195:13 | ref arg m18 | map.cpp:249:1:249:1 | m18 | |
+| map.cpp:196:7:196:9 | m15 | map.cpp:196:7:196:9 | call to map | |
+| map.cpp:197:7:197:9 | m16 | map.cpp:197:7:197:9 | call to map | |
+| map.cpp:198:7:198:9 | m17 | map.cpp:198:7:198:9 | call to map | |
+| map.cpp:199:7:199:9 | m18 | map.cpp:199:7:199:9 | call to map | |
+| map.cpp:202:27:202:29 | call to map | map.cpp:203:2:203:4 | m19 | |
+| map.cpp:202:27:202:29 | call to map | map.cpp:207:7:207:9 | m19 | |
+| map.cpp:202:27:202:29 | call to map | map.cpp:213:7:213:9 | m19 | |
+| map.cpp:202:27:202:29 | call to map | map.cpp:249:1:249:1 | m19 | |
+| map.cpp:202:32:202:34 | call to map | map.cpp:204:2:204:4 | m20 | |
+| map.cpp:202:32:202:34 | call to map | map.cpp:208:7:208:9 | m20 | |
+| map.cpp:202:32:202:34 | call to map | map.cpp:214:7:214:9 | m20 | |
+| map.cpp:202:32:202:34 | call to map | map.cpp:249:1:249:1 | m20 | |
+| map.cpp:202:37:202:39 | call to map | map.cpp:205:2:205:4 | m21 | |
+| map.cpp:202:37:202:39 | call to map | map.cpp:209:7:209:9 | m21 | |
+| map.cpp:202:37:202:39 | call to map | map.cpp:215:7:215:9 | m21 | |
+| map.cpp:202:37:202:39 | call to map | map.cpp:249:1:249:1 | m21 | |
+| map.cpp:202:42:202:44 | call to map | map.cpp:206:2:206:4 | m22 | |
+| map.cpp:202:42:202:44 | call to map | map.cpp:210:7:210:9 | m22 | |
+| map.cpp:202:42:202:44 | call to map | map.cpp:216:7:216:9 | m22 | |
+| map.cpp:202:42:202:44 | call to map | map.cpp:249:1:249:1 | m22 | |
+| map.cpp:203:2:203:4 | ref arg m19 | map.cpp:207:7:207:9 | m19 | |
+| map.cpp:203:2:203:4 | ref arg m19 | map.cpp:213:7:213:9 | m19 | |
+| map.cpp:203:2:203:4 | ref arg m19 | map.cpp:249:1:249:1 | m19 | |
+| map.cpp:203:13:203:57 | call to pair | map.cpp:203:13:203:57 | call to pair | TAINT |
+| map.cpp:204:2:204:4 | ref arg m20 | map.cpp:208:7:208:9 | m20 | |
+| map.cpp:204:2:204:4 | ref arg m20 | map.cpp:214:7:214:9 | m20 | |
+| map.cpp:204:2:204:4 | ref arg m20 | map.cpp:249:1:249:1 | m20 | |
+| map.cpp:204:13:204:51 | call to pair | map.cpp:204:13:204:51 | call to pair | TAINT |
+| map.cpp:205:2:205:4 | ref arg m21 | map.cpp:209:7:209:9 | m21 | |
+| map.cpp:205:2:205:4 | ref arg m21 | map.cpp:215:7:215:9 | m21 | |
+| map.cpp:205:2:205:4 | ref arg m21 | map.cpp:249:1:249:1 | m21 | |
+| map.cpp:205:13:205:51 | call to pair | map.cpp:205:13:205:51 | call to pair | TAINT |
+| map.cpp:206:2:206:4 | ref arg m22 | map.cpp:210:7:210:9 | m22 | |
+| map.cpp:206:2:206:4 | ref arg m22 | map.cpp:216:7:216:9 | m22 | |
+| map.cpp:206:2:206:4 | ref arg m22 | map.cpp:249:1:249:1 | m22 | |
+| map.cpp:206:13:206:57 | call to pair | map.cpp:206:13:206:57 | call to pair | TAINT |
+| map.cpp:207:7:207:9 | m19 | map.cpp:207:7:207:9 | call to map | |
+| map.cpp:208:7:208:9 | m20 | map.cpp:208:7:208:9 | call to map | |
+| map.cpp:209:7:209:9 | m21 | map.cpp:209:7:209:9 | call to map | |
+| map.cpp:210:7:210:9 | m22 | map.cpp:210:7:210:9 | call to map | |
+| map.cpp:211:2:211:4 | ref arg m15 | map.cpp:249:1:249:1 | m15 | |
+| map.cpp:211:12:211:14 | ref arg m16 | map.cpp:249:1:249:1 | m16 | |
+| map.cpp:212:2:212:4 | ref arg m17 | map.cpp:249:1:249:1 | m17 | |
+| map.cpp:212:12:212:14 | ref arg m18 | map.cpp:249:1:249:1 | m18 | |
+| map.cpp:213:7:213:9 | m19 | map.cpp:213:7:213:9 | call to map | |
+| map.cpp:214:7:214:9 | m20 | map.cpp:214:7:214:9 | call to map | |
+| map.cpp:215:7:215:9 | m21 | map.cpp:215:7:215:9 | call to map | |
+| map.cpp:216:7:216:9 | m22 | map.cpp:216:7:216:9 | call to map | |
+| map.cpp:219:27:219:29 | call to map | map.cpp:220:2:220:4 | m23 | |
+| map.cpp:219:27:219:29 | call to map | map.cpp:221:2:221:4 | m23 | |
+| map.cpp:219:27:219:29 | call to map | map.cpp:222:7:222:9 | m23 | |
+| map.cpp:219:27:219:29 | call to map | map.cpp:223:7:223:9 | m23 | |
+| map.cpp:219:27:219:29 | call to map | map.cpp:223:17:223:19 | m23 | |
+| map.cpp:219:27:219:29 | call to map | map.cpp:224:7:224:9 | m23 | |
+| map.cpp:219:27:219:29 | call to map | map.cpp:225:2:225:4 | m23 | |
+| map.cpp:219:27:219:29 | call to map | map.cpp:226:7:226:9 | m23 | |
+| map.cpp:219:27:219:29 | call to map | map.cpp:249:1:249:1 | m23 | |
+| map.cpp:220:2:220:4 | ref arg m23 | map.cpp:221:2:221:4 | m23 | |
+| map.cpp:220:2:220:4 | ref arg m23 | map.cpp:222:7:222:9 | m23 | |
+| map.cpp:220:2:220:4 | ref arg m23 | map.cpp:223:7:223:9 | m23 | |
+| map.cpp:220:2:220:4 | ref arg m23 | map.cpp:223:17:223:19 | m23 | |
+| map.cpp:220:2:220:4 | ref arg m23 | map.cpp:224:7:224:9 | m23 | |
+| map.cpp:220:2:220:4 | ref arg m23 | map.cpp:225:2:225:4 | m23 | |
+| map.cpp:220:2:220:4 | ref arg m23 | map.cpp:226:7:226:9 | m23 | |
+| map.cpp:220:2:220:4 | ref arg m23 | map.cpp:249:1:249:1 | m23 | |
+| map.cpp:220:13:220:57 | call to pair | map.cpp:220:13:220:57 | call to pair | TAINT |
+| map.cpp:221:2:221:4 | ref arg m23 | map.cpp:222:7:222:9 | m23 | |
+| map.cpp:221:2:221:4 | ref arg m23 | map.cpp:223:7:223:9 | m23 | |
+| map.cpp:221:2:221:4 | ref arg m23 | map.cpp:223:17:223:19 | m23 | |
+| map.cpp:221:2:221:4 | ref arg m23 | map.cpp:224:7:224:9 | m23 | |
+| map.cpp:221:2:221:4 | ref arg m23 | map.cpp:225:2:225:4 | m23 | |
+| map.cpp:221:2:221:4 | ref arg m23 | map.cpp:226:7:226:9 | m23 | |
+| map.cpp:221:2:221:4 | ref arg m23 | map.cpp:249:1:249:1 | m23 | |
+| map.cpp:221:13:221:57 | call to pair | map.cpp:221:13:221:57 | call to pair | TAINT |
+| map.cpp:222:7:222:9 | m23 | map.cpp:222:7:222:9 | call to map | |
+| map.cpp:223:7:223:9 | ref arg m23 | map.cpp:224:7:224:9 | m23 | |
+| map.cpp:223:7:223:9 | ref arg m23 | map.cpp:225:2:225:4 | m23 | |
+| map.cpp:223:7:223:9 | ref arg m23 | map.cpp:226:7:226:9 | m23 | |
+| map.cpp:223:7:223:9 | ref arg m23 | map.cpp:249:1:249:1 | m23 | |
+| map.cpp:223:17:223:19 | ref arg m23 | map.cpp:223:7:223:9 | m23 | |
+| map.cpp:223:17:223:19 | ref arg m23 | map.cpp:224:7:224:9 | m23 | |
+| map.cpp:223:17:223:19 | ref arg m23 | map.cpp:225:2:225:4 | m23 | |
+| map.cpp:223:17:223:19 | ref arg m23 | map.cpp:226:7:226:9 | m23 | |
+| map.cpp:223:17:223:19 | ref arg m23 | map.cpp:249:1:249:1 | m23 | |
+| map.cpp:224:7:224:9 | m23 | map.cpp:224:7:224:9 | call to map | |
+| map.cpp:225:2:225:4 | ref arg m23 | map.cpp:226:7:226:9 | m23 | |
+| map.cpp:225:2:225:4 | ref arg m23 | map.cpp:249:1:249:1 | m23 | |
+| map.cpp:226:7:226:9 | m23 | map.cpp:226:7:226:9 | call to map | |
+| map.cpp:229:27:229:29 | call to map | map.cpp:230:7:230:9 | m24 | |
+| map.cpp:229:27:229:29 | call to map | map.cpp:231:7:231:9 | m24 | |
+| map.cpp:229:27:229:29 | call to map | map.cpp:232:7:232:9 | m24 | |
+| map.cpp:229:27:229:29 | call to map | map.cpp:233:7:233:9 | m24 | |
+| map.cpp:229:27:229:29 | call to map | map.cpp:249:1:249:1 | m24 | |
+| map.cpp:229:32:229:34 | call to map | map.cpp:234:7:234:9 | m25 | |
+| map.cpp:229:32:229:34 | call to map | map.cpp:234:24:234:26 | m25 | |
+| map.cpp:229:32:229:34 | call to map | map.cpp:235:7:235:9 | m25 | |
+| map.cpp:229:32:229:34 | call to map | map.cpp:236:7:236:9 | m25 | |
+| map.cpp:229:32:229:34 | call to map | map.cpp:236:24:236:26 | m25 | |
+| map.cpp:229:32:229:34 | call to map | map.cpp:237:7:237:9 | m25 | |
+| map.cpp:229:32:229:34 | call to map | map.cpp:249:1:249:1 | m25 | |
+| map.cpp:230:7:230:9 | ref arg m24 | map.cpp:231:7:231:9 | m24 | |
+| map.cpp:230:7:230:9 | ref arg m24 | map.cpp:232:7:232:9 | m24 | |
+| map.cpp:230:7:230:9 | ref arg m24 | map.cpp:233:7:233:9 | m24 | |
+| map.cpp:230:7:230:9 | ref arg m24 | map.cpp:249:1:249:1 | m24 | |
+| map.cpp:230:33:230:37 | first | map.cpp:230:7:230:37 | call to iterator | |
+| map.cpp:231:7:231:9 | m24 | map.cpp:231:7:231:9 | call to map | |
+| map.cpp:232:7:232:9 | ref arg m24 | map.cpp:233:7:233:9 | m24 | |
+| map.cpp:232:7:232:9 | ref arg m24 | map.cpp:249:1:249:1 | m24 | |
+| map.cpp:232:36:232:40 | first | map.cpp:232:7:232:40 | call to iterator | |
+| map.cpp:233:7:233:9 | m24 | map.cpp:233:7:233:9 | call to map | |
+| map.cpp:234:7:234:9 | ref arg m25 | map.cpp:235:7:235:9 | m25 | |
+| map.cpp:234:7:234:9 | ref arg m25 | map.cpp:236:7:236:9 | m25 | |
+| map.cpp:234:7:234:9 | ref arg m25 | map.cpp:236:24:236:26 | m25 | |
+| map.cpp:234:7:234:9 | ref arg m25 | map.cpp:237:7:237:9 | m25 | |
+| map.cpp:234:7:234:9 | ref arg m25 | map.cpp:249:1:249:1 | m25 | |
+| map.cpp:234:24:234:26 | ref arg m25 | map.cpp:234:7:234:9 | m25 | |
+| map.cpp:234:24:234:26 | ref arg m25 | map.cpp:235:7:235:9 | m25 | |
+| map.cpp:234:24:234:26 | ref arg m25 | map.cpp:236:7:236:9 | m25 | |
+| map.cpp:234:24:234:26 | ref arg m25 | map.cpp:236:24:236:26 | m25 | |
+| map.cpp:234:24:234:26 | ref arg m25 | map.cpp:237:7:237:9 | m25 | |
+| map.cpp:234:24:234:26 | ref arg m25 | map.cpp:249:1:249:1 | m25 | |
+| map.cpp:234:28:234:32 | call to begin | map.cpp:234:24:234:34 | call to iterator | TAINT |
+| map.cpp:235:7:235:9 | m25 | map.cpp:235:7:235:9 | call to map | |
+| map.cpp:236:7:236:9 | ref arg m25 | map.cpp:237:7:237:9 | m25 | |
+| map.cpp:236:7:236:9 | ref arg m25 | map.cpp:249:1:249:1 | m25 | |
+| map.cpp:236:24:236:26 | ref arg m25 | map.cpp:236:7:236:9 | m25 | |
+| map.cpp:236:24:236:26 | ref arg m25 | map.cpp:237:7:237:9 | m25 | |
+| map.cpp:236:24:236:26 | ref arg m25 | map.cpp:249:1:249:1 | m25 | |
+| map.cpp:236:28:236:32 | call to begin | map.cpp:236:24:236:34 | call to iterator | TAINT |
+| map.cpp:237:7:237:9 | m25 | map.cpp:237:7:237:9 | call to map | |
+| map.cpp:240:27:240:29 | call to map | map.cpp:241:7:241:9 | m26 | |
+| map.cpp:240:27:240:29 | call to map | map.cpp:242:7:242:9 | m26 | |
+| map.cpp:240:27:240:29 | call to map | map.cpp:243:7:243:9 | m26 | |
+| map.cpp:240:27:240:29 | call to map | map.cpp:244:7:244:9 | m26 | |
+| map.cpp:240:27:240:29 | call to map | map.cpp:249:1:249:1 | m26 | |
+| map.cpp:240:32:240:34 | call to map | map.cpp:245:7:245:9 | m27 | |
+| map.cpp:240:32:240:34 | call to map | map.cpp:245:23:245:25 | m27 | |
+| map.cpp:240:32:240:34 | call to map | map.cpp:246:7:246:9 | m27 | |
+| map.cpp:240:32:240:34 | call to map | map.cpp:247:7:247:9 | m27 | |
+| map.cpp:240:32:240:34 | call to map | map.cpp:247:23:247:25 | m27 | |
+| map.cpp:240:32:240:34 | call to map | map.cpp:248:7:248:9 | m27 | |
+| map.cpp:240:32:240:34 | call to map | map.cpp:249:1:249:1 | m27 | |
+| map.cpp:241:7:241:9 | ref arg m26 | map.cpp:242:7:242:9 | m26 | |
+| map.cpp:241:7:241:9 | ref arg m26 | map.cpp:243:7:243:9 | m26 | |
+| map.cpp:241:7:241:9 | ref arg m26 | map.cpp:244:7:244:9 | m26 | |
+| map.cpp:241:7:241:9 | ref arg m26 | map.cpp:249:1:249:1 | m26 | |
+| map.cpp:241:37:241:41 | first | map.cpp:241:7:241:41 | call to iterator | |
+| map.cpp:242:7:242:9 | m26 | map.cpp:242:7:242:9 | call to map | |
+| map.cpp:243:7:243:9 | ref arg m26 | map.cpp:244:7:244:9 | m26 | |
+| map.cpp:243:7:243:9 | ref arg m26 | map.cpp:249:1:249:1 | m26 | |
+| map.cpp:243:40:243:44 | first | map.cpp:243:7:243:44 | call to iterator | |
+| map.cpp:244:7:244:9 | m26 | map.cpp:244:7:244:9 | call to map | |
+| map.cpp:245:7:245:9 | ref arg m27 | map.cpp:246:7:246:9 | m27 | |
+| map.cpp:245:7:245:9 | ref arg m27 | map.cpp:247:7:247:9 | m27 | |
+| map.cpp:245:7:245:9 | ref arg m27 | map.cpp:247:23:247:25 | m27 | |
+| map.cpp:245:7:245:9 | ref arg m27 | map.cpp:248:7:248:9 | m27 | |
+| map.cpp:245:7:245:9 | ref arg m27 | map.cpp:249:1:249:1 | m27 | |
+| map.cpp:245:23:245:25 | ref arg m27 | map.cpp:245:7:245:9 | m27 | |
+| map.cpp:245:23:245:25 | ref arg m27 | map.cpp:246:7:246:9 | m27 | |
+| map.cpp:245:23:245:25 | ref arg m27 | map.cpp:247:7:247:9 | m27 | |
+| map.cpp:245:23:245:25 | ref arg m27 | map.cpp:247:23:247:25 | m27 | |
+| map.cpp:245:23:245:25 | ref arg m27 | map.cpp:248:7:248:9 | m27 | |
+| map.cpp:245:23:245:25 | ref arg m27 | map.cpp:249:1:249:1 | m27 | |
+| map.cpp:245:27:245:31 | call to begin | map.cpp:245:23:245:33 | call to iterator | TAINT |
+| map.cpp:246:7:246:9 | m27 | map.cpp:246:7:246:9 | call to map | |
+| map.cpp:247:7:247:9 | ref arg m27 | map.cpp:248:7:248:9 | m27 | |
+| map.cpp:247:7:247:9 | ref arg m27 | map.cpp:249:1:249:1 | m27 | |
+| map.cpp:247:23:247:25 | ref arg m27 | map.cpp:247:7:247:9 | m27 | |
+| map.cpp:247:23:247:25 | ref arg m27 | map.cpp:248:7:248:9 | m27 | |
+| map.cpp:247:23:247:25 | ref arg m27 | map.cpp:249:1:249:1 | m27 | |
+| map.cpp:247:27:247:31 | call to begin | map.cpp:247:23:247:33 | call to iterator | TAINT |
+| map.cpp:248:7:248:9 | m27 | map.cpp:248:7:248:9 | call to map | |
+| map.cpp:254:37:254:38 | call to unordered_map | map.cpp:256:7:256:8 | m1 | |
+| map.cpp:254:37:254:38 | call to unordered_map | map.cpp:262:7:262:8 | m1 | |
+| map.cpp:254:37:254:38 | call to unordered_map | map.cpp:268:7:268:8 | m1 | |
+| map.cpp:254:37:254:38 | call to unordered_map | map.cpp:274:7:274:8 | m1 | |
+| map.cpp:254:37:254:38 | call to unordered_map | map.cpp:295:12:295:13 | m1 | |
+| map.cpp:254:37:254:38 | call to unordered_map | map.cpp:295:30:295:31 | m1 | |
+| map.cpp:254:37:254:38 | call to unordered_map | map.cpp:398:1:398:1 | m1 | |
+| map.cpp:254:41:254:42 | call to unordered_map | map.cpp:257:7:257:8 | m2 | |
+| map.cpp:254:41:254:42 | call to unordered_map | map.cpp:263:7:263:8 | m2 | |
+| map.cpp:254:41:254:42 | call to unordered_map | map.cpp:269:7:269:8 | m2 | |
+| map.cpp:254:41:254:42 | call to unordered_map | map.cpp:275:7:275:8 | m2 | |
+| map.cpp:254:41:254:42 | call to unordered_map | map.cpp:282:40:282:41 | m2 | |
+| map.cpp:254:41:254:42 | call to unordered_map | map.cpp:283:42:283:43 | m2 | |
+| map.cpp:254:41:254:42 | call to unordered_map | map.cpp:285:7:285:8 | m2 | |
+| map.cpp:254:41:254:42 | call to unordered_map | map.cpp:301:12:301:13 | m2 | |
+| map.cpp:254:41:254:42 | call to unordered_map | map.cpp:301:30:301:31 | m2 | |
+| map.cpp:254:41:254:42 | call to unordered_map | map.cpp:331:7:331:8 | m2 | |
+| map.cpp:254:41:254:42 | call to unordered_map | map.cpp:332:7:332:8 | m2 | |
+| map.cpp:254:41:254:42 | call to unordered_map | map.cpp:333:7:333:8 | m2 | |
+| map.cpp:254:41:254:42 | call to unordered_map | map.cpp:398:1:398:1 | m2 | |
+| map.cpp:254:45:254:46 | call to unordered_map | map.cpp:258:7:258:8 | m3 | |
+| map.cpp:254:45:254:46 | call to unordered_map | map.cpp:264:7:264:8 | m3 | |
+| map.cpp:254:45:254:46 | call to unordered_map | map.cpp:270:7:270:8 | m3 | |
+| map.cpp:254:45:254:46 | call to unordered_map | map.cpp:276:7:276:8 | m3 | |
+| map.cpp:254:45:254:46 | call to unordered_map | map.cpp:307:12:307:13 | m3 | |
+| map.cpp:254:45:254:46 | call to unordered_map | map.cpp:307:30:307:31 | m3 | |
+| map.cpp:254:45:254:46 | call to unordered_map | map.cpp:398:1:398:1 | m3 | |
+| map.cpp:254:49:254:50 | call to unordered_map | map.cpp:259:7:259:8 | m4 | |
+| map.cpp:254:49:254:50 | call to unordered_map | map.cpp:259:17:259:18 | m4 | |
+| map.cpp:254:49:254:50 | call to unordered_map | map.cpp:265:7:265:8 | m4 | |
+| map.cpp:254:49:254:50 | call to unordered_map | map.cpp:271:7:271:8 | m4 | |
+| map.cpp:254:49:254:50 | call to unordered_map | map.cpp:277:7:277:8 | m4 | |
+| map.cpp:254:49:254:50 | call to unordered_map | map.cpp:398:1:398:1 | m4 | |
+| map.cpp:254:53:254:54 | call to unordered_map | map.cpp:260:7:260:8 | m5 | |
+| map.cpp:254:53:254:54 | call to unordered_map | map.cpp:266:7:266:8 | m5 | |
+| map.cpp:254:53:254:54 | call to unordered_map | map.cpp:272:7:272:8 | m5 | |
+| map.cpp:254:53:254:54 | call to unordered_map | map.cpp:278:7:278:8 | m5 | |
+| map.cpp:254:53:254:54 | call to unordered_map | map.cpp:398:1:398:1 | m5 | |
+| map.cpp:254:57:254:58 | call to unordered_map | map.cpp:261:7:261:8 | m6 | |
+| map.cpp:254:57:254:58 | call to unordered_map | map.cpp:261:27:261:28 | m6 | |
+| map.cpp:254:57:254:58 | call to unordered_map | map.cpp:267:7:267:8 | m6 | |
+| map.cpp:254:57:254:58 | call to unordered_map | map.cpp:273:7:273:8 | m6 | |
+| map.cpp:254:57:254:58 | call to unordered_map | map.cpp:279:7:279:8 | m6 | |
+| map.cpp:254:57:254:58 | call to unordered_map | map.cpp:398:1:398:1 | m6 | |
+| map.cpp:256:7:256:8 | ref arg m1 | map.cpp:262:7:262:8 | m1 | |
+| map.cpp:256:7:256:8 | ref arg m1 | map.cpp:268:7:268:8 | m1 | |
+| map.cpp:256:7:256:8 | ref arg m1 | map.cpp:274:7:274:8 | m1 | |
+| map.cpp:256:7:256:8 | ref arg m1 | map.cpp:295:12:295:13 | m1 | |
+| map.cpp:256:7:256:8 | ref arg m1 | map.cpp:295:30:295:31 | m1 | |
+| map.cpp:256:7:256:8 | ref arg m1 | map.cpp:398:1:398:1 | m1 | |
+| map.cpp:256:17:256:30 | call to make_pair | map.cpp:256:17:256:44 | call to pair | TAINT |
+| map.cpp:256:47:256:51 | first | map.cpp:256:7:256:51 | call to iterator | |
+| map.cpp:257:7:257:8 | ref arg m2 | map.cpp:263:7:263:8 | m2 | |
+| map.cpp:257:7:257:8 | ref arg m2 | map.cpp:269:7:269:8 | m2 | |
+| map.cpp:257:7:257:8 | ref arg m2 | map.cpp:275:7:275:8 | m2 | |
+| map.cpp:257:7:257:8 | ref arg m2 | map.cpp:282:40:282:41 | m2 | |
+| map.cpp:257:7:257:8 | ref arg m2 | map.cpp:283:42:283:43 | m2 | |
+| map.cpp:257:7:257:8 | ref arg m2 | map.cpp:285:7:285:8 | m2 | |
+| map.cpp:257:7:257:8 | ref arg m2 | map.cpp:301:12:301:13 | m2 | |
+| map.cpp:257:7:257:8 | ref arg m2 | map.cpp:301:30:301:31 | m2 | |
+| map.cpp:257:7:257:8 | ref arg m2 | map.cpp:331:7:331:8 | m2 | |
+| map.cpp:257:7:257:8 | ref arg m2 | map.cpp:332:7:332:8 | m2 | |
+| map.cpp:257:7:257:8 | ref arg m2 | map.cpp:333:7:333:8 | m2 | |
+| map.cpp:257:7:257:8 | ref arg m2 | map.cpp:398:1:398:1 | m2 | |
+| map.cpp:257:17:257:30 | call to make_pair | map.cpp:257:17:257:47 | call to pair | TAINT |
+| map.cpp:257:50:257:54 | first | map.cpp:257:7:257:54 | call to iterator | |
+| map.cpp:258:7:258:8 | ref arg m3 | map.cpp:264:7:264:8 | m3 | |
+| map.cpp:258:7:258:8 | ref arg m3 | map.cpp:270:7:270:8 | m3 | |
+| map.cpp:258:7:258:8 | ref arg m3 | map.cpp:276:7:276:8 | m3 | |
+| map.cpp:258:7:258:8 | ref arg m3 | map.cpp:307:12:307:13 | m3 | |
+| map.cpp:258:7:258:8 | ref arg m3 | map.cpp:307:30:307:31 | m3 | |
+| map.cpp:258:7:258:8 | ref arg m3 | map.cpp:398:1:398:1 | m3 | |
+| map.cpp:258:17:258:30 | call to make_pair | map.cpp:258:17:258:47 | call to pair | TAINT |
+| map.cpp:258:50:258:54 | first | map.cpp:258:7:258:54 | call to iterator | |
+| map.cpp:259:7:259:8 | ref arg m4 | map.cpp:265:7:265:8 | m4 | |
+| map.cpp:259:7:259:8 | ref arg m4 | map.cpp:271:7:271:8 | m4 | |
+| map.cpp:259:7:259:8 | ref arg m4 | map.cpp:277:7:277:8 | m4 | |
+| map.cpp:259:7:259:8 | ref arg m4 | map.cpp:398:1:398:1 | m4 | |
+| map.cpp:259:17:259:18 | ref arg m4 | map.cpp:259:7:259:8 | m4 | |
+| map.cpp:259:17:259:18 | ref arg m4 | map.cpp:265:7:265:8 | m4 | |
+| map.cpp:259:17:259:18 | ref arg m4 | map.cpp:271:7:271:8 | m4 | |
+| map.cpp:259:17:259:18 | ref arg m4 | map.cpp:277:7:277:8 | m4 | |
+| map.cpp:259:17:259:18 | ref arg m4 | map.cpp:398:1:398:1 | m4 | |
+| map.cpp:259:20:259:24 | call to begin | map.cpp:259:17:259:26 | call to iterator | TAINT |
+| map.cpp:259:29:259:70 | call to pair | map.cpp:259:29:259:70 | call to pair | TAINT |
+| map.cpp:260:7:260:8 | ref arg m5 | map.cpp:266:7:266:8 | m5 | |
+| map.cpp:260:7:260:8 | ref arg m5 | map.cpp:272:7:272:8 | m5 | |
+| map.cpp:260:7:260:8 | ref arg m5 | map.cpp:278:7:278:8 | m5 | |
+| map.cpp:260:7:260:8 | ref arg m5 | map.cpp:398:1:398:1 | m5 | |
+| map.cpp:260:44:260:48 | first | map.cpp:260:7:260:48 | call to iterator | |
+| map.cpp:261:7:261:8 | ref arg m6 | map.cpp:267:7:267:8 | m6 | |
+| map.cpp:261:7:261:8 | ref arg m6 | map.cpp:273:7:273:8 | m6 | |
+| map.cpp:261:7:261:8 | ref arg m6 | map.cpp:279:7:279:8 | m6 | |
+| map.cpp:261:7:261:8 | ref arg m6 | map.cpp:398:1:398:1 | m6 | |
+| map.cpp:261:27:261:28 | ref arg m6 | map.cpp:261:7:261:8 | m6 | |
+| map.cpp:261:27:261:28 | ref arg m6 | map.cpp:267:7:267:8 | m6 | |
+| map.cpp:261:27:261:28 | ref arg m6 | map.cpp:273:7:273:8 | m6 | |
+| map.cpp:261:27:261:28 | ref arg m6 | map.cpp:279:7:279:8 | m6 | |
+| map.cpp:261:27:261:28 | ref arg m6 | map.cpp:398:1:398:1 | m6 | |
+| map.cpp:261:30:261:34 | call to begin | map.cpp:261:27:261:36 | call to iterator | TAINT |
+| map.cpp:262:7:262:8 | m1 | map.cpp:262:7:262:8 | call to unordered_map | |
+| map.cpp:263:7:263:8 | m2 | map.cpp:263:7:263:8 | call to unordered_map | |
+| map.cpp:264:7:264:8 | m3 | map.cpp:264:7:264:8 | call to unordered_map | |
+| map.cpp:265:7:265:8 | m4 | map.cpp:265:7:265:8 | call to unordered_map | |
+| map.cpp:266:7:266:8 | m5 | map.cpp:266:7:266:8 | call to unordered_map | |
+| map.cpp:267:7:267:8 | m6 | map.cpp:267:7:267:8 | call to unordered_map | |
+| map.cpp:268:7:268:8 | ref arg m1 | map.cpp:274:7:274:8 | m1 | |
+| map.cpp:268:7:268:8 | ref arg m1 | map.cpp:295:12:295:13 | m1 | |
+| map.cpp:268:7:268:8 | ref arg m1 | map.cpp:295:30:295:31 | m1 | |
+| map.cpp:268:7:268:8 | ref arg m1 | map.cpp:398:1:398:1 | m1 | |
+| map.cpp:269:7:269:8 | ref arg m2 | map.cpp:275:7:275:8 | m2 | |
+| map.cpp:269:7:269:8 | ref arg m2 | map.cpp:282:40:282:41 | m2 | |
+| map.cpp:269:7:269:8 | ref arg m2 | map.cpp:283:42:283:43 | m2 | |
+| map.cpp:269:7:269:8 | ref arg m2 | map.cpp:285:7:285:8 | m2 | |
+| map.cpp:269:7:269:8 | ref arg m2 | map.cpp:301:12:301:13 | m2 | |
+| map.cpp:269:7:269:8 | ref arg m2 | map.cpp:301:30:301:31 | m2 | |
+| map.cpp:269:7:269:8 | ref arg m2 | map.cpp:331:7:331:8 | m2 | |
+| map.cpp:269:7:269:8 | ref arg m2 | map.cpp:332:7:332:8 | m2 | |
+| map.cpp:269:7:269:8 | ref arg m2 | map.cpp:333:7:333:8 | m2 | |
+| map.cpp:269:7:269:8 | ref arg m2 | map.cpp:398:1:398:1 | m2 | |
+| map.cpp:270:7:270:8 | ref arg m3 | map.cpp:276:7:276:8 | m3 | |
+| map.cpp:270:7:270:8 | ref arg m3 | map.cpp:307:12:307:13 | m3 | |
+| map.cpp:270:7:270:8 | ref arg m3 | map.cpp:307:30:307:31 | m3 | |
+| map.cpp:270:7:270:8 | ref arg m3 | map.cpp:398:1:398:1 | m3 | |
+| map.cpp:271:7:271:8 | ref arg m4 | map.cpp:277:7:277:8 | m4 | |
+| map.cpp:271:7:271:8 | ref arg m4 | map.cpp:398:1:398:1 | m4 | |
+| map.cpp:272:7:272:8 | ref arg m5 | map.cpp:278:7:278:8 | m5 | |
+| map.cpp:272:7:272:8 | ref arg m5 | map.cpp:398:1:398:1 | m5 | |
+| map.cpp:273:7:273:8 | ref arg m6 | map.cpp:279:7:279:8 | m6 | |
+| map.cpp:273:7:273:8 | ref arg m6 | map.cpp:398:1:398:1 | m6 | |
+| map.cpp:274:7:274:8 | ref arg m1 | map.cpp:295:12:295:13 | m1 | |
+| map.cpp:274:7:274:8 | ref arg m1 | map.cpp:295:30:295:31 | m1 | |
+| map.cpp:274:7:274:8 | ref arg m1 | map.cpp:398:1:398:1 | m1 | |
+| map.cpp:275:7:275:8 | ref arg m2 | map.cpp:282:40:282:41 | m2 | |
+| map.cpp:275:7:275:8 | ref arg m2 | map.cpp:283:42:283:43 | m2 | |
+| map.cpp:275:7:275:8 | ref arg m2 | map.cpp:285:7:285:8 | m2 | |
+| map.cpp:275:7:275:8 | ref arg m2 | map.cpp:301:12:301:13 | m2 | |
+| map.cpp:275:7:275:8 | ref arg m2 | map.cpp:301:30:301:31 | m2 | |
+| map.cpp:275:7:275:8 | ref arg m2 | map.cpp:331:7:331:8 | m2 | |
+| map.cpp:275:7:275:8 | ref arg m2 | map.cpp:332:7:332:8 | m2 | |
+| map.cpp:275:7:275:8 | ref arg m2 | map.cpp:333:7:333:8 | m2 | |
+| map.cpp:275:7:275:8 | ref arg m2 | map.cpp:398:1:398:1 | m2 | |
+| map.cpp:276:7:276:8 | ref arg m3 | map.cpp:307:12:307:13 | m3 | |
+| map.cpp:276:7:276:8 | ref arg m3 | map.cpp:307:30:307:31 | m3 | |
+| map.cpp:276:7:276:8 | ref arg m3 | map.cpp:398:1:398:1 | m3 | |
+| map.cpp:277:7:277:8 | ref arg m4 | map.cpp:398:1:398:1 | m4 | |
+| map.cpp:278:7:278:8 | ref arg m5 | map.cpp:398:1:398:1 | m5 | |
+| map.cpp:279:7:279:8 | ref arg m6 | map.cpp:398:1:398:1 | m6 | |
+| map.cpp:282:40:282:41 | m2 | map.cpp:282:40:282:42 | call to unordered_map | |
+| map.cpp:282:40:282:42 | call to unordered_map | map.cpp:286:7:286:8 | m7 | |
+| map.cpp:282:40:282:42 | call to unordered_map | map.cpp:289:7:289:8 | m7 | |
+| map.cpp:282:40:282:42 | call to unordered_map | map.cpp:398:1:398:1 | m7 | |
+| map.cpp:283:41:283:43 | call to unordered_map | map.cpp:287:7:287:8 | m8 | |
+| map.cpp:283:41:283:43 | call to unordered_map | map.cpp:290:7:290:8 | m8 | |
+| map.cpp:283:41:283:43 | call to unordered_map | map.cpp:398:1:398:1 | m8 | |
+| map.cpp:283:42:283:43 | m2 | map.cpp:283:41:283:43 | call to unordered_map | |
+| map.cpp:284:37:284:38 | call to unordered_map | map.cpp:285:2:285:3 | m9 | |
+| map.cpp:284:37:284:38 | call to unordered_map | map.cpp:288:7:288:8 | m9 | |
+| map.cpp:284:37:284:38 | call to unordered_map | map.cpp:291:7:291:8 | m9 | |
+| map.cpp:284:37:284:38 | call to unordered_map | map.cpp:398:1:398:1 | m9 | |
+| map.cpp:285:2:285:3 | ref arg m9 | map.cpp:288:7:288:8 | m9 | |
+| map.cpp:285:2:285:3 | ref arg m9 | map.cpp:291:7:291:8 | m9 | |
+| map.cpp:285:2:285:3 | ref arg m9 | map.cpp:398:1:398:1 | m9 | |
+| map.cpp:285:7:285:8 | m2 | map.cpp:285:2:285:3 | ref arg m9 | TAINT |
+| map.cpp:285:7:285:8 | m2 | map.cpp:285:5:285:5 | call to operator= | TAINT |
+| map.cpp:286:7:286:8 | m7 | map.cpp:286:7:286:8 | call to unordered_map | |
+| map.cpp:287:7:287:8 | m8 | map.cpp:287:7:287:8 | call to unordered_map | |
+| map.cpp:288:7:288:8 | m9 | map.cpp:288:7:288:8 | call to unordered_map | |
+| map.cpp:289:7:289:8 | ref arg m7 | map.cpp:398:1:398:1 | m7 | |
+| map.cpp:290:7:290:8 | ref arg m8 | map.cpp:398:1:398:1 | m8 | |
+| map.cpp:291:7:291:8 | ref arg m9 | map.cpp:398:1:398:1 | m9 | |
+| map.cpp:295:12:295:13 | ref arg m1 | map.cpp:295:30:295:31 | m1 | |
+| map.cpp:295:12:295:13 | ref arg m1 | map.cpp:398:1:398:1 | m1 | |
+| map.cpp:295:15:295:19 | call to begin | map.cpp:295:7:295:21 | ... = ... | |
+| map.cpp:295:15:295:19 | call to begin | map.cpp:295:24:295:25 | i1 | |
+| map.cpp:295:15:295:19 | call to begin | map.cpp:295:40:295:41 | i1 | |
+| map.cpp:295:15:295:19 | call to begin | map.cpp:297:9:297:10 | i1 | |
+| map.cpp:295:15:295:19 | call to begin | map.cpp:298:8:298:9 | i1 | |
+| map.cpp:295:15:295:19 | call to begin | map.cpp:299:8:299:9 | i1 | |
+| map.cpp:295:30:295:31 | ref arg m1 | map.cpp:295:30:295:31 | m1 | |
+| map.cpp:295:30:295:31 | ref arg m1 | map.cpp:398:1:398:1 | m1 | |
+| map.cpp:295:40:295:41 | i1 | map.cpp:295:42:295:42 | call to operator++ | |
+| map.cpp:295:40:295:41 | ref arg i1 | map.cpp:295:24:295:25 | i1 | |
+| map.cpp:295:40:295:41 | ref arg i1 | map.cpp:295:40:295:41 | i1 | |
+| map.cpp:295:40:295:41 | ref arg i1 | map.cpp:297:9:297:10 | i1 | |
+| map.cpp:295:40:295:41 | ref arg i1 | map.cpp:298:8:298:9 | i1 | |
+| map.cpp:295:40:295:41 | ref arg i1 | map.cpp:299:8:299:9 | i1 | |
+| map.cpp:297:8:297:8 | call to operator* | map.cpp:297:8:297:10 | call to pair | TAINT |
+| map.cpp:297:9:297:10 | i1 | map.cpp:297:8:297:8 | call to operator* | TAINT |
+| map.cpp:298:8:298:9 | i1 | map.cpp:298:10:298:10 | call to operator-> | TAINT |
+| map.cpp:299:8:299:9 | i1 | map.cpp:299:10:299:10 | call to operator-> | TAINT |
+| map.cpp:301:12:301:13 | ref arg m2 | map.cpp:301:30:301:31 | m2 | |
+| map.cpp:301:12:301:13 | ref arg m2 | map.cpp:331:7:331:8 | m2 | |
+| map.cpp:301:12:301:13 | ref arg m2 | map.cpp:332:7:332:8 | m2 | |
+| map.cpp:301:12:301:13 | ref arg m2 | map.cpp:333:7:333:8 | m2 | |
+| map.cpp:301:12:301:13 | ref arg m2 | map.cpp:398:1:398:1 | m2 | |
+| map.cpp:301:15:301:19 | call to begin | map.cpp:301:7:301:21 | ... = ... | |
+| map.cpp:301:15:301:19 | call to begin | map.cpp:301:24:301:25 | i2 | |
+| map.cpp:301:15:301:19 | call to begin | map.cpp:301:40:301:41 | i2 | |
+| map.cpp:301:15:301:19 | call to begin | map.cpp:303:9:303:10 | i2 | |
+| map.cpp:301:15:301:19 | call to begin | map.cpp:304:8:304:9 | i2 | |
+| map.cpp:301:15:301:19 | call to begin | map.cpp:305:8:305:9 | i2 | |
+| map.cpp:301:15:301:19 | call to begin | map.cpp:310:8:310:9 | i2 | |
+| map.cpp:301:15:301:19 | call to begin | map.cpp:311:8:311:9 | i2 | |
+| map.cpp:301:30:301:31 | ref arg m2 | map.cpp:301:30:301:31 | m2 | |
+| map.cpp:301:30:301:31 | ref arg m2 | map.cpp:331:7:331:8 | m2 | |
+| map.cpp:301:30:301:31 | ref arg m2 | map.cpp:332:7:332:8 | m2 | |
+| map.cpp:301:30:301:31 | ref arg m2 | map.cpp:333:7:333:8 | m2 | |
+| map.cpp:301:30:301:31 | ref arg m2 | map.cpp:398:1:398:1 | m2 | |
+| map.cpp:301:40:301:41 | i2 | map.cpp:301:42:301:42 | call to operator++ | |
+| map.cpp:301:40:301:41 | ref arg i2 | map.cpp:301:24:301:25 | i2 | |
+| map.cpp:301:40:301:41 | ref arg i2 | map.cpp:301:40:301:41 | i2 | |
+| map.cpp:301:40:301:41 | ref arg i2 | map.cpp:303:9:303:10 | i2 | |
+| map.cpp:301:40:301:41 | ref arg i2 | map.cpp:304:8:304:9 | i2 | |
+| map.cpp:301:40:301:41 | ref arg i2 | map.cpp:305:8:305:9 | i2 | |
+| map.cpp:301:40:301:41 | ref arg i2 | map.cpp:310:8:310:9 | i2 | |
+| map.cpp:301:40:301:41 | ref arg i2 | map.cpp:311:8:311:9 | i2 | |
+| map.cpp:303:8:303:8 | call to operator* | map.cpp:303:8:303:10 | call to pair | TAINT |
+| map.cpp:303:9:303:10 | i2 | map.cpp:303:8:303:8 | call to operator* | TAINT |
+| map.cpp:304:8:304:9 | i2 | map.cpp:304:10:304:10 | call to operator-> | TAINT |
+| map.cpp:305:8:305:9 | i2 | map.cpp:305:10:305:10 | call to operator-> | TAINT |
+| map.cpp:307:12:307:13 | ref arg m3 | map.cpp:307:30:307:31 | m3 | |
+| map.cpp:307:12:307:13 | ref arg m3 | map.cpp:398:1:398:1 | m3 | |
+| map.cpp:307:15:307:19 | call to begin | map.cpp:307:7:307:21 | ... = ... | |
+| map.cpp:307:15:307:19 | call to begin | map.cpp:307:24:307:25 | i3 | |
+| map.cpp:307:15:307:19 | call to begin | map.cpp:307:40:307:41 | i3 | |
+| map.cpp:307:15:307:19 | call to begin | map.cpp:309:9:309:10 | i3 | |
+| map.cpp:307:30:307:31 | ref arg m3 | map.cpp:307:30:307:31 | m3 | |
+| map.cpp:307:30:307:31 | ref arg m3 | map.cpp:398:1:398:1 | m3 | |
+| map.cpp:307:40:307:41 | i3 | map.cpp:307:42:307:42 | call to operator++ | |
+| map.cpp:307:40:307:41 | ref arg i3 | map.cpp:307:24:307:25 | i3 | |
+| map.cpp:307:40:307:41 | ref arg i3 | map.cpp:307:40:307:41 | i3 | |
+| map.cpp:307:40:307:41 | ref arg i3 | map.cpp:309:9:309:10 | i3 | |
+| map.cpp:309:8:309:8 | call to operator* | map.cpp:309:8:309:10 | call to pair | TAINT |
+| map.cpp:309:9:309:10 | i3 | map.cpp:309:8:309:8 | call to operator* | TAINT |
+| map.cpp:310:8:310:9 | i2 | map.cpp:310:10:310:10 | call to operator-> | TAINT |
+| map.cpp:311:8:311:9 | i2 | map.cpp:311:10:311:10 | call to operator-> | TAINT |
+| map.cpp:315:37:315:39 | call to unordered_map | map.cpp:316:7:316:9 | m10 | |
+| map.cpp:315:37:315:39 | call to unordered_map | map.cpp:320:7:320:9 | m10 | |
+| map.cpp:315:37:315:39 | call to unordered_map | map.cpp:398:1:398:1 | m10 | |
+| map.cpp:315:42:315:44 | call to unordered_map | map.cpp:317:7:317:9 | m11 | |
+| map.cpp:315:42:315:44 | call to unordered_map | map.cpp:321:7:321:9 | m11 | |
+| map.cpp:315:42:315:44 | call to unordered_map | map.cpp:398:1:398:1 | m11 | |
+| map.cpp:315:47:315:49 | call to unordered_map | map.cpp:318:7:318:9 | m12 | |
+| map.cpp:315:47:315:49 | call to unordered_map | map.cpp:322:7:322:9 | m12 | |
+| map.cpp:315:47:315:49 | call to unordered_map | map.cpp:398:1:398:1 | m12 | |
+| map.cpp:315:52:315:54 | call to unordered_map | map.cpp:319:7:319:9 | m13 | |
+| map.cpp:315:52:315:54 | call to unordered_map | map.cpp:323:7:323:9 | m13 | |
+| map.cpp:315:52:315:54 | call to unordered_map | map.cpp:398:1:398:1 | m13 | |
+| map.cpp:316:7:316:9 | ref arg m10 | map.cpp:320:7:320:9 | m10 | |
+| map.cpp:316:7:316:9 | ref arg m10 | map.cpp:398:1:398:1 | m10 | |
+| map.cpp:316:7:316:24 | ... = ... | map.cpp:316:10:316:10 | call to operator[] [post update] | |
+| map.cpp:316:20:316:24 | def | map.cpp:316:7:316:24 | ... = ... | |
+| map.cpp:317:7:317:9 | ref arg m11 | map.cpp:321:7:321:9 | m11 | |
+| map.cpp:317:7:317:9 | ref arg m11 | map.cpp:398:1:398:1 | m11 | |
+| map.cpp:317:7:317:27 | ... = ... | map.cpp:317:10:317:10 | call to operator[] [post update] | |
+| map.cpp:317:20:317:25 | call to source | map.cpp:317:7:317:27 | ... = ... | |
+| map.cpp:318:7:318:9 | ref arg m12 | map.cpp:322:7:322:9 | m12 | |
+| map.cpp:318:7:318:9 | ref arg m12 | map.cpp:398:1:398:1 | m12 | |
+| map.cpp:318:7:318:27 | ... = ... | map.cpp:318:11:318:12 | call to at [post update] | |
+| map.cpp:318:23:318:27 | def | map.cpp:318:7:318:27 | ... = ... | |
+| map.cpp:319:7:319:9 | ref arg m13 | map.cpp:323:7:323:9 | m13 | |
+| map.cpp:319:7:319:9 | ref arg m13 | map.cpp:398:1:398:1 | m13 | |
+| map.cpp:319:7:319:30 | ... = ... | map.cpp:319:11:319:12 | call to at [post update] | |
+| map.cpp:319:23:319:28 | call to source | map.cpp:319:7:319:30 | ... = ... | |
+| map.cpp:320:7:320:9 | ref arg m10 | map.cpp:398:1:398:1 | m10 | |
+| map.cpp:321:7:321:9 | ref arg m11 | map.cpp:398:1:398:1 | m11 | |
+| map.cpp:322:7:322:9 | ref arg m12 | map.cpp:398:1:398:1 | m12 | |
+| map.cpp:323:7:323:9 | ref arg m13 | map.cpp:398:1:398:1 | m13 | |
+| map.cpp:326:37:326:39 | call to unordered_map | map.cpp:327:2:327:4 | m14 | |
+| map.cpp:326:37:326:39 | call to unordered_map | map.cpp:328:2:328:4 | m14 | |
+| map.cpp:326:37:326:39 | call to unordered_map | map.cpp:329:2:329:4 | m14 | |
+| map.cpp:326:37:326:39 | call to unordered_map | map.cpp:330:2:330:4 | m14 | |
+| map.cpp:326:37:326:39 | call to unordered_map | map.cpp:398:1:398:1 | m14 | |
+| map.cpp:327:2:327:4 | ref arg m14 | map.cpp:328:2:328:4 | m14 | |
+| map.cpp:327:2:327:4 | ref arg m14 | map.cpp:329:2:329:4 | m14 | |
+| map.cpp:327:2:327:4 | ref arg m14 | map.cpp:330:2:330:4 | m14 | |
+| map.cpp:327:2:327:4 | ref arg m14 | map.cpp:398:1:398:1 | m14 | |
+| map.cpp:327:13:327:26 | call to make_pair | map.cpp:327:13:327:36 | call to pair | TAINT |
+| map.cpp:328:2:328:4 | ref arg m14 | map.cpp:329:2:329:4 | m14 | |
+| map.cpp:328:2:328:4 | ref arg m14 | map.cpp:330:2:330:4 | m14 | |
+| map.cpp:328:2:328:4 | ref arg m14 | map.cpp:398:1:398:1 | m14 | |
+| map.cpp:328:13:328:26 | call to make_pair | map.cpp:328:13:328:41 | call to pair | TAINT |
+| map.cpp:329:2:329:4 | ref arg m14 | map.cpp:330:2:330:4 | m14 | |
+| map.cpp:329:2:329:4 | ref arg m14 | map.cpp:398:1:398:1 | m14 | |
+| map.cpp:329:13:329:26 | call to make_pair | map.cpp:329:13:329:41 | call to pair | TAINT |
+| map.cpp:330:2:330:4 | ref arg m14 | map.cpp:398:1:398:1 | m14 | |
+| map.cpp:330:13:330:26 | call to make_pair | map.cpp:330:13:330:36 | call to pair | TAINT |
+| map.cpp:331:7:331:8 | ref arg m2 | map.cpp:332:7:332:8 | m2 | |
+| map.cpp:331:7:331:8 | ref arg m2 | map.cpp:333:7:333:8 | m2 | |
+| map.cpp:331:7:331:8 | ref arg m2 | map.cpp:398:1:398:1 | m2 | |
+| map.cpp:331:27:331:31 | first | map.cpp:331:7:331:31 | call to iterator | |
+| map.cpp:332:7:332:8 | ref arg m2 | map.cpp:333:7:333:8 | m2 | |
+| map.cpp:332:7:332:8 | ref arg m2 | map.cpp:398:1:398:1 | m2 | |
+| map.cpp:332:27:332:32 | second | map.cpp:332:7:332:32 | call to iterator | |
+| map.cpp:333:7:333:8 | ref arg m2 | map.cpp:398:1:398:1 | m2 | |
+| map.cpp:333:27:333:32 | second | map.cpp:333:7:333:32 | call to iterator | |
+| map.cpp:336:37:336:39 | call to unordered_map | map.cpp:337:2:337:4 | m15 | |
+| map.cpp:336:37:336:39 | call to unordered_map | map.cpp:339:7:339:9 | m15 | |
+| map.cpp:336:37:336:39 | call to unordered_map | map.cpp:343:2:343:4 | m15 | |
+| map.cpp:336:37:336:39 | call to unordered_map | map.cpp:345:7:345:9 | m15 | |
+| map.cpp:336:37:336:39 | call to unordered_map | map.cpp:360:2:360:4 | m15 | |
+| map.cpp:336:37:336:39 | call to unordered_map | map.cpp:398:1:398:1 | m15 | |
+| map.cpp:336:42:336:44 | call to unordered_map | map.cpp:340:7:340:9 | m16 | |
+| map.cpp:336:42:336:44 | call to unordered_map | map.cpp:343:11:343:13 | m16 | |
+| map.cpp:336:42:336:44 | call to unordered_map | map.cpp:346:7:346:9 | m16 | |
+| map.cpp:336:42:336:44 | call to unordered_map | map.cpp:360:12:360:14 | m16 | |
+| map.cpp:336:42:336:44 | call to unordered_map | map.cpp:398:1:398:1 | m16 | |
+| map.cpp:336:47:336:49 | call to unordered_map | map.cpp:341:7:341:9 | m17 | |
+| map.cpp:336:47:336:49 | call to unordered_map | map.cpp:344:2:344:4 | m17 | |
+| map.cpp:336:47:336:49 | call to unordered_map | map.cpp:347:7:347:9 | m17 | |
+| map.cpp:336:47:336:49 | call to unordered_map | map.cpp:361:2:361:4 | m17 | |
+| map.cpp:336:47:336:49 | call to unordered_map | map.cpp:398:1:398:1 | m17 | |
+| map.cpp:336:52:336:54 | call to unordered_map | map.cpp:338:2:338:4 | m18 | |
+| map.cpp:336:52:336:54 | call to unordered_map | map.cpp:342:7:342:9 | m18 | |
+| map.cpp:336:52:336:54 | call to unordered_map | map.cpp:344:11:344:13 | m18 | |
+| map.cpp:336:52:336:54 | call to unordered_map | map.cpp:348:7:348:9 | m18 | |
+| map.cpp:336:52:336:54 | call to unordered_map | map.cpp:361:12:361:14 | m18 | |
+| map.cpp:336:52:336:54 | call to unordered_map | map.cpp:398:1:398:1 | m18 | |
+| map.cpp:337:2:337:4 | ref arg m15 | map.cpp:339:7:339:9 | m15 | |
+| map.cpp:337:2:337:4 | ref arg m15 | map.cpp:343:2:343:4 | m15 | |
+| map.cpp:337:2:337:4 | ref arg m15 | map.cpp:345:7:345:9 | m15 | |
+| map.cpp:337:2:337:4 | ref arg m15 | map.cpp:360:2:360:4 | m15 | |
+| map.cpp:337:2:337:4 | ref arg m15 | map.cpp:398:1:398:1 | m15 | |
+| map.cpp:337:13:337:57 | call to pair | map.cpp:337:13:337:57 | call to pair | TAINT |
+| map.cpp:338:2:338:4 | ref arg m18 | map.cpp:342:7:342:9 | m18 | |
+| map.cpp:338:2:338:4 | ref arg m18 | map.cpp:344:11:344:13 | m18 | |
+| map.cpp:338:2:338:4 | ref arg m18 | map.cpp:348:7:348:9 | m18 | |
+| map.cpp:338:2:338:4 | ref arg m18 | map.cpp:361:12:361:14 | m18 | |
+| map.cpp:338:2:338:4 | ref arg m18 | map.cpp:398:1:398:1 | m18 | |
+| map.cpp:338:13:338:57 | call to pair | map.cpp:338:13:338:57 | call to pair | TAINT |
+| map.cpp:339:7:339:9 | m15 | map.cpp:339:7:339:9 | call to unordered_map | |
+| map.cpp:340:7:340:9 | m16 | map.cpp:340:7:340:9 | call to unordered_map | |
+| map.cpp:341:7:341:9 | m17 | map.cpp:341:7:341:9 | call to unordered_map | |
+| map.cpp:342:7:342:9 | m18 | map.cpp:342:7:342:9 | call to unordered_map | |
+| map.cpp:343:2:343:4 | ref arg m15 | map.cpp:345:7:345:9 | m15 | |
+| map.cpp:343:2:343:4 | ref arg m15 | map.cpp:360:2:360:4 | m15 | |
+| map.cpp:343:2:343:4 | ref arg m15 | map.cpp:398:1:398:1 | m15 | |
+| map.cpp:343:11:343:13 | ref arg m16 | map.cpp:346:7:346:9 | m16 | |
+| map.cpp:343:11:343:13 | ref arg m16 | map.cpp:360:12:360:14 | m16 | |
+| map.cpp:343:11:343:13 | ref arg m16 | map.cpp:398:1:398:1 | m16 | |
+| map.cpp:344:2:344:4 | ref arg m17 | map.cpp:347:7:347:9 | m17 | |
+| map.cpp:344:2:344:4 | ref arg m17 | map.cpp:361:2:361:4 | m17 | |
+| map.cpp:344:2:344:4 | ref arg m17 | map.cpp:398:1:398:1 | m17 | |
+| map.cpp:344:11:344:13 | ref arg m18 | map.cpp:348:7:348:9 | m18 | |
+| map.cpp:344:11:344:13 | ref arg m18 | map.cpp:361:12:361:14 | m18 | |
+| map.cpp:344:11:344:13 | ref arg m18 | map.cpp:398:1:398:1 | m18 | |
+| map.cpp:345:7:345:9 | m15 | map.cpp:345:7:345:9 | call to unordered_map | |
+| map.cpp:346:7:346:9 | m16 | map.cpp:346:7:346:9 | call to unordered_map | |
+| map.cpp:347:7:347:9 | m17 | map.cpp:347:7:347:9 | call to unordered_map | |
+| map.cpp:348:7:348:9 | m18 | map.cpp:348:7:348:9 | call to unordered_map | |
+| map.cpp:351:37:351:39 | call to unordered_map | map.cpp:352:2:352:4 | m19 | |
+| map.cpp:351:37:351:39 | call to unordered_map | map.cpp:356:7:356:9 | m19 | |
+| map.cpp:351:37:351:39 | call to unordered_map | map.cpp:362:7:362:9 | m19 | |
+| map.cpp:351:37:351:39 | call to unordered_map | map.cpp:398:1:398:1 | m19 | |
+| map.cpp:351:42:351:44 | call to unordered_map | map.cpp:353:2:353:4 | m20 | |
+| map.cpp:351:42:351:44 | call to unordered_map | map.cpp:357:7:357:9 | m20 | |
+| map.cpp:351:42:351:44 | call to unordered_map | map.cpp:363:7:363:9 | m20 | |
+| map.cpp:351:42:351:44 | call to unordered_map | map.cpp:398:1:398:1 | m20 | |
+| map.cpp:351:47:351:49 | call to unordered_map | map.cpp:354:2:354:4 | m21 | |
+| map.cpp:351:47:351:49 | call to unordered_map | map.cpp:358:7:358:9 | m21 | |
+| map.cpp:351:47:351:49 | call to unordered_map | map.cpp:364:7:364:9 | m21 | |
+| map.cpp:351:47:351:49 | call to unordered_map | map.cpp:398:1:398:1 | m21 | |
+| map.cpp:351:52:351:54 | call to unordered_map | map.cpp:355:2:355:4 | m22 | |
+| map.cpp:351:52:351:54 | call to unordered_map | map.cpp:359:7:359:9 | m22 | |
+| map.cpp:351:52:351:54 | call to unordered_map | map.cpp:365:7:365:9 | m22 | |
+| map.cpp:351:52:351:54 | call to unordered_map | map.cpp:398:1:398:1 | m22 | |
+| map.cpp:352:2:352:4 | ref arg m19 | map.cpp:356:7:356:9 | m19 | |
+| map.cpp:352:2:352:4 | ref arg m19 | map.cpp:362:7:362:9 | m19 | |
+| map.cpp:352:2:352:4 | ref arg m19 | map.cpp:398:1:398:1 | m19 | |
+| map.cpp:352:13:352:57 | call to pair | map.cpp:352:13:352:57 | call to pair | TAINT |
+| map.cpp:353:2:353:4 | ref arg m20 | map.cpp:357:7:357:9 | m20 | |
+| map.cpp:353:2:353:4 | ref arg m20 | map.cpp:363:7:363:9 | m20 | |
+| map.cpp:353:2:353:4 | ref arg m20 | map.cpp:398:1:398:1 | m20 | |
+| map.cpp:353:13:353:51 | call to pair | map.cpp:353:13:353:51 | call to pair | TAINT |
+| map.cpp:354:2:354:4 | ref arg m21 | map.cpp:358:7:358:9 | m21 | |
+| map.cpp:354:2:354:4 | ref arg m21 | map.cpp:364:7:364:9 | m21 | |
+| map.cpp:354:2:354:4 | ref arg m21 | map.cpp:398:1:398:1 | m21 | |
+| map.cpp:354:13:354:51 | call to pair | map.cpp:354:13:354:51 | call to pair | TAINT |
+| map.cpp:355:2:355:4 | ref arg m22 | map.cpp:359:7:359:9 | m22 | |
+| map.cpp:355:2:355:4 | ref arg m22 | map.cpp:365:7:365:9 | m22 | |
+| map.cpp:355:2:355:4 | ref arg m22 | map.cpp:398:1:398:1 | m22 | |
+| map.cpp:355:13:355:57 | call to pair | map.cpp:355:13:355:57 | call to pair | TAINT |
+| map.cpp:356:7:356:9 | m19 | map.cpp:356:7:356:9 | call to unordered_map | |
+| map.cpp:357:7:357:9 | m20 | map.cpp:357:7:357:9 | call to unordered_map | |
+| map.cpp:358:7:358:9 | m21 | map.cpp:358:7:358:9 | call to unordered_map | |
+| map.cpp:359:7:359:9 | m22 | map.cpp:359:7:359:9 | call to unordered_map | |
+| map.cpp:360:2:360:4 | ref arg m15 | map.cpp:398:1:398:1 | m15 | |
+| map.cpp:360:12:360:14 | ref arg m16 | map.cpp:398:1:398:1 | m16 | |
+| map.cpp:361:2:361:4 | ref arg m17 | map.cpp:398:1:398:1 | m17 | |
+| map.cpp:361:12:361:14 | ref arg m18 | map.cpp:398:1:398:1 | m18 | |
+| map.cpp:362:7:362:9 | m19 | map.cpp:362:7:362:9 | call to unordered_map | |
+| map.cpp:363:7:363:9 | m20 | map.cpp:363:7:363:9 | call to unordered_map | |
+| map.cpp:364:7:364:9 | m21 | map.cpp:364:7:364:9 | call to unordered_map | |
+| map.cpp:365:7:365:9 | m22 | map.cpp:365:7:365:9 | call to unordered_map | |
+| map.cpp:368:37:368:39 | call to unordered_map | map.cpp:369:2:369:4 | m23 | |
+| map.cpp:368:37:368:39 | call to unordered_map | map.cpp:370:2:370:4 | m23 | |
+| map.cpp:368:37:368:39 | call to unordered_map | map.cpp:371:7:371:9 | m23 | |
+| map.cpp:368:37:368:39 | call to unordered_map | map.cpp:372:7:372:9 | m23 | |
+| map.cpp:368:37:368:39 | call to unordered_map | map.cpp:372:17:372:19 | m23 | |
+| map.cpp:368:37:368:39 | call to unordered_map | map.cpp:373:7:373:9 | m23 | |
+| map.cpp:368:37:368:39 | call to unordered_map | map.cpp:374:2:374:4 | m23 | |
+| map.cpp:368:37:368:39 | call to unordered_map | map.cpp:375:7:375:9 | m23 | |
+| map.cpp:368:37:368:39 | call to unordered_map | map.cpp:398:1:398:1 | m23 | |
+| map.cpp:369:2:369:4 | ref arg m23 | map.cpp:370:2:370:4 | m23 | |
+| map.cpp:369:2:369:4 | ref arg m23 | map.cpp:371:7:371:9 | m23 | |
+| map.cpp:369:2:369:4 | ref arg m23 | map.cpp:372:7:372:9 | m23 | |
+| map.cpp:369:2:369:4 | ref arg m23 | map.cpp:372:17:372:19 | m23 | |
+| map.cpp:369:2:369:4 | ref arg m23 | map.cpp:373:7:373:9 | m23 | |
+| map.cpp:369:2:369:4 | ref arg m23 | map.cpp:374:2:374:4 | m23 | |
+| map.cpp:369:2:369:4 | ref arg m23 | map.cpp:375:7:375:9 | m23 | |
+| map.cpp:369:2:369:4 | ref arg m23 | map.cpp:398:1:398:1 | m23 | |
+| map.cpp:369:13:369:57 | call to pair | map.cpp:369:13:369:57 | call to pair | TAINT |
+| map.cpp:370:2:370:4 | ref arg m23 | map.cpp:371:7:371:9 | m23 | |
+| map.cpp:370:2:370:4 | ref arg m23 | map.cpp:372:7:372:9 | m23 | |
+| map.cpp:370:2:370:4 | ref arg m23 | map.cpp:372:17:372:19 | m23 | |
+| map.cpp:370:2:370:4 | ref arg m23 | map.cpp:373:7:373:9 | m23 | |
+| map.cpp:370:2:370:4 | ref arg m23 | map.cpp:374:2:374:4 | m23 | |
+| map.cpp:370:2:370:4 | ref arg m23 | map.cpp:375:7:375:9 | m23 | |
+| map.cpp:370:2:370:4 | ref arg m23 | map.cpp:398:1:398:1 | m23 | |
+| map.cpp:370:13:370:57 | call to pair | map.cpp:370:13:370:57 | call to pair | TAINT |
+| map.cpp:371:7:371:9 | m23 | map.cpp:371:7:371:9 | call to unordered_map | |
+| map.cpp:372:7:372:9 | ref arg m23 | map.cpp:373:7:373:9 | m23 | |
+| map.cpp:372:7:372:9 | ref arg m23 | map.cpp:374:2:374:4 | m23 | |
+| map.cpp:372:7:372:9 | ref arg m23 | map.cpp:375:7:375:9 | m23 | |
+| map.cpp:372:7:372:9 | ref arg m23 | map.cpp:398:1:398:1 | m23 | |
+| map.cpp:372:17:372:19 | ref arg m23 | map.cpp:372:7:372:9 | m23 | |
+| map.cpp:372:17:372:19 | ref arg m23 | map.cpp:373:7:373:9 | m23 | |
+| map.cpp:372:17:372:19 | ref arg m23 | map.cpp:374:2:374:4 | m23 | |
+| map.cpp:372:17:372:19 | ref arg m23 | map.cpp:375:7:375:9 | m23 | |
+| map.cpp:372:17:372:19 | ref arg m23 | map.cpp:398:1:398:1 | m23 | |
+| map.cpp:373:7:373:9 | m23 | map.cpp:373:7:373:9 | call to unordered_map | |
+| map.cpp:374:2:374:4 | ref arg m23 | map.cpp:375:7:375:9 | m23 | |
+| map.cpp:374:2:374:4 | ref arg m23 | map.cpp:398:1:398:1 | m23 | |
+| map.cpp:375:7:375:9 | m23 | map.cpp:375:7:375:9 | call to unordered_map | |
+| map.cpp:378:37:378:39 | call to unordered_map | map.cpp:379:7:379:9 | m24 | |
+| map.cpp:378:37:378:39 | call to unordered_map | map.cpp:380:7:380:9 | m24 | |
+| map.cpp:378:37:378:39 | call to unordered_map | map.cpp:381:7:381:9 | m24 | |
+| map.cpp:378:37:378:39 | call to unordered_map | map.cpp:382:7:382:9 | m24 | |
+| map.cpp:378:37:378:39 | call to unordered_map | map.cpp:398:1:398:1 | m24 | |
+| map.cpp:378:42:378:44 | call to unordered_map | map.cpp:383:7:383:9 | m25 | |
+| map.cpp:378:42:378:44 | call to unordered_map | map.cpp:383:24:383:26 | m25 | |
+| map.cpp:378:42:378:44 | call to unordered_map | map.cpp:384:7:384:9 | m25 | |
+| map.cpp:378:42:378:44 | call to unordered_map | map.cpp:385:7:385:9 | m25 | |
+| map.cpp:378:42:378:44 | call to unordered_map | map.cpp:385:24:385:26 | m25 | |
+| map.cpp:378:42:378:44 | call to unordered_map | map.cpp:386:7:386:9 | m25 | |
+| map.cpp:378:42:378:44 | call to unordered_map | map.cpp:398:1:398:1 | m25 | |
+| map.cpp:379:7:379:9 | ref arg m24 | map.cpp:380:7:380:9 | m24 | |
+| map.cpp:379:7:379:9 | ref arg m24 | map.cpp:381:7:381:9 | m24 | |
+| map.cpp:379:7:379:9 | ref arg m24 | map.cpp:382:7:382:9 | m24 | |
+| map.cpp:379:7:379:9 | ref arg m24 | map.cpp:398:1:398:1 | m24 | |
+| map.cpp:379:33:379:37 | first | map.cpp:379:7:379:37 | call to iterator | |
+| map.cpp:380:7:380:9 | m24 | map.cpp:380:7:380:9 | call to unordered_map | |
+| map.cpp:381:7:381:9 | ref arg m24 | map.cpp:382:7:382:9 | m24 | |
+| map.cpp:381:7:381:9 | ref arg m24 | map.cpp:398:1:398:1 | m24 | |
+| map.cpp:381:36:381:40 | first | map.cpp:381:7:381:40 | call to iterator | |
+| map.cpp:382:7:382:9 | m24 | map.cpp:382:7:382:9 | call to unordered_map | |
+| map.cpp:383:7:383:9 | ref arg m25 | map.cpp:384:7:384:9 | m25 | |
+| map.cpp:383:7:383:9 | ref arg m25 | map.cpp:385:7:385:9 | m25 | |
+| map.cpp:383:7:383:9 | ref arg m25 | map.cpp:385:24:385:26 | m25 | |
+| map.cpp:383:7:383:9 | ref arg m25 | map.cpp:386:7:386:9 | m25 | |
+| map.cpp:383:7:383:9 | ref arg m25 | map.cpp:398:1:398:1 | m25 | |
+| map.cpp:383:24:383:26 | ref arg m25 | map.cpp:383:7:383:9 | m25 | |
+| map.cpp:383:24:383:26 | ref arg m25 | map.cpp:384:7:384:9 | m25 | |
+| map.cpp:383:24:383:26 | ref arg m25 | map.cpp:385:7:385:9 | m25 | |
+| map.cpp:383:24:383:26 | ref arg m25 | map.cpp:385:24:385:26 | m25 | |
+| map.cpp:383:24:383:26 | ref arg m25 | map.cpp:386:7:386:9 | m25 | |
+| map.cpp:383:24:383:26 | ref arg m25 | map.cpp:398:1:398:1 | m25 | |
+| map.cpp:383:28:383:32 | call to begin | map.cpp:383:24:383:34 | call to iterator | TAINT |
+| map.cpp:384:7:384:9 | m25 | map.cpp:384:7:384:9 | call to unordered_map | |
+| map.cpp:385:7:385:9 | ref arg m25 | map.cpp:386:7:386:9 | m25 | |
+| map.cpp:385:7:385:9 | ref arg m25 | map.cpp:398:1:398:1 | m25 | |
+| map.cpp:385:24:385:26 | ref arg m25 | map.cpp:385:7:385:9 | m25 | |
+| map.cpp:385:24:385:26 | ref arg m25 | map.cpp:386:7:386:9 | m25 | |
+| map.cpp:385:24:385:26 | ref arg m25 | map.cpp:398:1:398:1 | m25 | |
+| map.cpp:385:28:385:32 | call to begin | map.cpp:385:24:385:34 | call to iterator | TAINT |
+| map.cpp:386:7:386:9 | m25 | map.cpp:386:7:386:9 | call to unordered_map | |
+| map.cpp:389:37:389:39 | call to unordered_map | map.cpp:390:7:390:9 | m26 | |
+| map.cpp:389:37:389:39 | call to unordered_map | map.cpp:391:7:391:9 | m26 | |
+| map.cpp:389:37:389:39 | call to unordered_map | map.cpp:392:7:392:9 | m26 | |
+| map.cpp:389:37:389:39 | call to unordered_map | map.cpp:393:7:393:9 | m26 | |
+| map.cpp:389:37:389:39 | call to unordered_map | map.cpp:398:1:398:1 | m26 | |
+| map.cpp:389:42:389:44 | call to unordered_map | map.cpp:394:7:394:9 | m27 | |
+| map.cpp:389:42:389:44 | call to unordered_map | map.cpp:394:23:394:25 | m27 | |
+| map.cpp:389:42:389:44 | call to unordered_map | map.cpp:395:7:395:9 | m27 | |
+| map.cpp:389:42:389:44 | call to unordered_map | map.cpp:396:7:396:9 | m27 | |
+| map.cpp:389:42:389:44 | call to unordered_map | map.cpp:396:23:396:25 | m27 | |
+| map.cpp:389:42:389:44 | call to unordered_map | map.cpp:397:7:397:9 | m27 | |
+| map.cpp:389:42:389:44 | call to unordered_map | map.cpp:398:1:398:1 | m27 | |
+| map.cpp:390:7:390:9 | ref arg m26 | map.cpp:391:7:391:9 | m26 | |
+| map.cpp:390:7:390:9 | ref arg m26 | map.cpp:392:7:392:9 | m26 | |
+| map.cpp:390:7:390:9 | ref arg m26 | map.cpp:393:7:393:9 | m26 | |
+| map.cpp:390:7:390:9 | ref arg m26 | map.cpp:398:1:398:1 | m26 | |
+| map.cpp:390:37:390:41 | first | map.cpp:390:7:390:41 | call to iterator | |
+| map.cpp:391:7:391:9 | m26 | map.cpp:391:7:391:9 | call to unordered_map | |
+| map.cpp:392:7:392:9 | ref arg m26 | map.cpp:393:7:393:9 | m26 | |
+| map.cpp:392:7:392:9 | ref arg m26 | map.cpp:398:1:398:1 | m26 | |
+| map.cpp:392:40:392:44 | first | map.cpp:392:7:392:44 | call to iterator | |
+| map.cpp:393:7:393:9 | m26 | map.cpp:393:7:393:9 | call to unordered_map | |
+| map.cpp:394:7:394:9 | ref arg m27 | map.cpp:395:7:395:9 | m27 | |
+| map.cpp:394:7:394:9 | ref arg m27 | map.cpp:396:7:396:9 | m27 | |
+| map.cpp:394:7:394:9 | ref arg m27 | map.cpp:396:23:396:25 | m27 | |
+| map.cpp:394:7:394:9 | ref arg m27 | map.cpp:397:7:397:9 | m27 | |
+| map.cpp:394:7:394:9 | ref arg m27 | map.cpp:398:1:398:1 | m27 | |
+| map.cpp:394:23:394:25 | ref arg m27 | map.cpp:394:7:394:9 | m27 | |
+| map.cpp:394:23:394:25 | ref arg m27 | map.cpp:395:7:395:9 | m27 | |
+| map.cpp:394:23:394:25 | ref arg m27 | map.cpp:396:7:396:9 | m27 | |
+| map.cpp:394:23:394:25 | ref arg m27 | map.cpp:396:23:396:25 | m27 | |
+| map.cpp:394:23:394:25 | ref arg m27 | map.cpp:397:7:397:9 | m27 | |
+| map.cpp:394:23:394:25 | ref arg m27 | map.cpp:398:1:398:1 | m27 | |
+| map.cpp:394:27:394:31 | call to begin | map.cpp:394:23:394:33 | call to iterator | TAINT |
+| map.cpp:395:7:395:9 | m27 | map.cpp:395:7:395:9 | call to unordered_map | |
+| map.cpp:396:7:396:9 | ref arg m27 | map.cpp:397:7:397:9 | m27 | |
+| map.cpp:396:7:396:9 | ref arg m27 | map.cpp:398:1:398:1 | m27 | |
+| map.cpp:396:23:396:25 | ref arg m27 | map.cpp:396:7:396:9 | m27 | |
+| map.cpp:396:23:396:25 | ref arg m27 | map.cpp:397:7:397:9 | m27 | |
+| map.cpp:396:23:396:25 | ref arg m27 | map.cpp:398:1:398:1 | m27 | |
+| map.cpp:396:27:396:31 | call to begin | map.cpp:396:23:396:33 | call to iterator | TAINT |
+| map.cpp:397:7:397:9 | m27 | map.cpp:397:7:397:9 | call to unordered_map | |
| movableclass.cpp:8:2:8:15 | this | movableclass.cpp:8:27:8:31 | constructor init of field v [pre-this] | |
| movableclass.cpp:8:21:8:22 | _v | movableclass.cpp:8:29:8:30 | _v | |
| movableclass.cpp:8:29:8:30 | _v | movableclass.cpp:8:27:8:31 | constructor init of field v | TAINT |
@@ -653,22 +1716,22 @@
| standalone_iterators.cpp:51:37:51:43 | source1 | standalone_iterators.cpp:53:12:53:18 | source1 | |
| standalone_iterators.cpp:51:37:51:43 | source1 | standalone_iterators.cpp:54:14:54:20 | source1 | |
| standalone_iterators.cpp:53:12:53:18 | ref arg source1 | standalone_iterators.cpp:54:14:54:20 | source1 | |
-| stl.h:221:30:221:40 | call to allocator | stl.h:221:21:221:41 | noexcept(...) | TAINT |
-| stl.h:221:30:221:40 | call to allocator | stl.h:221:21:221:41 | noexcept(...) | TAINT |
-| stl.h:221:30:221:40 | call to allocator | stl.h:221:21:221:41 | noexcept(...) | TAINT |
-| stl.h:221:30:221:40 | call to allocator | stl.h:221:21:221:41 | noexcept(...) | TAINT |
-| stl.h:221:30:221:40 | call to allocator | stl.h:221:21:221:41 | noexcept(...) | TAINT |
-| stl.h:221:53:221:63 | 0 | stl.h:221:46:221:64 | (no string representation) | TAINT |
-| stl.h:314:9:314:9 | Unknown literal | stl.h:314:9:314:9 | constructor init of field first | TAINT |
-| stl.h:314:9:314:9 | Unknown literal | stl.h:314:9:314:9 | constructor init of field first | TAINT |
-| stl.h:314:9:314:9 | Unknown literal | stl.h:314:9:314:9 | constructor init of field second | TAINT |
-| stl.h:314:9:314:9 | Unknown literal | stl.h:314:9:314:9 | constructor init of field second | TAINT |
-| stl.h:314:9:314:9 | constructor init of field first [post-this] | stl.h:314:9:314:9 | constructor init of field second [pre-this] | |
-| stl.h:314:9:314:9 | constructor init of field first [post-this] | stl.h:314:9:314:9 | constructor init of field second [pre-this] | |
-| stl.h:314:9:314:9 | constructor init of field first [pre-this] | stl.h:314:9:314:9 | constructor init of field second [pre-this] | |
-| stl.h:314:9:314:9 | constructor init of field first [pre-this] | stl.h:314:9:314:9 | constructor init of field second [pre-this] | |
-| stl.h:314:9:314:9 | this | stl.h:314:9:314:9 | constructor init of field first [pre-this] | |
-| stl.h:314:9:314:9 | this | stl.h:314:9:314:9 | constructor init of field first [pre-this] | |
+| stl.h:222:30:222:40 | call to allocator | stl.h:222:21:222:41 | noexcept(...) | TAINT |
+| stl.h:222:30:222:40 | call to allocator | stl.h:222:21:222:41 | noexcept(...) | TAINT |
+| stl.h:222:30:222:40 | call to allocator | stl.h:222:21:222:41 | noexcept(...) | TAINT |
+| stl.h:222:30:222:40 | call to allocator | stl.h:222:21:222:41 | noexcept(...) | TAINT |
+| stl.h:222:30:222:40 | call to allocator | stl.h:222:21:222:41 | noexcept(...) | TAINT |
+| stl.h:222:53:222:63 | 0 | stl.h:222:46:222:64 | (no string representation) | TAINT |
+| stl.h:315:9:315:9 | Unknown literal | stl.h:315:9:315:9 | constructor init of field first | TAINT |
+| stl.h:315:9:315:9 | Unknown literal | stl.h:315:9:315:9 | constructor init of field first | TAINT |
+| stl.h:315:9:315:9 | Unknown literal | stl.h:315:9:315:9 | constructor init of field second | TAINT |
+| stl.h:315:9:315:9 | Unknown literal | stl.h:315:9:315:9 | constructor init of field second | TAINT |
+| stl.h:315:9:315:9 | constructor init of field first [post-this] | stl.h:315:9:315:9 | constructor init of field second [pre-this] | |
+| stl.h:315:9:315:9 | constructor init of field first [post-this] | stl.h:315:9:315:9 | constructor init of field second [pre-this] | |
+| stl.h:315:9:315:9 | constructor init of field first [pre-this] | stl.h:315:9:315:9 | constructor init of field second [pre-this] | |
+| stl.h:315:9:315:9 | constructor init of field first [pre-this] | stl.h:315:9:315:9 | constructor init of field second [pre-this] | |
+| stl.h:315:9:315:9 | this | stl.h:315:9:315:9 | constructor init of field first [pre-this] | |
+| stl.h:315:9:315:9 | this | stl.h:315:9:315:9 | constructor init of field first [pre-this] | |
| string.cpp:24:12:24:17 | call to source | string.cpp:28:7:28:7 | a | |
| string.cpp:25:16:25:20 | 123 | string.cpp:25:16:25:21 | call to basic_string | TAINT |
| string.cpp:25:16:25:21 | call to basic_string | string.cpp:29:7:29:7 | b | |
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp
index 0da7369cda2..ae8ad331518 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp
@@ -8,6 +8,10 @@ char *source();
void sink(char *);
void sink(const char *);
void sink(std::pair);
+void sink(std::map);
+void sink(std::map::iterator);
+void sink(std::unordered_map);
+void sink(std::unordered_map::iterator);
void test_pair()
{
@@ -44,9 +48,9 @@ void test_pair()
sink(f); // tainted [NOT DETECTED]
std::pair g(f);
- sink(f.first);
- sink(f.second); // tainted [NOT DETECTED]
- sink(f); // tainted [NOT DETECTED]
+ sink(g.first);
+ sink(g.second); // tainted [NOT DETECTED]
+ sink(g); // tainted [NOT DETECTED]
std::pair h;
h = f;
@@ -91,3 +95,304 @@ void test_pair()
sink(m.first.second); // tainted [NOT DETECTED]
sink(m.second);
}
+
+void test_map()
+{
+ // insert
+ std::map m1, m2, m3, m4, m5, m6;
+
+ sink(m1.insert(std::make_pair("abc", "def")).first);
+ sink(m2.insert(std::make_pair("abc", source())).first); // tainted [NOT DETECTED]
+ sink(m3.insert(std::make_pair(source(), "def")).first); // tainted [NOT DETECTED]
+ sink(m4.insert(m4.begin(), std::pair("abc", source()))); // tainted [NOT DETECTED]
+ sink(m5.insert_or_assign("abc", source()).first); // tainted [NOT DETECTED]
+ sink(m6.insert_or_assign(m6.begin(), "abc", source())); // tainted [NOT DETECTED]
+ sink(m1);
+ sink(m2); // tainted [NOT DETECTED]
+ sink(m3); // tainted [NOT DETECTED]
+ sink(m4); // tainted [NOT DETECTED]
+ sink(m5); // tainted [NOT DETECTED]
+ sink(m6); // tainted [NOT DETECTED]
+ sink(m1.find("abc"));
+ sink(m2.find("abc")); // tainted [NOT DETECTED]
+ sink(m3.find("abc"));
+ sink(m4.find("abc")); // tainted [NOT DETECTED]
+ sink(m5.find("abc")); // tainted [NOT DETECTED]
+ sink(m6.find("abc")); // tainted [NOT DETECTED]
+ sink(m1.find("def"));
+ sink(m2.find("def"));
+ sink(m3.find("def"));
+ sink(m4.find("def"));
+ sink(m5.find("def"));
+ sink(m6.find("def"));
+
+ // copy constructors and assignment
+ std::map m7(m2);
+ std::map m8 = m2;
+ std::map m9;
+ m9 = m2;
+ sink(m7); // tainted [NOT DETECTED]
+ sink(m8); // tainted [NOT DETECTED]
+ sink(m9); // tainted [NOT DETECTED]
+ sink(m7.find("abc")); // tainted [NOT DETECTED]
+ sink(m8.find("abc")); // tainted [NOT DETECTED]
+ sink(m9.find("abc")); // tainted [NOT DETECTED]
+
+ // iterators
+ std::map::iterator i1, i2, i3;
+ for (i1 = m1.begin(); i1 != m1.end(); i1++)
+ {
+ sink(*i1);
+ sink(i1->first);
+ sink(i1->second);
+ }
+ for (i2 = m2.begin(); i2 != m2.end(); i2++)
+ {
+ sink(*i2); // tainted [NOT DETECTED]
+ sink(i2->first);
+ sink(i2->second); // tainted [NOT DETECTED]
+ }
+ for (i3 = m3.begin(); i3 != m3.end(); i3++)
+ {
+ sink(*i3); // tainted [NOT DETECTED]
+ sink(i2->first); // tainted [NOT DETECTED]
+ sink(i2->second);
+ }
+
+ // array-like access
+ std::map m10, m11, m12, m13;
+ sink(m10["abc"] = "def");
+ sink(m11["abc"] = source()); // tainted
+ sink(m12.at("abc") = "def");
+ sink(m13.at("abc") = source()); // tainted
+ sink(m10["abc"]);
+ sink(m11["abc"]); // tainted [NOT DETECTED]
+ sink(m12["abc"]);
+ sink(m13["abc"]); // tainted [NOT DETECTED]
+
+ // ranges
+ std::map m14;
+ m14.insert(std::make_pair("a", "a"));
+ m14.insert(std::make_pair("b", source()));
+ m14.insert(std::make_pair("c", source()));
+ m14.insert(std::make_pair("d", "d"));
+ sink(m2.lower_bound("b")); // tainted [NOT DETECTED]
+ sink(m2.upper_bound("b")); // tainted [NOT DETECTED]
+ sink(m2.equal_range("b").first); // tainted [NOT DETECTED]
+ sink(m2.equal_range("b").second); // tainted [NOT DETECTED]
+ sink(m2.upper_bound("c"));
+ sink(m2.equal_range("c").second);
+
+ // swap
+ std::map m15, m16, m17, m18;
+ m15.insert(std::pair(source(), source()));
+ m18.insert(std::pair(source(), source()));
+ sink(m15); // tainted [NOT DETECTED]
+ sink(m16);
+ sink(m17);
+ sink(m18); // tainted [NOT DETECTED]
+ m15.swap(m16);
+ m17.swap(m18);
+ sink(m15);
+ sink(m16); // tainted [NOT DETECTED]
+ sink(m17); // tainted [NOT DETECTED]
+ sink(m18);
+
+ // merge
+ std::map m19, m20, m21, m22;
+ m19.insert(std::pair(source(), source()));
+ m20.insert(std::pair("abc", "def"));
+ m21.insert(std::pair("abc", "def"));
+ m22.insert(std::pair(source(), source()));
+ sink(m19); // tainted [NOT DETECTED]
+ sink(m20);
+ sink(m21);
+ sink(m22); // tainted [NOT DETECTED]
+ m15.merge(m16);
+ m17.merge(m18);
+ sink(m19); // tainted [NOT DETECTED]
+ sink(m20); // tainted [NOT DETECTED]
+ sink(m21); // tainted [NOT DETECTED]
+ sink(m22); // tainted [NOT DETECTED]
+
+ // erase, clear
+ std::map m23;
+ m23.insert(std::pair(source(), source()));
+ m23.insert(std::pair(source(), source()));
+ sink(m23); // tainted [NOT DETECTED]
+ sink(m23.erase(m23.begin())); // tainted [NOT DETECTED]
+ sink(m23); // tainted [NOT DETECTED]
+ m23.clear();
+ sink(m23);
+
+ // emplace, emplace_hint
+ std::map m24, m25;
+ sink(m24.emplace("abc", "def").first);
+ sink(m24);
+ sink(m24.emplace("abc", source()).first); // tainted [NOT DETECTED]
+ sink(m24); // tainted [NOT DETECTED]
+ sink(m25.emplace_hint(m25.begin(), "abc", "def"));
+ sink(m25);
+ sink(m25.emplace_hint(m25.begin(), "abc", source())); // tainted [NOT DETECTED]
+ sink(m25); // tainted [NOT DETECTED]
+
+ // try_emplace
+ std::map m26, m27;
+ sink(m26.try_emplace("abc", "def").first);
+ sink(m26);
+ sink(m26.try_emplace("abc", source()).first); // tainted [NOT DETECTED]
+ sink(m26); // tainted [NOT DETECTED]
+ sink(m27.try_emplace(m27.begin(), "abc", "def"));
+ sink(m27);
+ sink(m27.try_emplace(m27.begin(), "abc", source())); // tainted [NOT DETECTED]
+ sink(m27); // tainted [NOT DETECTED]
+}
+
+void test_unordered_map()
+{
+ // insert
+ std::unordered_map m1, m2, m3, m4, m5, m6;
+
+ sink(m1.insert(std::make_pair("abc", "def")).first);
+ sink(m2.insert(std::make_pair("abc", source())).first); // tainted [NOT DETECTED]
+ sink(m3.insert(std::make_pair(source(), "def")).first); // tainted [NOT DETECTED]
+ sink(m4.insert(m4.begin(), std::pair("abc", source()))); // tainted [NOT DETECTED]
+ sink(m5.insert_or_assign("abc", source()).first); // tainted [NOT DETECTED]
+ sink(m6.insert_or_assign(m6.begin(), "abc", source())); // tainted [NOT DETECTED]
+ sink(m1);
+ sink(m2); // tainted [NOT DETECTED]
+ sink(m3); // tainted [NOT DETECTED]
+ sink(m4); // tainted [NOT DETECTED]
+ sink(m5); // tainted [NOT DETECTED]
+ sink(m6); // tainted [NOT DETECTED]
+ sink(m1.find("abc"));
+ sink(m2.find("abc")); // tainted [NOT DETECTED]
+ sink(m3.find("abc"));
+ sink(m4.find("abc")); // tainted [NOT DETECTED]
+ sink(m5.find("abc")); // tainted [NOT DETECTED]
+ sink(m6.find("abc")); // tainted [NOT DETECTED]
+ sink(m1.find("def"));
+ sink(m2.find("def"));
+ sink(m3.find("def"));
+ sink(m4.find("def"));
+ sink(m5.find("def"));
+ sink(m6.find("def"));
+
+ // copy constructors and assignment
+ std::unordered_map m7(m2);
+ std::unordered_map m8 = m2;
+ std::unordered_map m9;
+ m9 = m2;
+ sink(m7); // tainted [NOT DETECTED]
+ sink(m8); // tainted [NOT DETECTED]
+ sink(m9); // tainted [NOT DETECTED]
+ sink(m7.find("abc")); // tainted [NOT DETECTED]
+ sink(m8.find("abc")); // tainted [NOT DETECTED]
+ sink(m9.find("abc")); // tainted [NOT DETECTED]
+
+ // iterators
+ std::unordered_map::iterator i1, i2, i3;
+ for (i1 = m1.begin(); i1 != m1.end(); i1++)
+ {
+ sink(*i1);
+ sink(i1->first);
+ sink(i1->second);
+ }
+ for (i2 = m2.begin(); i2 != m2.end(); i2++)
+ {
+ sink(*i2); // tainted [NOT DETECTED]
+ sink(i2->first);
+ sink(i2->second); // tainted [NOT DETECTED]
+ }
+ for (i3 = m3.begin(); i3 != m3.end(); i3++)
+ {
+ sink(*i3); // tainted [NOT DETECTED]
+ sink(i2->first); // tainted [NOT DETECTED]
+ sink(i2->second);
+ }
+
+ // array-like access
+ std::unordered_map m10, m11, m12, m13;
+ sink(m10["abc"] = "def");
+ sink(m11["abc"] = source()); // tainted
+ sink(m12.at("abc") = "def");
+ sink(m13.at("abc") = source()); // tainted
+ sink(m10["abc"]);
+ sink(m11["abc"]); // tainted [NOT DETECTED]
+ sink(m12["abc"]);
+ sink(m13["abc"]); // tainted [NOT DETECTED]
+
+ // ranges
+ std::unordered_map m14;
+ m14.insert(std::make_pair("a", "a"));
+ m14.insert(std::make_pair("b", source()));
+ m14.insert(std::make_pair("c", source()));
+ m14.insert(std::make_pair("d", "d"));
+ sink(m2.equal_range("b").first); // tainted [NOT DETECTED]
+ sink(m2.equal_range("b").second); // tainted [NOT DETECTED]
+ sink(m2.equal_range("c").second);
+
+ // swap
+ std::unordered_map m15, m16, m17, m18;
+ m15.insert(std::pair(source(), source()));
+ m18.insert(std::pair(source(), source()));
+ sink(m15); // tainted [NOT DETECTED]
+ sink(m16);
+ sink(m17);
+ sink(m18); // tainted [NOT DETECTED]
+ m15.swap(m16);
+ m17.swap(m18);
+ sink(m15);
+ sink(m16); // tainted [NOT DETECTED]
+ sink(m17); // tainted [NOT DETECTED]
+ sink(m18);
+
+ // merge
+ std::unordered_map m19, m20, m21, m22;
+ m19.insert(std::pair(source(), source()));
+ m20.insert(std::pair("abc", "def"));
+ m21.insert(std::pair("abc", "def"));
+ m22.insert(std::pair(source(), source()));
+ sink(m19); // tainted [NOT DETECTED]
+ sink(m20);
+ sink(m21);
+ sink(m22); // tainted [NOT DETECTED]
+ m15.merge(m16);
+ m17.merge(m18);
+ sink(m19); // tainted [NOT DETECTED]
+ sink(m20); // tainted [NOT DETECTED]
+ sink(m21); // tainted [NOT DETECTED]
+ sink(m22); // tainted [NOT DETECTED]
+
+ // erase, clear
+ std::unordered_map m23;
+ m23.insert(std::pair(source(), source()));
+ m23.insert(std::pair(source(), source()));
+ sink(m23); // tainted [NOT DETECTED]
+ sink(m23.erase(m23.begin())); // tainted [NOT DETECTED]
+ sink(m23); // tainted [NOT DETECTED]
+ m23.clear();
+ sink(m23);
+
+ // emplace, emplace_hint
+ std::unordered_map m24, m25;
+ sink(m24.emplace("abc", "def").first);
+ sink(m24);
+ sink(m24.emplace("abc", source()).first); // tainted [NOT DETECTED]
+ sink(m24); // tainted [NOT DETECTED]
+ sink(m25.emplace_hint(m25.begin(), "abc", "def"));
+ sink(m25);
+ sink(m25.emplace_hint(m25.begin(), "abc", source())); // tainted [NOT DETECTED]
+ sink(m25); // tainted [NOT DETECTED]
+
+ // try_emplace
+ std::unordered_map m26, m27;
+ sink(m26.try_emplace("abc", "def").first);
+ sink(m26);
+ sink(m26.try_emplace("abc", source()).first); // tainted [NOT DETECTED]
+ sink(m26); // tainted [NOT DETECTED]
+ sink(m27.try_emplace(m27.begin(), "abc", "def"));
+ sink(m27);
+ sink(m27.try_emplace(m27.begin(), "abc", source())); // tainted [NOT DETECTED]
+ sink(m27); // tainted [NOT DETECTED]
+}
diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h b/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h
index c6b2150510f..3a112cd0c88 100644
--- a/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h
+++ b/cpp/ql/test/library-tests/dataflow/taint-tests/stl.h
@@ -36,6 +36,7 @@ namespace std {
bool operator==(iterator other) const;
bool operator!=(iterator other) const;
reference_type operator*() const;
+ pointer_type operator->() const;
iterator operator+(int);
iterator operator-(int);
iterator &operator+=(int);
@@ -326,3 +327,137 @@ namespace std {
template pair make_pair(T1, T2);
}
+
+// --- map ---
+
+namespace std {
+ template struct less;
+
+ template, class Allocator = allocator>>
+ class map {
+ public:
+ using key_type = Key;
+ using mapped_type = T;
+ using value_type = pair;
+ using iterator = std::iterator;
+ using const_iterator = std::iterator;
+
+ map() /*: map(Compare()) { }*/;
+ map(const map& x);
+ map(map&& x);
+ ~map();
+
+ map& operator=(const map& x);
+ map& operator=(map&& x) /*noexcept(allocator_traits::is_always_equal::value && is_nothrow_move_assignable_v)*/;
+
+ iterator begin() noexcept;
+ const_iterator begin() const noexcept;
+ iterator end() noexcept;
+ const_iterator end() const noexcept;
+
+ T& operator[](const key_type& x);
+ T& operator[](key_type&& x);
+ T& at(const key_type& x);
+ const T& at(const key_type& x) const;
+
+ template pair emplace(Args&&... args);
+ template iterator emplace_hint(const_iterator position, Args&&... args);
+
+ pair insert(const value_type& x);
+ pair insert(value_type&& x);
+ iterator insert(const_iterator position, const value_type& x);
+ iterator insert(const_iterator position, value_type&& x);
+
+ template pair try_emplace(const key_type& k, Args&&... args);
+ template pair try_emplace(key_type&& k, Args&&... args);
+ template iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
+ template iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
+ template pair insert_or_assign(const key_type& k, M&& obj);
+ template pair insert_or_assign(key_type&& k, M&& obj);
+ template iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj);
+ template iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj);
+
+ iterator erase(iterator position);
+ iterator erase(const_iterator position);
+ iterator erase(const_iterator first, const_iterator last);
+ void swap(map&) /*noexcept(/*==allocator_traits::is_always_equal::value && is_nothrow_swappable_v)*/;
+ void clear() noexcept;
+
+ template void merge(map& source);
+ template void merge(map&& source);
+
+ iterator find(const key_type& x);
+ const_iterator find(const key_type& x) const;
+
+ iterator lower_bound(const key_type& x);
+ const_iterator lower_bound(const key_type& x) const;
+ iterator upper_bound(const key_type& x);
+ const_iterator upper_bound(const key_type& x) const;
+
+ pair equal_range(const key_type& x);
+ pair equal_range(const key_type& x) const;
+ };
+
+ template struct hash;
+ template struct equal_to;
+
+ template, class Pred = equal_to, class Allocator = allocator>>
+ class unordered_map {
+ public:
+ using key_type = Key;
+ using mapped_type = T;
+ using value_type = pair;
+ using iterator = std::iterator;
+ using const_iterator = std::iterator;
+
+ unordered_map();
+ unordered_map(const unordered_map&);
+ unordered_map(unordered_map&&);
+ ~unordered_map();
+
+ unordered_map& operator=(const unordered_map&);
+ unordered_map& operator=(unordered_map&&) /*noexcept(allocator_traits::is_always_equal::value && is_nothrow_move_assignable_v && is_nothrow_move_assignable_v)*/;
+
+ iterator begin() noexcept;
+ const_iterator begin() const noexcept;
+ iterator end() noexcept;
+ const_iterator end() const noexcept;
+
+ mapped_type& operator[](const key_type& k);
+ mapped_type& operator[](key_type&& k);
+ mapped_type& at(const key_type& k);
+ const mapped_type& at(const key_type& k) const;
+
+ template pair emplace(Args&&... args);
+ template iterator emplace_hint(const_iterator position, Args&&... args);
+
+ pair insert(const value_type& obj);
+ pair insert(value_type&& obj);
+ iterator insert(const_iterator hint, const value_type& obj);
+ iterator insert(const_iterator hint, value_type&& obj);
+
+ template pair try_emplace(const key_type& k, Args&&... args);
+ template pair try_emplace(key_type&& k, Args&&... args);
+ template iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args);
+ template iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args);
+ template pair insert_or_assign(const key_type& k, M&& obj);
+ template pair