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;