Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
35 / 35 |
|
100.00% |
21 / 21 |
CRAP | |
100.00% |
1 / 1 |
TaintednessAccessorsTrait | |
100.00% |
35 / 35 |
|
100.00% |
21 / 21 |
27 | |
100.00% |
1 / 1 |
getTaintednessRaw | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setTaintednessRaw | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
getCausedByRaw | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getCausedByRef | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getFuncCausedByRaw | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setCausedByRaw | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
setCausedByRef | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setFuncCausedByRaw | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getMethodLinks | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setMethodLinks | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
getMethodLinksRef | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getVarLinks | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
ensureVarLinksForArgExist | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getTaintednessRef | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setTaintednessRef | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
clearRefData | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getFuncTaint | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
doSetFuncTaint | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getRetObjs | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
addRetObjs | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
initRetObjs | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 |
1 | <?php declare( strict_types=1 ); |
2 | |
3 | namespace SecurityCheckPlugin; |
4 | |
5 | use Phan\Language\Element\FunctionInterface; |
6 | use Phan\Language\Element\PassByReferenceVariable; |
7 | use Phan\Language\Element\TypedElementInterface; |
8 | |
9 | /** |
10 | * Accessors to read and write taintedness props stored inside phan objects. This trait exists to avoid duplicating |
11 | * dynamic property names, to have better type inference, to enable phan checks for undeclared props on the other |
12 | * files, to keep track of props usage etc. |
13 | * @phan-file-suppress PhanUndeclaredProperty |
14 | */ |
15 | trait TaintednessAccessorsTrait { |
16 | /** |
17 | * @param TypedElementInterface $element |
18 | * @return Taintedness|null |
19 | */ |
20 | protected static function getTaintednessRaw( TypedElementInterface $element ): ?Taintedness { |
21 | return $element->taintedness ?? null; |
22 | } |
23 | |
24 | /** |
25 | * @param TypedElementInterface $element |
26 | * @param Taintedness $taintedness |
27 | */ |
28 | protected static function setTaintednessRaw( TypedElementInterface $element, Taintedness $taintedness ): void { |
29 | $element->taintedness = $taintedness; |
30 | if ( $element instanceof PassByReferenceVariable ) { |
31 | self::setTaintednessRef( $element->getElement(), $taintedness ); |
32 | } |
33 | } |
34 | |
35 | /** |
36 | * @param TypedElementInterface $element |
37 | * @return CausedByLines|null |
38 | */ |
39 | protected static function getCausedByRaw( TypedElementInterface $element ): ?CausedByLines { |
40 | return $element->taintedOriginalError ?? null; |
41 | } |
42 | |
43 | /** |
44 | * @param TypedElementInterface $element |
45 | * @return CausedByLines|null |
46 | */ |
47 | protected static function getCausedByRef( TypedElementInterface $element ): ?CausedByLines { |
48 | return $element->taintedOriginalErrorRef ?? null; |
49 | } |
50 | |
51 | /** |
52 | * @param FunctionInterface $func |
53 | * @return FunctionCausedByLines|null |
54 | */ |
55 | protected static function getFuncCausedByRaw( FunctionInterface $func ): ?FunctionCausedByLines { |
56 | return $func->funcTaintedOriginalError ?? null; |
57 | } |
58 | |
59 | /** |
60 | * @param TypedElementInterface $element |
61 | * @param CausedByLines $lines |
62 | */ |
63 | protected static function setCausedByRaw( TypedElementInterface $element, CausedByLines $lines ): void { |
64 | $element->taintedOriginalError = $lines; |
65 | if ( $element instanceof PassByReferenceVariable ) { |
66 | self::setCausedByRef( $element->getElement(), $lines ); |
67 | } |
68 | } |
69 | |
70 | /** |
71 | * @param TypedElementInterface $element |
72 | * @param CausedByLines $lines |
73 | */ |
74 | protected static function setCausedByRef( TypedElementInterface $element, CausedByLines $lines ): void { |
75 | $element->taintedOriginalErrorRef = $lines; |
76 | } |
77 | |
78 | /** |
79 | * @param FunctionInterface $func |
80 | * @param FunctionCausedByLines $lines |
81 | */ |
82 | protected static function setFuncCausedByRaw( FunctionInterface $func, FunctionCausedByLines $lines ): void { |
83 | $func->funcTaintedOriginalError = $lines; |
84 | } |
85 | |
86 | /** |
87 | * @param TypedElementInterface $element |
88 | * @return MethodLinks|null |
89 | */ |
90 | protected static function getMethodLinks( TypedElementInterface $element ): ?MethodLinks { |
91 | return $element->taintedMethodLinks ?? null; |
92 | } |
93 | |
94 | /** |
95 | * @param TypedElementInterface $element |
96 | * @param MethodLinks $links |
97 | */ |
98 | protected static function setMethodLinks( TypedElementInterface $element, MethodLinks $links ): void { |
99 | $element->taintedMethodLinks = $links; |
100 | if ( $element instanceof PassByReferenceVariable ) { |
101 | $element->getElement()->taintedMethodLinksRef = $links; |
102 | } |
103 | } |
104 | |
105 | /** |
106 | * @param TypedElementInterface $element |
107 | * @return MethodLinks|null |
108 | */ |
109 | protected static function getMethodLinksRef( TypedElementInterface $element ): ?MethodLinks { |
110 | return $element->taintedMethodLinksRef ?? null; |
111 | } |
112 | |
113 | /** |
114 | * @param FunctionInterface $func |
115 | * @param int $index |
116 | * @return VarLinksSet|null |
117 | */ |
118 | protected static function getVarLinks( FunctionInterface $func, int $index ): ?VarLinksSet { |
119 | return $func->taintedVarLinks[$index] ?? null; |
120 | } |
121 | |
122 | /** |
123 | * @param TypedElementInterface $element |
124 | * @param int $arg |
125 | */ |
126 | protected static function ensureVarLinksForArgExist( TypedElementInterface $element, int $arg ): void { |
127 | $element->taintedVarLinks ??= []; |
128 | $element->taintedVarLinks[$arg] ??= new VarLinksSet; |
129 | } |
130 | |
131 | /** |
132 | * @param TypedElementInterface $element |
133 | * @return Taintedness|null |
134 | */ |
135 | protected static function getTaintednessRef( TypedElementInterface $element ): ?Taintedness { |
136 | return $element->taintednessRef ?? null; |
137 | } |
138 | |
139 | /** |
140 | * @param TypedElementInterface $element |
141 | * @param Taintedness $taintedness |
142 | */ |
143 | protected static function setTaintednessRef( TypedElementInterface $element, Taintedness $taintedness ): void { |
144 | $element->taintednessRef = $taintedness; |
145 | } |
146 | |
147 | /** |
148 | * @param TypedElementInterface $element |
149 | */ |
150 | protected static function clearRefData( TypedElementInterface $element ): void { |
151 | unset( $element->taintednessRef, $element->taintedMethodLinksRef, $element->taintedOriginalErrorRef ); |
152 | } |
153 | |
154 | /** |
155 | * Get $func's taint, or null if not set. |
156 | * |
157 | * @param FunctionInterface $func |
158 | * @return FunctionTaintedness|null |
159 | */ |
160 | protected static function getFuncTaint( FunctionInterface $func ): ?FunctionTaintedness { |
161 | return $func->funcTaint ?? null; |
162 | } |
163 | |
164 | /** |
165 | * @param FunctionInterface $func |
166 | * @param FunctionTaintedness $funcTaint |
167 | */ |
168 | protected static function doSetFuncTaint( FunctionInterface $func, FunctionTaintedness $funcTaint ): void { |
169 | $func->funcTaint = $funcTaint; |
170 | } |
171 | |
172 | /** |
173 | * @param FunctionInterface $func |
174 | * @return TypedElementInterface[]|null |
175 | */ |
176 | protected static function getRetObjs( FunctionInterface $func ): ?array { |
177 | $funcNode = $func->getNode(); |
178 | if ( !$funcNode ) { |
179 | // If it has no node, it won't have any returned object, so don't return null, to avoid |
180 | // potential recursive analysis attempts. |
181 | return []; |
182 | } |
183 | return $funcNode->retObjs ?? null; |
184 | } |
185 | |
186 | /** |
187 | * @note These are saved in the function node so that they can be shared by all implementations, without |
188 | * having to check the defining FQSEN of a method and canonicalize $func for lookup. |
189 | * @param FunctionInterface $func |
190 | * @param TypedElementInterface[] $retObjs |
191 | * @suppress PhanUnreferencedProtectedMethod Used in TaintednessVisitor |
192 | */ |
193 | protected static function addRetObjs( FunctionInterface $func, array $retObjs ): void { |
194 | $funcNode = $func->getNode(); |
195 | if ( $funcNode ) { |
196 | $funcNode->retObjs = array_merge( $funcNode->retObjs ?? [], $retObjs ); |
197 | } |
198 | } |
199 | |
200 | /** |
201 | * @param FunctionInterface $func |
202 | */ |
203 | protected static function initRetObjs( FunctionInterface $func ): void { |
204 | $funcNode = $func->getNode(); |
205 | if ( $funcNode ) { |
206 | $funcNode->retObjs ??= []; |
207 | } |
208 | } |
209 | |
210 | } |