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