Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
80.00% covered (warning)
80.00%
64 / 80
83.33% covered (warning)
83.33%
15 / 18
CRAP
0.00% covered (danger)
0.00%
0 / 1
FunctionCausedByLines
80.00% covered (warning)
80.00%
64 / 80
83.33% covered (warning)
83.33%
15 / 18
73.63
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getGenericLines
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 addGenericLines
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setGenericLines
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 addParamSinkLines
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 addParamPreservedLines
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 setParamSinkLines
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setParamPreservedLines
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setVariadicParamSinkLines
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setVariadicParamPreservedLines
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 addVariadicParamSinkLines
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 addVariadicParamPreservedLines
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 getParamSinkLines
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
5
 getParamPreservedLines
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
5
 mergeWith
84.00% covered (warning)
84.00%
21 / 25
0.00% covered (danger)
0.00%
0 / 1
14.80
 __clone
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
 toString
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
30
 __toString
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php declare( strict_types=1 );
2
3namespace SecurityCheckPlugin;
4
5/**
6 * This class represents caused-by lines for a function-like:
7 * - Lines in genericLines are for taintedness that is added inside the function, regardless of parameters; these
8 *   have a Taintedness object associated, while the associated links are always empty.
9 * - Lines in (variadic)paramSinkLines are those inside a function that EXEC the arguments. These also have a
10 *   Taintedness object associated, and no links.
11 * - Lines in (variadic)paramPreservedLines are responsible for putting a parameter inside the return value. These have
12 *   a safe Taintedness associated, and usually non-empty links.
13 */
14class FunctionCausedByLines {
15    /** @var CausedByLines */
16    private $genericLines;
17    /** @var CausedByLines[] */
18    private $paramSinkLines = [];
19    /** @var CausedByLines[] */
20    private $paramPreservedLines = [];
21    /** @var int|null Index of a variadic parameter, if any */
22    private $variadicParamIndex;
23    /** @var CausedByLines|null */
24    private $variadicParamSinkLines;
25    /** @var CausedByLines|null */
26    private $variadicParamPreservedLines;
27
28    public function __construct() {
29        $this->genericLines = new CausedByLines();
30    }
31
32    /**
33     * @return CausedByLines
34     * @suppress PhanUnreferencedPublicMethod
35     */
36    public function getGenericLines(): CausedByLines {
37        return $this->genericLines;
38    }
39
40    /**
41     * @param string[] $lines
42     * @param Taintedness $taint
43     * @param MethodLinks|null $links
44     */
45    public function addGenericLines( array $lines, Taintedness $taint, MethodLinks $links = null ): void {
46        $this->genericLines->addLines( $lines, $taint, $links );
47    }
48
49    /**
50     * @param CausedByLines $lines
51     */
52    public function setGenericLines( CausedByLines $lines ): void {
53        $this->genericLines = $lines;
54    }
55
56    /**
57     * @param int $param
58     * @param string[] $lines
59     * @param Taintedness $taint
60     */
61    public function addParamSinkLines( int $param, array $lines, Taintedness $taint ): void {
62        assert( $param !== $this->variadicParamIndex );
63        if ( !isset( $this->paramSinkLines[$param] ) ) {
64            $this->paramSinkLines[$param] = new CausedByLines();
65        }
66        $this->paramSinkLines[$param]->addLines( $lines, $taint );
67    }
68
69    /**
70     * @param int $param
71     * @param string[] $lines
72     * @param Taintedness $taint
73     * @param MethodLinks|null $links
74     */
75    public function addParamPreservedLines(
76        int $param,
77        array $lines,
78        Taintedness $taint,
79        MethodLinks $links = null
80    ): void {
81        assert( $param !== $this->variadicParamIndex );
82        if ( !isset( $this->paramPreservedLines[$param] ) ) {
83            $this->paramPreservedLines[$param] = new CausedByLines();
84        }
85        $this->paramPreservedLines[$param]->addLines( $lines, $taint, $links );
86    }
87
88    /**
89     * @param int $param
90     * @param CausedByLines $lines
91     */
92    public function setParamSinkLines( int $param, CausedByLines $lines ): void {
93        $this->paramSinkLines[$param] = $lines;
94    }
95
96    /**
97     * @param int $param
98     * @param CausedByLines $lines
99     */
100    public function setParamPreservedLines( int $param, CausedByLines $lines ): void {
101        $this->paramPreservedLines[$param] = $lines;
102    }
103
104    /**
105     * @param int $param
106     * @param CausedByLines $lines
107     */
108    public function setVariadicParamSinkLines( int $param, CausedByLines $lines ): void {
109        $this->variadicParamIndex = $param;
110        $this->variadicParamSinkLines = $lines;
111    }
112
113    /**
114     * @param int $param
115     * @param CausedByLines $lines
116     */
117    public function setVariadicParamPreservedLines( int $param, CausedByLines $lines ): void {
118        $this->variadicParamIndex = $param;
119        $this->variadicParamPreservedLines = $lines;
120    }
121
122    /**
123     * @param int $param
124     * @param string[] $lines
125     * @param Taintedness $taint
126     */
127    public function addVariadicParamSinkLines(
128        int $param,
129        array $lines,
130        Taintedness $taint
131    ): void {
132        assert( !isset( $this->paramSinkLines[$param] ) && !isset( $this->paramPreservedLines[$param] ) );
133        $this->variadicParamIndex = $param;
134        if ( !$this->variadicParamSinkLines ) {
135            $this->variadicParamSinkLines = new CausedByLines();
136        }
137        $this->variadicParamSinkLines->addLines( $lines, $taint );
138    }
139
140    /**
141     * @param int $param
142     * @param string[] $lines
143     * @param Taintedness $taint
144     * @param MethodLinks|null $links
145     */
146    public function addVariadicParamPreservedLines(
147        int $param,
148        array $lines,
149        Taintedness $taint,
150        MethodLinks $links = null
151    ): void {
152        assert( !isset( $this->paramSinkLines[$param] ) && !isset( $this->paramPreservedLines[$param] ) );
153        $this->variadicParamIndex = $param;
154        if ( !$this->variadicParamPreservedLines ) {
155            $this->variadicParamPreservedLines = new CausedByLines();
156        }
157        $this->variadicParamPreservedLines->addLines( $lines, $taint, $links );
158    }
159
160    /**
161     * @param int $param
162     * @return CausedByLines
163     */
164    public function getParamSinkLines( int $param ): CausedByLines {
165        if ( isset( $this->paramSinkLines[$param] ) ) {
166            return $this->paramSinkLines[$param];
167        }
168        if (
169            $this->variadicParamIndex !== null && $param >= $this->variadicParamIndex &&
170            $this->variadicParamSinkLines
171        ) {
172            return $this->variadicParamSinkLines;
173        }
174        return new CausedByLines();
175    }
176
177    /**
178     * @param int $param
179     * @return CausedByLines
180     */
181    public function getParamPreservedLines( int $param ): CausedByLines {
182        if ( isset( $this->paramPreservedLines[$param] ) ) {
183            return $this->paramPreservedLines[$param];
184        }
185        if (
186            $this->variadicParamIndex !== null && $param >= $this->variadicParamIndex &&
187            $this->variadicParamPreservedLines
188        ) {
189            return $this->variadicParamPreservedLines;
190        }
191        return new CausedByLines();
192    }
193
194    /**
195     * @param FunctionCausedByLines $other
196     * @param FunctionTaintedness $funcTaint To check NO_OVERRIDE
197     */
198    public function mergeWith( self $other, FunctionTaintedness $funcTaint ): void {