Skip to content

Commit 49e1467

Browse files
committed
CPP: Fix handling of ternary operators in tempory queries and add tests.
1 parent 236a6a1 commit 49e1467

File tree

5 files changed

+20
-3
lines changed

5 files changed

+20
-3
lines changed

cpp/ql/src/Security/CWE/CWE-416/Temporaries.qll

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,21 @@ predicate isStoredInContainer(Expr e) {
4141
)
4242
}
4343

44+
45+
/**
46+
* Holds if `e` or a conversion of `e` has an lvalue-to-rvalue conversion.
47+
*/
48+
predicate hasLValueToRValueConversion(Expr e) {
49+
e.getConversion*().hasLValueToRValueConversion() and
50+
not e instanceof ConditionalExpr // ConditionalExpr may be spuriously reported as having an lvalue-to-rvalue conversion
51+
}
52+
4453
/**
4554
* Holds if the value of `e` outlives the enclosing full expression. For
4655
* example, because the value is stored in a local variable.
4756
*/
4857
predicate outlivesFullExpr(Expr e) {
49-
not e.getConversion*().hasLValueToRValueConversion() and
58+
not hasLValueToRValueConversion(e) and
5059
(
5160
any(Assignment assign).getRValue() = e
5261
or

cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/UseOfStringAfterLifetimeEnds/UseOfStringAfterLifetimeEnds.expected

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@
99
| test.cpp:188:39:188:42 | call to data | The underlying string object is destroyed after the call to 'data' returns. |
1010
| test.cpp:189:44:189:47 | call to data | The underlying string object is destroyed after the call to 'data' returns. |
1111
| test.cpp:191:29:191:32 | call to data | The underlying string object is destroyed after the call to 'data' returns. |
12-
| test.cpp:193:31:193:35 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. |
12+
| test.cpp:193:47:193:51 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. |
13+
| test.cpp:195:31:195:35 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. |

cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/UseOfStringAfterLifetimeEnds/test.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ const char* test1(bool b1, bool b2) {
190190
char* s9;
191191
s9 = std::string("hello").data(); // BAD
192192

193+
const char* s13 = b1 ? std::string("hello").c_str() : s1; // BAD
194+
193195
return std::string("hello").c_str(); // BAD
194196
}
195197

cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/UseOfUniquePtrAfterLifetimeEnds/UseOfUniquePointerAfterLifetimeEnds.expected

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@
66
| test.cpp:163:25:163:27 | call to get | The underlying unique pointer object is destroyed after the call to 'get' returns. |
77
| test.cpp:172:33:172:35 | call to get | The underlying unique pointer object is destroyed after the call to 'get' returns. |
88
| test.cpp:174:32:174:34 | call to get | The underlying unique pointer object is destroyed after the call to 'get' returns. |
9-
| test.cpp:176:11:176:11 | call to operator* | The underlying unique pointer object is destroyed after the call to 'operator*' returns. |
9+
| test.cpp:177:16:177:16 | call to operator* | The underlying unique pointer object is destroyed after the call to 'operator*' returns. |
10+
| test.cpp:177:36:177:36 | call to operator* | The underlying unique pointer object is destroyed after the call to 'operator*' returns. |
11+
| test.cpp:179:11:179:11 | call to operator* | The underlying unique pointer object is destroyed after the call to 'operator*' returns. |

cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/UseOfUniquePtrAfterLifetimeEnds/test.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ const S* test1(bool b1, bool b2) {
173173

174174
S* s5[] = { get_unique_ptr().get() }; // BAD
175175

176+
S s6 = b1 ? *get_unique_ptr() : *get_unique_ptr(); // GOOD
177+
S& s7 = b1 ? *get_unique_ptr() : *get_unique_ptr(); // BAD
178+
176179
return &*get_unique_ptr(); // BAD
177180
}
178181

0 commit comments

Comments
 (0)