@@ -10,11 +10,18 @@ import semmle.code.cpp.dataflow.DataFlow
10
10
* char data[1]; // v
11
11
* };
12
12
* ```
13
- * This requires that `v` is an array of size 0 or 1.
13
+ * or
14
+ * ```
15
+ * struct myStruct { // c
16
+ * int amount;
17
+ * char data[]; // v
18
+ * };
19
+ * ```
20
+ * This requires that `v` is an array of size 0 or 1, or that the array has no size.
14
21
*/
15
22
predicate memberMayBeVarSize ( Class c , MemberVariable v ) {
16
23
c = v .getDeclaringType ( ) and
17
- v .getUnspecifiedType ( ) . ( ArrayType ) . getArraySize ( ) <= 1
24
+ exists ( ArrayType t | t = v .getUnspecifiedType ( ) | not t . getArraySize ( ) > 1 )
18
25
}
19
26
20
27
/**
@@ -40,13 +47,18 @@ int getBufferSize(Expr bufferExpr, Element why) {
40
47
result = why .( Expr ) .getType ( ) .( ArrayType ) .getSize ( ) and
41
48
not exists ( bufferVar .getUnspecifiedType ( ) .( ArrayType ) .getSize ( ) )
42
49
or
43
- exists ( Class parentClass , VariableAccess parentPtr |
50
+ exists ( Class parentClass , VariableAccess parentPtr , int bufferSize |
44
51
// buffer is the parentPtr->bufferVar of a 'variable size struct'
45
52
memberMayBeVarSize ( parentClass , bufferVar ) and
46
53
why = bufferVar and
47
54
parentPtr = bufferExpr .( VariableAccess ) .getQualifier ( ) and
48
55
parentPtr .getTarget ( ) .getUnspecifiedType ( ) .( PointerType ) .getBaseType ( ) = parentClass and
49
- result = getBufferSize ( parentPtr , _) + bufferVar .getType ( ) .getSize ( ) - parentClass .getSize ( )
56
+ (
57
+ if exists ( bufferVar .getType ( ) .getSize ( ) )
58
+ then bufferSize = bufferVar .getType ( ) .getSize ( )
59
+ else bufferSize = 0
60
+ ) and
61
+ result = getBufferSize ( parentPtr , _) + bufferSize - parentClass .getSize ( )
50
62
)
51
63
)
52
64
or
0 commit comments