Skip to content

Commit d22e2ba

Browse files
committed
C++: Select the post-update node in 'getADestroyedNode'.
1 parent b2974ba commit d22e2ba

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

cpp/ql/src/experimental/Security/CWE/CWE-416/IteratorToExpiredContainer.ql

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ module TempToDestructorConfig implements DataFlow::ConfigSig {
3737

3838
module TempToDestructorFlow = DataFlow::Global<TempToDestructorConfig>;
3939

40+
/** Holds if `pun` is the post-update node of the qualifier of `Call`. */
41+
private predicate isPostUpdateOfQualifier(CallInstruction call, DataFlow::PostUpdateNode pun) {
42+
call.getThisArgumentOperand() = pun.getPreUpdateNode().asOperand()
43+
}
44+
4045
/**
4146
* Gets a `DataFlow::Node` that represents a temporary that will be destroyed
4247
* by a call to a destructor, or a `DataFlow::Node` that will transitively be
@@ -53,8 +58,12 @@ module TempToDestructorFlow = DataFlow::Global<TempToDestructorConfig>;
5358
* and thus the result of `get_2d_vector()[0]` is also an invalid reference.
5459
*/
5560
DataFlow::Node getADestroyedNode() {
56-
exists(TempToDestructorFlow::PathNode destroyedTemp | destroyedTemp.isSource() |
57-
result = destroyedTemp.getNode()
61+
exists(DataFlow::Node n | TempToDestructorFlow::flowTo(n) |
62+
// Case 1: The pointer that goes into the destructor call is destroyed
63+
exists(CallInstruction destructorCall |
64+
tempToDestructorSink(n, destructorCall) and
65+
isPostUpdateOfQualifier(destructorCall, result)
66+
)
5867
or
5968
exists(CallInstruction call |
6069
result.asInstruction() = call and

0 commit comments

Comments
 (0)