Skip to content

Instantly share code, notes, and snippets.

@oWeRQ
Last active August 18, 2017 15:14
Show Gist options
  • Save oWeRQ/6d2514409e84f863122d07ddb8a2878d to your computer and use it in GitHub Desktop.
Save oWeRQ/6d2514409e84f863122d07ddb8a2878d to your computer and use it in GitHub Desktop.
mbstring overload fix
<?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