Browse Source

merge from trunk

git-svn-id: svn://svn.lighttpd.net/xcache/branches/1.3@784 c26eb9a1-5813-0410-bd6c-c2e55f420ca7
1.3
Xuefer 11 years ago
parent
commit
418ac0b531
  1. 1
      ChangeLog
  2. 51
      Decompiler.class.php
  3. 1
      NEWS
  4. 20
      admin/common.php
  5. 7
      decompilesample.php
  6. 4
      opcode_spec_def.h
  7. 6
      utils.c
  8. 47
      xcache.c

1
ChangeLog

@ -1,5 +1,6 @@
1.3.2 2011-??-??
========
* avoid possible filename injection in admin page
* adds 30 seconds timeout to "compiling" flag
* decompiler: improves decompiling
* disassembler: DECLARE_INHERITED_CLASS/DELAYED class not found

51
Decompiler.class.php

@ -736,6 +736,8 @@ class Decompiler
$EX['arg_types_stack'] = array();
$EX['last'] = count($opcodes) - 1;
$EX['silence'] = 0;
$EX['recvs'] = array();
$EX['uses'] = array();
for ($next = 0, $last = $EX['last'];
$loop = $this->outputCode($EX, $next, $last, $indent, true);
@ -1138,6 +1140,21 @@ class Decompiler
unset($dim);
break;
}
if (is_a($rvalue, 'Decompiler_Fetch')) {
$src = str($rvalue->src, $EX);
if ('$' . unquoteName($src) == $lvalue) {
switch ($rvalue->fetchType) {
case ZEND_FETCH_STATIC:
$statics = &$EX['op_array']['static_variables'];
if ((xcache_get_type($statics[$name]) & IS_LEXICAL_VAR)) {
$EX['uses'][] = str($lvalue);
unset($statics);
break 2;
}
unset($statics);
}
}
}
$resvar = "$lvalue = " . str($rvalue, $EX);
break;
// }}}
@ -1154,6 +1171,12 @@ class Decompiler
break 2;
case ZEND_FETCH_STATIC:
$statics = &$EX['op_array']['static_variables'];
if ((xcache_get_type($statics[$name]) & IS_LEXICAL_REF)) {
$EX['uses'][] = '&' . str($lvalue);
unset($statics);
break 2;
}
$resvar = 'static ' . $lvalue;
$name = unquoteName($src);
if (isset($statics[$name])) {
@ -1202,6 +1225,10 @@ class Decompiler
case XC_ISSET_ISEMPTY_VAR: // {{{
if ($opc == XC_ISSET_ISEMPTY_VAR) {
$rvalue = $this->getOpVal($op1, $EX);
// for < PHP_5_3
if ($op1['op_type'] == XC_IS_CONST) {
$rvalue = '$' . unquoteVariableName($this->getOpVal($op1, $EX));
}
if ($op2['EA.type'] == ZEND_FETCH_STATIC_MEMBER) {
$class = $this->getOpVal($op2, $EX);
$rvalue = $class . '::' . $rvalue;
@ -1226,10 +1253,10 @@ class Decompiler
switch ((!ZEND_ENGINE_2 ? $op['op2']['var'] /* constant */ : $ext) & (ZEND_ISSET|ZEND_ISEMPTY)) {
case ZEND_ISSET:
$rvalue = "isset($rvalue)";
$rvalue = "isset(" . str($rvalue) . ")";
break;
case ZEND_ISEMPTY:
$rvalue = "empty($rvalue)";
$rvalue = "empty(" . str($rvalue) . ")";
break;
}
$resvar = $rvalue;
@ -1837,6 +1864,13 @@ class Decompiler
}
}
// }}}
function duses(&$EX, $indent) // {{{
{
if ($EX['uses']) {
echo ' use(', implode(', ', $EX['uses']), ')';
}
}
// }}}
function dfunction($func, $indent = '', $nobody = false) // {{{
{
$this->detectNamespace($func['op_array']['function_name']);
@ -1845,24 +1879,23 @@ class Decompiler
$EX = array();
$EX['op_array'] = &$func['op_array'];
$EX['recvs'] = array();
$EX['uses'] = array();
}
else {
ob_start();
$newindent = INDENT . $indent;
$EX = &$this->dop_array($func['op_array'], $newindent);
$body = ob_get_clean();
if (!isset($EX['recvs'])) {
$EX['recvs'] = array();
}
}
$functionName = $this->stripNamespace($func['op_array']['function_name']);
if ($functionName == '{closure}') {
$functionName = '';
}
echo 'function ', $functionName, '(';
echo 'function', $functionName ? ' ' . $functionName : '', '(';
$this->dargs($EX, $indent);
echo ")";
$this->duses($EX, $indent);
if ($nobody) {
echo ";\n";
}
@ -2230,6 +2263,12 @@ define('IS_STRING', ZEND_ENGINE_2 ? 6 : 3);
define('IS_RESOURCE', 7);
define('IS_CONSTANT', 8);
define('IS_CONSTANT_ARRAY', 9);
/* Ugly hack to support constants as static array indices */
define('IS_CONSTANT_TYPE_MASK', 0x0f);
define('IS_CONSTANT_UNQUALIFIED', 0x10);
define('IS_CONSTANT_INDEX', 0x80);
define('IS_LEXICAL_VAR', 0x20);
define('IS_LEXICAL_REF', 0x40);
@define('XC_IS_CV', 16);

1
NEWS

@ -1,5 +1,6 @@
1.3.2 2011-??-??
========
* admin page security fix
* adds 30 seconds timeout to "compiling" flag
* improves decompiling
* memory leak on recompile

20
admin/common.php

@ -1,5 +1,10 @@
<?php
function xcache_validateFileName($name)
{
return preg_match('!^[a-zA-Z0-9._-]+$!', $name);
}
function get_language_file_ex($name, $l, $s)
{
static $lmap = array(
@ -15,16 +20,19 @@ function get_language_file_ex($name, $l, $s)
if (isset($lmap[$l])) {
$l = $lmap[$l];
}
if (file_exists($file = "$name-$l-$s.lang.php")) {
$file = "$name-$l-$s.lang.php";
if (xcache_validateFileName($file) && file_exists($file)) {
return $file;
}
if (isset($smap[$s])) {
$s = $smap[$s];
if (file_exists($file = "$name-$l-$s.lang.php")) {
$file = "$name-$l-$s.lang.php";
if (xcache_validateFileName($file) && file_exists($file)) {
return $file;
}
}
if (file_exists($file = "$name-$l.lang.php")) {
$file = "$name-$l.lang.php";
if (xcache_validateFileName($file) && file_exists($file)) {
return $file;
}
return null;
@ -38,20 +46,20 @@ function get_language_file($name)
$l = strtolower($lang);
$file = get_language_file_ex($name, $l, $s);
if (!isset($file)) {
$l = strtok($l, '-');
$l = strtok($l, ':-');
$file = get_language_file_ex($name, $l, $s);
}
}
else if (!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
foreach (explode(',', str_replace(' ', '', $_SERVER['HTTP_ACCEPT_LANGUAGE'])) as $l) {
$l = strtok($l, ';');
$l = strtok($l, ':;');
$file = get_language_file_ex($name, $l, $s);
if (isset($file)) {
$lang = $l;
break;
}
if (strpos($l, '-') !== false) {
$ll = strtok($l, '-');
$ll = strtok($l, ':-');
$file = get_language_file_ex($name, $ll, $s);
if (isset($file)) {
$lang = $l;

7
decompilesample.php

@ -359,9 +359,12 @@ $greet('World');
$greet('PHP');
$total = 0;
$tax = 1;
$callback = function ($quantity, $product) use ($tax, &$total) {
static $static = array(1);
$callback = function($quantity, $product) use($tax, &$total) {
$tax = 'tax';
static $static1 = array(1);
static $static2;
$tax = 'tax';
$tax = --$tax;
$pricePerItem = constant('PRICE_' . strtoupper($product));
$total += $pricePerItem * $quantity * ($tax + 1);
};

4
opcode_spec_def.h

@ -146,7 +146,9 @@ static const xc_opcode_spec_t xc_opcode_spec[] = {
OPSPEC( UNUSED, VAR, STD, VAR) /* 96 FETCH_DIM_UNSET */
OPSPEC( UNUSED, VAR_2, STD, VAR) /* 97 FETCH_OBJ_UNSET */
OPSPEC( UNUSED, STD, STD, VAR) /* 98 FETCH_DIM_TMP_VAR */
#ifdef ZEND_ENGINE_2
#ifdef ZEND_ENGINE_2_3
OPSPEC( UNUSED, VAR_2, STD, TMP) /* 99 FETCH_CONSTANT */
#elif defined(ZEND_ENGINE_2)
OPSPEC( UNUSED, UCLASS, STD, TMP) /* 99 FETCH_CONSTANT */
#else
OPSPEC( UNUSED, STD, UNUSED, TMP) /* 99 FETCH_CONSTANT */

6
utils.c

@ -244,12 +244,6 @@ static void xc_fix_opcode_ex_znode(int tofix, xc_op_spec_t spec, Z_OP_TYPEOF_TYP
case IS_TMP_VAR:
break;
case IS_CONST:
if (spec == OPSPEC_UCLASS) {
break;
}
/* fall */
default:
/* TODO: data lost, find a way to keep it */
/* assert(*op_type == IS_CONST); */

47
xcache.c

@ -2279,6 +2279,34 @@ PHP_FUNCTION(xcache_dec)
xc_var_inc_dec(-1, INTERNAL_FUNCTION_PARAM_PASSTHRU);
}
/* }}} */
/* {{{ proto int xcache_get_refcount(mixed variable)
XCache internal uses only: Get reference count of variable */
PHP_FUNCTION(xcache_get_refcount)
{
zval *variable;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &variable) == FAILURE) {
RETURN_NULL();
}
RETURN_LONG(Z_REFCOUNT_P(variable));
}
/* }}} */
/* {{{ proto bool xcache_get_isref(mixed variable)
XCache internal uses only: Check if variable data is marked referenced */
ZEND_BEGIN_ARG_INFO_EX(arginfo_xcache_get_isref, 0, 0, 1)
ZEND_ARG_INFO(1, variable)
ZEND_END_ARG_INFO()
PHP_FUNCTION(xcache_get_isref)
{
zval *variable;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &variable) == FAILURE) {
RETURN_NULL();
}
RETURN_BOOL(Z_ISREF_P(variable) && Z_REFCOUNT_P(variable) >= 3);
}
/* }}} */
#ifdef HAVE_XCACHE_DPRINT
/* {{{ proto bool xcache_dprint(mixed value)
Prints variable (or value) internal struct (debug only) */
@ -2427,7 +2455,8 @@ PHP_FUNCTION(xcache_get_opcode_spec)
}
/* }}} */
#endif
/* {{{ proto mixed xcache_get_special_value(zval value) */
/* {{{ proto mixed xcache_get_special_value(zval value)
XCache internal use only: For decompiler to get static value with type fixed */
PHP_FUNCTION(xcache_get_special_value)
{
zval *value;
@ -2454,6 +2483,19 @@ PHP_FUNCTION(xcache_get_special_value)
}
}
/* }}} */
/* {{{ proto int xcache_get_type(zval value)
XCache internal use only for disassembler to get variable type in engine level */
PHP_FUNCTION(xcache_get_type)
{
zval *value;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == FAILURE) {
return;
}
RETURN_LONG(Z_TYPE_P(value));
}
/* }}} */
/* {{{ proto string xcache_coredump(int op_type) */
PHP_FUNCTION(xcache_coredump)
{
@ -2506,6 +2548,7 @@ static zend_function_entry xcache_functions[] = /* {{{ */
PHP_FE(xcache_coverager_get, NULL)
#endif
PHP_FE(xcache_get_special_value, NULL)
PHP_FE(xcache_get_type, NULL)
PHP_FE(xcache_get_op_type, NULL)
PHP_FE(xcache_get_data_type, NULL)
PHP_FE(xcache_get_opcode, NULL)
@ -2520,6 +2563,8 @@ static zend_function_entry xcache_functions[] = /* {{{ */
PHP_FE(xcache_isset, NULL)
PHP_FE(xcache_unset, NULL)
PHP_FE(xcache_unset_by_prefix, NULL)
PHP_FE(xcache_get_refcount, NULL)
PHP_FE(xcache_get_isref, arginfo_xcache_get_isref)
#ifdef HAVE_XCACHE_DPRINT
PHP_FE(xcache_dprint, NULL)
#endif

Loading…
Cancel
Save