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

Skip to content

Commit b7e42e8

Browse files
author
Robert Marsh
authored
Merge pull request #10994 from rdmarsh2/rdmarsh2/return-cstr-repair
C++: repair the ReturnCstr query
2 parents e43422a + 24cb36a commit b7e42e8

5 files changed

Lines changed: 112 additions & 90 deletions

File tree

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

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -738,11 +738,20 @@ private predicate exprNodeShouldBeIndirectOperand(IndirectOperand node, Expr e,
738738
not convertedExprMustBeOperand(e)
739739
}
740740

741+
private predicate exprNodeShouldBeIndirectOutNode(IndirectArgumentOutNode node, Expr e) {
742+
exists(CallInstruction call |
743+
call.getStaticCallTarget() instanceof Constructor and
744+
e = call.getConvertedResultExpression() and
745+
call.getThisArgumentOperand() = node.getAddressOperand()
746+
)
747+
}
748+
741749
/** Holds if `node` should be an instruction node that maps `node.asExpr()` to `e`. */
742750
predicate exprNodeShouldBeInstruction(Node node, Expr e) {
743751
e = node.asInstruction().getConvertedResultExpression() and
744752
not exprNodeShouldBeOperand(_, e) and
745-
not exprNodeShouldBeIndirectOperand(_, e, _)
753+
not exprNodeShouldBeIndirectOperand(_, e, _) and
754+
not exprNodeShouldBeIndirectOutNode(_, e)
746755
}
747756

748757
private class ExprNodeBase extends Node {
@@ -792,6 +801,16 @@ private class IndirectOperandExprNode extends ExprNodeBase, IndirectOperand {
792801
final override string toStringImpl() { result = this.getConvertedExpr().toString() }
793802
}
794803

804+
private class IndirectArgumentOutExprNode extends ExprNodeBase, IndirectArgumentOutNode {
805+
IndirectArgumentOutExprNode() { exprNodeShouldBeIndirectOutNode(this, _) }
806+
807+
final override Expr getConvertedExpr() { exprNodeShouldBeIndirectOutNode(this, result) }
808+
809+
final override Expr getExpr() { result = this.getConvertedExpr() }
810+
811+
final override string toStringImpl() { result = this.getConvertedExpr().toString() }
812+
}
813+
795814
/**
796815
* An expression, viewed as a node in a data flow graph.
797816
*/

cpp/ql/src/Likely Bugs/Memory Management/ReturnCstrOfLocalStdString.ql

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,20 @@ class StdString extends Class {
3636
* Holds if `e` is a direct or indirect reference to a locally
3737
* allocated `std::string`.
3838
*/
39-
predicate refToStdString(Expr e, ConstructorCall source) {
39+
predicate refToStdString(DataFlow::Node node, ConstructorCall source) {
4040
exists(StdString stdstring |
4141
stdstring.getAMemberFunction() = source.getTarget() and
4242
not exists(LocalVariable v |
4343
source = v.getInitializer().getExpr() and
4444
v.isStatic()
4545
) and
46-
e = source
46+
node.asExpr() = source
4747
)
4848
or
4949
// Indirect use.
50-
exists(Expr prev |
50+
exists(DataFlow::Node prev |
5151
refToStdString(prev, source) and
52-
DataFlow::localFlowStep(DataFlow::exprNode(prev), DataFlow::exprNode(e))
52+
DataFlow::localFlowStep(prev, node)
5353
)
5454
}
5555

@@ -74,29 +74,30 @@ predicate flowFunction(Function fcn, int argIndex) {
7474
* Holds if `e` is a direct or indirect reference to the result of calling
7575
* `c_str` on a locally allocated `std::string`.
7676
*/
77-
predicate refToCStr(Expr e, ConstructorCall source) {
78-
exists(MemberFunction f, FunctionCall call |
77+
predicate refToCStr(DataFlow::Node node, ConstructorCall source) {
78+
exists(MemberFunction f, FunctionCall call, DataFlow::Node qualifier |
7979
f.getName() = "c_str" and
80-
call = e and
80+
call = node.asExpr() and
8181
call.getTarget() = f and
82-
refToStdString(call.getQualifier(), source)
82+
qualifier.asIndirectArgument() = call.getQualifier() and
83+
refToStdString(qualifier, source)
8384
)
8485
or
8586
// Indirect use.
86-
exists(Expr prev |
87+
exists(DataFlow::Node prev |
8788
refToCStr(prev, source) and
88-
DataFlow::localFlowStep(DataFlow::exprNode(prev), DataFlow::exprNode(e))
89+
DataFlow::localFlowStep(prev, node)
8990
)
9091
or
9192
// Some functions, such as `JNIEnv::NewStringUTF()` (from Java's JNI)
9293
// embed return a structure containing a reference to the C-style string.
9394
exists(Function f, int argIndex |
9495
flowFunction(f, argIndex) and
95-
f = e.(Call).getTarget() and
96-
refToCStr(e.(Call).getArgument(argIndex), source)
96+
f = node.asExpr().(Call).getTarget() and
97+
refToCStr(DataFlow::exprNode(node.asExpr().(Call).getArgument(argIndex)), source)
9798
)
9899
}
99100

100101
from ReturnStmt r, ConstructorCall source
101-
where refToCStr(r.getExpr(), source)
102+
where refToCStr(DataFlow::exprNode(r.getExpr()), source)
102103
select r, "Return value may contain a dangling pointer to $@.", source, "this local std::string"

0 commit comments

Comments
 (0)