Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.89% covered (success)
97.89%
278 / 284
82.61% covered (warning)
82.61%
19 / 23
CRAP
0.00% covered (danger)
0.00%
0 / 1
CausedByLines
97.89% covered (success)
97.89%
278 / 284
82.61% covered (warning)
82.61%
19 / 23
145
0.00% covered (danger)
0.00%
0 / 1
 emptySingleton
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 withAddedLines
95.65% covered (success)
95.65%
22 / 23
0.00% covered (danger)
0.00%
0 / 1
15
 asMergedForAssignment
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
13
 asPreservedForParameter
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
6
 asPreservedForArgument
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
4
 asIntersectedWithTaintedness
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
4
 asFilteredForFuncAndParam
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
5
 getLinesForGenericReturn
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
 withTaintAddedToMethodArgLinks
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
6
 forSinkBackprop
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
4
 asAllMaybeMovedAtOffset
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
4
 asAllMovedToKeys
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
4
 getForDim
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
8
 asAllCollapsed
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
4
 asAllValueFirstLevel
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
4
 asAllKeyForForeach
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
8
 withOnlyLinks
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
5
 asMergedWith
95.38% covered (success)
95.38%
62 / 65
0.00% covered (danger)
0.00%
0 / 1
25
 getArraySubsetIdx
92.86% covered (success)
92.86%
13 / 14
0.00% covered (danger)
0.00%
0 / 1
7.02
 toStringForIssue
85.71% covered (warning)
85.71%
6 / 7
0.00% covered (danger)
0.00%
0 / 1
3.03
 getRelevantLinesForTaintedness
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
4
 isEmpty
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 toLinesArray
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 toDebugString
n/a
0 / 0
n/a
0 / 0
4
1<?php declare( strict_types=1 );
2
3namespace SecurityCheckPlugin;
4
5use ast\Node;
6use Phan\Language\Element\FunctionInterface;
7
8/**
9 * Value object used to store caused-by lines.
10 */
11class CausedByLines {
12    private const MAX_LINES_PER_ISSUE = 80;
13    // XXX Hack: Enforce a hard limit, or things may explode
14    private const LINES_HARD_LIMIT = 100;
15
16    /**
17     * Note: the links are nullable for performance.
18     * @var array<array<Taintedness|string|MethodLinks|null>>
19     * @phan-var list<array{0:Taintedness,1:string,2:?MethodLinks}>
20     */
21    private $lines = [];
22
23    public static function emptySingleton(): self {
24        static $singleton;
25        if ( !$singleton ) {
26            $singleton = new self();
27        }
28        return $singleton;
29    }
30
31    /**
32     * Adds the given lines to this object. For assignment statements, use {@see self::withAddedAssignmentLines}
33     * @param string[] $lines
34     * @param Taintedness $taintedness
35     * @param MethodLinks|null $links
36     * @return self
37     */
38    public function withAddedLines( array $lines, Taintedness $taintedness, ?MethodLinks $links = null ): self {
39        if ( $links && $links->isEmpty() ) {
40            $links = null;
41        }
42        if ( !$links && $taintedness->isSafe() ) {
43            return $this;
44        }
45
46        $ret = new self();
47
48        if ( !$this->lines ) {
49            foreach ( $lines as $line ) {
50                $ret->lines[] = [ $taintedness, $line, $links ];
51            }