mirror of
https://github.com/e107inc/e107.git
synced 2025-03-14 17:39:46 +01:00
parent
ca12f018c7
commit
c1e1132c52
@ -12,120 +12,289 @@
|
||||
| GNU General Public License (http://gnu.org).
|
||||
|
|
||||
| $Source: /cvs_backup/e107_0.8/e107_handlers/upload_handler.php,v $
|
||||
| $Revision: 1.7 $
|
||||
| $Date: 2007-07-23 20:05:54 $
|
||||
| $Revision: 1.8 $
|
||||
| $Date: 2007-09-20 21:04:23 $
|
||||
| $Author: e107steved $
|
||||
+---------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
if (!defined('e107_INIT')) { exit; }
|
||||
|
||||
@include_once(e_LANGUAGEDIR.e_LANGUAGE."/lan_upload_handler.php");
|
||||
@include_once(e_LANGUAGEDIR."English/lan_upload_handler.php");
|
||||
function file_upload($uploaddir, $avatar = FALSE, $fileinfo = "", $overwrite = "")
|
||||
{
|
||||
include_lan(e_LANGUAGEDIR.e_LANGUAGE."/lan_upload_handler.php");
|
||||
|
||||
//define("UH_DEBUG",TRUE);
|
||||
define("UH_DEBUG",FALSE);
|
||||
/*
|
||||
File upload handler - this is the preferred interface for new code
|
||||
-------------------
|
||||
function process_uploaded_files($uploaddir, $fileinfo = FALSE, $options = array())
|
||||
|
||||
Parameters:
|
||||
$uploaddir - target directory (checked that it exists, but path not otherwise changed)
|
||||
$fileinfo - determines any special handling of file name (combines previous $fileinfo and $avatar parameters):
|
||||
FALSE - default option; no processing
|
||||
"attachment+extra_text" - indicates an attachment (related to forum post or PM), and specifies some optional text which is
|
||||
incorporated into the final file name (the original $fileinfo parameter).
|
||||
$file_name = time()."_".USERID."_".'extra_text'.$name;
|
||||
"prefix+extra_text" - indicates an attachment, and specifies some optional text which is prefixed to the file name
|
||||
"unique" - if the proposed destination file doesn't exist, saved under given name
|
||||
- if the proposed destination file does exist, prepends time() to the file name to make it unique
|
||||
'avatar' - indicates an avatar is being uploaded (not used here)
|
||||
$options - an array of supplementary options, all of which will be given appropriate defaults if not defined:
|
||||
'filetypes' - name of file containing list of valid file types
|
||||
- Always looks in the admin directory
|
||||
- defaults to e_ADMIN.admin_filetypes.php for admins (if file exists), otherwise e_ADMIN.filetypes.php for users.
|
||||
- FALSE disables this option (which implies that 'extra_file_types' is used)
|
||||
'file_mask' - comma-separated list of file types which if defined limits the allowed file types to those which are in both this list and the
|
||||
file specified by the 'filetypes' option. Enables restriction to, for example, image files.
|
||||
'extra_file_types' - if is FALSE or undefined, rejects totally unknown file extensions (even if in $options['filetypes'] file).
|
||||
if TRUE, accepts totally unknown file extensions which are in $options['filetypes'] file.
|
||||
otherwise specifies a comma-separated list of additional permitted file extensions
|
||||
'final_chmod' - chmod() to be applied to uploaded files (0644 default) (This routine expects an integer value, so watch formatting/decoding - its normally
|
||||
specified in octal. Typically use intval($permissions,8) to convert)
|
||||
'max_upload_size' - maximum size of uploaded files in bytes, or as a string with a 'multiplier' letter (e.g. 16M) at the end.
|
||||
- otherwise uses $pref['upload_maxfilesize'] if set
|
||||
- overriding limit of the smaller of 'post_max_size' and 'upload_max_size' if set in php.ini
|
||||
- for DB storage, overriding upper limit of 512000 bytes.
|
||||
(Note: other parts of E107 don't understand strings with a multiplier letter yet)
|
||||
'file_array_name' - the name of the 'input' array - defaults to file_userfile[] - otherwise as set.
|
||||
'max_file_count' - maximum number of files which can be uploaded - default is 'unlimited' if this is zero of not set.
|
||||
'save_to_db' - storage type - if set and TRUE, uploaded files are saved in the database (rhater than as flat files)
|
||||
|
||||
|
||||
Returns FALSE if the upload directory doesn't exist, or various other errors occurred which restrict the amount of meaningful information.
|
||||
Returns an array, with one set of entries per uploaded file, regardless of whether saved or discarded (not all fields always present) - $c is array index:
|
||||
$uploaded[$c]['name'] - file name - as saved to disc or in database
|
||||
$uploaded[$c]['rawname'] - original file name, prior to any addition of identifiers etc (useful for display purposes)
|
||||
$uploaded[$c]['type'] - mime type (if set - as returned by browser)
|
||||
$uploaded[$c]['size'] - size in bytes (should be zero if error)
|
||||
$uploaded[$c]['error'] - numeric error code (zero = OK)
|
||||
$uploaded[$c]['index'] - if upload successful, the index position from the file_userfile[] array - usually numeric, but may be alphanumerif if coded
|
||||
$uploaded[$c]['message'] - text of displayed message relating to file
|
||||
$uploaded[$c]['line'] - only if an error occurred, has line number (from __LINE__)
|
||||
$uploaded[$c]['file'] - only if an error occurred, has file name (from __FILE__)
|
||||
On exit, uploaded files should all have been removed from the temporary directory.
|
||||
No messages displayed - its caller's responsibility to handle errors and display info to user (or can use handle_upload_messages() from this module)
|
||||
|
||||
|
||||
Details of uploaded files are in $_FILES['file_userfile'] (or other array name as set) on entry.
|
||||
|
||||
Elements passed (from PHP) relating to each file:
|
||||
['name'] - the original name
|
||||
['type'] - mime type (if provided - not checked by PHP)
|
||||
['size'] - file size in bytes
|
||||
['tmp_name'] - temporary file name on server
|
||||
['error'] - error code. 0 = 'good'. 1..4 main others, although up to 8 defined for later PHP versions
|
||||
Files stored in server's temporary directory, unless another set
|
||||
|
||||
*/
|
||||
function process_uploaded_files($uploaddir, $fileinfo = FALSE, $options = NULL)
|
||||
{
|
||||
global $pref, $sql, $tp;
|
||||
|
||||
if (!$uploaddir) {$uploaddir = e_FILE."public/";}
|
||||
if($uploaddir == e_THEME) {$pref['upload_storagetype'] = 1;}
|
||||
global $admin_log;
|
||||
|
||||
$allowed_filetypes = get_allowed_filetypes();
|
||||
if (UH_DEBUG) $admin_log->e_log_event(10,debug_backtrace(),"DEBUG","Upload Handler test","Process uploads to {$uploaddir}, fileinfo ".$fileinfo,FALSE,LOG_TO_ROLLING);
|
||||
|
||||
if ($pref['upload_storagetype'] == "2" && $avatar == FALSE)
|
||||
{
|
||||
extract($_FILES);
|
||||
for($c = 0; $c <= 1; $c++)
|
||||
{
|
||||
if ($file_userfile['tmp_name'][$c])
|
||||
{
|
||||
if (($file_status = vet_file($file_userfile['tmp_name'][$c], $file_userfile['name'][$c], $allowed_filetypes)) !== TRUE)
|
||||
{
|
||||
require_once(e_HANDLER."message_handler.php");
|
||||
message_handler("MESSAGE", "".LANUPLOAD_1." '".$file_userfile['type'][$c]."' ".LANUPLOAD_2." ({$file_status})");
|
||||
return FALSE;
|
||||
require_once(FOOTERF);
|
||||
exit;
|
||||
}
|
||||
set_magic_quotes_runtime(0);
|
||||
$data = mysql_escape_string(fread(fopen($file_userfile['tmp_name'][$c], "rb"), filesize($file_userfile['tmp_name'][$c])));
|
||||
set_magic_quotes_runtime(get_magic_quotes_gpc());
|
||||
$file_name = preg_replace("/[^a-z0-9._]/", "", str_replace(" ", "_", str_replace("%20", "_", strtolower($file_userfile['name'][$c]))));
|
||||
$sql->db_Insert("rbinary", "0, '".$tp -> toDB($file_name, true)."', '".$tp -> toDB($file_userfile['type'][$c], true)."', '$data' ");
|
||||
$uploaded[$c]['name'] = "Binary ".mysql_insert_id()."/".$file_name;
|
||||
$uploaded[$c]['type'] = $file_userfile['type'][$c];
|
||||
$uploaded[$c]['size'] = $file_userfile['size'][$c];
|
||||
$uploaded[$c]['index'] = $key; // Store the actual index from the file_userfile array
|
||||
}
|
||||
}
|
||||
return $uploaded;
|
||||
}
|
||||
/*
|
||||
if (ini_get('open_basedir') != ''){
|
||||
require_once(e_HANDLER."message_handler.php");
|
||||
message_handler("MESSAGE", "'open_basedir' restriction is in effect, unable to move uploaded file, deleting ...", __LINE__, __FILE__);
|
||||
return FALSE;
|
||||
}
|
||||
*/
|
||||
|
||||
// echo "<pre>"; print_r($_FILES); echo "</pre>"; exit;
|
||||
$overwrite = varset($options['overwrite'],FALSE); // Hopefully not needed
|
||||
$save_to_db = varset($options['save_to_db'],FALSE); // Hopefully not needed
|
||||
|
||||
$files = $_FILES['file_userfile'];
|
||||
if (!is_array($files))
|
||||
|
||||
$uploaddir = realpath($uploaddir); // Mostly to get rid of the grot that might be passed in from legacy code. Also strips any trailing '/'
|
||||
if (!is_dir($uploaddir))
|
||||
{
|
||||
return FALSE;
|
||||
if (UH_DEBUG) $admin_log->e_log_event(10,__FILE__."|".__FUNCTION__."@".__LINE__,"DEBUG","Upload Handler test","Invalid directory: ".$uploaddir,FALSE,FALSE);
|
||||
return FALSE; // Need a valid directory
|
||||
}
|
||||
if (UH_DEBUG) $admin_log->e_log_event(10,__FILE__."|".__FUNCTION__."@".__LINE__,"DEBUG","Upload Handler test","Destination directory: ".$uploaddir,FALSE,FALSE);
|
||||
|
||||
$c = 0;
|
||||
foreach($files['name'] as $key => $name)
|
||||
{
|
||||
|
||||
if ($files['size'][$key])
|
||||
|
||||
$file_mask = varset($options['file_mask'],'');
|
||||
if (isset($options['filetypes']))
|
||||
{
|
||||
$filesize[] = $files['size'][$key];
|
||||
$name = preg_replace("/[^a-z0-9._-]/", "", str_replace(" ", "_", str_replace("%20", "_", strtolower($name))));
|
||||
$raw_name = $name; // Save 'proper' file name - useful for display
|
||||
if ($avatar == "attachment") {
|
||||
$name = time()."_".USERID."_".$fileinfo.$name;
|
||||
$allowed_filetypes = get_allowed_filetypes($options['filetypes'], $file_mask);
|
||||
}
|
||||
|
||||
$destination_file = getcwd()."/".$uploaddir."/".$name;
|
||||
if ($avatar == "unique" && file_exists($destination_file))
|
||||
elseif (ADMIN && is_readable(e_ADMIN.'admin_filetypes.php'))
|
||||
{
|
||||
$name = time()."_".$name;
|
||||
$destination_file = getcwd()."/".$uploaddir."/".$name;
|
||||
}
|
||||
if (file_exists($destination_file) && !$overwrite)
|
||||
{
|
||||
require_once(e_HANDLER."message_handler.php");
|
||||
message_handler("MESSAGE", LANUPLOAD_10, __LINE__, __FILE__); // duplicate file
|
||||
$f_message .= LANUPLOAD_10 . __LINE__ . __FILE__;
|
||||
$dupe_found = TRUE;
|
||||
$allowed_filetypes = get_allowed_filetypes('admin_filetypes.php', $file_mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
$uploadfile = $files['tmp_name'][$key];
|
||||
if (($file_status = vet_file($uploadfile, $name, $allowed_filetypes)) !== TRUE)
|
||||
{
|
||||
require_once(e_HANDLER."message_handler.php");
|
||||
message_handler("MESSAGE", LANUPLOAD_1." ".$files['type'][$key]." ".LANUPLOAD_2.". ({$file_status})", __LINE__, __FILE__);
|
||||
$f_message .= LANUPLOAD_1." ".$files['type'][$key]." ".LANUPLOAD_2."." . __LINE__ . __FILE__;
|
||||
return FALSE;
|
||||
require_once(FOOTERF);
|
||||
exit;
|
||||
$allowed_filetypes = get_allowed_filetypes('filetypes.php', $file_mask);
|
||||
}
|
||||
|
||||
|
||||
$final_chmod = varset($options['final_chmod'],0644);
|
||||
|
||||
|
||||
|
||||
if (isset($options['file_array_name']))
|
||||
{
|
||||
$files = $_FILES[$options['file_array_name']];
|
||||
}
|
||||
else
|
||||
{
|
||||
$files = $_FILES['file_userfile'];
|
||||
}
|
||||
|
||||
|
||||
$max_file_count = varset($options['max_file_count'],0);
|
||||
|
||||
|
||||
if (!is_array($files))
|
||||
{
|
||||
if (UH_DEBUG) $admin_log->e_log_event(10,__FILE__."|".__FUNCTION__."@".__LINE__,"DEBUG","Upload Handler test","No files uploaded",FALSE,FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
$uploaded = array();
|
||||
|
||||
|
||||
// Work out maximum allowable file size
|
||||
if (UH_DEBUG)
|
||||
{ $admin_log->e_log_event(10,__FILE__."|".__FUNCTION__."@".__LINE__,"DEBUG","Upload Handler test",
|
||||
"File size limits - user set: ".$pref['upload_maxfilesize']." Post_max_size: ".ini_get('post_max_size')." upload_max_size: ".ini_get('upload_max_size'),FALSE,FALSE);
|
||||
}
|
||||
$max_upload_size = file_size_decode(ini_get('post_max_size'));
|
||||
$max_upload_size = file_size_decode(ini_get('upload_max_filesize'), $max_upload_size, 'lt');
|
||||
if (isset($options['max_upload_size']))
|
||||
{
|
||||
$max_upload_size = file_size_decode($options['max_upload_size'], $max_upload_size, 'lt');
|
||||
}
|
||||
else
|
||||
{
|
||||
if (varset($pref['upload_maxfilesize'],0) > 0) $max_upload_size = file_size_decode($pref['upload_maxfilesize'], $max_upload_size, 'lt');
|
||||
}
|
||||
if ($save_to_db) $max_upload_size = min($max_upload_size, 512000); // Approx 500k limit for database saves
|
||||
if (UH_DEBUG) $admin_log->e_log_event(10,__FILE__."|".__FUNCTION__."@".__LINE__,"DEBUG","Upload Handler test","Final max upload size: {$max_upload_size}",FALSE,FALSE);
|
||||
|
||||
|
||||
|
||||
// That's the basics set up - we can start processing files now
|
||||
|
||||
if (UH_DEBUG) $admin_log->e_log_event(10,__FILE__."|".__FUNCTION__."@".__LINE__,"DEBUG","Upload Handler test","Start individual files: ".count($files['name'])." Max upload: ".$max_upload_size,FALSE,FALSE);
|
||||
|
||||
|
||||
$c = 0;
|
||||
foreach ($files['name'] as $key => $name)
|
||||
{
|
||||
if (($name != '') || $files['size'][$key]) // Need this check for things like file manager which allow multiple possible uploads
|
||||
{
|
||||
$name = preg_replace("/[^a-z0-9._-]/", "", str_replace(" ", "_", str_replace("%20", "_", strtolower($name))));
|
||||
$raw_name = $name; // Save 'proper' file name - useful for display
|
||||
|
||||
if (!trim($files['type'][$key])) $files['type'][$key] = 'Unknowm mime-type';
|
||||
|
||||
if (UH_DEBUG) $admin_log->e_log_event(10,__FILE__."|".__FUNCTION__."@".__LINE__,"DEBUG","Upload Handler test","Process file {$name}, size ".$files['size'][$key],FALSE,FALSE);
|
||||
|
||||
if ($max_file_count && ($c > $max_file_count))
|
||||
{
|
||||
$first_error = 249; // 'Too many files uploaded' error
|
||||
}
|
||||
else
|
||||
{
|
||||
$first_error = $files['error'][$key]; // Start with whatever error PHP gives us for the file
|
||||
}
|
||||
|
||||
if (!$first_error)
|
||||
{ // Check file size early on
|
||||
if ($files['size'][$key] == 0)
|
||||
{
|
||||
$first_error = 4; // Standard error code for zero size file
|
||||
}
|
||||
elseif ($files['size'][$key] > $max_upload_size)
|
||||
{
|
||||
$first_error = 254;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$first_error)
|
||||
{
|
||||
$uploadfile = $files['tmp_name'][$key]; // Name in temporary directory
|
||||
if (!$uploadfile) $first_error = 253;
|
||||
}
|
||||
|
||||
if (!$first_error)
|
||||
{
|
||||
// Need to support multiple files with the same 'real' name in some cases
|
||||
if (strpos($fileinfo,"attachment") === 0)
|
||||
{ // For attachments, add in a prefix plus time and date to give a unique file name
|
||||
$addbit = explode('+',$fileinfo,2);
|
||||
$name = time()."_".USERID."_".trim($addbit[1]).$name;
|
||||
}
|
||||
elseif (strpos($fileinfo,"prefix") === 0)
|
||||
{ // For attachments, alternatively just add a prefix we've been passed
|
||||
$addbit = explode('+',$fileinfo,2);
|
||||
$name = trim($addbit[1]).$name;
|
||||
}
|
||||
|
||||
$destination_file = $uploaddir."/".$name;
|
||||
|
||||
if ($fileinfo == "unique" && file_exists($destination_file))
|
||||
{ // Modify destination name to make it unique - but only if target file name existis
|
||||
$name = time()."_".$name;
|
||||
$destination_file = $uploaddir."/".$name;
|
||||
}
|
||||
|
||||
if (file_exists($destination_file) && !$overwrite) $first_error = 250; // Invent our own error number - duplicate file
|
||||
}
|
||||
|
||||
if (!$first_error)
|
||||
{
|
||||
$tpos = strrchr($files['name'][$key], "."); // Require uploaded files to have an extension
|
||||
if ($tpos !== FALSE)
|
||||
{
|
||||
$fileext = strtolower($tpos);
|
||||
$tpos = (($file_status = vet_file($uploadfile, $name, $allowed_filetypes, varset($options['extra_file_types'],FALSE))) === TRUE);
|
||||
}
|
||||
if ($tpos === FALSE)
|
||||
{
|
||||
// File type upload not permitted - error message and abort
|
||||
$first_error = 251; // Invent our own error number - file type not permitted
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!$first_error)
|
||||
{ // All tests passed - can store it somewhere
|
||||
$uploaded[$c]['name'] = $name;
|
||||
$uploaded[$c]['rawname'] = $raw_name;
|
||||
$uploaded[$c]['type'] = $files['type'][$key];
|
||||
$uploaded[$c]['size'] = 0;
|
||||
$uploaded[$c]['index'] = $key; // Store the actual index from the file_userfile array
|
||||
|
||||
$method = (OPEN_BASEDIR == FALSE ? "copy" : "move_uploaded_file");
|
||||
|
||||
if (@$method($uploadfile, $destination_file))
|
||||
if ($save_to_db)
|
||||
{ // Store binary files in the database if selected. Maximum two files this way
|
||||
// This is really legacy stuff - not seriously changed from the original apart from using the newer file vetting routines
|
||||
if (UH_DEBUG) $admin_log->e_log_event(10,__FILE__."|".__FUNCTION__."@".__LINE__,"DEBUG","Upload Handler test","Save to DB {$c}: ".$uploaded[$c]['name'],FALSE,FALSE);
|
||||
set_magic_quotes_runtime(0);
|
||||
$data = mysql_real_escape_string(fread(fopen($files['tmp_name'][$c], "rb"), filesize($uploadfile)));
|
||||
set_magic_quotes_runtime(get_magic_quotes_gpc());
|
||||
if ($sql->db_Insert("rbinary", "0, '".$tp -> toDB($name, true)."', '".$tp -> toDB($files['type'][$c], true)."', '{$data}' "))
|
||||
{
|
||||
@chmod($destination_file, 0644);
|
||||
$uploaded[$c]['name'] = "Binary ".mysql_insert_id()."/".$name;
|
||||
$uploaded[$c]['size'] = $files['size'][$c];
|
||||
}
|
||||
else
|
||||
{
|
||||
$first_error = 252; // "Could not save file"
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Store as flat file
|
||||
// $method = (OPEN_BASEDIR == FALSE ? "copy" : "move_uploaded_file");
|
||||
// if (@$method($uploadfile, $destination_file))
|
||||
if (@move_uploaded_file($uploadfile, $destination_file)) // This should work on all hosts
|
||||
{
|
||||
@chmod($destination_file, $final_chmod);
|
||||
if (UH_DEBUG) $admin_log->e_log_event(10,__FILE__."|".__FUNCTION__."@".__LINE__,"DEBUG","Upload Handler test","Final chmod() file {$destination_file} to {$final_chmod} ",FALSE,FALSE);
|
||||
|
||||
if (FALSE)
|
||||
{ // Need to rename file under some circumstances - looks as if it needs a test round it! Or, more likely, just deleting.
|
||||
$_tmp = explode('.', $name);
|
||||
$fext = array_pop($_tmp);
|
||||
$fname = basename($name, '.'.$fext);
|
||||
@ -135,60 +304,193 @@ function file_upload($uploaddir, $avatar = FALSE, $fileinfo = "", $overwrite = "
|
||||
{
|
||||
$uploaded[$c]['name'] = $rename;
|
||||
}
|
||||
|
||||
if ($method == "copy")
|
||||
{
|
||||
@unlink($uploadfile);
|
||||
}
|
||||
|
||||
if(!$dupe_found)
|
||||
{ // don't display 'success message' when duplicate file found.
|
||||
require_once(e_HANDLER."message_handler.php");
|
||||
message_handler("MESSAGE", "".LANUPLOAD_3." '".$files['name'][$key]."'", __LINE__, __FILE__);
|
||||
$f_message .= "".LANUPLOAD_3." '".$files['name'][$key]."'.<br />";
|
||||
}
|
||||
$uploaded[$c]['size'] = $files['size'][$key];
|
||||
|
||||
if (UH_DEBUG) $admin_log->e_log_event(10,__FILE__."|".__FUNCTION__."@".__LINE__,"DEBUG","Upload Handler test","Saved file {$c} OK: ".$uploaded[$c]['name'],FALSE,FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
$uploaded[$c]['error'] = $files['error'][$key];
|
||||
switch ($files['error'][$key])
|
||||
$first_error = 252; // Error - "couldn't save destination"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!$first_error)
|
||||
{ // This file succeeded
|
||||
$uploaded[$c]['message'] = LANUPLOAD_3." '".$name."'";
|
||||
$uploaded[$c]['error'] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
case 0:
|
||||
$error = LANUPLOAD_4." [".str_replace("../", "", $uploaddir)."]";
|
||||
break;
|
||||
case 1:
|
||||
$uploaded[$c]['error'] = $first_error;
|
||||
$uploaded[$c]['size'] = 0;
|
||||
switch ($first_error)
|
||||
{
|
||||
case 1: // Exceeds upload_max_filesize in php.ini
|
||||
$error = LANUPLOAD_5;
|
||||
break;
|
||||
case 2:
|
||||
case 2: // Exceeds MAX_FILE_SIZE in form
|
||||
$error = LANUPLOAD_6;
|
||||
break;
|
||||
case 3:
|
||||
case 3: // Partial upload
|
||||
$error = LANUPLOAD_7;
|
||||
break;
|
||||
case 4:
|
||||
case 4: // No file uploaded
|
||||
$error = LANUPLOAD_8;
|
||||
break;
|
||||
case 5:
|
||||
case 5: // Undocumented code (zero file size)
|
||||
$error = LANUPLOAD_9;
|
||||
break;
|
||||
case 6: // Missing temporary folder
|
||||
$error = LANUPLOAD_13;
|
||||
break;
|
||||
case 7: // File write failed
|
||||
$error = LANUPLOAD_14;
|
||||
break;
|
||||
case 8: // Upload stopped by extension
|
||||
$error = LANUPLOAD_15;
|
||||
break;
|
||||
case 249: // Too many files (our error code)
|
||||
$error = LANUPLOAD_19;
|
||||
break;
|
||||
case 250: // Duplicate File (our error code)
|
||||
$error = LANUPLOAD_10;
|
||||
break;
|
||||
case 251: // File type not allowed (our error code)
|
||||
$error = LANUPLOAD_1." ".$files['type'][$key]." ".LANUPLOAD_2." ({$file_status})";
|
||||
break;
|
||||
case 252 : // File uploaded OK, but couldn't save it
|
||||
$error = LANUPLOAD_4." [".str_replace("../", "", $uploaddir)."]";
|
||||
break;
|
||||
case 253: // Bad name for uploaded file (our error code)
|
||||
$error = LANUPLOAD_17;
|
||||
break;
|
||||
case 254: // file size exceeds allowable limits (our error code)
|
||||
$error = LANUPLOAD_18;
|
||||
break;
|
||||
default : // Shouldn't happen - but at least try and make it obvious if it does!
|
||||
$error = LANUPLOAD_16;
|
||||
}
|
||||
require_once(e_HANDLER."message_handler.php");
|
||||
message_handler("MESSAGE", LANUPLOAD_11." '".$files['name'][$key]."' <br />".LANUPLOAD_12.": ".$error, __LINE__, __FILE__);
|
||||
$f_message .= LANUPLOAD_11." '".$files['name'][$key]."' <br />".LANUPLOAD_12.": ".$error . __LINE__ . __FILE__;
|
||||
|
||||
$uploaded[$c]['message'] = LANUPLOAD_11." '".$name."' <br />".LANUPLOAD_12.": ".$error;
|
||||
$uploaded[$c]['line'] = __LINE__ ;
|
||||
$uploaded[$c]['file'] = __FILE__;
|
||||
if (UH_DEBUG) $admin_log->e_log_event(10,__FILE__."|".__FUNCTION__."@".__LINE__,"DEBUG","Upload Handler test","Main routine error {$first_error} file {$c}: ".$uploaded[$c]['message'],FALSE,FALSE);
|
||||
// If we need to abort on first error, do so here - could check for specific error codes
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_file($uploadfile)) @unlink($uploadfile); // Don't leave the file on the server if error (although should be auto-deleted)
|
||||
$c++;
|
||||
}
|
||||
define("F_MESSAGE", "<br />".$f_message);
|
||||
|
||||
}
|
||||
return $uploaded;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Utility routine to handle the messages returned by process_uploaded_files().
|
||||
$upload_array is the list of uploaded files
|
||||
$errors_only - if TRUE, no message is shown for a successful upload.
|
||||
$use_handler - if TRUE, message_handler is used to display the message.
|
||||
|
||||
Returns - a list of all accumulated messages. (Non-destructive call, so can be called several times with different options).
|
||||
*/
|
||||
function handle_upload_messages(&$upload_array, $errors_only = TRUE, $use_handler = FALSE)
|
||||
{
|
||||
// Display error messages, accumulate FMESSAGE
|
||||
// Write as a separate routine - returns all messages displayed. Option to only display failures.
|
||||
$f_message = '';
|
||||
foreach($upload_array as $k => $r)
|
||||
{
|
||||
if (!$errors_only || $r['error'])
|
||||
{
|
||||
if ($use_handler)
|
||||
{
|
||||
require_once(e_HANDLER."message_handler.php");
|
||||
message_handler("MESSAGE",$r['message'], $r['line'], $r['file']);
|
||||
}
|
||||
$f_message[] = $r['message'];
|
||||
}
|
||||
}
|
||||
return implode("<br />",$f_message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
LEGACY FILE UPLOAD HANDLER
|
||||
====================================================================
|
||||
This is the 'legacy' interface, which handles various special cases etc.
|
||||
It was the only option in E107 0.7.8 and earlier, and is still used in some places in core.
|
||||
It also attempts to return in the same way as the original, especially when any errors occur
|
||||
|
||||
Parameters for file_upload():
|
||||
$uploaddir - target directory for file. Defaults to e_FILE/public
|
||||
|
||||
$avatar - sets the 'type' or destination of the file:
|
||||
FALSE - its a 'general' file
|
||||
'attachment' - indicates an attachment (related to forum post or PM)
|
||||
'unique' - indicates that file name must be unique - new name given (prefixed with time()_ )
|
||||
'avatar' - indicates an avatar is being uploaded
|
||||
|
||||
$fileinfo - included within the name of the saved file with attachments - can be an identifier of some sort
|
||||
(Forum adds 'FT{$tid}_' - where $tid is the thread ID.
|
||||
|
||||
$overwrite - if true, an uploaded file can overwrite an existing file of the same name (not used in 0.7 core)
|
||||
|
||||
Preference used:
|
||||
$pref['upload_storagetype'] = 1 for files, 2 for database
|
||||
|
||||
On exit, F_MESSAGE is defined with the success/failure message(s) that have been displayed - one file per line
|
||||
|
||||
For backward compatibility, returns FALSE if only one file uploaded and an error; otherwise returns an array with per-file error codes as appropriate.
|
||||
*/
|
||||
|
||||
|
||||
function file_upload($uploaddir, $avatar = FALSE, $fileinfo = "", $overwrite = "")
|
||||
{
|
||||
global $admin_log;
|
||||
|
||||
if (!$uploaddir) {$uploaddir = e_FILE."public/";}
|
||||
|
||||
// Compute storage type - 1 is file, 2 is DB
|
||||
$upload_storagetype = varset($pref['upload_storagetype'],1);
|
||||
if($uploaddir == e_THEME) {$upload_storagetype = 1;}
|
||||
$save_to_db = ($upload_storagetype == "2" && $avatar == FALSE);
|
||||
|
||||
if (UH_DEBUG) $admin_log->e_log_event(10,__FILE__."|".__FUNCTION__."@".__LINE__,"DEBUG","Upload Handler test","Legacy call, directory ".$uploaddir,FALSE,FALSE);
|
||||
|
||||
$ret = process_uploaded_files(getcwd()."/".$uploaddir, // Well, that's the way it was done before
|
||||
($avatar == "attachment" ? "attachment+".$fileinfo : $avatar),
|
||||
array('extra_file_types' => TRUE, // As default, allow any filetype enabled in filetypes.php
|
||||
'save_to_db' => $save_to_db));
|
||||
if ($ret === FALSE)
|
||||
{
|
||||
if (UH_DEBUG) $admin_log->e_log_event(10,__FILE__."|".__FUNCTION__."@".__LINE__,"DEBUG","Upload Handler test","Legacy return FALSE",FALSE,FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (UH_DEBUG) $admin_log->e_log_event(10,__FILE__."|".__FUNCTION__."@".__LINE__,"DEBUG","Upload Handler test","Legacy return with ".count($ret)." files",FALSE,FALSE);
|
||||
$messages = handle_upload_messages($ret, FALSE, TRUE); // Show all the error and acknowledgment messages
|
||||
define(F_MESSAGE, $messages);
|
||||
|
||||
if (count($ret) == 1)
|
||||
{
|
||||
if ($ret[0]['error'] != 0) return FALSE; // Special case if errors
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
VETTING AND UTILITY ROUTINES
|
||||
====================================================================
|
||||
|
||||
// Check uploaded file to try and identify dodgy content.
|
||||
// Return TRUE if appears OK.
|
||||
// Return a numeric reason code 1..9 if unacceptable
|
||||
@ -200,11 +502,19 @@ function file_upload($uploaddir, $avatar = FALSE, $fileinfo = "", $overwrite = "
|
||||
// if $unknown is FALSE, rejects totally unknown file extensions (even if in $allowed_filetypes).
|
||||
// if $unknown is TRUE, accepts totally unknown file extensions.
|
||||
// otherwise $unknown is a comma-separated list of additional permitted file extensions
|
||||
*/
|
||||
function vet_file($filename, $target_name, $allowed_filetypes = '', $unknown = FALSE)
|
||||
{
|
||||
// 1. Start by checking against filetypes - that's the easy one!
|
||||
$file_ext = strtolower(substr(strrchr($target_name, "."), 1));
|
||||
if (!in_array($file_ext, $allowed_filetypes)) return 1;
|
||||
if (!in_array($file_ext, $allowed_filetypes))
|
||||
{
|
||||
if (is_bool($unknown)) return 1; // Reject out of hand if no possible alternative extensions
|
||||
// Otherwise, it could be in the supplementary list
|
||||
$tmp = explode(',', $unknown);
|
||||
for ($i = 0; $i < count($tmp); $i++) { $tmp[$i] = strtolower(trim(str_replace('.', '', $tmp[$i]))); }
|
||||
if (!in_array($file_ext, $tmp)) return 6;
|
||||
}
|
||||
|
||||
|
||||
// 2. For all files, read the first little bit to check for any flags etc
|
||||
@ -249,29 +559,83 @@ function vet_file($filename, $target_name, $allowed_filetypes = '', $unknown = F
|
||||
|
||||
default :
|
||||
if (is_bool($unknown)) return ($unknown ? TRUE : 8);
|
||||
$tmp = explode(',', $unknown);
|
||||
for ($i = 0; $i < count($tmp); $i++) { $tmp[$i] = strtolower(trim(str_replace('.', '', $tmp[$i]))); }
|
||||
if (!in_array($file_ext, $tmp)) return 6;
|
||||
}
|
||||
return TRUE; // Accepted here
|
||||
}
|
||||
|
||||
|
||||
|
||||
function get_allowed_filetypes($def_file = 'filetypes.php')
|
||||
// Get array of file types (file extensions) which are permitted - reads a definition file.
|
||||
// If $file_mask is a comma-separated list of file types, only those types which are in both the definition file and in $file_mask are added
|
||||
function get_allowed_filetypes($def_file = FALSE, $file_mask = '')
|
||||
{
|
||||
$ret = array();
|
||||
if ($def_file === FALSE) return $ret;
|
||||
|
||||
if (is_readable(e_ADMIN.$def_file))
|
||||
if ($file_mask)
|
||||
{
|
||||
$file_array = explode(',', $file_mask);
|
||||
foreach ($file_array as $k => $f)
|
||||
{
|
||||
$file_array[$k] = trim($f);
|
||||
}
|
||||
}
|
||||
|
||||
if ($def_file && is_readable(e_ADMIN.$def_file))
|
||||
{
|
||||
$a_filetypes = trim(file_get_contents(e_ADMIN.$def_file));
|
||||
$a_filetypes = explode(',', $a_filetypes);
|
||||
foreach ($a_filetypes as $ftype)
|
||||
{
|
||||
if (!$file_mask || in_array($ftype, $file_array))
|
||||
{
|
||||
$ret[] = strtolower(trim(str_replace('.', '', $ftype)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
// Parse a file size string (e.g. 16M) and compute the simple numeric value.
|
||||
// If $action is empty, return this value.
|
||||
// If $source evaluates to zero, return the compare value instead
|
||||
// If $action == 'gt', return the larger of this value and $compare
|
||||
// If $action == 'lt', return the smaller of this value and $compare
|
||||
function file_size_decode($source, $compare = 0, $action = '')
|
||||
{
|
||||
$source = trim($source);
|
||||
$mult = 1;
|
||||
$nostrip = FALSE;
|
||||
if (!$source || is_numeric($source))
|
||||
{
|
||||
$val = $source;
|
||||
}
|
||||
else
|
||||
{
|
||||
$val = substr($source,0,-1);
|
||||
switch (substr($source,-1,1))
|
||||
{
|
||||
case 'T' :
|
||||
$val = $val * 1024;
|
||||
case 'G' :
|
||||
$val = $val * 1024;
|
||||
case 'M' :
|
||||
$val = $val * 1024;
|
||||
case 'K' :
|
||||
case 'k' :
|
||||
$val = $val * 1024;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($val == 0) return $compare;
|
||||
switch (action)
|
||||
{
|
||||
case 'lt' : return min($val, $compare);
|
||||
case 'gt' : return max($val, $compare);
|
||||
default : return $val;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
?>
|
Loading…
x
Reference in New Issue
Block a user