Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

new handling of uploaded files, please TEST, TEST, TEST

  • Loading branch information...
commit e7f927a0fc267e9e11c0ed01f865ce2e165ededb 1 parent 93c7d6d
skodak authored
163 file.php
... ... @@ -1,111 +1,114 @@
1   -<?php
2   -
3   - /**
4   - * file.php - Used to fetch file from the data directory
5   - *
6   - * This script file fetches files from the data directory (dataroot)<br>
7   - * Syntax: file.php/courseid/dir/.../dir/filename.ext
8   - *
9   - * @uses $CFG
10   - * @uses FORMAT_HTML
11   - * @uses FORMAT_MOODLE
12   - * @author Martin Dougiamas
13   - * @version $Id$
14   - * @package moodlecore
15   - */
16   -
  1 +<?php // $Id$
  2 + // This script fetches files from the dataroot directory
  3 + // Syntax: file.php/courseid/dir/dir/dir/filename.ext
  4 + // file.php/courseid/dir (returns index.html from dir)
  5 + // Workaround: file.php?file=/courseid/dir/dir/dir/filename.ext
  6 + // Test: file.php/test
  7 +
17 8 require_once('config.php');
18 9 require_once('files/mimetypes.php');
19 10
20 11 if (empty($CFG->filelifetime)) {
21   - $CFG->filelifetime = 86400; /// Seconds for files to remain in caches
22   - }
23   -
24   - if (isset($file)) { // workaround for situations where / syntax doesn't work
25   - $pathinfo = $file;
  12 + $lifetime = 86400; // Seconds for files to remain in caches
26 13 } else {
27   - $pathinfo = get_slash_arguments('file.php');
  14 + $lifetime = $CFG->filelifetime;
28 15 }
  16 +
