This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Saltwater\Water; |
||
4 | |||
5 | use Saltwater\Server as S; |
||
6 | use Saltwater\Utils as U; |
||
7 | use Saltwater\Salt\Context; |
||
8 | use Saltwater\Salt\Module; |
||
9 | use Saltwater\Salt\Provider; |
||
10 | |||
11 | class ModuleFinder |
||
12 | { |
||
13 | /** |
||
14 | * Return the master context for the current master module |
||
15 | * |
||
16 | * @param Context|null $parent inject a parent context |
||
17 | * |
||
18 | * @return Context |
||
19 | */ |
||
20 | public function masterContext($parent = null) |
||
21 | { |
||
22 | $stack = S::$n->modules->getStack(); |
||
23 | |||
24 | foreach (S::$n->modules as $name => $module) { |
||
25 | /** @var Module $module */ |
||
26 | if (!$module->doesProvide('context')) { |
||
27 | continue; |
||
28 | } |
||
29 | |||
30 | $parent = S::$n->context->get($module->masterContext(), $parent); |
||
31 | |||
32 | if ($stack->isMaster($name)) { |
||
33 | break; |
||
34 | } |
||
35 | } |
||
36 | |||
37 | return $parent; |
||
38 | } |
||
39 | |||
40 | /** |
||
41 | * @param int $bit |
||
42 | * @param string $caller |
||
43 | * @param string $type |
||
44 | * |
||
45 | * @return bool|Provider |
||
46 | */ |
||
47 | public function provider($bit, $caller, $type) |
||
48 | { |
||
49 | $stack = S::$n->modules->getStack(); |
||
50 | |||
51 | // Depending on the caller, reset the module stack |
||
52 | $previous_master = $stack->setMaster($caller); |
||
53 | |||
54 | foreach (S::$n->modules->precedenceList() as $module) { |
||
55 | $return = $this->providerFromModule($module, $bit, $caller, $type); |
||
56 | |||
57 | if ($return) { |
||
58 | $stack->setMaster($previous_master); |
||
59 | |||
60 | return $return; |
||
61 | } |
||
62 | } |
||
63 | |||
64 | $stack->setMaster($previous_master); |
||
65 | |||
66 | return $this->tryModuleFallback($bit, $type); |
||
67 | } |
||
68 | |||
69 | /** |
||
70 | * @param Module $module |
||
71 | * @param string $name |
||
0 ignored issues
–
show
|
|||
72 | * @param int $bit |
||
73 | * @param string $caller |
||
74 | * @param string $type |
||
75 | * |
||
76 | * @return Provider|bool |
||
77 | */ |
||
78 | private function providerFromModule($module, $bit, $caller, $type) |
||
79 | { |
||
80 | if (!$module->has($bit)) { |
||
81 | return false; |
||
82 | } |
||
83 | |||
84 | return $module->provider($caller, $type); |
||
85 | } |
||
86 | |||
87 | /** |
||
88 | * @param integer $bit |
||
89 | * @param string $type |
||
90 | * |
||
91 | * @return Provider|bool |
||
92 | */ |
||
93 | private function tryModuleFallback($bit, $type) |
||
94 | { |
||
95 | // As a last resort, step one module up within stack and try again |
||
96 | if ($caller = S::$n->modules->getStack()->advanceMaster()) { |
||
97 | return $this->provider($bit, $caller, $type); |
||
0 ignored issues
–
show
It seems like
$caller defined by \Saltwater\Server::$n->m...tack()->advanceMaster() on line 96 can also be of type boolean ; however, Saltwater\Water\ModuleFinder::provider() does only seem to accept string , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
98 | } |
||
99 | |||
100 | return false; |
||
101 | } |
||
102 | |||
103 | /** |
||
104 | * Find the module of a caller class |
||
105 | * |
||
106 | * @param array $caller |
||
107 | * @param string $provider |
||
108 | * |
||
109 | * @return string module name |
||
110 | */ |
||
111 | public function find($caller, $provider) |
||
112 | { |
||
113 | list(, $salt, $namespace) = U::extractFromClass($caller); |
||
114 | |||
115 | $is_provider = $salt == $provider; |
||
116 | |||
117 | $bit = S::$n->registry->bit($salt); |
||
118 | |||
119 | foreach (S::$n->modules->reverse() as $name => $module) { |
||
120 | /** @var Module $module */ |
||
121 | if ($this->check($module, $is_provider, $bit, $namespace)) { |
||
122 | return $name; |
||
123 | } |
||
124 | } |
||
125 | |||
126 | return null; |
||
127 | } |
||
128 | |||
129 | /** |
||
130 | * @param Module $module |
||
131 | * @param bool $is_provider |
||
0 ignored issues
–
show
There is no parameter named
$is_provider . Was it maybe removed?
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. Consider the following example. The parameter /**
* @param array $germany
* @param array $island
* @param array $italy
*/
function finale($germany, $island) {
return "2:1";
}
The most likely cause is that the parameter was removed, but the annotation was not. ![]() |
|||
132 | * @param int $bit |
||
133 | * @param string $namespace |
||
134 | * |
||
135 | * @return bool |
||
136 | */ |
||
137 | private function check($module, $isProvider, $bit, $namespace) |
||
138 | { |
||
139 | if ($isProvider === ($module::getNamespace() == $namespace)) { |
||
140 | return false; |
||
141 | } |
||
142 | |||
143 | return $module->has($bit); |
||
144 | } |
||
145 | |||
146 | /** |
||
147 | * Return a list of Modules providing a Salt |
||
148 | * |
||
149 | * @param string $salt |
||
150 | * @param bool $first only return the first item on the list |
||
151 | * |
||
152 | * @return Module[]|string[]|false |
||
153 | */ |
||
154 | public function modulesBySalt($salt, $first = false) |
||
155 | { |
||
156 | if (!S::$n->registry->exists($salt)) { |
||
157 | return false; |
||
158 | } |
||
159 | |||
160 | $list = new ModuleList( |
||
161 | S::$n->modules->precedenceList() ?: S::$n->modules |
||
162 | ); |
||
163 | |||
164 | $call = $first ? 'filterOneBit' : 'filterByBit'; |
||
165 | |||
166 | return $list->$call(S::$n->registry->bit($salt)); |
||
167 | } |
||
168 | } |
||
169 |
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.
Consider the following example. The parameter
$italy
is not defined by the methodfinale(...)
.The most likely cause is that the parameter was removed, but the annotation was not.