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 | declare(strict_types=1); |
||
3 | |||
4 | namespace FakeSocket\Stream; |
||
5 | |||
6 | use FakeSocket\StreamWrapper; |
||
7 | |||
8 | final class Buffer implements StreamWrapper |
||
9 | { |
||
10 | /** @var string */ |
||
11 | private $stream = ''; |
||
12 | |||
13 | /** @var int */ |
||
14 | private $position = 0; |
||
15 | |||
16 | /** @var int */ |
||
17 | private $readCount = 0; |
||
18 | |||
19 | /** @var int */ |
||
20 | private $writeCount = 0; |
||
21 | |||
22 | /** @var array */ |
||
23 | private $limits = [ |
||
24 | 'read' => -1, |
||
25 | 'read_after' => 0, |
||
26 | 'read_every' => 1, |
||
27 | 'write' => -1, |
||
28 | 'write_after' => 0, |
||
29 | 'write_every' => 1, |
||
30 | ]; |
||
31 | |||
32 | 11 | public function stream_open($path, $mode, $options, &$opened_path) |
|
0 ignored issues
–
show
|
|||
33 | { |
||
34 | 11 | $components = parse_url($path); |
|
35 | |||
36 | 11 | static $query = []; |
|
37 | |||
38 | 11 | if (isset($components['query'])) { |
|
39 | 4 | parse_str($components['query'], $query); |
|
40 | } |
||
41 | |||
42 | 11 | $this->configureLimits($query); |
|
0 ignored issues
–
show
It seems like
$query can also be of type null ; however, FakeSocket\Stream\Buffer::configureLimits() does only seem to accept array , 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. ![]() |
|||
43 | |||
44 | 11 | return true; |
|
45 | } |
||
46 | |||
47 | 7 | public function stream_eof() |
|
0 ignored issues
–
show
|
|||
48 | { |
||
49 | 7 | return $this->position >= strlen($this->stream); |
|
50 | } |
||
51 | |||
52 | 3 | public function stream_tell() |
|
0 ignored issues
–
show
|
|||
53 | { |
||
54 | 3 | return $this->position; |
|
55 | } |
||
56 | |||
57 | 8 | public function stream_write($data) |
|
0 ignored issues
–
show
|
|||
58 | { |
||
59 | 8 | ++$this->writeCount; |
|
60 | |||
61 | 8 | if (!$this->canWrite()) { |
|
62 | 2 | return false; |
|
63 | } |
||
64 | |||
65 | 8 | $left = substr($this->stream, 0, $this->position); |
|
66 | |||
67 | 8 | $this->stream = "{$left}{$data}"; |
|
68 | 8 | $this->position += $bytesWritten = strlen($data); |
|
69 | |||
70 | 8 | return $bytesWritten; |
|
71 | } |
||
72 | |||
73 | 3 | public function stream_read($count) |
|
0 ignored issues
–
show
|
|||
74 | { |
||
75 | 3 | ++$this->readCount; |
|
76 | |||
77 | 3 | if (!$this->canRead()) { |
|
78 | 1 | return false; |
|
79 | } |
||
80 | |||
81 | 3 | $data = substr($this->stream, $this->position, $count); |
|
82 | |||
83 | 3 | if ($data) { |
|
84 | 2 | $this->position += strlen($data); |
|
85 | } |
||
86 | |||
87 | 3 | return $data; |
|
88 | } |
||
89 | |||
90 | 3 | public function stream_seek($offset, $whence) |
|
0 ignored issues
–
show
|
|||
91 | { |
||
92 | 3 | static $values = [SEEK_SET, SEEK_CUR, SEEK_END]; |
|
93 | |||
94 | 3 | if (in_array($whence, $values)) { |
|
95 | 3 | if (SEEK_END === $whence) { |
|
96 | 1 | $offset = strlen($this->stream) + $offset; |
|
97 | } |
||
98 | |||
99 | 3 | if ($offset >= 0) { |
|
100 | 3 | $this->position = $offset; |
|
101 | 3 | return true; |
|
102 | } |
||
103 | } |
||
104 | |||
105 | return false; |
||
106 | } |
||
107 | |||
108 | 2 | public function stream_stat() |
|
0 ignored issues
–
show
|
|||
109 | { |
||
110 | 2 | return []; |
|
111 | } |
||
112 | |||
113 | 2 | public function stream_truncate($new_size) |
|
0 ignored issues
–
show
|
|||
114 | { |
||
115 | 2 | $currentLength = strlen($this->stream); |
|
116 | |||
117 | 2 | if ($new_size > $currentLength) { |
|
118 | 1 | $multiplier = $new_size - $currentLength; |
|
119 | 1 | $this->stream .= str_repeat(chr(0), $multiplier); |
|
120 | |||
121 | 1 | return true; |
|
122 | } |
||
123 | |||
124 | 1 | $this->stream = substr($this->stream, 0, $new_size); |
|
125 | |||
126 | 1 | return true; |
|
127 | } |
||
128 | |||
129 | 1 | public function stream_set_option($option, $arg1, $arg2) |
|
0 ignored issues
–
show
|
|||
130 | { |
||
131 | 1 | return true; |
|
132 | } |
||
133 | |||
134 | 11 | private function configureLimits(array $query): void |
|
135 | { |
||
136 | 11 | foreach (array_keys($this->limits) as $limit) { |
|
137 | 11 | if (!isset($query[$limit])) { |
|
138 | 11 | continue; |
|
139 | } |
||
140 | |||
141 | 10 | if (false !== strrpos($limit, 'every')) { |
|
142 | 2 | $query[$limit] = max(1, (int) $query[$limit]); |
|
143 | } |
||
144 | |||
145 | 10 | $this->limits[$limit] = (int) $query[$limit]; |
|
146 | } |
||
147 | 11 | } |
|
148 | |||
149 | 3 | private function canRead(): bool |
|
150 | { |
||
151 | 3 | $noLimit = $this->readCount !== $this->limits['read'] + 1; |
|
152 | |||
153 | 3 | return $noLimit |
|
154 | 3 | && $this->readCount > $this->limits['read_after'] |
|
155 | 3 | && $this->readCount % $this->limits['read_every'] === 0; |
|
156 | } |
||
157 | |||
158 | 8 | private function canWrite(): bool |
|
159 | { |
||
160 | 8 | $noLimit = $this->writeCount !== $this->limits['write'] + 1; |
|
161 | |||
162 | 8 | return $noLimit |
|
163 | 8 | && $this->writeCount > $this->limits['write_after'] |
|
164 | 8 | && $this->writeCount % $this->limits['write_every'] === 0; |
|
165 | } |
||
166 | } |
||
167 |
This check looks from parameters that have been defined for a function or method, but which are not used in the method body.