diff options
author | Felipe Pena <felipe@php.net> | 2009-06-16 02:53:50 +0000 |
---|---|---|
committer | Felipe Pena <felipe@php.net> | 2009-06-16 02:53:50 +0000 |
commit | edb136aed30fd9efcafd61108fdfae94df83960d (patch) | |
tree | ae94a5e9327e2fb0f8807fb5b9df5d8cd90f2341 | |
parent | 1f6a21a72f6fcd5efc0426e660e95a909ae97696 (diff) | |
download | php-git-edb136aed30fd9efcafd61108fdfae94df83960d.tar.gz |
- Fixed bug #48562 (Reference recursion causes segfault when used in wddx_serialize_vars())
-rw-r--r-- | ext/wddx/tests/bug48562.phpt | 22 | ||||
-rw-r--r-- | ext/wddx/wddx.c | 16 |
2 files changed, 37 insertions, 1 deletions
diff --git a/ext/wddx/tests/bug48562.phpt b/ext/wddx/tests/bug48562.phpt new file mode 100644 index 0000000000..d9ae376c56 --- /dev/null +++ b/ext/wddx/tests/bug48562.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #48562 (Reference recursion causes segfault when used in wddx_serialize_vars()) +--FILE-- +<?php + +$foo = 'bar'; + +$a['x'] = 'foo'; +$a['x'] = &$a; + +var_dump(wddx_serialize_vars($a)); + +$a['x'] = 'foo'; +$a['x'] = $a; + +var_dump(wddx_serialize_vars($a)); + +?> +--EXPECTF-- +Warning: wddx_serialize_vars(): recursion detected in %s on line %d +string(78) "<wddxPacket version='1.0'><header/><data><struct></struct></data></wddxPacket>" +string(120) "<wddxPacket version='1.0'><header/><data><struct><var name='foo'><string>bar</string></var></struct></data></wddxPacket>" diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c index 4c4d6ff4bf..10edb9da06 100644 --- a/ext/wddx/wddx.c +++ b/ext/wddx/wddx.c @@ -700,13 +700,27 @@ static void php_wddx_add_var(wddx_packet *packet, zval *name_var) php_wddx_serialize_var(packet, *val, Z_STRVAL_P(name_var), Z_STRLEN_P(name_var) TSRMLS_CC); } } else if (Z_TYPE_P(name_var) == IS_ARRAY || Z_TYPE_P(name_var) == IS_OBJECT) { + int is_array = Z_TYPE_P(name_var) == IS_ARRAY; + target_hash = HASH_OF(name_var); + if (is_array && target_hash->nApplyCount > 1) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected"); + return; + } + zend_hash_internal_pointer_reset(target_hash); while(zend_hash_get_current_data(target_hash, (void**)&val) == SUCCESS) { + if (is_array) { + target_hash->nApplyCount++; + } + php_wddx_add_var(packet, *val); - + + if (is_array) { + target_hash->nApplyCount--; + } zend_hash_move_forward(target_hash); } } |