diff --git a/CHANGELOG.md b/CHANGELOG.md index 6817f9ecb..c01f5e75c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v1.5.3 +## mm/dd/2018 + +1. [](#new) + * Added `Utils::getMimeByFilename()`, `Utils::getMimeByLocalFile()` and `Utils::checkFilename()` methods + # v1.5.2 ## 10/01/2018 diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index 5de4fe7b1..83dd22480 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -478,6 +478,51 @@ abstract class Utils return $default; } + /** + * Return the mimetype based on filename + * + * @param string $filename Filename or path to file + * @param string $default default value + * + * @return string + */ + public static function getMimeByFilename($filename, $default = 'application/octet-stream') + { + return static::getMimeByExtension(pathinfo($filename, PATHINFO_EXTENSION), $default); + } + + /** + * Return the mimetype based on existing local file + * + * @param string $filename Path to the file + * + * @return string|bool + */ + public static function getMimeByLocalFile($filename, $default = 'application/octet-stream') + { + $type = false; + + // For local files we can detect type by the file content. + if (!stream_is_local($filename) || !file_exists($filename)) { + return false; + } + + // Prefer using finfo if it exists. + if (\extension_loaded('fileinfo')) { + $finfo = finfo_open(FILEINFO_SYMLINK | FILEINFO_MIME_TYPE); + $type = finfo_file($finfo, $filename); + finfo_close($finfo); + } else { + // Fall back to use getimagesize() if it is available (not recommended, but better than nothing) + $info = @getimagesize($filename); + if ($info) { + $type = $info['mime']; + } + } + + return $type ?: static::getMimeByFilename($filename, $default); + } + /** * Return the mimetype based on filename extension * @@ -520,6 +565,26 @@ abstract class Utils return $default; } + /** + * Returns true if filename is considered safe. + * + * @param string $filename + * @return bool + */ + public static function checkFilename($filename) + { + return !( + // Empty filenames are not allowed. + !$filename + // Filename should not contain horizontal/vertical tabs, newlines, nils or back/forward slashes. + || strtr($filename, "\t\v\n\r\0\\/", '_______') !== $filename + // Filename should not start or end with dot or space. + || trim($filename, '. ') !== $filename + // Filename should not contain .php in it. + || strpos($filename, '.php') !== false + ); + } + /** * Normalize path by processing relative `.` and `..` syntax and merging path *