X-Git-Url: https://git.typo3.org/Packages/TYPO3.CMS.git/blobdiff_plain/28b3d1c9227191a7203a36f8a7924662ce905f4a..f60f1209c7ac21fddb8176b0c58b4d522f9cae90:/t3lib/class.t3lib_div.php diff --git a/t3lib/class.t3lib_div.php b/t3lib/class.t3lib_div.php index 245ec27..c42ccf2 100644 --- a/t3lib/class.t3lib_div.php +++ b/t3lib/class.t3lib_div.php @@ -25,15 +25,6 @@ * This copyright notice MUST APPEAR in all copies of the script! ***************************************************************/ - // a tabulator -define('TAB', chr(9)); - // a linefeed -define('LF', chr(10)); - // a carriage return -define('CR', chr(13)); - // a CR-LF combination -define('CRLF', CR . LF); - /** * The legendary "t3lib_div" class - Miscellaneous functions for general purpose. * Most of the functions do not relate specifically to TYPO3 @@ -50,7 +41,7 @@ define('CRLF', CR . LF); * @package TYPO3 * @subpackage t3lib */ -final class t3lib_div { +class t3lib_div { // Severity constants used by t3lib_div::sysLog() const SYSLOG_SEVERITY_INFO = 0; @@ -74,13 +65,6 @@ final class t3lib_div { */ protected static $nonSingletonInstances = array(); - /** - * Register for makeInstance with given class name and final class names to reduce number of class_exists() calls - * - * @var array Given class name => final class name - */ - protected static $finalClassNameRegister = array(); - /************************* * * GET/POST Variables @@ -144,7 +128,8 @@ final class t3lib_div { */ public static function _GET($var = NULL) { $value = ($var === NULL) ? $_GET : (empty($var) ? NULL : $_GET[$var]); - if (isset($value)) { // Removes slashes since TYPO3 has added them regardless of magic_quotes setting. + // Removes slashes since TYPO3 has added them regardless of magic_quotes setting. + if (isset($value)) { if (is_array($value)) { self::stripSlashesOnArray($value); } else { @@ -164,7 +149,8 @@ final class t3lib_div { */ public static function _POST($var = NULL) { $value = ($var === NULL) ? $_POST : (empty($var) ? NULL : $_POST[$var]); - if (isset($value)) { // Removes slashes since TYPO3 has added them regardless of magic_quotes setting. + // Removes slashes since TYPO3 has added them regardless of magic_quotes setting. + if (isset($value)) { if (is_array($value)) { self::stripSlashesOnArray($value); } else { @@ -178,11 +164,11 @@ final class t3lib_div { * Writes input value to $_GET. * * @param mixed $inputGet - * array or single value to write to $_GET. Values should NOT be + * Array or single value to write to $_GET. Values should NOT be * escaped at input time (but will be escaped before writing * according to TYPO3 standards). * @param string $key - * alternative key; If set, this will not set the WHOLE GET array, + * Alternative key; If set, this will not set the WHOLE GET array, * but only the key in it specified by this value! * You can specify to replace keys on deeper array levels by * separating the keys with a pipe. @@ -192,7 +178,7 @@ final class t3lib_div { * @return void */ public static function _GETset($inputGet, $key = '') { - // adds slashes since TYPO3 standard currently is that slashes + // Adds slashes since TYPO3 standard currently is that slashes // must be applied (regardless of magic_quotes setting) if (is_array($inputGet)) { self::addSlashesOnArray($inputGet); @@ -240,14 +226,12 @@ final class t3lib_div { return $string; } - /************************* * * IMAGE FUNCTIONS * *************************/ - /** * Compressing a GIF file if not already LZW compressed. * This function is a workaround for the fact that ImageMagick and/or GD does not compress GIF-files to their minimun size (that is RLE or no compression used) @@ -269,11 +253,13 @@ final class t3lib_div { public static function gif_compress($theFile, $type) { $gfxConf = $GLOBALS['TYPO3_CONF_VARS']['GFX']; $returnCode = ''; - if ($gfxConf['gif_compress'] && strtolower(substr($theFile, -4, 4)) == '.gif') { // GIF... - if (($type == 'IM' || !$type) && $gfxConf['im'] && $gfxConf['im_path_lzw']) { // IM - // use temporary file to prevent problems with read and write lock on same file on network file systems + // GIF... + if ($gfxConf['gif_compress'] && strtolower(substr($theFile, -4, 4)) == '.gif') { + // IM + if (($type == 'IM' || !$type) && $gfxConf['im'] && $gfxConf['im_path_lzw']) { + // Use temporary file to prevent problems with read and write lock on same file on network file systems $temporaryName = dirname($theFile) . '/' . md5(uniqid()) . '.gif'; - // rename could fail, if a simultaneous thread is currently working on the same thing + // Rename could fail, if a simultaneous thread is currently working on the same thing if (@rename($theFile, $temporaryName)) { $cmd = self::imageMagickCommand('convert', '"' . $temporaryName . '" "' . $theFile . '"', $gfxConf['im_path_lzw']); t3lib_utility_Command::exec($cmd); @@ -301,8 +287,8 @@ final class t3lib_div { * Converts a png file to gif. * This converts a png file to gif IF the FLAG $GLOBALS['TYPO3_CONF_VARS']['FE']['png_to_gif'] is set TRUE. * - * @param string $theFile the filename with path - * @return string new filename + * @param string $theFile The filename with path + * @return string New filename */ public static function png_to_gif_by_imagemagick($theFile) { if ($GLOBALS['TYPO3_CONF_VARS']['FE']['png_to_gif'] @@ -351,7 +337,6 @@ final class t3lib_div { } } - /************************* * * STRING FUNCTIONS @@ -361,10 +346,10 @@ final class t3lib_div { /** * Truncates a string with appended/prepended "..." and takes current character set into consideration. * - * @param string $string string to truncate - * @param integer $chars must be an integer with an absolute value of at least 4. if negative the string is cropped from the right end. - * @param string $appendString appendix to the truncated string - * @return string cropped string + * @param string $string String to truncate + * @param integer $chars Must be an integer with an absolute value of at least 4. if negative the string is cropped from the right end. + * @param string $appendString Appendix to the truncated string + * @return string Cropped string */ public static function fixed_lgd_cs($string, $chars, $appendString = '...') { if (is_object($GLOBALS['LANG'])) { @@ -373,32 +358,18 @@ final class t3lib_div { $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 + // This case should not happen $csConvObj = self::makeInstance('t3lib_cs'); - return $csConvObj->crop('iso-8859-1', $string, $chars, $appendString); + return $csConvObj->crop('utf-8', $string, $chars, $appendString); } } /** - * Breaks up a single line of text for emails - * - * @param string $str The string to break up - * @param string $newlineChar The string to implode the broken lines with (default/typically \n) - * @param integer $lineWidth The line width - * @return string reformatted text - * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.8 - Use t3lib_utility_Mail::breakLinesForEmail() - */ - public static function breakLinesForEmail($str, $newlineChar = LF, $lineWidth = 76) { - self::logDeprecatedFunction(); - return t3lib_utility_Mail::breakLinesForEmail($str, $newlineChar, $lineWidth); - } - - /** * Match IP number with list of numbers with wildcard * Dispatcher method for switching into specialised IPv4 and IPv6 methods. * - * @param string $baseIP is the current remote IP address for instance, typ. REMOTE_ADDR - * @param string $list is a comma-list of IP-addresses to match with. *-wildcard allowed instead of number, plus leaving out parts in the IP number is accepted as wildcard (eg. 192.168.*.* equals 192.168). If list is "*" no check is done and the function returns TRUE immediately. An empty list always returns FALSE. + * @param string $baseIP Is the current remote IP address for instance, typ. REMOTE_ADDR + * @param string $list Is a comma-list of IP-addresses to match with. *-wildcard allowed instead of number, plus leaving out parts in the IP number is accepted as wildcard (eg. 192.168.*.* equals 192.168). If list is "*" no check is done and the function returns TRUE immediately. An empty list always returns FALSE. * @return boolean TRUE if an IP-mask from $list matches $baseIP */ public static function cmpIP($baseIP, $list) { @@ -418,9 +389,9 @@ final class t3lib_div { /** * Match IPv4 number with list of numbers with wildcard * - * @param string $baseIP is the current remote IP address for instance, typ. REMOTE_ADDR - * @param string $list is a comma-list of IP-addresses to match with. *-wildcard allowed instead of number, plus leaving out parts in the IP number is accepted as wildcard (eg. 192.168.*.* equals 192.168), could also contain IPv6 addresses - * @return boolean TRUE if an IP-mask from $list matches $baseIP + * @param string $baseIP Is the current remote IP address for instance, typ. REMOTE_ADDR + * @param string $list Is a comma-list of IP-addresses to match with. *-wildcard allowed instead of number, plus leaving out parts in the IP number is accepted as wildcard (eg. 192.168.*.* equals 192.168), could also contain IPv6 addresses + * @return boolean TRUE if an IP-mask from $list matches $baseIP */ public static function cmpIPv4($baseIP, $list) { $IPpartsReq = explode('.', $baseIP); @@ -466,12 +437,13 @@ final class t3lib_div { /** * Match IPv6 address with a list of IPv6 prefixes * - * @param string $baseIP is the current remote IP address for instance - * @param string $list is a comma-list of IPv6 prefixes, could also contain IPv4 addresses - * @return boolean TRUE if an baseIP matches any prefix + * @param string $baseIP Is the current remote IP address for instance + * @param string $list Is a comma-list of IPv6 prefixes, could also contain IPv4 addresses + * @return boolean TRUE If an baseIP matches any prefix */ public static function cmpIPv6($baseIP, $list) { - $success = FALSE; // Policy default: Deny connection + // Policy default: Deny connection + $success = FALSE; $baseIP = self::normalizeIPv6($baseIP); $values = self::trimExplode(',', $list, 1); @@ -486,7 +458,8 @@ final class t3lib_div { if (self::validIPv6($test)) { $test = self::normalizeIPv6($test); $maskInt = intval($mask) ? intval($mask) : 128; - if ($mask === '0') { // special case; /0 is an allowed mask - equals a wildcard + // Special case; /0 is an allowed mask - equals a wildcard + if ($mask === '0') { $success = TRUE; } elseif ($maskInt == 128) { $success = ($test === $baseIP); @@ -495,14 +468,14 @@ final class t3lib_div { $baseIPBin = self::IPv6Hex2Bin($baseIP); $success = TRUE; - // modulo is 0 if this is a 8-bit-boundary + // Modulo is 0 if this is a 8-bit-boundary $maskIntModulo = $maskInt % 8; $numFullCharactersUntilBoundary = intval($maskInt / 8); if (substr($testBin, 0, $numFullCharactersUntilBoundary) !== substr($baseIPBin, 0, $numFullCharactersUntilBoundary)) { $success = FALSE; } elseif ($maskIntModulo > 0) { - // if not an 8-bit-boundary, check bits of last character + // If not an 8-bit-boundary, check bits of last character $testLastBits = str_pad(decbin(ord(substr($testBin, $numFullCharactersUntilBoundary, 1))), 8, '0', STR_PAD_LEFT); $baseIPLastBits = str_pad(decbin(ord(substr($baseIPBin, $numFullCharactersUntilBoundary, 1))), 8, '0', STR_PAD_LEFT); if (strncmp($testLastBits, $baseIPLastBits, $maskIntModulo) != 0) { @@ -526,39 +499,18 @@ final class t3lib_div { * @see IPv6Bin2Hex() */ public static function IPv6Hex2Bin($hex) { - // use PHP-function if PHP was compiled with IPv6-support - if (defined('AF_INET6')) { - $bin = inet_pton($hex); - } else { - $hex = self::normalizeIPv6($hex); - $hex = str_replace(':', '', $hex); // Replace colon to nothing - $bin = pack("H*" , $hex); - } - return $bin; + return inet_pton($hex); } /** * Transform an IPv6 address from binary to hex-representation * - * @param string $hex IPv6 address in hex-presentation + * @param string $bin IPv6 address in hex-presentation * @return string Binary representation (16 characters, 128 characters) * @see IPv6Hex2Bin() */ public static function IPv6Bin2Hex($bin) { - // use PHP-function if PHP was compiled with IPv6-support - if (defined('AF_INET6')) { - $hex = inet_ntop($bin); - } else { - $hex = unpack("H*" , $bin); - $hex = chunk_split($hex[1], 4, ':'); - // strip last colon (from chunk_split) - $hex = substr($hex, 0, -1); - // IPv6 is now in normalized form - // compress it for easier handling and to match result from inet_ntop() - $hex = self::compressIPv6($hex); - } - return $hex; - + return inet_ntop($bin); } /** @@ -572,16 +524,17 @@ final class t3lib_div { $normalizedAddress = ''; $stageOneAddress = ''; - // according to RFC lowercase-representation is recommended + // According to RFC lowercase-representation is recommended $address = strtolower($address); - // normalized representation has 39 characters (0000:0000:0000:0000:0000:0000:0000:0000) + // Normalized representation has 39 characters (0000:0000:0000:0000:0000:0000:0000:0000) if (strlen($address) == 39) { - // already in full expanded form + // Already in full expanded form return $address; } - $chunks = explode('::', $address); // Count 2 if if address has hidden zero blocks + // Count 2 if if address has hidden zero blocks + $chunks = explode('::', $address); if (count($chunks) == 2) { $chunksLeft = explode(':', $chunks[0]); $chunksRight = explode(':', $chunks[1]); @@ -610,7 +563,7 @@ final class t3lib_div { $stageOneAddress = $address; } - // normalize the blocks: + // Normalize the blocks: $blocks = explode(':', $stageOneAddress); $divCounter = 0; foreach ($blocks as $block) { @@ -639,37 +592,7 @@ final class t3lib_div { * @see normalizeIPv6() */ public static function compressIPv6($address) { - // use PHP-function if PHP was compiled with IPv6-support - if (defined('AF_INET6')) { - $bin = inet_pton($address); - $address = inet_ntop($bin); - } else { - $address = self::normalizeIPv6($address); - - // append one colon for easier handling - // will be removed later - $address .= ':'; - - // according to IPv6-notation the longest match - // of a package of '0000:' may be replaced with ':' - // (resulting in something like '1234::abcd') - for ($counter = 8; $counter > 1; $counter--) { - $search = str_repeat('0000:', $counter); - if (($pos = strpos($address, $search)) !== FALSE) { - $address = substr($address, 0, $pos) . ':' . substr($address, $pos + ($counter*5)); - break; - } - } - - // up to 3 zeros in the first part may be removed - $address = preg_replace('/^0{1,3}/', '', $address); - // up to 3 zeros at the beginning of other parts may be removed - $address = preg_replace('/:0{1,3}/', ':', $address); - - // strip last colon (from chunk_split) - $address = substr($address, 0, -1); - } - return $address; + return inet_ntop(inet_pton($address)); } /** @@ -711,7 +634,7 @@ final class t3lib_div { /** * Match fully qualified domain name with list of strings with wildcard * - * @param string $baseIP A hostname or an IPv4/IPv6-address (will by reverse-resolved; typically REMOTE_ADDR) + * @param string $baseHost A hostname or an IPv4/IPv6-address (will by reverse-resolved; typically REMOTE_ADDR) * @param string $list A comma-list of domain names to match with. *-wildcard allowed but cannot be part of a string, so it must match the full host name (eg. myhost.*.com => correct, myhost.*domain.com => wrong) * @return boolean TRUE if a domain name mask from $list matches $baseIP */ @@ -721,12 +644,12 @@ final class t3lib_div { return FALSE; } if (self::validIPv4($baseHost) || self::validIPv6($baseHost)) { - // resolve hostname - // note: this is reverse-lookup and can be randomly set as soon as somebody is able to set + // Resolve hostname + // Note: this is reverse-lookup and can be randomly set as soon as somebody is able to set // the reverse-DNS for his IP (security when for example used with REMOTE_ADDR) $baseHostName = gethostbyaddr($baseHost); if ($baseHostName === $baseHost) { - // unable to resolve hostname + // Unable to resolve hostname return FALSE; } } else { @@ -739,7 +662,7 @@ final class t3lib_div { foreach ($values as $test) { $hostNameParts = explode('.', $test); - // to match hostNameParts can only be shorter (in case of wildcards) or equal + // To match hostNameParts can only be shorter (in case of wildcards) or equal if (count($hostNameParts) > count($baseHostNameParts)) { continue; } @@ -748,10 +671,10 @@ final class t3lib_div { foreach ($hostNameParts as $index => $val) { $val = trim($val); if ($val === '*') { - // wildcard valid for one or more hostname-parts + // Wildcard valid for one or more hostname-parts $wildcardStart = $index + 1; - // wildcard as last/only part always matches, otherwise perform recursive checks + // Wildcard as last/only part always matches, otherwise perform recursive checks if ($wildcardStart < count($hostNameParts)) { $wildcardMatched = FALSE; $tempHostName = implode('.', array_slice($hostNameParts, $index + 1)); @@ -761,14 +684,14 @@ final class t3lib_div { $wildcardStart++; } if ($wildcardMatched) { - // match found by recursive compare + // Match found by recursive compare return TRUE; } else { $yes = FALSE; } } } elseif ($baseHostNameParts[$index] !== $val) { - // in case of no match + // In case of no match $yes = FALSE; } } @@ -783,7 +706,7 @@ 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 + * @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) { @@ -794,8 +717,8 @@ final class t3lib_div { * Check for item in list * Check if an item exists in a comma-separated list of items. * - * @param string $list comma-separated list of items (string) - * @param string $item item to check for + * @param string $list Comma-separated list of items (string) + * @param string $item Item to check for * @return boolean TRUE if $item is in $list */ public static function inList($list, $item) { @@ -805,9 +728,9 @@ final class t3lib_div { /** * Removes an item from a comma-separated list of items. * - * @param string $element element to remove - * @param string $list comma-separated list of items (string) - * @return string new comma-separated list of items + * @param string $element Element to remove + * @param string $list Comma-separated list of items (string) + * @return string New comma-separated list of items */ public static function rmFromList($element, $list) { $items = explode(',', $list); @@ -823,9 +746,8 @@ final class t3lib_div { * Expand a comma-separated list of integers with ranges (eg 1,3-5,7 becomes 1,3,4,5,7). * Ranges are limited to 1000 values per range. * - * @param string $list comma-separated list of integers with ranges (string) - * @return string new comma-separated list of items - * @author Martin Kutschker + * @param string $list Comma-separated list of integers with ranges (string) + * @return string New comma-separated list of items */ public static function expandList($list) { $items = explode(',', $list); @@ -850,38 +772,11 @@ final class t3lib_div { } /** - * Forces the integer $theInt into the boundaries of $min and $max. If the $theInt is 'FALSE' then the $zeroValue is applied. - * - * @param integer $theInt Input value - * @param integer $min Lower limit - * @param integer $max Higher limit - * @param integer $zeroValue Default value if input is FALSE. - * @return integer The input value forced into the boundaries of $min and $max - * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.8 - Use t3lib_utility_Math::forceIntegerInRange() instead - */ - public static function intInRange($theInt, $min, $max = 2000000000, $zeroValue = 0) { - self::logDeprecatedFunction(); - return t3lib_utility_Math::forceIntegerInRange($theInt, $min, $max, $zeroValue); - } - - /** - * Returns the $integer if greater than zero, otherwise returns zero. - * - * @param integer $theInt Integer string to process - * @return integer - * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.8 - Use t3lib_utility_Math::convertToPositiveInteger() instead - */ - public static function intval_positive($theInt) { - self::logDeprecatedFunction(); - return t3lib_utility_Math::convertToPositiveInteger($theInt); - } - - /** * Returns an integer from a three part version number, eg '4.12.3' -> 4012003 * * @param string $verNumberStr Version number on format x.x.x * @return integer Integer version of version number (where each part can count to 999) - * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.9 - Use t3lib_utility_VersionNumber::convertVersionNumberToInteger() instead + * @deprecated since TYPO3 4.6, will be removed in TYPO3 6.1 - Use t3lib_utility_VersionNumber::convertVersionNumberToInteger() instead */ public static function int_from_ver($verNumberStr) { // Deprecation log is activated only for TYPO3 4.7 and above @@ -895,7 +790,7 @@ final class t3lib_div { * Returns TRUE if the current TYPO3 version (or compatibility version) is compatible to the input version * Notice that this function compares branches, not versions (4.0.1 would be > 4.0.0 although they use the same compat_version) * - * @param string $verNumberStr Minimum branch number required (format x.y / e.g. "4.0" NOT "4.0.0"!) + * @param string $verNumberStr Minimum branch number required (format x.y / e.g. "4.0" NOT "4.0.0"!) * @return boolean Returns TRUE if this setup is compatible with the provided version number * @todo Still needs a function to convert versions to branches */ @@ -944,15 +839,15 @@ final class t3lib_div { if (extension_loaded('hash') && function_exists('hash_hmac') && function_exists('hash_algos') && in_array($hashAlgorithm, hash_algos())) { $hmac = hash_hmac($hashAlgorithm, $input, $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']); } else { - // outer padding + // Outer padding $opad = str_repeat(chr(0x5C), $hashBlocksize); - // innner padding + // Inner padding $ipad = str_repeat(chr(0x36), $hashBlocksize); if (strlen($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']) > $hashBlocksize) { - // keys longer than blocksize are shorten + // Keys longer than block size are shorten $key = str_pad(pack('H*', call_user_func($hashAlgorithm, $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])), $hashBlocksize, chr(0x00)); } else { - // keys shorter than blocksize are zero-padded + // Keys shorter than block size are zero-padded $key = str_pad($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'], $hashBlocksize, chr(0x00)); } $hmac = call_user_func($hashAlgorithm, ($key ^ $opad) . pack('H*', call_user_func($hashAlgorithm, ($key ^ $ipad) . $input))); @@ -964,8 +859,8 @@ final class t3lib_div { * Takes comma-separated lists and arrays and removes all duplicates * If a value in the list is trim(empty), the value is ignored. * - * @param string $in_list Accept multiple parameters wich can be comma-separated lists of values and arrays. - * @param mixed $secondParameter: Dummy field, which if set will show a warning! + * @param string $in_list Accept multiple parameters which can be comma-separated lists of values and arrays. + * @param mixed $secondParameter Dummy field, which if set will show a warning! * @return string Returns the list without any duplicates of values, space around values are trimmed */ public static function uniqueList($in_list, $secondParameter = NULL) { @@ -1068,32 +963,6 @@ final class t3lib_div { } /** - * Removes comma (if present) in the end of string - * - * @param string $string String from which the comma in the end (if any) will be removed. - * @return string - * @deprecated since TYPO3 4.5, will be removed in TYPO3 4.7 - Use rtrim() directly - */ - public static function rm_endcomma($string) { - self::logDeprecatedFunction(); - - return rtrim($string, ','); - } - - /** - * Tests if the input can be interpreted as integer. - * - * @param mixed $var Any input variable to test - * @return boolean Returns TRUE if string is an integer - * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.8 - Use t3lib_utility_Math::canBeInterpretedAsInteger() instead - */ - public static function testInt($var) { - self::logDeprecatedFunction(); - - return t3lib_utility_Math::canBeInterpretedAsInteger($var); - } - - /** * Returns TRUE if the first part of $str matches the string $partStr * * @param string $str Full string to check @@ -1123,11 +992,11 @@ final class t3lib_div { // Find size: if ($sizeInBytes > 900) { - if ($sizeInBytes > 900000000) { // GB + // GB + if ($sizeInBytes > 900000000) { $val = $sizeInBytes / (1024 * 1024 * 1024); return number_format($val, (($val < 20) ? 1 : 0), '.', '') . $labelArr[3]; - } - elseif ($sizeInBytes > 900000) { // MB + } elseif ($sizeInBytes > 900000) { // MB $val = $sizeInBytes / (1024 * 1024); return number_format($val, (($val < 20) ? 1 : 0), '.', '') . $labelArr[2]; } else { // KB @@ -1173,34 +1042,6 @@ final class t3lib_div { } /** - * Calculates the input by +,-,*,/,%,^ with priority to + and - - * - * @param string $string Input string, eg "123 + 456 / 789 - 4" - * @return integer Calculated value. Or error string. - * @see calcParenthesis() - * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.8 - Use t3lib_utility_Math::calculateWithPriorityToAdditionAndSubtraction() instead - */ - public static function calcPriority($string) { - self::logDeprecatedFunction(); - - return t3lib_utility_Math::calculateWithPriorityToAdditionAndSubtraction($string); - } - - /** - * Calculates the input with parenthesis levels - * - * @param string $string Input string, eg "(123 + 456) / 789 - 4" - * @return integer Calculated value. Or error string. - * @see calcPriority(), tslib_cObj::stdWrap() - * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.8 - Use t3lib_utility_Math::calculateWithParentheses() instead - */ - public static function calcParenthesis($string) { - self::logDeprecatedFunction(); - - return t3lib_utility_Math::calculateWithParentheses($string); - } - - /** * Inverse version of htmlspecialchars() * * @param string $value Value where >, <, " and & should be converted to regular chars. @@ -1234,9 +1075,9 @@ final class t3lib_div { */ public static function slashJS($string, $extended = FALSE, $char = "'") { if ($extended) { - $string = str_replace("\\", "\\\\", $string); + $string = str_replace('\\', '\\\\', $string); } - return str_replace($char, "\\" . $char, $string); + return str_replace($char, '\\' . $char, $string); } /** @@ -1252,7 +1093,7 @@ final class t3lib_div { /** * rawurlencode which preserves "/" chars - * Useful when filepaths should keep the "/" chars, but have all other special chars encoded. + * Useful when file paths should keep the "/" chars, but have all other special chars encoded. * * @param string $str Input string * @return string Output string @@ -1268,12 +1109,15 @@ final class t3lib_div { * @return boolean Returns TRUE if the $email address (input string) is valid */ public static function validEmail($email) { - // enforce maximum length to prevent libpcre recursion crash bug #52929 in PHP + // Enforce maximum length to prevent libpcre recursion crash bug #52929 in PHP // fixed in PHP 5.3.4; length restriction per SMTP RFC 2821 if (strlen($email) > 320) { return FALSE; } - return (filter_var($email, FILTER_VALIDATE_EMAIL) !== FALSE); + require_once(PATH_typo3 . 'contrib/idna/idna_convert.class.php'); + $IDN = new idna_convert(array('idn_version' => 2008)); + + return (filter_var($IDN->encode($email), FILTER_VALIDATE_EMAIL) !== FALSE); } /** @@ -1348,57 +1192,118 @@ final class t3lib_div { /** * Returns a string of highly randomized bytes (over the full 8-bit range). * - * @copyright Drupal CMS - * @license GNU General Public License version 2 - * @param integer $count Number of characters (bytes) to return + * Note: Returned values are not guaranteed to be crypto-safe, + * most likely they are not, depending on the used retrieval method. + * + * @param integer $bytesToReturn Number of characters (bytes) to return * @return string Random Bytes - */ - public static function generateRandomBytes($count) { - $output = ''; - // /dev/urandom is available on many *nix systems and is considered - // the best commonly available pseudo-random source. - if (TYPO3_OS != 'WIN' && ($fh = @fopen('/dev/urandom', 'rb'))) { - $output = fread($fh, $count); - fclose($fh); - } elseif (TYPO3_OS == 'WIN') { - if (class_exists('COM')) { - try { - $com = new COM('CAPICOM.Utilities.1'); - $output = base64_decode($com->GetRandom($count, 0)); - } catch (Exception $e) { - // CAPICOM not installed + * @see http://bugs.php.net/bug.php?id=52523 + * @see http://www.php-security.org/2010/05/09/mops-submission-04-generating-unpredictable-session-ids-and-hashes/index.html + */ + public static function generateRandomBytes($bytesToReturn) { + // Cache 4k of the generated bytestream. + static $bytes = ''; + $bytesToGenerate = max(4096, $bytesToReturn); + + // if we have not enough random bytes cached, we generate new ones + if (!isset($bytes{$bytesToReturn - 1})) { + if (TYPO3_OS === 'WIN') { + // Openssl seems to be deadly slow on Windows, so try to use mcrypt + // Windows PHP versions have a bug when using urandom source (see #24410) + $bytes .= self::generateRandomBytesMcrypt($bytesToGenerate, MCRYPT_RAND); + } else { + // Try to use native PHP functions first, precedence has openssl + $bytes .= self::generateRandomBytesOpenSsl($bytesToGenerate); + + if (!isset($bytes{$bytesToReturn - 1})) { + $bytes .= self::generateRandomBytesMcrypt($bytesToGenerate, MCRYPT_DEV_URANDOM); } - } - if ($output === '') { - if (function_exists('mcrypt_create_iv')) { - $output = mcrypt_create_iv($count, MCRYPT_DEV_URANDOM); - } elseif (function_exists('openssl_random_pseudo_bytes')) { - $isStrong = NULL; - $output = openssl_random_pseudo_bytes($count, $isStrong); - // skip ssl since it wasn't using the strong algo - if ($isStrong !== TRUE) { - $output = ''; - } + + // If openssl and mcrypt failed, try /dev/urandom + if (!isset($bytes{$bytesToReturn - 1})) { + $bytes .= self::generateRandomBytesUrandom($bytesToGenerate); } } - } - // fallback if other random byte generation failed until now - if (!isset($output{$count - 1})) { - // We initialize with the somewhat random. - $randomState = $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] - . base_convert(memory_get_usage() % pow(10, 6), 10, 2) - . microtime() . uniqid('') . getmypid(); - while (!isset($output{$count - 1})) { - $randomState = sha1(microtime() . mt_rand() . $randomState); - $output .= sha1(mt_rand() . $randomState, TRUE); + // Fall back if other random byte generation failed until now + if (!isset($bytes{$bytesToReturn - 1})) { + $bytes .= self::generateRandomBytesFallback($bytesToReturn); } - $output = substr($output, strlen($output) - $count, $count); } + + // get first $bytesToReturn and remove it from the byte cache + $output = substr($bytes, 0, $bytesToReturn); + $bytes = substr($bytes, $bytesToReturn); + return $output; } /** + * Generate random bytes using openssl if available + * + * @param string $bytesToGenerate + * @return string + */ + protected static function generateRandomBytesOpenSsl($bytesToGenerate) { + if (!function_exists('openssl_random_pseudo_bytes')) { + return ''; + } + $isStrong = NULL; + return (string) openssl_random_pseudo_bytes($bytesToGenerate, $isStrong); + } + + /** + * Generate random bytes using mcrypt if available + * + * @param $bytesToGenerate + * @param $randomSource + * @return string + */ + protected static function generateRandomBytesMcrypt($bytesToGenerate, $randomSource) { + if (!function_exists('mcrypt_create_iv')) { + return ''; + } + return (string) @mcrypt_create_iv($bytesToGenerate, $randomSource); + } + + /** + * Read random bytes from /dev/urandom if it is accessible + * + * @param $bytesToGenerate + * @return string + */ + protected static function generateRandomBytesUrandom($bytesToGenerate) { + $bytes = ''; + $fh = @fopen('/dev/urandom', 'rb'); + if ($fh) { + // PHP only performs buffered reads, so in reality it will always read + // at least 4096 bytes. Thus, it costs nothing extra to read and store + // that much so as to speed any additional invocations. + $bytes = fread($fh, $bytesToGenerate); + fclose($fh); + } + + return $bytes; + } + + /** + * Generate pseudo random bytes as last resort + * + * @param $bytesToReturn + * @return string + */ + protected static function generateRandomBytesFallback($bytesToReturn) { + $bytes = ''; + // We initialize with somewhat random. + $randomState = $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] . base_convert(memory_get_usage() % pow(10, 6), 10, 2) . microtime() . uniqid('') . getmypid(); + while (!isset($bytes{$bytesToReturn - 1})) { + $randomState = sha1(microtime() . mt_rand() . $randomState); + $bytes .= sha1(mt_rand() . $randomState, TRUE); + } + return $bytes; + } + + /** * Returns a hex representation of a random byte string. * * @param integer $count Number of hex characters to return @@ -1412,7 +1317,7 @@ final class t3lib_div { * Returns a given string with underscores as UpperCamelCase. * Example: Converts blog_example to BlogExample * - * @param string $string: String to be converted to camel case + * @param string $string String to be converted to camel case * @return string UpperCamelCasedWord */ public static function underscoredToUpperCamelCase($string) { @@ -1424,7 +1329,7 @@ final class t3lib_div { * Returns a given string with underscores as lowerCamelCase. * Example: Converts minimal_value to minimalValue * - * @param string $string: String to be converted to camel case + * @param string $string String to be converted to camel case * @return string lowerCamelCasedWord */ public static function underscoredToLowerCamelCase($string) { @@ -1462,9 +1367,11 @@ final class t3lib_div { * @return boolean Whether the given URL is valid */ public static function isValidUrl($url) { - return (filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED) !== FALSE); - } + require_once(PATH_typo3 . 'contrib/idna/idna_convert.class.php'); + $IDN = new idna_convert(array('idn_version' => 2008)); + return (filter_var($IDN->encode($url), FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED) !== FALSE); + } /************************* * @@ -1490,8 +1397,8 @@ final class t3lib_div { * | 0 | TRUE | TRUE | TRUE | * +---------+-----------+-----------+-----------+ * - * @param array $in_array one-dimensional array of items - * @param string $item item to check for + * @param array $in_array One-dimensional array of items + * @param string $item Item to check for * @return boolean TRUE if $item is in the one-dimensional array $in_array */ public static function inArray(array $in_array, $item) { @@ -1614,9 +1521,9 @@ final class t3lib_div { * array('bb' => array('third', 'fourth'), * ) * - * @param array $array: The initial array to be filtered/reduced - * @param mixed $keepItems: The items which are allowed/kept in the array - accepts array or csv string - * @param string $getValueFunc: (optional) Unique function name set by create_function() used to get the value to keep + * @param array $array The initial array to be filtered/reduced + * @param mixed $keepItems The items which are allowed/kept in the array - accepts array or csv string + * @param string $getValueFunc (optional) Unique function name set by create_function() used to get the value to keep * @return array The filtered/reduced array with the kept items */ public static function keepItemsInArray(array $array, $keepItems, $getValueFunc = NULL) { @@ -1647,7 +1554,7 @@ final class t3lib_div { * Implodes a multidim-array into GET-parameters (eg. ¶m[key][key2]=value2¶m[key][key3]=value3) * * @param string $name Name prefix for entries. Set to blank if you wish none. - * @param array $theArray The (multidim) array to implode + * @param array $theArray The (multidimensional) array to implode * @param string $str (keep blank) * @param boolean $skipBlank If set, parameters which were blank strings would be removed. * @param boolean $rawurlencodeParamName If set, the param name itself (for example "param[key][key2]") would be rawurlencoded as well. @@ -1717,7 +1624,7 @@ final class t3lib_div { /** * AddSlash array - * This function traverses a multidimentional array and adds slashes to the values. + * This function traverses a multidimensional array and adds slashes to the values. * NOTE that the input array is and argument by reference.!! * Twin-function to stripSlashesOnArray * @@ -1738,7 +1645,7 @@ final class t3lib_div { /** * StripSlash array - * This function traverses a multidimentional array and strips slashes to the values. + * This function traverses a multidimensional array and strips slashes to the values. * NOTE that the input array is and argument by reference.!! * Twin-function to addSlashesOnArray * @@ -1802,28 +1709,30 @@ final class t3lib_div { * @param array $arr1 Second array, overruling the first array * @param boolean $notAddKeys If set, keys that are NOT found in $arr0 (first array) will not be set. Thus only existing value can/will be overruled from second array. * @param boolean $includeEmptyValues If set, values from $arr1 will overrule if they are empty or zero. Default: TRUE + * @param boolean $enableUnsetFeature If set, special values "__UNSET" can be used in the second array in order to unset array keys in the resulting array. * @return array Resulting array where $arr1 values has overruled $arr0 values */ - public static function array_merge_recursive_overrule(array $arr0, array $arr1, $notAddKeys = FALSE, $includeEmptyValues = TRUE) { + public static function array_merge_recursive_overrule(array $arr0, array $arr1, $notAddKeys = FALSE, $includeEmptyValues = TRUE, $enableUnsetFeature = TRUE) { foreach ($arr1 as $key => $val) { if (is_array($arr0[$key])) { if (is_array($arr1[$key])) { - $arr0[$key] = self::array_merge_recursive_overrule($arr0[$key], $arr1[$key], $notAddKeys, $includeEmptyValues); + $arr0[$key] = self::array_merge_recursive_overrule( + $arr0[$key], + $arr1[$key], + $notAddKeys, + $includeEmptyValues, + $enableUnsetFeature + ); } - } else { - if ($notAddKeys) { - if (isset($arr0[$key])) { - if ($includeEmptyValues || $val) { - $arr0[$key] = $val; - } - } - } else { - if ($includeEmptyValues || $val) { - $arr0[$key] = $val; - } + } elseif (!$notAddKeys || isset($arr0[$key])) { + if ($enableUnsetFeature && $val === '__UNSET') { + unset($arr0[$key]); + } elseif ($includeEmptyValues || $val) { + $arr0[$key] = $val; } } } + reset($arr0); return $arr0; } @@ -1840,7 +1749,7 @@ final class t3lib_div { } /** - * Filters keys off from first array that also exist in second array. Comparision is done by keys. + * Filters keys off from first array that also exist in second array. Comparison is done by keys. * This method is a recursive version of php array_diff_assoc() * * @param array $array1 Source array @@ -1866,7 +1775,7 @@ final class t3lib_div { * Takes a row and returns a CSV string of the values with $delim (default is ,) and $quote (default is ") as separator chars. * * @param array $row Input array of values - * @param string $delim Delimited, default is comman + * @param string $delim Delimited, default is comma * @param string $quote Quote-character to wrap around the values. * @return string A single line of CSV */ @@ -1883,7 +1792,7 @@ final class t3lib_div { * Removes dots "." from end of a key identifier of TypoScript styled array. * array('key.' => array('property.' => 'value')) --> array('key' => array('property' => 'value')) * - * @param array $ts: TypoScript configuration array + * @param array $ts TypoScript configuration array * @return array TypoScript configuration array without dots at the end of all keys */ public static function removeDotsFromTS(array $ts) { @@ -1916,7 +1825,6 @@ final class t3lib_div { return TRUE; } - /************************* * * HTML/XML PROCESSING @@ -1925,7 +1833,7 @@ final class t3lib_div { /** * Returns an array with all attributes of the input HTML tag as key/value pairs. Attributes are only lowercase a-z - * $tag is either a whole tag (eg '') or the parameterlist (ex ' OPTION ATTRIB=VALUE>') + * $tag is either a whole tag (eg '') or the parameter list (ex ' OPTION ATTRIB=VALUE>') * If an attribute is empty, then the value for the key is empty. You can check if it existed with isset() * * @param string $tag HTML-tag string (or attributes only) @@ -1933,18 +1841,20 @@ final class t3lib_div { */ public static function get_tag_attributes($tag) { $components = self::split_tag_attributes($tag); - $name = ''; // attribute name is stored here + // Attribute name is stored here + $name = ''; $valuemode = FALSE; $attributes = array(); foreach ($components as $key => $val) { - if ($val != '=') { // Only if $name is set (if there is an attribute, that waits for a value), that valuemode is enabled. This ensures that the attribute is assigned it's value + // Only if $name is set (if there is an attribute, that waits for a value), that valuemode is enabled. This ensures that the attribute is assigned it's value + if ($val != '=') { if ($valuemode) { if ($name) { $attributes[$name] = $val; $name = ''; } } else { - if ($key = strtolower(preg_replace('/[^a-zA-Z0-9]/', '', $val))) { + if ($key = strtolower(preg_replace('/[^[:alnum:]_\:\-]/', '', $val))) { $attributes[$key] = ''; $name = $key; } @@ -1970,7 +1880,8 @@ final class t3lib_div { $tag_tmp = trim(rtrim($tag_tmp, '>')); $value = array(); - while (strcmp($tag_tmp, '')) { // Compared with empty string instead , 030102 + // Compared with empty string instead , 030102 + while (strcmp($tag_tmp, '')) { $firstChar = substr($tag_tmp, 0, 1); if (!strcmp($firstChar, '"') || !strcmp($firstChar, "'")) { $reg = explode($firstChar, $tag_tmp, 3); @@ -1978,7 +1889,8 @@ final class t3lib_div { $tag_tmp = trim($reg[2]); } elseif (!strcmp($firstChar, '=')) { $value[] = '='; - $tag_tmp = trim(substr($tag_tmp, 1)); // Removes = chars. + // Removes = chars. + $tag_tmp = trim(substr($tag_tmp, 1)); } else { // There are '' around the value. We look for the next ' ' or '>' $reg = preg_split('/[[:space:]=]/', $tag_tmp, 2); @@ -2019,14 +1931,12 @@ final class t3lib_div { /** * Wraps JavaScript code XHTML ready with