From d609207c3eda537a267ffb838297935a74582f73 Mon Sep 17 00:00:00 2001 From: Mihail Geshoski Date: Mon, 26 Mar 2018 11:14:46 +0800 Subject: [PATCH] MDL-61724 resource: Unable to view or download file resource --- lib/moodlelib.php | 44 +++++++++++++++++++++------------- lib/tests/moodlelib_test.php | 30 +++++++++++++++++------ mod/folder/download_folder.php | 2 +- 3 files changed, 51 insertions(+), 25 deletions(-) diff --git a/lib/moodlelib.php b/lib/moodlelib.php index a8259ae5eab..84e06a53a2a 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -442,7 +442,7 @@ define('FEATURE_USES_QUESTIONS', 'usesquestions'); /** * Maximum filename char size */ -define('MAX_FILENAME_SIZE', 90); +define('MAX_FILENAME_SIZE', 100); /** Unspecified module archetype */ define('MOD_ARCHETYPE_OTHER', 0); @@ -991,21 +991,6 @@ function clean_param($param, $type) { if ($param === '.' || $param === '..') { $param = ''; } - // Extract a part of the filename if it's char size exceeds MAX_FILENAME_SIZE. - // If the filename is too long, the file cannot be created on the filesystem due to exceeding max byte size. - // Limiting the filename to a certain size (considering multibyte characters) will prevent this. - if (core_text::strlen($param) > MAX_FILENAME_SIZE) { - // Exclude extension if present in filename. - $mimetypes = get_mimetypes_array(); - $extension = pathinfo($param, PATHINFO_EXTENSION); - if ($extension && !empty($mimetypes[$extension])) { - $basename = pathinfo($param, PATHINFO_FILENAME); - $param = core_text::substr($basename, 0, MAX_FILENAME_SIZE); - $param .= '.' . $extension; - } else { - $param = core_text::substr($param, 0, MAX_FILENAME_SIZE); - } - } return $param; case PARAM_PATH: @@ -6816,7 +6801,6 @@ function clean_filename($string) { return clean_param($string, PARAM_FILE); } - // STRING TRANSLATION. /** @@ -8261,6 +8245,32 @@ function shorten_text($text, $ideal=30, $exact = false, $ending='...') { return $truncate; } +/** + * Shortens a given filename by removing characters positioned after the ideal string length. + * When the filename is too long, the file cannot be created on the filesystem due to exceeding max byte size. + * Limiting the filename to a certain size (considering multibyte characters) will prevent this. + * + * @param string $filename file name + * @param int $length ideal string length + * @return string $shortened shortened file name + */ +function shorten_filename($filename, $length = MAX_FILENAME_SIZE) { + $shortened = $filename; + // Extract a part of the filename if it's char size exceeds the ideal string length. + if (core_text::strlen($filename) > $length) { + // Exclude extension if present in filename. + $mimetypes = get_mimetypes_array(); + $extension = pathinfo($filename, PATHINFO_EXTENSION); + if ($extension && !empty($mimetypes[$extension])) { + $basename = pathinfo($filename, PATHINFO_FILENAME); + $shortened = core_text::substr($basename, 0, $length); + $shortened .= '.' . $extension; + } else { + $shortened = core_text::substr($filename, 0, $length); + } + } + return $shortened; +} /** * Given dates in seconds, how many weeks is the date from startdate diff --git a/lib/tests/moodlelib_test.php b/lib/tests/moodlelib_test.php index 454d9cc1939..87f59e82233 100644 --- a/lib/tests/moodlelib_test.php +++ b/lib/tests/moodlelib_test.php @@ -682,13 +682,6 @@ class core_moodlelib_testcase extends advanced_testcase { $this->assertSame(' . .dontltrim.me', clean_param(' . .dontltrim.me', PARAM_FILE)); $this->assertSame('here is a tab.txt', clean_param("here is a tab\t.txt", PARAM_FILE)); $this->assertSame('here is a linebreak.txt', clean_param("here is a line\r\nbreak.txt", PARAM_FILE)); - // Test filename that contains more than 90 characters. - $filename = 'sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium totam rem'; - $this->assertSame('sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laud', - clean_param($filename, PARAM_FILE)); - // Filename contains extension. - $this->assertSame('sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laud.zip', - clean_param($filename . '.zip', PARAM_FILE)); // The following behaviours have been maintained although they seem a little odd. $this->assertSame('funnything', clean_param('funny:thing', PARAM_FILE)); @@ -1014,6 +1007,29 @@ class core_moodlelib_testcase extends advanced_testcase { shorten_text($text, 1)); } + public function test_shorten_filename() { + // Test filename that contains more than 100 characters. + $filename = 'sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium totam rem'; + $this->assertSame('sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium tot', + shorten_filename($filename)); + // Filename contains extension. + $this->assertSame('sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium tot.zip', + shorten_filename($filename . '.zip')); + // Limit filename to 50 chars. + $this->assertSame('sed ut perspiciatis unde omnis iste natus error si', + shorten_filename($filename, 50)); + $this->assertSame('sed ut perspiciatis unde omnis iste natus error si.zip', + shorten_filename($filename . '.zip', 50)); + + // Test filename that contains less than 100 characters. + $filename = 'sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque'; + $this->assertSame('sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque', + shorten_filename($filename)); + // Filename contains extension. + $this->assertSame('sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque.zip', + shorten_filename($filename . '.zip')); + } + public function test_usergetdate() { global $USER, $CFG, $DB; $this->resetAfterTest(); diff --git a/mod/folder/download_folder.php b/mod/folder/download_folder.php index ef6d101ce53..53d00053243 100644 --- a/mod/folder/download_folder.php +++ b/mod/folder/download_folder.php @@ -49,7 +49,7 @@ if (!$file) { } $zipper = get_file_packer('application/zip'); -$filename = clean_filename($folder->name . "-" . date("Ymd")) . ".zip"; +$filename = shorten_filename(clean_filename($folder->name . "-" . date("Ymd")) . ".zip"); $temppath = make_request_directory() . $filename; if ($zipper->archive_to_pathname(array('/' => $file), $temppath)) {