Skip to content

Commit fad03e7

Browse files
committed
Python: Move helper predicate outside of class
otherwise the helper predicate can (and sometimes will) be evaluated once _per_ instance of that class.
1 parent 663dc24 commit fad03e7

1 file changed

Lines changed: 24 additions & 24 deletions

File tree

  • python/ql/test/library-tests/examples/custom-sanitizer

python/ql/test/library-tests/examples/custom-sanitizer/Taint.qll

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -35,32 +35,32 @@ class MySanitizerHandlingNot extends Sanitizer {
3535
taint instanceof ExternalStringKind and
3636
clears_taint_on_true(test.getTest(), test.getSense(), test)
3737
}
38+
}
3839

39-
/**
40-
* Helper predicate that recurses into any nesting of `not`
41-
*
42-
* To reduce the number of tuples this predicate holds for, we include the `PyEdgeRefinement` and
43-
* ensure that `test` is a part of this `PyEdgeRefinement` (instead of just taking the
44-
* `edge_refinement.getInput().getAUse()` part as a part of the predicate). Without including
45-
* `PyEdgeRefinement` as an argument *any* `CallNode c` to `test.is_safe` would be a result of
46-
* this predicate, since the tuple where `test = c` and `sense = true` would hold.
47-
*/
48-
private predicate clears_taint_on_true(
49-
ControlFlowNode test, boolean sense, PyEdgeRefinement edge_refinement
50-
) {
51-
edge_refinement.getTest().getNode().(Expr).getASubExpression*() = test.getNode() and
52-
(
53-
test = Value::named("test.is_safe").getACall() and
54-
edge_refinement.getInput().getAUse() = test.(CallNode).getAnArg() and
55-
sense = true
56-
or
57-
test.(UnaryExprNode).getNode().getOp() instanceof Not and
58-
exists(ControlFlowNode nested_test |
59-
nested_test = test.(UnaryExprNode).getOperand() and
60-
clears_taint_on_true(nested_test, sense.booleanNot(), edge_refinement)
61-
)
40+
/**
41+
* Helper predicate that recurses into any nesting of `not`
42+
*
43+
* To reduce the number of tuples this predicate holds for, we include the `PyEdgeRefinement` and
44+
* ensure that `test` is a part of this `PyEdgeRefinement` (instead of just taking the
45+
* `edge_refinement.getInput().getAUse()` part as a part of the predicate). Without including
46+
* `PyEdgeRefinement` as an argument *any* `CallNode c` to `test.is_safe` would be a result of
47+
* this predicate, since the tuple where `test = c` and `sense = true` would hold.
48+
*/
49+
private predicate clears_taint_on_true(
50+
ControlFlowNode test, boolean sense, PyEdgeRefinement edge_refinement
51+
) {
52+
edge_refinement.getTest().getNode().(Expr).getASubExpression*() = test.getNode() and
53+
(
54+
test = Value::named("test.is_safe").getACall() and
55+
edge_refinement.getInput().getAUse() = test.(CallNode).getAnArg() and
56+
sense = true
57+
or
58+
test.(UnaryExprNode).getNode().getOp() instanceof Not and
59+
exists(ControlFlowNode nested_test |
60+
nested_test = test.(UnaryExprNode).getOperand() and
61+
clears_taint_on_true(nested_test, sense.booleanNot(), edge_refinement)
6262
)
63-
}
63+
)
6464
}
6565

6666
class TestConfig extends TaintTracking::Configuration {

0 commit comments

Comments
 (0)