Skip to content

Commit 3e022ad

Browse files
authored
Merge pull request #270 from geoffw0/negindex
CPP: Improvements to Buffer.qll
2 parents c064b1f + 8163def commit 3e022ad

File tree

1 file changed

+24
-12
lines changed

1 file changed

+24
-12
lines changed

cpp/ql/src/semmle/code/cpp/commons/Buffer.qll

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import cpp
2+
import semmle.code.cpp.dataflow.DataFlow
23

34
/**
45
* Holds if `sizeof(s)` occurs as part of the parameter of a dynamic
@@ -47,6 +48,7 @@ predicate memberMayBeVarSize(Class c, MemberVariable v) {
4748
/**
4849
* Get the size in bytes of the buffer pointed to by an expression (if this can be determined).
4950
*/
51+
language[monotonicAggregates]
5052
int getBufferSize(Expr bufferExpr, Element why) {
5153
exists(Variable bufferVar | bufferVar = bufferExpr.(VariableAccess).getTarget() |
5254
(
@@ -58,6 +60,10 @@ int getBufferSize(Expr bufferExpr, Element why) {
5860
// buffer is an initialized array
5961
// e.g. int buffer[] = {1, 2, 3};
6062
why = bufferVar.getInitializer().getExpr() and
63+
(
64+
why instanceof AggregateLiteral or
65+
why instanceof StringLiteral
66+
) and
6167
result = why.(Expr).getType().(ArrayType).getSize() and
6268
not exists(bufferVar.getType().getUnspecifiedType().(ArrayType).getSize())
6369
) or exists(Class parentClass, VariableAccess parentPtr |
@@ -71,19 +77,25 @@ int getBufferSize(Expr bufferExpr, Element why) {
7177
bufferVar.getType().getSize() -
7278
parentClass.getSize()
7379
)
74-
) or exists(Expr def |
75-
// buffer is assigned with an allocation
76-
definitionUsePair(_, def, bufferExpr) and
77-
exprDefinition(_, def, why) and
78-
isFixedSizeAllocationExpr(why, result)
79-
) or exists(Expr def, Expr e, Element why2 |
80-
// buffer is assigned with another buffer
81-
definitionUsePair(_, def, bufferExpr) and
82-
exprDefinition(_, def, e) and
83-
result = getBufferSize(e, why2) and
84-
(
80+
) or (
81+
// buffer is a fixed size dynamic allocation
82+
isFixedSizeAllocationExpr(bufferExpr, result) and
83+
why = bufferExpr
84+
) or (
85+
// dataflow (all sources must be the same size)
86+
result = min(Expr def |
87+
DataFlow::localFlowStep(DataFlow::exprNode(def), DataFlow::exprNode(bufferExpr)) |
88+
getBufferSize(def, _)
89+
) and result = max(Expr def |
90+
DataFlow::localFlowStep(DataFlow::exprNode(def), DataFlow::exprNode(bufferExpr)) |
91+
getBufferSize(def, _)
92+
) and
93+
94+
// find reason
95+
exists(Expr def |
96+
DataFlow::localFlowStep(DataFlow::exprNode(def), DataFlow::exprNode(bufferExpr)) |
8597
why = def or
86-
why = why2
98+
exists(getBufferSize(def, why))
8799
)
88100
) or exists(Type bufferType |
89101
// buffer is the address of a variable

0 commit comments

Comments
 (0)