X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=functions%2Fglobal.php;h=1faeac33917879d79387f97a244b9800fbe273da;hb=aa84daced451fe171b6b606939dba8df6bcab26c;hp=10a861ee8d70fdb846f0a0dcf25f463edac8c53b;hpb=253ca97e54d037d73ff542a68be8c37c89814085;p=squirrelmail.git diff --git a/functions/global.php b/functions/global.php index 10a861ee..1faeac33 100644 --- a/functions/global.php +++ b/functions/global.php @@ -83,6 +83,54 @@ function sqstripslashes(&$array) { } } +/** + * Squelch error output to screen (only) for the given function. + * If the SquirrelMail debug mode SM_DEBUG_MODE_ADVANCED is not + * enabled, error output will not go to the log, either. + * + * This provides an alternative to the @ error-suppression + * operator where errors will not be shown in the interface + * but will show up in the server log file (assuming the + * administrator has configured PHP logging). + * + * @since 1.4.12 and 1.5.2 + * + * @param string $function The function to be executed + * @param array $args The arguments to be passed to the function + * (OPTIONAL; default no arguments) + * NOTE: The caller must take extra action if + * the function being called is supposed + * to use any of the parameters by + * reference. In the following example, + * $x is passed by reference and $y is + * passed by value to the "my_func" + * function. + * sq_call_function_suppress_errors('my_func', array(&$x, $y)); + * + * @return mixed The return value, if any, of the function being + * executed will be returned. + * + */ +function sq_call_function_suppress_errors($function, $args=NULL) { + global $sm_debug_mode; + + $display_errors = ini_get('display_errors'); + ini_set('display_errors', '0'); + + // if advanced debug mode isn't enabled, don't log the error, either + // + if (!($sm_debug_mode & SM_DEBUG_MODE_ADVANCED)) + $error_reporting = error_reporting(0); + + $ret = call_user_func_array($function, $args); + + if (!($sm_debug_mode & SM_DEBUG_MODE_ADVANCED)) + error_reporting($error_reporting); + + ini_set('display_errors', $display_errors); + return $ret; +} + /** * Add a variable to the session. * @param mixed $var the variable to register @@ -326,9 +374,8 @@ function sqsession_destroy() { global $base_uri, $_COOKIE, $_SESSION; - if (isset($_COOKIE[session_name()]) && session_name()) sqsetcookie(session_name(), '', 0, $base_uri); - if (isset($_COOKIE['username']) && $_COOKIE['username']) sqsetcookie('username','',0,$base_uri); - if (isset($_COOKIE['key']) && $_COOKIE['key']) sqsetcookie('key','',0,$base_uri); + if (isset($_COOKIE[session_name()]) && session_name()) sqsetcookie(session_name(), $_COOKIE[session_name()], 1, $base_uri); + if (isset($_COOKIE['key']) && $_COOKIE['key']) sqsetcookie('key','SQMTRASH',1,$base_uri); $sessid = session_id(); if (!empty( $sessid )) { @@ -365,15 +412,23 @@ function sqsession_is_active() { function sqsession_start() { global $base_uri; - @session_start(); + sq_call_function_suppress_errors('session_start'); + // was: @session_start(); $session_id = session_id(); - // session_starts sets the sessionid cookie buth without the httponly var + // session_starts sets the sessionid cookie but without the httponly var // setting the cookie again sets the httponly cookie attribute - sqsetcookie(session_name(),$session_id,false,$base_uri); + // + // need to check if headers have been sent, since sqsession_is_active() + // has become just a passthru to this function, so the sqsetcookie() + // below is called every time, even after headers have already been sent + // + if (!headers_sent()) + sqsetcookie(session_name(),$session_id,false,$base_uri); } + /** * Set a cookie * @param string $sName The name of the cookie. @@ -401,18 +456,18 @@ function sqsetcookie($sName,$sValue='deleted',$iExpire=0,$sPath="",$sDomain="",$ // broken we use the header function for php 5.2 as well. We might change that later. //setcookie($sName,$sValue,(int) $iExpire,$sPath,$sDomain,$bSecure,$bHttpOnly); } else { - if (!empty($Domain)) { + if (!empty($sDomain)) { // Fix the domain to accept domains with and without 'www.'. - if (strtolower(substr($Domain, 0, 4)) == 'www.') $Domain = substr($Domain, 4); - $Domain = '.' . $Domain; + if (strtolower(substr($sDomain, 0, 4)) == 'www.') $sDomain = substr($sDomain, 4); + $sDomain = '.' . $sDomain; // Remove port information. - $Port = strpos($Domain, ':'); - if ($Port !== false) $Domain = substr($Domain, 0, $Port); + $Port = strpos($sDomain, ':'); + if ($Port !== false) $sDomain = substr($sDomain, 0, $Port); } if (!$sValue) $sValue = 'deleted'; header('Set-Cookie: ' . rawurlencode($sName) . '=' . rawurlencode($sValue) - . (empty($iExpires) ? '' : '; expires=' . gmdate('D, d-M-Y H:i:s', $iExpires) . ' GMT') + . (empty($iExpire) ? '' : '; expires=' . gmdate('D, d-M-Y H:i:s', $iExpire) . ' GMT') . (empty($sPath) ? '' : '; path=' . $sPath) . (empty($sDomain) ? '' : '; domain=' . $sDomain) . (!$bSecure ? '' : '; secure') @@ -508,8 +563,11 @@ FIXME: do we WANT to throw an error or a notice or... or return FALSE? * * @param string $directory_path The path (relative or absolute) * to the desired directory. - * @param string $extension The file extension filter (optional; - * default is to return all files (dirs). + * @param mixed $extension The file extension filter - either + * an array of desired extension(s), + * or a comma-separated list of same + * (optional; default is to return + * all files (dirs). * @param boolean $return_filenames_only When TRUE, only file/dir names * are returned, otherwise the * $directory_path string is @@ -534,22 +592,36 @@ FIXME: do we WANT to throw an error or a notice or... or return FALSE? * files or all directories * (optional; default do not * split up return array). - * + * @param boolean $only_sm When TRUE, a security check will + * limit directory access to only + * paths within the SquirrelMail + * installation currently being used + * (optional; default TRUE) * * @return array The requested file/directory list(s). * * @since 1.5.2 * */ -function list_files($directory_path, $extension='', $return_filenames_only=TRUE, +function list_files($directory_path, $extensions='', $return_filenames_only=TRUE, $include_directories=TRUE, $directories_only=FALSE, - $separate_files_and_directories=FALSE) { + $separate_files_and_directories=FALSE, $only_sm=TRUE) { $files = array(); $directories = array(); -//FIXME: do we want to place security restrictions here like only allowing -// directories under SM_PATH? + + // make sure requested path is under SM_PATH if needed + // + if ($only_sm) { + if (strpos(realpath($directory_path), realpath(SM_PATH)) !== 0) { + //plain_error_message(_("Illegal filesystem access was requested")); + echo _("Illegal filesystem access was requested"); + exit; + } + } + + // validate given directory // if (empty($directory_path) @@ -559,7 +631,18 @@ function list_files($directory_path, $extension='', $return_filenames_only=TRUE, } - if (!empty($extension)) $extension = '.' . trim($extension, '.'); + // ensure extensions is an array and is properly formatted + // + if (!empty($extensions)) { + if (!is_array($extensions)) + $extensions = explode(',', $extensions); + $temp_extensions = array(); + foreach ($extensions as $ext) + $temp_extensions[] = '.' . trim(trim($ext), '.'); + $extensions = $temp_extensions; + } else $extensions = array(); + + $directory_path = rtrim($directory_path, '/'); @@ -569,9 +652,10 @@ function list_files($directory_path, $extension='', $return_filenames_only=TRUE, if ($file == '.' || $file == '..') continue; - if (!empty($extension) - && strrpos($file, $extension) !== (strlen($file) - strlen($extension))) - continue; + if (!empty($extensions)) + foreach ($extensions as $ext) + if (strrpos($file, $ext) !== (strlen($file) - strlen($ext))) + continue 2; // only use is_dir() if we really need to (be as efficient as possible) // @@ -646,6 +730,7 @@ function sm_print_r() { print ''; } + /** * Sanitize a value using htmlspecialchars() or similar, but also * recursively run htmlspecialchars() (or similar) on array keys