/lib/typo3/class.t3lib_div.php
PHP | 5839 lines | 3481 code | 478 blank | 1880 comment | 802 complexity | e8ddd127c69953ca521eed2bc1738094 MD5 | raw file
Possible License(s): Apache-2.0, LGPL-2.1, BSD-3-Clause, MIT, GPL-3.0
Large files files are truncated, but you can click here to view the full file
- <?php
- /***************************************************************
- * Copyright notice
- *
- * (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
- * All rights reserved
- *
- * This script is part of the TYPO3 project. The TYPO3 project is
- * free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The GNU General Public License can be found at
- * http://www.gnu.org/copyleft/gpl.html.
- * A copy is found in the textfile GPL.txt and important notices to the license
- * from the author is found in LICENSE.txt distributed with these scripts.
- *
- *
- * This script is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * 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
- * However a section of functions requires certain TYPO3 features available
- * See comments in the source.
- * You are encouraged to use this library in your own scripts!
- *
- * USE:
- * The class is intended to be used without creating an instance of it.
- * So: Don't instantiate - call functions with "t3lib_div::" prefixed the function name.
- * So use t3lib_div::[method-name] to refer to the functions, eg. 't3lib_div::milliseconds()'
- *
- * @author Kasper Skårhøj <kasperYYYY@typo3.com>
- * @package TYPO3
- * @subpackage t3lib
- */
- final class t3lib_div {
- // Severity constants used by t3lib_div::sysLog()
- const SYSLOG_SEVERITY_INFO = 0;
- const SYSLOG_SEVERITY_NOTICE = 1;
- const SYSLOG_SEVERITY_WARNING = 2;
- const SYSLOG_SEVERITY_ERROR = 3;
- const SYSLOG_SEVERITY_FATAL = 4;
- const ENV_TRUSTED_HOSTS_PATTERN_ALLOW_ALL = '.*';
- const ENV_TRUSTED_HOSTS_PATTERN_SERVER_NAME = 'SERVER_NAME';
- /**
- * State of host header value security check
- * in order to avoid unnecessary multiple checks during one request
- *
- * @var bool
- */
- static protected $allowHostHeaderValue = FALSE;
- /**
- * Singleton instances returned by makeInstance, using the class names as
- * array keys
- *
- * @var array<t3lib_Singleton>
- */
- protected static $singletonInstances = array();
- /**
- * Instances returned by makeInstance, using the class names as array keys
- *
- * @var array<array><object>
- */
- 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
- *
- * Background:
- * Input GET/POST variables in PHP may have their quotes escaped with "\" or not depending on configuration.
- * TYPO3 has always converted quotes to BE escaped if the configuration told that they would not be so.
- * But the clean solution is that quotes are never escaped and that is what the functions below offers.
- * Eventually TYPO3 should provide this in the global space as well.
- * In the transitional phase (or forever..?) we need to encourage EVERY to read and write GET/POST vars through the API functions below.
- *
- *************************/
- /**
- * Returns the 'GLOBAL' value of incoming data from POST or GET, with priority to POST (that is equalent to 'GP' order)
- * Strips slashes from all output, both strings and arrays.
- * To enhancement security in your scripts, please consider using t3lib_div::_GET or t3lib_div::_POST if you already
- * know by which method your data is arriving to the scripts!
- *
- * @param string $var GET/POST var to return
- * @return mixed POST var named $var and if not set, the GET var of the same name.
- */
- public static function _GP($var) {
- if (empty($var)) {
- return;
- }
- $value = isset($_POST[$var]) ? $_POST[$var] : $_GET[$var];
- if (isset($value)) {
- if (is_array($value)) {
- self::stripSlashesOnArray($value);
- } else {
- $value = stripslashes($value);
- }
- }
- return $value;
- }
- /**
- * Returns the global arrays $_GET and $_POST merged with $_POST taking precedence.
- *
- * @param string $parameter 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 = (isset($_POST[$parameter]) && is_array($_POST[$parameter])) ? $_POST[$parameter] : array();
- $getParameter = (isset($_GET[$parameter]) && is_array($_GET[$parameter])) ? $_GET[$parameter] : array();
- $mergedParameters = self::array_merge_recursive_overrule($getParameter, $postParameter);
- self::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!
- *
- * @param string $var Optional pointer to value in GET array (basically name of GET var)
- * @return mixed If $var is set it returns the value of $_GET[$var]. If $var is NULL (default), returns $_GET itself. In any case *slashes are stipped from the output!*
- * @see _POST(), _GP(), _GETset()
- */
- 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.
- if (is_array($value)) {
- self::stripSlashesOnArray($value);
- } else {
- $value = stripslashes($value);
- }
- }
- return $value;
- }
- /**
- * Returns the global $_POST array (or value from) normalized to contain un-escaped values.
- * ALWAYS use this API function to acquire the $_POST variables!
- *
- * @param string $var Optional pointer to value in POST array (basically name of POST var)
- * @return mixed If $var is set it returns the value of $_POST[$var]. If $var is NULL (default), returns $_POST itself. In any case *slashes are stipped from the output!*
- * @see _GET(), _GP()
- */
- 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.
- if (is_array($value)) {
- self::stripSlashesOnArray($value);
- } else {
- $value = stripslashes($value);
- }
- }
- return $value;
- }
- /**
- * Writes input value to $_GET.
- *
- * @param mixed $inputGet
- * 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,
- * 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.
- * Example: 'parentKey|childKey' will result in
- * array('parentKey' => array('childKey' => $inputGet))
- *
- * @return void
- */
- public static function _GETset($inputGet, $key = '') {
- // adds slashes since TYPO3 standard currently is that slashes
- // must be applied (regardless of magic_quotes setting)
- if (is_array($inputGet)) {
- self::addSlashesOnArray($inputGet);
- } else {
- $inputGet = addslashes($inputGet);
- }
- if ($key != '') {
- if (strpos($key, '|') !== FALSE) {
- $pieces = explode('|', $key);
- $newGet = array();
- $pointer =& $newGet;
- foreach ($pieces as $piece) {
- $pointer =& $pointer[$piece];
- }
- $pointer = $inputGet;
- $mergedGet = self::array_merge_recursive_overrule(
- $_GET, $newGet
- );
- $_GET = $mergedGet;
- $GLOBALS['HTTP_GET_VARS'] = $mergedGet;
- } else {
- $_GET[$key] = $inputGet;
- $GLOBALS['HTTP_GET_VARS'][$key] = $inputGet;
- }
- } elseif (is_array($inputGet)) {
- $_GET = $inputGet;
- $GLOBALS['HTTP_GET_VARS'] = $inputGet;
- }
- }
- /**
- * Wrapper for the RemoveXSS function.
- * Removes potential XSS code from an input string.
- *
- * Using an external class by Travis Puderbaugh <kallahar@quickwired.com>
- *
- * @param string $string Input string
- * @return string Input string with potential XSS code removed
- */
- public static function removeXSS($string) {
- require_once(PATH_typo3 . 'contrib/RemoveXSS/RemoveXSS.php');
- $string = RemoveXSS::process($string);
- 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)
- *
- * The function takes a file-reference, $theFile, and saves it again through GD or ImageMagick in order to compress the file
- * GIF:
- * If $type is not set, the compression is done with ImageMagick (provided that $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw'] is pointing to the path of a lzw-enabled version of 'convert') else with GD (should be RLE-enabled!)
- * If $type is set to either 'IM' or 'GD' the compression is done with ImageMagick and GD respectively
- * PNG:
- * No changes.
- *
- * $theFile is expected to be a valid GIF-file!
- * The function returns a code for the operation.
- *
- * @param string $theFile Filepath
- * @param string $type See description of function
- * @return string Returns "GD" if GD was used, otherwise "IM" if ImageMagick was used. If nothing done at all, it returns empty string.
- */
- 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
- $temporaryName = dirname($theFile) . '/' . md5(uniqid()) . '.gif';
- // 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);
- unlink($temporaryName);
- }
- $returnCode = 'IM';
- if (@is_file($theFile)) {
- self::fixPermissions($theFile);
- }
- } elseif (($type == 'GD' || !$type) && $gfxConf['gdlib'] && !$gfxConf['gdlib_png']) { // GD
- $tempImage = imageCreateFromGif($theFile);
- imageGif($tempImage, $theFile);
- imageDestroy($tempImage);
- $returnCode = 'GD';
- if (@is_file($theFile)) {
- self::fixPermissions($theFile);
- }
- }
- }
- return $returnCode;
- }
- /**
- * 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
- */
- public static function png_to_gif_by_imagemagick($theFile) {
- if ($GLOBALS['TYPO3_CONF_VARS']['FE']['png_to_gif']
- && $GLOBALS['TYPO3_CONF_VARS']['GFX']['im']
- && $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']
- && strtolower(substr($theFile, -4, 4)) == '.png'
- && @is_file($theFile)) { // IM
- $newFile = substr($theFile, 0, -4) . '.gif';
- $cmd = self::imageMagickCommand('convert', '"' . $theFile . '" "' . $newFile . '"', $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']);
- t3lib_utility_Command::exec($cmd);
- $theFile = $newFile;
- if (@is_file($newFile)) {
- self::fixPermissions($newFile);
- }
- // unlink old file?? May be bad idea because TYPO3 would then recreate the file every time as
- // TYPO3 thinks the file is not generated because it's missing!! So do not unlink $theFile here!!
- }
- return $theFile;
- }
- /**
- * Returns filename of the png/gif version of the input file (which can be png or gif).
- * If input file type does not match the wanted output type a conversion is made and temp-filename returned.
- *
- * @param string $theFile Filepath of image file
- * @param boolean $output_png If set, then input file is converted to PNG, otherwise to GIF
- * @return string If the new image file exists, its filepath is returned
- */
- public static function read_png_gif($theFile, $output_png = FALSE) {
- if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im'] && @is_file($theFile)) {
- $ext = strtolower(substr($theFile, -4, 4));
- if (
- ((string) $ext == '.png' && $output_png) ||
- ((string) $ext == '.gif' && !$output_png)
- ) {
- return $theFile;
- } else {
- $newFile = PATH_site . 'typo3temp/readPG_' . md5($theFile . '|' . filemtime($theFile)) . ($output_png ? '.png' : '.gif');
- $cmd = self::imageMagickCommand('convert', '"' . $theFile . '" "' . $newFile . '"', $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path']);
- t3lib_utility_Command::exec($cmd);
- if (@is_file($newFile)) {
- self::fixPermissions($newFile);
- return $newFile;
- }
- }
- }
- }
- /*************************
- *
- * STRING FUNCTIONS
- *
- *************************/
- /**
- * 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
- */
- 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'])) {
- $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 = self::makeInstance('t3lib_cs');
- 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 6.0 - 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.
- * @return boolean TRUE if an IP-mask from $list matches $baseIP
- */
- public static function cmpIP($baseIP, $list) {
- $list = trim($list);
- if ($list === '') {
- return FALSE;
- } elseif ($list === '*') {
- return TRUE;
- }
- if (strpos($baseIP, ':') !== FALSE && self::validIPv6($baseIP)) {
- return self::cmpIPv6($baseIP, $list);
- } else {
- return self::cmpIPv4($baseIP, $list);
- }
- }
- /**
- * 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
- */
- public static function cmpIPv4($baseIP, $list) {
- $IPpartsReq = explode('.', $baseIP);
- if (count($IPpartsReq) == 4) {
- $values = self::trimExplode(',', $list, 1);
- foreach ($values as $test) {
- $testList = explode('/', $test);
- if (count($testList) == 2) {
- list($test, $mask) = $testList;
- } else {
- $mask = FALSE;
- }
- if (intval($mask)) {
- // "192.168.3.0/24"
- $lnet = ip2long($test);
- $lip = ip2long($baseIP);
- $binnet = str_pad(decbin($lnet), 32, '0', STR_PAD_LEFT);
- $firstpart = substr($binnet, 0, $mask);
- $binip = str_pad(decbin($lip), 32, '0', STR_PAD_LEFT);
- $firstip = substr($binip, 0, $mask);
- $yes = (strcmp($firstpart, $firstip) == 0);
- } else {
- // "192.168.*.*"
- $IPparts = explode('.', $test);
- $yes = 1;
- foreach ($IPparts as $index => $val) {
- $val = trim($val);
- if (($val !== '*') && ($IPpartsReq[$index] !== $val)) {
- $yes = 0;
- }
- }
- }
- if ($yes) {
- return TRUE;
- }
- }
- }
- return FALSE;
- }
- /**
- * 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
- */
- public static function cmpIPv6($baseIP, $list) {
- $success = FALSE; // Policy default: Deny connection
- $baseIP = self::normalizeIPv6($baseIP);
- $values = self::trimExplode(',', $list, 1);
- foreach ($values as $test) {
- $testList = explode('/', $test);
- if (count($testList) == 2) {
- list($test, $mask) = $testList;
- } else {
- $mask = FALSE;
- }
- 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
- $success = TRUE;
- } elseif ($maskInt == 128) {
- $success = ($test === $baseIP);
- } else {
- $testBin = self::IPv6Hex2Bin($test);
- $baseIPBin = self::IPv6Hex2Bin($baseIP);
- $success = TRUE;
- // 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
- $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) {
- $success = FALSE;
- }
- }
- }
- }
- if ($success) {
- return TRUE;
- }
- }
- return FALSE;
- }
- /**
- * Transform a regular IPv6 address from hex-representation into binary
- *
- * @param string $hex IPv6 address in hex-presentation
- * @return string Binary representation (16 characters, 128 characters)
- * @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;
- }
- /**
- * Transform an IPv6 address from binary to hex-representation
- *
- * @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;
- }
- /**
- * Normalize an IPv6 address to full length
- *
- * @param string $address Given IPv6 address
- * @return string Normalized address
- * @see compressIPv6()
- */
- public static function normalizeIPv6($address) {
- $normalizedAddress = '';
- $stageOneAddress = '';
- // according to RFC lowercase-representation is recommended
- $address = strtolower($address);
- // normalized representation has 39 characters (0000:0000:0000:0000:0000:0000:0000:0000)
- if (strlen($address) == 39) {
- // already in full expanded form
- return $address;
- }
- $chunks = explode('::', $address); // Count 2 if if address has hidden zero blocks
- if (count($chunks) == 2) {
- $chunksLeft = explode(':', $chunks[0]);
- $chunksRight = explode(':', $chunks[1]);
- $left = count($chunksLeft);
- $right = count($chunksRight);
- // Special case: leading zero-only blocks count to 1, should be 0
- if ($left == 1 && strlen($chunksLeft[0]) == 0) {
- $left = 0;
- }
- $hiddenBlocks = 8 - ($left + $right);
- $hiddenPart = '';
- $h = 0;
- while ($h < $hiddenBlocks) {
- $hiddenPart .= '0000:';
- $h++;
- }
- if ($left == 0) {
- $stageOneAddress = $hiddenPart . $chunks[1];
- } else {
- $stageOneAddress = $chunks[0] . ':' . $hiddenPart . $chunks[1];
- }
- } else {
- $stageOneAddress = $address;
- }
- // normalize the blocks:
- $blocks = explode(':', $stageOneAddress);
- $divCounter = 0;
- foreach ($blocks as $block) {
- $tmpBlock = '';
- $i = 0;
- $hiddenZeros = 4 - strlen($block);
- while ($i < $hiddenZeros) {
- $tmpBlock .= '0';
- $i++;
- }
- $normalizedAddress .= $tmpBlock . $block;
- if ($divCounter < 7) {
- $normalizedAddress .= ':';
- $divCounter++;
- }
- }
- return $normalizedAddress;
- }
- /**
- * Compress an IPv6 address to the shortest notation
- *
- * @param string $address Given IPv6 address
- * @return string Compressed address
- * @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;
- }
- /**
- * Validate a given IP address.
- *
- * Possible format are IPv4 and IPv6.
- *
- * @param string $ip IP address to be tested
- * @return boolean TRUE if $ip is either of IPv4 or IPv6 format.
- */
- public static function validIP($ip) {
- return (filter_var($ip, FILTER_VALIDATE_IP) !== FALSE);
- }
- /**
- * Validate a given IP address to the IPv4 address format.
- *
- * Example for possible format: 10.0.45.99
- *
- * @param string $ip IP address to be tested
- * @return boolean TRUE if $ip is of IPv4 format.
- */
- public static function validIPv4($ip) {
- return (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== FALSE);
- }
- /**
- * Validate a given IP address to the IPv6 address format.
- *
- * Example for possible format: 43FB::BB3F:A0A0:0 | ::1
- *
- * @param string $ip IP address to be tested
- * @return boolean TRUE if $ip is of IPv6 format.
- */
- public static function validIPv6($ip) {
- return (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== FALSE);
- }
- /**
- * Match fully qualified domain name with list of strings with wildcard
- *
- * @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
- */
- public static function cmpFQDN($baseHost, $list) {
- $baseHost = trim($baseHost);
- if (empty($baseHost)) {
- 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
- // the reverse-DNS for his IP (security when for example used with REMOTE_ADDR)
- $baseHostName = gethostbyaddr($baseHost);
- if ($baseHostName === $baseHost) {
- // unable to resolve hostname
- return FALSE;
- }
- } else {
- $baseHostName = $baseHost;
- }
- $baseHostNameParts = explode('.', $baseHostName);
- $values = self::trimExplode(',', $list, 1);
- foreach ($values as $test) {
- $hostNameParts = explode('.', $test);
- // to match hostNameParts can only be shorter (in case of wildcards) or equal
- if (count($hostNameParts) > count($baseHostNameParts)) {
- continue;
- }
- $yes = TRUE;
- foreach ($hostNameParts as $index => $val) {
- $val = trim($val);
- if ($val === '*') {
- // wildcard valid for one or more hostname-parts
- $wildcardStart = $index + 1;
- // wildcard as last/only part always matches, otherwise perform recursive checks
- if ($wildcardStart < count($hostNameParts)) {
- $wildcardMatched = FALSE;
- $tempHostName = implode('.', array_slice($hostNameParts, $index + 1));
- while (($wildcardStart < count($baseHostNameParts)) && (!$wildcardMatched)) {
- $tempBaseHostName = implode('.', array_slice($baseHostNameParts, $wildcardStart));
- $wildcardMatched = self::cmpFQDN($tempBaseHostName, $tempHostName);
- $wildcardStart++;
- }
- if ($wildcardMatched) {
- // match found by recursive compare
- return TRUE;
- } else {
- $yes = FALSE;
- }
- }
- } elseif ($baseHostNameParts[$index] !== $val) {
- // in case of no match
- $yes = FALSE;
- }
- }
- if ($yes) {
- return TRUE;
- }
- }
- return FALSE;
- }
- /**
- * 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.
- *
- * @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) {
- return (strpos(',' . $list . ',', ',' . $item . ',') !== FALSE ? TRUE : FALSE);
- }
- /**
- * 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
- */
- public static function rmFromList($element, $list) {
- $items = explode(',', $list);
- foreach ($items as $k => $v) {
- if ($v == $element) {
- unset($items[$k]);
- }
- }
- return implode(',', $items);
- }
- /**
- * 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
- */
- public static function expandList($list) {
- $items = explode(',', $list);
- $list = array();
- foreach ($items as $item) {
- $range = explode('-', $item);
- if (isset($range[1])) {
- $runAwayBrake = 1000;
- for ($n = $range[0]; $n <= $range[1]; $n++) {
- $list[] = $n;
- $runAwayBrake--;
- if ($runAwayBrake <= 0) {
- break;
- }
- }
- } else {
- $list[] = $item;
- }
- }
- return implode(',', $list);
- }
- /**
- * 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 6.0 - 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 6.0 - 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 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
- if (t3lib_utility_VersionNumber::convertVersionNumberToInteger(TYPO3_version) >= 4007000) {
- self::logDeprecatedFunction();
- }
- return t3lib_utility_VersionNumber::convertVersionNumberToInteger($verNumberStr);
- }
- /**
- * 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"!)
- * @return boolean Returns TRUE if this setup is compatible with the provided version number
- * @todo Still needs a function to convert versions to branches
- */
- public static function compat_version($verNumberStr) {
- $currVersionStr = $GLOBALS['TYPO3_CONF_VARS']['SYS']['compat_version'] ? $GLOBALS['TYPO3_CONF_VARS']['SYS']['compat_version'] : TYPO3_branch;
- if (t3lib_utility_VersionNumber::convertVersionNumberToInteger($currVersionStr) < t3lib_utility_VersionNumber::convertVersionNumberToInteger($verNumberStr)) {
- return FALSE;
- } else {
- return TRUE;
- }
- }
- /**
- * Makes a positive integer hash out of the first 7 chars from the md5 hash of the input
- *
- * @param string $str String to md5-hash
- * @return integer Returns 28bit integer-hash
- */
- public static function md5int($str) {
- return hexdec(substr(md5($str), 0, 7));
- }
- /**
- * Returns the first 10 positions of the MD5-hash (changed from 6 to 10 recently)
- *
- * @param string $input Input string to be md5-hashed
- * @param integer $len The string-length of the output
- * @return string Substring of the resulting md5-hash, being $len chars long (from beginning)
- */
- public static function shortMD5($input, $len = 10) {
- return substr(md5($input), 0, $len);
- }
- /**
- * Returns a proper HMAC on a given input string and secret TYPO3 encryption key.
- *
- * @param string $input Input string to create HMAC from
- * @param string $additionalSecret additionalSecret to prevent hmac beeing used in a different context
- * @return string resulting (hexadecimal) HMAC currently with a length of 40 (HMAC-SHA-1)
- */
- public static function hmac($input, $additionalSecret = '') {
- $hashAlgorithm = 'sha1';
- $hashBlocksize = 64;
- $hmac = '';
- $secret = $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] . $additionalSecret;
- if (extension_loaded('hash') && function_exists('hash_hmac') && function_exists('hash_algos') && in_array($hashAlgorithm, hash_algos())) {
- $hmac = hash_hmac($hashAlgorithm, $input, $secret);
- } else {
- // outer padding
- $opad = str_repeat(chr(0x5C), $hashBlocksize);
- // inner padding
- $ipad = str_repeat(chr(0x36), $hashBlocksize);
- if (strlen($secret) > $hashBlocksize) {
- // keys longer than block size are shorten
- $key = str_pad(pack('H*', call_user_func($hashAlgorithm, $secret)), $hashBlocksize, chr(0));
- } else {
- // keys shorter than block size are zero-padded
- $key = str_pad($secret, $hashBlocksize, chr(0));
- }
- $hmac = call_user_func($hashAlgorithm, ($key ^ $opad) . pack('H*', call_user_func($hashAlgorithm, ($key ^ $ipad) . $input)));
- }
- return $hmac;
- }
- /**
- * 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 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) {
- if (is_array($in_list)) {
- throw new InvalidArgumentException(
- 'TYPO3 Fatal Error: t3lib_div::uniqueList() does NOT support array arguments anymore! Only string comma lists!',
- 1270853885
- );
- }
- if (isset($secondParameter)) {
- throw new InvalidArgumentException(
- 'TYPO3 Fatal Error: t3lib_div::uniqueList() does NOT support more than a single argument value anymore. You have specified more than one!',
- 1270853886
- );
- }
- return implode(',', array_unique(self::trimExplode(',', $in_list, 1)));
- }
- /**
- * Splits a reference to a file in 5 parts
- *
- * @param string $fileref Filename/filepath to be analysed
- * @return array Contains keys [path], [file], [filebody], [fileext], [realFileext]
- */
- public static function split_fileref($fileref) {
- $reg = array();
- if (preg_match('/(.*\/)(.*)$/', $fileref, $reg)) {
- $info['path'] = $reg[1];
- $info['file'] = $reg[2];
- } else {
- $info['path'] = '';
- $info['file'] = $fileref;
- }
- $reg = '';
- if (!is_dir($fileref) && preg_match('/(.*)\.([^\.]*$)/', $info['file'], $reg)) {
- $info['filebody'] = $reg[1];
- $info['fileext'] = strtolower($reg[2]);
- $info['realFileext'] = $reg[2];
- } else {
- $info['filebody'] = $info['file'];
- $info['fileext'] = '';
- }
- reset($info);
- return $info;
- }
- /**
- * Returns the directory part of a path without trailing slash
- * If there is no dir-part, then an empty string is returned.
- * Behaviour:
- *
- * '/dir1/dir2/script.php' => '/dir1/dir2'
- * '/dir1/' => '/dir1'
- * 'dir1/script.php' => 'dir1'
- * 'd/script.php' => 'd'
- * '/script.php' => ''
- * '' => ''
- *
- * @param string $path Directory name / path
- * @return string Processed input value. See function description.
- */
- public static function dirname($path) {
- $p = self::revExplode('/', $path, 2);
- return count($p) == 2 ? $p[0] : '';
- }
- /**
- * Modifies a HTML Hex color by adding/subtracting $R,$G and $B integers
- *
- * @param string $color A hexadecimal color code, #xxxxxx
- * @param integer $R Offset value 0-255
- * @param integer $G Offset value 0-255
- * @param integer $B Offset value 0-255
- * @return string A hexadecimal color code, #xxxxxx, modified according to input vars
- * @see modifyHTMLColorAll()
- */
- public static function modifyHTMLColor($color, $R, $G, $B) {
- // This takes a hex-color (# included!) and adds $R, $G and $B to the HTML-color (format: #xxxxxx) and returns the new color
- $nR = t3lib_utility_Math::forceIntegerInRange(hexdec(substr($color, 1, 2)) + $R, 0, 255);
- $nG = t3lib_utility_Math::forceIntegerInRange(hexdec(substr($color, 3, 2)) + $G, 0, 255);
- $nB = t3lib_utility_Math::forceIntegerInRange(hexdec(substr($color, 5, 2)) + $B, 0, 255);
- return '#' .
- substr('0' . dechex($nR), -2) .
- substr('0' . dechex($nG), -2) .
- substr('0' . dechex($nB), -2);
- }
- /**
- * Modifies a HTML Hex color by adding/subtracting $all integer from all R/G/B channels
- *
- * @param string $color A hexadecimal color code, #xxxxxx
- * @param integer $all Offset value 0-255 for all three channels.
- * @return string A hexadecimal color code, #xxxxxx, modified according to input vars
- * @see modifyHTMLColor()
- */
- public static function modifyHTMLColorAll($color, $all) {
- return self::modifyHTMLColor($color, $all, $all, $all);
- }
- /**
- * 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 6.0 - 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
- * @param string $partStr Reference string which must be found as the "first part" of the full string
- * @return boolean TRUE if $partStr was found to be equal to the first part of $str
- */
- public static function isFirstPartOfStr($str, $partStr) {
- return $partStr != '' && strpos((string) $str, (string) $partStr, 0) === 0;
- }
- /**
- * Formats the input integer $sizeInBytes as bytes/kilobytes/megabytes (-/K/M)
- *
- * @param integer $sizeInBytes Number of bytes to format.
- * @param string $labels Labels for bytes, kilo, mega and giga separated by vertical bar (|) and possibly encapsulated in "". Eg: " | K| M| G" (which is the default value)
- * @return string Formatted representation of the byte number, for output.
- */
- public static function formatSize($sizeInBytes, $labels = '') {
- // Set labels:
- if (strlen($labels) == 0) {
- $labels = ' | K| M| G';
- } else {
- $labels = str_replace('"', '', $labels);
- }
- $labelArr = explode('|', $labels);
- // Find size:
- if ($sizeInBytes > 900) {
- if ($sizeInBytes > 900000000) { // GB
- $val = $sizeInBytes / (1024 * 1024 * 1024);
- return number_format($val, (($val < 20) ? 1 : 0), '.', '') . $labelArr[3];
- }
- elseif ($sizeInBytes > 900000) { // MB
- $val = $sizeInBytes / (1024 * 1024);
- return number_format($val, (($val < 20) ? 1 : 0), '.', '') . $labelArr[2];
- } else { // KB
- $val = $sizeInBytes / (1024);
- return number_format($val, (($val < 20) ? 1 : 0), '.', '') . $labelArr[1];
- }
- } else { // Bytes
- return $sizeInBytes . $labelArr[0];
- }
- }
- /**
- * Returns microtime input to milliseconds
- *
- * @param string $microtime Microtime
- * @return integer Microtime input string converted to an integer (milliseconds)
- */
- public static function convertMicrotime($microtime) {
- $parts = explode(' ', $microtime);
- return round(($parts[0] + $parts[1]) * 1000);
- }
- /**
- * This splits a string by the chars in $operators (typical /+-*) and returns an array with them in
- *
- * @param string $string Input string, eg "123 + 456 / 789 - 4"
- * @param string $operators Operators to split by, typically "/+-*"
- * @return array Array with operators and operands separated.
- * @see tslib_cObj::calc(), tslib_gifBuilder::calcOffset()
- */
- public static function splitCalc($string, $operators) {
- $res = Array();
- $sign = '+';
- while ($string) {
- $valueLen = strcspn($string, $operators);
- $value = substr($string, 0, $valueLen);
- $res[] = Array($sign, trim($value));
- $sign = substr($string, $valueLen, 1);
- $string = substr($string, $valueLen + 1);
- }
- reset($res);
- return $res;
- }
- /**
- * 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 6.0 - 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 6.0 - 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.
- * @return string Converted result.
- */
- public static function htmlspecialchars_decode($value) {
- $value = str_replace('>', '>', $value);
- $value = str_replace('<', '<', $value);
- $value = str_replace('"', '"', $value);
- $value = str_replace('&', '&', $value);
- return $value;
- }
- /**
- * Re-converts HTML entities if they have been converted by htmlspecialchars()
- *
- * @param string $str String which contains eg. "&amp;" which should stay "&". Or "&#1234;" to "Ӓ". Or "&#x1b;" to ""
- * @return string Converted result.
- */
- public static function deHSCentities($str) {
- return preg_replace('/&([#[:alnum:]]*;)/', '&\1', $str);
- }
- /**
- * This function is used to escape any ' -characters when transferring text to JavaScript!
- *
- * @param string $string String to escape
- * @param boolean $extended If set, also backslashes are escaped.
- * @param string $char The character to escape, default is ' (single-quote)
- * @return string Processed input string
- */
- public static function slashJS($string, $extended = FALSE, $char = "'") {
- if ($extended) {
- $string = str_replace("\\", "\\\\", $string);
- }
- return str_replace($char, "\\" . $char, $string);
- }
- /**
- * Version of rawurlencode() where all spaces (%20) are re-converted to space-characters.
- * Useful when passing text to JavaScript where you simply url-encode it to get around problems with syntax-errors, linebreaks etc.
- *
- * @param string $str String to raw-url-encode with spaces preserved
- * @return string Rawurlencoded result of input string, but with all %20 (space chars) converted to real spaces.
- */
- public static function rawUrlEncodeJS($str) {
- return str_replace('%20', ' ', rawurlencode($str));
- }
- /**
- * rawurlencode which preserves "/" chars
- * Useful when file paths should keep the "/" chars, but have all other special chars encoded.
- *
- * @param string $str Input string
- * @return string Output string
- */
- public static function rawUrlEncodeFP($str) {
- return str_replace('%2F', '/', rawurlencode($str));
- }
- /**
- * Checking syntax of input email address
- *
- * @param string $email Input string to evaluate
- * @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
- // fixed in PHP 5.3.4; length restriction per SMTP RFC 2821
- if (strlen($email) > 320) {
- return 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);
- }
- /**
- * Checks if current e-mail sending method does not accept recipient/sender name
- * in a call to PHP mail() function. Windows version of mail() and mini_sendmail
- * program are known not to process such input correctly and they cause SMTP
- * errors. This function will return TRUE if current mail sending method has
- * problem with recipient name in recipient/sender argument for mail().
- *
- * TODO: 4.3 should have additional configuration variable, which is combined
- * by || with the rest in this function.
- *
- * @return boolean TRUE if mail() does not accept recipient name
- */
- public static function isBrokenEmailEnvironment() {
- return TYPO3_OS == 'WIN' || (FALSE !== strpos(ini_get('sendmail_path'), 'mini_sendmail'));
- }
- /**
- * Changes from/to arguments for mail() function to work in any environment.
- *
- * @param string $address Address to adjust
- * @return string Adjusted address
- * @see t3lib_::isBrokenEmailEnvironment()
- */
- public static function normalizeMailAddress($address) {
- if (self::isBrokenEmailEnvironment() && FALSE !== ($pos1 = strrpos($address, '<'))) {
- $pos2 = strpos($address, '>', $pos1);
- $address = substr($address, $pos1 + 1, ($pos2 ? $pos2 : strlen($address)) - $pos1 - 1);
- }
- return $address;
- }
- /**
- * Formats a string for output between <textarea>-tags
- * All content outputted in a textarea form should be passed through this function
- * Not only is the content htmlspecialchar'ed on output but there is also a single newline added in the top. The newline is necessary because browsers will ignore the first newline after <textarea> if that is the first character. Therefore better set it!
- *
- * @param string $content Input string to be formatted.
- * @return string Formatted for <textarea>-tags
- */
- public static function formatForTextarea($content) {
- return LF . htmlspecialchars($content);
- }
- /**
- * Converts string to uppercase
- * The function converts all Latin characters (a-z, but no accents, etc) to
- * uppercase. It is safe for all supported character sets (incl. utf-8).
- * Unlike strtoupper() it does not honour the locale.
- *
- * @param string $str Input string
- * @return string Uppercase String
- */
- public static function strtoupper($str) {
- return strtr((string) $str, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
- }
- /**
- * Converts string to lowercase
- * The function converts all Latin characters (A-Z, but no accents, etc) to
- * lowercase. It is safe for all supported character sets (incl. utf-8).
- * Unlike strtolower() it does not honour the locale.
- *
- * @param string $str Input string
- * @return string Lowercase String
- */
- public static function strtolower($str) {
- return strtr((string) $str, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
- }
- /**
- * Returns a string of highly randomized bytes (over the full 8-bit range).
- *
- * 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
- * @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 openssl and mcrypt failed, try /dev/urandom
- if (!isset($bytes[$bytesToReturn - 1])) {
- $bytes .= self::generateRandomBytesUrandom($bytesToGenerate);
- }
- }
- // Fall back if other random byte generation failed until now
- if (!isset($bytes[$bytesToReturn - 1])) {
- $bytes .= self::generateRandomBytesFallback($bytesToReturn);
- }
- }
- // 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…
Large files files are truncated, but you can click here to view the full file