diff --git a/core/lib/Thelia/Config/I18n/en_US.php b/core/lib/Thelia/Config/I18n/en_US.php index c2e166df4..5b42b3879 100644 --- a/core/lib/Thelia/Config/I18n/en_US.php +++ b/core/lib/Thelia/Config/I18n/en_US.php @@ -112,6 +112,7 @@ return array( 'Fax' => 'Fax', 'Feature value does not match FLOAT format' => 'Feature value does not match FLOAT format', 'File is too large, please retry with a file having a size less than %size%.' => 'File is too large, please retry with a file having a size less than %size%.', + 'Files with the following extension are not allowed: %extension, please do an archive of the file if you want to upload it' => 'Files with the following extension are not allowed: %extension, please do an archive of the file if you want to upload it', 'First Name' => 'First Name', 'Firstname' => 'Firstname', 'Fixed Amount Discount' => 'Fixed Amount Discount', @@ -309,6 +310,7 @@ return array( 'The detailed description.' => 'The detailed description.', 'The image which replaces an undefined country flag (%file) was not found. Please check unknown-flag-path configuration variable, and check that the image exists.' => 'The image which replaces an undefined country flag (%file) was not found. Please check unknown-flag-path configuration variable, and check that the image exists.', 'The loop name \'%name\' is already defined in %className class' => 'The loop name \'%name\' is already defined in %className class', + 'There\'s a conflict between your file extension "%ext" and the mime type "%mime"' => 'There\'s a conflict between your file extension "%ext" and the mime type "%mime"', 'This brand is online' => 'This brand is online', 'This category is online.' => 'This category is online.', 'This condition is always true' => 'This condition is always true', diff --git a/core/lib/Thelia/Config/I18n/fr_FR.php b/core/lib/Thelia/Config/I18n/fr_FR.php index 12113b8c2..895b859e9 100644 --- a/core/lib/Thelia/Config/I18n/fr_FR.php +++ b/core/lib/Thelia/Config/I18n/fr_FR.php @@ -112,6 +112,7 @@ return array( 'Fax' => 'Fax', 'Feature value does not match FLOAT format' => 'valeur de caractéristique n\'est pas un FLOAT', 'File is too large, please retry with a file having a size less than %size%.' => 'La taille de ce fichier est trop importante. Merci d\'envoyer des fichier dont la taille est inférieure à %size%.', + 'Files with the following extension are not allowed: %extension, please do an archive of the file if you want to upload it' => 'Les fichiers avec l\'extension suivante ne sont pas acceptés: %extension, veuillez créer une archive contenant ce fichier si vous voulez l\'envoyer', 'First Name' => 'Prénom', 'Firstname' => 'Prénom', 'Fixed Amount Discount' => 'Remise d\'un montant fixe', @@ -309,6 +310,7 @@ return array( 'The detailed description.' => 'La description détaillée', 'The image which replaces an undefined country flag (%file) was not found. Please check unknown-flag-path configuration variable, and check that the image exists.' => 'L\'image qui remplace un drapeau de pays manquant (%file) n\'a pas été trouvée. Merci de vérifier la variable de configuration unknown-flag-path.', 'The loop name \'%name\' is already defined in %className class' => 'La boucle \'%name\' est déjà définir dans la classe %className', + 'There\'s a conflict between your file extension "%ext" and the mime type "%mime"' => 'Il y a un conflit entre l\'extension "%ext" et le type mome "%mime" ', 'This brand is online' => 'Cette marque est en ligne', 'This category is online.' => 'Cette catégorie est en ligne.', 'This condition is always true' => 'Cette condition est troujours vérifiée', diff --git a/core/lib/Thelia/Config/Resources/config.xml b/core/lib/Thelia/Config/Resources/config.xml index 6e001e18a..f25ef42b7 100644 --- a/core/lib/Thelia/Config/Resources/config.xml +++ b/core/lib/Thelia/Config/Resources/config.xml @@ -137,7 +137,7 @@ - + diff --git a/core/lib/Thelia/Controller/Admin/FileController.php b/core/lib/Thelia/Controller/Admin/FileController.php index a5cc4e7e1..4c7ae3751 100644 --- a/core/lib/Thelia/Controller/Admin/FileController.php +++ b/core/lib/Thelia/Controller/Admin/FileController.php @@ -26,6 +26,7 @@ use Thelia\Files\FileModelInterface; use Thelia\Form\Exception\FormValidationException; use Thelia\Log\Tlog; use Thelia\Model\Lang; +use Thelia\Tools\MimeTypeTools; use Thelia\Tools\Rest\ResponseRest; use Thelia\Tools\URL; @@ -56,16 +57,24 @@ class FileController extends BaseAdminController /** * Manage how a file collection has to be saved * - * @param int $parentId Parent id owning files being saved - * @param string $parentType Parent Type owning files being saved (product, category, content, etc.) - * @param string $objectType Object type, e.g. image or document - * @param array $validMimeTypes an array of valid mime types. If empty, any mime type is allowed. - * + * @param int $parentId Parent id owning files being saved + * @param string $parentType Parent Type owning files being saved (product, category, content, etc.) + * @param string $objectType Object type, e.g. image or document + * @param array $validMimeTypes an array of valid mime types. If empty, any mime type is allowed. + * @param array $extBlackList an array of blacklisted extensions. * @return Response */ - public function saveFileAjaxAction($parentId, $parentType, $objectType, $validMimeTypes = array()) - { - $this->checkAuth(AdminResources::retrieve($parentType), array(), AccessManager::UPDATE); + public function saveFileAjaxAction( + $parentId, + $parentType, + $objectType, + $validMimeTypes = array(), + $extBlackList = array() + ) { + if (null !== $response = $this->checkAuth(AdminResources::retrieve($parentType), array(), AccessManager::UPDATE)) { + return $response; + } + $this->checkXmlHttpRequest(); if ($this->getRequest()->isMethod('POST')) { @@ -87,26 +96,50 @@ class FileController extends BaseAdminController return new ResponseRest($message, 'text', 403); } + $message = null; + $realFileName = $fileBeingUploaded->getClientOriginalName(); + if (! empty($validMimeTypes)) { - - // Check if we have the proper file type - $isValid = false; - $mimeType = $fileBeingUploaded->getMimeType(); - if (in_array($mimeType, $validMimeTypes)) { - $isValid = true; - } - - if (! $isValid) { + if (!isset($validMimeTypes[$mimeType])) { $message = $this->getTranslator() ->trans( 'Only files having the following mime type are allowed: %types%', [ '%types%' => implode(', ', $validMimeTypes)] ); - - return new ResponseRest($message, 'text', 415); } + + $regex = "#^(.+)\.(".implode("|", $validMimeTypes[$mimeType]).")$#i"; + + if (!preg_match($regex, $realFileName)) { + $message = $this->getTranslator() + ->trans( + "There's a conflict between your file extension \"%ext\" and the mime type \"%mime\"", + [ + '%mime' => $mimeType, + '%ext' => $fileBeingUploaded->getClientOriginalExtension() + ] + ); + } + } + + if (!empty($extBlackList)) { + $regex = "#^(.+)\.(".implode("|", $extBlackList).")$#i"; + + if (preg_match($regex, $realFileName)) { + $message = $this->getTranslator() + ->trans( + 'Files with the following extension are not allowed: %extension, please do an archive of the file if you want to upload it', + [ + '%extension' => $fileBeingUploaded->getClientOriginalExtension(), + ] + ); + } + } + + if ($message !== null) { + return new ResponseRest($message, 'text', 415); } $fileModel = $fileManager->getModelInstance($objectType, $parentType); @@ -169,7 +202,16 @@ class FileController extends BaseAdminController */ public function saveImageAjaxAction($parentId, $parentType) { - return $this->saveFileAjaxAction($parentId, $parentType, 'image', ['image/jpeg' , 'image/png' ,'image/gif']); + return $this->saveFileAjaxAction( + $parentId, + $parentType, + 'image', + [ + 'image/jpeg' => ["jpg", "jpeg"], + 'image/png' => ["png"], + 'image/gif' => ["gif"], + ] + ); } /** @@ -182,7 +224,21 @@ class FileController extends BaseAdminController */ public function saveDocumentAjaxAction($parentId, $parentType) { - return $this->saveFileAjaxAction($parentId, $parentType, 'document'); + return $this->saveFileAjaxAction( + $parentId, + $parentType, + 'document', + [], + [ + "php", + "php3", + "php4", + "php5", + "php6", + "asp", + "aspx", + ] + ); } /** diff --git a/core/lib/Thelia/Tests/Tools/URLTest.php b/core/lib/Thelia/Tests/Tools/URLTest.php index a6b934544..d22bfa09e 100755 --- a/core/lib/Thelia/Tests/Tools/URLTest.php +++ b/core/lib/Thelia/Tests/Tools/URLTest.php @@ -10,7 +10,7 @@ /* file that was distributed with this source code. */ /*************************************************************************************/ -namespace Thelia\Tests\Type; +namespace Thelia\Tests\Tools; use Thelia\Tools\URL;