Xcache баг-трекер декомпилятора

Статус
В этой теме нельзя размещать новые ответы.
Проблему __NAMESPACE__ и т.п. констант разжевал тут - Для просмотра ссылки Войди или Зарегистрируйся
Скорее всего не удастся надежно распознать, т.к. в опкоде уже текстовые константы, только если их проверять каждый раз на соответствие текущего состояния (имя функции, номер строки, имя метода) и вставлять служебную константу, но это будет не надежно.
 
такого рода константы вроде бы в др случаях распознаются
PHP:
if (!defined('__DIR__')) { 
  class __FILE_CLASS__ { 
    function  __toString() { 
      $X = debug_backtrace(); 
      return dirname($X[1]['file']); 
    } 
  } 
  define('__DIR__', new __FILE_CLASS__); 
}
[/spoil]
[spoil]
PHP:
<?php 
echo (defined('__DIR__') ? '__DIR__ is defined' : '__DIR__ is NOT defined' . PHP_EOL); 
echo (defined('__FILE__') ? '__FILE__ is defined' : '__FILE__ is NOT defined' . PHP_EOL); 
echo (defined('PHP_VERSION') ? 'PHP_VERSION is defined' : 'PHP_VERSION is NOT defined') . PHP_EOL; 
echo 'PHP Version: ' . PHP_VERSION . PHP_EOL; 
?>
[/spoil]
[spoil]
PHP:
<?php 
 
// With __STATIC__ keyword. (Would be better.) 
 
class Model 
{ 
    public static function find() 
    { 
        echo __STATIC__; 
    } 
} 
 
class Product extends Model {} 
 
class User extends Model {} 
 
Product::find(); // "Product" 
User::find(); // "User" 
 
?>
 
такого рода константы вроде бы в др случаях распознаются
Вся разница в содержимом опкодов =( Функция выводит только то, что ей передают.
И вот еще такой код совсем разваливается при разборе:
PHP:
namespace myProject {
//Здесь должен быть код, относящийся к пространству имен myProject.
function helloWorld() {
print('Hello world!');
}
}

//Объявляем второе пространство имен, в котором опишем констансту и
//произвольный класс
namespace myProject2 {
const MY_CONST = 'PHP 5.3.0';

class MyClass {
static function helloWorld() {
print('Hello world from Class');
}

}
}

//Дочернее пространство имен
namespace myProject2\sub {
function helloWorld() {
print('Hello world from sub namespace');
}
}
, но тут мало того, что нужно пространства имен из получившихся строковых констант выдирать, так еще и менять логику собирания классов и функций, чтобы они собирались последовательно, а не как сейчас - вначале классы, потом функции, потом остальной код.
 
такого рода константы вроде бы в др случаях распознаются
Там, где они распознаются - они взять в "", т.е. передаются как строка, а не как magic constant. Ни __STATIC__, ни __FILE_CLASS__ не являются magic constant, это обычные константы, соответственно они и работают. Список служебных констант - Для просмотра ссылки Войди или Зарегистрируйся.

Но вообще вот так при компиляции обрабатываются константы в сканнере (т.е. в лексер они уже приходят обработанными:(
Код:
<ST_IN_SCRIPTING>"__LINE__" {
    zendlval->value.lval = CG(zend_lineno);
    zendlval->type = IS_LONG;
    return T_LINE;
}
 
<ST_IN_SCRIPTING>"__FILE__" {
    char *filename = zend_get_compiled_filename(TSRMLS_C);
    if (!filename) {
        filename = "";
    }
    zendlval->value.str.len = strlen(filename);
    zendlval->value.str.val = estrndup(filename, zendlval->value.str.len);
    zendlval->type = IS_STRING;
    return T_FILE;
}
Как видно, константы уже перед лексером заменены на свои значения, т.е. невозможно восстановить их первоначальный вид.

2dima2k: обещанный патч $a or die("") будет или копаться?
 
покопался в RM насчет __FILE__, это тоже мэджик константы (там была разобрана замена на __FILE__)
если как-то конечно это выглядит информативно, верно без кавычек, вырисовывается ситуация со слешами
 
2dima2k: обещанный патч $a or die("") будет или копаться?

PHP:
case XC_EXIT: // {{{
$op1val = $this->getOpVal($op1, $EX);
$resvar = "exit(" . str($op1val) . ")"; //sidxx55 not empty DIE fix code
break;
// }}}
меняем на
PHP:
case XC_EXIT: // {{{
$op1val = $this->getOpVal($op1, $EX);
$resvar = "exit(" . str($op1val) . ")"; //sidxx55 not empty DIE fix code
if ( $opcodes[$i + 1]['opcode'] == XC_BOOL
&& $opcodes[$i + 1]['op1']['op_type'] == XC_IS_CONST
&& $opcodes[$i + 1]['op1']['constant'] === TRUE
) {
$istmpres = TRUE;
}
break;
// }}}
и
PHP:
case XC_BOOL: // {{{
$resvar = /*'(bool) ' .*/
$this->getOpVal($op1, $EX);
break;
// }}}
меняем на
PHP:
case XC_BOOL: // {{{
if ( $opcodes[$i - 1]['opcode'] == XC_EXIT
&& $op['op1']['op_type'] == XC_IS_CONST
&& $op['op1']['constant'] === TRUE
) {
$resvar = $lastresvar;
} else {
$resvar = /*'(bool) ' .*/ $this->getOpVal($op1, $EX);
}
break;
// }}}
После этого условия отрабатываются нормально. Думал еще приводить полученный код к виду "or" или "||" в зависимотси от исходного файла, но получается слишком много правок, а бинопы и триопы и так разбираются за счет скобок правильно, т.ч. задвинул пока эти правки на потом. Пример:
PHP:
// Acts like: ($g = (true && false))
$g = true && false; // $g = true && false; - правильно
 
// Acts like: (($h = true) and false)
$g = true and false; // ($g = true) && false; - тоже правильно
 
покопался в RM насчет __FILE__, это тоже мэджик константы (там была разобрана замена на __FILE__)
если как-то конечно это выглядит информативно, верно без кавычек, вырисовывается ситуация со слешами
Судя по коду, к таким константам выставляется старший бит в размере, а потом, при анализе, он обнуляется но учитывается. Выставить можно только в ядре, а убирать нужно будет в xcache (если он ориентируется на длину, если нет, то можно не убирать). Скорее всего пропатчен zend_language_scanner.l для выставления флага. Возможно как-то сорцы получить?
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху