Commit f552d6bf authored by Nigel McNie's avatar Nigel McNie
Browse files

Handle slashes in file/folder paths, restrict names to 255 characters.

Both limits are of most underlying filesystems.
parent c5c02885
......@@ -28,7 +28,6 @@ defined('INTERNAL') || die();
/**
* TODO:
* - handle filenames with slashes
* - handle exporting when there's no files/folders
*/
class HtmlExportFile extends HtmlExportArtefactPlugin {
......@@ -101,15 +100,14 @@ class HtmlExportFile extends HtmlExportArtefactPlugin {
check_dir_exists($profileiconsdir);
}
// TODO: sanitise path for /'s
if (!copy($artefact->get_path(), $profileiconsdir . $artefact->get('title'))) {
if (!copy($artefact->get_path(), $profileiconsdir . PluginExportHtml::sanitise_path($artefact->get('title')))) {
throw new SystemException("Unable to copy profile icon $artefactid into export");
}
// Make sure we grab a nicely resized version too
$maxdimension = 200;
$resizedpath = get_dataroot_image_path('artefact/file/profileicons/', $artefactid, $maxdimension);
if (!copy($resizedpath, $profileiconsdir . $maxdimension . 'px-' . $artefact->get('title'))) {
if (!copy($resizedpath, $profileiconsdir . $maxdimension . 'px-' . PluginExportHtml::sanitise_path($artefact->get('title')))) {
throw new SystemException("Unable to copy resized profile icon {$maxdimension}px-{$artefact->get('title')} into export");
}
}
......@@ -138,14 +136,14 @@ class HtmlExportFile extends HtmlExportArtefactPlugin {
foreach ($this->artefactdata as $artefactid => $artefact) {
if ($artefact->get('parent') == $parentid) {
if ($artefact->get('artefacttype') == 'folder') {
$directory = $filesystemdirectory . $artefact->get('title') . '/';
$directory = $filesystemdirectory . PluginExportHtml::sanitise_path($artefact->get('title')) . '/';
check_dir_exists($directory);
$this->create_index_for_directory($directory, $level + 1, $artefact);
$this->populate_filedir($directory, $level + 1, $artefactid);
}
else {
$artefact = artefact_instance_from_id($artefactid);
if (!copy($artefact->get_path(), $filesystemdirectory . $artefact->get('title'))) {
if (!copy($artefact->get_path(), $filesystemdirectory . PluginExportHtml::sanitise_path($artefact->get('title')))) {
throw new SystemException("Unable to copy artefact $artefactid's file");
}
}
......@@ -205,6 +203,7 @@ class HtmlExportFile extends HtmlExportArtefactPlugin {
$data[] = array(
'icon' => '',
'title' => $artefact->get('title'),
'path' => PluginExportHtml::sanitise_path($artefact->get('title')),
'description' => $artefact->get('description'),
'size' => $size,
'date' => strftime(get_string('strftimedaydatetime'), $artefact->get('ctime')),
......@@ -213,6 +212,7 @@ class HtmlExportFile extends HtmlExportArtefactPlugin {
return $data;
}
}
?>
......@@ -30,7 +30,7 @@
{foreach from=$folders item=folder}
<tr class="r{cycle values=0,1}">
<td><img src="{$rootpath}static/file/theme/default/static/images/folder.gif" alt="{str tag=Folder section=artefact.file}"></td>
<td><a href="{$folder.title|rawurlencode|escape}/index.html">{$folder.title|escape}</a></td>
<td><a href="{$folder.path|rawurlencode|escape}/index.html">{$folder.title|escape}</a></td>
<td>{$folder.description|escape}</td>
<td>{$folder.size|escape}</td>
<td>{$folder.ctime|escape}</td>
......@@ -39,7 +39,7 @@
{foreach from=$files item=file}
<tr class="r{cycle values=0,1}">
<td><img src="{$rootpath}static/file/theme/default/static/images/file.gif" alt="{str tag=File section=artefact.file}"></td>
<td><a href="{$file.title|rawurlencode|escape}">{$file.title|escape}</a></td>
<td><a href="{$file.path|rawurlencode|escape}">{$file.title|escape}</a></td>
<td>{$file.description|escape}</td>
<td>{$file.size|escape}</td>
<td>{$file.ctime|escape}</td>
......
......@@ -233,16 +233,26 @@ class PluginExportHtml extends PluginExport {
}
/**
* Converts the passed text, which is assumed to be a reasonably short
* string, into a a form that could be used in a URL.
* Converts the passed text into a a form that could be used in a URL.
*
* @param string $text The text to convert
* @return string The converted text
*/
public static function text_to_path($text) {
return preg_replace('#[^a-zA-Z0-9_-]+#', '-', $text);
return substr(preg_replace('#[^a-zA-Z0-9_-]+#', '-', $text), 0, 255);
}
/**
* Sanitises a string meant to be used as a filesystem path.
*
* Mahara allows file/folder artefact names to have slashes in them, which
* aren't legal on most real filesystems.
*/
public static function sanitise_path($path) {
return substr(str_replace('/', '_', $path), 0, 255);
}
private function build_index_page($summaries) {
$smarty = $this->get_smarty();
$smarty->assign('page_heading', full_name($this->get('user')));
......@@ -491,7 +501,7 @@ class HtmlExportOutputFilter {
case 'file':
case 'image':
$folderpath = $this->get_path_for_file($artefact);
return '<a href="' . $this->basepath . '/files/file/' . $folderpath . $artefact->get('title') . '">' . $matches[5] . '</a>';
return '<a href="' . $this->basepath . '/files/file/' . $folderpath . PluginExportHtml::sanitise_path($artefact->get('title')) . '">' . $matches[5] . '</a>';
default:
return $matches[5];
}
......@@ -526,6 +536,9 @@ class HtmlExportOutputFilter {
private function get_path_for_file(ArtefactTypeFileBase $file) {
if ($this->folderdata === null) {
$this->folderdata = get_records_select_assoc('artefact', "artefacttype = 'folder' AND owner = ?", array($file->get('owner')));
foreach ($this->folderdata as &$folder) {
$folder->title = PluginExportHtml::sanitise_path($folder->title);
}
}
$folderpath = ArtefactTypeFileBase::get_full_path($file->get('parent'), $this->folderdata);
return $folderpath;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment