From ce10c0ff1dd0b47bd494ae88ab2eaf6ab354b2b3 Mon Sep 17 00:00:00 2001 From: polo Date: Fri, 2 Jun 2023 01:21:06 +0200 Subject: filtre nom des images + reorg code Image --- controller/Security.php | 44 +++++++++++++++++++++++++++++++++++++++++++ controller/ajax.php | 10 +++++++--- controller/ckeditor.php | 28 ++++++++++++++++++++++----- index.php | 2 +- model/Album.php | 31 +----------------------------- model/Article.php | 2 -- model/Image.php | 37 ++++++++++++++++++++++++------------ public/css/discographie.css | 2 +- public/file_upload.js | 13 +++++++++++++ view/album.php | 1 + view/articlesContent.php | 9 +-------- view/discographie.php | 10 +++------- view/template-formulaires.php | 2 ++ 13 files changed, 122 insertions(+), 69 deletions(-) diff --git a/controller/Security.php b/controller/Security.php index 39205c1..3475a8d 100644 --- a/controller/Security.php +++ b/controller/Security.php @@ -20,6 +20,50 @@ class Security $chaine = trim($chaine); // supprimer espaces, tabulations et sauts de ligne en début et fin de chaine (pour l'entrée de l'éditeur) return $chaine; } + + public static function secureFileName(string $chaine): string + { + // sécuriser un nom avec chemin avec basename? + //$chaine = basename($chaine); + + /* + - caractères interdits sous windows / \ : * ? " < > | + - mac autorise les / + - mac interdit : + - linux autorise tout sauf les / + - imagemagick ne supporte pas les : + + - 'espace' fonctionne + - / remplacé par firefox en : + - \ retire ce qui est devant le \ + - * fonctionne + - ? permet le téléchargement mais pas l'affichage + - " ne fonctionne pas, remplacé par %22, filtrer %22 + - < > fonctionnent + - | fonctionne + - = fonctionne, mais je filtre parce qu'on en trouve dans une URL + - ' ` fonctionnent + - % fonctionne + - (){}[] fonctionnent + - ^ fonctionne + - # ne fonctionne pas + - ~ fonctionne + - & fonctionne + */ + + // => on remplace tout par des _ + // filtrer / et \ semble inutile + + $cibles = [' ', '/', '\\', ':', '*', '?', '<', '>', '|', '=', "'", '`', '"', '%22', '#']; + return(str_replace($cibles, '_', $chaine)); + + // les problèmes avec \ persistent !! + // => javascript + // malheureusement document.getElementById('upload').files[0].name = chaine; ne marche pas! interdit! + // solution? + // créer une copie du fichier et l'envoyer à la place + // envoyer le nom souhaité au serveur en AJAX puis renommer avec PHP + } } // erreurs à la création des mots de passe diff --git a/controller/ajax.php b/controller/ajax.php index ed840cd..9272dea 100644 --- a/controller/ajax.php +++ b/controller/ajax.php @@ -17,7 +17,8 @@ if(isset($_GET['action']) && isset($_GET['page']) && $_GET['action'] == 'upload_ else { require('model/Image.php'); - // vaut "true" parce qu'on reçoit une requête AJAX + require('controller/Security.php'); + // paramètre "true" parce qu'on reçoit une requête AJAX $Image = new Image($_GET['page'], $_GET['page'], true); // les données des albums sont dans le dossier discographie if($_GET['page'] === 'album') @@ -25,12 +26,15 @@ if(isset($_GET['action']) && isset($_GET['page']) && $_GET['action'] == 'upload_ $Image->setFolder('discographie'); } - $Image->upload(); + $nomFichier = Security::secureFileName($_FILES['upload']['name']); + $Image->setFileName($nomFichier); + $Image->setThumbnailWidth(630); + $Image->upload(); echo($Image->reponseAjax); // attendu par l'éditeur // attention ici aux var_dump() ou echo() qui trainent - $Image->makeThumbnail(630); // => taille de la
+ $Image->makeThumbnail(); // => taille de la
// on pourra l'agrandir en cliquant dessus // code exécuté alors que l'utilisateur récupère la main } diff --git a/controller/ckeditor.php b/controller/ckeditor.php index 4d4639d..3765261 100644 --- a/controller/ckeditor.php +++ b/controller/ckeditor.php @@ -66,7 +66,7 @@ function submitCKeditor() if($_GET['page'] === 'discographie' || $_GET['page'] === 'album') { $Album = new Album($_GET['page'], 'discographie'); - + // on retrouve les données si nécessaire if(isset($_SESSION['file_code']) && $_SESSION['file_code'] != '') { @@ -76,10 +76,28 @@ function submitCKeditor() $nouveauTitre = Security::secureString($_POST['titre']); $nouvelleAnnee = Security::secureString($_POST['annee']); + + // enregistrement de l'image if(!empty($_FILES['upload']['name'])) { - $nouvellePochette = $_FILES['upload']['name']; - $nouvellePochetteMini = pathinfo($_FILES['upload']['name'], PATHINFO_FILENAME) . '-mini.' . pathinfo($_FILES['upload']['name'], PATHINFO_EXTENSION); + require('model/Image.php'); + $Image = new Image($_GET['page'], 'discographie', false); + $nomFichier = Security::secureFileName($_FILES['upload']['name']); + $Image->setFileName($nomFichier); + $Image->setThumbnailWidth(201); + + $nouvellePochette = $nomFichier; + /*$nouvellePochetteMini = pathinfo($_FILES['upload']['name'], PATHINFO_FILENAME) . '-mini.' . pathinfo($_FILES['upload']['name'], PATHINFO_EXTENSION);*/ + $nouvellePochetteMini = pathinfo($nomFichier, PATHINFO_FILENAME) . '-mini.' . pathinfo($nomFichier, PATHINFO_EXTENSION); + + $Image->upload(); + $Image->makeThumbnail(); + + $erreur = $Image->erreur; + if(!empty($erreur)) + { + // remettre pochette précédente si il y a + } } else { @@ -89,11 +107,11 @@ function submitCKeditor() //var_dump($nouvellePochetteMini); die(); - // enregistrement nouvel album + // enregistrement du texte JSON if(!isset($_SESSION['file_code']) || $_SESSION['file_code'] == '') { // page disco - $Album->createVignette($nouveauTitre, $nouvelleAnnee, $nouvellePochette, $nouvellePochetteMini); + $Album->createVignetteJSON($nouveauTitre, $nouvelleAnnee, $nouvellePochette, $nouvellePochetteMini); // page de l'album if(!empty($_POST['contenu'])) diff --git a/index.php b/index.php index 4e2de59..1888704 100644 --- a/index.php +++ b/index.php @@ -37,7 +37,7 @@ if(isset($_SESSION['admin']) && $_SESSION['admin'] == 1 || (isset($_POST['titre']) && isset($_POST['annee'])))) { require('controller/ckeditor.php'); // traitement du POST - require('controller/Security.php'); // sécurité des chaines + require('controller/Security.php'); // HTML + nom de fichier require('model/Article.php'); if($_GET['page'] === 'discographie' || $_GET['page'] === 'album') diff --git a/model/Album.php b/model/Album.php index d2537f7..801afef 100644 --- a/model/Album.php +++ b/model/Album.php @@ -39,25 +39,10 @@ class Album extends Article // fonctions CRUD // create - public function createVignette($titre, $annee, $pochette, $pochetteMini) + public function createVignetteJSON($titre, $annee, $pochette, $pochetteMini) { //$this->format = 'json'; - if($pochette != '') - { - //echo($pochette); die(); // = nom sans chemin - - // télécharger la pochette - require('model/Image.php'); - $Image = new Image($this->page, $this->folder, false); - $Image->upload(); - $Image->makeThumbnail(201); - - $erreur = $Image->erreur; - if(!empty($erreur)) - {} - } - $albumJSON = json_encode([$titre, $annee, $pochette, $pochetteMini]); //var_dump($albumJSON); die(); @@ -171,20 +156,6 @@ class Album extends Article $pochette = $albumJSON[2]; $pochetteMini = $albumJSON[3]; } - else - { - // télécharger la pochette - require('model/Image.php'); - $Image = new Image($this->page, $this->folder, false); - $Image->upload(); - $Image->makeThumbnail(201); - $erreur = $Image->erreur; - if(!empty($erreur)) - { - // remettre pochette d'avant - //$pochette - } - } $albumJSON = json_encode([$titre, $annee, $pochette, $pochetteMini]); diff --git a/model/Article.php b/model/Article.php index 0e8db61..d94ba01 100644 --- a/model/Article.php +++ b/model/Article.php @@ -198,8 +198,6 @@ class Article fputs($file, $content); fclose($file); chmod($fileName, 0666); - - } // read diff --git a/model/Image.php b/model/Image.php index d71b96a..dbdad62 100644 --- a/model/Image.php +++ b/model/Image.php @@ -11,6 +11,8 @@ class Image public $path; public $pathMini; + public $FileName; // après sécurisation + public $width; public $pathInfos; public $erreur; @@ -33,20 +35,31 @@ class Image $this->pathMini = 'data/' . $this->folder . '/images-mini/'; } + public function setFileName($fileName) + { + $this->FileName = $fileName; + } + + public function setThumbnailWidth($width) + { + $this->width = $width; + } public function upload() { // traitement et enregistrement de l'image if (isset($_FILES['upload']) AND $_FILES['upload']['error'] == 0) // 0 signifie ok { - $this->pathInfos = pathinfo($_FILES['upload']['name']); + //$this->pathInfos = pathinfo($_FILES['upload']['name']); + $this->pathInfos = pathinfo($this->FileName); + $extension = $this->pathInfos['extension']; $extautorisées = array('jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'tiff'); // on prend la même liste que celle côté javascript, le SVG est bloqué pour raison de sécurité (javascript à l'intérieur) if (in_array($extension, $extautorisées)) { - move_uploaded_file($_FILES['upload']['tmp_name'], $this->path . $_FILES['upload']['name']); - chmod($this->path . $_FILES['upload']['name'], 0666); + move_uploaded_file($_FILES['upload']['tmp_name'], $this->path . $this->FileName); + chmod($this->path . $this->FileName, 0666); } else { @@ -63,24 +76,24 @@ class Image if($this->ajax && empty($Image->erreur)) { // chemin en JSON attendu par l'éditeur - $this->reponseAjax = '{"url": "data/' . $this->folder . '/images/' . $_FILES['upload']['name'] . '"}'; + $this->reponseAjax = '{"url": "data/' . $this->folder . '/images/' . $this->FileName . '"}'; } } // miniatures des photos - public function makeThumbnail($largeur) + public function makeThumbnail() { global $imageLibrary; if($imageLibrary == 'imagick') { - $Image = new Imagick($this->path . $_FILES['upload']['name']); + $Image = new Imagick($this->path . $this->FileName); $source = $Image->getImageGeometry(); - if($source['width'] > $largeur) + if($source['width'] > $this->width) { // 0 signifie qu'on conserve les proportions - $Image->thumbnailImage($largeur, 0); + $Image->thumbnailImage($this->width, 0); } // écriture dans un fichier @@ -89,18 +102,18 @@ class Image elseif($imageLibrary == 'gd') { // cette fonction fonctionne pour tous les formats - $source = imagecreatefromstring(file_get_contents($this->path . $_FILES['upload']['name'])); + $source = imagecreatefromstring(file_get_contents($this->path . $this->FileName)); $nomMiniImage = $this->pathMini . $this->pathInfos['filename'] . '-mini.jpg'; $forme = imagesy($source) / imagesx($source); - if(imagesx($source) > $largeur) + if(imagesx($source) > $this->width) { // créer un rectangle noir - $destination = imagecreatetruecolor($largeur, $largeur * $forme); + $destination = imagecreatetruecolor($this->width, $this->width * $forme); // sélectionne un rectangle dans l'image source // et le place dans un rectangle dans la nouvelle - imagecopyresampled($destination, $source, 0, 0, 0, 0, $largeur, $largeur * $forme, imagesx($source), imagesy($source)); + imagecopyresampled($destination, $source, 0, 0, 0, 0, $this->width, $this->width * $forme, imagesx($source), imagesy($source)); // envoie l'image dans un fichier imagejpeg($destination, $nomMiniImage); diff --git a/public/css/discographie.css b/public/css/discographie.css index 31df03e..38ca683 100644 --- a/public/css/discographie.css +++ b/public/css/discographie.css @@ -25,7 +25,7 @@ aside div #bouton_chronologie { - width: 300px; + width: 250px; text-align: center; font-size: large; font-weight: bold; diff --git a/public/file_upload.js b/public/file_upload.js index 88a61a8..4102828 100644 --- a/public/file_upload.js +++ b/public/file_upload.js @@ -4,6 +4,19 @@ // ce fichier est "caché", le serveur ne l'envoit qu'à // un utilisateur connecté et sur la page "restauration" +// retirer antislash dans le nom à l'upload d'une image +/*function filtrerAntislash() +{ + var fileInfos = getFileInfo('upload'); // = ID + var chaine = fileInfos.name.replace('\\', '_'); + alert(document.getElementById('upload').files[0].name); + + // ne marche pas, "name" est en lecture seule + document.getElementById('upload').files[0].name = chaine; + alert(document.getElementById('upload').files[0].name); + //return chaine; +}*/ + // -> input file onchange function sendFileSize() { diff --git a/view/album.php b/view/album.php index f8879aa..fe5d8c2 100644 --- a/view/album.php +++ b/view/album.php @@ -14,6 +14,7 @@ $css = ob_get_clean(); ob_start(); ?> + fileListCount; $i++) { // on pourrait utiliser ici le timedate, ou encore le nom de l'article ?> -

Modification d'un article

+

Modification d'un article

-

- - - - -

+ fileListCount; $i++) // boutons if($_SESSION['admin'] == 1) { - /*$lien_partage = 'index.php?page=' . $page . '#' . $Albums->fileList[$i]['fileCode']; - global $host;*/ - ?> +?>

- @@ -173,7 +169,7 @@ for($i = 0; $i < $Albums->fileListCount; $i++)

- diff --git a/view/template-formulaires.php b/view/template-formulaires.php index 0ffbba3..fc73a27 100644 --- a/view/template-formulaires.php +++ b/view/template-formulaires.php @@ -33,6 +33,7 @@ ob_start();

+


+ -- cgit v1.2.3