@@ -10,11 +10,18 @@ import semmle.code.cpp.dataflow.DataFlow
1010 * char data[1]; // v
1111 * };
1212 * ```
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.
1421 */
1522predicate memberMayBeVarSize ( Class c , MemberVariable v ) {
1623 c = v .getDeclaringType ( ) and
17- v .getUnspecifiedType ( ) . ( ArrayType ) . getArraySize ( ) <= 1
24+ exists ( ArrayType t | t = v .getUnspecifiedType ( ) | not t . getArraySize ( ) > 1 )
1825}
1926
2027/**
@@ -40,13 +47,18 @@ int getBufferSize(Expr bufferExpr, Element why) {
4047 result = why .( Expr ) .getType ( ) .( ArrayType ) .getSize ( ) and
4148 not exists ( bufferVar .getUnspecifiedType ( ) .( ArrayType ) .getSize ( ) )
4249 or
43- exists ( Class parentClass , VariableAccess parentPtr |
50+ exists ( Class parentClass , VariableAccess parentPtr , int bufferSize |
4451 // buffer is the parentPtr->bufferVar of a 'variable size struct'
4552 memberMayBeVarSize ( parentClass , bufferVar ) and
4653 why = bufferVar and
4754 parentPtr = bufferExpr .( VariableAccess ) .getQualifier ( ) and
4855 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 ( )
5062 )
5163 )
5264 or
0 commit comments