[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/includes/ -> functions_upload.php (source)

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


Generated: Wed Oct 2 15:03:47 2013 Cross-referenced by PHPXref 0.7.1