| 1 | <?php
|
|---|
| 2 | /**
|
|---|
| 3 | *
|
|---|
| 4 | * @package phpBB3
|
|---|
| 5 | * @version $Id$
|
|---|
| 6 | * @copyright (c) 2005 phpBB Group
|
|---|
| 7 | * @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
|---|
| 8 | *
|
|---|
| 9 | */
|
|---|
| 10 |
|
|---|
| 11 | /**
|
|---|
| 12 | * @ignore
|
|---|
| 13 | */
|
|---|
| 14 | if (!defined('IN_PHPBB'))
|
|---|
| 15 | {
|
|---|
| 16 | exit;
|
|---|
| 17 | }
|
|---|
| 18 |
|
|---|
| 19 | /**
|
|---|
| 20 | * Responsible for holding all file relevant information, as well as doing file-specific operations.
|
|---|
| 21 | * The {@link fileupload fileupload class} can be used to upload several files, each of them being this object to operate further on.
|
|---|
| 22 | * @package phpBB3
|
|---|
| 23 | */
|
|---|
| 24 | class filespec
|
|---|
| 25 | {
|
|---|
| 26 | var $filename = '';
|
|---|
| 27 | var $realname = '';
|
|---|
| 28 | var $uploadname = '';
|
|---|
| 29 | var $mimetype = '';
|
|---|
| 30 | var $extension = '';
|
|---|
| 31 | var $filesize = 0;
|
|---|
| 32 | var $width = 0;
|
|---|
| 33 | var $height = 0;
|
|---|
| 34 | var $image_info = array();
|
|---|
| 35 |
|
|---|
| 36 | var $destination_file = '';
|
|---|
| 37 | var $destination_path = '';
|
|---|
| 38 |
|
|---|
| 39 | var $file_moved = false;
|
|---|
| 40 | var $init_error = false;
|
|---|
| 41 | var $local = false;
|
|---|
| 42 |
|
|---|
| 43 | var $error = array();
|
|---|
| 44 |
|
|---|
| 45 | var $upload = '';
|
|---|
| 46 |
|
|---|
| 47 | /**
|
|---|
| 48 | * File Class
|
|---|
| 49 | * @access private
|
|---|
| 50 | */
|
|---|
| 51 | function filespec($upload_ary, $upload_namespace)
|
|---|
| 52 | {
|
|---|
| 53 | if (!isset($upload_ary))
|
|---|
| 54 | {
|
|---|
| 55 | $this->init_error = true;
|
|---|
| 56 | return;
|
|---|
| 57 | }
|
|---|
| 58 |
|
|---|
| 59 | $this->filename = $upload_ary['tmp_name'];
|
|---|
| 60 | $this->filesize = $upload_ary['size'];
|
|---|
| 61 | $name = trim(utf8_htmlspecialchars(utf8_basename($upload_ary['name'])));
|
|---|
| 62 | $this->realname = $this->uploadname = (STRIP) ? stripslashes($name) : $name;
|
|---|
| 63 | $this->mimetype = $upload_ary['type'];
|
|---|
| 64 |
|
|---|
| 65 | // Opera adds the name to the mime type
|
|---|
| 66 | $this->mimetype = (strpos($this->mimetype, '; name') !== false) ? str_replace(strstr($this->mimetype, '; name'), '', $this->mimetype) : $this->mimetype;
|
|---|
| 67 |
|
|---|
| 68 | if (!$this->mimetype)
|
|---|
| 69 | {
|
|---|
| 70 | $this->mimetype = 'application/octetstream';
|
|---|
| 71 | }
|
|---|
| 72 |
|
|---|
| 73 | $this->extension = strtolower($this->get_extension($this->realname));
|
|---|
| 74 |
|
|---|
| 75 | // Try to get real filesize from temporary folder (not always working) ;)
|
|---|
| 76 | $this->filesize = (@filesize($this->filename)) ? @filesize($this->filename) : $this->filesize;
|
|---|
| 77 |
|
|---|
| 78 | $this->width = $this->height = 0;
|
|---|
| 79 | $this->file_moved = false;
|
|---|
| 80 |
|
|---|
| 81 | $this->local = (isset($upload_ary['local_mode'])) ? true : false;
|
|---|
| 82 | $this->upload = $upload_namespace;
|
|---|
| 83 | }
|
|---|
| 84 |
|
|---|
| 85 | /**
|
|---|
| 86 | * Cleans destination filename
|
|---|
| 87 | *
|
|---|
| 88 | * @param real|unique|unique_ext $mode real creates a realname, filtering some characters, lowering every character. Unique creates an unique filename
|
|---|
| 89 | * @param string $prefix Prefix applied to filename
|
|---|
| 90 | * @access public
|
|---|
| 91 | */
|
|---|
| 92 | function clean_filename($mode = 'unique', $prefix = '', $user_id = '')
|
|---|
| 93 | {
|
|---|
| 94 | if ($this->init_error)
|
|---|
| 95 | {
|
|---|
| 96 | return;
|
|---|
| 97 | }
|
|---|
| 98 |
|
|---|
| 99 | switch ($mode)
|
|---|
| 100 | {
|
|---|
| 101 | case 'real':
|
|---|
| 102 | // Remove every extension from filename (to not let the mime bug being exposed)
|
|---|
| 103 | if (strpos($this->realname, '.') !== false)
|
|---|
| 104 | {
|
|---|
| 105 | $this->realname = substr($this->realname, 0, strpos($this->realname, '.'));
|
|---|
| 106 | }
|
|---|
| 107 |
|
|---|
| 108 | // Replace any chars which may cause us problems with _
|
|---|
| 109 | $bad_chars = array("'", "\\", ' ', '/', ':', '*', '?', '"', '<', '>', '|');
|
|---|
| 110 |
|
|---|
| 111 | $this->realname = rawurlencode(str_replace($bad_chars, '_', strtolower($this->realname)));
|
|---|
| 112 | $this->realname = preg_replace("/%(\w{2})/", '_', $this->realname);
|
|---|
| 113 |
|
|---|
| 114 | $this->realname = $prefix . $this->realname . '.' . $this->extension;
|
|---|
| 115 | break;
|
|---|
| 116 |
|
|---|
| 117 | case 'unique':
|
|---|
| 118 | $this->realname = $prefix . md5(unique_id());
|
|---|
| 119 | break;
|
|---|
| 120 |
|
|---|
| 121 | case 'avatar':
|
|---|
| 122 | $this->extension = strtolower($this->extension);
|
|---|
| 123 | $this->realname = $prefix . $user_id . '.' . $this->extension;
|
|---|
| 124 |
|
|---|
| 125 | break;
|
|---|
| 126 |
|
|---|
| 127 | case 'unique_ext':
|
|---|
| 128 | default:
|
|---|
| 129 | $this->realname = $prefix . md5(unique_id()) . '.' . $this->extension;
|
|---|
| 130 | break;
|
|---|
| 131 | }
|
|---|
| 132 | }
|
|---|
| 133 |
|
|---|
| 134 | /**
|
|---|
| 135 | * Get property from file object
|
|---|
| 136 | */
|
|---|
| 137 | function get($property)
|
|---|
| 138 | {
|
|---|
| 139 | if ($this->init_error || !isset($this->$property))
|
|---|
| 140 | {
|
|---|
| 141 | return false;
|
|---|
| 142 | }
|
|---|
| 143 |
|
|---|
| 144 | return $this->$property;
|
|---|
| 145 | }
|
|---|
| 146 |
|
|---|
| 147 | /**
|
|---|
| 148 | * Check if file is an image (mimetype)
|
|---|
| 149 | *
|
|---|
| 150 | * @return true if it is an image, false if not
|
|---|
| 151 | */
|
|---|
| 152 | function is_image()
|
|---|
| 153 | {
|
|---|
| 154 | return (strpos($this->mimetype, 'image/') !== false) ? true : false;
|
|---|
| 155 | }
|
|---|
| 156 |
|
|---|
| 157 | /**
|
|---|
| 158 | * Check if the file got correctly uploaded
|
|---|
| 159 | *
|
|---|
| 160 | * @return true if it is a valid upload, false if not
|
|---|
| 161 | */
|
|---|
| 162 | function is_uploaded()
|
|---|
| 163 | {
|
|---|
| 164 | if (!$this->local && !is_uploaded_file($this->filename))
|
|---|
| 165 | {
|
|---|
| 166 | return false;
|
|---|
| 167 | }
|
|---|
| 168 |
|
|---|
| 169 | if ($this->local && !file_exists($this->filename))
|
|---|
| 170 | {
|
|---|
| 171 | return false;
|
|---|
| 172 | }
|
|---|
| 173 |
|
|---|
| 174 | return true;
|
|---|
| 175 | }
|
|---|
| 176 |
|
|---|
| 177 | /**
|
|---|
| 178 | * Remove file
|
|---|
| 179 | */
|
|---|
| 180 | function remove()
|
|---|
| 181 | {
|
|---|
| 182 | if ($this->file_moved)
|
|---|
| 183 | {
|
|---|
| 184 | @unlink($this->destination_file);
|
|---|
| 185 | }
|
|---|
| 186 | }
|
|---|
| 187 |
|
|---|
| 188 | /**
|
|---|
| 189 | * Get file extension
|
|---|
| 190 | */
|
|---|
| 191 | function get_extension($filename)
|
|---|
| 192 | {
|
|---|
| 193 | if (strpos($filename, '.') === false)
|
|---|
| 194 | {
|
|---|
| 195 | return '';
|
|---|
| 196 | }
|
|---|
| 197 |
|
|---|
| 198 | $filename = explode('.', $filename);
|
|---|
| 199 | return array_pop($filename);
|
|---|
| 200 | }
|
|---|
| 201 |
|
|---|
| 202 | /**
|
|---|
| 203 | * Get mimetype. Utilize mime_content_type if the function exist.
|
|---|
| 204 | * Not used at the moment...
|
|---|
| 205 | */
|
|---|
| 206 | function get_mimetype($filename)
|
|---|
| 207 | {
|
|---|
| 208 | $mimetype = '';
|
|---|
| 209 |
|
|---|
| 210 | if (function_exists('mime_content_type'))
|
|---|
| 211 | {
|
|---|
| 212 | $mimetype = mime_content_type($filename);
|
|---|
| 213 | }
|
|---|
| 214 |
|
|---|
| 215 | // Some browsers choke on a mimetype of application/octet-stream
|
|---|
| 216 | if (!$mimetype || $mimetype == 'application/octet-stream')
|
|---|
| 217 | {
|
|---|
| 218 | $mimetype = 'application/octetstream';
|
|---|
| 219 | }
|
|---|
| 220 |
|
|---|
| 221 | return $mimetype;
|
|---|
| 222 | }
|
|---|
| 223 |
|
|---|
| 224 | /**
|
|---|
| 225 | * Get filesize
|
|---|
| 226 | */
|
|---|
| 227 | function get_filesize($filename)
|
|---|
| 228 | {
|
|---|
| 229 | return @filesize($filename);
|
|---|
| 230 | }
|
|---|
| 231 |
|
|---|
| 232 |
|
|---|
| 233 | /**
|
|---|
| 234 | * Check the first 256 bytes for forbidden content
|
|---|
| 235 | */
|
|---|
| 236 | function check_content($disallowed_content)
|
|---|
| 237 | {
|
|---|
| 238 | if (empty($disallowed_content))
|
|---|
| 239 | {
|
|---|
| 240 | return true;
|
|---|
| 241 | }
|
|---|
| 242 |
|
|---|
| 243 | $fp = @fopen($this->filename, 'rb');
|
|---|
| 244 |
|
|---|
| 245 | if ($fp !== false)
|
|---|
| 246 | {
|
|---|
| 247 | $ie_mime_relevant = fread($fp, 256);
|
|---|
| 248 | fclose($fp);
|
|---|
| 249 | foreach ($disallowed_content as $forbidden)
|
|---|
| 250 | {
|
|---|
| 251 | if (stripos($ie_mime_relevant, '<' . $forbidden) !== false)
|
|---|
| 252 | {
|
|---|
| 253 | return false;
|
|---|
| 254 | }
|
|---|
| 255 | }
|
|---|
| 256 | }
|
|---|
| 257 | return true;
|
|---|
| 258 | }
|
|---|
| 259 |
|
|---|
| 260 | /**
|
|---|
| 261 | * Move file to destination folder
|
|---|
| 262 | * The phpbb_root_path variable will be applied to the destination path
|
|---|
| 263 | *
|
|---|
| 264 | * @param string $destination_path Destination path, for example $config['avatar_path']
|
|---|
| 265 | * @param bool $overwrite If set to true, an already existing file will be overwritten
|
|---|
| 266 | * @param string $chmod Permission mask for chmodding the file after a successful move. The mode entered here reflects the mode defined by {@link phpbb_chmod()}
|
|---|
| 267 | *
|
|---|
| 268 | * @access public
|
|---|
| 269 | */
|
|---|
| 270 | function move_file($destination, $overwrite = false, $skip_image_check = false, $chmod = false)
|
|---|
| 271 | {
|
|---|
| 272 | global $user, $phpbb_root_path;
|
|---|
| 273 |
|
|---|
| 274 | if (sizeof($this->error))
|
|---|
| 275 | {
|
|---|
| 276 | return false;
|
|---|
| 277 | }
|
|---|
| 278 |
|
|---|
| 279 | $chmod = ($chmod === false) ? CHMOD_READ | CHMOD_WRITE : $chmod;
|
|---|
| 280 |
|
|---|
| 281 | // We need to trust the admin in specifying valid upload directories and an attacker not being able to overwrite it...
|
|---|
| 282 | $this->destination_path = $phpbb_root_path . $destination;
|
|---|
| 283 |
|
|---|
| 284 | // Check if the destination path exist...
|
|---|
| 285 | if (!file_exists($this->destination_path))
|
|---|
| 286 | {
|
|---|
| 287 | @unlink($this->filename);
|
|---|
| 288 | return false;
|
|---|
| 289 | }
|
|---|
| 290 |
|
|---|
| 291 | $upload_mode = (@ini_get('open_basedir') || @ini_get('safe_mode') || strtolower(@ini_get('safe_mode')) == 'on') ? 'move' : 'copy';
|
|---|
| 292 | $upload_mode = ($this->local) ? 'local' : $upload_mode;
|
|---|
| 293 | $this->destination_file = $this->destination_path . '/' . utf8_basename($this->realname);
|
|---|
| 294 |
|
|---|
| 295 | // Check if the file already exist, else there is something wrong...
|
|---|
| 296 | if (file_exists($this->destination_file) && !$overwrite)
|
|---|
| 297 | {
|
|---|
| 298 | @unlink($this->filename);
|
|---|
| 299 | }
|
|---|
| 300 | else
|
|---|
| 301 | {
|
|---|
| 302 | if (file_exists($this->destination_file))
|
|---|
| 303 | {
|
|---|
| 304 | @unlink($this->destination_file);
|
|---|
| 305 | }
|
|---|
| 306 |
|
|---|
| 307 | switch ($upload_mode)
|
|---|
| 308 | {
|
|---|
| 309 | case 'copy':
|
|---|
| 310 |
|
|---|
| 311 | if (!@copy($this->filename, $this->destination_file))
|
|---|
| 312 | {
|
|---|
| 313 | if (!@move_uploaded_file($this->filename, $this->destination_file))
|
|---|
| 314 | {
|
|---|
| 315 | $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file);
|
|---|
| 316 | }
|
|---|
| 317 | }
|
|---|
| 318 |
|
|---|
| 319 | break;
|
|---|
| 320 |
|
|---|
| 321 | case 'move':
|
|---|
| 322 |
|
|---|
| 323 | if (!@move_uploaded_file($this->filename, $this->destination_file))
|
|---|
| 324 | {
|
|---|
| 325 | if (!@copy($this->filename, $this->destination_file))
|
|---|
| 326 | {
|
|---|
| 327 | $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file);
|
|---|
| 328 | }
|
|---|
| 329 | }
|
|---|
| 330 |
|
|---|
| 331 | break;
|
|---|
| 332 |
|
|---|
| 333 | case 'local':
|
|---|
| 334 |
|
|---|
| 335 | if (!@copy($this->filename, $this->destination_file))
|
|---|
| 336 | {
|
|---|
| 337 | $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file);
|
|---|
| 338 | }
|
|---|
| 339 |
|
|---|
| 340 | break;
|
|---|
| 341 | }
|
|---|
| 342 |
|
|---|
| 343 | // Remove temporary filename
|
|---|
| 344 | @unlink($this->filename);
|
|---|
| 345 |
|
|---|
| 346 | if (sizeof($this->error))
|
|---|
| 347 | {
|
|---|
| 348 | return false;
|
|---|
| 349 | }
|
|---|
| 350 |
|
|---|
| 351 | phpbb_chmod($this->destination_file, $chmod);
|
|---|
| 352 | }
|
|---|
| 353 |
|
|---|
| 354 | // Try to get real filesize from destination folder
|
|---|
| 355 | $this->filesize = (@filesize($this->destination_file)) ? @filesize($this->destination_file) : $this->filesize;
|
|---|
| 356 |
|
|---|
| 357 | if ($this->is_image() && !$skip_image_check)
|
|---|
| 358 | {
|
|---|
| 359 | $this->width = $this->height = 0;
|
|---|
| 360 |
|
|---|
| 361 | if (($this->image_info = @getimagesize($this->destination_file)) !== false)
|
|---|
| 362 | {
|
|---|
| 363 | $this->width = $this->image_info[0];
|
|---|
| 364 | $this->height = $this->image_info[1];
|
|---|
| 365 |
|
|---|
| 366 | if (!empty($this->image_info['mime']))
|
|---|
| 367 | {
|
|---|
| 368 | $this->mimetype = $this->image_info['mime'];
|
|---|
| 369 | }
|
|---|
| 370 |
|
|---|
| 371 | // Check image type
|
|---|
| 372 | $types = $this->upload->image_types();
|
|---|
| 373 |
|
|---|
| 374 | if (!isset($types[$this->image_info[2]]) || !in_array($this->extension, $types[$this->image_info[2]]))
|
|---|
| 375 | {
|
|---|
| 376 | if (!isset($types[$this->image_info[2]]))
|
|---|
| 377 | {
|
|---|
| 378 | $this->error[] = sprintf($user->lang['IMAGE_FILETYPE_INVALID'], $this->image_info[2], $this->mimetype);
|
|---|
| 379 | }
|
|---|
| 380 | else
|
|---|
| 381 | {
|
|---|
| 382 | $this->error[] = sprintf($user->lang['IMAGE_FILETYPE_MISMATCH'], $types[$this->image_info[2]][0], $this->extension);
|
|---|
| 383 | }
|
|---|
| 384 | }
|
|---|
| 385 |
|
|---|
| 386 | // Make sure the dimensions match a valid image
|
|---|
| 387 | if (empty($this->width) || empty($this->height))
|
|---|
| 388 | {
|
|---|
| 389 | $this->error[] = $user->lang['ATTACHED_IMAGE_NOT_IMAGE'];
|
|---|
| 390 | }
|
|---|
| 391 | }
|
|---|
| 392 | else
|
|---|
| 393 | {
|
|---|
| 394 | $this->error[] = $user->lang['UNABLE_GET_IMAGE_SIZE'];
|
|---|
| 395 | }
|
|---|
| 396 | }
|
|---|
| 397 |
|
|---|
| 398 | $this->file_moved = true;
|
|---|
| 399 | $this->additional_checks();
|
|---|
| 400 | unset($this->upload);
|
|---|
| 401 |
|
|---|
| 402 | return true;
|
|---|
| 403 | }
|
|---|
| 404 |
|
|---|
| 405 | /**
|
|---|
| 406 | * Performing additional checks
|
|---|
| 407 | */
|
|---|
| 408 | function additional_checks()
|
|---|
| 409 | {
|
|---|
| 410 | global $user;
|
|---|
| 411 |
|
|---|
| 412 | if (!$this->file_moved)
|
|---|
| 413 | {
|
|---|
| 414 | return false;
|
|---|
| 415 | }
|
|---|
| 416 |
|
|---|
| 417 | // Filesize is too big or it's 0 if it was larger than the maxsize in the upload form
|
|---|
| 418 | if ($this->upload->max_filesize && ($this->get('filesize') > $this->upload->max_filesize || $this->filesize == 0))
|
|---|
| 419 | {
|
|---|
| 420 | $max_filesize = get_formatted_filesize($this->upload->max_filesize, false);
|
|---|
| 421 |
|
|---|
| 422 | $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit']);
|
|---|
| 423 |
|
|---|
| 424 | return false;
|
|---|
| 425 | }
|
|---|
| 426 |
|
|---|
| 427 | if (!$this->upload->valid_dimensions($this))
|
|---|
| 428 | {
|
|---|
| 429 | $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'WRONG_SIZE'], $this->upload->min_width, $this->upload->min_height, $this->upload->max_width, $this->upload->max_height, $this->width, $this->height);
|
|---|
| 430 |
|
|---|
| 431 | return false;
|
|---|
| 432 | }
|
|---|
| 433 |
|
|---|
| 434 | return true;
|
|---|
| 435 | }
|
|---|
| 436 | }
|
|---|
| 437 |
|
|---|
| 438 | /**
|
|---|
| 439 | * Class for assigning error messages before a real filespec class can be assigned
|
|---|
| 440 | *
|
|---|
| 441 | * @package phpBB3
|
|---|
| 442 | */
|
|---|
| 443 | class fileerror extends filespec
|
|---|
| 444 | {
|
|---|
| 445 | function fileerror($error_msg)
|
|---|
| 446 | {
|
|---|
| 447 | $this->error[] = $error_msg;
|
|---|
| 448 | }
|
|---|
| 449 | }
|
|---|
| 450 |
|
|---|
| 451 | /**
|
|---|
| 452 | * File upload class
|
|---|
| 453 | * Init class (all parameters optional and able to be set/overwritten separately) - scope is global and valid for all uploads
|
|---|
| 454 | *
|
|---|
| 455 | * @package phpBB3
|
|---|
| 456 | */
|
|---|
| 457 | class fileupload
|
|---|
| 458 | {
|
|---|
| 459 | var $allowed_extensions = array();
|
|---|
| 460 | var $disallowed_content = array();
|
|---|
| 461 | var $max_filesize = 0;
|
|---|
| 462 | var $min_width = 0;
|
|---|
| 463 | var $min_height = 0;
|
|---|
| 464 | var $max_width = 0;
|
|---|
| 465 | var $max_height = 0;
|
|---|
| 466 | var $error_prefix = '';
|
|---|
| 467 |
|
|---|
| 468 | /**
|
|---|
| 469 | * Init file upload class.
|
|---|
| 470 | *
|
|---|
| 471 | * @param string $error_prefix Used error messages will get prefixed by this string
|
|---|
| 472 | * @param array $allowed_extensions Array of allowed extensions, for example array('jpg', 'jpeg', 'gif', 'png')
|
|---|
| 473 | * @param int $max_filesize Maximum filesize
|
|---|
| 474 | * @param int $min_width Minimum image width (only checked for images)
|
|---|
| 475 | * @param int $min_height Minimum image height (only checked for images)
|
|---|
| 476 | * @param int $max_width Maximum image width (only checked for images)
|
|---|
| 477 | * @param int $max_height Maximum image height (only checked for images)
|
|---|
| 478 | *
|
|---|
| 479 | */
|
|---|
| 480 | function fileupload($error_prefix = '', $allowed_extensions = false, $max_filesize = false, $min_width = false, $min_height = false, $max_width = false, $max_height = false, $disallowed_content = false)
|
|---|
| 481 | {
|
|---|
| 482 | $this->set_allowed_extensions($allowed_extensions);
|
|---|
| 483 | $this->set_max_filesize($max_filesize);
|
|---|
| 484 | $this->set_allowed_dimensions($min_width, $min_height, $max_width, $max_height);
|
|---|
| 485 | $this->set_error_prefix($error_prefix);
|
|---|
| 486 | $this->set_disallowed_content($disallowed_content);
|
|---|
| 487 | }
|
|---|
| 488 |
|
|---|
| 489 | /**
|
|---|
| 490 | * Reset vars
|
|---|
| 491 | */
|
|---|
| 492 | function reset_vars()
|
|---|
| 493 | {
|
|---|
| 494 | $this->max_filesize = 0;
|
|---|
| 495 | $this->min_width = $this->min_height = $this->max_width = $this->max_height = 0;
|
|---|
| 496 | $this->error_prefix = '';
|
|---|
| 497 | $this->allowed_extensions = array();
|
|---|
| 498 | $this->disallowed_content = array();
|
|---|
| 499 | }
|
|---|
| 500 |
|
|---|
| 501 | /**
|
|---|
| 502 | * Set allowed extensions
|
|---|
| 503 | */
|
|---|
| 504 | function set_allowed_extensions($allowed_extensions)
|
|---|
| 505 | {
|
|---|
| 506 | if ($allowed_extensions !== false && is_array($allowed_extensions))
|
|---|
| 507 | {
|
|---|
| 508 | $this->allowed_extensions = $allowed_extensions;
|
|---|
| 509 | }
|
|---|
| 510 | }
|
|---|
| 511 |
|
|---|
| 512 | /**
|
|---|
| 513 | * Set allowed dimensions
|
|---|
| 514 | */
|
|---|
| 515 | function set_allowed_dimensions($min_width, $min_height, $max_width, $max_height)
|
|---|
| 516 | {
|
|---|
| 517 | $this->min_width = (int) $min_width;
|
|---|
| 518 | $this->min_height = (int) $min_height;
|
|---|
| 519 | $this->max_width = (int) $max_width;
|
|---|
| 520 | $this->max_height = (int) $max_height;
|
|---|
| 521 | }
|
|---|
| 522 |
|
|---|
| 523 | /**
|
|---|
| 524 | * Set maximum allowed filesize
|
|---|
| 525 | */
|
|---|
| 526 | function set_max_filesize($max_filesize)
|
|---|
| 527 | {
|
|---|
| 528 | if ($max_filesize !== false && (int) $max_filesize)
|
|---|
| 529 | {
|
|---|
| 530 | $this->max_filesize = (int) $max_filesize;
|
|---|
| 531 | }
|
|---|
| 532 | }
|
|---|
| 533 |
|
|---|
| 534 | /**
|
|---|
| 535 | * Set disallowed strings
|
|---|
| 536 | */
|
|---|
| 537 | function set_disallowed_content($disallowed_content)
|
|---|
| 538 | {
|
|---|
| 539 | if ($disallowed_content !== false && is_array($disallowed_content))
|
|---|
| 540 | {
|
|---|
| 541 | $this->disallowed_content = $disallowed_content;
|
|---|
| 542 | }
|
|---|
| 543 | }
|
|---|
| 544 |
|
|---|
| 545 | /**
|
|---|
| 546 | * Set error prefix
|
|---|
| 547 | */
|
|---|
| 548 | function set_error_prefix($error_prefix)
|
|---|
| 549 | {
|
|---|
| 550 | $this->error_prefix = $error_prefix;
|
|---|
| 551 | }
|
|---|
| 552 |
|
|---|
| 553 | /**
|
|---|
| 554 | * Form upload method
|
|---|
| 555 | * Upload file from users harddisk
|
|---|
| 556 | *
|
|---|
| 557 | * @param string $form_name Form name assigned to the file input field (if it is an array, the key has to be specified)
|
|---|
| 558 | * @return object $file Object "filespec" is returned, all further operations can be done with this object
|
|---|
| 559 | * @access public
|
|---|
| 560 | */
|
|---|
| 561 | function form_upload($form_name)
|
|---|
| 562 | {
|
|---|
| 563 | global $user;
|
|---|
| 564 |
|
|---|
| 565 | unset($_FILES[$form_name]['local_mode']);
|
|---|
| 566 | $file = new filespec($_FILES[$form_name], $this);
|
|---|
| 567 |
|
|---|
| 568 | if ($file->init_error)
|
|---|
| 569 | {
|
|---|
| 570 | $file->error[] = '';
|
|---|
| 571 | return $file;
|
|---|
| 572 | }
|
|---|
| 573 |
|
|---|
| 574 | // Error array filled?
|
|---|
| 575 | if (isset($_FILES[$form_name]['error']))
|
|---|
| 576 | {
|
|---|
| 577 | $error = $this->assign_internal_error($_FILES[$form_name]['error']);
|
|---|
| 578 |
|
|---|
| 579 | if ($error !== false)
|
|---|
| 580 | {
|
|---|
| 581 | $file->error[] = $error;
|
|---|
| 582 | return $file;
|
|---|
| 583 | }
|
|---|
| 584 | }
|
|---|
| 585 |
|
|---|
| 586 | // Check if empty file got uploaded (not catched by is_uploaded_file)
|
|---|
| 587 | if (isset($_FILES[$form_name]['size']) && $_FILES[$form_name]['size'] == 0)
|
|---|
| 588 | {
|
|---|
| 589 | $file->error[] = $user->lang[$this->error_prefix . 'EMPTY_FILEUPLOAD'];
|
|---|
| 590 | return $file;
|
|---|
| 591 | }
|
|---|
| 592 |
|
|---|
| 593 | // PHP Upload filesize exceeded
|
|---|
| 594 | if ($file->get('filename') == 'none')
|
|---|
| 595 | {
|
|---|
| 596 | $max_filesize = @ini_get('upload_max_filesize');
|
|---|
| 597 | $unit = 'MB';
|
|---|
| 598 |
|
|---|
| 599 | if (!empty($max_filesize))
|
|---|
| 600 | {
|
|---|
| 601 | $unit = strtolower(substr($max_filesize, -1, 1));
|
|---|
| 602 | $max_filesize = (int) $max_filesize;
|
|---|
| 603 |
|
|---|
| 604 | $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB');
|
|---|
| 605 | }
|
|---|
| 606 |
|
|---|
| 607 | $file->error[] = (empty($max_filesize)) ? $user->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($user->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], $max_filesize, $user->lang[$unit]);
|
|---|
| 608 | return $file;
|
|---|
| 609 | }
|
|---|
| 610 |
|
|---|
| 611 | // Not correctly uploaded
|
|---|
| 612 | if (!$file->is_uploaded())
|
|---|
| 613 | {
|
|---|
| 614 | $file->error[] = $user->lang[$this->error_prefix . 'NOT_UPLOADED'];
|
|---|
| 615 | return $file;
|
|---|
| 616 | }
|
|---|
| 617 |
|
|---|
| 618 | $this->common_checks($file);
|
|---|
| 619 |
|
|---|
| 620 | return $file;
|
|---|
| 621 | }
|
|---|
| 622 |
|
|---|
| 623 | /**
|
|---|
| 624 | * Move file from another location to phpBB
|
|---|
| 625 | */
|
|---|
| 626 | function local_upload($source_file, $filedata = false)
|
|---|
| 627 | {
|
|---|
| 628 | global $user;
|
|---|
| 629 |
|
|---|
| 630 | $form_name = 'local';
|
|---|
| 631 |
|
|---|
| 632 | $_FILES[$form_name]['local_mode'] = true;
|
|---|
| 633 | $_FILES[$form_name]['tmp_name'] = $source_file;
|
|---|
| 634 |
|
|---|
| 635 | if ($filedata === false)
|
|---|
| 636 | {
|
|---|
| 637 | $_FILES[$form_name]['name'] = utf8_basename($source_file);
|
|---|
| 638 | $_FILES[$form_name]['size'] = 0;
|
|---|
| 639 | $mimetype = '';
|
|---|
| 640 |
|
|---|
| 641 | if (function_exists('mime_content_type'))
|
|---|
| 642 | {
|
|---|
| 643 | $mimetype = mime_content_type($source_file);
|
|---|
| 644 | }
|
|---|
| 645 |
|
|---|
| 646 | // Some browsers choke on a mimetype of application/octet-stream
|
|---|
| 647 | if (!$mimetype || $mimetype == 'application/octet-stream')
|
|---|
| 648 | {
|
|---|
| 649 | $mimetype = 'application/octetstream';
|
|---|
| 650 | }
|
|---|
| 651 |
|
|---|
| 652 | $_FILES[$form_name]['type'] = $mimetype;
|
|---|
| 653 | }
|
|---|
| 654 | else
|
|---|
| 655 | {
|
|---|
| 656 | $_FILES[$form_name]['name'] = $filedata['realname'];
|
|---|
| 657 | $_FILES[$form_name]['size'] = $filedata['size'];
|
|---|
| 658 | $_FILES[$form_name]['type'] = $filedata['type'];
|
|---|
| 659 | }
|
|---|
| 660 |
|
|---|
| 661 | $file = new filespec($_FILES[$form_name], $this);
|
|---|
| 662 |
|
|---|
| 663 | if ($file->init_error)
|
|---|
| 664 | {
|
|---|
| 665 | $file->error[] = '';
|
|---|
| 666 | return $file;
|
|---|
| 667 | }
|
|---|
| 668 |
|
|---|
| 669 | if (isset($_FILES[$form_name]['error']))
|
|---|
| 670 | {
|
|---|
| 671 | $error = $this->assign_internal_error($_FILES[$form_name]['error']);
|
|---|
| 672 |
|
|---|
| 673 | if ($error !== false)
|
|---|
| 674 | {
|
|---|
| 675 | $file->error[] = $error;
|
|---|
| 676 | return $file;
|
|---|
| 677 | }
|
|---|
| 678 | }
|
|---|
| 679 |
|
|---|
| 680 | // PHP Upload filesize exceeded
|
|---|
| 681 | if ($file->get('filename') == 'none')
|
|---|
| 682 | {
|
|---|
| 683 | $max_filesize = @ini_get('upload_max_filesize');
|
|---|
| 684 | $unit = 'MB';
|
|---|
| 685 |
|
|---|
| 686 | if (!empty($max_filesize))
|
|---|
| 687 | {
|
|---|
| 688 | $unit = strtolower(substr($max_filesize, -1, 1));
|
|---|
| 689 | $max_filesize = (int) $max_filesize;
|
|---|
| 690 |
|
|---|
| 691 | $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB');
|
|---|
| 692 | }
|
|---|
| 693 |
|
|---|
| 694 | $file->error[] = (empty($max_filesize)) ? $user->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($user->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], $max_filesize, $user->lang[$unit]);
|
|---|
| 695 | return $file;
|
|---|
| 696 | }
|
|---|
| 697 |
|
|---|
| 698 | // Not correctly uploaded
|
|---|
| 699 | if (!$file->is_uploaded())
|
|---|
| 700 | {
|
|---|
| 701 | $file->error[] = $user->lang[$this->error_prefix . 'NOT_UPLOADED'];
|
|---|
| 702 | return $file;
|
|---|
| 703 | }
|
|---|
| 704 |
|
|---|
| 705 | $this->common_checks($file);
|
|---|
| 706 |
|
|---|
| 707 | return $file;
|
|---|
| 708 | }
|
|---|
| 709 |
|
|---|
| 710 | /**
|
|---|
| 711 | * Remote upload method
|
|---|
| 712 | * Uploads file from given url
|
|---|
| 713 | *
|
|---|
| 714 | * @param string $upload_url URL pointing to file to upload, for example http://www.foobar.com/example.gif
|
|---|
| 715 | * @return object $file Object "filespec" is returned, all further operations can be done with this object
|
|---|
| 716 | * @access public
|
|---|
| 717 | */
|
|---|
| 718 | function remote_upload($upload_url)
|
|---|
| 719 | {
|
|---|
| 720 | global $user, $phpbb_root_path;
|
|---|
| 721 |
|
|---|
| 722 | $upload_ary = array();
|
|---|
| 723 | $upload_ary['local_mode'] = true;
|
|---|
| 724 |
|
|---|
| 725 | if (!preg_match('#^(https?://).*?\.(' . implode('|', $this->allowed_extensions) . ')$#i', $upload_url, $match))
|
|---|
| 726 | {
|
|---|
| 727 | $file = new fileerror($user->lang[$this->error_prefix . 'URL_INVALID']);
|
|---|
| 728 | return $file;
|
|---|
| 729 | }
|
|---|
| 730 |
|
|---|
| 731 | if (empty($match[2]))
|
|---|
| 732 | {
|
|---|
| 733 | $file = new fileerror($user->lang[$this->error_prefix . 'URL_INVALID']);
|
|---|
| 734 | return $file;
|
|---|
| 735 | }
|
|---|
| 736 |
|
|---|
| 737 | $url = parse_url($upload_url);
|
|---|
| 738 |
|
|---|
| 739 | $host = $url['host'];
|
|---|
| 740 | $path = $url['path'];
|
|---|
| 741 | $port = (!empty($url['port'])) ? (int) $url['port'] : 80;
|
|---|
| 742 |
|
|---|
| 743 | $upload_ary['type'] = 'application/octet-stream';
|
|---|
| 744 |
|
|---|
| 745 | $url['path'] = explode('.', $url['path']);
|
|---|
| 746 | $ext = array_pop($url['path']);
|
|---|
| 747 |
|
|---|
| 748 | $url['path'] = implode('', $url['path']);
|
|---|
| 749 | $upload_ary['name'] = utf8_basename($url['path']) . (($ext) ? '.' . $ext : '');
|
|---|
| 750 | $filename = $url['path'];
|
|---|
| 751 | $filesize = 0;
|
|---|
| 752 |
|
|---|
| 753 | $errno = 0;
|
|---|
| 754 | $errstr = '';
|
|---|
| 755 |
|
|---|
| 756 | if (!($fsock = @fsockopen($host, $port, $errno, $errstr)))
|
|---|
| 757 | {
|
|---|
| 758 | $file = new fileerror($user->lang[$this->error_prefix . 'NOT_UPLOADED']);
|
|---|
| 759 | return $file;
|
|---|
| 760 | }
|
|---|
| 761 |
|
|---|
| 762 | // Make sure $path not beginning with /
|
|---|
| 763 | if (strpos($path, '/') === 0)
|
|---|
| 764 | {
|
|---|
| 765 | $path = substr($path, 1);
|
|---|
| 766 | }
|
|---|
| 767 |
|
|---|
| 768 | fputs($fsock, 'GET /' . $path . " HTTP/1.1\r\n");
|
|---|
| 769 | fputs($fsock, "HOST: " . $host . "\r\n");
|
|---|
| 770 | fputs($fsock, "Connection: close\r\n\r\n");
|
|---|
| 771 |
|
|---|
| 772 | $get_info = false;
|
|---|
| 773 | $data = '';
|
|---|
| 774 | while (!@feof($fsock))
|
|---|
| 775 | {
|
|---|
| 776 | if ($get_info)
|
|---|
| 777 | {
|
|---|
| 778 | $data .= @fread($fsock, 1024);
|
|---|
| 779 | }
|
|---|
| 780 | else
|
|---|
| 781 | {
|
|---|
| 782 | $line = @fgets($fsock, 1024);
|
|---|
| 783 |
|
|---|
| 784 | if ($line == "\r\n")
|
|---|
| 785 | {
|
|---|
| 786 | $get_info = true;
|
|---|
| 787 | }
|
|---|
| 788 | else
|
|---|
| 789 | {
|
|---|
| 790 | if (stripos($line, 'content-type: ') !== false)
|
|---|
| 791 | {
|
|---|
| 792 | $upload_ary['type'] = rtrim(str_replace('content-type: ', '', strtolower($line)));
|
|---|
| 793 | }
|
|---|
| 794 | else if (stripos($line, '404 not found') !== false)
|
|---|
| 795 | {
|
|---|
| 796 | $file = new fileerror($user->lang[$this->error_prefix . 'URL_NOT_FOUND']);
|
|---|
| 797 | return $file;
|
|---|
| 798 | }
|
|---|
| 799 | }
|
|---|
| 800 | }
|
|---|
| 801 | }
|
|---|
| 802 | @fclose($fsock);
|
|---|
| 803 |
|
|---|
| 804 | if (empty($data))
|
|---|
| 805 | {
|
|---|
| 806 | $file = new fileerror($user->lang[$this->error_prefix . 'EMPTY_REMOTE_DATA']);
|
|---|
| 807 | return $file;
|
|---|
| 808 | }
|
|---|
| 809 |
|
|---|
| 810 | $tmp_path = (!@ini_get('safe_mode') || strtolower(@ini_get('safe_mode')) == 'off') ? false : $phpbb_root_path . 'cache';
|
|---|
| 811 | $filename = tempnam($tmp_path, unique_id() . '-');
|
|---|
| 812 |
|
|---|
| 813 | if (!($fp = @fopen($filename, 'wb')))
|
|---|
| 814 | {
|
|---|
| 815 | $file = new fileerror($user->lang[$this->error_prefix . 'NOT_UPLOADED']);
|
|---|
| 816 | return $file;
|
|---|
| 817 | }
|
|---|
| 818 |
|
|---|
| 819 | $upload_ary['size'] = fwrite($fp, $data);
|
|---|
| 820 | fclose($fp);
|
|---|
| 821 | unset($data);
|
|---|
| 822 |
|
|---|
| 823 | $upload_ary['tmp_name'] = $filename;
|
|---|
| 824 |
|
|---|
| 825 | $file = new filespec($upload_ary, $this);
|
|---|
| 826 | $this->common_checks($file);
|
|---|
| 827 |
|
|---|
| 828 | return $file;
|
|---|
| 829 | }
|
|---|
| 830 |
|
|---|
| 831 | /**
|
|---|
| 832 | * Assign internal error
|
|---|
| 833 | * @access private
|
|---|
| 834 | */
|
|---|
| 835 | function assign_internal_error($errorcode)
|
|---|
| 836 | {
|
|---|
| 837 | global $user;
|
|---|
| 838 |
|
|---|
| 839 | switch ($errorcode)
|
|---|
| 840 | {
|
|---|
| 841 | case 1:
|
|---|
| 842 | $max_filesize = @ini_get('upload_max_filesize');
|
|---|
| 843 | $unit = 'MB';
|
|---|
| 844 |
|
|---|
| 845 | if (!empty($max_filesize))
|
|---|
| 846 | {
|
|---|
| 847 | $unit = strtolower(substr($max_filesize, -1, 1));
|
|---|
| 848 | $max_filesize = (int) $max_filesize;
|
|---|
| 849 |
|
|---|
| 850 | $unit = ($unit == 'k') ? 'KB' : (($unit == 'g') ? 'GB' : 'MB');
|
|---|
| 851 | }
|
|---|
| 852 |
|
|---|
| 853 | $error = (empty($max_filesize)) ? $user->lang[$this->error_prefix . 'PHP_SIZE_NA'] : sprintf($user->lang[$this->error_prefix . 'PHP_SIZE_OVERRUN'], $max_filesize, $user->lang[$unit]);
|
|---|
| 854 | break;
|
|---|
| 855 |
|
|---|
| 856 | case 2:
|
|---|
| 857 | $max_filesize = get_formatted_filesize($this->max_filesize, false);
|
|---|
| 858 |
|
|---|
| 859 | $error = sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit']);
|
|---|
| 860 | break;
|
|---|
| 861 |
|
|---|
| 862 | case 3:
|
|---|
| 863 | $error = $user->lang[$this->error_prefix . 'PARTIAL_UPLOAD'];
|
|---|
| 864 | break;
|
|---|
| 865 |
|
|---|
| 866 | case 4:
|
|---|
| 867 | $error = $user->lang[$this->error_prefix . 'NOT_UPLOADED'];
|
|---|
| 868 | break;
|
|---|
| 869 |
|
|---|
| 870 | case 6:
|
|---|
| 871 | $error = 'Temporary folder could not be found. Please check your PHP installation.';
|
|---|
| 872 | break;
|
|---|
| 873 |
|
|---|
| 874 | default:
|
|---|
| 875 | $error = false;
|
|---|
| 876 | break;
|
|---|
| 877 | }
|
|---|
| 878 |
|
|---|
| 879 | return $error;
|
|---|
| 880 | }
|
|---|
| 881 |
|
|---|
| 882 | /**
|
|---|
| 883 | * Perform common checks
|
|---|
| 884 | */
|
|---|
| 885 | function common_checks(&$file)
|
|---|
| 886 | {
|
|---|
| 887 | global $user;
|
|---|
| 888 |
|
|---|
| 889 | // Filesize is too big or it's 0 if it was larger than the maxsize in the upload form
|
|---|
| 890 | if ($this->max_filesize && ($file->get('filesize') > $this->max_filesize || $file->get('filesize') == 0))
|
|---|
| 891 | {
|
|---|
| 892 | $max_filesize = get_formatted_filesize($this->max_filesize, false);
|
|---|
| 893 |
|
|---|
| 894 | $file->error[] = sprintf($user->lang[$this->error_prefix . 'WRONG_FILESIZE'], $max_filesize['value'], $max_filesize['unit']);
|
|---|
| 895 | }
|
|---|
| 896 |
|
|---|
| 897 | // check Filename
|
|---|
| 898 | if (preg_match("#[\\/:*?\"<>|]#i", $file->get('realname')))
|
|---|
| 899 | {
|
|---|
| 900 | $file->error[] = sprintf($user->lang[$this->error_prefix . 'INVALID_FILENAME'], $file->get('realname'));
|
|---|
| 901 | }
|
|---|
| 902 |
|
|---|
| 903 | // Invalid Extension
|
|---|
| 904 | if (!$this->valid_extension($file))
|
|---|
| 905 | {
|
|---|
| 906 | $file->error[] = sprintf($user->lang[$this->error_prefix . 'DISALLOWED_EXTENSION'], $file->get('extension'));
|
|---|
| 907 | }
|
|---|
| 908 |
|
|---|
| 909 | // MIME Sniffing
|
|---|
| 910 | if (!$this->valid_content($file))
|
|---|
| 911 | {
|
|---|
| 912 | $file->error[] = sprintf($user->lang[$this->error_prefix . 'DISALLOWED_CONTENT']);
|
|---|
| 913 | }
|
|---|
| 914 | }
|
|---|
| 915 |
|
|---|
| 916 | /**
|
|---|
| 917 | * Check for allowed extension
|
|---|
| 918 | */
|
|---|
| 919 | function valid_extension(&$file)
|
|---|
| 920 | {
|
|---|
| 921 | return (in_array($file->get('extension'), $this->allowed_extensions)) ? true : false;
|
|---|
| 922 | }
|
|---|
| 923 |
|
|---|
| 924 | /**
|
|---|
| 925 | * Check for allowed dimension
|
|---|
| 926 | */
|
|---|
| 927 | function valid_dimensions(&$file)
|
|---|
| 928 | {
|
|---|
| 929 | if (!$this->max_width && !$this->max_height && !$this->min_width && !$this->min_height)
|
|---|
| 930 | {
|
|---|
| 931 | return true;
|
|---|
| 932 | }
|
|---|
| 933 |
|
|---|
| 934 | if (($file->get('width') > $this->max_width && $this->max_width) ||
|
|---|
| 935 | ($file->get('height') > $this->max_height && $this->max_height) ||
|
|---|
| 936 | ($file->get('width') < $this->min_width && $this->min_width) ||
|
|---|
| 937 | ($file->get('height') < $this->min_height && $this->min_height))
|
|---|
| 938 | {
|
|---|
| 939 | return false;
|
|---|
| 940 | }
|
|---|
| 941 |
|
|---|
| 942 | return true;
|
|---|
| 943 | }
|
|---|
| 944 |
|
|---|
| 945 | /**
|
|---|
| 946 | * Check if form upload is valid
|
|---|
| 947 | */
|
|---|
| 948 | function is_valid($form_name)
|
|---|
| 949 | {
|
|---|
| 950 | return (isset($_FILES[$form_name]) && $_FILES[$form_name]['name'] != 'none') ? true : false;
|
|---|
| 951 | }
|
|---|
| 952 |
|
|---|
| 953 |
|
|---|
| 954 | /**
|
|---|
| 955 | * Check for allowed extension
|
|---|
| 956 | */
|
|---|
| 957 | function valid_content(&$file)
|
|---|
| 958 | {
|
|---|
| 959 | return ($file->check_content($this->disallowed_content));
|
|---|
| 960 | }
|
|---|
| 961 |
|
|---|
| 962 | /**
|
|---|
| 963 | * Return image type/extension mapping
|
|---|
| 964 | */
|
|---|
| 965 | function image_types()
|
|---|
| 966 | {
|
|---|
| 967 | return array(
|
|---|
| 968 | 1 => array('gif'),
|
|---|
| 969 | 2 => array('jpg', 'jpeg'),
|
|---|
| 970 | 3 => array('png'),
|
|---|
| 971 | 4 => array('swf'),
|
|---|
| 972 | 5 => array('psd'),
|
|---|
| 973 | 6 => array('bmp'),
|
|---|
| 974 | 7 => array('tif', 'tiff'),
|
|---|
| 975 | 8 => array('tif', 'tiff'),
|
|---|
| 976 | 9 => array('jpg', 'jpeg'),
|
|---|
| 977 | 10 => array('jpg', 'jpeg'),
|
|---|
| 978 | 11 => array('jpg', 'jpeg'),
|
|---|
| 979 | 12 => array('jpg', 'jpeg'),
|
|---|
| 980 | 13 => array('swc'),
|
|---|
| 981 | 14 => array('iff'),
|
|---|
| 982 | 15 => array('wbmp'),
|
|---|
| 983 | 16 => array('xbm'),
|
|---|
| 984 | );
|
|---|
| 985 | }
|
|---|
| 986 | }
|
|---|
| 987 |
|
|---|
| 988 | ?>
|
|---|