11import 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]
5052int 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