summaryrefslogtreecommitdiff
path: root/ext/wddx
diff options
context:
space:
mode:
authorFelipe Pena <felipe@php.net>2009-06-16 02:54:26 (GMT)
committerFelipe Pena <felipe@php.net>2009-06-16 02:54:26 (GMT)
commitc353601a3f99b2bc072fa967e9ae79b4cd69bb05 (patch)
tree895f6876baf5f2410c355b224c80574a40e60f65 /ext/wddx
parent8e76db4aa7d20a264dda0e1de5e35cdacc4fba08 (diff)
downloadphp-c353601a3f99b2bc072fa967e9ae79b4cd69bb05.tar.gz
- MFH: Fixed bug #48562 (Reference recursion causes segfault when used in wddx_serialize_vars())
Diffstat (limited to 'ext/wddx')
-rw-r--r--ext/wddx/tests/bug48562.phpt22
-rw-r--r--ext/wddx/wddx.c16
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 0000000..d9ae376
--- /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 e1139f8..cd7e01a 100644
--- a/ext/wddx/wddx.c
+++ b/ext/wddx/wddx.c
@@ -704,13 +704,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);
}
}