[9.2.14] mise à jour rfm

This commit is contained in:
fredtempez 2019-12-06 16:04:30 +01:00
parent c26436efc7
commit 8dc8577244
4 changed files with 1584 additions and 3131 deletions

View File

@ -1,5 +1,9 @@
# Changelog # Changelog
## version 9.2.14
- Mise à jour :
- Script d'upload du gestionnaire de fichiers
## version 9.2.13 ## version 9.2.13
- Corrections - Corrections
- Gestionnaire de fichiers, modifications des paramètres des miniatures. - Gestionnaire de fichiers, modifications des paramètres des miniatures.

View File

@ -33,7 +33,7 @@ class common {
const TEMP_DIR = 'site/tmp/'; const TEMP_DIR = 'site/tmp/';
// Numéro de version // Numéro de version
const ZWII_VERSION = '9.2.13'; const ZWII_VERSION = '9.2.14';
public static $actions = []; public static $actions = [];
public static $coreModuleIds = [ public static $coreModuleIds = [

View File

@ -38,6 +38,10 @@ class UploadHandler
'image_resize' => 'Failed to resize image' 'image_resize' => 'Failed to resize image'
); );
const IMAGETYPE_GIF = 1;
const IMAGETYPE_JPEG = 2;
const IMAGETYPE_PNG = 3;
protected $image_objects = array(); protected $image_objects = array();
public function __construct($options = null, $initialize = true, $error_messages = null) { public function __construct($options = null, $initialize = true, $error_messages = null) {
@ -48,7 +52,7 @@ class UploadHandler
'upload_url' => $this->get_full_url().'/files/', 'upload_url' => $this->get_full_url().'/files/',
'input_stream' => 'php://input', 'input_stream' => 'php://input',
'user_dirs' => false, 'user_dirs' => false,
'mkdir_mode' => 0777, 'mkdir_mode' => 0755,
'param_name' => 'files', 'param_name' => 'files',
// Set the following option to 'POST', if your server does not support // Set the following option to 'POST', if your server does not support
// DELETE requests. This is a parameter sent to the client: // DELETE requests. This is a parameter sent to the client:
@ -86,21 +90,36 @@ class UploadHandler
'download_via_php' => false, 'download_via_php' => false,
// Read files in chunks to avoid memory limits when download_via_php // Read files in chunks to avoid memory limits when download_via_php
// is enabled, set to 0 to disable chunked reading of files: // is enabled, set to 0 to disable chunked reading of files:
'readfile_chunk_size' => 2 * 1024 * 1024, // 10 MiB 'readfile_chunk_size' => 10 * 1024 * 1024, // 10 MiB
// Defines which files can be displayed inline when downloaded: // Defines which files can be displayed inline when downloaded:
'inline_file_types' => '/\.(gif|jpe?g|png)$/i', 'inline_file_types' => '/\.(gif|jpe?g|png)$/i',
// Defines which files (based on their names) are accepted for upload: // Defines which files (based on their names) are accepted for upload.
'accept_file_types' => '/.+$/i', // By default, only allows file uploads with image file extensions.
// Only change this setting after making sure that any allowed file
// types cannot be executed by the webserver in the files directory,
// e.g. PHP scripts, nor executed by the browser when downloaded,
// e.g. HTML files with embedded JavaScript code.
// Please also read the SECURITY.md document in this repository.
'accept_file_types' => '/\.(gif|jpe?g|png)$/i',
// Replaces dots in filenames with the given string.
// Can be disabled by setting it to false or an empty string.
// Note that this is a security feature for servers that support
// multiple file extensions, e.g. the Apache AddHandler Directive:
// https://httpd.apache.org/docs/current/mod/mod_mime.html#addhandler
// Before disabling it, make sure that files uploaded with multiple
// extensions cannot be executed by the webserver, e.g.
// "example.php.png" with embedded PHP code, nor executed by the
// browser when downloaded, e.g. "example.html.gif" with embedded
// JavaScript code.
'replace_dots_in_filenames' => '-',
// The php.ini settings upload_max_filesize and post_max_size // The php.ini settings upload_max_filesize and post_max_size
// take precedence over the following max_file_size setting: // take precedence over the following max_file_size setting:
'max_file_size' => null, 'max_file_size' => null,
'min_file_size' => 1, 'min_file_size' => 1,
// The maximum number of files for the upload directory: // The maximum number of files for the upload directory:
'max_number_of_files' => null, 'max_number_of_files' => null,
// Defines which files are handled as image files: // Reads first file bytes to identify and correct file extensions:
'image_file_types' => '/\.(gif|jpe?g|png)$/i', 'correct_image_extensions' => false,
// Use exif_imagetype on all files to correct file extensions:
'correct_image_extensions' => true,
// Image resolution restrictions: // Image resolution restrictions:
'max_width' => null, 'max_width' => null,
'max_height' => null, 'max_height' => null,
@ -131,33 +150,40 @@ class UploadHandler
// Command or path for to the ImageMagick identify binary: // Command or path for to the ImageMagick identify binary:
'identify_bin' => 'identify', 'identify_bin' => 'identify',
'image_versions' => array( 'image_versions' => array(
// The empty image version key defines options for the original image: // The empty image version key defines options for the original image.
// Keep in mind that these options are inherited by all other image versions! // Keep in mind: these image manipulations are inherited by all other image versions from this point onwards.
// Also note that the property 'no_cache' is not inherited, since it's not a manipulation.
'' => array( '' => array(
// Automatically rotate images based on EXIF meta data: // Automatically rotate images based on EXIF meta data:
'auto_orient' => true 'auto_orient' => true
), ),
// Uncomment the following to create medium sized images: // You can add arrays to generate different versions.
// The name of the key is the name of the version (example: 'medium').
// the array contains the options to apply.
/* /*
'medium' => array( 'medium' => array(
'max_width' => 800, 'max_width' => 800,
'max_height' => 600 'max_height' => 600
), ),
'thumbnail' => array( */
//'thumbnail' => array(
// Uncomment the following to use a defined directory for the thumbnails // Uncomment the following to use a defined directory for the thumbnails
// instead of a subdirectory based on the version identifier. // instead of a subdirectory based on the version identifier.
// Make sure that this directory doesn't allow execution of files if you // Make sure that this directory doesn't allow execution of files if you
// don't pose any restrictions on the type of uploaded files, e.g. by // don't pose any restrictions on the type of uploaded files, e.g. by
// copying the .htaccess file from the files directory for Apache: // copying the .htaccess file from the files directory for Apache:
//'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/thumb/', //'upload_dir' => dirname($this->get_server_var('SCRIPT_FILENAME')).'/thumb/',
'upload_url' => $this->get_full_url().'/thumb/', //'upload_url' => $this->get_full_url().'/thumb/',
// Uncomment the following to force the max // Uncomment the following to force the max
// dimensions and e.g. create square thumbnails: // dimensions and e.g. create square thumbnails:
'crop' => true, // 'auto_orient' => true,
'max_width' => 80, // 'crop' => true,
'max_height' => 80 // 'jpeg_quality' => 70,
) // 'no_cache' => true, (there's a caching option, but this remembers thumbnail sizes from a previous action!)
*/ // 'strip' => true, (this strips EXIF tags, such as geolocation)
// 'max_width' => 80, // either specify width, or set to 0. Then width is automatically adjusted - keeping aspect ratio to a specified max_height.
// 'max_height' => 80 // either specify height, or set to 0. Then height is automatically adjusted - keeping aspect ratio to a specified max_width.
// )
), ),
'print_response' => true 'print_response' => true
); );
@ -380,10 +406,6 @@ class UploadHandler
$file->error = $this->get_error_message('accept_file_types'); $file->error = $this->get_error_message('accept_file_types');
return false; return false;
} }
if (preg_match($this->options['image_file_types'], $file->name) && function_exists('exif_imagetype') && !@exif_imagetype($uploaded_file)) {
$file->error = $this->get_error_message('accept_file_types');
return false;
}
if ($uploaded_file && is_uploaded_file($uploaded_file)) { if ($uploaded_file && is_uploaded_file($uploaded_file)) {
$file_size = $this->get_file_size($uploaded_file); $file_size = $this->get_file_size($uploaded_file);
} else { } else {
@ -413,9 +435,8 @@ class UploadHandler
$min_width = @$this->options['min_width']; $min_width = @$this->options['min_width'];
$min_height = @$this->options['min_height']; $min_height = @$this->options['min_height'];
if (($max_width || $max_height || $min_width || $min_height) if (($max_width || $max_height || $min_width || $min_height)
&& preg_match($this->options['image_file_types'], $file->name)) { && $this->is_valid_image_file($uploaded_file)) {
list($img_width, $img_height) = $this->get_image_size($uploaded_file); list($img_width, $img_height) = $this->get_image_size($uploaded_file);
// If we are auto rotating the image by default, do the checks on // If we are auto rotating the image by default, do the checks on
// the correct orientation // the correct orientation
if ( if (
@ -429,7 +450,6 @@ class UploadHandler
$img_height = $tmp; $img_height = $tmp;
unset($tmp); unset($tmp);
} }
} }
if (!empty($img_width)) { if (!empty($img_width)) {
if ($max_width && $img_width > $max_width) { if ($max_width && $img_width > $max_width) {
@ -491,16 +511,15 @@ class UploadHandler
preg_match('/^image\/(gif|jpe?g|png)/', $type, $matches)) { preg_match('/^image\/(gif|jpe?g|png)/', $type, $matches)) {
$name .= '.'.$matches[1]; $name .= '.'.$matches[1];
} }
if ($this->options['correct_image_extensions'] && if ($this->options['correct_image_extensions']) {
function_exists('exif_imagetype')) { switch ($this->imagetype($file_path)) {
switch (@exif_imagetype($file_path)){ case self::IMAGETYPE_JPEG:
case IMAGETYPE_JPEG:
$extensions = array('jpg', 'jpeg'); $extensions = array('jpg', 'jpeg');
break; break;
case IMAGETYPE_PNG: case self::IMAGETYPE_PNG:
$extensions = array('png'); $extensions = array('png');
break; break;
case IMAGETYPE_GIF: case self::IMAGETYPE_GIF:
$extensions = array('gif'); $extensions = array('gif');
break; break;
} }
@ -523,7 +542,17 @@ class UploadHandler
// Remove path information and dots around the filename, to prevent uploading // Remove path information and dots around the filename, to prevent uploading
// into different directories or replacing hidden system files. // into different directories or replacing hidden system files.
// Also remove control characters and spaces (\x00..\x20) around the filename: // Also remove control characters and spaces (\x00..\x20) around the filename:
$name = trim($this->basename(stripslashes($name)), "\x00..\x20"); $name = trim($this->basename(stripslashes($name)), ".\x00..\x20");
// Replace dots in filenames to avoid security issues with servers
// that interpret multiple file extensions, e.g. "example.php.png":
$replacement = $this->options['replace_dots_in_filenames'];
if (!empty($replacement)) {
$parts = explode('.', $name);
if (count($parts) > 2) {
$ext = array_pop($parts);
$name = implode($replacement, $parts).'.'.$ext;
}
}
// Use a timestamp for empty filenames: // Use a timestamp for empty filenames:
if (!$name) { if (!$name) {
$name = str_replace('.', '-', microtime(true)); $name = str_replace('.', '-', microtime(true));
@ -868,25 +897,31 @@ class UploadHandler
if (!empty($options['auto_orient'])) { if (!empty($options['auto_orient'])) {
$image_oriented = $this->imagick_orient_image($image); $image_oriented = $this->imagick_orient_image($image);
} }
$image_resize = false;
$new_width = $max_width = $img_width = $image->getImageWidth(); $new_width = $max_width = $img_width = $image->getImageWidth();
$new_height = $max_height = $img_height = $image->getImageHeight(); $new_height = $max_height = $img_height = $image->getImageHeight();
if (!empty($options['max_width'])) {
// use isset(). User might be setting max_width = 0 (auto in regular resizing). Value 0 would be considered empty when you use empty()
if (isset($options['max_width'])) {
$image_resize = true;
$new_width = $max_width = $options['max_width']; $new_width = $max_width = $options['max_width'];
} }
if (!empty($options['max_height'])) { if (isset($options['max_height'])) {
$image_resize = true;
$new_height = $max_height = $options['max_height']; $new_height = $max_height = $options['max_height'];
} }
$image_strip = false;
if( !empty($options["strip"]) ) { $image_strip = (isset($options['strip']) ? $options['strip'] : false);
$image_strip = $options["strip"];
}
if ( !$image_oriented && ($max_width >= $img_width) && ($max_height >= $img_height) && !$image_strip && empty($options["jpeg_quality"]) ) { if ( !$image_oriented && ($max_width >= $img_width) && ($max_height >= $img_height) && !$image_strip && empty($options["jpeg_quality"]) ) {
if ($file_path !== $new_file_path) { if ($file_path !== $new_file_path) {
return copy($file_path, $new_file_path); return copy($file_path, $new_file_path);
} }
return true; return true;
} }
$crop = !empty($options['crop']); $crop = (isset($options['crop']) ? $options['crop'] : false);
if ($crop) { if ($crop) {
$x = 0; $x = 0;
$y = 0; $y = 0;
@ -1012,6 +1047,7 @@ class UploadHandler
} }
protected function create_scaled_image($file_name, $version, $options) { protected function create_scaled_image($file_name, $version, $options) {
try {
if ($this->options['image_library'] === 2) { if ($this->options['image_library'] === 2) {
return $this->imagemagick_create_scaled_image($file_name, $version, $options); return $this->imagemagick_create_scaled_image($file_name, $version, $options);
} }
@ -1019,6 +1055,10 @@ class UploadHandler
return $this->imagick_create_scaled_image($file_name, $version, $options); return $this->imagick_create_scaled_image($file_name, $version, $options);
} }
return $this->gd_create_scaled_image($file_name, $version, $options); return $this->gd_create_scaled_image($file_name, $version, $options);
} catch (\Exception $e) {
error_log($e->getMessage());
return false;
}
} }
protected function destroy_image_object($file_path) { protected function destroy_image_object($file_path) {
@ -1027,15 +1067,30 @@ class UploadHandler
} }
} }
protected function is_valid_image_file($file_path) { protected function imagetype($file_path) {
if (!preg_match($this->options['image_file_types'], $file_path)) { $fp = fopen($file_path, 'r');
$data = fread($fp, 4);
fclose($fp);
// GIF: 47 49 46 38
if ($data === 'GIF8') {
return self::IMAGETYPE_GIF;
}
// JPG: FF D8 FF
if (bin2hex(substr($data, 0, 3)) === 'ffd8ff') {
return self::IMAGETYPE_JPEG;
}
// PNG: 89 50 4E 47
if (bin2hex(@$data[0]).substr($data, 1, 4) === '89PNG') {
return self::IMAGETYPE_PNG;
}
return false; return false;
} }
if (function_exists('exif_imagetype')) {
return @exif_imagetype($file_path); protected function is_valid_image_file($file_path) {
if (!preg_match('/\.(gif|jpe?g|png)$/i', $file_path)) {
return false;
} }
$image_info = $this->get_image_size($file_path); return !!$this->imagetype($file_path);
return $image_info && $image_info[0] && $image_info[1];
} }
protected function handle_image_file($file_path, $file) { protected function handle_image_file($file_path, $file) {
@ -1062,7 +1117,8 @@ class UploadHandler
$this->destroy_image_object($file_path); $this->destroy_image_object($file_path);
} }
protected function handle_file_upload($uploaded_file, $name, $size, $type, $error, $index = null, $content_range = null) { protected function handle_file_upload($uploaded_file, $name, $size, $type, $error,
$index = null, $content_range = null) {
$file = new \stdClass(); $file = new \stdClass();
$file->name = $this->get_file_name($uploaded_file, $name, $size, $type, $error, $file->name = $this->get_file_name($uploaded_file, $name, $size, $type, $error,
$index, $content_range); $index, $content_range);
@ -1071,7 +1127,7 @@ class UploadHandler
if ($this->validate($uploaded_file, $file, $error, $index)) { if ($this->validate($uploaded_file, $file, $error, $index)) {
$this->handle_form_data($file, $index); $this->handle_form_data($file, $index);
$upload_dir = $this->get_upload_path(); $upload_dir = $this->get_upload_path();
if (!$this->options['ftp'] && !is_dir($upload_dir)) { if (!is_dir($upload_dir)) {
mkdir($upload_dir, $this->options['mkdir_mode'], true); mkdir($upload_dir, $this->options['mkdir_mode'], true);
} }
$file_path = $this->get_upload_path($file->name); $file_path = $this->get_upload_path($file->name);
@ -1089,10 +1145,6 @@ class UploadHandler
move_uploaded_file($uploaded_file, $file_path); move_uploaded_file($uploaded_file, $file_path);
} }
} else { } else {
if($this->get_file_size($uploaded_file) == $file->size){
copy($uploaded_file, $file_path);
}else{
// Non-multipart uploads (PUT method support) // Non-multipart uploads (PUT method support)
file_put_contents( file_put_contents(
$file_path, $file_path,
@ -1100,9 +1152,7 @@ class UploadHandler
$append_file ? FILE_APPEND : 0 $append_file ? FILE_APPEND : 0
); );
} }
}
$file_size = $this->get_file_size($file_path, $append_file); $file_size = $this->get_file_size($file_path, $append_file);
$file->path = $file_path;
if ($file_size === $file->size) { if ($file_size === $file->size) {
$file->url = $this->get_download_url($file->name); $file->url = $this->get_download_url($file->name);
if ($this->is_valid_image_file($file_path)) { if ($this->is_valid_image_file($file_path)) {
@ -1317,7 +1367,6 @@ class UploadHandler
$this->options['param_name'] => $this->get_file_objects() $this->options['param_name'] => $this->get_file_objects()
); );
} }
return $this->generate_response($response, $print_response); return $this->generate_response($response, $print_response);
} }
@ -1334,11 +1383,6 @@ class UploadHandler
'', '',
$content_disposition_header $content_disposition_header
)) : null; )) : null;
// TODO check
// if (isset($content_disposition_header) && !empty($content_disposition_header) ) {
// $file_name = str_replace('attachment; filename="', '', $content_disposition_header);
// $file_name = str_replace('"', '', $file_name);
// }
// Parse the Content-Range header, which has the following form: // Parse the Content-Range header, which has the following form:
// Content-Range: bytes 0-524287/2000000 // Content-Range: bytes 0-524287/2000000
$content_range_header = $this->get_server_var('HTTP_CONTENT_RANGE'); $content_range_header = $this->get_server_var('HTTP_CONTENT_RANGE');
@ -1351,15 +1395,12 @@ class UploadHandler
// param_name is an array identifier like "files[]", // param_name is an array identifier like "files[]",
// $upload is a multi-dimensional array: // $upload is a multi-dimensional array:
foreach ($upload['tmp_name'] as $index => $value) { foreach ($upload['tmp_name'] as $index => $value) {
if(!isset($upload['error'][$index])){
$upload['error'][$index] = null;
}
$files[] = $this->handle_file_upload( $files[] = $this->handle_file_upload(
$upload['tmp_name'][$index], $upload['tmp_name'][$index],
$file_name ? $file_name : $upload['name'][$index], $file_name ? $file_name : $upload['name'][$index],
$size ? $size : $upload['size'][$index], $size ? $size : $upload['size'][$index],
$upload['type'][$index], $upload['type'][$index],
$upload['error'][$index], isset($upload['error']) ? $upload['error'][$index] : null,
$index, $index,
$content_range $content_range
); );
@ -1436,6 +1477,9 @@ class UploadHandler
$magicianObj -> saveImage($targetFile); $magicianObj -> saveImage($targetFile);
} }
$thumbResult = create_img($targetFile, $targetFileThumb, 122, 91); $thumbResult = create_img($targetFile, $targetFileThumb, 122, 91);
if ( $thumbResult!==true) if ( $thumbResult!==true)

File diff suppressed because it is too large Load Diff