|
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