* @license http://www.gnu.org/copyleft/gpl.html GNU GPL * @copyright (C) 2006,2007 Catalyst IT Ltd http://catalyst.net.nz * @copyright (C) portions from Moodle, (C) Martin Dougiamas http://dougiamas.com */ defined('INTERNAL') || die(); /** * This function creates a Smarty object and sets it up for use within our * podclass app, setting up some variables. * * The variables that it sets up are: * * - THEMEURL: The base url for static content * - WWWROOT: The base url for the podclass system * - USER: The user object * - JAVASCRIPT: A list of javascript files to include in the header. This * list is passed into this function (see below). * - HEADERS: An array of any further headers to set. Each header is just * straight HTML (see below). * * @param array A list of javascript includes. Each include should be just * the name of a file, and reside in {$THEMEURL}js/{filename} * @param array A list of additional headers. These are to be specified as * actual HTML. * @return Smarty */ function &smarty($javascript = array(), $headers = array()) { global $USER, $CFG; require_once(get_config('libroot') . 'smarty/Smarty.class.php'); $smarty =& new Smarty(); $smarty->template_dir = get_config('docroot').'theme/'.get_config('theme').'/templates/'; $smarty->compile_dir = get_config('dataroot').'smarty/compile'; $smarty->cache_dir = get_config('dataroot').'smarty/cache'; $smarty->assign('THEMEURL', get_config('themeurl')); $smarty->assign('WWWROOT', get_config('wwwroot')); $smarty->assign_by_ref('USER', $USER); foreach ($javascript as &$value) { if ($value == 'mochikit') { $value = get_config('wwwroot').'js/mochikit/MochiKit.js'; } // more later... } $smarty->assign_by_ref('JAVASCRIPT', $javascript); $smarty->assign_by_ref('HEADERS', $headers); return $smarty; } function clean_requestdata($paramname,$paramtype,$where=REQUEST_EITHER) { $cleanversion = ''; if ($where == REQUEST_POST || $where == REQUEST_EITHER) { // post overrides get for either if (array_key_exists($paramname,$_POST)) { $cleanversion = $_POST[$paramname]; } } // now check get. if (empty($cleanversion) && $where != REQUEST_POST && array_key_exists($paramname,$_GET)) { $cleanversion = $_GET[$paramname]; } // if it's not where we asked for it, return null if ('' == $cleanversion) { return null; } if (is_array($cleanversion)) { $new = array(); foreach ($cleanversion as $key => $value) { $new[$key] = clean_parameter($value); } return $new; } else { return clean_param($cleanversion, $paramtype); } } /** * clean the variables and/or cast to specific types, based on * an options field. * * @uses PARAM_INT * @uses PARAM_INTEGER * @uses PARAM_ALPHA * @uses PARAM_ALPHANUM * @uses PARAM_NOTAGS * @uses PARAM_ALPHAEXT * @uses PARAM_BOOL * @uses PARAM_SAFEDIR * @uses PARAM_CLEANFILE * @uses PARAM_FILE * @uses PARAM_PATH * @uses PARAM_HOST * @uses PARAM_URL * @uses PARAM_LOCALURL * @uses PARAM_CLEANHTML * @uses PARAM_SEQUENCE * @param mixed $param the variable we are cleaning * @param int $type expected format of param after cleaning. * @return mixed */ function clean_param($param, $type) { if (is_array($param)) { // Let's loop $newparam = array(); foreach ($param as $key => $value) { $newparam[$key] = clean_param($value, $type); } return $newparam; } switch ($type) { case PARAM_CLEANHTML: // prepare html fragment for display, do not store it into db!! $param = stripslashes($param); // Remove any slashes $param = clean_text($param); // Sweep for scripts, etc return trim($param); case PARAM_INT: return (int)$param; // Convert to integer case PARAM_ALPHA: // Remove everything not a-z return eregi_replace('[^a-zA-Z]', '', $param); case PARAM_ALPHANUM: // Remove everything not a-zA-Z0-9 return eregi_replace('[^A-Za-z0-9]', '', $param); case PARAM_ALPHAEXT: // Remove everything not a-zA-Z/_-. return eregi_replace('[^.a-zA-Z/_-]', '', $param); case PARAM_SEQUENCE: // Remove everything not 0-9, return eregi_replace('[^0-9,]', '', $param); case PARAM_BOOL: // Convert to 1 or 0 $tempstr = strtolower($param); if ($tempstr == 'on' or $tempstr == 'yes' ) { $param = 1; } else if ($tempstr == 'off' or $tempstr == 'no') { $param = 0; } else { $param = empty($param) ? 0 : 1; } return $param; case PARAM_NOTAGS: // Strip all tags return strip_tags($param); case PARAM_MULTILANG: // leave only tags needed for multilang return clean_param(strip_tags($param, ''), PARAM_CLEAN); case PARAM_SAFEDIR: // Remove everything not a-zA-Z0-9_- return eregi_replace('[^a-zA-Z0-9_-]', '', $param); case PARAM_CLEANFILE: // allow only safe characters return clean_filename($param); case PARAM_FILE: // Strip all suspicious characters from filename $param = ereg_replace('[[:cntrl:]]|[<>"`\|\':\\/]', '', $param); $param = ereg_replace('\.\.+', '', $param); if($param == '.') { $param = ''; } return $param; case PARAM_PATH: // Strip all suspicious characters from file path $param = str_replace('\\\'', '\'', $param); $param = str_replace('\\"', '"', $param); $param = str_replace('\\', '/', $param); $param = ereg_replace('[[:cntrl:]]|[<>"`\|\':]', '', $param); $param = ereg_replace('\.\.+', '', $param); $param = ereg_replace('//+', '/', $param); return ereg_replace('/(\./)+', '/', $param); case PARAM_HOST: // allow FQDN or IPv4 dotted quad preg_replace('/[^\.\d\w-]/','', $param ); // only allowed chars // match ipv4 dotted quad if (preg_match('/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/',$param, $match)){ // confirm values are ok if ( $match[0] > 255 || $match[1] > 255 || $match[3] > 255 || $match[4] > 255 ) { // hmmm, what kind of dotted quad is this? $param = ''; } } elseif ( preg_match('/^[\w\d\.-]+$/', $param) // dots, hyphens, numbers && !preg_match('/^[\.-]/', $param) // no leading dots/hyphens && !preg_match('/[\.-]$/', $param) // no trailing dots/hyphens ) { // all is ok - $param is respected } else { // all is not ok... $param=''; } return $param; case PARAM_URL: // allow safe ftp, http, mailto urls include_once(get_config('libroot').'validateurlsyntax.php'); if (!empty($param) && validateUrlSyntax($param, 's?H?S?F?E?u-P-a?I?p-f?q?r?')) { // all is ok, param is respected } else { $param =''; // not really ok } return $param; case PARAM_LOCALURL: // allow http absolute, root relative and relative URLs within wwwroot clean_param($param, PARAM_URL); if (!empty($param)) { if (preg_match(':^/:', $param)) { // root-relative, ok! } elseif (preg_match('/^'.preg_quote(get_config('wwwroot')).'/i',$param)) { // absolute, and matches our wwwroot } else { // relative - let's make sure there are no tricks if (validateUrlSyntax($param, 's-u-P-a-p-f+q?r?')) { // looks ok. } else { $param = ''; } } } return $param; default: // throw error, switched parameters in optional_param or another serious problem // @todo nigel hissy fit error("Unknown parameter type: $type"); } } /** * Given raw text (eg typed in by a user), this function cleans it up * and removes any nasty tags that could mess up Moodle pages. * * @uses ALLOWED_TAGS * @param string $text The text to be cleaned * @return string The cleaned up text */ function clean_text($text) { global $ALLOWED_TAGS; /// Fix non standard entity notations $text = preg_replace('/(&#[0-9]+)(;?)/', "\\1;", $text); $text = preg_replace('/(&#x[0-9a-fA-F]+)(;?)/', "\\1;", $text); /// Remove tags that are not allowed $text = strip_tags($text, $ALLOWED_TAGS); /// Clean up embedded scripts and , using kses $text = cleanAttributes($text); /// Remove script events $text = eregi_replace("([^a-z])language([[:space:]]*)=", "\\1Xlanguage=", $text); $text = eregi_replace("([^a-z])on([a-z]+)([[:space:]]*)=", "\\1Xon\\2=", $text); return $text; } /** * This function takes a string and examines it for HTML tags. * If tags are detected it passes the string to a helper function {@link cleanAttributes2()} * which checks for attributes and filters them for malicious content * 17/08/2004 :: Eamon DOT Costello AT dcu DOT ie * * @param string $str The string to be examined for html tags * @return string */ function cleanAttributes($str){ $result = preg_replace_callback( '%(<[^>]*(>|$)|>)%m', #search for html tags "cleanAttributes2", $str ); return $result; } /** * This function takes a string with an html tag and strips out any unallowed * protocols e.g. javascript: * It calls ancillary functions in kses which are prefixed by kses * 17/08/2004 :: Eamon DOT Costello AT dcu DOT ie * * @param array $htmlArray An array from {@link cleanAttributes()}, containing in its 1st * element the html to be cleared * @return string */ function cleanAttributes2($htmlArray){ global $CFG, $ALLOWED_PROTOCOLS; require_once(get_config('libroot').'kses.php'); $htmlTag = $htmlArray[1]; if (substr($htmlTag, 0, 1) != '<') { return '>'; //a single character ">" detected } if (!preg_match('%^<\s*(/\s*)?([a-zA-Z0-9]+)([^>]*)>?$%', $htmlTag, $matches)) { return ''; // It's seriously malformed } $slash = trim($matches[1]); //trailing xhtml slash $elem = $matches[2]; //the element name $attrlist = $matches[3]; // the list of attributes as a string $attrArray = kses_hair($attrlist, $ALLOWED_PROTOCOLS); $attStr = ''; foreach ($attrArray as $arreach) { $arreach['name'] = strtolower($arreach['name']); if ($arreach['name'] == 'style') { $value = $arreach['value']; while (true) { $prevvalue = $value; $value = kses_no_null($value); $value = preg_replace("/\/\*.*\*\//Us", '', $value); $value = kses_decode_entities($value); $value = preg_replace('/(&#[0-9]+)(;?)/', "\\1;", $value); $value = preg_replace('/(&#x[0-9a-fA-F]+)(;?)/', "\\1;", $value); if ($value === $prevvalue) { $arreach['value'] = $value; break; } } $arreach['value'] = preg_replace("/j\s*a\s*v\s*a\s*s\s*c\s*r\s*i\s*p\s*t/i", "Xjavascript", $arreach['value']); $arreach['value'] = preg_replace("/e\s*x\s*p\s*r\s*e\s*s\s*s\s*i\s*o\s*n/i", "Xexpression", $arreach['value']); } $attStr .= ' '.$arreach['name'].'="'.$arreach['value'].'" '; } // Remove last space from attribute list $attStr = rtrim($attStr); $xhtml_slash = ''; if (preg_match('%/\s*$%', $attrlist)) { $xhtml_slash = ' /'; } return '<'. $slash . $elem . $attStr . $xhtml_slash .'>'; } ?>