]> granicus.if.org Git - php/commitdiff
- MFH: Fixed bug #48562 (Reference recursion causes segfault when used in wddx_serial...
authorFelipe Pena <felipe@php.net>
Tue, 16 Jun 2009 02:59:10 +0000 (02:59 +0000)
committerFelipe Pena <felipe@php.net>
Tue, 16 Jun 2009 02:59:10 +0000 (02:59 +0000)
NEWS
ext/wddx/tests/bug48562.phpt [new file with mode: 0644]
ext/wddx/wddx.c

diff --git a/NEWS b/NEWS
index 37f9369feb8b2341e66fa784fea104da4158ff65..f27f0f69eec91f549b5fa35df0e3ad6f59924c3c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,8 @@
 PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? Jun 2009, PHP 5.2.10
+- Fixed bug #48562 (Reference recursion causes segfault when used in 
+  wddx_serialize_vars()). (Felipe)
 - Fixed bug #48557 (Numeric string keys in Apache Hashmaps are not cast to
   integers). (David Zuelke)
 - Fixed bug #48514 (cURL extension uses same resource name for simple and
diff --git a/ext/wddx/tests/bug48562.phpt b/ext/wddx/tests/bug48562.phpt
new file mode 100644 (file)
index 0000000..d9ae376
--- /dev/null
@@ -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>"
index eb58aa57e5570be0b36455f2b61053248b65e57e..572f5a3975230d7c64fc89b14f0d78fb257656ee 100644 (file)
@@ -672,13 +672,27 @@ static void php_wddx_add_var(wddx_packet *packet, zval *name_var)
        }
        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);
                }
        }