mirror of
https://github.com/github/codeql.git
synced 2026-05-01 19:55:15 +02:00
C++: Add an initial pruning stage to prevent this
large TC in 'localFlowToExpr':
```
Evaluated relational algebra for predicate Buffer#61e3d199::localFlowStepToExpr#2#ff@0a49913i with tuple counts:
4713946 ~0% {2} r1 = SCAN DataFlowUtil#47741e1f::simpleLocalFlowStep#2#ff OUTPUT In.1, In.0
40897385 ~46% {2} r2 = JOIN boundedFastTC:Buffer#61e3d199::localFlowToExprStep#2#ff_10#higher_order_body:DataFlowUtil#47741e1f::simpleLocalFlowStep#2#ff_0#higher_order_body WITH DataFlowUtil#47741e1f::simpleLocalFlowStep#2#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.1
45611331 ~43% {2} r3 = r1 UNION r2
3376553 ~14% {2} r4 = JOIN r3 WITH DataFlowUtil#47741e1f::ExprNode::getExpr#0#dispred#ff ON FIRST 1 OUTPUT Lhs.1, Rhs.1
return r4
```
After this commit the tuple counts looks like:
```
Evaluated relational algebra for predicate Buffer#61e3d199::localFlowStepToExpr#2#ff@8cc38x5k on iteration 2 running pipeline standard with tuple counts:
51367 ~3% {2} r1 = JOIN Buffer#61e3d199::getBufferSize0#1#f#prev_delta WITH DataFlowUtil#47741e1f::ExprNode::getExpr#0#dispred#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.0
124933 ~18% {2} r2 = JOIN r1 WITH #Buffer#61e3d199::localFlowToExprStep#2Plus#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.1
176300 ~17% {2} r3 = r1 UNION r2
184685 ~22% {2} r4 = JOIN r3 WITH DataFlowUtil#47741e1f::simpleLocalFlowStep#2#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.1
56646 ~47% {2} r5 = JOIN r4 WITH DataFlowUtil#47741e1f::ExprNode::getExpr#0#dispred#ff ON FIRST 1 OUTPUT Lhs.1, Rhs.1
44635 ~16% {2} r6 = r5 AND NOT Buffer#61e3d199::localFlowStepToExpr#2#ff#prev(Lhs.0, Lhs.1)
return r6
```
This commit is contained in:
@@ -79,8 +79,10 @@ private predicate localFlowToExprStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||
}
|
||||
|
||||
/** Holds if `n2 + delta` may be equal to `n1`. */
|
||||
private predicate localFlowStepToExpr(DataFlow::Node n1, Expr e2) {
|
||||
exists(DataFlow::Node mid, DataFlow::Node n2 |
|
||||
private predicate localFlowStepToExpr(Expr e1, Expr e2) {
|
||||
getBufferSize0(e1) and
|
||||
exists(DataFlow::Node n1, DataFlow::Node mid, DataFlow::Node n2 |
|
||||
n1.asExpr() = e1 and
|
||||
localFlowToExprStep*(n1, mid) and
|
||||
DataFlow::localFlowStep(mid, n2) and
|
||||
n2.asExpr() = e2
|
||||
@@ -93,6 +95,7 @@ private predicate localFlowStepToExpr(DataFlow::Node n1, Expr e2) {
|
||||
* expression.
|
||||
*/
|
||||
private predicate step(Expr e1, Expr e2, int delta) {
|
||||
getBufferSize0(e1) and
|
||||
exists(Variable bufferVar, Class parentClass, VariableAccess parentPtr, int bufferSize |
|
||||
e1 = parentPtr
|
||||
|
|
||||
@@ -109,19 +112,32 @@ private predicate step(Expr e1, Expr e2, int delta) {
|
||||
delta = bufferSize - parentClass.getSize()
|
||||
)
|
||||
or
|
||||
localFlowStepToExpr(DataFlow::exprNode(e1), e2) and
|
||||
localFlowStepToExpr(e1, e2) and
|
||||
delta = 0
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate getBufferSize0(Expr e) {
|
||||
exists(isSource(e, _))
|
||||
or
|
||||
exists(Expr e0 |
|
||||
getBufferSize0(e0) and
|
||||
step(e0, e, _)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size in bytes of the buffer pointed to by an expression (if this can be determined).
|
||||
*/
|
||||
int getBufferSize(Expr bufferExpr, Element why) {
|
||||
result = isSource(bufferExpr, why)
|
||||
or
|
||||
exists(Expr e0, int delta, int size |
|
||||
size = getBufferSize(e0, why) and
|
||||
delta = unique(int cand | step(e0, bufferExpr, cand) | cand) and
|
||||
result = size + delta
|
||||
getBufferSize0(bufferExpr) and
|
||||
(
|
||||
result = isSource(bufferExpr, why)
|
||||
or
|
||||
exists(Expr e0, int delta, int size |
|
||||
size = getBufferSize(e0, why) and
|
||||
delta = unique(int cand | step(e0, bufferExpr, cand) | cand) and
|
||||
result = size + delta
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user