File: /var/www/ilya/data/www/kamforum.ru/ips_kernel/class_upload.php
<?php
/*
+--------------------------------------------------------------------------
| Invision Power Board v2.1.5
| =============================================
| by Matthew Mecham
| (c) 2001 - 2005 Invision Power Services, Inc.
| http://www.invisionpower.com
| =============================================
| Web: http://www.invisionboard.com
| Time: Tue, 18 Oct 2005 19:30:11 GMT
| Release: 95f5a3c9ea538e4ebb097b9464fc22d2
| Licence Info: http://www.invisionboard.com/?license
+---------------------------------------------------------------------------
| > $Date: 2005-10-10 14:03:20 +0100 (Mon, 10 Oct 2005) $
| > $Revision: 22 $
| > $Author: matt $
+---------------------------------------------------------------------------
|
| > UPLOAD handling methods (KERNEL)
| > Module written by Matt Mecham
| > Date started: 15th March 2004
|
| > Module Version Number: 1.0.0
+--------------------------------------------------------------------------
| ERRORS:
| 1: No upload
| 2: Not valid upload type
| 3: Upload exceeds $max_file_size
| 4: Could not move uploaded file, upload deleted
| 5: File pretending to be an image but isn't (poss XSS attack)
+--------------------------------------------------------------------------
*/
/**
* IPS Kernel Pages: Upload
*
* This class contains all generic functions to handle
* the parsing of $_FILE data.
*
* Example Usage:
* <code>
* $upload = new class_upload();
* $upload->out_file_dir = './uploads';
* $upload->max_file_size = '10000000';
* $upload->make_script_safe = 1;
* $upload->allowed_file_ext = array( 'gif', 'jpg', 'jpeg', 'png' );
* $upload->upload_process();
*
* if ( $upload->error_no )
* {
* switch( $upload->error_no )
* {
* case 1:
* // No upload
* print "No upload"; exit();
* case 2:
* case 5:
* // Invalid file ext
* print "Invalid File Extension"; exit();
* case 3:
* // Too big...
* print "File too big"; exit();
* case 4:
* // Cannot move uploaded file
* print "Move failed"; exit();
* }
* }
* print $upload->saved_upload_name . " uploaded!";
* </code>
* ERRORS:
* 1: No upload
* 2: Not valid upload type
* 3: Upload exceeds $max_file_size
* 4: Could not move uploaded file, upload deleted
* 5: File pretending to be an image but isn't (poss XSS attack)
*
* @package IPS_KERNEL
* @author Matt Mecham
* @copyright Invision Power Services, Inc.
* @version 2.1
*/
/**
*
*/
/**
* Upload Class
*
* Methods and functions for handling file uploads
*
* @package IPS_KERNEL
* @author Matt Mecham
* @version 2.1
*/
class class_upload
{
/**
* Name of upload form field
*
* @var string
*/
var $upload_form_field = 'FILE_UPLOAD';
/**
* Out filename *without* extension
* (Leave blank to retain user filename)
*
* @var string
*/
var $out_file_name = '';
/**
* Out dir (./upload) - no trailing slash
*
* @var string
*/
var $out_file_dir = './';
/**
* maximum file size of this upload
*
* @var integer
*/
var $max_file_size = 0;
/**
* Forces PHP, CGI, etc to text
*
* @var integer
*/
var $make_script_safe = 1;
/**
* Force non-img file extenstion (leave blank if not) (ex: 'ibf' makes upload.doc => upload.ibf)
*
* @var string
*/
var $force_data_ext = '';
/**
* Allowed file extensions array( 'gif', 'jpg', 'jpeg'..)
*
* @var array
*/
var $allowed_file_ext = array();
/**
* Array of IMAGE file extensions
*
* @var array
*/
var $image_ext = array( 'gif', 'jpeg', 'jpg', 'jpe', 'png' );
/**
* Check to make sure an image is an image
*
* @var boolean flag
*/
var $image_check = 1;
/**
* Returns current file extension
*
* @var string
*/
var $file_extension = '';
/**
* If force_data_ext == 1, this will return the 'real' extension
* and $file_extension will return the 'force_data_ext'
*
* @var string
*/
var $real_file_extension = '';
/**
* Returns error number
*
* @var integer
*/
var $error_no = 0;
/**
* Returns if upload is img or not
*
* @var integer
*/
var $is_image = 0;
/**
* Returns file name as was uploaded by user
*
* @var string
*/
var $original_file_name = "";
/**
* Returns final file name as is saved on disk. (no path info)
*
* @var string
*/
var $parsed_file_name = "";
/**
* Returns final file name with path info
*
* @var string
*/
var $saved_upload_name = "";
/*-------------------------------------------------------------------------*/
// CONSTRUCTOR
/*-------------------------------------------------------------------------*/
function class_upload()
{
}
/*-------------------------------------------------------------------------*/
// PROCESS THE UPLOAD
/*-------------------------------------------------------------------------*/
/**
* Processes the upload
*
*/
function upload_process()
{
$this->_clean_paths();
//-------------------------------------------------
// Check for getimagesize
//-------------------------------------------------
if ( ! function_exists( 'getimagesize' ) )
{
$this->image_check = 0;
}
//-------------------------------------------------
// Set up some variables to stop carpals developing
//-------------------------------------------------
$FILE_NAME = $_FILES[ $this->upload_form_field ]['name'];
$FILE_SIZE = $_FILES[ $this->upload_form_field ]['size'];
$FILE_TYPE = $_FILES[ $this->upload_form_field ]['type'];
//-------------------------------------------------
// Naughty Opera adds the filename on the end of the
// mime type - we don't want this.
//-------------------------------------------------
$FILE_TYPE = preg_replace( "/^(.+?);.*$/", "\\1", $FILE_TYPE );
//-------------------------------------------------
// Naughty Mozilla likes to use "none" to indicate an empty upload field.
// I love universal languages that aren't universal.
//-------------------------------------------------
if ($_FILES[ $this->upload_form_field ]['name'] == ""
or !$_FILES[ $this->upload_form_field ]['name']
or !$_FILES[ $this->upload_form_field ]['size']
or ($_FILES[ $this->upload_form_field ]['name'] == "none") )
{
$this->error_no = 1;
return;
}
//-------------------------------------------------
// De we have allowed file_extensions?
//-------------------------------------------------
if ( ! is_array( $this->allowed_file_ext ) or ! count( $this->allowed_file_ext ) )
{
$this->error_no = 2;
return;
}
//-------------------------------------------------
// Get file extension
//-------------------------------------------------
$this->file_extension = $this->_get_file_extension( $FILE_NAME );
if ( ! $this->file_extension )
{
$this->error_no = 2;
return;
}
$this->real_file_extension = $this->file_extension;
//-------------------------------------------------
// Valid extension?
//-------------------------------------------------
if ( ! in_array( $this->file_extension, $this->allowed_file_ext ) )
{
$this->error_no = 2;
return;
}
//-------------------------------------------------
// Check the file size
//-------------------------------------------------
if ( ( $this->max_file_size ) and ( $FILE_SIZE > $this->max_file_size ) )
{
$this->error_no = 3;
return;
}
//-------------------------------------------------
// Make the uploaded file safe
//-------------------------------------------------
$FILE_NAME = preg_replace( "/[^\w\.]/", "_", $FILE_NAME );
$this->original_file_name = $FILE_NAME;
//-------------------------------------------------
// Convert file name?
// In any case, file name is WITHOUT extension
//-------------------------------------------------
if ( $this->out_file_name )
{
$this->parsed_file_name = $this->out_file_name;
}
else
{
$this->parsed_file_name = preg_replace( '#\.'.$this->file_extension."#is", "", $FILE_NAME );
}
//-------------------------------------------------
// Make safe?
//-------------------------------------------------
if ( $this->make_script_safe )
{
if ( preg_match( "/\.(cgi|pl|js|asp|php|html|htm|jsp|jar)/", $FILE_NAME ) )
{
$FILE_TYPE = 'text/plain';
$this->file_extension = 'txt';
}
}
//-------------------------------------------------
// Is it an image?
//-------------------------------------------------
if ( is_array( $this->image_ext ) and count( $this->image_ext ) )
{
if ( in_array( $this->file_extension, $this->image_ext ) )
{
$this->is_image = 1;
}
}
//-------------------------------------------------
// Add on the extension...
//-------------------------------------------------
if ( $this->force_data_ext and ! $this->is_image )
{
$this->file_extension = str_replace( ".", "", $this->force_data_ext );
}
$this->parsed_file_name .= '.'.$this->file_extension;
//-------------------------------------------------
// Copy the upload to the uploads directory
// ^^ We need to do this before checking the img
// size for the openbasedir restriction peeps
// We'll just unlink if it doesn't checkout
//-------------------------------------------------
$this->saved_upload_name = $this->out_file_dir.'/'.$this->parsed_file_name;
if ( ! @move_uploaded_file( $_FILES[ $this->upload_form_field ]['tmp_name'], $this->saved_upload_name) )
{
$this->error_no = 4;
return;
}
else
{
@chmod( $this->saved_upload_name, 0777 );
}
//-------------------------------------------------
// Is it an image?
//-------------------------------------------------
if ( $this->is_image )
{
//-------------------------------------------------
// Are we making sure its an image?
//-------------------------------------------------
if ( $this->image_check )
{
$img_attributes = @getimagesize( $this->saved_upload_name );
if ( ! is_array( $img_attributes ) or ! count( $img_attributes ) )
{
// Unlink the file first
@unlink( $this->saved_upload_name );
$this->error_no = 5;
return;
}
else if ( ! $img_attributes[2] )
{
// Unlink the file first
@unlink( $this->saved_upload_name );
$this->error_no = 5;
return;
}
else if ( $img_attributes[2] == 1 AND ( $this->file_extension == 'jpg' OR $this->file_extension == 'jpeg' ) )
{
// Potential XSS attack with a fake GIF header in a JPEG
@unlink( $this->saved_upload_name );
$this->error_no = 5;
return;
}
}
}
}
/*-------------------------------------------------------------------------*/
// INTERNAL: Get file extension
/*-------------------------------------------------------------------------*/
/**
* Returns the file extension of the current filename
*
* @param string Filename
*/
function _get_file_extension($file)
{
return strtolower( str_replace( ".", "", substr( $file, strrpos( $file, '.' ) ) ) );
}
/*-------------------------------------------------------------------------*/
// INTERNAL: Clean paths
/*-------------------------------------------------------------------------*/
/**
* Trims off trailing slashes
*
*/
function _clean_paths()
{
$this->out_file_dir = preg_replace( "#/$#", "", $this->out_file_dir );
}
}
?>