%PDF- %PDF-
Direktori : /var/www/projetos/suporte.iigd.com.br/src/Toolbox/ |
Current File : /var/www/projetos/suporte.iigd.com.br/src/Toolbox/Filesystem.php |
<?php /** * --------------------------------------------------------------------- * * GLPI - Gestionnaire Libre de Parc Informatique * * http://glpi-project.org * * @copyright 2015-2024 Teclib' and contributors. * @copyright 2003-2014 by the INDEPNET Development Team. * @licence https://www.gnu.org/licenses/gpl-3.0.html * * --------------------------------------------------------------------- * * LICENSE * * This file is part of GLPI. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * * --------------------------------------------------------------------- */ namespace Glpi\Toolbox; final class Filesystem { /** * Checks if the file with given path can be written. * * @param string $path * * @return bool */ public static function canWriteFile(string $path): bool { if (file_exists($path)) { return is_writable($path); } // If the file does not exists, try to create it. $file = @fopen($path, 'c'); if ($file === false) { return false; } @fclose($file); // Remove the file, as presence of an empty file may not be handled properly. @unlink($path); return true; } /** * Checks if the files with given paths can be written. * * @param string[] $paths * * @return bool */ public static function canWriteFiles(array $paths): bool { foreach ($paths as $path) { if (!self::canWriteFile($path)) { return false; } } return true; } /** * Checks if the given file path is safe. * * @param string $path * @param string $restricted_directory * * @return bool */ public static function isFilepathSafe(string $path, ?string $restricted_directory = null): bool { $parsed_scheme = parse_url($path, PHP_URL_SCHEME); if ($parsed_scheme === 'file') { // If scheme is `file://`, parse the path again to validate that it does not contains itself // an unexpected scheme. $path = parse_url($path, PHP_URL_PATH); $parsed_scheme = parse_url($path, PHP_URL_SCHEME); } if ($parsed_scheme !== null && preg_match('/^[a-z]$/i', $parsed_scheme) !== 1) { // As soon as the path contains a scheme, it is not considered as safe, // unless the scheme is 1 letter (corresponds to a drive letter on Windows system). return false; } if ($restricted_directory === null) { // All directories are allowed. return true; } $restricted_directory = self::normalizePath($restricted_directory); if (!str_ends_with($restricted_directory, '/')) { // Ensure directory ends with a `/`, to prevent false positives: // - /path/to/dir/file is inside /path/to/dir // - /path/to/dir_file is not inside /path/to/dir $restricted_directory .= '/'; } return str_starts_with(self::normalizePath($path), $restricted_directory); } /** * Normalize a path, to make comparisons and relative paths computation easier. * * @param string $path * @return string */ private static function normalizePath(string $path): string { $realpath = realpath($path); if ($realpath !== false) { // Use realpath if possible (not always possible, for instance when file not exists). $path = $realpath; } // Normalize all directory separators to `/`. $path = preg_replace('/\\\/', '/', $path); return $path; } }