diff --git a/file.php b/file.php index 1adac2ad366..8d1b13a43d9 100644 --- a/file.php +++ b/file.php @@ -1,111 +1,114 @@ - - * Syntax: file.php/courseid/dir/.../dir/filename.ext - * - * @uses $CFG - * @uses FORMAT_HTML - * @uses FORMAT_MOODLE - * @author Martin Dougiamas - * @version $Id$ - * @package moodlecore - */ - require_once('config.php'); require_once('files/mimetypes.php'); if (empty($CFG->filelifetime)) { - $CFG->filelifetime = 86400; /// Seconds for files to remain in caches - } - - if (isset($file)) { // workaround for situations where / syntax doesn't work - $pathinfo = $file; + $lifetime = 86400; // Seconds for files to remain in caches } else { - $pathinfo = get_slash_arguments('file.php'); + $lifetime = $CFG->filelifetime; + } + + + $relativepath = get_file_argument('file.php'); + + // relative path must start with '/', because of backup/restore!!! + if (!$relativepath) { + error('No valid arguments supplied or incorrect server configuration'); + } else if ($relativepath{0} != '/') { + error('No valid arguments supplied, path does not start with slash!'); } - if (!$pathinfo) { - error('No file parameters!'); - } + $pathname = $CFG->dataroot.$relativepath; - $pathinfo = urldecode($pathinfo); - - if (! $args = parse_slash_arguments($pathinfo)) { + // extract relative path components + $args = explode('/', trim($relativepath, '/')); + if (count($args) == 0) { // always at least courseid, may search for index.html in course root error('No valid arguments supplied'); } - $numargs = count($args); - if ($numargs < 2 or empty($args[1])) { - error('No valid arguments supplied'); - } - - $courseid = (integer)$args[0]; - - if (!$course = get_record('course', 'id', $courseid)) { // Course ID must be specified + // security: limit access to existing course subdirectories + // note: course ID must be specified + // note: the lang field is needed for the course language switching hack in weblib.php + if (!$course = get_record_sql("SELECT id, lang FROM {$CFG->prefix}course WHERE id='".(int)$args[0]."'")) { error('Invalid course ID'); } - if ($course->category) { - require_login($courseid); + // security: prevent access to "000" or "1 something" directories + if ($args[0] != $course->id) { + error('Invalid course ID'); + } + + // security: login to course if necessary + if ($course->id != SITEID) { + require_login($course->id); } else if ($CFG->forcelogin) { require_login(); } - $pathname = $CFG->dataroot . $pathinfo; - if ($pathargs = explode('?', $pathname)) { - $pathname = $pathargs[0]; // Only keep what's before the '?' - } - $filename = $args[$numargs-1]; - if ($fileargs = explode('?', $filename)) { - $filename = $fileargs[0]; // Only keep what's before the '?' + // security: only editing teachers can access backups + if ((!isteacheredit($course->id)) + and (count($args) >= 2) + and (strtolower($args[1]) == 'backupdata')) { + + error('Access not allowed'); } - if (file_exists($pathname)) { - $lastmodified = filemtime($pathname); - $mimetype = mimeinfo('type', $filename); + // security: teachers can view all assignments, students only their own + if ((count($args) >= 3) + and (strtolower($args[1]) == 'moddata') + and (strtolower($args[2]) == 'assignment')) { - header('Last-Modified: ' . gmdate("D, d M Y H:i:s", $lastmodified) . ' GMT'); - header('Expires: ' . gmdate("D, d M Y H:i:s", time() + $CFG->filelifetime) . ' GMT'); - header('Cache-control: max_age = '. $CFG->filelifetime); - header('Pragma: '); - header('Content-disposition: inline; filename='. $filename); - - - if (empty($CFG->filteruploadedfiles)) { - header('Content-length: '. filesize($pathname)); - header('Content-type: '. $mimetype); - readfile($pathname); - - } else { /// Try and put the file through filters - if ($mimetype == 'text/html') { - $options->noclean = true; - $output = format_text(implode('', file($pathname)), FORMAT_HTML, $options, $courseid); - - header('Content-length: '. strlen($output)); - header('Content-type: text/html'); - echo $output; - - } else if ($mimetype == 'text/plain') { - $options->newlines = false; - $options->noclean = true; - $output = '
'. format_text(implode('', file($pathname)), FORMAT_MOODLE, $options, $courseid) .'
'; - header('Content-length: '. strlen($output)); - header('Content-type: text/html'); - echo $output; - - } else { /// Just send it out raw - header('Content-length: '. filesize($pathname)); - header('Content-type: '. $mimetype); - readfile($pathname); - } + $lifetime = 0; // do not cache assignments, students may reupload them + if ((!isteacher($course->id)) && (count($args) != 6 || $args[4] != $USER->id)) { + error('Access not allowed'); } - } else { - header('HTTP/1.0 404 not found'); - error(get_string('filenotfound', 'error'), $CFG->wwwroot .'/course/view.php?id='. $courseid); } - exit; -?> \ No newline at end of file + if (is_dir($pathname)) { + if (file_exists($pathname.'/index.html')) { + $pathname = rtrim($pathname, '/').'/index.html'; + $args[] = 'index.html'; + } else if (file_exists($pathname.'/index.htm')) { + $pathname = rtrim($pathname, '/').'/index.htm'; + $args[] = 'index.htm'; + } else if (file_exists($pathname.'/Default.htm')) { + $pathname = rtrim($pathname, '/').'/Default.htm'; + $args[] = 'Default.htm'; + } else { + // security: do not return directory node! + not_found($course->id); + } + } + + // check that file exists + if (!file_exists($pathname)) { + not_found($course->id); + } + + // extra security: keep symbolic links inside dataroot/courseid if required + /*if (!empty($CFG->checksymlinks)) { + $realpath = realpath($pathname); + $realdataroot = realpath($CFG->dataroot.'/'.$course->id); + if (strpos($realpath, $realdataroot) !== 0) { + not_found($course->id); + } + }*/ + + // ======================================== + // finally send the file + // ======================================== + $filename = $args[count($args)-1]; + send_file($pathname, $filename, $lifetime, !empty($CFG->filteruploadedfiles)); + + function not_found($courseid) { + global $CFG; + header('HTTP/1.0 404 not found'); + error(get_string('filenotfound', 'error'), $CFG->wwwroot.'/course/view.php?id='.$courseid); //this is not displayed on IIS?? + } +?> diff --git a/files/mimetypes.php b/files/mimetypes.php index d1b74894feb..60a5bc7119a 100644 --- a/files/mimetypes.php +++ b/files/mimetypes.php @@ -79,7 +79,7 @@ function mimeinfo($element, $filename) { ); if (eregi("\.([a-z0-9]+)$", $filename, $match)) { - if(isset($mimeinfo[strtolower($match[1])][$element])) { + if (isset($mimeinfo[strtolower($match[1])][$element])) { return $mimeinfo[strtolower($match[1])][$element]; } else { return $mimeinfo["xxx"][$element]; // By default @@ -89,4 +89,68 @@ function mimeinfo($element, $filename) { } } +function send_file($path, $filename, $lifetime=86400 , $filter=false, $pathisstring=false) { + + $mimetype = mimeinfo('type', $filename); + $lastmodified = $pathisstring ? time() : filemtime($path); + $filesize = $pathisstring ? strlen($path) : filesize($path); + + @header('Last-Modified: '. gmdate("D, d M Y H:i:s", $lastmodified) .' GMT'); + if ($lifetime > 0) { + @header('Cache-control: max-age='.$lifetime); + @header('Expires: '. gmdate("D, d M Y H:i:s", time() + $lifetime) .'GMT'); + @header('Pragma: '); + } else { + // this part is tricky, displaying of MS Office documents in IE needs + // to store the file on disk, but no-cache may prevent it + @header('Cache-Control: private, must-revalidate, pre-check=0, post-check=0, max-age=10'); + @header('Expires: '. gmdate("D, d M Y H:i:s", 0) .'GMT'); + @header('Pragma: no-cache'); + } + @header('Accept-Ranges: none'); // PDF compatibility + @header('Content-disposition: inline; filename='.$filename); + + if (!$filter) { + @header('Content-length: '.$filesize); + if ($mimetype == 'text/plain') { + @header('Content-type: text/plain; charset='.get_string('thischarset')); //add encoding + } else { + @header('Content-type: '.$mimetype); + } + if ($pathisstring) { + echo $path; + }else { + readfile($path); + } + } else { // Try to put the file through filters + if ($mimetype == 'text/html') { + $options->noclean = true; + $text = $pathisstring ? $path : implode('', file($path)); + $output = format_text($text, FORMAT_HTML, $options, $course->id); + + @header('Content-length: '.strlen($output)); + @header('Content-type: text/html'); + echo $output; + } else if ($mimetype == 'text/plain') { + $options->newlines = false; + $options->noclean = true; + $text = htmlentities($pathisstring ? $path : implode('', file($path))); + $output = '
'. format_text($text, FORMAT_MOODLE, $options, $course->id) .'
'; + + @header('Content-length: '.strlen($output)); + @header('Content-type: text/html; charset='. get_string('thischarset')); //add encoding + echo $output; + } else { // Just send it out raw + @header('Content-length: '.$filesize); + @header('Content-type: '.$mimetype); + if ($pathisstring) { + echo $path; + }else { + readfile($path); + } + } + } + die; //no more chars to output!!! +} + ?> diff --git a/filter/algebra/pix.php b/filter/algebra/pix.php index a2e027292be..e70fd3afcab 100644 --- a/filter/algebra/pix.php +++ b/filter/algebra/pix.php @@ -5,43 +5,34 @@ $nomoodlecookie = true; // Because it interferes with caching - require_once("../../config.php"); + require_once('../../config.php'); + require_once('../../files/mimetypes.php'); - $CFG->algebrafilterdir = "filter/algebra"; - $CFG->texfilterdir = "filter/tex"; - $CFG->algebraimagedir = "filter/algebra"; + $CFG->texfilterdir = 'filter/tex'; + $CFG->algebrafilterdir = 'filter/algebra'; + $CFG->algebraimagedir = 'filter/algebra'; - $cmd = ''; // Initialise these variables + + $cmd = ''; // Initialise these variables $status = ''; - error_reporting(E_ALL); + //error_reporting(E_ALL); - $lifetime = 86400; - if (isset($file)) { // workaround for situations where / syntax doesn't work - $pathinfo = '/' . $file; + $relativepath = get_file_argument('pix.php'); + + $args = explode('/', trim($relativepath, '/')); + + if (count($args) == 1) { + $image = $args[0]; + $pathname = $CFG->dataroot.'/'.$CFG->algebraimagedir.'/'.$image; } else { - $pathinfo = get_slash_arguments("pix.php"); + error('No valid arguments supplied'); } - if (! $args = parse_slash_arguments($pathinfo)) { - error("No valid arguments supplied"); - } - - $numargs = count($args); - - if ($numargs == 1) { - $image = $args[0]; - $pathname = "$CFG->dataroot/$CFG->algebraimagedir/$image"; - $filetype = "image/gif"; - } else { - error("No valid arguments supplied"); - } - - if (!file_exists($pathname)) { $md5 = str_replace('.gif','',$image); - if ($texcache = get_record("cache_filters", "filter", "algebra", "md5key", $md5)) { - if (!file_exists("$CFG->dataroot/$CFG->algebraimagedir")) { + if ($texcache = get_record('cache_filters', 'filter', 'algebra', 'md5key', $md5)) { + if (!file_exists($CFG->dataroot.'/'.$CFG->algebraimagedir)) { make_upload_directory($CFG->algebraimagedir); } @@ -59,7 +50,7 @@ } else if (is_executable("$CFG->dirroot/$CFG->texfilterdir/mimetex")) { /// Use the custom binary $cmd = "$CFG->dirroot/$CFG->texfilterdir/mimetex -e $pathname ". escapeshellarg($texexp); - + } else { /// Auto-detect the right TeX binary switch (PHP_OS) { @@ -72,12 +63,17 @@ break; default: /// Nothing was found, so tell them how to fix it. - echo "Make sure you have an appropriate MimeTeX binary here:\n\n"; - echo " $CFG->dirroot/$CFG->texfilterdir/mimetex\n\n"; - echo "and that it has the right permissions set on it as executable program.\n\n"; - echo "You can get the latest binaries for your ".PHP_OS." platform from: \n\n"; - echo " http://moodle.org/download/mimetex/"; - exit; + if ($CFG->debug > 7) { + echo "Make sure you have an appropriate MimeTeX binary here:\n\n"; + echo " $CFG->dirroot/$CFG->texfilterdir/mimetex\n\n"; + echo "and that it has the right permissions set on it as executable program.\n\n"; + echo "You can get the latest binaries for your ".PHP_OS." platform from: \n\n"; + echo " http://moodle.org/download/mimetex/"; + } else { + echo "Mimetex executable was not found,\n"; + echo "Please turn on debug mode in site configuration to see more info here."; + } + die; break; } } @@ -86,20 +82,16 @@ } if (file_exists($pathname)) { - $lastmodified = filemtime($pathname); - header("Last-Modified: " . gmdate("D, d M Y H:i:s", $lastmodified) . " GMT"); - header("Expires: " . gmdate("D, d M Y H:i:s", time() + $lifetime) . " GMT"); - header("Cache-control: max_age = $lifetime"); // a day - header("Pragma: "); - header("Content-disposition: inline; filename=$image"); - header("Content-length: ".filesize($pathname)); - header("Content-type: $filetype"); - readfile("$pathname"); + send_file($pathname, $image); } else { - echo "The shell command
$cmd
returned status = $status
\n"; - echo "Image not found!
"; - echo "Please try the wwwroot/filter/algebra/algebradebug.php\">debugging script"; + if ($CFG->debug > 7) { + echo "The shell command
$cmd
returned status = $status
\n"; + echo "Image not found!
"; + echo "Please try the wwwroot/$CFG->algebrafilterdir/algebradebug.php\">debugging script"; + } else { + echo "Image not found!
"; + echo "Please try the wwwroot/$CFG->algebrafilterdir/algebradebug.php\">debugging script
"; + echo "Please turn on debug mode in site configuration to see more info here."; + } } - - exit; ?> diff --git a/filter/tex/pix.php b/filter/tex/pix.php index cc7304c0848..1928fb73a8c 100644 --- a/filter/tex/pix.php +++ b/filter/tex/pix.php @@ -5,42 +5,33 @@ $nomoodlecookie = true; // Because it interferes with caching - require_once("../../config.php"); + require_once('../../config.php'); + require_once('../../files/mimetypes.php'); - $CFG->texfilterdir = "filter/tex"; - $CFG->teximagedir = "filter/tex"; + $CFG->texfilterdir = 'filter/tex'; + $CFG->teximagedir = 'filter/tex'; - $cmd = ''; // Initialise these variables + + $cmd = ''; // Initialise these variables $status = ''; - error_reporting(E_ALL); + //error_reporting(E_ALL); - $lifetime = 86400; - if (isset($file)) { // workaround for situations where / syntax doesn't work - $pathinfo = '/' . $file; + $relativepath = get_file_argument('pix.php'); + + $args = explode('/', trim($relativepath, '/')); + + if (count($args) == 1) { + $image = $args[0]; + $pathname = $CFG->dataroot.'/'.$CFG->teximagedir.'/'.$image; } else { - $pathinfo = get_slash_arguments("pix.php"); + error('No valid arguments supplied'); } - if (! $args = parse_slash_arguments($pathinfo)) { - error("No valid arguments supplied"); - } - - $numargs = count($args); - - if ($numargs == 1) { - $image = $args[0]; - $pathname = "$CFG->dataroot/$CFG->teximagedir/$image"; - $filetype = "image/gif"; - } else { - error("No valid arguments supplied"); - } - - if (!file_exists($pathname)) { $md5 = str_replace('.gif','',$image); - if ($texcache = get_record("cache_filters", "filter", "tex", "md5key", $md5)) { - if (!file_exists("$CFG->dataroot/$CFG->teximagedir")) { + if ($texcache = get_record('cache_filters', 'filter', 'tex', 'md5key', $md5)) { + if (!file_exists($CFG->dataroot.'/'.$CFG->teximagedir)) { make_upload_directory($CFG->teximagedir); } @@ -58,7 +49,7 @@ } else if (is_executable("$CFG->dirroot/$CFG->texfilterdir/mimetex")) { /// Use the custom binary $cmd = "$CFG->dirroot/$CFG->texfilterdir/mimetex -e $pathname ". escapeshellarg($texexp); - + } else { /// Auto-detect the right TeX binary switch (PHP_OS) { @@ -71,12 +62,17 @@ break; default: /// Nothing was found, so tell them how to fix it. - echo "Make sure you have an appropriate MimeTeX binary here:\n\n"; - echo " $CFG->dirroot/$CFG->texfilterdir/mimetex\n\n"; - echo "and that it has the right permissions set on it as executable program.\n\n"; - echo "You can get the latest binaries for your ".PHP_OS." platform from: \n\n"; - echo " http://moodle.org/download/mimetex/"; - exit; + if ($CFG->debug > 7) { + echo "Make sure you have an appropriate MimeTeX binary here:\n\n"; + echo " $CFG->dirroot/$CFG->texfilterdir/mimetex\n\n"; + echo "and that it has the right permissions set on it as executable program.\n\n"; + echo "You can get the latest binaries for your ".PHP_OS." platform from: \n\n"; + echo " http://moodle.org/download/mimetex/"; + } else { + echo "Mimetex executable was not found,\n"; + echo "Please turn on debug mode in site configuration to see more info here."; + } + die; break; } } @@ -85,20 +81,16 @@ } if (file_exists($pathname)) { - $lastmodified = filemtime($pathname); - header("Last-Modified: " . gmdate("D, d M Y H:i:s", $lastmodified) . " GMT"); - header("Expires: " . gmdate("D, d M Y H:i:s", time() + $lifetime) . " GMT"); - header("Cache-control: max_age = $lifetime"); // a day - header("Pragma: "); - header("Content-disposition: inline; filename=$image"); - header("Content-length: ".filesize($pathname)); - header("Content-type: $filetype"); - readfile("$pathname"); + send_file($pathname, $image); } else { - echo "The shell command
$cmd
returned status = $status
\n"; - echo "Image not found!
"; - echo "Please try the wwwroot/$CFG->texfilterdir/texdebug.php\">debugging script"; + if ($CFG->debug > 7) { + echo "The shell command
$cmd
returned status = $status
\n"; + echo "Image not found!
"; + echo "Please try the wwwroot/$CFG->texfilterdir/texdebug.php\">debugging script"; + } else { + echo "Image not found!
"; + echo "Please try the wwwroot/$CFG->texfilterdir/texdebug.php\">debugging script
"; + echo "Please turn on debug mode in site configuration to see more info here."; + } } - - exit; ?> diff --git a/mod/quiz/lib.php b/mod/quiz/lib.php index 47e507337de..c38beedf1bd 100644 --- a/mod/quiz/lib.php +++ b/mod/quiz/lib.php @@ -965,6 +965,10 @@ function quiz_print_possible_question_image($quizid, $question) { global $CFG; + if ($quizid == '') { + $quizid = '0'; + } + if ($question->image) { echo 'filelifetime)) { + $lifetime = 86400; // Seconds for files to remain in caches } else { - $pathinfo = get_slash_arguments("file.php"); + $lifetime = $CFG->filelifetime; + } + + $relativepath = get_file_argument('quizfile.php'); + + if (!$relativepath) { + error('No valid arguments supplied or incorrect server configuration'); + } + + // extract relative path components + $args = explode('/', trim($relativepath, '/')); + if (count($args) < 3) { // always at least category, question and path + error('No valid arguments supplied'); + } + + $quizid = (int)array_shift($args); + $questionid = (int)array_shift($args); + $relativepath = implode ('/', $args); + + if (!($question = get_record('quiz_questions', 'id', $questionid))) { + error('No valid arguments supplied'); } - if (!$pathinfo) { - error("No file parameters!"); + if (!($questioncategory = get_record('quiz_categories', 'id', $question->category))) { + error('No valid arguments supplied'); } ///////////////////////////////////// - // Extract info from $pathinfo + // Check access ///////////////////////////////////// - - $idreg = '[0-9]+'; - if (!ereg("^/?($idreg)/($idreg)/((.+/)?([^/]+))$", - $pathinfo, - $regs) ) { - error("File parameters are badly formated"); - } - if (! ($quiz = get_record('quiz', 'id', $regs[1]))) { - error("No valid quiz supplied"); - } - if (! ($question = get_record('quiz_questions', 'id', $regs[2]))) { - error("No valid question supplied"); - } - if (! ($relativefilepath = $regs[3])) { - error("No valid file path supplied"); - } - if (! ($filename = $regs[5])) { - error("No valid file name supplied"); - } - if (detect_munged_arguments($relativefilepath)) { - error("Errors in the supplied file path"); - } - - ////////////////////////////////////////// - // Info from $pathinfo is now extracted! - // Now check the user's persmissions on this quiz... - ////////////////////////////////////////// - - if (! ($course = get_record("course", "id", $quiz->course))) { - error("Supplied quiz $quiz->name does not belong to a valid course"); - } - - require_login($course->id); - - // For now, let's not worry about this. The following check causes - // problems sometimes when reviewing a quiz - //if (!isteacher($course->id) - // and !quiz_get_user_attempt_unfinished($quiz->id, $USER->id) - // and ! ($quiz->review && time() > $quiz->timeclose) - // || !quiz_get_user_attempts($quiz->id, $USER->id) ) - //{ - // error("Logged-in user is not allowed to view this quiz"); - //} - - /////////////////////////////////////////////////// - // The logged-in user has the right to view material on this quiz! - // Now verify the consistency between $quiz, $question, its category and $relativepathname - /////////////////////////////////////////////////// - - // For now, let's not worry about this. The following check doesn't - // work for randomly selected questions and it gets complicated - //if (!in_array($question->id, explode(',', $quiz->questions), FALSE)) { - // error("Specified question is not on the specified quiz"); - //} - - if (! ($questioncategory = get_record('quiz_categories', 'id', - $question->category))) - { - error("Question category is not valid"); + if ($quizid == 0) { // teache doing preview during quiz creation + if ($questioncategory->publish) { + require_login(); + if (!isteacher()) { + error('No valid arguments supplied'); + } + } else { + require_login($questioncategory->course); + if (!isteacher($questioncategory->course)) { + error('Access not allowed'); + } + } + } else { + if (!($quiz = get_record('quiz', 'id', $quizid))) { + error('No valid arguments supplied'); + } + if (!($course = get_record('course', 'id', $quiz->course))) { + error('No valid arguments supplied'); + } + require_login($course->id); + + // For now, let's not worry about this. The following check causes + // problems sometimes when reviewing a quiz + //if (!isteacher($course->id) + // and !quiz_get_user_attempt_unfinished($quiz->id, $USER->id) + // and ! ($quiz->review && time() > $quiz->timeclose) + // || !quiz_get_user_attempts($quiz->id, $USER->id) ) + //{ + // error("Logged-in user is not allowed to view this quiz"); + //} + + /////////////////////////////////////////////////// + // The logged-in user has the right to view material on this quiz! + // Now verify the consistency between $quiz, $question, its category and $relativepathname + /////////////////////////////////////////////////// + + // For now, let's not worry about this. The following check doesn't + // work for randomly selected questions and it gets complicated + //if (!in_array($question->id, explode(',', $quiz->questions), FALSE)) { + // error("Specified question is not on the specified quiz"); + //} } // Have the question check whether it uses this file or not if (!$QUIZ_QTYPES[$question->qtype]->uses_quizfile($question, - $relativefilepath)) { + $relativepath)) { error("The specified file path is not on the specified question"); } @@ -95,35 +95,14 @@ // Specified file can now be returned... ////////////////////////////////////////// - $pathname = "$CFG->dataroot/$questioncategory->course/$relativefilepath"; - // $filename has already been extracted + $pathname = "$CFG->dataroot/$questioncategory->course/$relativepath"; + $filename = $args[count($args)-1]; - ///////////////////////////////////////////////////////////////// - // The remaining code is identical to the final lines of file.php - // If you ask me - this stuff should be separated into a separate - // function for conviency. - // That function would find itself very in comfortable in the - // file mimetypes.php - ////////////////////////////////// - - $mimetype = mimeinfo("type", $filename); - if (file_exists($pathname)) { - $lastmodified = filemtime($pathname); - - header("Last-Modified: " . gmdate("D, d M Y H:i:s", $lastmodified) . " GMT"); - header("Expires: " . gmdate("D, d M Y H:i:s", time() + $lifetime) . " GMT"); - header("Cache-control: max_age = $lifetime"); // a day - header("Pragma: "); - header("Content-disposition: inline; filename=$filename"); - header("Content-length: ".filesize($pathname)); - header("Content-type: $mimetype"); - readfile("$pathname"); + send_file($pathname, $filename, $lifetime); } else { - error("Sorry, but the file you are looking for was not found (".clean_text($pathname).")", - "course/view.php?id=$courseid"); + header('HTTP/1.0 404 not found'); + error(get_string('filenotfound', 'error')); //this is not displayed on IIS?? } - - exit; ?> diff --git a/rss/file.php b/rss/file.php index c2fd872ee29..eb169a5e22b 100644 --- a/rss/file.php +++ b/rss/file.php @@ -1,10 +1,10 @@ -dirroot/files/mimetypes.php"); + $nomoodlecookie = true; // Because it interferes with caching + + require_once('../config.php'); + require_once('../files/mimetypes.php'); + require_once('rsslib.php'); - $allowed = true; - $error = false; - if (empty($CFG->filelifetime)) { - $CFG->filelifetime = 86400; /// Seconds for files to remain in caches + $lifetime = 3600; // Seconds for files to remain in caches - 1 hour + + $relativepath = get_file_argument('file.php'); + + if (!$relativepath) { + not_found(); } - if (isset($file)) { // workaround for situations where / syntax doesn't work - $pathinfo = $file; - } else { - $pathinfo = get_slash_arguments("file.php"); + // extract relative path components + $args = explode('/', trim($relativepath, '/')); + + if (count($args) < 4) { + not_found(); } - if (!$pathinfo) { - $error = true; + $courseid = (int)$args[0]; + $userid = (int)$args[1]; + $modulename = clean_param($args[2], PARAM_FILE); + $instance = (int)$args[3]; + + if (!$course = get_record("course", "id", $courseid)) { + not_found(); } - - $pathinfo = urldecode($pathinfo); - - if (! $args = parse_slash_arguments($pathinfo)) { - $error = true; - } - - $numargs = count($args); - if ($numargs < 5 or empty($args[1])) { - $error = true; - } - - $courseid = (integer)$args[0]; - $userid = (integer)$args[1]; - $modulename = $args[2]; - $instance = (integer)$args[3]; - + //Check name of module $mods = get_list_of_plugins("mod"); if (!in_array(strtolower($modulename), $mods)) { - error("This module doesn't exist!"); - } - - if (! $course = get_record("course", "id", $courseid)) { - $error = true; + not_found(); } //Get course_module to check it's visible - if (! $cm = get_coursemodule_from_instance($modulename,$instance,$courseid)) { - $error = true; + if (!$cm = get_coursemodule_from_instance($modulename,$instance,$courseid)) { + not_found(); } - $cmvisible = $cm->visible; $isstudent = isstudent($courseid,$userid); $isteacher = isteacher($courseid,$userid); //Check for "security" if !course->guest or course->password - if (!$course->guest || $course->password) { - $allowed = ($isstudent || $isteacher); + if ((!$course->guest || $course->password) && (!($isstudent || $isteacher))) { + not_found(); } //Check for "security" if the course is hidden or the activity is hidden - if ($allowed && (!$course->visible || !$cmvisible)) { - $allowed = $isteacher; + if ((!$course->visible || !$cm->visible) && (!$isteacher)) { + not_found(); } - $pathname = $CFG->dataroot."/rss/".$modulename."/".$instance.".xml"; - $filename = $args[$numargs-1]; + $filename = $instance.'.xml';; + $pathname = $CFG->dataroot.'/rss/'.$modulename.'/'.$filename; - //If the file exists and its allowed for me, download it! - if (file_exists($pathname) && $allowed && !$error) { - $lastmodified = filemtime($pathname); - $mimetype = mimeinfo("type", $filename); - - header("Last-Modified: " . gmdate("D, d M Y H:i:s", $lastmodified) . " GMT"); - header("Expires: " . gmdate("D, d M Y H:i:s", time() + $CFG->filelifetime) . " GMT"); - header("Cache-control: max_age = $CFG->filelifetime"); - header("Pragma: "); - header("Content-disposition: inline; filename=$filename"); - - header("Content-length: ".filesize($pathname)); - header("Content-type: $mimetype"); - readfile($pathname); + //Check that file exists + if (!file_exists($pathname)) { + not_found(); } + //Send it to user! + send_file($pathname, $filename, $lifetime); + + function not_found() { + /// error, send some XML with error message + global $lifetime; + send_file(rss_geterrorxmlfile(), 'rsserror.xml', $lifetime, false, true); + } ?> diff --git a/user/pix.php b/user/pix.php index 1e649b4fb48..bc3ab4cf2ae 100644 --- a/user/pix.php +++ b/user/pix.php @@ -5,45 +5,26 @@ $nomoodlecookie = true; // Because it interferes with caching - require_once("../config.php"); + require_once('../config.php'); + require_once('../files/mimetypes.php'); - $lifetime = 86400; + $relativepath = get_file_argument('pix.php'); - if (isset($file)) { // workaround for situations where / syntax doesn't work - $pathinfo = $file; + $args = explode('/', trim($relativepath, '/')); + if (count($args) == 2) { + $userid = (integer)$args[0]; + $image = $args[1]; + $pathname = $CFG->dataroot.'/users/'.$userid.'/'.$image; } else { - $pathinfo = get_slash_arguments("pix.php"); + $image = 'f1.png'; + $pathname = $CFG->dirroot.'/pix/u/f1.png'; } - if (! $args = parse_slash_arguments($pathinfo)) { - error("No valid arguments supplied"); - } - - $numargs = count($args); - - if ($numargs == 2) { - $userid = (integer)$args[0]; - $image = $args[1]; - $pathname = "$CFG->dataroot/users/$userid/$image"; - $filetype = "image/jpeg"; + if (file_exists($pathname) and !is_dir($pathname)) { + send_file($pathname, $image); } else { - $image = "f1.png"; - $pathname = "$CFG->dirroot/pix/u/f1.png"; - $filetype = "image/png"; + header('HTTP/1.0 404 not found'); + error(get_string('filenotfound', 'error')); //this is not displayed on IIS?? } - - if (file_exists($pathname)) { - $lastmodified = filemtime($pathname); - header("Last-Modified: " . gmdate("D, d M Y H:i:s", $lastmodified) . " GMT"); - header("Expires: " . gmdate("D, d M Y H:i:s", time() + $lifetime) . " GMT"); - header("Cache-control: max_age = $lifetime"); // a day - header("Pragma: "); - header("Content-disposition: inline; filename=$image"); - header("Content-length: ".filesize($pathname)); - header("Content-type: $filetype"); - readfile("$pathname"); - } - - exit; ?> diff --git a/user/pixgroup.php b/user/pixgroup.php index 793afb4b2a2..231b521effc 100644 --- a/user/pixgroup.php +++ b/user/pixgroup.php @@ -5,45 +5,26 @@ $nomoodlecookie = true; // Because it interferes with caching - require_once("../config.php"); + require_once('../config.php'); + require_once('../files/mimetypes.php'); - $lifetime = 86400; + $relativepath = get_file_argument('pixgroup.php'); - if (isset($file)) { // workaround for situations where / syntax doesn't work - $pathinfo = $file; + $args = explode('/', trim($relativepath, '/')); + if (count($args) == 2) { + $groupid = (integer)$args[0]; + $image = $args[1]; + $pathname = $CFG->dataroot.'/groups/'.$groupid.'/'.$image; } else { - $pathinfo = get_slash_arguments("pixgroup.php"); + $image = 'f1.png'; + $pathname = $CFG->dirroot.'/pix/g/f1.png'; } - if (! $args = parse_slash_arguments($pathinfo)) { - error("No valid arguments supplied"); - } - - $numargs = count($args); - - if ($numargs == 2) { - $groupid = (integer)$args[0]; - $image = $args[1]; - $pathname = "$CFG->dataroot/groups/$groupid/$image"; - $filetype = "image/jpeg"; + if (file_exists($pathname) and !is_dir($pathname)) { + send_file($pathname, $image); } else { - $image = "f1.png"; - $pathname = "$CFG->dirroot/pix/g/f1.png"; - $filetype = "image/png"; + header('HTTP/1.0 404 not found'); + error(get_string('filenotfound', 'error')); //this is not displayed on IIS?? } - - if (file_exists($pathname)) { - $lastmodified = filemtime($pathname); - header("Last-Modified: " . gmdate("D, d M Y H:i:s", $lastmodified) . " GMT"); - header("Expires: " . gmdate("D, d M Y H:i:s", time() + $lifetime) . " GMT"); - header("Cache-control: max_age = $lifetime"); // a day - header("Pragma: "); - header("Content-disposition: inline; filename=$image"); - header("Content-length: ".filesize($pathname)); - header("Content-type: $filetype"); - readfile("$pathname"); - } - - exit; ?>