Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
88.06% |
1210 / 1374 |
|
68.33% |
41 / 60 |
CRAP | |
0.00% |
0 / 1 |
TaintednessBaseVisitor | |
88.06% |
1210 / 1374 |
|
68.33% |
41 / 60 |
941.38 | |
0.00% |
0 / 1 |
addFuncTaint | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
2 | |||
ensureFuncTaintIsSet | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
maybeAddFuncError | |
100.00% |
40 / 40 |
|
100.00% |
1 / 1 |
22 | |||
mergeFuncError | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
addTaintError | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
getCausedByLinesToAdd | |
83.33% |
5 / 6 |
|
0.00% |
0 / 1 |
7.23 | |||
ensureTaintednessIsSet | |
50.00% |
3 / 6 |
|
0.00% |
0 / 1 |
6.00 | |||
setTaintedness | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
5 | |||
getDefiningFuncIfDifferent | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
4 | |||
getPossibleFuncDefinitions | |
87.50% |
21 / 24 |
|
0.00% |
0 / 1 |
9.16 | |||
getTaintOfFunction | |
100.00% |
30 / 30 |
|
100.00% |
1 / 1 |
11 | |||
getSetKnownTaintOfFunctionWithoutAnalysis | |
100.00% |
23 / 23 |
|
100.00% |
1 / 1 |
8 | |||
analyzeFunc | |
86.36% |
19 / 22 |
|
0.00% |
0 / 1 |
10.25 | |||
getDocBlockTaintOfFunc | |
100.00% |
93 / 93 |
|
100.00% |
1 / 1 |
22 | |||
getTaintByType | |
91.94% |
57 / 62 |
|
0.00% |
0 / 1 |
33.57 | |||
getTaintMaskForTypedElement | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
getTaintMaskForType | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
getPossibleFutureTaintOfElement | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getCurrentMethod | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
getTaintedness | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
3 | |||
getTaintednessNode | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
2 | |||
getTaintednessPhanObj | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
3 | |||
resolveOffset | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
3 | |||
resolveValue | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
getPropInCurrentScopeByName | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getCtxN | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
getObjsForNodeForNumkeyBackprop | |
67.53% |
52 / 77 |
|
0.00% |
0 / 1 |
153.80 | |||
getPropFromNode | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
2 | |||
getDebugInfo | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
dbgInfo | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
linkParamAndFunc | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
2 | |||
mergeTaintDependencies | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
6 | |||
markAllDependentMethodsExec | |
100.00% |
54 / 54 |
|
100.00% |
1 / 1 |
17 | |||
markAllDependentMethodsExecForNode | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
3 | |||
markAllDependentVarsYes | |
100.00% |
23 / 23 |
|
100.00% |
1 / 1 |
5 | |||
getCausedByLinesForFunc | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getActualFuncWithCausedBy | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
debug | n/a |
0 / 0 |
n/a |
0 / 0 |
8 | |||||
getCallableFromNode | |
88.89% |
16 / 18 |
|
0.00% |
0 / 1 |
10.14 | |||
getFirstElmFromArrayOrGenerator | |
66.67% |
2 / 3 |
|
0.00% |
0 / 1 |
4.59 | |||
taintToIssuesAndSeverities | |
92.06% |
58 / 63 |
|
0.00% |
0 / 1 |
11.06 | |||
maybeEmitIssueSimplified | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
maybeEmitIssue | |
97.78% |
44 / 45 |
|
0.00% |
0 / 1 |
14 | |||
isIssueSuppressedOrFalsePositive | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
4 | |||
handleMethodCall | |
100.00% |
114 / 114 |
|
100.00% |
1 / 1 |
24 | |||
maybeHandleSpecialCall | |
92.86% |
39 / 42 |
|
0.00% |
0 / 1 |
17.11 | |||
extractArrayArgs | |
75.00% |
6 / 8 |
|
0.00% |
0 / 1 |
5.39 | |||
translateNamedArg | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
backpropagateArgTaint | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
2 | |||
handlePassByRef | |
100.00% |
53 / 53 |
|
100.00% |
1 / 1 |
14 | |||
getPassByRefObjFromNode | |
54.55% |
6 / 11 |
|
0.00% |
0 / 1 |
14.01 | |||
getHardcodedPreservedTaintForFunc | |
69.01% |
216 / 313 |
|
0.00% |
0 / 1 |
294.01 | |||
getBinOpTaintMask | |
90.00% |
36 / 40 |
|
0.00% |
0 / 1 |
6.04 | |||
getNodeType | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
2 | |||
nodeIsArray | |
85.71% |
6 / 7 |
|
0.00% |
0 / 1 |
6.10 | |||
nodeCanBeArray | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
5 | |||
nodeCanBeString | |
75.00% |
3 / 4 |
|
0.00% |
0 / 1 |
3.14 | |||
elementCanBeNumkey | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
5 | |||
nodeCanBeIntKey | |
90.00% |
9 / 10 |
|
0.00% |
0 / 1 |
7.05 | |||
getReturnObjsOfFunc | |
91.67% |
11 / 12 |
|
0.00% |
0 / 1 |
3.01 | |||
isSubclassOf | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
1 | <?php declare( strict_types=1 ); |
2 | |
3 | namespace SecurityCheckPlugin; |
4 | |
5 | use ast\Node; |
6 | use Closure; |
7 | use Exception; |
8 | use Generator; |
9 | use Phan\AST\ASTReverter; |
10 | use Phan\AST\ContextNode; |
11 | use Phan\AST\UnionTypeVisitor; |
12 | use Phan\BlockAnalysisVisitor; |
13 | use Phan\CodeBase; |
14 | use Phan\Debug; |
15 | use Phan\Exception\CodeBaseException; |
16 | use Phan\Exception\FQSENException; |
17 | use Phan\Exception\IssueException; |
18 | use Phan\Exception\NodeException; |
19 | use Phan\Exception\UnanalyzableException; |
20 | use Phan\Issue; |
21 | use Phan\Language\Context; |
22 | use Phan\Language\Element\FunctionInterface; |
23 | use Phan\Language\Element\GlobalVariable; |
24 | use Phan\Language\Element\Method; |
25 | use Phan\Language\Element\Property; |
26 | use Phan\Language\Element\TypedElementInterface; |
27 | use Phan\Language\Element\Variable; |
28 | use Phan\Language\FQSEN\FullyQualifiedClassName; |
29 | use Phan\Language\FQSEN\FullyQualifiedFunctionLikeName; |
30 | use Phan\Language\FQSEN\FullyQualifiedFunctionName; |
31 | use Phan\Language\FQSEN\FullyQualifiedMethodName; |
32 | use Phan\Language\Type\FunctionLikeDeclarationType; |
33 | use Phan\Language\Type\GenericArrayType; |
34 | use Phan\Language\Type\LiteralTypeInterface; |
35 | use Phan\Language\UnionType; |
36 | use Phan\Library\Set; |
37 | |
38 | /** |
39 | * Trait for the Tainedness visitor subclasses. Mostly contains |
40 | * utility methods. |
41 | * |
42 | * Copyright (C) 2017 Brian Wolff <bawolff@gmail.com> |
43 | * |
44 | * This program is free software; you can redistribute it and/or modify |
45 | * it under the terms of the GNU General Public License as published by |
46 | * the Free Software Foundation; either version 2 of the License, or |
47 | * (at your option) any later version. |
48 | * |
49 | * This program is distributed in the hope that it will be useful, |
50 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
51 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
52 | * GNU General Public License for more details. |
53 | * |
54 | * You should have received a copy of the GNU General Public License along |
55 | * with this program; if not, write to the Free Software Foundation, Inc., |
56 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
57 | */ |
58 | /** |
59 | * @property-read Context $context |
60 | * @property-read \Phan\CodeBase $code_base |
61 | */ |
62 | trait TaintednessBaseVisitor { |
63 | use TaintednessAccessorsTrait; |
64 | |
65 | /** @var null|string|bool|resource filehandle to output debug messages */ |
66 | private $debugOutput; |
67 | |
68 | /** @var Context|null Override the file/line number to emit issues */ |
69 | protected $overrideContext; |
70 | |
71 | /** |
72 | * @var bool[] FQSENs of classes without __toString, map of [ (string)FQSEN => true ] |
73 | */ |
74 | protected static $fqsensWithoutToStringCache = []; |
75 | |
76 | /** |
77 | * @var array<string,bool> FQSENs of functions currently being analyzed by us, map of [ (string)FQSEN => true ] |
78 | */ |
79 | private static $funcAnalysisStack = []; |
80 | |
81 | /** |
82 | * Merge taintedness of a function/method |
83 | * |
84 | * @param FunctionInterface $func |
85 | * @param FunctionTaintedness $taint |
86 | */ |
87 | protected function addFuncTaint( FunctionInterface $func, FunctionTaintedness $taint ): void { |
88 | $curTaint = self::getFuncTaint( $func ); |
89 | if ( $curTaint ) { |
90 | $newTaint = $curTaint->asMergedWith( $taint ); |
91 | } else { |
92 | $newTaint = $taint; |
93 | } |
94 | self::doSetFuncTaint( $func, $newTaint ); |
95 | } |
96 | |
97 | /** |
98 | * Ensure a function-like has its taintedness set and not unknown |
99 | * |
100 | * @param FunctionInterface $func |
101 | */ |
102 | protected function ensureFuncTaintIsSet( FunctionInterface $func ): void { |
103 | if ( !self::getFuncTaint( $func ) ) { |
104 | self::doSetFuncTaint( $func, FunctionTaintedness::emptySingleton() ); |
105 | } |
106 | } |
107 | |
108 | /** |
109 | * @param FunctionInterface $func |
110 | * @param Context|string|null $reason To override the caused-by line |
111 | * @param FunctionTaintedness $addedTaint |
112 | * @param FunctionTaintedness $allNewTaint |
113 | * @param MethodLinks|null $returnLinks NOTE: These are only used for preserved params, since for sink params |
114 | * we're already adding a Taintedness with the expected EXEC bits. |
115 | */ |
116 | private function maybeAddFuncError( |
117 | FunctionInterface $func, |
118 | $reason, |
119 | FunctionTaintedness $addedTaint, |
120 | FunctionTaintedness $allNewTaint, |
121 | ?MethodLinks $returnLinks = null |
122 | ): void { |
123 | if ( !is_string( $reason ) ) { |
124 | $newErrors = [ $this->dbgInfo( $reason ?? $this->context ) ]; |
125 | } else { |
126 | $newErrors = [ $reason ]; |
127 | } |
128 | if ( $this->overrideContext && !( $this->isHook ?? false ) ) { |
129 | // @phan-suppress-previous-line PhanUndeclaredProperty |
130 | $newErrors[] = $this->dbgInfo( $this->overrideContext ); |
131 | } |
132 | |
133 | $hasReturnLinks = $returnLinks && !$returnLinks->isEmpty(); |
134 | |
135 | // Future TODO: we might consider using PreservedTaintedness from the funcs instead of MethodLinks, but using |
136 | // links is more consistent with what we do for non-function causedby lines. |
137 | |
138 | $newErr = self::getFuncCausedByRaw( $func ) ?? FunctionCausedByLines::emptySingleton(); |
139 | |
140 | foreach ( $addedTaint->getSinkParamKeysNoVariadic() as $key ) { |
141 | if ( $reason || $allNewTaint->canOverrideNonVariadicParam( $key ) ) { |
142 | $curTaint = $addedTaint->getParamSinkTaint( $key ); |