|
1 | 1 | /**
|
2 | 2 | * @name Loop variable capture
|
3 | 3 | * @description Capture of a loop variable is not the same as capturing the value of a loop variable, and may be erroneous.
|
4 |
| - * @kind problem |
| 4 | + * @kind path-problem |
5 | 5 | * @tags correctness
|
6 | 6 | * @problem.severity error
|
7 | 7 | * @sub-severity low
|
@@ -60,13 +60,23 @@ module EscapingCaptureFlowSig implements DataFlow::ConfigSig {
|
60 | 60 |
|
61 | 61 | module EscapingCaptureFlow = DataFlow::Global<EscapingCaptureFlowSig>;
|
62 | 62 |
|
63 |
| -predicate escapingCapture(CallableExpr capturing, Loop loop, Variable var) { |
| 63 | +import EscapingCaptureFlow::PathGraph |
| 64 | + |
| 65 | +predicate escapingCapture( |
| 66 | + CallableExpr capturing, Loop loop, Variable var, EscapingCaptureFlow::PathNode source, |
| 67 | + EscapingCaptureFlow::PathNode sink |
| 68 | +) { |
64 | 69 | capturesLoopVariable(capturing, loop, var) and
|
65 |
| - EscapingCaptureFlow::flow(DataFlow::exprNode(capturing), _) |
| 70 | + capturing = source.getNode().asExpr() and |
| 71 | + EscapingCaptureFlow::flowPath(source, sink) |
66 | 72 | }
|
67 | 73 |
|
68 |
| -from CallableExpr capturing, AstNode loop, Variable var, string descr |
| 74 | +from |
| 75 | + CallableExpr capturing, AstNode loop, Variable var, string descr, |
| 76 | + EscapingCaptureFlow::PathNode source, EscapingCaptureFlow::PathNode sink |
69 | 77 | where
|
70 |
| - escapingCapture(capturing, loop, var) and |
| 78 | + escapingCapture(capturing, loop, var, source, sink) and |
71 | 79 | if capturing instanceof Lambda then descr = "lambda" else descr = "function"
|
72 |
| -select capturing, "This " + descr + " captures the loop variable $@.", loop, var.getId() |
| 80 | +select capturing, source, sink, |
| 81 | + "This " + descr + " captures the loop variable $@, and may escape the loop by being stored $@.", |
| 82 | + loop, var.getId(), sink, "here" |
0 commit comments