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 iqb\stream; |
||
4 | |||
5 | /** |
||
6 | * A SubStream wraps another stream and provides access to a portion of that stream. |
||
7 | * A SubStream is read only. |
||
8 | * The wrapped stream/resource must be seekable for SubStream to work. |
||
9 | * |
||
10 | * The URL schema is: fopen("iqb.substream://$startindex:$length/$resourceId") |
||
11 | */ |
||
12 | final class SubStream |
||
13 | { |
||
14 | /** |
||
15 | * @var resource |
||
16 | */ |
||
17 | public $context; |
||
18 | |||
19 | /** |
||
20 | * @var resource |
||
21 | */ |
||
22 | private $handle; |
||
23 | |||
24 | /** |
||
25 | * @var int |
||
26 | */ |
||
27 | private $enforceOffsetMin; |
||
28 | |||
29 | /** |
||
30 | * @var int |
||
31 | */ |
||
32 | private $enforceOffsetMax; |
||
33 | |||
34 | /** |
||
35 | * Current offset |
||
36 | * @var int |
||
37 | */ |
||
38 | private $offset = 0; |
||
39 | |||
40 | |||
41 | public function stream_close() |
||
42 | { |
||
43 | } |
||
44 | |||
45 | |||
46 | public function stream_eof() |
||
47 | { |
||
48 | return ($this->offset >= $this->enforceOffsetMax); |
||
49 | } |
||
50 | |||
51 | |||
52 | public function stream_open(string $path, string $mode, int $options) |
||
0 ignored issues
–
show
|
|||
53 | { |
||
54 | $errors = ($options & \STREAM_REPORT_ERRORS); |
||
55 | $parts = \parse_url($path); |
||
56 | |||
57 | if (!isset($parts['scheme']) || $parts['scheme'] !== SUBSTREAM_SCHEME) { |
||
58 | $errors && \trigger_error("Invalid URL scheme.", \E_USER_ERROR); |
||
59 | return false; |
||
60 | } |
||
61 | |||
62 | View Code Duplication | if (!isset($parts['host']) || !\is_numeric($parts['host'])) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
63 | $errors && \trigger_error("Invalid start offset.", \E_USER_ERROR); |
||
64 | return false; |
||
65 | } else { |
||
66 | $offset = \intval($parts['host']); |
||
67 | } |
||
68 | |||
69 | View Code Duplication | if (!isset($parts['port']) || !\is_numeric($parts['port'])) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
70 | $errors && \trigger_error("Invalid length.", \E_USER_ERROR); |
||
71 | return false; |
||
72 | } else { |
||
73 | $length = \intval($parts['port']); |
||
74 | } |
||
75 | |||
76 | if (!isset($parts['path']) || !\is_numeric(\substr($parts['path'], 1))) { |
||
77 | $errors && \trigger_error("Invalid resource to wrap.", \E_USER_ERROR); |
||
78 | return false; |
||
79 | } else { |
||
80 | $resourceId = \intval(\substr($parts['path'], 1)); |
||
81 | } |
||
82 | |||
83 | if (\function_exists('\get_resources')) { |
||
84 | $resources = \get_resources('stream'); |
||
85 | if (isset($resources[$resourceId])) { |
||
86 | $originalResource = $resources[$resourceId]; |
||
87 | $meta = \stream_get_meta_data($originalResource); |
||
88 | |||
89 | if (!isset($meta['seekable']) || !$meta['seekable']) { |
||
90 | $errors && \trigger_error("Can only wrap seekable resources.", \E_USER_ERROR); |
||
91 | return false; |
||
92 | } |
||
93 | |||
94 | if ($meta['wrapper_type'] === 'PHP' && $meta['stream_type'] === 'MEMORY') { |
||
95 | $oldStreamPosition = \ftell($originalResource); |
||
96 | $resource = \fopen($meta['uri'], 'w+b'); |
||
97 | \fseek($originalResource, $this->enforceOffsetMin); |
||
98 | \stream_copy_to_stream($originalResource, $resource, $length, $offset); |
||
99 | $this->enforceOffsetMin = $this->offset = 0; |
||
100 | $this->enforceOffsetMax = $length; |
||
101 | \fseek($originalResource, $oldStreamPosition); |
||
102 | } |
||
103 | |||
104 | else { |
||
105 | $this->enforceOffsetMin = $this->offset = $offset; |
||
106 | $this->enforceOffsetMax = $offset + $length; |
||
107 | $resource = \fopen($meta['uri'], 'r'); |
||
108 | } |
||
109 | } |
||
110 | } |
||
111 | |||
112 | if (!isset($resource)) { |
||
113 | $errors && \trigger_error("Resource not available.", \E_USER_ERROR); |
||
114 | return false; |
||
115 | } |
||
116 | |||
117 | $this->handle = $resource; |
||
118 | return true; |
||
119 | } |
||
120 | |||
121 | |||
122 | public function stream_read(int $count) |
||
123 | { |
||
124 | $realCount = \min($count, $this->enforceOffsetMax - $this->offset); |
||
125 | |||
126 | if ($realCount > 0) { |
||
127 | \fseek($this->handle, $this->offset); |
||
128 | if (($data = \fread($this->handle, $realCount)) !== false) { |
||
129 | $this->offset += \strlen($data); |
||
130 | } |
||
131 | |||
132 | return $data; |
||
133 | } else { |
||
134 | return false; |
||
135 | } |
||
136 | } |
||
137 | |||
138 | |||
139 | public function stream_seek(int $offset, int $whence = \SEEK_SET) |
||
140 | { |
||
141 | if ($whence === \SEEK_SET) { |
||
142 | $newOffset = $this->enforceOffsetMin + $offset; |
||
143 | } elseif ($whence === \SEEK_CUR) { |
||
144 | $newOffset = $this->offset + $offset; |
||
145 | } elseif ($whence === \SEEK_END) { |
||
146 | $newOffset = $this->enforceOffsetMax + $offset; |
||
147 | } else { |
||
148 | return false; |
||
149 | } |
||
150 | |||
151 | if (($newOffset < $this->enforceOffsetMin) || ($this->enforceOffsetMax <= $newOffset)) { |
||
152 | return false; |
||
153 | } |
||
154 | |||
155 | $this->offset = $newOffset; |
||
156 | return true; |
||
157 | } |
||
158 | |||
159 | |||
160 | public function stream_tell() |
||
161 | { |
||
162 | if ($this->offset < $this->enforceOffsetMin || $this->enforceOffsetMax <= $this->offset) { |
||
163 | return; |
||
164 | } |
||
165 | |||
166 | return $this->offset - $this->enforceOffsetMin; |
||
167 | } |
||
168 | |||
169 | |||
170 | public function stream_stat() |
||
171 | { |
||
172 | return [ |
||
173 | 7 => ($this->enforceOffsetMax - $this->enforceOffsetMin), |
||
174 | 'size' => ($this->enforceOffsetMax - $this->enforceOffsetMin), |
||
175 | ]; |
||
176 | } |
||
177 | } |
||
178 |
This check looks from parameters that have been defined for a function or method, but which are not used in the method body.