From 24f679d531dd8a73018725580dcc4eeb7adbe989 Mon Sep 17 00:00:00 2001 From: Fred Tempez Date: Fri, 5 Apr 2024 16:33:46 +0200 Subject: [PATCH] 1.7.09 fonction secureFilePutContents --- core/class/jsondb/JsonDb.class.php | 5 +- core/class/router.class.php | 10 +- core/core.php | 219 ++++++++++++++++++++--------- core/module/config/config.php | 14 +- core/module/course/course.php | 6 +- core/module/install/install.php | 4 +- core/module/language/language.php | 8 +- core/module/plugin/plugin.php | 4 +- core/module/theme/theme.php | 8 +- module/gallery/gallery.php | 4 +- module/news/news.php | 4 +- module/search/search.php | 4 +- 12 files changed, 187 insertions(+), 103 deletions(-) diff --git a/core/class/jsondb/JsonDb.class.php b/core/class/jsondb/JsonDb.class.php index 81fc83a..eb08a26 100644 --- a/core/class/jsondb/JsonDb.class.php +++ b/core/class/jsondb/JsonDb.class.php @@ -193,7 +193,10 @@ class JsonDb extends \Prowebcraft\Dot fclose($lockHandle); return false; } - + // Supprimer le fichier de verrouillage + if (file_exists($lockFile)) { + unlink($lockFile); + } return true; } diff --git a/core/class/router.class.php b/core/class/router.class.php index 17922c2..3f31f9a 100644 --- a/core/class/router.class.php +++ b/core/class/router.class.php @@ -61,17 +61,17 @@ class core extends common // Crée le fichier de personnalisation avancée if (file_exists(self::DATA_DIR . 'custom.css') === false) { - file_put_contents(self::DATA_DIR . 'custom.css', ('core/module/theme/resource/custom.css')); + $this->secureFilePutContents(self::DATA_DIR . 'custom.css', 'core/module/theme/resource/custom.css'); chmod(self::DATA_DIR . 'custom.css', 0755); } // Crée le fichier de personnalisation if (file_exists(self::DATA_DIR . self::$siteContent . '/theme.css') === false) { - file_put_contents(self::DATA_DIR . self::$siteContent . '/theme.css', ''); + $this->secureFilePutContents(self::DATA_DIR . self::$siteContent . '/theme.css', ''); chmod(self::DATA_DIR . self::$siteContent . '/theme.css', 0755); } // Crée le fichier de personnalisation de l'administration if (file_exists(self::DATA_DIR . 'admin.css') === false) { - file_put_contents(self::DATA_DIR . 'admin.css', ''); + $this->secureFilePutContents(self::DATA_DIR . 'admin.css', ''); chmod(self::DATA_DIR . 'admin.css', 0755); } @@ -273,7 +273,7 @@ class core extends common $css .= '#footerCopyright{text-align:' . $this->getData(['theme', 'footer', 'copyrightAlign']) . '}'; // Enregistre la personnalisation - file_put_contents(self::DATA_DIR . self::$siteContent . '/theme.css', $css); + $this->secureFilePutContents(self::DATA_DIR . self::$siteContent . '/theme.css', $css); // Effacer le cache pour tenir compte de la couleur de fond TinyMCE header("Expires: Tue, 01 Jan 2000 00:00:00 GMT"); @@ -368,7 +368,7 @@ class core extends common // Bordure du contour TinyMCE $css .= '.mce-tinymce{border: 1px solid ' . $this->getData(['admin', 'borderBlockColor']) . '!important;}'; // Enregistre la personnalisation - file_put_contents(self::DATA_DIR . 'admin.css', $css); + $this->secureFilePutContents(self::DATA_DIR . 'admin.css', $css); } } /** diff --git a/core/core.php b/core/core.php index 5042924..f3957f6 100644 --- a/core/core.php +++ b/core/core.php @@ -60,6 +60,18 @@ class common // Valeurs possibles multiple de 10, 10 autorise 9 profils, 100 autorise 99 profils const MAX_PROFILS = 10; + const MAX_FILE_WRITE_ATTEMPTS = 5; + + /** + * Nombre maximal de tentatives d'encodage JSON + */ + const MAX_JSON_ENCODE_ATTEMPTS = 3; + + /** + * Temps d'attente entre les tentatives en secondes + */ + const RETRY_DELAY_SECONDS = 1; + // Constantes pourles contenus // Modalités d'ouverture @@ -447,7 +459,7 @@ class common } // Mise à jour des données core - include('core/include/update.inc.php'); + include ('core/include/update.inc.php'); } @@ -595,7 +607,7 @@ class common public function setPage($page, $value, $path) { - return file_put_contents(self::DATA_DIR . $path . '/content/' . $page . '.html', $value); + return $this->secureFilePutContents(self::DATA_DIR . $path . '/content/' . $page . '.html', $value); } @@ -634,7 +646,7 @@ class common { // Tableau avec les données vierges - require_once('core/module/install/ressource/defaultdata.php'); + require_once ('core/module/install/ressource/defaultdata.php'); // L'arborescence if (!file_exists(self::DATA_DIR . $path)) { @@ -669,7 +681,7 @@ class common public function saveConfig($module) { // Tableau avec les données vierges - require_once('core/module/install/ressource/defaultdata.php'); + require_once ('core/module/install/ressource/defaultdata.php'); // Installation des données des autres modules cad theme profil font config, admin et core $this->setData([$module, init::$defaultData[$module]]); common::$coreNotices[] = $module; @@ -705,65 +717,134 @@ class common * Fonction pour construire le tableau des pages */ - private function buildHierarchy() - { - - $pages = helper::arrayColumn($this->getData(['page']), 'position', 'SORT_ASC'); - // Parents - foreach ($pages as $pageId => $pagePosition) { - if ( - // Page parent - $this->getData(['page', $pageId, 'parentPageId']) === "" - // Ignore les pages dont l'utilisateur n'a pas accès - and ($this->getData(['page', $pageId, 'group']) === self::GROUP_VISITOR - or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') - //and $this->getUser('group') >= $this->getData(['page', $pageId, 'group']) - // Modification qui tient compte du profil de la page - and ($this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil'])) - - ) - ) - ) { - if ($pagePosition !== 0) { - $this->hierarchy['visible'][$pageId] = []; - } - if ($this->getData(['page', $pageId, 'block']) === 'bar') { - $this->hierarchy['bar'][$pageId] = []; - } - $this->hierarchy['all'][$pageId] = []; - } - } - // Enfants - foreach ($pages as $pageId => $pagePosition) { - - if ( - // Page parent - $parentId = $this->getData(['page', $pageId, 'parentPageId']) - // Ignore les pages dont l'utilisateur n'a pas accès - and ( - ( - $this->getData(['page', $pageId, 'group']) === self::GROUP_VISITOR - and - $this->getData(['page', $parentId, 'group']) === self::GROUP_VISITOR - ) - or ( - $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') - and - $this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil']) - - ) - ) - ) { - if ($pagePosition !== 0) { - $this->hierarchy['visible'][$parentId][] = $pageId; - } - if ($this->getData(['page', $pageId, 'block']) === 'bar') { - $this->hierarchy['bar'][$pageId] = []; - } - $this->hierarchy['all'][$parentId][] = $pageId; - } - } - } + private function buildHierarchy() + { + + $pages = helper::arrayColumn($this->getData(['page']), 'position', 'SORT_ASC'); + // Parents + foreach ($pages as $pageId => $pagePosition) { + if ( + // Page parent + $this->getData(['page', $pageId, 'parentPageId']) === "" + // Ignore les pages dont l'utilisateur n'a pas accès + and ($this->getData(['page', $pageId, 'group']) === self::GROUP_VISITOR + or ($this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') + //and $this->getUser('group') >= $this->getData(['page', $pageId, 'group']) + // Modification qui tient compte du profil de la page + and ($this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil'])) + + ) + ) + ) { + if ($pagePosition !== 0) { + $this->hierarchy['visible'][$pageId] = []; + } + if ($this->getData(['page', $pageId, 'block']) === 'bar') { + $this->hierarchy['bar'][$pageId] = []; + } + $this->hierarchy['all'][$pageId] = []; + } + } + // Enfants + foreach ($pages as $pageId => $pagePosition) { + + if ( + // Page parent + $parentId = $this->getData(['page', $pageId, 'parentPageId']) + // Ignore les pages dont l'utilisateur n'a pas accès + and ( + ( + $this->getData(['page', $pageId, 'group']) === self::GROUP_VISITOR + and + $this->getData(['page', $parentId, 'group']) === self::GROUP_VISITOR + ) + or ( + $this->getUser('password') === $this->getInput('ZWII_USER_PASSWORD') + and + $this->getUser('group') * self::MAX_PROFILS + $this->getUser('profil')) >= ($this->getData(['page', $pageId, 'group']) * self::MAX_PROFILS + $this->getData(['page', $pageId, 'profil']) + + ) + ) + ) { + if ($pagePosition !== 0) { + $this->hierarchy['visible'][$parentId][] = $pageId; + } + if ($this->getData(['page', $pageId, 'block']) === 'bar') { + $this->hierarchy['bar'][$pageId] = []; + } + $this->hierarchy['all'][$parentId][] = $pageId; + } + } + } + + /** + * Nombre maximal de tentatives d'écriture dans le fichier + */ + + + /** + * Écriture sécurisée dans un fichier en utilisant un verrouillage de fichier pour éviter les accès concurrents. + * Les données sont encodées au format JSON si l'extension du fichier est JSON. + * + * @param string $filename Le chemin du fichier dans lequel écrire les données. + * @param mixed $data Les données à écrire dans le fichier. + * @param int $options Les options pour la fonction file_put_contents, par défaut 0. + * + * @return bool Retourne true si l'écriture dans le fichier est réussie, false sinon. + */ + public static function secureFilePutContents($filename, $data, $options = 0) + { + // Vérifier si l'extension du fichier est JSON + $extension = pathinfo($filename, PATHINFO_EXTENSION); + $encodeJson = strtolower($extension) === 'json'; + + // Tentatives d'encodage JSON si nécessaire + if ($encodeJson) { + $jsonData = null; + $attempts = 0; + while ($attempts < self::MAX_JSON_ENCODE_ATTEMPTS) { + $jsonData = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); + if ($jsonData !== false) { + break; // Sortir de la boucle si l'encodage réussit + } + $attempts++; + error_log('Erreur d\'encodage JSON (tentative ' . $attempts . ') : ' . json_last_error_msg()); + sleep(self::RETRY_DELAY_SECONDS); // Attendre avant de réessayer + } + + if ($jsonData === false) { + error_log('Impossible d\'encoder les données en format JSON.'); + return false; + } + } else { + // Pas d'encodage JSON nécessaire + $jsonData = $data; + } + + // Écriture sécurisée dans le fichier avec un verrouillage + $attempts = 0; + while ($attempts < self::MAX_FILE_WRITE_ATTEMPTS) { + $lockHandle = fopen($filename . '.lock', 'w'); + if (flock($lockHandle, LOCK_EX)) { + $bytesWritten = file_put_contents($filename, $jsonData, $options); + flock($lockHandle, LOCK_UN); + fclose($lockHandle); + if ($bytesWritten !== false && $bytesWritten === strlen($jsonData)) { + return true; // Écriture réussie + } + } else { + fclose($lockHandle); + } + $attempts++; + error_log('Erreur d\'écriture (tentative ' . $attempts . ') : impossible de sauvegarder les données dans ' . $filename); + sleep(self::RETRY_DELAY_SECONDS); // Attendre avant de réessayer + } + + error_log('Impossible d\'écrire dans le fichier ' . $filename . ' après ' . self::MAX_FILE_WRITE_ATTEMPTS . ' tentatives.'); + return false; + } + + /** * Génère un fichier json avec la liste des pages @@ -826,7 +907,7 @@ class common // Enregistrement : 3 tentatives for ($i = 0; $i < 3; $i++) { - if (file_put_contents('core/vendor/tinymce/link_list.json', json_encode($parents, JSON_UNESCAPED_UNICODE), LOCK_EX) !== false) { + if ($this->secureFilePutContents('core/vendor/tinymce/link_list.json', json_encode($parents, JSON_UNESCAPED_UNICODE), LOCK_EX) !== false) { break; } // Pause de 10 millisecondes @@ -1118,7 +1199,7 @@ class common } $sitemap->updateRobots(); } else { - file_put_contents('robots.txt', 'User-agent: *' . PHP_EOL . 'Disallow: /'); + $this->secureFilePutContents('robots.txt', 'User-agent: *' . PHP_EOL . 'Disallow: /'); } // Submit your sitemaps to Google, Yahoo, Bing and Ask.com @@ -1408,7 +1489,7 @@ class common $dataLog .= $message ? $this->getUrl() . ';' . $message : $this->getUrl(); $dataLog .= PHP_EOL; if ($this->getData(['config', 'connect', 'log'])) { - file_put_contents(self::DATA_DIR . 'journal.log', $dataLog, FILE_APPEND); + $this->secureFilePutContents(self::DATA_DIR . 'journal.log', $dataLog, FILE_APPEND); } } @@ -1435,8 +1516,8 @@ class common foreach ($courses as $courseId => $value) { // Affiche les espaces gérés par l'éditeur, les espaces où il participe et les espaces anonymes if ( - // le membre est inscrit - ( $this->getData(['enrolment', $courseId]) && array_key_exists($this->getUser('id'), $this->getData(['enrolment', $courseId])) ) + // le membre est inscrit + ($this->getData(['enrolment', $courseId]) && array_key_exists($this->getUser('id'), $this->getData(['enrolment', $courseId]))) // Il est l'auteur || $this->getUser('id') === $this->getData(['course', $courseId, 'author']) // Le cours est ouvert @@ -1450,7 +1531,7 @@ class common foreach ($courses as $courseId => $value) { // Affiche les espaces du participant et les espaces anonymes if ( - ($this->getData(['enrolment', $courseId]) && array_key_exists($this->getUser('id'), $this->getData(['enrolment', $courseId])) ) + ($this->getData(['enrolment', $courseId]) && array_key_exists($this->getUser('id'), $this->getData(['enrolment', $courseId]))) || $this->getData(['course', $courseId, 'enrolment']) === self::COURSE_ENROLMENT_GUEST ) { $filter[$courseId] = $courses[$courseId]; diff --git a/core/module/config/config.php b/core/module/config/config.php index bcc4134..88e3085 100644 --- a/core/module/config/config.php +++ b/core/module/config/config.php @@ -567,7 +567,7 @@ class config extends common '' . PHP_EOL . '# URL rewriting' . PHP_EOL; $fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent); - file_put_contents( + $this->secureFilePutContents( '.htaccess', $fileContent ); @@ -583,7 +583,7 @@ class config extends common $fileContent = file_get_contents('.htaccess'); $fileContent = explode('# URL rewriting', $fileContent); $fileContent = $fileContent[0] . '# URL rewriting' . $fileContent[2]; - file_put_contents( + $this->secureFilePutContents( '.htaccess', $fileContent ); @@ -709,10 +709,10 @@ class config extends common ) { // Ecrire les fichiers de script if ($this->geturl(2) === 'head') { - file_put_contents(self::DATA_DIR . 'head.inc.html', $this->getInput('configScriptHead', null)); + $this->secureFilePutContents(self::DATA_DIR . 'head.inc.html', $this->getInput('configScriptHead', null)); } if ($this->geturl(2) === 'body') { - file_put_contents(self::DATA_DIR . 'body.inc.html', $this->getInput('configScriptBody', null)); + $this->secureFilePutContents(self::DATA_DIR . 'body.inc.html', $this->getInput('configScriptBody', null)); } // Valeurs en sortie $this->addOutput([ @@ -754,7 +754,7 @@ class config extends common unlink(self::DATA_DIR . 'journal.log'); // Créer les en-têtes des journaux $d = 'Date;Heure;IP;Id;Action' . PHP_EOL; - file_put_contents(self::DATA_DIR . 'journal.log', $d); + $this->secureFilePutContents(self::DATA_DIR . 'journal.log', $d); // Valeurs en sortie $this->addOutput([ 'title' => helper::translate('Configuration'), @@ -830,7 +830,7 @@ class config extends common ob_start(); $fileName = self::TEMP_DIR . 'blacklist.log'; $d = 'Date dernière tentative;Heure dernière tentative;Id;Adresse IP;Nombre d\'échecs' . PHP_EOL; - file_put_contents($fileName, $d); + $this->secureFilePutContents($fileName, $d); if (file_exists($fileName)) { $d = $this->getData(['blacklist']); $data = ''; @@ -838,7 +838,7 @@ class config extends common $data .= helper::dateUTF8('%Y %m %d', $item['lastFail'], self::$i18nUI) . ' - ' . helper::dateUTF8('%H:%M', time(), self::$i18nUI); $data .= $key . ';' . $item['ip'] . ';' . $item['connectFail'] . PHP_EOL; } - file_put_contents($fileName, $data, FILE_APPEND); + $this->secureFilePutContents($fileName, $data, FILE_APPEND); header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Transfer-Encoding: binary'); diff --git a/core/module/course/course.php b/core/module/course/course.php index cc4d2bd..77904eb 100644 --- a/core/module/course/course.php +++ b/core/module/course/course.php @@ -1597,17 +1597,17 @@ class course extends common // Participants avec historiques $enrolment = $this->getData(['enrolment', $courseId]); // Générer un fichier dans le dossier de l'espace - file_put_contents(self::DATA_DIR . $courseId . '/enrolment.json', json_encode([$courseId => $enrolment], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); + $this->secureFilePutContents(self::DATA_DIR . $courseId . '/enrolment.json', [$courseId => $enrolment]); // Idem pour les données du cours $course = $this->getData(['course', $courseId]); // Générer un fichier dans le dossier de l'espace - file_put_contents(self::DATA_DIR . $courseId . '/course.json', json_encode([$courseId => $course], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); + $this->secureFilePutContents(self::DATA_DIR . $courseId . '/course.json',[$courseId => $course]); // Idem pour la catégorie $category = $this->getData(['category', $this->getData(['course', $courseId, 'category'])]); // Générer un fichier dans le dossier de l'espace - file_put_contents(self::DATA_DIR . $courseId . '/category.json', json_encode([$this->getData(['course', $courseId, 'category']) => $category], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); + $this->secureFilePutContents(self::DATA_DIR . $courseId . '/category.json', [$this->getData(['course', $courseId, 'category']) => $category]); // Génère une archive ZIP diff --git a/core/module/install/install.php b/core/module/install/install.php index 23e455a..d3f9d60 100644 --- a/core/module/install/install.php +++ b/core/module/install/install.php @@ -278,7 +278,7 @@ class install extends common case 2: $success = true; $message = ''; - file_put_contents(self::TEMP_DIR . 'update.tar.gz', helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.tar.gz')); + $this->secureFilePutContents(self::TEMP_DIR . 'update.tar.gz', helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.tar.gz')); $md5origin = helper::getUrlContents(common::ZWII_UPDATE_URL . common::ZWII_UPDATE_CHANNEL . '/update.md5'); $md5origin = explode(' ', $md5origin); $md5target = md5_file(self::TEMP_DIR . 'update.tar.gz'); @@ -387,7 +387,7 @@ class install extends common '' . PHP_EOL . '# URL rewriting' . PHP_EOL; $fileContent = str_replace('# URL rewriting', $rewriteData, $fileContent); - $success = file_put_contents( + $success = $this->secureFilePutContents( '.htaccess', $fileContent ); diff --git a/core/module/language/language.php b/core/module/language/language.php index b6b3d9f..fea4c43 100644 --- a/core/module/language/language.php +++ b/core/module/language/language.php @@ -99,7 +99,7 @@ class language extends common is_array($descripteur['language'][$lang]) ) { if ($this->setData(['language', $lang, $descripteur['language'][$lang]])) { - $success = file_put_contents(self::I18N_DIR . $lang . '.json', json_encode($languageData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); + $success = $this->secureFilePutContents(self::I18N_DIR . $lang . '.json', $languageData); $success = is_int($success) ? true : false; } } @@ -419,7 +419,7 @@ class language extends common $this->setData(['locale', $data['locale']]); } else { // Sauver sur le disque - file_put_contents(self::DATA_DIR . $lang . '/locale.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX); + $this->secureFilePutContents(self::DATA_DIR . $lang . '/locale.json', $data); } // Valeurs en sortie @@ -501,7 +501,7 @@ class language extends common $data[$key] = $target; } } - file_put_contents(self::I18N_DIR . $lang . '.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX); + $this->secureFilePutContents(self::I18N_DIR . $lang . '.json', $data); // Mettre à jour le descripteur $this->setData([ @@ -535,7 +535,7 @@ class language extends common $data[$key] = ''; } } - file_put_contents(self::I18N_DIR . $lang . '.json', json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT), LOCK_EX); + $this->secureFilePutContents(self::I18N_DIR . $lang . '.json', $data); // Tableau des chaines à traduire dans la langue sélectionnée foreach ($data as $key => $value) { diff --git a/core/module/plugin/plugin.php b/core/module/plugin/plugin.php index dd7958f..f0a65a0 100644 --- a/core/module/plugin/plugin.php +++ b/core/module/plugin/plugin.php @@ -317,7 +317,7 @@ class plugin extends common mkdir(self::FILE_DIR . 'source/modules', 0755); } // Sauver les données du fichiers - file_put_contents(self::FILE_DIR . 'source/modules/' . $moduleFile, $moduleData); + $this->secureFilePutContents(self::FILE_DIR . 'source/modules/' . $moduleFile, $moduleData); // Installation directe if (file_exists(self::FILE_DIR . 'source/modules/' . $moduleFile)) { @@ -597,7 +597,7 @@ class plugin extends common $fileName = $moduleId . str_replace('.', '-', $infoModule[$moduleId]['version']) . '.zip'; // Régénération du descripteur du module - file_put_contents(self::MODULE_DIR . $moduleId . '/enum.json', json_encode($infoModule[$moduleId], JSON_UNESCAPED_UNICODE)); + $this->secureFilePutContents(self::MODULE_DIR . $moduleId . '/enum.json',$infoModule[$moduleId]); // Construire l'archive $this->makeZip($tmpFolder . $fileName, self::MODULE_DIR . $moduleId); diff --git a/core/module/theme/theme.php b/core/module/theme/theme.php index 50298cc..6753de9 100644 --- a/core/module/theme/theme.php +++ b/core/module/theme/theme.php @@ -304,7 +304,7 @@ class theme extends common $this->isPost() ) { // Enregistre le CSS - file_put_contents(self::DATA_DIR . 'custom.css', $this->getInput('themeAdvancedCss', null)); + $this->secureFilePutContents(self::DATA_DIR . 'custom.css', $this->getInput('themeAdvancedCss', null)); // Valeurs en sortie $this->addOutput([ 'notification' => helper::translate('Modifications enregistrées'), @@ -1305,7 +1305,7 @@ class theme extends common } // Sauvegarder la chaîne modifiée if ($count > 0) { - file_put_contents($file, $data); + $this->secureFilePutContents($file, $data); } // Retourner le nombre d'occurrences return ($count); @@ -1411,8 +1411,8 @@ class theme extends common } // Enregistre la personnalisation - file_put_contents(self::DATA_DIR . 'font/font.html', $fileContent); + $this->secureFilePutContents(self::DATA_DIR . 'font/font.html', $fileContent); // Enregistre la personnalisation - file_put_contents(self::DATA_DIR . 'font/font.css', $fileContentCss); + $this->secureFilePutContents(self::DATA_DIR . 'font/font.css', $fileContentCss); } } \ No newline at end of file diff --git a/module/gallery/gallery.php b/module/gallery/gallery.php index b1559ce..77f6086 100644 --- a/module/gallery/gallery.php +++ b/module/gallery/gallery.php @@ -260,7 +260,7 @@ class gallery extends common $content = str_replace('#legendBgColor#', $this->getData(['module', $this->getUrl(0), 'theme', 'legendBgColor']), $content); // Ecriture de la feuille de style - file_put_contents(self::DATADIRECTORY . $this->getUrl(0) . '/theme.css', $content . $themeCss); + $this->secureFilePutContents(self::DATADIRECTORY . $this->getUrl(0) . '/theme.css', $content . $themeCss); // Nom de la feuille de style $this->setData(['module', $this->getUrl(0), 'theme', 'style', $fileCSS]); } @@ -894,7 +894,7 @@ class gallery extends common $content = str_replace('#legendHeight#', $this->getinput('galleryThemeLegendHeight'), $content); $content = str_replace('#legendTextColor#', $this->getinput('galleryThemeLegendTextColor'), $content); $content = str_replace('#legendBgColor#', $this->getinput('galleryThemeLegendBgColor'), $content); - $success = is_int(file_put_contents(self::DATADIRECTORY . $this->getUrl(0) . '/theme.css', $content . $themeCss)); + $success = is_int($this->secureFilePutContents(self::DATADIRECTORY . $this->getUrl(0) . '/theme.css', $content . $themeCss)); // Valeurs en sortie $this->addOutput([ 'redirect' => helper::baseUrl() . $this->getUrl() . '/theme', diff --git a/module/news/news.php b/module/news/news.php index 0d2c6ea..e4c284d 100644 --- a/module/news/news.php +++ b/module/news/news.php @@ -281,7 +281,7 @@ class news extends common mkdir(self::DATADIRECTORY . $this->getUrl(0) . '/theme.css', 0755, true); } - $success = is_int(file_put_contents(self::DATADIRECTORY . $this->getUrl(0) . '/theme.css', $style)); + $success = is_int($this->secureFilePutContents(self::DATADIRECTORY . $this->getUrl(0) . '/theme.css', $style)); // Fin feuille de style @@ -643,7 +643,7 @@ class news extends common $style .= '}'; // Sauver la feuille de style - file_put_contents(self::DATADIRECTORY . $this->getUrl(0) . '/theme.css', $style); + $this->secureFilePutContents(self::DATADIRECTORY . $this->getUrl(0) . '/theme.css', $style); // Stocker le nom de la feuille de style $this->setData(['module', $this->getUrl(0), 'theme', 'style', self::DATADIRECTORY . $this->getUrl(0) . '/theme.css']); } diff --git a/module/search/search.php b/module/search/search.php index 7d9842d..91a1af7 100644 --- a/module/search/search.php +++ b/module/search/search.php @@ -106,7 +106,7 @@ class search extends common // Générer la feuille de CSS $style = '.keywordColor {background: ' . $this->getData(['module', $this->getUrl(0), 'theme', 'keywordColor']) . ';}'; // Sauver la feuille de style - file_put_contents(self::DATADIRECTORY . $this->getUrl(0) . '/theme.css', $style); + $this->secureFilePutContents(self::DATADIRECTORY . $this->getUrl(0) . '/theme.css', $style); // Stocker le nom de la feuille de style $this->setData(['module', $this->getUrl(0), 'theme', 'style', $fileCSS]); } @@ -128,7 +128,7 @@ class search extends common // Générer la feuille de CSS $style = '.keywordColor {background:' . $this->getInput('searchKeywordColor') . ';}'; - $success = is_int(file_put_contents(self::DATADIRECTORY . $this->getUrl(0) . '/theme.css', $style)); + $success = is_int($this->secureFilePutContents(self::DATADIRECTORY . $this->getUrl(0) . '/theme.css', $style)); // Fin feuille de style // Soumission du formulaire