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

Skip to content

Commit 5a8b900

Browse files
committed
C++: Properly track smart pointer wrappers.
1 parent 64abf5b commit 5a8b900

5 files changed

Lines changed: 23 additions & 7 deletions

File tree

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,22 @@ private class PointerOrReferenceTypeIndirection extends Indirection instanceof P
186186
override int getNumberOfIndirections() {
187187
result = 1 + countIndirections(this.getBaseType().getUnspecifiedType())
188188
}
189+
}
189190

190-
override predicate isAdditionalDereference(Instruction deref, Operand address) { none() }
191+
private class PointerWrapperTypeIndirection extends Indirection instanceof PointerWrapper {
192+
PointerWrapperTypeIndirection() { baseType = PointerWrapper.super.getBaseType() }
191193

192-
override predicate isAdditionalWrite(Node0Impl value, Operand address, boolean certain) { none() }
194+
override int getNumberOfIndirections() {
195+
result = 1 + countIndirections(this.getBaseType().getUnspecifiedType())
196+
}
197+
198+
override predicate isAdditionalDereference(Instruction deref, Operand address) {
199+
exists(CallInstruction call |
200+
operandForFullyConvertedCall(getAUse(deref), call) and
201+
this = call.getStaticCallTarget().getClassAndName("operator*") and
202+
address = call.getThisArgumentOperand()
203+
)
204+
}
193205
}
194206

195207
private module IteratorIndirections {

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ private class SmartPtr extends Class, PointerWrapper {
1717
}
1818

1919
override predicate pointsToConst() { this.getTemplateArgument(0).(Type).isConst() }
20+
21+
override Type getBaseType() { result = this.getTemplateArgument(0) }
2022
}
2123

2224
/**

cpp/ql/lib/semmle/code/cpp/models/interfaces/PointerWrapper.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,7 @@ abstract class PointerWrapper extends Class {
1414

1515
/** Holds if the type of the data that is pointed to by this pointer wrapper is `const`. */
1616
abstract predicate pointsToConst();
17+
18+
/** Gets the type pointed to by this pointer wrapper type. */
19+
abstract Type getBaseType();
1720
}
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +0,0 @@
1-
| test.cpp:34:13:34:23 | // $ ast,ir | Missing result:ir= |

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,11 @@ struct B {
8585

8686
void test_operator_arrow(std::unique_ptr<A> p, std::unique_ptr<B> q) {
8787
p->x = source();
88-
sink(p->x); // $ ast MISSING: ir
88+
sink(p->x); // $ ast,ir
8989
sink(p->y);
9090

9191
q->a1.x = source();
92-
sink(q->a1.x); // $ ast MISSING: ir
92+
sink(q->a1.x); // $ ast,ir
9393
sink(q->a1.y);
9494
sink(q->a2.x);
9595
}
@@ -101,7 +101,7 @@ void taint_x(A* pa) {
101101
void reverse_taint_smart_pointer() {
102102
std::unique_ptr<A> p = std::unique_ptr<A>(new A);
103103
taint_x(p.get());
104-
sink(p->x); // $ ast MISSING: ir
104+
sink(p->x); // $ ast,ir
105105
}
106106

107107
struct C {
@@ -131,7 +131,7 @@ int nested_shared_ptr_taint(std::shared_ptr<C> p1, std::unique_ptr<std::shared_p
131131

132132
int nested_shared_ptr_taint_cref(std::shared_ptr<C> p1, std::unique_ptr<std::shared_ptr<int>> p2) {
133133
taint_x_shared_cref(p1->q);
134-
sink(p1->q->x); // $ ast MISSING: ir
134+
sink(p1->q->x); // $ ast,ir
135135

136136
getNumberCRef(*p2);
137137
sink(**p2); // $ ast,ir

0 commit comments

Comments
 (0)