From 87ed3a5c39f11ae0f6e1ad074f92e22e362b70e8 Mon Sep 17 00:00:00 2001 From: Davo Smith Date: Tue, 7 Feb 2012 07:26:54 +0000 Subject: [PATCH] MDL-31112 Repository upload - check for completely null files (likely to be folders uploaded by mistake via drag and drop) --- .../upload/lang/en/repository_upload.php | 1 + repository/upload/lib.php | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/repository/upload/lang/en/repository_upload.php b/repository/upload/lang/en/repository_upload.php index 614b2199e07ac..1d5664db3d445 100644 --- a/repository/upload/lang/en/repository_upload.php +++ b/repository/upload/lang/en/repository_upload.php @@ -34,3 +34,4 @@ $string['upload_error_no_tmp_dir'] = 'PHP is missing a temporary folder.'; $string['upload_error_cant_write'] = 'Failed to write file to disk.'; $string['upload_error_extension'] = 'A PHP extension stopped the file upload.'; +$string['upload_error_invalid_file'] = 'The file \'{$a}\' has no data in it - did you try to upload a folder?'; \ No newline at end of file diff --git a/repository/upload/lib.php b/repository/upload/lib.php index 823a68b52a3e0..e0ce43359f691 100644 --- a/repository/upload/lib.php +++ b/repository/upload/lib.php @@ -129,6 +129,12 @@ public function upload($saveas_filename, $maxbytes) { } } + // Check the file has some non-null contents - usually an indication that a user has + // tried to upload a folder by mistake + if (!$this->check_valid_contents($_FILES[$elname]['tmp_name'])) { + throw new moodle_exception('upload_error_invalid_file', 'repository_upload', '', $record->filename); + } + if ($this->mimetypes != '*') { // check filetype $filemimetype = mimeinfo('type', $_FILES[$elname]['name']); @@ -178,6 +184,32 @@ public function upload($saveas_filename, $maxbytes) { } } + /** + * Checks the contents of the given file is not completely NULL - this can happen if a + * user drags & drops a folder onto a filemanager / filepicker element + * @param filepath full path (including filename) to file to check + * @return true if file has at least one non-null byte within it + */ + protected function check_valid_contents($filepath) { + $buffersize = 4096; + + $fp = fopen($filepath, 'r'); + if (!$fp) { + return false; // Cannot read the file - something has gone wrong + } + while (!feof($fp)) { + // Read the file 4k at a time + $data = fread($fp, $buffersize); + if (preg_match('/[^\0]+/', $data)) { + fclose($fp); + return true; // Return as soon as a non-null byte is found + } + } + // Entire file is NULL + fclose($fp); + return false; + } + /** * Return a upload form * @return array