29 17
30   - if (!$pathinfo) {
31   - error('No file parameters!');
  18 + $relativepath = get_file_argument('file.php');
  19 +
  20 + // relative path must start with '/', because of backup/restore!!!
  21 + if (!$relativepath) {
  22 + error('No valid arguments supplied or incorrect server configuration');
  23 + } else if ($relativepath{0} != '/') {
  24 + error('No valid arguments supplied, path does not start with slash!');
32 25 }
33 26
34   - $pathinfo = urldecode($pathinfo);
  27 + $pathname = $CFG->dataroot.$relativepath;
35 28
36   - if (! $args = parse_slash_arguments($pathinfo)) {
  29 + // extract relative path components
  30 + $args = explode('/', trim($relativepath, '/'));
  31 + if (count($args) == 0) { // always at least courseid, may search for index.html in course root
37 32 error('No valid arguments supplied');
38 33 }
39 34
40   - $numargs = count($args);
41   - if ($numargs < 2 or empty($args[1])) {
42   - error('No valid arguments supplied');
  35 + // security: limit access to existing course subdirectories
  36 + // note: course ID must be specified
  37 + // note: the lang field is needed for the course language switching hack in weblib.php
  38 + if (!$course = get_record_sql("SELECT id, lang FROM {$CFG->prefix}course WHERE id='".(int)$args[0]."'")) {
  39 + error('Invalid course ID');
43 40 }
44 41
45   - $courseid = (integer)$args[0];
46   -
47   - if (!$course = get_record('course', 'id', $courseid)) { // Course ID must be specified
  42 + // security: prevent access to "000" or "1 something" directories
  43 + if ($args[0] != $course->id) {
48 44 error('Invalid course ID');
49 45 }
50 46
51   - if ($course->category) {
52   - require_login($courseid);
  47 + // security: login to course if necessary
  48 + if ($course->id != SITEID) {
  49 + require_login($course->id);
53 50 } else if ($CFG->forcelogin) {
54 51 require_login();
55 52 }
56 53
57   - $pathname = $CFG->dataroot . $pathinfo;
58   - if ($pathargs = explode('?', $pathname)) {
59   - $pathname = $pathargs[0]; // Only keep what's before the '?'
60   - }
61   - $filename = $args[$numargs-1];
62   - if ($fileargs = explode('?', $filename)) {
63   - $filename = $fileargs[0]; // Only keep what's before the '?'
64   - }
  54 + // security: only editing teachers can access backups
  55 + if ((!isteacheredit($course->id))
  56 + and (count($args) >= 2)
  57 + and (strtolower($args[1]) == 'backupdata')) {
65 58
66   - if (file_exists($pathname)) {
67   - $lastmodified = filemtime($pathname);
68   - $mimetype = mimeinfo('type', $filename);
  59 + error('Access not allowed');
  60 + }
69 61
70   - header('Last-Modified: ' . gmdate("D, d M Y H:i:s", $lastmodified) . ' GMT');
71   - header('Expires: ' . gmdate("D, d M Y H:i:s", time() + $CFG->filelifetime) . ' GMT');
72   - header('Cache-control: max_age = '. $CFG->filelifetime);
73   - header('Pragma: ');
74   - header('Content-disposition: inline; filename='. $filename);
  62 + // security: teachers can view all assignments, students only their own
  63 + if ((count($args) >= 3)
  64 + and (strtolower($args[1]) == 'moddata')
  65 + and (strtolower($args[2]) == 'assignment')) {
75 66
  67 + $lifetime = 0; // do not cache assignments, students may reupload them
  68 + if ((!isteacher($course->id)) && (count($args) != 6 || $args[4] != $USER->id)) {
  69 + error('Access not allowed');
  70 + }
  71 + }
76 72
77   - if (empty($CFG->filteruploadedfiles)) {
78   - header('Content-length: '. filesize($pathname));
79   - header('Content-type: '. $mimetype);
80   - readfile($pathname);
  73 + if (is_dir($pathname)) {
  74 + if (file_exists($pathname.'/index.html')) {
  75 + $pathname = rtrim($pathname, '/').'/index.html';
  76 + $args[] = 'index.html';
  77 + } else if (file_exists($pathname.'/index.htm')) {
  78 + $pathname = rtrim($pathname, '/').'/index.htm';
  79 + $args[] = 'index.htm';
  80 + } else if (file_exists($pathname.'/Default.htm')) {
  81 + $pathname = rtrim($pathname, '/').'/Default.htm';
  82 + $args[] = 'Default.htm';
  83 + } else {
  84 + // security: do not return directory node!
  85 + not_found($course->id);
  86 + }
  87 + }
81 88
82   - } else { /// Try and put the file through filters
83   - if ($mimetype == 'text/html') {
84   - $options->noclean = true;
85   - $output = format_text(implode('', file($pathname)), FORMAT_HTML, $options, $courseid);
  89 + // check that file exists
  90 + if (!file_exists($pathname)) {
  91 + not_found($course->id);
  92 + }
86 93
87   - header('Content-length: '. strlen($output));
88   - header('Content-type: text/html');
89   - echo $output;
90   -
91   - } else if ($mimetype == 'text/plain') {
92   - $options->newlines = false;
93   - $options->noclean = true;
94   - $output = '<pre>'. format_text(implode('', file($pathname)), FORMAT_MOODLE, $options, $courseid) .'</pre>';
95   - header('Content-length: '. strlen($output));
96   - header('Content-type: text/html');
97   - echo $output;
98   -
99   - } else { /// Just send it out raw
100   - header('Content-length: '. filesize($pathname));
101   - header('Content-type: '. $mimetype);
102   - readfile($pathname);
103   - }
  94 + // extra security: keep symbolic links inside dataroot/courseid if required
  95 + /*if (!empty($CFG->checksymlinks)) {
  96 + $realpath = realpath($pathname);
  97 + $realdataroot = realpath($CFG->dataroot.'/'.$course->id);
  98 + if (strpos($realpath, $realdataroot) !== 0) {
  99 + not_found($course->id);
104 100 }
105   - } else {
  101 + }*/
  102 +
  103 + // ========================================
  104 + // finally send the file
  105 + // ========================================
  106 + $filename = $args[count($args)-1];
  107 + send_file($pathname, $filename, $lifetime, !empty($CFG->filteruploadedfiles));
  108 +
  109 + function not_found($courseid) {
  110 + global $CFG;
106 111 header('HTTP/1.0 404 not found');
107   - error(get_string('filenotfound', 'error'), $CFG->wwwroot .'/course/view.php?id='. $courseid);
  112 + error(get_string('filenotfound', 'error'), $CFG->wwwroot.'/course/view.php?id='.$courseid); //this is not displayed on IIS??
108 113 }
109   -
110   - exit;
111   -?>
  114 +?>
66 files/mimetypes.php
@@ -79,7 +79,7 @@ function mimeinfo($element, $filename) {
79 79 );
80 80
81 81 if (eregi("\.([a-z0-9]+)$", $filename, $match)) {
82   - if(isset($mimeinfo[strtolower($match[1])][$element])) {
  82 + if (isset($mimeinfo[strtolower($match[1])][$element])) {
83 83 return $mimeinfo[strtolower($match[1])][$element];
84 84 } else {
85 85 return $mimeinfo["xxx"][$element]; // By default
@@ -89,4 +89,68 @@ function mimeinfo($element, $filename) {
89 89 }
90 90 }
91 91
  92 +function send_file($path, $filename, $lifetime=86400 , $filter=false, $pathisstring=false) {
  93 +
  94 + $mimetype = mimeinfo('type', $filename);
  95 + $lastmodified = $pathisstring ? time() : filemtime($path);
  96 + $filesize = $pathisstring ? strlen($path) : filesize($path);
  97 +
  98 + @header('Last-Modified: '. gmdate("D, d M Y H:i:s", $lastmodified) .' GMT');
  99 + if ($lifetime > 0) {
  100 + @header('Cache-control: max-age='.$lifetime);
  101 + @header('Expires: '. gmdate("D, d M Y H:i:s", time() + $lifetime) .'GMT');
  102 + @header('Pragma: ');
  103 + } else {
  104 + // this part is tricky, displaying of MS Office documents in IE needs
  105 + // to store the file on disk, but no-cache may prevent it
  106 + @header('Cache-Control: private, must-revalidate, pre-check=0, post-check=0, max-age=10');
  107 + @header('Expires: '. gmdate("D, d M Y H:i:s", 0) .'GMT');
  108 + @header('Pragma: no-cache');
  109 + }
  110 + @header('Accept-Ranges: none'); // PDF compatibility
  111 + @header('Content-disposition: inline; filename='.$filename);
  112 +
  113 + if (!$filter) {
  114 + @header('Content-length: '.$filesize);
  115 + if ($mimetype == 'text/plain') {
  116 + @header('Content-type: text/plain; charset='.get_string('thischarset')); //add encoding
  117 + } else {
  118 + @header('Content-type: '.$mimetype);
  119 + }
  120 + if ($pathisstring) {
  121 + echo $path;
  122 + }else {
  123 + readfile($path);
  124 + }
  125 + } else { // Try to put the file through filters
  126 + if ($mimetype == 'text/html') {
  127 + $options->noclean = true;
  128 + $text = $pathisstring ? $path : implode('', file($path));
  129 + $output = format_text($text, FORMAT_HTML, $options, $course->id);
  130 +
  131 + @header('Content-length: '.strlen($output));
  132 + @header('Content-type: text/html');
  133 + echo $output;
  134 + } else if ($mimetype == 'text/plain') {
  135 + $options->newlines = false;
  136 + $options->noclean = true;
  137 + $text = htmlentities($pathisstring ? $path : implode('', file($path)));
  138 + $output = '<pre>'. format_text($text, FORMAT_MOODLE, $options, $course->id) .'</pre>';
  139 +
  140 + @header('Content-length: '.strlen($output));
  141 + @header('Content-type: text/html; charset='. get_string('thischarset')); //add encoding
  142 + echo $output;
  143 + } else { // Just send it out raw
  144 + @header('Content-length: '.$filesize);
  145 + @header('Content-type: '.$mimetype);
  146 + if ($pathisstring) {
  147 + echo $path;
  148 + }else {
  149 + readfile($path);
  150 + }
  151 + }
  152 + }
  153 + die; //no more chars to output!!!
  154 +}
  155 +
92 156 ?>
84 filter/algebra/pix.php
@@ -5,43 +5,34 @@
5 5
6 6 $nomoodlecookie = true; // Because it interferes with caching
7 7
8   - require_once("../../config.php");
  8 + require_once('../../config.php');
  9 + require_once('../../files/mimetypes.php');
9 10
10   - $CFG->algebrafilterdir = "filter/algebra";
11   - $CFG->texfilterdir = "filter/tex";
12   - $CFG->algebraimagedir = "filter/algebra";
  11 + $CFG->texfilterdir = 'filter/tex';
  12 + $CFG->algebrafilterdir = 'filter/algebra';
  13 + $CFG->algebraimagedir = 'filter/algebra';
13 14
14   - $cmd = ''; // Initialise these variables
  15 +
  16 + $cmd = ''; // Initialise these variables
15 17 $status = '';
16 18
17   - error_reporting(E_ALL);
  19 + //error_reporting(E_ALL);
18 20
19   - $lifetime = 86400;
20   - if (isset($file)) { // workaround for situations where / syntax doesn't work
21   - $pathinfo = '/' . $file;
22   - } else {
23   - $pathinfo = get_slash_arguments("pix.php");
24   - }
25   -
26   - if (! $args = parse_slash_arguments($pathinfo)) {
27   - error("No valid arguments supplied");
28   - }
  21 + $relativepath = get_file_argument('pix.php');
29 22
30   - $numargs = count($args);
  23 + $args = explode('/', trim($relativepath, '/'));
31 24
32   - if ($numargs == 1) {
33   - $image = $args[0];
34   - $pathname = "$CFG->dataroot/$CFG->algebraimagedir/$image";
35   - $filetype = "image/gif";
  25 + if (count($args) == 1) {
  26 + $image = $args[0];
  27 + $pathname = $CFG->dataroot.'/'.$CFG->algebraimagedir.'/'.$image;
36 28 } else {
37   - error("No valid arguments supplied");
  29 + error('No valid arguments supplied');
38 30 }
39 31
40   -
41 32 if (!file_exists($pathname)) {
42 33 $md5 = str_replace('.gif','',$image);
43   - if ($texcache = get_record("cache_filters", "filter", "algebra", "md5key", $md5)) {
44   - if (!file_exists("$CFG->dataroot/$CFG->algebraimagedir")) {
  34 + if ($texcache = get_record('cache_filters', 'filter', 'algebra', 'md5key', $md5)) {
  35 + if (!file_exists($CFG->dataroot.'/'.$CFG->algebraimagedir)) {
45 36 make_upload_directory($CFG->algebraimagedir);
46 37 }
47 38
@@ -59,7 +50,7 @@
59 50 } else if (is_executable("$CFG->dirroot/$CFG->texfilterdir/mimetex")) { /// Use the custom binary
60 51
61 52 $cmd = "$CFG->dirroot/$CFG->texfilterdir/mimetex -e $pathname ". escapeshellarg($texexp);
62   -
  53 +
63 54 } else { /// Auto-detect the right TeX binary
64 55 switch (PHP_OS) {
65 56
@@ -72,12 +63,17 @@
72 63 break;
73 64
74 65 default: /// Nothing was found, so tell them how to fix it.
75   - echo "Make sure you have an appropriate MimeTeX binary here:\n\n";
76   - echo " $CFG->dirroot/$CFG->texfilterdir/mimetex\n\n";
77   - echo "and that it has the right permissions set on it as executable program.\n\n";
78   - echo "You can get the latest binaries for your ".PHP_OS." platform from: \n\n";
79   - echo " http://moodle.org/download/mimetex/";
80   - exit;
  66 + if ($CFG->debug > 7) {
  67 + echo "Make sure you have an appropriate MimeTeX binary here:\n\n";
  68 + echo " $CFG->dirroot/$CFG->texfilterdir/mimetex\n\n";
  69 + echo "and that it has the right permissions set on it as executable program.\n\n";
  70 + echo "You can get the latest binaries for your ".PHP_OS." platform from: \n\n";
  71 + echo " http://moodle.org/download/mimetex/";
  72 + } else {
  73 + echo "Mimetex executable was not found,\n";
  74 + echo "Please turn on debug mode in site configuration to see more info here.";
  75 + }
  76 + die;
81 77 break;
82 78 }
83 79 }
@@ -86,20 +82,16 @@
86 82 }
87 83
88 84 if (file_exists($pathname)) {
89   - $lastmodified = filemtime($pathname);
90   - header("Last-Modified: " . gmdate("D, d M Y H:i:s", $lastmodified) . " GMT");
91   - header("Expires: " . gmdate("D, d M Y H:i:s", time() + $lifetime) . " GMT");
92   - header("Cache-control: max_age = $lifetime"); // a day
93   - header("Pragma: ");
94   - header("Content-disposition: inline; filename=$image");
95   - header("Content-length: ".filesize($pathname));
96   - header("Content-type: $filetype");
97   - readfile("$pathname");
  85 + send_file($pathname, $image);
98 86 } else {
99   - echo "The shell command<br />$cmd<br />returned status = $status<br />\n";
100   - echo "Image not found!<br />";
101   - echo "Please try the <a href=\"$CFG->wwwroot/filter/algebra/algebradebug.php\">debugging script</a>";
  87 + if ($CFG->debug > 7) {
  88 + echo "The shell command<br />$cmd<br />returned status = $status<br />\n";
  89 + echo "Image not found!<br />";
  90 + echo "Please try the <a href=\"$CFG->wwwroot/$CFG->algebrafilterdir/algebradebug.php\">debugging script</a>";
  91 + } else {
  92 + echo "Image not found!<br />";
  93 + echo "Please try the <a href=\"$CFG->wwwroot/$CFG->algebrafilterdir/algebradebug.php\">debugging script</a><br />";
  94 + echo "Please turn on debug mode in site configuration to see more info here.";
  95 + }
102 96 }
103   -
104   - exit;
105 97 ?>
82 filter/tex/pix.php
@@ -5,42 +5,33 @@
5 5
6 6 $nomoodlecookie = true; // Because it interferes with caching
7 7
8   - require_once("../../config.php");
  8 + require_once('../../config.php');
  9 + require_once('../../files/mimetypes.php');
9 10
10   - $CFG->texfilterdir = "filter/tex";
11   - $CFG->teximagedir = "filter/tex";
  11 + $CFG->texfilterdir = 'filter/tex';
  12 + $CFG->teximagedir = 'filter/tex';
12 13
13   - $cmd = ''; // Initialise these variables
  14 +
  15 + $cmd = ''; // Initialise these variables
14 16 $status = '';
15 17
16   - error_reporting(E_ALL);
  18 + //error_reporting(E_ALL);
17 19
18   - $lifetime = 86400;
19   - if (isset($file)) { // workaround for situations where / syntax doesn't work
20   - $pathinfo = '/' . $file;
21   - } else {
22   - $pathinfo = get_slash_arguments("pix.php");
23   - }
24   -
25   - if (! $args = parse_slash_arguments($pathinfo)) {
26   - error("No valid arguments supplied");
27   - }
  20 + $relativepath = get_file_argument('pix.php');
28 21
29   - $numargs = count($args);
  22 + $args = explode('/', trim($relativepath, '/'));
30 23
31   - if ($numargs == 1) {
32   - $image = $args[0];
33   - $pathname = "$CFG->dataroot/$CFG->teximagedir/$image";
34   - $filetype = "image/gif";
  24 + if (count($args) == 1) {
  25 + $image = $args[0];
  26 + $pathname = $CFG->dataroot.'/'.$CFG->teximagedir.'/'.$image;
35 27 } else {
36   - error("No valid arguments supplied");
  28 + error('No valid arguments supplied');
37 29 }
38 30
39   -
40 31 if (!file_exists($pathname)) {
41 32 $md5 = str_replace('.gif','',$image);
42   - if ($texcache = get_record("cache_filters", "filter", "tex", "md5key", $md5)) {
43   - if (!file_exists("$CFG->dataroot/$CFG->teximagedir")) {
  33 + if ($texcache = get_record('cache_filters', 'filter', 'tex', 'md5key', $md5)) {
  34 + if (!file_exists($CFG->dataroot.'/'.$CFG->teximagedir)) {
44 35 make_upload_directory($CFG->teximagedir);
45 36 }
46 37
@@ -58,7 +49,7 @@
58 49 } else if (is_executable("$CFG->dirroot/$CFG->texfilterdir/mimetex")) { /// Use the custom binary
59 50
60 51 $cmd = "$CFG->dirroot/$CFG->texfilterdir/mimetex -e $pathname ". escapeshellarg($texexp);
61   -
  52 +
62 53 } else { /// Auto-detect the right TeX binary
63 54 switch (PHP_OS) {
64 55
@@ -71,12 +62,17 @@
71 62 break;
72 63
73 64 default: /// Nothing was found, so tell them how to fix it.
74   - echo "Make sure you have an appropriate MimeTeX binary here:\n\n";
75   - echo " $CFG->dirroot/$CFG->texfilterdir/mimetex\n\n";
76   - echo "and that it has the right permissions set on it as executable program.\n\n";
77   - echo "You can get the latest binaries for your ".PHP_OS." platform from: \n\n";
78   - echo " http://moodle.org/download/mimetex/";
79   - exit;
  65 + if ($CFG->debug > 7) {
  66 + echo "Make sure you have an appropriate MimeTeX binary here:\n\n";
  67 + echo " $CFG->dirroot/$CFG->texfilterdir/mimetex\n\n";
  68 + echo "and that it has the right permissions set on it as executable program.\n\n";
  69 + echo "You can get the latest binaries for your ".PHP_OS." platform from: \n\n";
  70 + echo " http://moodle.org/download/mimetex/";
  71 + } else {
  72 + echo "Mimetex executable was not found,\n";
  73 + echo "Please turn on debug mode in site configuration to see more info here.";
  74 + }
  75 + die;
80 76 break;
81 77 }
82 78 }
@@ -85,20 +81,16 @@
85 81 }
86 82
87 83 if (file_exists($pathname)) {
88   - $lastmodified = filemtime($pathname);
89   - header("Last-Modified: " . gmdate("D, d M Y H:i:s", $lastmodified) . " GMT");
90   - header("Expires: " . gmdate("D, d M Y H:i:s", time() + $lifetime) . " GMT");
91   - header("Cache-control: max_age = $lifetime"); // a day
92   - header("Pragma: ");
93   - header("Content-disposition: inline; filename=$image");
94   - header("Content-length: ".filesize($pathname));
95   - header("Content-type: $filetype");
96   - readfile("$pathname");
  84 + send_file($pathname, $image);
97 85 } else {
98   - echo "The shell command<br />$cmd<br />returned status = $status<br />\n";
99   - echo "Image not found!<br />";
100   - echo "Please try the <a href=\"$CFG->wwwroot/$CFG->texfilterdir/texdebug.php\">debugging script</a>";
  86 + if ($CFG->debug > 7) {
  87 + echo "The shell command<br />$cmd<br />returned status = $status<br />\n";
  88 + echo "Image not found!<br />";
  89 + echo "Please try the <a href=\"$CFG->wwwroot/$CFG->texfilterdir/texdebug.php\">debugging script</a>";
  90 + } else {
  91 + echo "Image not found!<br />";
  92 + echo "Please try the <a href=\"$CFG->wwwroot/$CFG->texfilterdir/texdebug.php\">debugging script</a><br />";
  93 + echo "Please turn on debug mode in site configuration to see more info here.";
  94 + }
101 95 }
102   -
103   - exit;
104 96 ?>
4 mod/quiz/lib.php
@@ -965,6 +965,10 @@ function quiz_print_possible_question_image($quizid, $question) {
965 965
966 966 global $CFG;
967 967
  968 + if ($quizid == '') {
  969 + $quizid = '0';
  970 + }
  971 +
968 972 if ($question->image) {
969 973 echo '<img border="0" src="';
970 974
173 mod/quiz/quizfile.php
... ... @@ -1,91 +1,91 @@
1   -<?php // $Id$
  1 +<?PHP // $Id$
2 2 // This function fetches files from the data directory
3 3 // Syntax: quizfile.php/quiz id/question id/dir/.../dir/filename.ext
4 4 // It is supposed to be used by the quiz module only
5 5
6   - require_once("../../config.php");
7   - require_once("../../files/mimetypes.php");
8   - require_once("lib.php");
  6 + require_once('../../config.php');
  7 + require_once('../../files/mimetypes.php');
  8 + require_once('lib.php');
9 9
10   - $lifetime = 86400;
11   -
12   - if (isset($file)) { // workaround for situations where / syntax doesn't work
13   - $pathinfo = $file;
  10 + if (empty($CFG->filelifetime)) {
  11 + $lifetime = 86400; // Seconds for files to remain in caches
14 12 } else {
15   - $pathinfo = get_slash_arguments("file.php");
16   - }
17   -
18   - if (!$pathinfo) {
19   - error("No file parameters!");
  13 + $lifetime = $CFG->filelifetime;
20 14 }
21   -
22   - /////////////////////////////////////
23   - // Extract info from $pathinfo
24   - /////////////////////////////////////
25   -
26   - $idreg = '[0-9]+';
27   - if (!ereg("^/?($idreg)/($idreg)/((.+/)?([^/]+))$",
28   - $pathinfo,
29   - $regs) ) {
30   - error("File parameters are badly formated");
  15 +
  16 + $relativepath = get_file_argument('quizfile.php');
  17 +
  18 + if (!$relativepath) {
  19 + error('No valid arguments supplied or incorrect server configuration');
31 20 }
32   - if (! ($quiz = get_record('quiz', 'id', $regs[1]))) {
33   - error("No valid quiz supplied");
34   - }
35   - if (! ($question = get_record('quiz_questions', 'id', $regs[2]))) {
36   - error("No valid question supplied");
37   - }
38   - if (! ($relativefilepath = $regs[3])) {
39   - error("No valid file path supplied");
40   - }
41   - if (! ($filename = $regs[5])) {
42   - error("No valid file name supplied");
43   - }
44   - if (detect_munged_arguments($relativefilepath)) {
45   - error("Errors in the supplied file path");
  21 +
  22 + // extract relative path components
  23 + $args = explode('/', trim($relativepath, '/'));
  24 + if (count($args) < 3) { // always at least category, question and path
  25 + error('No valid arguments supplied');
46 26 }
  27 +
  28 + $quizid = (int)array_shift($args);
  29 + $questionid = (int)array_shift($args);
  30 + $relativepath = implode ('/', $args);
47 31
48   - //////////////////////////////////////////
49   - // Info from $pathinfo is now extracted!
50   - // Now check the user's persmissions on this quiz...
51   - //////////////////////////////////////////
52   -
53   - if (! ($course = get_record("course", "id", $quiz->course))) {
54   - error("Supplied quiz $quiz->name does not belong to a valid course");
  32 + if (!($question = get_record('quiz_questions', 'id', $questionid))) {
  33 + error('No valid arguments supplied');
55 34 }
56 35
57   - require_login($course->id);
58   -
59   - // For now, let's not worry about this. The following check causes
60   - // problems sometimes when reviewing a quiz
61   - //if (!isteacher($course->id)
62   - // and !quiz_get_user_attempt_unfinished($quiz->id, $USER->id)
63   - // and ! ($quiz->review && time() > $quiz->timeclose)
64   - // || !quiz_get_user_attempts($quiz->id, $USER->id) )
65   - //{
66   - // error("Logged-in user is not allowed to view this quiz");
67   - //}
68   -
69   - ///////////////////////////////////////////////////
70   - // The logged-in user has the right to view material on this quiz!
71   - // Now verify the consistency between $quiz, $question, its category and $relativepathname
72   - ///////////////////////////////////////////////////
73   -
74   - // For now, let's not worry about this. The following check doesn't
75   - // work for randomly selected questions and it gets complicated
76   - //if (!in_array($question->id, explode(',', $quiz->questions), FALSE)) {
77   - // error("Specified question is not on the specified quiz");
78   - //}
  36 + if (!($questioncategory = get_record('quiz_categories', 'id', $question->category))) {
  37 + error('No valid arguments supplied');
  38 + }
79 39
80   - if (! ($questioncategory = get_record('quiz_categories', 'id',
81   - $question->category)))
82   - {
83   - error("Question category is not valid");
  40 + /////////////////////////////////////
  41 + // Check access
  42 + /////////////////////////////////////
  43 + if ($quizid == 0) { // teache doing preview during quiz creation
  44 + if ($questioncategory->publish) {
  45 + require_login();
  46 + if (!isteacher()) {
  47 + error('No valid arguments supplied');
  48 + }
  49 + } else {
  50 + require_login($questioncategory->course);
  51 + if (!isteacher($questioncategory->course)) {
  52 + error('Access not allowed');
  53 + }
  54 + }
  55 + } else {
  56 + if (!($quiz = get_record('quiz', 'id', $quizid))) {
  57 + error('No valid arguments supplied');
  58 + }
  59 + if (!($course = get_record('course', 'id', $quiz->course))) {
  60 + error('No valid arguments supplied');
  61 + }
  62 + require_login($course->id);
  63 +
  64 + // For now, let's not worry about this. The following check causes
  65 + // problems sometimes when reviewing a quiz
  66 + //if (!isteacher($course->id)
  67 + // and !quiz_get_user_attempt_unfinished($quiz->id, $USER->id)
  68 + // and ! ($quiz->review && time() > $quiz->timeclose)
  69 + // || !quiz_get_user_attempts($quiz->id, $USER->id) )
  70 + //{
  71 + // error("Logged-in user is not allowed to view this quiz");
  72 + //}
  73 +
  74 + ///////////////////////////////////////////////////
  75 + // The logged-in user has the right to view material on this quiz!
  76 + // Now verify the consistency between $quiz, $question, its category and $relativepathname
  77 + ///////////////////////////////////////////////////
  78 +
  79 + // For now, let's not worry about this. The following check doesn't
  80 + // work for randomly selected questions and it gets complicated
  81 + //if (!in_array($question->id, explode(',', $quiz->questions), FALSE)) {
  82 + // error("Specified question is not on the specified quiz");
  83 + //}
84 84 }
85 85
86 86 // Have the question check whether it uses this file or not
87 87 if (!$QUIZ_QTYPES[$question->qtype]->uses_quizfile($question,
88   - $relativefilepath)) {
  88 + $relativepath)) {
89 89 error("The specified file path is not on the specified question");
90 90 }
91 91
@@ -95,35 +95,14 @@
95 95 // Specified file can now be returned...
96 96 //////////////////////////////////////////
97 97
98   - $pathname = "$CFG->dataroot/$questioncategory->course/$relativefilepath";
99   - // $filename has already been extracted
100   -
  98 + $pathname = "$CFG->dataroot/$questioncategory->course/$relativepath";
  99 + $filename = $args[count($args)-1];
101 100
102   - /////////////////////////////////////////////////////////////////
103   - // The remaining code is identical to the final lines of file.php
104   - // If you ask me - this stuff should be separated into a separate
105   - // function for conviency.
106   - // That function would find itself very in comfortable in the
107   - // file mimetypes.php
108   - //////////////////////////////////
109   -
110   - $mimetype = mimeinfo("type", $filename);
111 101
112 102 if (file_exists($pathname)) {
113   - $lastmodified = filemtime($pathname);
114   -
115   - header("Last-Modified: " . gmdate("D, d M Y H:i:s", $lastmodified) . " GMT");
116   - header("Expires: " . gmdate("D, d M Y H:i:s", time() + $lifetime) . " GMT");
117   - header("Cache-control: max_age = $lifetime"); // a day
118   - header("Pragma: ");
119   - header("Content-disposition: inline; filename=$filename");
120   - header("Content-length: ".filesize($pathname));
121   - header("Content-type: $mimetype");
122   - readfile("$pathname");
  103 + send_file($pathname, $filename, $lifetime);
123 104 } else {
124   - error("Sorry, but the file you are looking for was not found (".clean_text($pathname).")",
125   - "course/view.php?id=$courseid");
  105 + header('HTTP/1.0 404 not found');
  106 + error(get_string('filenotfound', 'error')); //this is not displayed on IIS??
126 107 }
127   -
128   - exit;
129 108 ?>
105 rss/file.php
... ... @@ -1,10 +1,10 @@
1   -<?php //$Id$
  1 +<?PHP //$Id$
2 2 //This file returns the required rss feeds
3 3 //The URL format MUST include:
4 4 // course: the course id
5   - // user: the user id
6   - // name: the name of the module (forum...)
7   - // id: the id (instance) of the module (forumid...)
  5 + // user: the user id
  6 + // name: the name of the module (forum...)
  7 + // id: the id (instance) of the module (forumid...)
8 8 //If the course has a password or it doesn't
9 9 //allow guest access then the user field is
10 10 //required to see that the user is enrolled
@@ -13,88 +13,75 @@
13 13 //to correct users. It isn't unbreakable,
14 14 //obviously, but its the best I've thought!!
15 15
16   - require_once("../config.php");
17   - require_once("$CFG->dirroot/files/mimetypes.php");
  16 + $nomoodlecookie = true; // Because it interferes with caching
  17 +
  18 + require_once('../config.php');
  19 + require_once('../files/mimetypes.php');
  20 + require_once('rsslib.php');
18 21
19   - $allowed = true;
20   - $error = false;
21 22
22   - if (empty($CFG->filelifetime)) {
23   - $CFG->filelifetime = 86400; /// Seconds for files to remain in caches
24   - }
  23 + $lifetime = 3600; // Seconds for files to remain in caches - 1 hour
25 24
26   - if (isset($file)) { // workaround for situations where / syntax doesn't work
27   - $pathinfo = $file;
28   - } else {
29   - $pathinfo = get_slash_arguments("file.php");
30   - }
  25 + $relativepath = get_file_argument('file.php');
31 26
32   - if (!$pathinfo) {
33   - $error = true;
  27 + if (!$relativepath) {
  28 + not_found();
34 29 }
35 30
36   - $pathinfo = urldecode($pathinfo);
37   -
38   - if (! $args = parse_slash_arguments($pathinfo)) {
39   - $error = true;
  31 + // extract relative path components
  32 + $args = explode('/', trim($relativepath, '/'));
  33 +
  34 + if (count($args) < 4) {
  35 + not_found();
40 36 }
41 37
42   - $numargs = count($args);
43   - if ($numargs < 5 or empty($args[1])) {
44   - $error = true;
  38 + $courseid = (int)$args[0];
  39 + $userid = (int)$args[1];
  40 + $modulename = clean_param($args[2], PARAM_FILE);
  41 + $instance = (int)$args[3];
  42 +
  43 + if (!$course = get_record("course", "id", $courseid)) {
  44 + not_found();
45 45 }
46   -
47   - $courseid = (integer)$args[0];
48   - $userid = (integer)$args[1];
49   - $modulename = $args[2];
50   - $instance = (integer)$args[3];
51   -
  46 +
52 47 //Check name of module
53 48 $mods = get_list_of_plugins("mod");
54 49 if (!in_array(strtolower($modulename), $mods)) {
55   - error("This module doesn't exist!");
56   - }
57   -
58   - if (! $course = get_record("course", "id", $courseid)) {
59   - $error = true;
  50 + not_found();
60 51 }
61 52
62 53 //Get course_module to check it's visible
63   - if (! $cm = get_coursemodule_from_instance($modulename,$instance,$courseid)) {
64   - $error = true;
  54 + if (!$cm = get_coursemodule_from_instance($modulename,$instance,$courseid)) {
  55 + not_found();
65 56 }
66   - $cmvisible = $cm->visible;
67 57
68 58 $isstudent = isstudent($courseid,$userid);
69 59 $isteacher = isteacher($courseid,$userid);
70 60
71 61 //Check for "security" if !course->guest or course->password
72   - if (!$course->guest || $course->password) {
73   - $allowed = ($isstudent || $isteacher);
  62 + if ((!$course->guest || $course->password) && (!($isstudent || $isteacher))) {
  63 + not_found();
74 64 }
75 65
76 66 //Check for "security" if the course is hidden or the activity is hidden
77   - if ($allowed && (!$course->visible || !$cmvisible)) {
78   - $allowed = $isteacher;
  67 + if ((!$course->visible || !$cm->visible) && (!$isteacher)) {
  68 + not_found();
79 69 }
80 70
81   - $pathname = $CFG->dataroot."/rss/".$modulename."/".$instance.".xml";
82   - $filename = $args[$numargs-1];
  71 + $filename = $instance.'.xml';;
  72 + $pathname = $CFG->dataroot.'/rss/'.$modulename.'/'.$filename;
83 73
84   - //If the file exists and its allowed for me, download it!
85   - if (file_exists($pathname) && $allowed && !$error) {
86   - $lastmodified = filemtime($pathname);
87   - $mimetype = mimeinfo("type", $filename);
88   -
89   - header("Last-Modified: " . gmdate("D, d M Y H:i:s", $lastmodified) . " GMT");
90   - header("Expires: " . gmdate("D, d M Y H:i:s", time() + $CFG->filelifetime) . " GMT");
91   - header("Cache-control: max_age = $CFG->filelifetime");
92   - header("Pragma: ");
93   - header("Content-disposition: inline; filename=$filename");
94   -
95   - header("Content-length: ".filesize($pathname));
96   - header("Content-type: $mimetype");
97   - readfile($pathname);
  74 + //Check that file exists
  75 + if (!file_exists($pathname)) {
  76 + not_found();
98 77 }
99 78
  79 + //Send it to user!
  80 + send_file($pathname, $filename, $lifetime);
  81 +
  82 + function not_found() {
  83 + /// error, send some XML with error message
  84 + global $lifetime;
  85 + send_file(rss_geterrorxmlfile(), 'rsserror.xml', $lifetime, false, true);
  86 + }
100 87 ?>
47 user/pix.php
@@ -5,45 +5,26 @@
5 5
6 6 $nomoodlecookie = true; // Because it interferes with caching
7 7
8   - require_once("../config.php");
  8 + require_once('../config.php');
  9 + require_once('../files/mimetypes.php');
9 10
10   - $lifetime = 86400;
  11 + $relativepath = get_file_argument('pix.php');
11 12
12   - if (isset($file)) { // workaround for situations where / syntax doesn't work
13   - $pathinfo = $file;
  13 + $args = explode('/', trim($relativepath, '/'));
14 14
  15 + if (count($args) == 2) {
  16 + $userid = (integer)$args[0];
  17 + $image = $args[1];
  18 + $pathname = $CFG->dataroot.'/users/'.$userid.'/'.$image;
15 19 } else {
16   - $pathinfo = get_slash_arguments("pix.php");
  20 + $image = 'f1.png';
  21 + $pathname = $CFG->dirroot.'/pix/u/f1.png';
17 22 }
18 23
19   - if (! $args = parse_slash_arguments($pathinfo)) {
20   - error("No valid arguments supplied");
21   - }
22   -
23   - $numargs = count($args);
24   -
25   - if ($numargs == 2) {
26   - $userid = (integer)$args[0];
27   - $image = $args[1];
28   - $pathname = "$CFG->dataroot/users/$userid/$image";
29   - $filetype = "image/jpeg";
  24 + if (file_exists($pathname) and !is_dir($pathname)) {
  25 + send_file($pathname, $image);
30 26 } else {
31   - $image = "f1.png";
32   - $pathname = "$CFG->dirroot/pix/u/f1.png";
33   - $filetype = "image/png";
  27 + header('HTTP/1.0 404 not found');
  28 + error(get_string('filenotfound', 'error')); //this is not displayed on IIS??
34 29 }
35   -
36   - if (file_exists($pathname)) {
37   - $lastmodified = filemtime($pathname);
38   - header("Last-Modified: " . gmdate("D, d M Y H:i:s", $lastmodified) . " GMT");
39   - header("Expires: " . gmdate("D, d M Y H:i:s", time() + $lifetime) . " GMT");
40   - header("Cache-control: max_age = $lifetime"); // a day
41   - header("Pragma: ");
42   - header("Content-disposition: inline; filename=$image");
43   - header("Content-length: ".filesize($pathname));
44   - header("Content-type: $filetype");
45   - readfile("$pathname");
46   - }
47   -
48   - exit;
49 30 ?>
47 user/pixgroup.php
@@ -5,45 +5,26 @@
5 5
6 6 $nomoodlecookie = true; // Because it interferes with caching
7 7
8   - require_once("../config.php");
  8 + require_once('../config.php');
  9 + require_once('../files/mimetypes.php');
9 10
10   - $lifetime = 86400;
  11 + $relativepath = get_file_argument('pixgroup.php');
11 12
12   - if (isset($file)) { // workaround for situations where / syntax doesn't work
13   - $pathinfo = $file;
  13 + $args = explode('/', trim($relativepath, '/'));
14 14
  15 + if (count($args) == 2) {
  16 + $groupid = (integer)$args[0];
  17 + $image = $args[1];
  18 + $pathname = $CFG->dataroot.'/groups/'.$groupid.'/'.$image;
15 19 } else {
16   - $pathinfo = get_slash_arguments("pixgroup.php");
  20 + $image = 'f1.png';
  21 + $pathname = $CFG->dirroot.'/pix/g/f1.png';
17 22 }
18 23
19   - if (! $args = parse_slash_arguments($pathinfo)) {
20   - error("No valid arguments supplied");
21   - }
22   -
23   - $numargs = count($args);
24   -
25   - if ($numargs == 2) {
26   - $groupid = (integer)$args[0];
27   - $image = $args[1];
28   - $pathname = "$CFG->dataroot/groups/$groupid/$image";
29   - $filetype = "image/jpeg";
  24 + if (file_exists($pathname) and !is_dir($pathname)) {
  25 + send_file($pathname, $image);
30 26 } else {
31   - $image = "f1.png";
32   - $pathname = "$CFG->dirroot/pix/g/f1.png";
33   - $filetype = "image/png";
  27 + header('HTTP/1.0 404 not found');
  28 + error(get_string('filenotfound', 'error')); //this is not displayed on IIS??
34 29 }
35   -
36   - if (file_exists($pathname)) {
37   - $lastmodified = filemtime($pathname);
38   - header("Last-Modified: " . gmdate("D, d M Y H:i:s", $lastmodified) . " GMT");
39   - header("Expires: " . gmdate("D, d M Y H:i:s", time() + $lifetime) . " GMT");
40   - header("Cache-control: max_age = $lifetime"); // a day
41   - header("Pragma: ");
42   - header("Content-disposition: inline; filename=$image");
43   - header("Content-length: ".filesize($pathname));
44   - header("Content-type: $filetype");
45   - readfile("$pathname");
46   - }
47   -
48   - exit;
49 30 ?>

0 comments on commit e7f927a

Please sign in to comment.
Something went wrong with that request. Please try again.