Last active
August 18, 2017 15:14
-
-
Save oWeRQ/6d2514409e84f863122d07ddb8a2878d to your computer and use it in GitHub Desktop.
mbstring overload fix
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
defined('MBO_ENCODING') || define('MBO_ENCODING', 'iso-8859-1'); | |
function mbo_virtual($path, $debug = 0) | |
{ | |
static $realFiles = array(); | |
$cacheDir = __DIR__.'/cache/'; | |
$callFrom = debug_backtrace(0, 1); | |
$callFile = $callFrom[0]['file']; | |
$isRealPath = (substr($path, 0, 1) === '/'); | |
$isFromCache = (strpos($callFile, $cacheDir) === 0); | |
if ($isRealPath && $isFromCache) { | |
$realFile = realpath(str_replace($cacheDir, dirname($realFiles[$callFile]).'/', $path)); | |
} else { | |
//TODO: check include paths | |
//$paths = explode(':', get_include_path()); | |
$realFile = realpath($path); | |
} | |
if (!$realFile) { | |
var_dump(compact('callFile', 'path', 'isRealPath', 'isFromCache', 'realPath')); | |
die(); | |
} | |
$cacheFile = $cacheDir.str_replace('/', '_', $realFile); | |
if ($debug || !file_exists($cacheFile)) { | |
if (!@file_put_contents($cacheFile, mbo_virtual_patch($realFile, $debug))) | |
return $realFile; | |
} | |
$realFiles[$cacheFile] = $realFile; | |
return $cacheFile; | |
} | |
function mbo_virtual_check($replace) | |
{ | |
$chars = count_chars($replace); | |
return ($chars[ord('\'')] % 2 === 0 && $chars[ord('\"')] % 2 === 0 && $chars[ord('(')] === $chars[ord(')')]); | |
} | |
function mbo_virtual_patch($realFile, $debug) | |
{ | |
$realDir = dirname($realFile); | |
$source = file_get_contents($realFile); | |
$source = strtr($source, array( | |
'__FILE__' => "'$realFile'", | |
'__DIR__' => "'$realDir'", | |
)); | |
$source = preg_replace_callback('/\b(require|include)(_once)?\b\s*?([^;\n]+);/', function($m) use($debug){ | |
return !mbo_virtual_check($m[3]) ? $m[0] : $m[1].$m[2].' mbo_virtual('.$m[3].', '.$debug.');'; | |
}, $source); | |
return mbo_patch($source); | |
} | |
function mbo_patch($source, $revert = false) | |
{ | |
$output = ''; | |
if (is_array($revert)) { | |
$replace = $revert; | |
} else { | |
$replace = [ | |
'strlen' => 'mbo_strlen', | |
'strpos' => 'mbo_strpos', | |
'strrpos' => 'mbo_strrpos', | |
'substr' => 'mbo_substr', | |
'strtolower' => 'mbo_strtolower', | |
'strtoupper' => 'mbo_strtoupper', | |
'stripos' => 'mbo_stripos', | |
'strripos' => 'mbo_strripos', | |
'strstr' => 'mbo_strstr', | |
'stristr' => 'mbo_stristr', | |
'strrchr' => 'mbo_strrchr', | |
'substr_count' => 'mbo_substr_count', | |
]; | |
if ($revert) { | |
$replace = array_flip($replace); | |
} | |
} | |
$tokens = token_get_all($source); | |
foreach ($tokens as $i => $token) { | |
if (!is_array($token)) { | |
$output .= $token; | |
} elseif ($token[0] === T_STRING && isset($replace[$token[1]])) { | |
$isReplace = ($i === 0 || !is_array($tokens[$i - 1]) || ($tokens[$i - 1][0] !== T_DOUBLE_COLON && $tokens[$i - 1][0] !== T_OBJECT_OPERATOR)); | |
$output .= $isReplace ? $replace[$token[1]] : $token[1]; | |
} else { | |
$output .= $token[1]; | |
} | |
} | |
return $output; | |
} | |
function mbo_strlen($string) | |
{ | |
return mb_strlen($string, MBO_ENCODING); | |
} | |
function mbo_strpos($haystack, $needle, $offset = 0) | |
{ | |
return mb_strpos($haystack, $needle, $offset, MBO_ENCODING); | |
} | |
function mbo_strrpos($haystack, $needle, $offset = 0) | |
{ | |
return mb_strrpos($haystack, $needle, $offset, MBO_ENCODING); | |
} | |
function mbo_substr($string, $start) | |
{ | |
$args = func_get_args(); | |
if (array_key_exists(2, $args)) | |
$length = $args[2]; | |
else | |
$length = mb_strlen($string, MBO_ENCODING); | |
return mb_substr($string, $start, $length, MBO_ENCODING); | |
} | |
function mbo_strtolower($string) | |
{ | |
return mb_strtolower($string, MBO_ENCODING); | |
} | |
function mbo_strtoupper($string) | |
{ | |
return mb_strtoupper($string, MBO_ENCODING); | |
} | |
function mbo_stripos($haystack, $needle, $offset = 0) | |
{ | |
return mb_stripos($haystack, $needle, $offset, MBO_ENCODING); | |
} | |
function mbo_strripos($haystack, $needle, $offset = 0) | |
{ | |
return mb_strripos($haystack, $needle, $offset, MBO_ENCODING); | |
} | |
function mbo_strstr($haystack, $needle, $before_needle = false) | |
{ | |
return mb_strstr($haystack, $needle, $before_needle, MBO_ENCODING); | |
} | |
function mbo_stristr($haystack, $needle, $before_needle = false) | |
{ | |
return mb_stristr($haystack, $needle, $before_needle, MBO_ENCODING); | |
} | |
function mbo_strrchr($haystack, $needle) | |
{ | |
$needle = mb_substr($needle, 0, 1, MBO_ENCODING); | |
if (is_integer($needle)) | |
$needle = chr($needle); | |
return mb_strrchr($haystack, $needle, false, MBO_ENCODING); | |
} | |
function mbo_substr_count($haystack, $needle, $offset = 0) | |
{ | |
$args = func_get_args(); | |
if (array_key_exists(3, $args)) | |
$length = $args[3]; | |
else | |
$length = mb_strlen($haystack, MBO_ENCODING); | |
$haystack = mb_substr($haystack, $offset, $length, MBO_ENCODING); | |
return mb_substr_count($haystack, $needle, MBO_ENCODING); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment