11import cpp
22import semmle.code.cpp.dataflow.DataFlow
33
4- /**
5- * Holds if `sizeof(s)` occurs as part of the parameter of a dynamic
6- * memory allocation (`malloc`, `realloc`, etc.), except if `sizeof(s)`
7- * only ever occurs as the immediate parameter to allocations.
8- *
9- * For example, holds for `s` if it occurs as
10- * ```
11- * malloc(sizeof(s) + 100 * sizeof(char))
12- * ```
13- * but not if it only ever occurs as
14- * ```
15- * malloc(sizeof(s))
16- * ```
17- */
18- private predicate isDynamicallyAllocatedWithDifferentSize ( Class s ) {
19- exists ( SizeofOperator so |
20- so .( SizeofTypeOperator ) .getTypeOperand ( ) .getUnspecifiedType ( ) = s or
21- so .( SizeofExprOperator ) .getExprOperand ( ) .getType ( ) .getUnspecifiedType ( ) = s |
22- // Check all ancestor nodes except the immediate parent for
23- // allocations.
24- isStdLibAllocationExpr ( so .getParent ( ) .( Expr ) .getParent + ( ) )
25- )
26- }
27-
284/**
295 * Holds if `v` is a member variable of `c` that looks like it might be variable sized in practice. For
306 * example:
@@ -35,15 +11,38 @@ private predicate isDynamicallyAllocatedWithDifferentSize(Class s) {
3511 * };
3612 * ```
3713 * This requires that `v` is an array of size 0 or 1, and `v` is the last member of `c`. In addition,
38- * there must be at least one instance where a `c` pointer is allocated with additional space.
14+ * there must be at least one instance where a `c` pointer is allocated with additional space. For
15+ * example, holds for `c` if it occurs as
16+ * ```
17+ * malloc(sizeof(c) + 100 * sizeof(char))
18+ * ```
19+ * but not if it only ever occurs as
20+ * ```
21+ * malloc(sizeof(c))
22+ * ```
3923 */
4024predicate memberMayBeVarSize ( Class c , MemberVariable v ) {
4125 exists ( int i |
26+ // `v` is the last field in `c`
4227 i = max ( int j | c .getCanonicalMember ( j ) instanceof Field | j ) and
4328 v = c .getCanonicalMember ( i ) and
29+
30+ // v is an array of size at most 1
4431 v .getType ( ) .getUnspecifiedType ( ) .( ArrayType ) .getSize ( ) <= 1
45- ) and
46- isDynamicallyAllocatedWithDifferentSize ( c )
32+ ) and (
33+ exists ( SizeofOperator so |
34+ // `sizeof(c)` is taken
35+ so .( SizeofTypeOperator ) .getTypeOperand ( ) .getUnspecifiedType ( ) = c or
36+ so .( SizeofExprOperator ) .getExprOperand ( ) .getType ( ) .getUnspecifiedType ( ) = c |
37+ // Check all ancestor nodes except the immediate parent for
38+ // allocations.
39+ isStdLibAllocationExpr ( so .getParent ( ) .( Expr ) .getParent + ( ) )
40+ ) or exists ( AddressOfExpr aoe |
41+ // `&(c.v)` is taken
42+ aoe .getAddressable ( ) = v and
43+ isStdLibAllocationExpr ( aoe .getParent ( ) .( Expr ) .getParent + ( ) )
44+ )
45+ )
4746}
4847
4948/**
0 commit comments