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 | ar_pinp::allow( 'ar_connect_ftp'); |
||
4 | ar_pinp::allow( 'ar_connect_ftpClient' ); |
||
5 | |||
6 | class ar_connect_ftp extends arBase { |
||
7 | |||
8 | public static $timeout = 90; |
||
9 | public static $pasv = false; |
||
10 | public static $transferMode = FTP_BINARY; |
||
11 | |||
12 | View Code Duplication | public static function get( $url, $options = array() ) { |
|
13 | $path = parse_url($url, PHP_URL_PATH ); |
||
14 | if ($path !== false ) { |
||
15 | $fileName = basename($path); |
||
16 | $client = new ar_connect_ftpClient( $url, $options ); |
||
17 | if ( !ar_error::isError( $client) ) { |
||
18 | return $client->get( $fileName ); |
||
19 | } else { |
||
20 | return $client; |
||
21 | } |
||
22 | } else { |
||
23 | return ar::error( "Could not parse url ".(string)$url, 11); |
||
24 | } |
||
25 | } |
||
26 | |||
27 | View Code Duplication | public static function put( $url, $contents, $options = array() ) { |
|
28 | $path = parse_url( $url, PHP_URL_PATH ); |
||
29 | if ($path !== false ) { |
||
30 | $fileName = basename($path); |
||
31 | $client = new ar_connect_ftpClient($url, $options ); |
||
32 | if ( !ar_error::isError( $client ) ) { |
||
33 | return $client->put( $contents, $fileName ); |
||
34 | } else { |
||
35 | return $client; |
||
36 | } |
||
37 | } else { |
||
38 | return ar::error( "Could not parse url ".(string)$url, 11); |
||
39 | } |
||
40 | } |
||
41 | |||
42 | public static function client( $url = null, $options = array() ) { |
||
43 | return new ar_connect_ftpClient( $url, $options ); |
||
44 | } |
||
45 | |||
46 | public static function configure( $option, $value ) { |
||
47 | switch ( $option ) { |
||
48 | case 'timeout' : |
||
49 | self::$timeout = $value; |
||
50 | break; |
||
51 | case 'pasv' : |
||
52 | self::$pasv = $value; |
||
53 | break; |
||
54 | case 'transferMode' : |
||
55 | self::$transferMode = $value; |
||
56 | break; |
||
57 | } |
||
58 | } |
||
59 | |||
60 | public function __set( $name, $value ) { |
||
61 | ar_connect_ftp::configure( $name, $value ); |
||
62 | } |
||
63 | |||
64 | public function __get( $name ) { |
||
65 | if ( isset( ar_connect_ftp::${$name} ) ) { |
||
66 | return ar_connect_ftp::${$name}; |
||
67 | } |
||
68 | } |
||
69 | |||
70 | } |
||
71 | |||
72 | interface ar_connect_ftpClientInterface { |
||
73 | |||
74 | public function get( $file, $options = array() ); |
||
75 | |||
76 | public function put( $contents, $file, $options = array() ); |
||
77 | |||
78 | public function login( $username, $password = null); |
||
79 | |||
80 | public function connect( $host, $port = 21); |
||
81 | |||
82 | public function disconnect(); |
||
83 | |||
84 | public function delete( $file, $options = array() ); |
||
85 | |||
86 | public function cd( $dir ); |
||
87 | |||
88 | public function ls(); |
||
89 | |||
90 | public function mkdir( $dirname ); |
||
91 | |||
92 | public function rename( $name, $newname ); |
||
93 | |||
94 | public function chmod( $mode, $filename ); |
||
95 | |||
96 | public function size( $filename ); |
||
97 | |||
98 | public function mdtm( $filename ); |
||
99 | |||
100 | public function pwd(); |
||
101 | |||
102 | public function mode( $mode ); |
||
103 | |||
104 | public function pasv( $pasv ); |
||
105 | |||
106 | } |
||
107 | |||
108 | class ar_connect_ftpClient extends arBase implements ar_connect_ftpClientInterface { |
||
109 | //FIXME: change error codes to the ar_exception constants |
||
110 | public $options = array(); |
||
111 | public $host = null; |
||
112 | public $port = null; |
||
113 | public $user = null; |
||
114 | protected $pass = null; |
||
115 | public $path = null; |
||
116 | protected $connection = null; |
||
117 | |||
118 | public function __construct( $url = null, $options = array() ) { |
||
119 | $this->options = $options + array( |
||
120 | 'mode' => ar_connect_ftp::$transferMode, |
||
121 | 'pasv' => ar_connect_ftp::$pasv |
||
122 | ); |
||
123 | $parsed = parse_url( $url ); |
||
124 | if ($parsed) { |
||
125 | $this->host = $parsed['host']; |
||
126 | $this->port = $parsed['port'] ? $parsed['port'] : 21; |
||
127 | $this->user = $parsed['user'] ? $parsed['user'] : 'anonymous'; |
||
128 | $this->pass = $parsed['pass'] ? $parsed['pass'] : 'guest'; |
||
129 | $this->path = $parsed['path']; |
||
130 | if ($this->path[strlen($this->path)-1] != '/' ) { |
||
131 | $this->path = substr(dirname($this->path), 1); // relative path for cd |
||
132 | } |
||
133 | if ($this->host) { |
||
134 | $this->connect( $this->host, $this->port ); |
||
135 | $this->login( $this->user, $this->pass ); |
||
136 | if ($this->path) { |
||
137 | $this->cd( $this->path ); |
||
138 | } |
||
139 | } |
||
140 | } |
||
141 | } |
||
142 | |||
143 | public function get( $file, $options = array() ) { |
||
144 | $this->options = array_merge( $this->options, (array) $options ); |
||
145 | $fp = fopen("php://temp/maxmemory:10485760", "w"); |
||
146 | $result = @ftp_fget( $this->connection, $fp, $file, $this->options['mode'] ); |
||
147 | if( $result ) { |
||
148 | fseek( $fp, 0 ); |
||
149 | $result = stream_get_contents( $fp ); |
||
150 | } else { |
||
151 | $result = ar::error( "Failed to get file $file", 12); |
||
152 | } |
||
153 | fclose( $fp ); |
||
154 | return $result; |
||
155 | } |
||
156 | |||
157 | public function put( $contents, $file, $options = array() ) { |
||
158 | $this->options = array_merge( $this->options, (array) $options ); |
||
159 | if ($contents instanceof pfile ) { |
||
0 ignored issues
–
show
|
|||
160 | global $store; |
||
161 | $files = $store->get_filestore('files'); |
||
162 | $path = $files->make_path($contents->id, 'file'); |
||
163 | $fp = fopen($path, 'r'); |
||
164 | } else { |
||
165 | $fp = fopen("php://temp/maxmemory:10485760", "w+"); |
||
166 | fwrite( $fp, (string) $contents ); |
||
167 | fseek( $fp, 0); |
||
168 | } |
||
169 | $result = ftp_fput( $this->connection, $file, $fp, $this->options['mode'] ); |
||
170 | fclose($fp); |
||
171 | if ( !$result ) { |
||
172 | return ar::error( "Could not save file $file.", 10 ); |
||
173 | } |
||
174 | return $this; |
||
175 | } |
||
176 | |||
177 | public function login( $username, $password = null) { |
||
178 | if (!@ftp_login($this->connection, $username, $password)) { |
||
179 | return ar::error( "Could not connect as $username", 1); |
||
180 | } |
||
181 | return $this; |
||
182 | } |
||
183 | |||
184 | public function connect( $host, $port = 21) { |
||
185 | if ( ! $this->connection = ftp_connect( $host, $port ) ) { // FIXME: add timeout? |
||
186 | return ar::error( "Could not connect to $host on port $port", 2); |
||
187 | } else if (ar_connect_ftp::$timeout) { |
||
188 | ftp_set_option( $this->connection, FTP_TIMEOUT_SEC, ar_connect_ftp::$timeout ); |
||
189 | } |
||
190 | return $this; |
||
191 | } |
||
192 | |||
193 | public function cd( $dir ) { |
||
194 | $result = ftp_chdir( $this->connection, $dir ); |
||
195 | if ( !$result ) { |
||
196 | return ar::error( "Could not change to directory $dir.", 9); |
||
197 | } |
||
198 | return $this; |
||
199 | } |
||
200 | |||
201 | public function disconnect() { |
||
202 | ftp_close( $this->connection ); |
||
203 | return $this; |
||
204 | } |
||
205 | |||
206 | public function delete( $file, $options = array() ) { |
||
207 | $result = ftp_delete( $this->connection, $file ); |
||
208 | if ( !$result ) { |
||
209 | return ar::error( "Could not delete file $file.", 7 ); |
||
210 | } |
||
211 | return $this; |
||
212 | } |
||
213 | |||
214 | public function ls($path='.', $verbose=false) { |
||
215 | if (!$verbose) { |
||
216 | $result = ftp_nlist($this->connection, $path); |
||
217 | if ( !$result ) { |
||
0 ignored issues
–
show
The expression
$result of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
218 | return ar::error( "Could not list the current directory.", 8); |
||
219 | } |
||
220 | } else { |
||
221 | if (!$this->connection) { |
||
222 | return ar::error("Connection is not active", 42); |
||
223 | } |
||
224 | $list = ftp_rawlist($this->connection, $path); |
||
225 | if ( !$list ) { |
||
0 ignored issues
–
show
The expression
$list of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
226 | return ar::error( "Could not rawlist the current directory.", 9); |
||
227 | } |
||
228 | $result = array(); |
||
229 | foreach($list as $info) { |
||
230 | $info = preg_split("/[\s]+/", $info, 9); |
||
231 | $entry = array( |
||
232 | "permissions" => $info[0], |
||
233 | "linkcount" => $info[1], |
||
234 | "userid" => $info[2], |
||
235 | "groupid" => $info[3], |
||
236 | "size" => (int)$info[4], |
||
237 | "mtime" => strtotime($info[5] . " " . $info[6] . " " . $info[7]), |
||
238 | "name"=> $info[8] |
||
239 | ); |
||
240 | |||
241 | if (substr($info[0], 0, 1) == "d") { |
||
242 | $entry['type'] = "dir"; |
||
243 | } elseif (substr($info[0], 0, 1) == "l") { |
||
244 | $entry['type'] = "shortcut"; |
||
245 | $nameinfo = explode(" -> ", $info[8]); |
||
246 | $entry['name'] = $nameinfo[0]; |
||
247 | $entry['target'] = $nameinfo[1]; |
||
248 | } else { |
||
249 | $entry['type'] = "file"; |
||
250 | } |
||
251 | $result[$entry['name']] = $entry; |
||
252 | } |
||
253 | } |
||
254 | return $result; |
||
255 | } |
||
256 | |||
257 | public function mkdir( $dirname ) { |
||
258 | $result = ftp_mkdir( $this->connection, $dirname ); |
||
259 | if (!$result) { |
||
260 | return ar::error( "Could not make directory $dirname.", 3); |
||
261 | } |
||
262 | return $this; |
||
263 | } |
||
264 | |||
265 | public function rename( $name, $newname ) { |
||
266 | if (!ftp_rename( $this->connection, $name, $newname ) ) { |
||
267 | return ar::error( "Could not rename $name to $newname.", 4); |
||
268 | } |
||
269 | return $this; |
||
270 | } |
||
271 | |||
272 | public function chmod( $mode, $filename ) { |
||
273 | if (!ftp_chmod( $this->connection, $mode, $filename) ) { |
||
274 | return ar::error( "Could not chmod $filename.", 5); |
||
275 | } |
||
276 | return $this; |
||
277 | } |
||
278 | |||
279 | public function size( $filename ) { |
||
280 | $result = ftp_size($this->connection, $filename); |
||
281 | if ( $result == -1 ) { |
||
282 | return null; |
||
283 | } else { |
||
284 | return $result; |
||
285 | } |
||
286 | } |
||
287 | |||
288 | public function mdtm( $filename ) { |
||
289 | $result = ftp_mdtm( $this->connection, $filename ); |
||
290 | if ($result == -1 ) { |
||
291 | return null; |
||
292 | } else { |
||
293 | return $result; |
||
294 | } |
||
295 | } |
||
296 | |||
297 | public function pwd() { |
||
298 | return ftp_pwd( $this->connection ); |
||
299 | } |
||
300 | |||
301 | public function mode( $mode ) { |
||
302 | $this->options['mode'] = $mode; |
||
303 | return $this; |
||
304 | } |
||
305 | |||
306 | public function pasv( $pasv = true ) { |
||
307 | $this->options['pasv'] = $pasv; |
||
308 | if ( !ftp_pasv( $this->connection, $pasv) ) { |
||
309 | return ar::error( "Could not switch passive mode.", 6); |
||
310 | } |
||
311 | return $this; |
||
312 | } |
||
313 | |||
314 | } |
||
315 |
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.json
file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.json
to be in the root folder of your repository.Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the
require
orrequire-dev
section?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceof
checks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.