@@ -60,17 +60,31 @@ private import semmle.code.cpp.rangeanalysis.new.RangeAnalysisUtil
6060
6161private VariableAccess getAVariableAccess ( Expr e ) { e .getAChild * ( ) = result }
6262
63+ /**
64+ * Gets a (sub)expression that may be the result of evaluating `size`.
65+ *
66+ * For example, `getASizeCandidate(a ? b : c)` gives `a ? b : c`, `b` and `c`.
67+ */
68+ bindingset [ size]
69+ pragma [ inline_late]
70+ private Expr getASizeCandidate ( Expr size ) {
71+ result = size
72+ or
73+ result = [ size .( ConditionalExpr ) .getThen ( ) , size .( ConditionalExpr ) .getElse ( ) ]
74+ }
75+
6376/**
6477 * Holds if the `(n, state)` pair represents the source of flow for the size
6578 * expression associated with `alloc`.
6679 */
6780predicate hasSize ( HeuristicAllocationExpr alloc , DataFlow:: Node n , int state ) {
68- exists ( VariableAccess va , Expr size , int delta |
81+ exists ( VariableAccess va , Expr size , int delta , Expr s |
6982 size = alloc .getSizeExpr ( ) and
83+ s = getASizeCandidate ( size ) and
7084 // Get the unique variable in a size expression like `x` in `malloc(x + 1)`.
71- va = unique( | | getAVariableAccess ( size ) ) and
85+ va = unique( | | getAVariableAccess ( s ) ) and
7286 // Compute `delta` as the constant difference between `x` and `x + 1`.
73- bounded1 ( any ( Instruction instr | instr .getUnconvertedResultExpression ( ) = size ) ,
87+ bounded1 ( any ( Instruction instr | instr .getUnconvertedResultExpression ( ) = s ) ,
7488 any ( LoadInstruction load | load .getUnconvertedResultExpression ( ) = va ) , delta ) and
7589 n .asExpr ( ) = va and
7690 state = delta
0 commit comments