Fixed bug #11937: Do not show E_DEPRECATED messages on productive systems
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_div.php
index e198c77..76ed5ba 100644 (file)
@@ -308,7 +308,6 @@ final class t3lib_div {
         *
         * @param       string          GET/POST var to return
         * @return      mixed           POST var named $var and if not set, the GET var of the same name.
-        * @see GPvar()
         */
        public static function _GP($var)        {
                if(empty($var)) return;
@@ -320,6 +319,22 @@ final class t3lib_div {
        }
 
        /**
+        * Returns the global arrays $_GET and $_POST merged with $_POST taking precedence.
+        *
+        * @param       string          Key (variable name) from GET or POST vars
+        * @return      array           Returns the GET vars merged recursively onto the POST vars.
+        */
+       public static function _GPmerged($parameter) {
+               $postParameter = is_array($_POST[$parameter]) ? $_POST[$parameter] : array();
+               $getParameter  = is_array($_GET[$parameter])  ? $_GET[$parameter]  : array();
+
+               $mergedParameters = t3lib_div::array_merge_recursive_overrule($getParameter, $postParameter);
+               t3lib_div::stripSlashesOnArray($mergedParameters);
+
+               return $mergedParameters;
+       }
+
+       /**
         * Returns the global $_GET array (or value from) normalized to contain un-escaped values.
         * ALWAYS use this API function to acquire the GET variables!
         * Usage: 27
@@ -403,13 +418,13 @@ final class t3lib_div {
         *
         * @param       string          Key (variable name) from GET or POST vars
         * @return      array           Returns the GET vars merged recursively onto the POST vars.
+        * @deprecated since TYPO3 3.7 - Use t3lib_div::_GPmerged instead
+        * @see _GP()
         */
        public static function GParrayMerged($var)      {
-               $postA = is_array($_POST[$var]) ? $_POST[$var] : array();
-               $getA = is_array($_GET[$var]) ? $_GET[$var] : array();
-               $mergedA = t3lib_div::array_merge_recursive_overrule($getA,$postA);
-               t3lib_div::stripSlashesOnArray($mergedA);
-               return $mergedA;
+               self::logDeprecatedFunction();
+
+               return self::_GPmerged($var);
        }
 
        /**
@@ -603,13 +618,14 @@ final class t3lib_div {
         * @param       string          string to truncate
         * @param       integer         must be an integer with an absolute value of at least 4. if negative the string is cropped from the right end.
         * @param       string          appendix to the truncated string
-        * @return      string          New string
+        * @return      string          cropped string
         */
        public static function fixed_lgd_cs($string, $chars, $appendString='...') {
                if (is_object($GLOBALS['LANG'])) {
                        return $GLOBALS['LANG']->csConvObj->crop($GLOBALS['LANG']->charSet, $string, $chars, $appendString);
                } elseif (is_object($GLOBALS['TSFE'])) {
-                       return $GLOBALS['TSFE']->csConvObj->crop($GLOBALS['TSFE']->charSet, $string, $chars, $appendString);
+                       $charSet = ($GLOBALS['TSFE']->renderCharset != '' ? $GLOBALS['TSFE']->renderCharset : $GLOBALS['TSFE']->defaultCharSet);
+                       return $GLOBALS['TSFE']->csConvObj->crop($charSet, $string, $chars, $appendString);
                } else {
                                // this case should not happen
                        $csConvObj = t3lib_div::makeInstance('t3lib_cs');
@@ -917,6 +933,17 @@ final class t3lib_div {
        }
 
        /**
+        * Checks if a given URL matches the host that currently handles this HTTP request.
+        * Scheme, hostname and (optional) port of the given URL are compared.
+        *
+        * @param       string          $url: URL to compare with the TYPO3 request host
+        * @return      boolean         Whether the URL matches the TYPO3 request host
+        */
+       public static function isOnCurrentHost($url) {
+               return (stripos($url . '/', self::getIndpEnv('TYPO3_REQUEST_HOST') . '/') === 0);
+       }
+
+       /**
         * Check for item in list
         * Check if an item exists in a comma-separated list of items.
         * Usage: 163
@@ -1598,6 +1625,16 @@ final class t3lib_div {
                return self::strtolower(substr($string, 0, 1)) . substr($string, 1);
        }
 
+       /**
+        * Checks if a given string is a Uniform Resource Locator (URL).
+        *
+        * @param       string          $url: The URL to be validated
+        * @return      boolean         Whether the given URL is valid
+        */
+       public static function isValidUrl($url) {
+               return (filter_var($url, FILTER_VALIDATE_URL) !== false);
+       }
+
 
 
 
@@ -1719,7 +1756,13 @@ final class t3lib_div {
                }
 
                if ($limit != 0) {
-                       $result = array_slice($result, 0, $limit);
+                       if ($limit < 0) {
+                               $result = array_slice($result, 0, $limit);
+                       } elseif (count($result) > $limit) {
+                               $lastElements = array_slice($result, $limit - 1);
+                               $result = array_slice($result, 0, $limit - 1);
+                               $result[] = implode($delim, $lastElements);
+                       }
                }
 
                return $result;
@@ -1898,6 +1941,7 @@ final class t3lib_div {
                        } else {
                                $value = addslashes($value);
                        }
+                       unset($value);
                }
                reset($theArray);
        }
@@ -1919,6 +1963,7 @@ final class t3lib_div {
                        } else {
                                $value = stripslashes($value);
                        }
+                       unset($value);
                }
                reset($theArray);
        }
