MDL-61724 resource: Unable to view or download file resource
authorMihail Geshoski <mihail@moodle.com>
Mon, 26 Mar 2018 03:14:46 +0000 (11:14 +0800)
committerMihail Geshoski <mihail@moodle.com>
Mon, 26 Mar 2018 03:14:46 +0000 (11:14 +0800)
lib/moodlelib.php
lib/tests/moodlelib_test.php
mod/folder/download_folder.php

index a8259ae..84e06a5 100644 (file)
@@ -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
index 454d9cc..87f59e8 100644 (file)
@@ -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();
index ef6d101..53d0005 100644 (file)
@@ -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)) {