Browse Source

fix some xcache_get leak by refcount

git-svn-id: svn://svn.lighttpd.net/xcache/trunk@1576 c26eb9a1-5813-0410-bd6c-c2e55f420ca7
master
Xuefer 6 years ago
parent
commit
f843d679ae
7 changed files with 239 additions and 10 deletions
  1. +3
    -3
      processor/foot.m4
  2. +7
    -5
      processor/processor.m4
  3. +4
    -1
      tests/xcache_var_object.phpt
  4. +101
    -0
      tests/xcache_var_object_5.1.phpt
  5. +4
    -1
      tests/xcache_var_reference.phpt
  6. +60
    -0
      tests/xcache_var_reference_4.phpt
  7. +60
    -0
      tests/xcache_var_reference_5.1.phpt

+ 3
- 3
processor/foot.m4 View File

@@ -124,9 +124,6 @@ EXPORTED_FUNCTION(`void xc_processor_restore_var(zval *dst, zval **dst_ptr, cons

if (processor.handle_reference) {
zend_hash_init(&processor.zvalptrs, 0, NULL, NULL, 0);
if (dst_ptr) {
zval_ptr_dtor(dst_ptr);
}
}
processor.index_to_ce = index_to_ce;

@@ -144,11 +141,14 @@ EXPORTED_FUNCTION(`void xc_processor_restore_var(zval *dst, zval **dst_ptr, cons
}
}
#endif
zval_ptr_dtor(&dst);
if (dst_ptr) {
xc_restore_zval_ptr(&processor, dst_ptr, &src->value TSRMLS_CC);
Z_ADDREF(**dst_ptr);
}
else {
xc_restore_zval(&processor, dst, src->value TSRMLS_CC);
Z_ADDREF(*dst);
}
if (processor.handle_reference) {
zend_hash_destroy(&processor.zvalptrs);


+ 7
- 5
processor/processor.m4 View File

@@ -306,7 +306,6 @@ DEF_STRUCT_P_FUNC(`zval_ptr', , `dnl {{{
RELOCATE_EX(zval, pzv)
')
if (zend_hash_add(&processor->zvalptrs, (char *) &SRC()[0], sizeof(SRC()[0]), (void *) &pzv, sizeof(pzv), NULL) == SUCCESS) { /* first add, go on */
IFSTORE(`Z_SET_REFCOUNT(**DST(), 1);')
dnl IFSTORE(`fprintf(stderr, "mark[%p] = %p\n", (void *) SRC()[0], (void *) pzv);')
}
else {
@@ -319,6 +318,8 @@ DEF_STRUCT_P_FUNC(`zval_ptr', , `dnl {{{
')
IFDPRINT(`INDENT()`'fprintf(stderr, "[%p] ", (void *) SRC()[0]);')
STRUCT_P_EX(zval, DST()[0], SRC()[0], `[0]', `', ` ')
dnl don't set refcount in zval processor
IFSTORE(`Z_SET_REFCOUNT(**DST(), 1);')
RELOCATE_EX(zval, DST()[0])
} while (0);
')
@@ -1418,21 +1419,23 @@ DEF_STRUCT_P_FUNC(`xc_entry_var_t', , `dnl {{{

IFDPRINT(`INDENT()`'fprintf(stderr, "zval:value");')
STRUCT_P_EX(zval_ptr, DST(`value'), SRC(`value'), `value', `', `&')
DONE(value)
#if 0
IFSTORE(`
{
HashTable *ht;
zval **zv;

assert(Z_TYPE_P(SRC(`value')) == IS_ARRAY);
ht = Z_ARRVAL_P(SRC(`value'));
assert(Z_TYPE_P(DST(`value')) == IS_ARRAY);
ht = Z_ARRVAL_P(DST(`value'));
assert(ht->nNumOfElements == 1);
fprintf(stderr, "key %s\n", ht->pListHead->arKey);

zv = (zval **) ht->pListHead->pData;
fprintf(stderr, "%d\n", Z_TYPE_PP(zv));
assert(Z_TYPE_PP(zv) == IS_ARRAY);
assert(Z_ARRVAL_PP(zv) == ht);
fprintf(stderr, "refcount=%d\n", Z_REFCOUNT(*DST(`value')));
fprintf(stderr, "refcount=%d\n", Z_REFCOUNT(**zv));
}
')
#endif
@@ -1482,7 +1485,6 @@ DEF_STRUCT_P_FUNC(`xc_entry_var_t', , `dnl {{{
')

PROCESS(zend_bool, have_references)
DONE(value)
')
dnl }}}
dnl ====================================================

+ 4
- 1
tests/xcache_var_object.phpt View File

@@ -1,8 +1,11 @@
--TEST--
xcache_set/get test for object
xcache_set/get test for object PHP 5.2+
--SKIPIF--
<?php
require("skipif.inc");
if (!version_compare(phpversion(), '5.2', '>=')) {
echo 'skip for PHP 5.2+ only';
}
?>
--INI--
xcache.test = 1


+ 101
- 0
tests/xcache_var_object_5.1.phpt View File

@@ -0,0 +1,101 @@
--TEST--
xcache_set/get test for object 5.1-
--SKIPIF--
<?php
require("skipif.inc");
if (!version_compare(phpversion(), '5.2', '<')) {
echo 'skip for PHP 5.1- only';
}
?>
--INI--
xcache.test = 1
xcache.size = 32M
xcache.var_size = 2M
--FILE--
<?php
class a
{
}

class b
{
}

$a = new a();
$b = new b();
$stdclass = new stdclass();

$b->a = $a;
$b->b = $b;
$b->array = array($b, $a);
$b->stdclass = $stdclass;

var_dump(xcache_set("a", $a));
unset($a);
var_dump($a = xcache_get("a"));

var_dump(xcache_set("b", $b));
unset($b);
var_dump($b = xcache_get("b"));

$b->test = 1;
var_dump($b->b->test);
?>
--EXPECT--
bool(true)
object(a)#4 (0) {
}
bool(true)
object(b)#7 (4) {
["a"]=>
object(a)#6 (0) {
}
["b"]=>
object(b)#7 (4) {
["a"]=>
object(a)#6 (0) {
}
["b"]=>
*RECURSION*
["array"]=>
array(2) {
[0]=>
*RECURSION*
[1]=>
object(a)#6 (0) {
}
}
["stdclass"]=>
object(stdClass)#5 (0) {
}
}
["array"]=>
array(2) {
[0]=>
object(b)#7 (4) {
["a"]=>
object(a)#6 (0) {
}
["b"]=>
*RECURSION*
["array"]=>
array(2) {
[0]=>
*RECURSION*
[1]=>
object(a)#6 (0) {
}
}
["stdclass"]=>
object(stdClass)#5 (0) {
}
}
[1]=>
object(a)#6 (0) {
}
}
["stdclass"]=>
object(stdClass)#5 (0) {
}
}
int(1)

+ 4
- 1
tests/xcache_var_reference.phpt View File

@@ -1,8 +1,11 @@
--TEST--
xcache_set/get test for reference
xcache_set/get test for reference for PHP 5.2+
--SKIPIF--
<?php
require("skipif.inc");
if (!version_compare(phpversion(), '5.2', '>=')) {
echo 'skip for PHP 5.2+ only';
}
?>
--INI--
xcache.test = 1


+ 60
- 0
tests/xcache_var_reference_4.phpt View File

@@ -0,0 +1,60 @@
--TEST--
xcache_set/get test for reference for PHP 4
--SKIPIF--
<?php
require("skipif.inc");
if (!(version_compare(phpversion(), '5.0', '<'))) {
echo 'skip for PHP 4 only';
}
?>
--INI--
xcache.test = 1
xcache.size = 32M
xcache.var_size = 2M
--FILE--
<?php
$ref = array();
$ref['ref'] = &$ref;
$ref['array'] = array(&$ref);
var_dump(xcache_set("ref", $ref));

unset($ref);
$ref = xcache_get("ref");
var_dump(array(&$ref));

$ref['test'] = 1;
var_dump($ref['ref']['test']);
var_dump($ref['array'][0]['test']);
?>
--EXPECT--
bool(true)
array(1) {
[0]=>
&array(2) {
["ref"]=>
&array(2) {
["ref"]=>
*RECURSION*
["array"]=>
array(1) {
[0]=>
*RECURSION*
}
}
["array"]=>
array(1) {
[0]=>
&array(2) {
["ref"]=>
*RECURSION*
["array"]=>
array(1) {
[0]=>
*RECURSION*
}
}
}
}
}
int(1)
int(1)

+ 60
- 0
tests/xcache_var_reference_5.1.phpt View File

@@ -0,0 +1,60 @@
--TEST--
xcache_set/get test for reference for PHP 5.{0,1}
--SKIPIF--
<?php
require("skipif.inc");
if (!(version_compare(phpversion(), '5.0', '>=') && version_compare(phpversion(), '5.2', '<'))) {
echo 'skip for PHP 5.{0,1} only';
}
?>
--INI--
xcache.test = 1
xcache.size = 32M
xcache.var_size = 2M
--FILE--
<?php
$ref = array();
$ref['ref'] = &$ref;
$ref['array'] = array(&$ref);
var_dump(xcache_set_ref("ref", $ref));

unset($ref);
$ref = &xcache_get_ref("ref");
var_dump(array(&$ref));

$ref['test'] = 1;
var_dump($ref['ref']['test']);
var_dump($ref['array'][0]['test']);
?>
--EXPECT--
bool(true)
array(1) {
[0]=>
&array(2) {
["ref"]=>
&array(2) {
["ref"]=>
*RECURSION*
["array"]=>
array(1) {
[0]=>
*RECURSION*
}
}
["array"]=>
array(1) {
[0]=>
&array(2) {
["ref"]=>
*RECURSION*
["array"]=>
array(1) {
[0]=>
*RECURSION*
}
}
}
}
}
int(1)
int(1)

Loading…
Cancel
Save