PluginProbe
The WP Remote WordPress Plugin / 5.88
The WP Remote WordPress Plugin v5.88
6.72 6.69 6.65 6.62 6.48 6.47 4.87 4.97 5.05 5.09 5.16 5.22 5.24 5.25 5.38 5.41 5.42 5.45 5.47 5.53 5.56 5.65 5.68 5.72 5.73 All 53 releases
wpremote / callback / wings / fs_write.php

fs_write.php in The WP Remote WordPress Plugin 5.88, at callback/wings/fs_write.php

452 lines 11.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH')) exit;
3 if (!class_exists('BVFSWriteCallback')) :
4
5 class BVFSWriteCallback extends BVCallbackBase {
6
7 const MEGABYTE = 1048576;
8 const FS_WRITE_WING_VERSION = 1.1;
9
10 public function __construct() {
11 }
12
13 public function removeFiles($files) {
14 $result = array();
15
16 foreach($files as $file) {
17 $file_result = array();
18
19 if (file_exists($file)) {
20
21 $file_result['status'] = unlink($file);
22 if ($file_result['status'] === false) {
23 $file_result['error'] = "UNLINK_FAILED";
24 }
25
26 } else {
27 $file_result['status'] = true;
28 $file_result['error'] = "NOT_PRESENT";
29 }
30
31 $result[$file] = $file_result;
32 }
33
34 $result['status'] = true;
35 return $result;
36 }
37
38 public function makeDirs($dirs, $permissions = 0777, $recursive = true) {
39 $result = array();
40
41 foreach($dirs as $dir) {
42 $dir_result = array();
43
44 if (file_exists($dir)) {
45
46 if (is_dir($dir)) {
47 $dir_result['status'] = true;
48 $dir_result['message'] = "DIR_ALREADY_PRESENT";
49 } else {
50 $dir_result['status'] = false;
51 $dir_result['error'] = "FILE_PRESENT_IN_PLACE_OF_DIR";
52 }
53
54 } else {
55 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_mkdir -- Using mkdir() directly as there is no direct suport for recursion
56 $dir_result['status'] = mkdir($dir, $permissions, $recursive);
57 if ($dir_result['status'] === false) {
58 $dir_result['error'] = "MKDIR_FAILED";
59 }
60
61 }
62
63 $result[$dir] = $dir_result;
64 }
65
66 $result['status'] = true;
67 return $result;
68 }
69
70 public function removeDirs($dirs) {
71 $result = array();
72 $filesystem = WPRHelper::get_direct_filesystem();
73
74 foreach($dirs as $dir) {
75 $dir_result = array();
76
77 if ($filesystem->is_dir($dir) && !is_link($dir)) {
78 if ($this->isEmptyDir($dir)) {
79 $dir_result['status'] = $filesystem->rmdir($dir);
80 if ($dir_result['status'] === false) {
81 $dir_result['error'] = "RMDIR_FAILED";
82 if (is_wp_error($filesystem->errors) && $filesystem->errors->has_errors()) {
83 $dir_result['fs_error'] = $filesystem->errors->get_error_message();
84 }
85 }
86 } else {
87 $dir_result['status'] = false;
88 $dir_result['error'] = "NOT_EMPTY";
89 }
90 } else {
91 $dir_result['status'] = false;
92 $dir_result['error'] = "NOT_DIR";
93 }
94
95 $result[$dir] = $dir_result;
96 }
97
98 $result['status'] = true;
99 return $result;
100 }
101
102 public function isEmptyDir($dir) {
103 $handle = opendir($dir);
104
105 while (false !== ($entry = readdir($handle))) {
106 if ($entry != "." && $entry != "..") {
107 closedir($handle);
108 return false;
109 }
110 }
111 closedir($handle);
112
113 return true;
114 }
115
116 public function doChmod($path_infos) {
117 $result = array();
118 $filesystem = WPRHelper::get_direct_filesystem();
119
120 foreach($path_infos as $path => $mode) {
121 $path_result = array();
122
123 if ($filesystem->exists($path)) {
124 $path_result['status'] = $filesystem->chmod($path, $mode);
125 if ($path_result['status'] === false) {
126 $path_result['error'] = "CHMOD_FAILED";
127 if (is_wp_error($filesystem->errors) && $filesystem->errors->has_errors()) {
128 $path_result['fs_error'] = $filesystem->errors->get_error_message();
129 }
130 }
131 } else {
132 $path_result['status'] = false;
133 $path_result['error'] = "NOT_FOUND";
134 }
135
136 $result[$path] = $path_result;
137 }
138
139 $result['status'] = true;
140 return $result;
141 }
142
143 // phpcs:disable WordPress.WP.AlternativeFunctions.file_system_operations_fopen
144 // phpcs:disable WordPress.WP.AlternativeFunctions.file_system_operations_fread
145 // phpcs:disable WordPress.WP.AlternativeFunctions.file_system_operations_fwrite
146 // phpcs:disable WordPress.WP.AlternativeFunctions.file_system_operations_fclose
147 public function concatFiles($ifiles, $ofile, $bsize, $offset) {
148 if (($offset !== 0) && (!file_exists($ofile))) {
149 return array(
150 'status' => false,
151 'error' => 'OFILE_NOT_FOUND_BEFORE_CONCAT'
152 );
153 }
154
155 if (file_exists($ofile) && ($offset !== 0)) {
156 $handle = fopen($ofile, 'rb+');
157 } else {
158 $handle = fopen($ofile, 'wb+');
159 }
160
161 if ($handle === false) {
162 return array(
163 'status' => false,
164 'error' => 'FOPEN_FAILED'
165 );
166 }
167
168 if ($offset !== 0) {
169 if (fseek($handle, $offset, SEEK_SET) === -1) {
170 return array(
171 'status' => false,
172 'error' => 'FSEEK_FAILED'
173 );
174 }
175 }
176
177 $total_written = 0;
178 foreach($ifiles as $file) {
179 $fp = fopen($file, 'rb');
180 if ($fp === false) {
181 return array(
182 'status' => false,
183 'error' => "UNABLE_TO_OPEN_TMP_OFILE_FOR_READING"
184 );
185 }
186
187 while (!feof($fp)) {
188 $content = fread($fp, $bsize);
189 if ($content === false) {
190 return array(
191 'status' => false,
192 'error' => "UNABLE_TO_READ_INFILE",
193 'filename' => $file
194 );
195 }
196
197 $written = fwrite($handle, $content);
198 if ($written === false) {
199 return array(
200 'status' => false,
201 'error' => "UNABLE_TO_WRITE_TO_OFILE",
202 'filename' => $file
203 );
204 }
205 $total_written += $written;
206 }
207
208 fclose($fp);
209 }
210
211 $result = array();
212 $result['fclose'] = fclose($handle);
213
214 if (file_exists($ofile) && ($total_written != 0)) {
215 $result['status'] = true;
216 $result['fsize'] = filesize($ofile);
217 $result['total_written'] = $total_written;
218 } else {
219 $result['status'] = false;
220 $result['error'] = 'CONCATINATED_FILE_FAILED';
221 }
222
223 return $result;
224 }
225 // phpcs:enable
226 public function renameFiles($path_infos) {
227 $result = array();
228 $filesystem = WPRHelper::get_direct_filesystem();
229
230 foreach ($path_infos as $oldpath => $newpath) {
231 $action_result = array();
232
233 if ($filesystem->exists($oldpath)) {
234 $action_result['status'] = $filesystem->move($oldpath, $newpath, true);
235 if ($action_result['status'] === false) {
236 $action_result['error'] = "RENAME_FAILED";
237 if (is_wp_error($filesystem->errors) && $filesystem->errors->has_errors()) {
238 $action_result['fs_error'] = $filesystem->errors->get_error_message();
239 }
240 }
241 } else {
242 $action_result['status'] = false;
243 $action_result['error'] = "NOT_FOUND";
244 }
245
246 $result[$oldpath] = $action_result;
247 }
248
249 $result['status'] = true;
250 return $result;
251 }
252
253 public function curlFile($ifile_url, $ofile, $timeout) {
254 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen
255 $fp = fopen($ofile, "wb+");
256 if ($fp === false) {
257 return array(
258 'error' => 'FOPEN_FAILED_FOR_TEMP_OFILE'
259 );
260 }
261
262 $result = array();
263
264 // phpcs:disable WordPress.WP.AlternativeFunctions.curl_curl_init, WordPress.WP.AlternativeFunctions.curl_curl_exec, WordPress.WP.AlternativeFunctions.curl_curl_setopt, WordPress.WP.AlternativeFunctions.curl_curl_close, WordPress.WP.AlternativeFunctions.curl_curl_error, WordPress.WP.AlternativeFunctions.curl_curl_errno
265 $ch = curl_init($ifile_url);
266 curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
267 curl_setopt($ch, CURLOPT_HEADER, 0);
268 curl_setopt($ch, CURLOPT_FILE, $fp);
269
270 if (!curl_exec($ch)) {
271 $result['error'] = curl_error($ch);
272 $result['errorno'] = curl_errno($ch);
273 }
274
275 curl_close($ch);
276
277 // phpcs:enable WordPress.WP.AlternativeFunctions.curl_curl_init, WordPress.WP.AlternativeFunctions.curl_curl_exec, WordPress.WP.AlternativeFunctions.curl_curl_setopt, WordPress.WP.AlternativeFunctions.curl_curl_close, WordPress.WP.AlternativeFunctions.curl_curl_error, WordPress.WP.AlternativeFunctions.curl_curl_errno
278
279 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
280 fclose($fp);
281
282
283 return $result;
284 }
285
286 public function streamCopyFile($ifile_url, $ofile) {
287 $result = array();
288 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen
289 $handle = fopen($ifile_url, "rb");
290
291 if ($handle === false) {
292 return array(
293 'error' => "UNABLE_TO_OPEN_REMOTE_FILE_STREAM"
294 );
295 }
296
297 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen
298 $fp = fopen($ofile, "wb+");
299 if ($fp === false) {
300 fclose($handle); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
301
302 return array(
303 'error' => 'FOPEN_FAILED_FOR_OFILE'
304 );
305 }
306
307 if (stream_copy_to_stream($handle, $fp) === false) {
308 $result['error'] = "UNABLE_TO_WRITE_TO_TMP_OFILE";
309 }
310
311 fclose($handle); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
312 fclose($fp); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
313
314 return $result;
315 }
316
317 public function writeContentToFile($content, $ofile) {
318 $result = array();
319 $filesystem = WPRHelper::get_direct_filesystem();
320
321 if ($filesystem->put_contents($ofile, $content) === false) {
322 $result['error'] = 'UNABLE_TO_WRITE_TO_TMP_OFILE';
323
324 if (is_wp_error($filesystem->errors) && $filesystem->errors->has_errors()) {
325 $result['fs_error'] = $filesystem->errors->get_error_message();
326 }
327 }
328
329 return $result;
330 }
331
332 public function moveUploadedFile($ofile) {
333 $result = array();
334
335 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing
336 if (isset($_FILES['myfile'])) {
337 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.NonceVerification.Missing -- tmp_name is a path and nonce is ignored here
338 $myfile = $_FILES['myfile'];
339 $is_upload_ok = false;
340
341 switch ($myfile['error']) {
342 case UPLOAD_ERR_OK:
343 $is_upload_ok = true;
344 break;
345 case UPLOAD_ERR_NO_FILE:
346 $result['error'] = "UPLOADERR_NO_FILE";
347 break;
348 case UPLOAD_ERR_INI_SIZE:
349 case UPLOAD_ERR_FORM_SIZE:
350 $result['error'] = "UPLOADERR_FORM_SIZE";
351 break;
352 default:
353 $result['error'] = "UPLOAD_ERR_UNKNOWN";
354 }
355
356 if ($is_upload_ok && !isset($myfile['tmp_name'])) {
357 $result['error'] = "MYFILE_TMP_NAME_NOT_FOUND";
358 $is_upload_ok = false;
359 }
360
361 if ($is_upload_ok) {
362 if (move_uploaded_file($myfile['tmp_name'], $ofile) === false) {
363 $result['error'] = 'MOVE_UPLOAD_FILE_FAILED';
364 }
365 }
366
367 } else {
368 $result['error'] = "FILE_NOT_PRESENT_IN_FILES";
369 }
370
371 return $result;
372 }
373
374
375 public function uploadFile($params) {
376 $resp = array();
377 $ofile = $params['ofile'];
378
379 switch($params['protocol']) {
380 case "curl":
381 $timeout = isset($params['timeout']) ? $params['timeout'] : 60;
382 $ifile_url = isset($params['ifileurl']) ? $params['ifileurl'] : null;
383
384 $resp = $this->curlFile($ifile_url, $ofile, $timeout);
385 break;
386 case "streamcopy":
387 $ifile_url = isset($params['ifileurl']) ? $params['ifileurl'] : null;
388
389 $resp = $this->streamCopyFile($ifile_url, $ofile);
390 break;
391 case "httpcontenttransfer":
392 $resp = $this->writeContentToFile($params['content'], $ofile);
393 break;
394 case "httpfiletransfer":
395 $resp = $this->moveUploadedFile($ofile);
396 break;
397 default:
398 $resp['error'] = "INVALID_PROTOCOL";
399 }
400
401 if (isset($resp['error'])) {
402 $resp['status'] = false;
403 } else {
404
405 if (file_exists($ofile)) {
406 $resp['status'] = true;
407 $resp['fsize'] = filesize($ofile);
408 } else {
409 $resp['status'] = false;
410 $resp['error'] = "OFILE_NOT_FOUND";
411 }
412
413 }
414
415 return $resp;
416 }
417
418 public function process($request) {
419 $params = $request->params;
420
421 switch ($request->method) {
422 case "rmfle":
423 $resp = $this->removeFiles($params['files']);
424 break;
425 case "chmd":
426 $resp = $this->doChmod($params['pathinfos']);
427 break;
428 case "mkdr":
429 $resp = $this->makeDirs($params['dirs'], $params['permissions'], $params['recursive']);
430 break;
431 case "rmdr":
432 $resp = $this->removeDirs($params['dirs']);
433 break;
434 case "renmefle":
435 $resp = $this->renameFiles($params['pathinfos']);
436 break;
437 case "wrtfle":
438 $resp = $this->uploadFile($params);
439 break;
440 case "cncatfls":
441 $bsize = (isset($params['bsize'])) ? $params['bsize'] : (8 * BVFSWriteCallback::MEGABYTE);
442 $offset = (isset($params['offset'])) ? $params['offset'] : 0;
443 $resp = $this->concatFiles($params['infiles'], $params['ofile'], $bsize, $offset);
444 break;
445 default:
446 $resp = false;
447 }
448
449 return $resp;
450 }
451 }
452 endif;