|
35 | 35 | use Psalm\Type\TaintKind; |
36 | 36 | use Webmozart\Assert\Assert; |
37 | 37 |
|
| 38 | +use function array_diff; |
| 39 | +use function array_filter; |
| 40 | +use function array_intersect; |
| 41 | +use function array_merge; |
| 42 | +use function array_unique; |
| 43 | +use function array_unshift; |
38 | 44 | use function count; |
39 | 45 | use function end; |
40 | 46 | use function json_encode; |
@@ -185,23 +191,23 @@ public function getSuccessorPath(DataFlowNode $sink): string |
185 | 191 | */ |
186 | 192 | public function getIssueTrace(DataFlowNode $source): array |
187 | 193 | { |
188 | | - $previous_source = $source->taintSource; |
189 | | - $path_types = $source->path_types; |
190 | | - $node = [ |
191 | | - 'location' => $source->code_location, |
192 | | - 'label' => $source->label, |
193 | | - 'entry_path_type' => end($path_types) ?: '', |
194 | | - ]; |
195 | | - |
196 | | - if ($previous_source) { |
| 194 | + $out = []; |
| 195 | + do { |
| 196 | + /** @var DataFlowNode $source */ |
| 197 | + $previous_source = $source->taintSource; |
197 | 198 | if ($previous_source === $source) { |
198 | | - return []; |
| 199 | + break; |
199 | 200 | } |
200 | | - |
201 | | - return [...$this->getIssueTrace($previous_source), $node]; |
202 | | - } |
203 | | - |
204 | | - return [$node]; |
| 201 | + $path_types = $source->path_types; |
| 202 | + array_unshift($out, [ |
| 203 | + 'location' => $source->code_location, |
| 204 | + 'label' => $source->label, |
| 205 | + 'entry_path_type' => end($path_types) ?: '', |
| 206 | + ]); |
| 207 | + $source = $previous_source; |
| 208 | + } while ($previous_source); |
| 209 | + |
| 210 | + return $out; |
205 | 211 | } |
206 | 212 |
|
207 | 213 | public function connectSinksAndSources(Progress $progress): void |
|
0 commit comments