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