* */ use Piwik\SettingsServer; /** * ------------------------------ 5.2 --- * @group 5_2 * @since 5.2 * * Additions of PHP 5.2.0 * - some listed here might have appeared earlier or in release candidates * * @emulated * error_get_last * preg_last_error * lchown * lchgrp * E_RECOVERABLE_ERROR * M_SQRTPI * M_LNPI * M_EULER * M_SQRT3 * * @missing * sys_getloadavg * inet_ntop * inet_pton * array_fill_keys * array_intersect_key * array_intersect_ukey * array_diff_key * array_diff_ukey * array_product * pdo_drivers * ftp_ssl_connect * XmlReader * XmlWriter * PDO* * * @unimplementable * stream_* * */ /** * Constants for future 64-bit integer support. * */ if (!defined("PHP_INT_SIZE")) { define("PHP_INT_SIZE", 4); } if (!defined("PHP_INT_MAX")) { define("PHP_INT_MAX", 2147483647); } /* These functions emulate the "character type" extension, which is present in PHP first since version 4.3 per default. In this variant only ASCII and Latin-1 characters are being handled. The first part is eventually faster. */ /** * Sets the default client character set. * * @compat * Procedural style * @bugs * PHP documentation says this function exists in PHP 5 >= 5.0.5, * but it also depends on the versions of external libraries, e.g., * php_mysqli.dll and libmysql.dll. * * @param $link mysqli MySQLi connection resource * @param $charset string Character set * @return bool TRUE on success, FALSE on failure */ if (in_array('mysqli', @get_loaded_extensions()) && !function_exists('mysqli_set_charset')) { function mysqli_set_charset($link, $charset) { return mysqli_query($link, "SET NAMES '$charset'"); } } /** * parse_ini_file() replacement. * Behaves like parse_ini_file($filename, $process_sections); * * @author Andrew Sohn * @author anthon (dot) pang (at) gmail (dot) com * * @param string $filename * @param bool $process_sections (defaults to false) * @return array */ if(function_exists('parse_ini_file')) { // provide a wrapper function _parse_ini_file($filename, $process_sections = false) { if(!file_exists($filename)) { return false; } return parse_ini_file($filename, $process_sections); } } else { // we can't redefine parse_ini_file() if it has been disabled function _parse_ini_file($filename, $process_sections = false) { if(!file_exists($filename)) { return false; } if(function_exists('file_get_contents')) { $ini = file_get_contents($filename); } else if(function_exists('file')) { if($ini = file($filename)) { $ini = implode("\n", $ini); } } else if(function_exists('fopen') && function_exists('fread')) { $handle = fopen($filename, 'r'); if(!$handle) { return false; } $ini = fread($handle, filesize($filename)); fclose($handle); } else { return false; } if($ini === false) { return false; } if(is_string($ini)) { $ini = explode("\n", str_replace("\r", "\n", $ini)); } if (count($ini) == 0) { return array(); } $sections = array(); $values = array(); $result = array(); $globals = array(); $i = 0; foreach ($ini as $line) { $line = trim($line); $line = str_replace("\t", " ", $line); // Comments if (!preg_match('/^[a-zA-Z0-9[]/', $line)) {continue;} // Sections if ($line[0] == '[') { $tmp = explode(']', $line); $sections[] = trim(substr($tmp[0], 1)); $i++; continue; } // Key-value pair list($key, $value) = explode('=', $line, 2); $key = trim($key); $value = trim($value); if (strstr($value, ";")) { $tmp = explode(';', $value); if (count($tmp) == 2) { if ((($value[0] != '"') && ($value[0] != "'")) || preg_match('/^".*"\s*;/', $value) || preg_match('/^".*;[^"]*$/', $value) || preg_match("/^'.*'\s*;/", $value) || preg_match("/^'.*;[^']*$/", $value) ){ $value = $tmp[0]; } } else { if ($value[0] == '"') { $value = preg_replace('/^"(.*)".*/', '$1', $value); } elseif ($value[0] == "'") { $value = preg_replace("/^'(.*)'.*/", '$1', $value); } else { $value = $tmp[0]; } } } $value = trim($value); $value = trim($value, "'\""); if ($i == 0) { if (substr($key, -2) == '[]') { $globals[substr($key, 0, -2)][] = $value; } else { $globals[$key] = $value; } } else { if (substr($key, -2) == '[]') { $values[$i-1][substr($key, 0, -2)][] = $value; } else { $values[$i-1][$key] = $value; } } } for ($j = 0; $j < $i; $j++) { if (isset($values[$j])) { if ($process_sections === true) { $result[$sections[$j]] = $values[$j]; } else { $result[] = $values[$j]; } } else { if ($process_sections === true) { $result[$sections[$j]] = array(); } } } return $result + $globals; } } /** * glob() replacement. * Behaves like glob($pattern, $flags) * * @author BigueNique AT yahoo DOT ca * @author anthon (dot) pang (at) gmail (dot) com * * @param string $pattern * @param int $flags GLOBL_ONLYDIR, GLOB_MARK, GLOB_NOSORT (other flags not supported; defaults to 0) * @return array */ if(function_exists('glob')) { // provide a wrapper function _glob($pattern, $flags = 0) { return glob($pattern, $flags); } } else if(function_exists('opendir') && function_exists('readdir')) { // we can't redefine glob() if it has been disabled function _glob($pattern, $flags = 0) { $path = dirname($pattern); $filePattern = basename($pattern); if(is_dir($path) && ($handle = opendir($path)) !== false) { $matches = array(); while(($file = readdir($handle)) !== false) { if(($file[0] != '.') && fnmatch($filePattern, $file) && (!($flags & GLOB_ONLYDIR) || is_dir("$path/$file"))) { $matches[] = "$path/$file" . ($flags & GLOB_MARK ? '/' : ''); } } closedir($handle); if(!($flags & GLOB_NOSORT)) { sort($matches); } return $matches; } return false; } } else { function _glob($pattern, $flags = 0) { return false; } } /** * Reads entire file into a string. * This function is not 100% compatible with the native function. * * @see http://php.net/file_get_contents * @since PHP 4.3.0 * * @param string $filename Name of the file to read. * @return string The read data or false on failure. */ if (!function_exists('file_get_contents')) { function file_get_contents($filename) { $fhandle = fopen($filename, "r"); $fcontents = fread($fhandle, filesize($filename)); fclose($fhandle); return $fcontents; } } /** * Safe serialize() and unserialize() replacements * * @license Public Domain * * @author anthon (dot) pang (at) gmail (dot) com */ /* * Arbitrary limits for safe_unserialize() */ define('MAX_SERIALIZED_INPUT_LENGTH', 4096); define('MAX_SERIALIZED_ARRAY_LENGTH', 256); define('MAX_SERIALIZED_ARRAY_DEPTH', 3); /** * Safe serialize() replacement * - output a strict subset of PHP's native serialized representation * - does not serialize objects * * @param mixed $value * @return string * @throw Exception if $value is malformed or contains unsupported types (e.g., resources, objects) */ function _safe_serialize( $value ) { if(is_null($value)) { return 'N;'; } if(is_bool($value)) { return 'b:'.(int)$value.';'; } if(is_int($value)) { return 'i:'.$value.';'; } if(is_float($value)) { return 'd:'.str_replace(',', '.', $value).';'; } if(is_string($value)) { return 's:'.strlen($value).':"'.$value.'";'; } if(is_array($value)) { $out = ''; foreach($value as $k => $v) { $out .= _safe_serialize($k) . _safe_serialize($v); } return 'a:'.count($value).':{'.$out.'}'; } // safe_serialize cannot serialize resources or objects return false; } /** * Wrapper for _safe_serialize() that handles exceptions and multibyte encoding issue * * @param mixed $value * @return string */ function safe_serialize( $value ) { // ensure we use the byte count for strings even when strlen() is overloaded by mb_strlen() if (function_exists('mb_internal_encoding') && (((int) ini_get('mbstring.func_overload')) & 2)) { $mbIntEnc = mb_internal_encoding(); mb_internal_encoding('ASCII'); } $out = _safe_serialize($value); if (isset($mbIntEnc)) { mb_internal_encoding($mbIntEnc); } return $out; } /** * Safe unserialize() replacement * - accepts a strict subset of PHP's native serialized representation * - does not unserialize objects * * @param string $str * @return mixed * @throw Exception if $str is malformed or contains unsupported types (e.g., resources, objects) */ function _safe_unserialize($str) { if(strlen($str) > MAX_SERIALIZED_INPUT_LENGTH) { // input exceeds MAX_SERIALIZED_INPUT_LENGTH return false; } if(empty($str) || !is_string($str)) { return false; } $stack = array(); $expected = array(); /* * states: * 0 - initial state, expecting a single value or array * 1 - terminal state * 2 - in array, expecting end of array or a key * 3 - in array, expecting value or another array */ $state = 0; while($state != 1) { $type = isset($str[0]) ? $str[0] : ''; if($type == '}') { $str = substr($str, 1); } else if($type == 'N' && $str[1] == ';') { $value = null; $str = substr($str, 2); } else if($type == 'b' && preg_match('/^b:([01]);/', $str, $matches)) { $value = $matches[1] == '1' ? true : false; $str = substr($str, 4); } else if($type == 'i' && preg_match('/^i:(-?[0-9]+);(.*)/s', $str, $matches)) { $value = (int)$matches[1]; $str = $matches[2]; } else if($type == 'd' && preg_match('/^d:(-?[0-9]+\.?[0-9]*(E[+-][0-9]+)?);(.*)/s', $str, $matches)) { $value = (float)$matches[1]; $str = $matches[3]; } else if($type == 's' && preg_match('/^s:([0-9]+):"(.*)/s', $str, $matches) && substr($matches[2], (int)$matches[1], 2) == '";') { $value = substr($matches[2], 0, (int)$matches[1]); $str = substr($matches[2], (int)$matches[1] + 2); } else if($type == 'a' && preg_match('/^a:([0-9]+):{(.*)/s', $str, $matches) && $matches[1] < MAX_SERIALIZED_ARRAY_LENGTH) { $expectedLength = (int)$matches[1]; $str = $matches[2]; } else { // object or unknown/malformed type return false; } switch($state) { case 3: // in array, expecting value or another array if($type == 'a') { if(count($stack) >= MAX_SERIALIZED_ARRAY_DEPTH) { // array nesting exceeds MAX_SERIALIZED_ARRAY_DEPTH return false; } $stack[] = &$list; $list[$key] = array(); $list = &$list[$key]; $expected[] = $expectedLength; $state = 2; break; } if($type != '}') { $list[$key] = $value; $state = 2; break; } // missing array value return false; case 2: // in array, expecting end of array or a key if($type == '}') { if(count($list) < end($expected)) { // array size less than expected return false; } unset($list); $list = &$stack[count($stack)-1]; array_pop($stack); // go to terminal state if we're at the end of the root array array_pop($expected); if(count($expected) == 0) { $state = 1; } break; } if($type == 'i' || $type == 's') { if(count($list) >= MAX_SERIALIZED_ARRAY_LENGTH) { // array size exceeds MAX_SERIALIZED_ARRAY_LENGTH return false; } if(count($list) >= end($expected)) { // array size exceeds expected length return false; } $key = $value; $state = 3; break; } // illegal array index type return false; case 0: // expecting array or value if($type == 'a') { if(count($stack) >= MAX_SERIALIZED_ARRAY_DEPTH) { // array nesting exceeds MAX_SERIALIZED_ARRAY_DEPTH return false; } $data = array(); $list = &$data; $expected[] = $expectedLength; $state = 2; break; } if($type != '}') { $data = $value; $state = 1; break; } // not in array return false; } } if(!empty($str)) { // trailing data in input return false; } return $data; } /** * Wrapper for _safe_unserialize() that handles exceptions and multibyte encoding issue * * @param string $str * @return mixed */ function safe_unserialize( $str ) { // ensure we use the byte count for strings even when strlen() is overloaded by mb_strlen() if (function_exists('mb_internal_encoding') && (((int) ini_get('mbstring.func_overload')) & 2)) { $mbIntEnc = mb_internal_encoding(); mb_internal_encoding('ASCII'); } $out = _safe_unserialize($str); if (isset($mbIntEnc)) { mb_internal_encoding($mbIntEnc); } return $out; } /** * readfile() replacement. * Behaves similar to readfile($filename); * * @author anthon (dot) pang (at) gmail (dot) com * * @param string $filename * @param bool $useIncludePath * @param resource $context * @return int the number of bytes read from the file, or false if an error occurs */ function _readfile($filename, $byteStart, $byteEnd, $useIncludePath = false, $context = null) { $count = @filesize($filename); // built-in function has a 2 MB limit when using mmap if (function_exists('readfile') && $count <= (2 * 1024 * 1024) && $byteStart == 0 && $byteEnd == $count ) { return @readfile($filename, $useIncludePath, $context); } // when in doubt (or when readfile() function is disabled) $handle = @fopen($filename, SettingsServer::isWindows() ? "rb" : "r"); if ($handle) { fseek($handle, $byteStart); for ($pos = $byteStart; $pos < $byteEnd && !feof($handle); $pos = ftell($handle)) { echo fread($handle, min(8192, $byteEnd - $pos)); @ob_flush(); @flush(); } fclose($handle); return $byteEnd - $byteStart; } return false; } /** * utf8_encode replacement * * @param string $data * @return string */ if (!function_exists('utf8_encode')) { function utf8_encode($data) { if (function_exists('iconv')) { return @iconv('ISO-8859-1', 'UTF-8', $data); } return $data; } } /** * utf8_decode replacement * * @param string $data * @return string */ if (!function_exists('utf8_decode')) { function utf8_decode($data) { if (function_exists('iconv')) { return @iconv('UTF-8', 'ISO-8859-1', $data); } return $data; } } /** * Use strtolower if mb_strtolower doesn't exist (i.e., php not compiled with --enable-mbstring) * This is not a functional replacement for mb_strtolower. * * @param string $input * @param string $charset */ if(!function_exists('mb_strtolower')) { function mb_strtolower($input, $charset) { return strtolower($input); } } /** * On ubuntu in some cases, there is a bug that gzopen does not exist and one must use gzopen64 instead */ if (!function_exists('gzopen') && function_exists('gzopen64')) { function gzopen($filename , $mode = 'r', $use_include_path = 0 ) { return gzopen64($filename , $mode, $use_include_path); } } if (!function_exists('dump')) { function dump () { } } /** * Need to catch that PHP7 error object on php5 */ if( !class_exists('\Error')) { class Error { } } if(!function_exists('fnmatch')) { function fnmatch($pattern, $string) { return preg_match("#^".strtr(preg_quote($pattern, '#'), array('\*' => '.*', '\?' => '.'))."$#i", $string); } // end } // end if