@@ -1938,6 +1983,23 @@ final class t3lib_div {
        }
 
        /**
+       * Rename Array keys with a given mapping table
+       * @param        array   Array by reference which should be remapped
+       * @param        array   Array with remap information, array/$oldKey => $newKey)
+       */
+       function remapArrayKeys(&$array, $mappingTable) {
+               if (is_array($mappingTable)) {
+                       foreach ($mappingTable as $old => $new) {
+                               if ($new && isset($array[$old])) {
+                                       $array[$new] = $array[$old];
+                                       unset ($array[$old]);
+                               }
+                       }
+               }
+       }
+
+
+       /**
         * Merges two arrays recursively and "binary safe" (integer keys are
         * overridden as well), overruling similar values in the first array
         * ($arr0) with the values of the second array ($arr1)
@@ -2445,15 +2507,51 @@ final class t3lib_div {
        /**
         * Converts an XML string to a PHP array.
         * This is the reverse function of array2xml()
+        * This is a wrapper for xml2arrayProcess that adds a two-level cache
         * Usage: 17
         *
         * @param       string          XML content to convert into an array
         * @param       string          The tag-prefix resolve, eg. a namespace like "T3:"
         * @param       boolean         If set, the document tag will be set in the key "_DOCUMENT_TAG" of the output array
         * @return      mixed           If the parsing had errors, a string with the error message is returned. Otherwise an array with the content.
-        * @see array2xml()
+        * @see array2xml(),xml2arrayProcess()
+        * @author      Fabrizio Branca <typo3@fabrizio-branca.de> (added caching)
         */
        public static function xml2array($string,$NSprefix='',$reportDocTag=FALSE) {
+               static $firstLevelCache = array();
+
+               $identifier = md5($string . $NSprefix . ($reportDocTag ? '1' : '0'));
+
+                       // look up in first level cache
+               if (!empty($firstLevelCache[$identifier])) {
+                       $array = $firstLevelCache[$identifier];
+               } else {
+                               // look up in second level cache
+                       $cacheContent = t3lib_pageSelect::getHash($identifier, 0);
+                       $array = unserialize($cacheContent);
+
+                       if ($array === false) {
+                               $array = self::xml2arrayProcess($string, $NSprefix, $reportDocTag);
+                               t3lib_pageSelect::storeHash($identifier, serialize($array), 'ident_xml2array');
+                       }
+                               // store content in first level cache
+                       $firstLevelCache[$identifier] = $array;
+               }
+               return $array;
+       }
+
+       /**
+        * Converts an XML string to a PHP array.
+        * This is the reverse function of array2xml()
+        * Usage: 1
+        *
+        * @param       string          XML content to convert into an array
+        * @param       string          The tag-prefix resolve, eg. a namespace like "T3:"
+        * @param       boolean         If set, the document tag will be set in the key "_DOCUMENT_TAG" of the output array
+        * @return      mixed           If the parsing had errors, a string with the error message is returned. Otherwise an array with the content.
+        * @see array2xml()
+        */
+       protected function xml2arrayProcess($string,$NSprefix='',$reportDocTag=FALSE) {
                global $TYPO3_CONF_VARS;
 
                        // Create parser:
@@ -2858,10 +2956,12 @@ final class t3lib_div {
        }
 
        /**
-        * Setting file system mode & group ownership of file
+        * Sets the file system mode and group ownership of file.
         *
-        * @param       string          Filepath of newly created file
-        * @return      void
+        * @param string $file
+        *               the path of an existing file, must not be escaped
+        *
+        * @return void
         */
        public static function fixPermissions($file)    {
                if (@is_file($file) && TYPO3_OS!='WIN') {
@@ -3001,18 +3101,20 @@ final class t3lib_div {
         * @return      array           Returns an array with the directory entries as values. If no path, the return value is nothing.
         */
        public static function get_dirs($path)  {
-               if ($path)      {
-                       $d = @dir($path);
-                       if (is_object($d))      {
-                               while(false !== ($entry=$d->read())) {
-                                       if (@is_dir($path.'/'.$entry) && $entry!= '..' && $entry!= '.') {
-                                               $filearray[]=$entry;
+               if ($path) {
+                       if (is_dir($path)) {
+                               $dir = scandir($path);
+                               $dirs = array();
+                               foreach ($dir as $entry) {
+                                       if (is_dir($path . '/' . $entry) && $entry != '..' && $entry != '.') {
+                                               $dirs[] = $entry;
                                        }
                                }
-                               $d->close();
-                       } else return 'error';
-                       return $filearray;
+                       } else {
+                               $dirs = 'error';
+                       }
                }
+               return $dirs;
        }
 
        /**
@@ -3173,7 +3275,7 @@ final class t3lib_div {
 
        /**
         * Returns the maximum upload size for a file that is allowed. Measured in KB.
-        * This might be handy to find out the real upload limit that is possible for this 
+        * This might be handy to find out the real upload limit that is possible for this
         * TYPO3 installation. The first parameter can be used to set something that overrides
         * the maxFileSize, usually for the TCA values.
         *
@@ -3218,6 +3320,31 @@ final class t3lib_div {
                return $bytes;
        }
 
+       /**
+        * Retrieves the maximum path length that is valid in the current environment.
+        *
+        * @return integer The maximum available path length
+        * @author Ingo Renner <ingo@typo3.org>
+        */
+       public static function getMaximumPathLength() {
+               $maximumPathLength = 0;
+
+               if (version_compare(PHP_VERSION, '5.3.0', '<')) {
+                               // rough assumptions
+                       if (TYPO3_OS == 'WIN') {
+                                       // WIN is usually 255, Vista 260, although NTFS can hold about 2k
+                               $maximumPathLength = 255;
+                       } else {
+                               $maximumPathLength = 2048;
+                       }
+               } else {
+                               // precise information is available since PHP 5.3
+                       $maximumPathLength = PHP_MAXPATHLEN;
+               }
+
+               return $maximumPathLength;
+       }
+
 
 
 
@@ -3613,7 +3740,7 @@ final class t3lib_div {
 
                switch ((string)$getEnvName)    {
                        case 'SCRIPT_NAME':
-                               $retVal = (php_sapi_name()=='cgi'||php_sapi_name()=='cgi-fcgi')&&($_SERVER['ORIG_PATH_INFO']?$_SERVER['ORIG_PATH_INFO']:$_SERVER['PATH_INFO']) ? ($_SERVER['ORIG_PATH_INFO']?$_SERVER['ORIG_PATH_INFO']:$_SERVER['PATH_INFO']) : ($_SERVER['ORIG_SCRIPT_NAME']?$_SERVER['ORIG_SCRIPT_NAME']:$_SERVER['SCRIPT_NAME']);
+                               $retVal = (PHP_SAPI=='cgi'||PHP_SAPI=='cgi-fcgi')&&($_SERVER['ORIG_PATH_INFO']?$_SERVER['ORIG_PATH_INFO']:$_SERVER['PATH_INFO']) ? ($_SERVER['ORIG_PATH_INFO']?$_SERVER['ORIG_PATH_INFO']:$_SERVER['PATH_INFO']) : ($_SERVER['ORIG_SCRIPT_NAME']?$_SERVER['ORIG_SCRIPT_NAME']:$_SERVER['SCRIPT_NAME']);
                                        // add a prefix if TYPO3 is behind a proxy: ext-domain.com => int-server.com/prefix
                                if (t3lib_div::cmpIP($_SERVER['REMOTE_ADDR'], $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyIP'])) {
                                        if (t3lib_div::getIndpEnv('TYPO3_SSL') && $GLOBALS['TYPO3_CONF_VARS']['SYS']['reverseProxyPrefixSSL']) {
@@ -3624,7 +3751,7 @@ final class t3lib_div {
                                }
                        break;
                        case 'SCRIPT_FILENAME':
-                               $retVal = str_replace('//','/', str_replace('\\','/', (php_sapi_name()=='cgi'||php_sapi_name()=='isapi' ||php_sapi_name()=='cgi-fcgi')&&($_SERVER['ORIG_PATH_TRANSLATED']?$_SERVER['ORIG_PATH_TRANSLATED']:$_SERVER['PATH_TRANSLATED'])? ($_SERVER['ORIG_PATH_TRANSLATED']?$_SERVER['ORIG_PATH_TRANSLATED']:$_SERVER['PATH_TRANSLATED']):($_SERVER['ORIG_SCRIPT_FILENAME']?$_SERVER['ORIG_SCRIPT_FILENAME']:$_SERVER['SCRIPT_FILENAME'])));
+                               $retVal = str_replace('//','/', str_replace('\\','/', (PHP_SAPI=='cgi'||PHP_SAPI=='isapi' ||PHP_SAPI=='cgi-fcgi')&&($_SERVER['ORIG_PATH_TRANSLATED']?$_SERVER['ORIG_PATH_TRANSLATED']:$_SERVER['PATH_TRANSLATED'])? ($_SERVER['ORIG_PATH_TRANSLATED']?$_SERVER['ORIG_PATH_TRANSLATED']:$_SERVER['PATH_TRANSLATED']):($_SERVER['ORIG_SCRIPT_FILENAME']?$_SERVER['ORIG_SCRIPT_FILENAME']:$_SERVER['SCRIPT_FILENAME'])));
                        break;
                        case 'REQUEST_URI':
                                        // Typical application of REQUEST_URI is return urls, forms submitting to itself etc. Example: returnUrl='.rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI'))
@@ -3649,9 +3776,9 @@ final class t3lib_div {
                        case 'PATH_INFO':
                                        // $_SERVER['PATH_INFO']!=$_SERVER['SCRIPT_NAME'] is necessary because some servers (Windows/CGI) are seen to set PATH_INFO equal to script_name
                                        // Further, there must be at least one '/' in the path - else the PATH_INFO value does not make sense.
-                                       // IF 'PATH_INFO' never works for our purpose in TYPO3 with CGI-servers, then 'php_sapi_name()=='cgi'' might be a better check. Right now strcmp($_SERVER['PATH_INFO'],t3lib_div::getIndpEnv('SCRIPT_NAME')) will always return false for CGI-versions, but that is only as long as SCRIPT_NAME is set equal to PATH_INFO because of php_sapi_name()=='cgi' (see above)
+                                       // IF 'PATH_INFO' never works for our purpose in TYPO3 with CGI-servers, then 'PHP_SAPI=='cgi'' might be a better check. Right now strcmp($_SERVER['PATH_INFO'],t3lib_div::getIndpEnv('SCRIPT_NAME')) will always return false for CGI-versions, but that is only as long as SCRIPT_NAME is set equal to PATH_INFO because of PHP_SAPI=='cgi' (see above)
 //                             if (strcmp($_SERVER['PATH_INFO'],t3lib_div::getIndpEnv('SCRIPT_NAME')) && count(explode('/',$_SERVER['PATH_INFO']))>1)  {
-                               if (php_sapi_name()!='cgi' && php_sapi_name()!='cgi-fcgi')      {
+                               if (PHP_SAPI!='cgi' && PHP_SAPI!='cgi-fcgi')    {
                                        $retVal = $_SERVER['PATH_INFO'];
                                }
                        break;
@@ -3815,15 +3942,12 @@ final class t3lib_div {
        }
 
        /**
-        * milliseconds
-        * microtime recalculated to t3lib_div::milliseconds(1/1000 sec)
-        * Usage: 20
+        * Gets the unixtime as milliseconds.
         *
-        * @return      integer
+        * @return      integer         The unixtime as milliseconds
         */
-       public static function milliseconds()   {
-               $p=explode(' ',microtime());
-               return round(($p[0]+$p[1])*1000);
+       public static function milliseconds() {
+               return round(microtime(true) * 1000);
        }
 
        /**
@@ -4040,6 +4164,49 @@ final class t3lib_div {
        }
 
        /**
+        * Checks if a given string is a valid frame URL to be loaded in the
+        * backend.
+        *
+        * @param string $url potential URL to check
+        *
+        * @return string either $url if $url is considered to be harmless, or an
+        *                empty string otherwise
+        */
+       public static function sanitizeLocalUrl($url = '') {
+               $sanitizedUrl = '';
+               $decodedUrl = rawurldecode($url);
+
+               if (!empty($url) && self::removeXSS($decodedUrl) === $decodedUrl) {
+                       $testAbsoluteUrl = self::resolveBackPath($decodedUrl);
+                       $testRelativeUrl = self::resolveBackPath(
+                               t3lib_div::dirname(t3lib_div::getIndpEnv('SCRIPT_NAME')) . '/' . $decodedUrl
+                       );
+
+                               // Pass if URL is on the current host:
+                       if (self::isValidUrl($decodedUrl)) {
+                               if (self::isOnCurrentHost($decodedUrl) && strpos($decodedUrl, self::getIndpEnv('TYPO3_SITE_URL')) === 0) {
+                                       $sanitizedUrl = $url;
+                               }
+                               // Pass if URL is an absolute file path:
+                       } elseif (self::isAbsPath($decodedUrl) && self::isAllowedAbsPath($decodedUrl)) {
+                               $sanitizedUrl = $url;
+                               // Pass if URL is absolute and below TYPO3 base directory:
+                       } elseif (strpos($testAbsoluteUrl, self::getIndpEnv('TYPO3_SITE_PATH')) === 0 && substr($decodedUrl, 0, 1) === '/') {
+                               $sanitizedUrl = $url;
+                               // Pass if URL is relative and below TYPO3 base directory:
+                       } elseif (strpos($testRelativeUrl, self::getIndpEnv('TYPO3_SITE_PATH')) === 0 && substr($decodedUrl, 0, 1) !== '/') {
+                               $sanitizedUrl = $url;
+                       }
+               }
+
+               if (!empty($url) && empty($sanitizedUrl)) {
+                       self::sysLog('The URL "' . $url . '" is not considered to be local and was denied.', 'Core', self::SYSLOG_SEVERITY_NOTICE);
+               }
+
+               return $sanitizedUrl;
+       }
+
+       /**
         * Moves $source file to $destination if uploaded, otherwise try to make a copy
         * Usage: 4
         *
@@ -4150,7 +4317,7 @@ final class t3lib_div {
         *
         * @param       string          Query-parameters: "&xxx=yyy&zzz=uuu"
         * @return      array           Array with key/value pairs of query-parameters WITHOUT a certain list of variable names (like id, type, no_cache etc.) and WITH a variable, encryptionKey, specific for this server/installation
-        * @see tslib_fe::makeCacheHash(), tslib_cObj::typoLink()
+        * @see tslib_fe::makeCacheHash(), tslib_cObj::typoLink(), t3lib_div::calculateCHash()
         */
        public static function cHashParams($addQueryParams) {
                $params = explode('&',substr($addQueryParams,1));       // Splitting parameters up
@@ -4186,6 +4353,30 @@ final class t3lib_div {
        }
 
        /**
+        * Returns the cHash based on provided query parameters and added values from internal call
+        *
+        * @param       string          Query-parameters: "&xxx=yyy&zzz=uuu"
+        * @return      string          Hash of all the values
+        * @see t3lib_div::cHashParams(), t3lib_div::calculateCHash()
+        */
+       public static function generateCHash($addQueryParams) {
+               $cHashParams = t3lib_div::cHashParams($addQueryParams);
+               $cHash = t3lib_div::calculateCHash($cHashParams);
+               return $cHash;
+       }
+
+       /**
+        * Calculates the cHash based on the provided parameters
+        *
+        * @param       array           Array of key-value pairs
+        * @return      string          Hash of all the values
+        */
+       public static function calculateCHash($params) {
+               $cHash = md5(serialize($params));
+               return $cHash;
+       }
+
+       /**
         * Responds on input localization setting value whether the page it comes from should be hidden if no translation exists or not.
         *
         * @param       integer         Value from "l18n_cfg" field of a page record
@@ -4205,10 +4396,13 @@ final class t3lib_div {
         * @param       string          Input is a file-reference (see t3lib_div::getFileAbsFileName). That file is expected to be a 'locallang.php' file containing a $LOCAL_LANG array (will be included!) or a 'locallang.xml' file conataining a valid XML TYPO3 language structure.
         * @param       string          Language key
         * @param       string          Character set (option); if not set, determined by the language key
-        * @return      array           Value of $LOCAL_LANG found in the included file. If that array is found it's returned. Otherwise an empty array
+        * @param       integer         Error mode (when file could not be found): 0 - call debug(), 1 - do nothing, 2 - throw an exception
+        * @return      array           Value of $LOCAL_LANG found in the included file. If that array is found it  will returned.
+        *                                              Otherwise an empty array and it is FALSE in error case.
         */
-       public static function readLLfile($fileRef, $langKey, $charset='')      {
+       public static function readLLfile($fileRef, $langKey, $charset = '', $errorMode = 0)    {
 
+               $result = FALSE;
                $file = t3lib_div::getFileAbsFileName($fileRef);
                if ($file)      {
                        $baseFile = preg_replace('/\.(php|xml)$/', '', $file);
@@ -4224,11 +4418,28 @@ final class t3lib_div {
                                                $LOCAL_LANG = array('default'=>$LOCAL_LANG['default'], $langKey=>$LOCAL_LANG[$langKey]); }
                                }
                        } else {
-                               die('File "' . $fileRef. '" not found!');
+                               $errorMsg = 'File "' . $fileRef. '" not found!';
+                               if ($errorMode == 2) {
+                                       throw new t3lib_exception($errorMsg);
+                               } elseif(!$errorMode)   {
+                                       debug($errorMsg, 1);
+                               }
+                               $fileNotFound = TRUE;
+                       }
+                       if (is_array($GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride'][$fileRef])) {
+                               foreach ($GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride'][$fileRef] as $overrideFile) {
+                                       $languageOverrideFileName = t3lib_div::getFileAbsFileName($overrideFile);
+                                       if (@is_file($languageOverrideFileName)) {
+                                               $languageOverrideArray = t3lib_div::readLLXMLfile($languageOverrideFileName, $langKey, $charset);
+                                               $LOCAL_LANG = t3lib_div::array_merge_recursive_overrule($LOCAL_LANG, $languageOverrideArray);
+                                       }
+                               }
                        }
                }
-
-               return is_array($LOCAL_LANG) ? $LOCAL_LANG : array();
+               if ($fileNotFound !== TRUE)     {
+                       $result = is_array($LOCAL_LANG) ? $LOCAL_LANG : array();
+               }
+               return $result;
        }
 
        /**
@@ -4243,9 +4454,9 @@ final class t3lib_div {
        public static function readLLPHPfile($fileRef, $langKey, $charset='')   {
 
                if (is_object($GLOBALS['LANG']))        {
-                       $csConvObj = &$GLOBALS['LANG']->csConvObj;
+                       $csConvObj = $GLOBALS['LANG']->csConvObj;
                } elseif (is_object($GLOBALS['TSFE']))  {
-                       $csConvObj = &$GLOBALS['TSFE']->csConvObj;
+                       $csConvObj = $GLOBALS['TSFE']->csConvObj;
                } else {
                        $csConvObj = t3lib_div::makeInstance('t3lib_cs');
                }
@@ -4318,9 +4529,9 @@ final class t3lib_div {
        public static function readLLXMLfile($fileRef, $langKey, $charset='')   {
 
                if (is_object($GLOBALS['LANG']))        {
-                       $csConvObj = &$GLOBALS['LANG']->csConvObj;
+                       $csConvObj = $GLOBALS['LANG']->csConvObj;
                } elseif (is_object($GLOBALS['TSFE']))  {
-                       $csConvObj = &$GLOBALS['TSFE']->csConvObj;
+                       $csConvObj = $GLOBALS['TSFE']->csConvObj;
                } else {
                        $csConvObj = t3lib_div::makeInstance('t3lib_cs');
                }
@@ -4649,11 +4860,11 @@ final class t3lib_div {
                                        // Get/Create object of class:
                                if ($storePersistentObject)     {       // Get reference to current instance of class:
                                        if (!is_object($GLOBALS['T3_VAR']['callUserFunction_classPool'][$parts[0]]))    {
-                                               $GLOBALS['T3_VAR']['callUserFunction_classPool'][$parts[0]] = &t3lib_div::makeInstance($parts[0]);
+                                               $GLOBALS['T3_VAR']['callUserFunction_classPool'][$parts[0]] = t3lib_div::makeInstance($parts[0]);
                                        }
-                                       $classObj = &$GLOBALS['T3_VAR']['callUserFunction_classPool'][$parts[0]];
+                                       $classObj = $GLOBALS['T3_VAR']['callUserFunction_classPool'][$parts[0]];
                                } else {        // Create new object:
-                                       $classObj = &t3lib_div::makeInstance($parts[0]);
+                                       $classObj = t3lib_div::makeInstance($parts[0]);
                                }
 
                                if (method_exists($classObj, $parts[1]))        {
@@ -4712,7 +4923,7 @@ final class t3lib_div {
         * @return      object          The instance of the class asked for. Instance is created with t3lib_div::makeInstance
         * @see callUserFunction()
         */
-       public static function &getUserObj($classRef,$checkPrefix='user_',$silent=0)    {
+       public static function getUserObj($classRef, $checkPrefix='user_', $silent=false) {
                global $TYPO3_CONF_VARS;
                        // Check persistent object and if found, call directly and exit.
                if (is_object($GLOBALS['T3_VAR']['getUserObj'][$classRef]))     {
@@ -4747,11 +4958,11 @@ final class t3lib_div {
 
                                // Check if class exists:
                        if (class_exists($class))       {
-                               $classObj = &t3lib_div::makeInstance($class);
+                               $classObj = t3lib_div::makeInstance($class);
 
                                        // If persistent object should be created, set reference:
                                if ($storePersistentObject)     {
-                                       $GLOBALS['T3_VAR']['getUserObj'][$classRef] = &$classObj;
+                                       $GLOBALS['T3_VAR']['getUserObj'][$classRef] = $classObj;
                                }
 
                                return $classObj;
@@ -4771,17 +4982,10 @@ final class t3lib_div {
         * @param       string          Class name to instantiate
         * @return      object          A reference to the object
         */
-       public static function &makeInstance($className) {
+       public static function makeInstance($className) {
                        // holds references of singletons
                static $instances = array();
 
-                       // Load class file if not found:
-               if (!class_exists($className))  {
-                       if (substr($className,0,6) == 't3lib_') {
-                               t3lib_div::requireOnce(PATH_t3lib.'class.'.strtolower($className).'.php');
-                       }
-               }
-
                        // Get final classname
                $className = self::getClassName($className);
 
@@ -4822,7 +5026,7 @@ final class t3lib_div {
        public static function makeInstanceClassName($className)        {
                self::logDeprecatedFunction();
 
-               return class_exists('ux_'.$className) ? t3lib_div::makeInstanceClassName('ux_'.$className) : $className;
+               return (class_exists($className) && class_exists('ux_'.$className, false) ? t3lib_div::makeInstanceClassName('ux_' . $className) : $className);
        }
 
        /**
@@ -4833,7 +5037,7 @@ final class t3lib_div {
         * @return      string          Final class name to instantiate with "new [classname]"
         */
        protected function getClassName($className) {
-               return class_exists('ux_' . $className) ? self::getClassName('ux_' . $className) : $className;
+               return (class_exists($className) && class_exists('ux_' . $className, false) ? self::getClassName('ux_' . $className) : $className);
        }
 
        /**
@@ -4846,7 +5050,7 @@ final class t3lib_div {
         * @return      object          The service object or an array with error info's.
         * @author      RenĂ© Fritz <r.fritz@colorcube.de>
         */
-       public static function &makeInstanceService($serviceType, $serviceSubType='', $excludeServiceKeys=array())      {
+       public static function makeInstanceService($serviceType, $serviceSubType='', $excludeServiceKeys=array()) {
                global $T3_SERVICES, $T3_VAR, $TYPO3_CONF_VARS;
 
                $error = FALSE;
@@ -4877,7 +5081,7 @@ final class t3lib_div {
                                                if ($obj->init()) { // service available?
 
                                                                // create persistent object
-                                                       $T3_VAR['makeInstanceService'][$info['className']] = &$obj;
+                                                       $T3_VAR['makeInstanceService'][$info['className']] = $obj;
 
                                                                // needed to delete temp files
                                                        register_shutdown_function(array(&$obj, '__destruct'));
@@ -4906,6 +5110,19 @@ final class t3lib_div {
        }
 
        /**
+        * Requires a class for TYPO3
+        * Useful to require classes from inside other classes (not global scope).
+        * A limited set of global variables are available (see function)
+        *
+        * @param       string          $requireFile: Path of the file to be included
+        * @return      void
+        */
+       public static function requireFile($requireFile) {
+               global $T3_SERVICES, $T3_VAR, $TYPO3_CONF_VARS;
+               require $requireFile;
+       }
+
+       /**
         * Simple substitute for the PHP function mail() which allows you to specify encoding and character set
         * The fifth parameter ($encoding) will allow you to specify 'base64' encryption for the output (set $encoding=base64)
         * Further the output has the charset set to ISO-8859-1 by default.
@@ -5066,7 +5283,12 @@ final class t3lib_div {
                                default:
                                        $qpValue = t3lib_div::quoted_printable($part,1000);
                                        if ($part!=$qpValue)    {
-                                               $qpValue = str_replace(' ','_',$qpValue);       // Encoded words in the header should not contain non-encoded spaces. "_" is a shortcut for "=20". See RFC 2047 for details.
+                                               // Encoded words in the header should not contain non-encoded:
+                                               // * spaces. "_" is a shortcut for "=20". See RFC 2047 for details.
+                                               // * question mark. See RFC 1342 (http://tools.ietf.org/html/rfc1342)
+                                               $search = array(' ', '?');
+                                               $replace = array('_', '=3F');
+                                               $qpValue = str_replace($search, $replace, $qpValue);
                                                $part = '=?'.$charset.'?Q?'.$qpValue.'?=';
                                        }
                                break;
@@ -5135,7 +5357,7 @@ final class t3lib_div {
                        if (!$count) {
                                $insertFields = array(
                                        'md5hash' => $md5,
-                                       'tstamp' => time(),
+                                       'tstamp' => $GLOBALS['EXEC_TIME'],
                                        'type' => 2,
                                        'params' => $inUrl
                                );
@@ -5322,6 +5544,10 @@ final class t3lib_div {
         * @return      void
         */
        public static function deprecationLog($msg) {
+               if (!$GLOBALS['TYPO3_CONF_VARS']['SYS']['enableDeprecationLog']) {
+                       return;
+               }
+
                // write a longer message to the deprecation log
                $destination = PATH_typo3conf . '/deprecation_' . t3lib_div::shortMD5(PATH_site . $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']) . '.log';
                $file = @fopen($destination, 'a');
@@ -5343,6 +5569,10 @@ final class t3lib_div {
         * @return      void
         */
        public static function logDeprecatedFunction() {
+               if (!$GLOBALS['TYPO3_CONF_VARS']['SYS']['enableDeprecationLog']) {
+                       return;
+               }
+
                $trail = debug_backtrace();
 
                if ($trail[1]['type']) {
@@ -5492,23 +5722,57 @@ final class t3lib_div {
                                $val = preg_replace('/(^"|"$)/','',$val);
                        }
                }
-               return $paramsArr;
+               // return reindexed array
+               return array_values($paramsArr);
        }
 
 
        /**
-        * Quotes a string for usage as JS parameter. Depends wheter the value is used in script tags (it doesn't need/must not get htmlspecialchar'ed in this case)
+        * Quotes a string for usage as JS parameter. Depends whether the value is
+        * used in script tags (it doesn't need/must not get htmlspecialchar'ed in
+        * this case).
         *
-        * @param       string          The string to encode.
-        * @param       boolean         If the values get's used in <script> tags.
-        * @return      string          The encoded value already quoted
+        * @param string $value the string to encode, may be empty
+        * @param boolean $withinCData
+        *        whether the escaped data is expected to be used as CDATA and thus
+        *        does not need to be htmlspecialchared
+        *
+        * @return string the encoded value already quoted (with single quotes),
+        *                will not be empty
+        */
+       static public function quoteJSvalue($value, $withinCData = false)       {
+               $escapedValue = addcslashes(
+                       $value, '\'' . '"' . '\\' . chr(9) . chr(10) . chr(13)
+               );
+               if (!$withinCData) {
+                       $escapedValue = htmlspecialchars($escapedValue);
+               }
+               return '\'' . $escapedValue . '\'';
+       }
+
+
+       /**
+        * Ends and cleans all output buffers
+        *
+        * @return      void
+        */
+       public static function cleanOutputBuffers() {
+               while (ob_get_level()) {
+                       ob_end_clean();
+               }
+               header('Content-Encoding: None', TRUE);
+       }
+
+
+       /**
+        *  Ends and flushes all output buffers
+        *
+        * @return      void
         */
-       public static function quoteJSvalue($value, $inScriptTags = false)      {
-               $value = addcslashes($value, '\''.'"'.chr(10).chr(13));
-               if (!$inScriptTags) {
-                       $value = htmlspecialchars($value);
+       public static function flushOutputBuffers() {
+               while (ob_get_level()) {
+                       ob_end_flush();
                }
-               return '\''.$value.'\'';
        }
 }