Merge pull request #1631 from JoelESvensson/develop

Files in the media library can now contain two dots
This commit is contained in:
Samuel Georges 2016-02-27 14:36:38 +11:00
commit 423360b2d2
3 changed files with 105 additions and 10 deletions

View File

@ -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.

View File

@ -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;
}

View File

@ -0,0 +1,55 @@
<?php
use Cms\Classes\MediaLibrary;
class MediaLibraryTest extends TestCase // @codingStandardsIgnoreLine
{
public function invalidPathsProvider()
{
return [
['./file'],
['../secret'],
['.../secret'],
['/../secret'],
['/.../secret'],
['/secret/..'],
['file/../secret'],
['file/..'],
['......./secret'],
['./file'],
];
}
public function validPathsProvider()
{
return [
['file'],
['folder/file'],
['/file'],
['/folder/file'],
['/.file'],
['/..file'],
['/...file'],
['file.ext'],
['file..ext'],
['file...ext'],
];
}
/**
* @dataProvider invalidPathsProvider
*/
public function testInvalidPathsOnValidatePath($path)
{
$this->setExpectedException('ApplicationException');
MediaLibrary::validatePath($path);
}
/**
* @dataProvider validPathsProvider
*/
public function testValidPathsOnValidatePath($path)
{
MediaLibrary::validatePath($path);
}
}