/** * Test minimalistic parameter cleaning. */ public function test_min_clean_param() { $this->assertSame('foo', min_clean_param('foo', 'RAW')); $this->assertSame('aš', min_clean_param('a' . chr(130) . 'š', 'RAW')); $this->assertSame(1, min_clean_param('1', 'INT')); $this->assertSame(1, min_clean_param('1aa', 'INT')); $this->assertSame('1abc-d_f', min_clean_param('/.1ačž"b?;c-d{}\\_f.', 'SAFEDIR')); $this->assertSame(1, min_clean_param('1aa', 'INT')); $this->assertSame('/a/b/./c5', min_clean_param('/a*?$//b/.../c5', 'SAFEPATH')); $this->assertSame(1, min_clean_param('1aa', 'INT')); }
/** * Minimalistic parameter validation function. * Can not use optional param because moodlelib.php is not loaded yet * @param string $name * @param mixed $default * @param string $type * @return mixed */ function min_optional_param($name, $default, $type) { $value = $default; if (isset($_GET[$name])) { $value = $_GET[$name]; } else { if (isset($_GET['amp;' . $name])) { // very, very, very ugly hack, unfortunately $OUTPUT->pix_url() is not used properly in javascript code :-( $value = $_GET['amp;' . $name]; } } return min_clean_param($value, $type); }
if (substr($parts, -3) === '.js') { $mimetype = 'application/javascript'; } else { if (substr($parts, -4) === '.css') { $mimetype = 'text/css'; } else { combo_not_found(); } } $parts = explode('&', $parts); $cache = true; foreach ($parts as $part) { if (empty($part)) { continue; } $part = min_clean_param($part, 'SAFEPATH'); $bits = explode('/', $part); if (count($bits) < 2) { $content .= "\n// Wrong combo resource {$part}!\n"; continue; } //debug($bits); $version = array_shift($bits); if ($version == 'moodle') { //TODO: this is a ugly hack because we should not load any libs here! define('MOODLE_INTERNAL', true); require_once $CFG->libdir . '/moodlelib.php'; $revision = (int) array_shift($bits); if ($revision === -1) { // Revision -1 says please don't cache the JS $cache = false;
// we need just the values from config.php and minlib.php define('ABORT_AFTER_CONFIG', true); require '../config.php'; // this stops immediately at the beginning of lib/setup.php require_once "{$CFG->dirroot}/lib/jslib.php"; if ($slashargument = min_get_slash_argument()) { $slashargument = ltrim($slashargument, '/'); if (substr_count($slashargument, '/') < 2) { header('HTTP/1.0 404 not found'); die('Slash argument must contain both a revision and a file path'); } // image must be last because it may contain "/" list($themename, $rev, $type) = explode('/', $slashargument, 3); $themename = min_clean_param($themename, 'SAFEDIR'); $rev = min_clean_param($rev, 'INT'); $type = min_clean_param($type, 'SAFEDIR'); } else { $themename = min_optional_param('theme', 'standard', 'SAFEDIR'); $rev = min_optional_param('rev', -1, 'INT'); $type = min_optional_param('type', 'head', 'RAW'); } if ($type !== 'head' and $type !== 'footer') { header('HTTP/1.0 404 not found'); die('Theme was not found, sorry.'); } if (file_exists("{$CFG->dirroot}/theme/{$themename}/config.php")) { // exists } else { if (!empty($CFG->themedir) and file_exists("{$CFG->themedir}/{$themename}/config.php")) { // exists } else {
*/ // Disable moodle specific debug messages and any errors in output, // comment out when debugging or better look into error log! define('NO_DEBUG_DISPLAY', true); define('ABORT_AFTER_CONFIG', true); require '../config.php'; if ($slashargument = min_get_slash_argument()) { $slashargument = ltrim($slashargument, '/'); if (substr_count($slashargument, '/') < 3) { font_not_found(); } list($themename, $component, $rev, $font) = explode('/', $slashargument, 4); $themename = min_clean_param($themename, 'SAFEDIR'); $component = min_clean_param($component, 'SAFEDIR'); $rev = min_clean_param($rev, 'INT'); $font = min_clean_param($font, 'RAW'); } else { $themename = min_optional_param('theme', 'standard', 'SAFEDIR'); $component = min_optional_param('component', 'core', 'SAFEDIR'); $rev = min_optional_param('rev', -1, 'INT'); $font = min_optional_param('font', '', 'RAW'); } if (!$font) { font_not_found(); } if (empty($component) or $component === 'moodle' or $component === 'core') { $component = 'core'; } if (preg_match('/^[a-z0-9_-]+\\.woff$/i', $font, $matches)) { // This is the real standard! $font = $matches[0];
if (substr_count($slashargument, '/') < 3) { image_not_found(); } if (strpos($slashargument, '_s/') === 0) { // Can't use SVG $slashargument = substr($slashargument, 3); $usesvg = false; } else { $usesvg = true; } // image must be last because it may contain "/" list($themename, $component, $rev, $image) = explode('/', $slashargument, 4); $themename = min_clean_param($themename, 'SAFEDIR'); $component = min_clean_param($component, 'SAFEDIR'); $rev = min_clean_param($rev, 'INT'); $image = min_clean_param($image, 'SAFEPATH'); } else { $themename = min_optional_param('theme', 'standard', 'SAFEDIR'); $component = min_optional_param('component', 'core', 'SAFEDIR'); $rev = min_optional_param('rev', -1, 'INT'); $image = min_optional_param('image', '', 'SAFEPATH'); $usesvg = (bool) min_optional_param('svg', '1', 'INT'); } if (empty($component) or $component === 'moodle' or $component === 'core') { $component = 'core'; } if (empty($image)) { image_not_found(); } if (file_exists("{$CFG->dirroot}/theme/{$themename}/config.php")) { // exists
// comment out when debugging or better look into error log! define('NO_DEBUG_DISPLAY', true); // we need just the values from config.php and minlib.php define('ABORT_AFTER_CONFIG', true); require '../config.php'; // this stops immediately at the beginning of lib/setup.php require_once "{$CFG->dirroot}/lib/jslib.php"; if ($slashargument = min_get_slash_argument()) { $slashargument = ltrim($slashargument, '/'); if (substr_count($slashargument, '/') < 1) { image_not_found(); } // image must be last because it may contain "/" list($rev, $file) = explode('/', $slashargument, 2); $rev = min_clean_param($rev, 'INT'); $file = '/' . min_clean_param($file, 'SAFEPATH'); } else { $rev = min_optional_param('rev', 0, 'INT'); $file = min_optional_param('jsfile', '', 'RAW'); // 'file' would collide with URL rewriting! } // some security first - pick only files with .js extension in dirroot $jsfiles = array(); $files = explode(',', $file); foreach ($files as $fsfile) { $jsfile = realpath($CFG->dirroot . $fsfile); if ($jsfile === false) { // does not exist continue; } if ($CFG->dirroot === '/') {
/** * Returns the slashargument part of the URL. * * Note: ".php" is NOT allowed in slasharguments, * it is intended for ASCII characters only. * * @param boolean $clean - Should we do cleaning on this path argument. If you set this * to false you MUST be very careful and do the cleaning manually. * @return string */ function min_get_slash_argument($clean = true) { // Note: This code has to work in the same cases as normal get_file_argument(), // but at the same time it may be simpler because we do not have to deal // with encodings and other tricky stuff. $relativepath = ''; if (!empty($_GET['file']) and strpos($_GET['file'], '/') === 0) { // Server is using url rewriting, most probably IIS. // Always clean the result of this function as it may be used in unsafe calls to send_file. $relativepath = $_GET['file']; if ($clean) { $relativepath = min_clean_param($relativepath, 'SAFEPATH'); } return $relativepath; } else if (stripos($_SERVER['SERVER_SOFTWARE'], 'iis') !== false) { if (isset($_SERVER['PATH_INFO']) and $_SERVER['PATH_INFO'] !== '') { $relativepath = urldecode($_SERVER['PATH_INFO']); } } else { if (isset($_SERVER['PATH_INFO'])) { $relativepath = $_SERVER['PATH_INFO']; } } $matches = null; if (preg_match('|^.+\.php(.*)$|i', $relativepath, $matches)) { $relativepath = $matches[1]; } // Always clean the result of this function as it may be used in unsafe calls to send_file. if ($clean) { $relativepath = min_clean_param($relativepath, 'SAFEPATH'); } return $relativepath; }