From 8f1e2ff8a318e90c0cb4b28eff4dc70801d39c85 Mon Sep 17 00:00:00 2001 From: "Joel E. Svensson" Date: Wed, 2 Dec 2015 14:39:32 +0100 Subject: [PATCH 1/3] Files in the media library can now contain two dots --- modules/cms/classes/MediaLibrary.php | 37 ++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/modules/cms/classes/MediaLibrary.php b/modules/cms/classes/MediaLibrary.php index 2bfadb3ef..42fa3e968 100644 --- a/modules/cms/classes/MediaLibrary.php +++ b/modules/cms/classes/MediaLibrary.php @@ -125,9 +125,9 @@ class MediaLibrary /** * Finds files in the Library. * @param string $searchTerm Specifies the search term. - * @param string $sortBy Determines the sorting preference. + * @param string $sortBy Determines the sorting preference. * Supported values are 'title', 'size', 'lastModified' (see SORT_BY_XXX class constants). - * @param string $filter Determines the document type filtering preference. + * @param string $filter Determines the document type filtering preference. * Supported values are 'image', 'video', 'audio', 'document' (see FILE_TYPE_XXX constants of MediaLibraryItem class). * @return array Returns an array of MediaLibraryItem objects. */ @@ -384,10 +384,31 @@ class MediaLibrary if ($normalizeOnly) return $path; - if (strpos($path, '..') !== false) - throw new ApplicationException(Lang::get('cms::lang.media.invalid_path', ['path'=>$path])); + $regexDirectorySeparator = preg_quote(DIRECTORY_SEPARATOR, '/'); + $regexDot = preg_quote('.', '/'); + $regex = [ - if (strpos($path, './') !== false || strpos($path, '//') !== false) + /** + * Checks for parent or current directory reference at beginning of path + */ + '(^'.$regexDot.'+?'.$regexDirectorySeparator.')', + + /** + * Check for parent or current directory reference in middle of path + */ + '('.$regexDirectorySeparator.$regexDot.'+?'.$regexDirectorySeparator.')', + + /** + * Check for parent or current directory reference at end of path + */ + '('.$regexDirectorySeparator.$regexDot.'+?$)', + ]; + + /** + * Now, let's combine everything to one regex + */ + $regex = '/'.implode('|', $regex).'/'; + if (preg_match($regex, $path) !== 0 || strpos($path, '//') !== false) throw new ApplicationException(Lang::get('cms::lang.media.invalid_path', ['path'=>$path])); return $path; @@ -537,7 +558,7 @@ class MediaLibrary /** * Sorts the item list by title, size or last modified date. * @param array $itemList Specifies the item list to sort. - * @param string $sortBy Determines the sorting preference. + * @param string $sortBy Determines the sorting preference. * Supported values are 'title', 'size', 'lastModified' (see SORT_BY_XXX class constants). */ protected function sortItemList(&$itemList, $sortBy) @@ -567,7 +588,7 @@ class MediaLibrary /** * Filters item list by file type. * @param array $itemList Specifies the item list to sort. - * @param string $filter Determines the document type filtering preference. + * @param string $filter Determines the document type filtering preference. * Supported values are 'image', 'video', 'audio', 'document' (see FILE_TYPE_XXX constants of MediaLibraryItem class). */ protected function filterItemList(&$itemList, $filter) @@ -586,7 +607,7 @@ class MediaLibrary /** * Initializes and returns the Media Library disk. - * This method should always be used instead of trying to access the + * This method should always be used instead of trying to access the * $storageDisk property directly as initializing the disc requires * communicating with the remote storage. * @return mixed Returns the storage disk object. From ce0bbc988e591a9d3fa4b964e5d1ed1b2b43e185 Mon Sep 17 00:00:00 2001 From: "Joel E. Svensson" Date: Sun, 6 Dec 2015 19:02:51 +0100 Subject: [PATCH 2/3] Added tests for Cms\Classes\MediaLibrary::validatePath($path) --- tests/unit/cms/classes/MediaLibraryTest.php | 55 +++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 tests/unit/cms/classes/MediaLibraryTest.php diff --git a/tests/unit/cms/classes/MediaLibraryTest.php b/tests/unit/cms/classes/MediaLibraryTest.php new file mode 100644 index 000000000..5ce1ecb67 --- /dev/null +++ b/tests/unit/cms/classes/MediaLibraryTest.php @@ -0,0 +1,55 @@ +setExpectedException('ApplicationException'); + MediaLibrary::validatePath($path); + } + + /** + * @dataProvider validPathsProvider + */ + public function testValidPathsOnValidatePath($path) + { + MediaLibrary::validatePath($path); + } +} From ed583491e0b86339e0c612fac3e8776b2780d45c Mon Sep 17 00:00:00 2001 From: "Joel E. Svensson" Date: Sat, 23 Jan 2016 20:36:05 +0100 Subject: [PATCH 3/3] Fixes #1681 Added a customzied slug-function to MediaManager which supports @-signs --- modules/cms/widgets/MediaManager.php | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/modules/cms/widgets/MediaManager.php b/modules/cms/widgets/MediaManager.php index 2114c47e5..d84e07acb 100644 --- a/modules/cms/widgets/MediaManager.php +++ b/modules/cms/widgets/MediaManager.php @@ -945,6 +945,25 @@ class MediaManager extends WidgetBase } } + /** + * Creates a slug form the string. A modified version of Laravel's Str::slug + * with the main difference that it accepts @-signs + * @param string + * @return string + */ + public static function slug($string) + { + $title = Str::ascii($title); + // Convert all dashes/underscores into separator + $flip = $separator == '-' ? '_' : '-'; + $title = preg_replace('!['.preg_quote($flip).']+!u', $separator, $title); + // Remove all characters that are not the separator, letters, numbers, whitespace or @. + $title = preg_replace('![^'.preg_quote($separator).'\pL\pN\s@]+!u', '', mb_strtolower($title)); + // Replace all separator characters and whitespace by a single separator + $title = preg_replace('!['.preg_quote($separator).'\s]+!u', $separator, $title); + return trim($title, $separator); + } + protected function checkUploadPostback() { $fileName = null; @@ -973,7 +992,7 @@ class MediaManager extends WidgetBase * File name contains non-latin characters, attempt to slug the value */ if (!$this->validateFileName($fileName)) { - $fileNameSlug = Str::slug(File::name($fileName), '-'); + $fileNameSlug = static::slug(File::name($fileName), '-'); $fileName = $fileNameSlug.'.'.$extension; } @@ -1001,7 +1020,7 @@ class MediaManager extends WidgetBase protected function validateFileName($name) { - if (!preg_match('/^[0-9a-z\.\s_\-]+$/i', $name)) { + if (!preg_match('/^[0-9a-z@\.\s_\-]+$/i', $name)) { return false; }