Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
94.06% covered (success)
94.06%
95 / 101
86.96% covered (warning)
86.96%
20 / 23
CRAP
0.00% covered (danger)
0.00%
0 / 1
FunctionTaintedness
94.06% covered (success)
94.06%
95 / 101
86.96% covered (warning)
86.96%
20 / 23
65.89
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 emptySingleton
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 withOverall
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 getOverall
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 canOverrideOverall
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 withParamSinkTaint
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 withParamPreservedTaint
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 withVariadicParamSinkTaint
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 withVariadicParamPreservedTaint
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 getParamSinkTaint
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
5
 getParamPreservedTaint
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
5.12
 getParamFlags
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 canOverrideNonVariadicParam
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getVariadicParamSinkTaint
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getVariadicParamPreservedTaint
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getVariadicParamIndex
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 canOverrideVariadicParam
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getSinkParamKeysNoVariadic
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPreserveParamKeysNoVariadic
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasParamPreserve
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 asMergedWith
88.24% covered (warning)
88.24%
30 / 34
0.00% covered (danger)
0.00%
0 / 1
14.32
 withoutPreserved
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 asOnlyPreserved
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 toString
n/a
0 / 0
n/a
0 / 0
7
 flagsToString
n/a
0 / 0
n/a
0 / 0
4
 __toString
n/a
0 / 0
n/a
0 / 0
1
1<?php declare( strict_types=1 );
2
3namespace SecurityCheckPlugin;
4
5/**
6 * Value object used to store taintedness of functions.
7 * The $overall prop specifies what taint the function returns
8 *   irrespective of its arguments.
9 *
10 *   For 'overall': only TAINT flags, what taint the output has
11 *   For param keys: EXEC flags for what taints are unsafe here
12 *                     TAINT flags for what taint gets passed through func.
13 * As a special case, if the overall key has self::PRESERVE_TAINT
14 * then any unspecified keys behave like they are self::YES_TAINT
15 *
16 * If func has no info for a parameter, the UnionType will be used to determine its taintedness.
17 * The $overall taintedness must always be set.
18 */
19class FunctionTaintedness {
20    /** @var Taintedness Overall taintedness of the func */
21    private $overall;
22    /** @var Taintedness[] EXEC taintedness for each param */
23    private $paramSinkTaints = [];
24    /** @var PreservedTaintedness[] Preserved taintedness for each param */
25    private $paramPreserveTaints = [];
26    /** @var int|null Index of a variadic parameter, if any */
27    private $variadicParamIndex;
28    /** @var Taintedness|null EXEC taintedness for a variadic parameter, if any */
29    private $variadicParamSinkTaint;
30    /** @var PreservedTaintedness|null Preserved taintedness for a variadic parameter, if any */
31    private $variadicParamPreserveTaint;
32    /** @var int Special overall flags */
33    private $overallFlags = 0;
34    /** @var int[] Special flags for parameters */
35    private $paramFlags = [];
36    /** @var int */
37    private $variadicParamFlags = 0;
38
39    /**
40     * @param Taintedness $overall
41     */
42    public function __construct( Taintedness $overall, int $overallFlags = 0 ) {
43        $this->overall = $overall;
44        $this->overallFlags = $overallFlags;
45    }
46
47    public static function emptySingleton(): self {
48        static $singleton;
49        if ( !$singleton ) {
50            $singleton = new self( Taintedness::safeSingleton() );
51        }
52        return $singleton;
53    }
54
55    public function withOverall( Taintedness $val, int $flags = 0 ): self {
56        $ret = clone $this;
57        $ret->overall = $val;
58        $ret->overallFlags |= $flags;
59        return $ret;
60    }
61
62    /**
63     * Get the overall taint (NOT a clone)
64     *
65     * @return Taintedness
66     */
67    public function getOverall(): Taintedness {
68        return $this->overall;
69    }
70
71    /**
72     * @return bool
73     */
74    public function canOverrideOverall(): bool {
75        return ( $this->overallFlags & SecurityCheckPlugin::NO_OVERRIDE ) === 0;
76    }
77
78    /**
79     * Set the sink taint for a given param
80     *
81     * @param int $param
82     * @param Taintedness $taint
83     * @param int $flags
84     * @return self
85     */
86    public function withParamSinkTaint( int $param, Taintedness $taint, int $flags = 0 ): self {
87        $ret = clone $this;
88        assert( $param !== $ret->variadicParamIndex );
89        $ret->paramSinkTaints[$param] = $taint;
90        $ret->paramFlags[$param] = ( $ret->paramFlags[$param] ?? 0 ) | $flags;
91        return $ret;
92    }
93
94    /**
95     * Set the preserved taint for a given param
96     *
97     * @param int $param
98     * @param PreservedTaintedness $taint
99     * @param int $flags
100     * @return self
101     */
102    public function withParamPreservedTaint( int $param, PreservedTaintedness $taint, int $flags = 0 ): self {
103        $ret = clone $this;
104        assert( $param !== $ret->variadicParamIndex );
105        $ret->paramPreserveTaints[$param] = $taint;
106        $ret->paramFlags[$param] = ( $ret->paramFlags[$param] ?? 0 ) | $flags;