BUG Fixed critical issue with Folder::find_or_make failing to handle invalid filename characters

BUG Fix UploadField duplicate checking with invalid folderName
This commit is contained in:
Damian Mooyman 2014-02-20 14:03:40 +13:00
parent 429fdfaa72
commit ebeb663ddf
3 changed files with 36 additions and 12 deletions

View File

@ -57,20 +57,23 @@ class Folder extends File {
$parentID = 0; $parentID = 0;
$item = null; $item = null;
$filter = FileNameFilter::create();
foreach($parts as $part) { foreach($parts as $part) {
if(!$part) continue; // happens for paths with a trailing slash if(!$part) continue; // happens for paths with a trailing slash
$item = DataObject::get_one(
"Folder", // Ensure search includes folders with illegal characters removed, but
sprintf( // err in favour of matching existing folders if $folderPath
"\"Name\" = '%s' AND \"ParentID\" = %d", // includes illegal characters itself.
Convert::raw2sql($part), $partSafe = $filter->filter($part);
(int)$parentID $item = Folder::get()->filter(array(
) 'ParentID' => $parentID,
); 'Name' => array($partSafe, $part)
))->first();
if(!$item) { if(!$item) {
$item = new Folder(); $item = new Folder();
$item->ParentID = $parentID; $item->ParentID = $parentID;
$item->Name = $part; $item->Name = $partSafe;
$item->Title = $part; $item->Title = $part;
$item->write(); $item->write();
} }
@ -460,7 +463,7 @@ class Folder extends File {
* Get the children of this folder that are also folders. * Get the children of this folder that are also folders.
*/ */
public function ChildFolders() { public function ChildFolders() {
return DataObject::get("Folder", "\"ParentID\" = " . (int)$this->ID); return Folder::get()->filter('ParentID', $this->ID);
} }
/** /**

View File

@ -1273,11 +1273,15 @@ class UploadField extends FileField {
$nameFilter = FileNameFilter::create(); $nameFilter = FileNameFilter::create();
$filteredFile = basename($nameFilter->filter($originalFile)); $filteredFile = basename($nameFilter->filter($originalFile));
// Resolve expected folder name
$folderName = $this->getFolderName();
$folder = Folder::find_or_make($folderName);
$parentPath = BASE_PATH."/".$folder->getFilename();
// check if either file exists // check if either file exists
$folder = $this->getFolderName();
$exists = false; $exists = false;
foreach(array($originalFile, $filteredFile) as $file) { foreach(array($originalFile, $filteredFile) as $file) {
if(file_exists(ASSETS_PATH."/$folder/$file")) { if(file_exists($parentPath.$file)) {
$exists = true; $exists = true;
break; break;
} }

View File

@ -338,4 +338,21 @@ class FolderTest extends SapphireTest {
))->count()); ))->count());
} }
public function testIllegalFilenames() {
// Test that generating a filename with invalid characters generates a correctly named folder.
$folder = Folder::find_or_make('/FolderTest/EN_US Lang');
$this->assertEquals(ASSETS_DIR.'/FolderTest/EN-US-Lang/', $folder->getRelativePath());
// Test repeatitions of folder
$folder2 = Folder::find_or_make('/FolderTest/EN_US Lang');
$this->assertEquals($folder->ID, $folder2->ID);
$folder3 = Folder::find_or_make('/FolderTest/EN--US_L!ang');
$this->assertEquals($folder->ID, $folder3->ID);
$folder4 = Folder::find_or_make('/FolderTest/EN-US-Lang');
$this->assertEquals($folder->ID, $folder4->ID);
}
} }