New: add hook in dol_move_uploaded_file method and split function with
dol_check_uploaded_file method
This commit is contained in:
parent
221b671636
commit
83fbaac70d
@ -75,7 +75,7 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil
|
|||||||
$parameters=array(
|
$parameters=array(
|
||||||
'path' => $newpath,
|
'path' => $newpath,
|
||||||
'types'=> $types,
|
'types'=> $types,
|
||||||
'recursive' =>$recursive,
|
'recursive' => $recursive,
|
||||||
'filter' => $filter,
|
'filter' => $filter,
|
||||||
'excludefilter' => $excludefilter,
|
'excludefilter' => $excludefilter,
|
||||||
'sortcriteria' => $sortcriteria,
|
'sortcriteria' => $sortcriteria,
|
||||||
@ -553,6 +553,136 @@ function dol_unescapefile($filename)
|
|||||||
return trim(basename($filename), ".\x00..\x20");
|
return trim(basename($filename), ".\x00..\x20");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move an uploaded file after some controls.
|
||||||
|
* If there is errors (virus found, antivir in error, bad filename), file is not moved.
|
||||||
|
*
|
||||||
|
* @param string $src_file Source full path filename ($_FILES['field']['tmp_name'])
|
||||||
|
* @param string $dest_file Target full path filename ($_FILES['field']['name'])
|
||||||
|
* @param int $allowoverwrite 1=Overwrite target file if it already exists
|
||||||
|
* @param int $disablevirusscan 1=Disable virus scan
|
||||||
|
* @param string $uploaderrorcode Value of upload error code ($_FILES['field']['error'])
|
||||||
|
* @param int $notrigger Disable all triggers
|
||||||
|
* @param string $upload_dir Upload directory
|
||||||
|
* @param array $upload_file Values of file uploaded $_FILES['field']
|
||||||
|
* @return int >0 if OK, <0 or string if KO
|
||||||
|
*/
|
||||||
|
function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disablevirusscan=0, $uploaderrorcode=0, $notrigger=0, $upload_dir='', $upload_file=null)
|
||||||
|
{
|
||||||
|
global $db, $hookmanager;
|
||||||
|
global $object;
|
||||||
|
|
||||||
|
$error=0;
|
||||||
|
|
||||||
|
// Check uploaded file
|
||||||
|
$dest_file=dolCheckUploadedFile($src_file, $dest_file, $disablevirusscan, $uploaderrorcode);
|
||||||
|
if (is_array($dest_file) && isset($dest_file['error'])) return $dest_file['error'];
|
||||||
|
|
||||||
|
if (! is_object($hookmanager))
|
||||||
|
{
|
||||||
|
if (! class_exists('HookManager')) {
|
||||||
|
// Initialize technical object to manage hooks of thirdparties. Note that conf->hooks_modules contains array array
|
||||||
|
require DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
|
||||||
|
$hookmanager=new HookManager($db);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$hookmanager->initHooks(array('fileslib'));
|
||||||
|
|
||||||
|
$parameters=array('upload_dir' => $upload_dir, 'upload_file' => $upload_file, 'allowoverwrite' => $allowoverwrite);
|
||||||
|
$reshook=$hookmanager->executeHooks('dolMoveUploadedFile', $parameters, $object);
|
||||||
|
|
||||||
|
if (empty($reshook)) {
|
||||||
|
return dolMoveUploadedFile($src_file, $dest_file, $allowoverwrite, $notrigger);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check an uploaded file.
|
||||||
|
* If there is errors (virus found, antivir in error, bad filename), file is not moved.
|
||||||
|
*
|
||||||
|
* @param string $src_file Source full path filename ($_FILES['field']['tmp_name'])
|
||||||
|
* @param string $dest_file Target full path filename ($_FILES['field']['name'])
|
||||||
|
* @param int $disablevirusscan 1=Disable virus scan
|
||||||
|
* @param string $uploaderrorcode Value of upload error code ($_FILES['field']['error'])
|
||||||
|
* @return int >0 if OK, <0 or string if KO
|
||||||
|
*/
|
||||||
|
function dolCheckUploadedFile($src_file, $dest_file, $disablevirusscan=0, $uploaderrorcode=0)
|
||||||
|
{
|
||||||
|
global $conf;
|
||||||
|
|
||||||
|
$file_name = $dest_file;
|
||||||
|
// If an upload error has been reported
|
||||||
|
if ($uploaderrorcode)
|
||||||
|
{
|
||||||
|
switch($uploaderrorcode)
|
||||||
|
{
|
||||||
|
case UPLOAD_ERR_INI_SIZE: // 1
|
||||||
|
return array('error' => 'ErrorFileSizeTooLarge');
|
||||||
|
break;
|
||||||
|
case UPLOAD_ERR_FORM_SIZE: // 2
|
||||||
|
return array('error' => 'ErrorFileSizeTooLarge');
|
||||||
|
break;
|
||||||
|
case UPLOAD_ERR_PARTIAL: // 3
|
||||||
|
return array('error' => 'ErrorPartialFile');
|
||||||
|
break;
|
||||||
|
case UPLOAD_ERR_NO_TMP_DIR: //
|
||||||
|
return array('error' => 'ErrorNoTmpDir');
|
||||||
|
break;
|
||||||
|
case UPLOAD_ERR_CANT_WRITE:
|
||||||
|
return array('error' => 'ErrorFailedToWriteInDir');
|
||||||
|
break;
|
||||||
|
case UPLOAD_ERR_EXTENSION:
|
||||||
|
return array('error' => 'ErrorUploadBlockedByAddon');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we need to make a virus scan
|
||||||
|
if (empty($disablevirusscan) && file_exists($src_file) && ! empty($conf->global->MAIN_ANTIVIRUS_COMMAND))
|
||||||
|
{
|
||||||
|
if (! class_exists('AntiVir')) {
|
||||||
|
require DOL_DOCUMENT_ROOT.'/core/class/antivir.class.php';
|
||||||
|
}
|
||||||
|
$antivir=new AntiVir($db);
|
||||||
|
$result = $antivir->dol_avscan_file($src_file);
|
||||||
|
if ($result < 0) // If virus or error, we stop here
|
||||||
|
{
|
||||||
|
$reterrors=$antivir->errors;
|
||||||
|
dol_syslog('Files.lib::dol_move_uploaded_file File "'.$src_file.'" (target name "'.$file_name.'") KO with antivirus: result='.$result.' errors='.join(',',$antivir->errors), LOG_WARNING);
|
||||||
|
return array('error' => 'ErrorFileIsInfectedWithAVirus: '.join(',',$reterrors));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Security:
|
||||||
|
// Disallow file with some extensions. We renamed them.
|
||||||
|
// Car si on a mis le rep documents dans un rep de la racine web (pas bien), cela permet d'executer du code a la demande.
|
||||||
|
if (preg_match('/\.htm|\.html|\.php|\.pl|\.cgi$/i',$file_name))
|
||||||
|
{
|
||||||
|
$file_name.= '.noexe';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Security:
|
||||||
|
// On interdit fichiers caches, remontees de repertoire ainsi que les pipes dans les noms de fichiers.
|
||||||
|
if (preg_match('/^\./',$src_file) || preg_match('/\.\./',$src_file) || preg_match('/[<>|]/',$src_file))
|
||||||
|
{
|
||||||
|
dol_syslog("Refused to deliver file ".$src_file, LOG_WARNING);
|
||||||
|
return array('error' => -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Security:
|
||||||
|
// On interdit fichiers caches, remontees de repertoire ainsi que les pipe dans
|
||||||
|
// les noms de fichiers.
|
||||||
|
if (preg_match('/^\./',$dest_file) || preg_match('/\.\./',$dest_file) || preg_match('/[<>|]/',$dest_file))
|
||||||
|
{
|
||||||
|
dol_syslog("Refused to deliver file ".$dest_file, LOG_WARNING);
|
||||||
|
return array('error' => -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $file_name;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move an uploaded file after some controls.
|
* Move an uploaded file after some controls.
|
||||||
* If there is errors (virus found, antivir in error, bad filename), file is not moved.
|
* If there is errors (virus found, antivir in error, bad filename), file is not moved.
|
||||||
@ -560,89 +690,19 @@ function dol_unescapefile($filename)
|
|||||||
* @param string $src_file Source full path filename ($_FILES['field']['tmp_name'])
|
* @param string $src_file Source full path filename ($_FILES['field']['tmp_name'])
|
||||||
* @param string $dest_file Target full path filename ($_FILES['field']['name'])
|
* @param string $dest_file Target full path filename ($_FILES['field']['name'])
|
||||||
* @param int $allowoverwrite 1=Overwrite target file if it already exists
|
* @param int $allowoverwrite 1=Overwrite target file if it already exists
|
||||||
* @param int $disablevirusscan 1=Disable virus scan
|
|
||||||
* @param string $uploaderrorcode Value of upload error code ($_FILES['field']['error'])
|
|
||||||
* @param int $notrigger Disable all triggers
|
* @param int $notrigger Disable all triggers
|
||||||
* @return int >0 if OK, <0 or string if KO
|
* @return int >0 if OK, <0 or string if KO
|
||||||
*/
|
*/
|
||||||
function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disablevirusscan=0, $uploaderrorcode=0, $notrigger=0)
|
function dolMoveUploadedFile($src_file, $dest_file, $allowoverwrite, $notrigger=0)
|
||||||
{
|
{
|
||||||
global $conf, $user, $langs, $db;
|
global $conf, $user, $langs, $db;
|
||||||
global $object;
|
global $object;
|
||||||
|
|
||||||
$error=0;
|
$error=0;
|
||||||
|
|
||||||
$file_name = $dest_file;
|
|
||||||
// If an upload error has been reported
|
|
||||||
if ($uploaderrorcode)
|
|
||||||
{
|
|
||||||
switch($uploaderrorcode)
|
|
||||||
{
|
|
||||||
case UPLOAD_ERR_INI_SIZE: // 1
|
|
||||||
return 'ErrorFileSizeTooLarge';
|
|
||||||
break;
|
|
||||||
case UPLOAD_ERR_FORM_SIZE: // 2
|
|
||||||
return 'ErrorFileSizeTooLarge';
|
|
||||||
break;
|
|
||||||
case UPLOAD_ERR_PARTIAL: // 3
|
|
||||||
return 'ErrorPartialFile';
|
|
||||||
break;
|
|
||||||
case UPLOAD_ERR_NO_TMP_DIR: //
|
|
||||||
return 'ErrorNoTmpDir';
|
|
||||||
break;
|
|
||||||
case UPLOAD_ERR_CANT_WRITE:
|
|
||||||
return 'ErrorFailedToWriteInDir';
|
|
||||||
break;
|
|
||||||
case UPLOAD_ERR_EXTENSION:
|
|
||||||
return 'ErrorUploadBlockedByAddon';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we need to make a virus scan
|
|
||||||
if (empty($disablevirusscan) && file_exists($src_file) && ! empty($conf->global->MAIN_ANTIVIRUS_COMMAND))
|
|
||||||
{
|
|
||||||
require_once DOL_DOCUMENT_ROOT.'/core/class/antivir.class.php';
|
|
||||||
$antivir=new AntiVir($db);
|
|
||||||
$result = $antivir->dol_avscan_file($src_file);
|
|
||||||
if ($result < 0) // If virus or error, we stop here
|
|
||||||
{
|
|
||||||
$reterrors=$antivir->errors;
|
|
||||||
dol_syslog('Files.lib::dol_move_uploaded_file File "'.$src_file.'" (target name "'.$file_name.'") KO with antivirus: result='.$result.' errors='.join(',',$antivir->errors), LOG_WARNING);
|
|
||||||
return 'ErrorFileIsInfectedWithAVirus: '.join(',',$reterrors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Security:
|
|
||||||
// Disallow file with some extensions. We renamed them.
|
|
||||||
// Car si on a mis le rep documents dans un rep de la racine web (pas bien), cela permet d'executer du code a la demande.
|
|
||||||
if (preg_match('/\.htm|\.html|\.php|\.pl|\.cgi$/i',$file_name))
|
|
||||||
{
|
|
||||||
$file_name.= '.noexe';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Security:
|
|
||||||
// On interdit fichiers caches, remontees de repertoire ainsi que les pipes dans les noms de fichiers.
|
|
||||||
if (preg_match('/^\./',$src_file) || preg_match('/\.\./',$src_file) || preg_match('/[<>|]/',$src_file))
|
|
||||||
{
|
|
||||||
dol_syslog("Refused to deliver file ".$src_file, LOG_WARNING);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Security:
|
|
||||||
// On interdit fichiers caches, remontees de repertoire ainsi que les pipe dans
|
|
||||||
// les noms de fichiers.
|
|
||||||
if (preg_match('/^\./',$dest_file) || preg_match('/\.\./',$dest_file) || preg_match('/[<>|]/',$dest_file))
|
|
||||||
{
|
|
||||||
dol_syslog("Refused to deliver file ".$dest_file, LOG_WARNING);
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The file functions must be in OS filesystem encoding.
|
// The file functions must be in OS filesystem encoding.
|
||||||
$src_file_osencoded=dol_osencode($src_file);
|
$src_file_osencoded=dol_osencode($src_file);
|
||||||
$file_name_osencoded=dol_osencode($file_name);
|
$file_name_osencoded=dol_osencode($dest_file);
|
||||||
|
|
||||||
// Check if destination dir is writable
|
// Check if destination dir is writable
|
||||||
// TODO
|
// TODO
|
||||||
@ -973,11 +1033,11 @@ function dol_add_file_process($upload_dir,$allowoverwrite=0,$donotupdatesession=
|
|||||||
{
|
{
|
||||||
global $db,$user,$conf,$langs,$_FILES;
|
global $db,$user,$conf,$langs,$_FILES;
|
||||||
|
|
||||||
if (! empty($_FILES[$varfiles]['tmp_name']))
|
if (! empty($_FILES[$varfiles])) // For view $_FILES[$varfiles]['error']
|
||||||
{
|
{
|
||||||
if (dol_mkdir($upload_dir) >= 0)
|
if (dol_mkdir($upload_dir) >= 0)
|
||||||
{
|
{
|
||||||
$resupload = dol_move_uploaded_file($_FILES[$varfiles]['tmp_name'], $upload_dir . "/" . $_FILES[$varfiles]['name'],$allowoverwrite,0, $_FILES[$varfiles]['error']);
|
$resupload = dol_move_uploaded_file($_FILES[$varfiles]['tmp_name'], $upload_dir . "/" . $_FILES[$varfiles]['name'], $allowoverwrite, 0, $_FILES[$varfiles]['error'], 0, $upload_dir, $_FILES[$varfiles]);
|
||||||
if (is_numeric($resupload) && $resupload > 0)
|
if (is_numeric($resupload) && $resupload > 0)
|
||||||
{
|
{
|
||||||
if (empty($donotupdatesession))
|
if (empty($donotupdatesession))
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user