Skip to content

Commit 2b36ba3

Browse files
committed
C++: Add support for 'data' in the query.
1 parent 7b8d164 commit 2b36ba3

File tree

4 files changed

+17
-3
lines changed

4 files changed

+17
-3
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,11 @@ private class StdStringCStrModel extends StdStringCStr, StdStringTaintFunction {
114114
/**
115115
* The `std::string` function `data`.
116116
*/
117-
private class StdStringData extends StdStringTaintFunction {
117+
class StdStringData extends MemberFunction {
118118
StdStringData() { this.getClassAndName("data") instanceof StdBasicString }
119+
}
119120

121+
private class StdStringDataModel extends StdStringData, StdStringTaintFunction {
120122
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
121123
// flow from string itself (qualifier) to return value
122124
input.isQualifierObject() and

cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import semmle.code.cpp.models.implementations.StdContainer
2222
* a temporary object.
2323
*/
2424
predicate isTemporary(Expr e) {
25+
e instanceof TemporaryObjectExpr
26+
or
2527
e.isPRValueCategory() and
2628
e.getUnspecifiedType() instanceof Class and
2729
not e.hasLValueToRValueConversion()
@@ -92,7 +94,7 @@ from Call c
9294
where
9395
outlivesFullExpr(c) and
9496
not c.isFromUninstantiatedTemplate(_) and
95-
c.getTarget() instanceof StdStringCStr and
97+
(c.getTarget() instanceof StdStringCStr or c.getTarget() instanceof StdStringData) and
9698
isTemporary(c.getQualifier().getFullyConverted())
9799
select c,
98100
"The underlying string object is destroyed after the call to '" + c.getTarget() + "' returns."

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,8 @@
55
| test.cpp:178:37:178:41 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. |
66
| test.cpp:181:39:181:43 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. |
77
| test.cpp:183:37:183:41 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. |
8-
| test.cpp:187:31:187:35 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. |
8+
| test.cpp:187:34:187:37 | call to data | The underlying string object is destroyed after the call to 'data' returns. |
9+
| test.cpp:188:39:188:42 | call to data | The underlying string object is destroyed after the call to 'data' returns. |
10+
| test.cpp:189:44:189:47 | call to data | The underlying string object is destroyed after the call to 'data' returns. |
11+
| 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. |

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,12 @@ const char* test1(bool b1, bool b2) {
184184

185185
char c = std::string("hello").c_str()[0]; // GOOD
186186

187+
auto s6 = std::string("hello").data(); // BAD
188+
auto s7 = b1 ? std::string("hello").data() : ""; // BAD
189+
auto s8 = b2 ? "" : std::string("hello").data(); // BAD
190+
char* s9;
191+
s9 = std::string("hello").data(); // BAD
192+
187193
return std::string("hello").c_str(); // BAD
188194
}
189195

0 commit comments

Comments
 (0)