pre-approval of new upload of php5:(was: [RFC] Gentoo patches)
Hi all,
[RT, skip this:]
There are a couple of issues in php5 that need to be fixed soonish, so
it would be great if others could comment on whether I should commit
the changes/patches or not (targeted at lenny).
RT:
Would you accept the attached .diff for lenny's php5?
I'm aware of pcre's shlibs bump and the need of a t-p-u to get the
bugs fixed (the DFSG-freeness one, a security issue, and a couple of
other minor bugs); but it would be great if the only two differences
between the versions in lenny and sid are a changelog entry and the
dependencies of the built binaries.
---------- Forwarded message ----------
From: Raphael Geissert <atomo64@gmail.com>
Date: 2008/11/17
Subject: [RFC] Gentoo patches
To: pkg-php-maint@lists.alioth.debian.org
Hi all,
I've been taking a look at the patches applied to php5 at Gentoo and picked up
some of which I consider relevant for lenny.
Attached is my current svn diff from pkg-php/php5/trunk/debian.
Comments?
I would really like to see the majority of them in lenny (the xmlrpc one looks
quite large, but if you ignore the white space changes you will see it is
not).
Cheers,
--
Raphael Geissert - Debian Maintainer
www.debian.org - get.debian.net
Bob Dole - "The internet is a great way to get on the net."
Index: patches/series
===================================================================
--- patches/series (revision 1170)
+++ patches/series (working copy)
@@ -33,8 +33,17 @@
CVE-2008-2829.patch
libedit_is_editline.patch
bad_whatis_entries.patch
-deprecated_freetds_check.patch
+gentoo/freetds-compat.patch
snmp_leaks.patch
CVE-2008-3658.patch
CVE-2008-3659.patch
CVE-2008-3660.patch
+gentoo/010_ticks-zts-crashes.patch
+gentoo/019_new-memory-corruption.patch
+gentoo/014_explode-overflow.patch
+gentoo/009_array-function-crashes.patch
+gentoo/015_CVE-2008-2665-wrapper-safemode-bypass.patch
+gentoo/017_xmlrpc-invalid-callback-crash.patch
+gentoo/007_dom-setAttributeNode-crash.patch
+gentoo/006_PDORow-crash.patch
+gentoo/005_stream_context_set_params-crash.patch
Index: patches/gentoo/010_ticks-zts-crashes.patch
===================================================================
--- patches/gentoo/010_ticks-zts-crashes.patch (revision 0)
+++ patches/gentoo/010_ticks-zts-crashes.patch (revision 0)
@@ -0,0 +1,68 @@
+Fixed bug #45352 (Segmentation fault because of tick function on second request)
+http://cvs.php.net/viewvc.cgi/php-src/main/main.c?r1=1.640.2.23.2.62&r2=1.640.2.23.2.63&diff_format=u
+http://cvs.php.net/viewvc.cgi/php-src/main/php_ticks.c?r1=1.20.2.1.2.2&r2=1.20.2.1.2.3&diff_format=u
+http://cvs.php.net/viewvc.cgi/php-src/main/php_ticks.h?r1=1.14.2.1.2.2&r2=1.14.2.1.2.3&diff_format=u
+
+diff -r 1cc016a9e5d9 main/main.c
+--- a/main/main.c Thu Jun 19 18:29:09 2008 +0200
++++ b/main/main.c Tue Jul 01 19:17:54 2008 +0200
+@@ -18,7 +18,7 @@
+ +----------------------------------------------------------------------+
+ */
+
+-/* $Id: main.c,v 1.640.2.23.2.62 2008/03/05 20:58:08 pajoye Exp $ */
++/* $Id: main.c,v 1.640.2.23.2.63 2008/06/25 12:18:21 dmitry Exp $ */
+
+ /* {{{ includes
+ */
+@@ -1435,6 +1435,8 @@
+ EG(opline_ptr) = NULL;
+ EG(active_op_array) = NULL;
+
++ php_deactivate_ticks(TSRMLS_C);
++
+ /* 1. Call all possible shutdown functions registered with register_shutdown_function() */
+ if (PG(modules_activated)) zend_try {
+ php_call_shutdown_functions(TSRMLS_C);
+diff -r 1cc016a9e5d9 main/php_ticks.c
+--- a/main/php_ticks.c Thu Jun 19 18:29:09 2008 +0200
++++ b/main/php_ticks.c Tue Jul 01 19:17:54 2008 +0200
+@@ -16,7 +16,7 @@
+ +----------------------------------------------------------------------+
+ */
+
+-/* $Id: php_ticks.c,v 1.20.2.1.2.2 2007/12/31 07:20:15 sebastian Exp $ */
++/* $Id: php_ticks.c,v 1.20.2.1.2.3 2008/06/25 12:18:22 dmitry Exp $ */
+
+ #include "php.h"
+ #include "php_ticks.h"
+@@ -25,6 +25,11 @@
+ {
+ zend_llist_init(&PG(tick_functions), sizeof(void(*)(int)), NULL, 1);
+ return SUCCESS;
++}
++
++void php_deactivate_ticks(TSRMLS_D)
++{
++ zend_llist_clean(&PG(tick_functions));
+ }
+
+ void php_shutdown_ticks(TSRMLS_D)
+diff -r 1cc016a9e5d9 main/php_ticks.h
+--- a/main/php_ticks.h Thu Jun 19 18:29:09 2008 +0200
++++ b/main/php_ticks.h Tue Jul 01 19:17:54 2008 +0200
+@@ -16,12 +16,13 @@
+ +----------------------------------------------------------------------+
+ */
+
+-/* $Id: php_ticks.h,v 1.14.2.1.2.2 2007/12/31 07:20:15 sebastian Exp $ */
++/* $Id: php_ticks.h,v 1.14.2.1.2.3 2008/06/25 12:18:22 dmitry Exp $ */
+
+ #ifndef PHP_TICKS_H
+ #define PHP_TICKS_H
+
+ int php_startup_ticks(TSRMLS_D);
++void php_deactivate_ticks(TSRMLS_D);
+ void php_shutdown_ticks(TSRMLS_D);
+ void php_run_ticks(int count);
+
Index: patches/gentoo/014_explode-overflow.patch
===================================================================
--- patches/gentoo/014_explode-overflow.patch (revision 0)
+++ patches/gentoo/014_explode-overflow.patch (revision 0)
@@ -0,0 +1,46 @@
+Fix for an overflow issue in explode() (internal function: memnstr)
+Patch by Laurent Gaffie, accepted by upstream
+http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/strings/explode_bug.phpt?revision
+http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_operators.h?r1=1.94.2.4.2.11&r2=1.94.2.4.2.12&diff_format=u
+
+diff -r df1c020e171c -r 114012db1b3f Zend/zend_operators.h
+--- a/Zend/zend_operators.h Sat Jul 19 16:10:06 2008 +0200
++++ b/Zend/zend_operators.h Wed Aug 06 17:14:57 2008 +0200
+@@ -17,7 +17,7 @@
+ +----------------------------------------------------------------------+
+ */
+
+-/* $Id: zend_operators.h,v 1.94.2.4.2.11 2007/12/31 07:20:03 sebastian Exp $ */
++/* $Id: zend_operators.h,v 1.94.2.4.2.12 2008/08/05 20:11:17 stas Exp $ */
+
+ #ifndef ZEND_OPERATORS_H
+ #define ZEND_OPERATORS_H
+@@ -220,6 +220,9 @@
+ char *p = haystack;
+ char ne = needle[needle_len-1];
+
++ if(needle_len > end-haystack) {
++ return NULL;
++ }
+ end -= needle_len;
+
+ while (p <= end) {
+diff -r df1c020e171c -r 114012db1b3f ext/standard/tests/strings/explode_bug.phpt
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ b/ext/standard/tests/strings/explode_bug.phpt Wed Aug 06 17:14:57 2008 +0200
+@@ -0,0 +1,15 @@
++--TEST--
++Explode/memnstr bug
++--INI--
++error_reporting=2047
++memory_limit=256M
++--FILE--
++<?php
++$res = explode(str_repeat("A",145999999),1);
++var_dump($res);
++?>
++--EXPECTF--
++array(1) {
++ [0]=>
++ string(1) "1"
++}
Index: patches/gentoo/007_dom-setAttributeNode-crash.patch
===================================================================
--- patches/gentoo/007_dom-setAttributeNode-crash.patch (revision 0)
+++ patches/gentoo/007_dom-setAttributeNode-crash.patch (revision 0)
@@ -0,0 +1,37 @@
+fixed bug #45251 (double free or corruption with setAttributeNode())
+http://cvs.php.net/viewvc.cgi/php-src/ext/dom/element.c?r1=1.36.2.4.2.10&r2=1.36.2.4.2.11&diff_format=u
+
+diff -r 8101f188933b ext/dom/element.c
+--- a/ext/dom/element.c Wed Jun 18 19:02:33 2008 +0200
++++ b/ext/dom/element.c Wed Jun 18 19:12:21 2008 +0200
+@@ -17,7 +17,7 @@
+ +----------------------------------------------------------------------+
+ */
+
+-/* $Id: element.c,v 1.36.2.4.2.10 2008/02/04 15:23:11 sebastian Exp $ */
++/* $Id: element.c,v 1.36.2.4.2.11 2008/06/14 11:24:00 rrichards Exp $ */
+
+ #ifdef HAVE_CONFIG_H
+ #include "config.h"
+@@ -585,6 +585,10 @@
+ xmlUnlinkNode((xmlNodePtr) existattrp);
+ }
+
++ if (attrp->parent != NULL) {
++ xmlUnlinkNode((xmlNodePtr) attrp);
++ }
++
+ if (attrp->doc == NULL && nodep->doc != NULL) {
+ attrobj->document = intern->document;
+ php_libxml_increment_doc_ref((php_libxml_node_object *)attrobj, NULL TSRMLS_CC);
+@@ -998,6 +1002,10 @@
+ xmlUnlinkNode((xmlNodePtr) existattrp);
+ }
+
++ if (attrp->parent != NULL) {
++ xmlUnlinkNode((xmlNodePtr) attrp);
++ }
++
+ if (attrp->doc == NULL && nodep->doc != NULL) {
+ attrobj->document = intern->document;
+ php_libxml_increment_doc_ref((php_libxml_node_object *)attrobj, NULL TSRMLS_CC);
Index: patches/gentoo/015_CVE-2008-2665-wrapper-safemode-bypass.patch
===================================================================
--- patches/gentoo/015_CVE-2008-2665-wrapper-safemode-bypass.patch (revision 0)
+++ patches/gentoo/015_CVE-2008-2665-wrapper-safemode-bypass.patch (revision 0)
@@ -0,0 +1,40 @@
+Fix for CVE-2008-2665 and CVE-2008-2666 (stream wrapper safe_mode bypass)
+Patch by Christian Hoffmann, accepted by upstream
+http://cvs.php.net/viewvc.cgi/php-src/main/safe_mode.c?r1=1.62.2.1.2.15&r2=1.62.2.1.2.16&diff_format=u
+http://cvs.php.net/viewvc.cgi/php-src/main/safe_mode.c?r1=1.62.2.1.2.16&r2=1.62.2.1.2.17&diff_format=u
+
+diff -r 114012db1b3f main/safe_mode.c
+--- a/main/safe_mode.c Wed Aug 06 17:14:57 2008 +0200
++++ b/main/safe_mode.c Wed Aug 06 17:31:13 2008 +0200
+@@ -16,7 +16,7 @@
+ +----------------------------------------------------------------------+
+ */
+
+-/* $Id: safe_mode.c,v 1.62.2.1.2.15 2007/12/31 07:20:15 sebastian Exp $ */
++/* $Id: safe_mode.c,v 1.62.2.1.2.17 2008/07/24 16:01:59 felipe Exp $ */
+
+ #include "php.h"
+
+@@ -52,7 +52,6 @@
+ long uid=0L, gid=0L, duid=0L, dgid=0L;
+ char path[MAXPATHLEN];
+ char *s, filenamecopy[MAXPATHLEN];
+- php_stream_wrapper *wrapper = NULL;
+ TSRMLS_FETCH();
+
+ path[0] = '\0';
+@@ -73,14 +72,6 @@
+ mode = CHECKUID_CHECK_FILE_AND_DIR;
+ }
+ }
+-
+- /*
+- * If given filepath is a URL, allow - safe mode stuff
+- * related to URL's is checked in individual functions
+- */
+- wrapper = php_stream_locate_url_wrapper(filename, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC);
+- if (wrapper != NULL)
+- return 1;
+
+ /* First we see if the file is owned by the same user...
+ * If that fails, passthrough and check directory...
Index: patches/gentoo/017_xmlrpc-invalid-callback-crash.patch
===================================================================
--- patches/gentoo/017_xmlrpc-invalid-callback-crash.patch (revision 0)
+++ patches/gentoo/017_xmlrpc-invalid-callback-crash.patch (revision 0)
@@ -0,0 +1,1056 @@
+Segfault with invalid non-string as register_introspection_callback
+Patch by chris_se at gmx dot ne, accepted by upstream
+
+http://cvs.php.net/viewvc.cgi/php-src/ext/xmlrpc/xmlrpc-epi-php.c?r1=1.39.2.5.2.8&r2=1.39.2.5.2.9&diff_format=u
+http://cvs.php.net/viewvc.cgi/php-src/ext/xmlrpc/xmlrpc-epi-php.c?r1=1.39.2.5.2.9&r2=1.39.2.5.2.10&diff_format=u
+http://cvs.php.net/viewvc.cgi/php-src/ext/xmlrpc/tests/bug45555.phpt?revision=1.1.2.1&view=markup
+
+
+diff -r 93c02cfbcfb6 ext/xmlrpc/tests/bug45555.phpt
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ b/ext/xmlrpc/tests/bug45555.phpt Wed Aug 06 17:50:26 2008 +0200
+@@ -0,0 +1,20 @@
++--TEST--
++Bug #45555 (Segfault with invalid non-string as register_introspection_callback)
++--FILE--
++<?php
++
++$options = array ();
++$request = xmlrpc_encode_request ("system.describeMethods", $options);
++$server = xmlrpc_server_create ();
++
++xmlrpc_server_register_introspection_callback($server, 1);
++xmlrpc_server_register_introspection_callback($server, array('foo', 'bar'));
++
++$options = array ('output_type' => 'xml', 'version' => 'xmlrpc');
++xmlrpc_server_call_method ($server, $request, NULL, $options);
++
++?>
++--EXPECTF--
++Warning: xmlrpc_server_call_method(): Invalid callback '1' passed in %s on line %d
++
++Warning: xmlrpc_server_call_method(): Invalid callback 'foo::bar' passed in %s on line %d
+diff -r 93c02cfbcfb6 ext/xmlrpc/xmlrpc-epi-php.c
+--- a/ext/xmlrpc/xmlrpc-epi-php.c Wed Aug 06 17:47:19 2008 +0200
++++ b/ext/xmlrpc/xmlrpc-epi-php.c Wed Aug 06 17:50:26 2008 +0200
+@@ -51,7 +51,7 @@
+ +----------------------------------------------------------------------+
+ */
+
+-/* $Id: xmlrpc-epi-php.c,v 1.39.2.5.2.8 2007/12/31 07:20:14 sebastian Exp $ */
++/* $Id: xmlrpc-epi-php.c,v 1.39.2.5.2.10 2008/07/18 15:52:38 felipe Exp $ */
+
+ /**********************************************************************
+ * BUGS: *
+@@ -356,65 +356,61 @@
+ }
+ }
+
+- /* encoding code set */
+- if(zend_hash_find(Z_ARRVAL_P(output_opts),
+- ENCODING_KEY, ENCODING_KEY_LEN + 1,
+- (void**)&val) == SUCCESS) {
+- if(Z_TYPE_PP(val) == IS_STRING) {
+- options->xmlrpc_out.xml_elem_opts.encoding = estrdup(Z_STRVAL_PP(val));
+- }
+- }
++ /* encoding code set */
++ if(zend_hash_find(Z_ARRVAL_P(output_opts), ENCODING_KEY, ENCODING_KEY_LEN + 1, (void**)&val) == SUCCESS) {
++ if(Z_TYPE_PP(val) == IS_STRING) {
++ options->xmlrpc_out.xml_elem_opts.encoding = estrdup(Z_STRVAL_PP(val));
++ }
++ }
+
+- /* escaping options */
+- if(zend_hash_find(Z_ARRVAL_P(output_opts),
+- ESCAPING_KEY, ESCAPING_KEY_LEN + 1,
+- (void**)&val) == SUCCESS) {
+- /* multiple values allowed. check if array */
+- if(Z_TYPE_PP(val) == IS_ARRAY) {
+- zval** iter_val;
+- zend_hash_internal_pointer_reset(Z_ARRVAL_PP(val));
+- options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_no_escaping;
+- while(1) {
+- if(zend_hash_get_current_data(Z_ARRVAL_PP(val), (void**)&iter_val) == SUCCESS) {
+- if(Z_TYPE_PP(iter_val) == IS_STRING && Z_STRVAL_PP(iter_val)) {
+- if(!strcmp(Z_STRVAL_PP(iter_val), ESCAPING_VALUE_CDATA)) {
+- options->xmlrpc_out.xml_elem_opts.escaping |= xml_elem_cdata_escaping;
+- }
+- else if(!strcmp(Z_STRVAL_PP(iter_val), ESCAPING_VALUE_NON_ASCII)) {
+- options->xmlrpc_out.xml_elem_opts.escaping |= xml_elem_non_ascii_escaping;
+- }
+- else if(!strcmp(Z_STRVAL_PP(iter_val), ESCAPING_VALUE_NON_PRINT)) {
+- options->xmlrpc_out.xml_elem_opts.escaping |= xml_elem_non_print_escaping;
+- }
+- else if(!strcmp(Z_STRVAL_PP(iter_val), ESCAPING_VALUE_MARKUP)) {
+- options->xmlrpc_out.xml_elem_opts.escaping |= xml_elem_markup_escaping;
+- }
+- }
+- }
+- else {
+- break;
+- }
++ /* escaping options */
++ if (zend_hash_find(Z_ARRVAL_P(output_opts), ESCAPING_KEY, ESCAPING_KEY_LEN + 1, (void**)&val) == SUCCESS) {
++ /* multiple values allowed. check if array */
++ if (Z_TYPE_PP(val) == IS_ARRAY) {
++ zval** iter_val;
++ zend_hash_internal_pointer_reset(Z_ARRVAL_PP(val));
++ options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_no_escaping;
++ while(1) {
++ if(zend_hash_get_current_data(Z_ARRVAL_PP(val), (void**)&iter_val) == SUCCESS) {
++ if(Z_TYPE_PP(iter_val) == IS_STRING && Z_STRVAL_PP(iter_val)) {
++ if(!strcmp(Z_STRVAL_PP(iter_val), ESCAPING_VALUE_CDATA)) {
++ options->xmlrpc_out.xml_elem_opts.escaping |= xml_elem_cdata_escaping;
++ }
++ else if(!strcmp(Z_STRVAL_PP(iter_val), ESCAPING_VALUE_NON_ASCII)) {
++ options->xmlrpc_out.xml_elem_opts.escaping |= xml_elem_non_ascii_escaping;
++ }
++ else if(!strcmp(Z_STRVAL_PP(iter_val), ESCAPING_VALUE_NON_PRINT)) {
++ options->xmlrpc_out.xml_elem_opts.escaping |= xml_elem_non_print_escaping;
++ }
++ else if(!strcmp(Z_STRVAL_PP(iter_val), ESCAPING_VALUE_MARKUP)) {
++ options->xmlrpc_out.xml_elem_opts.escaping |= xml_elem_markup_escaping;
++ }
++ }
++ }
++ else {
++ break;
++ }
+
+- zend_hash_move_forward(Z_ARRVAL_PP(val));
+- }
+- }
+- /* else, check for single value */
+- else if(Z_TYPE_PP(val) == IS_STRING) {
+- if(!strcmp(Z_STRVAL_PP(val), ESCAPING_VALUE_CDATA)) {
+- options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_cdata_escaping;
+- }
+- else if(!strcmp(Z_STRVAL_PP(val), ESCAPING_VALUE_NON_ASCII)) {
+- options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_non_ascii_escaping;
+- }
+- else if(!strcmp(Z_STRVAL_PP(val), ESCAPING_VALUE_NON_PRINT)) {
+- options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_non_print_escaping;
+- }
+- else if(!strcmp(Z_STRVAL_PP(val), ESCAPING_VALUE_MARKUP)) {
+- options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_markup_escaping;
+- }
+- }
+- }
+- }
++ zend_hash_move_forward(Z_ARRVAL_PP(val));
++ }
++ }
++ /* else, check for single value */
++ else if(Z_TYPE_PP(val) == IS_STRING) {
++ if(!strcmp(Z_STRVAL_PP(val), ESCAPING_VALUE_CDATA)) {
++ options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_cdata_escaping;
++ }
++ else if(!strcmp(Z_STRVAL_PP(val), ESCAPING_VALUE_NON_ASCII)) {
++ options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_non_ascii_escaping;
++ }
++ else if(!strcmp(Z_STRVAL_PP(val), ESCAPING_VALUE_NON_PRINT)) {
++ options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_non_print_escaping;
++ }
++ else if(!strcmp(Z_STRVAL_PP(val), ESCAPING_VALUE_MARKUP)) {
++ options->xmlrpc_out.xml_elem_opts.escaping = xml_elem_markup_escaping;
++ }
++ }
++ }
++ }
+ }
+ }
+
+@@ -430,199 +426,196 @@
+ */
+ static XMLRPC_VECTOR_TYPE determine_vector_type (HashTable *ht)
+ {
+- int bArray = 0, bStruct = 0, bMixed = 0;
+- unsigned long num_index;
+- char* my_key;
++ int bArray = 0, bStruct = 0, bMixed = 0;
++ unsigned long num_index;
++ char* my_key;
+
+- zend_hash_internal_pointer_reset(ht);
+- while(1) {
+- int res = my_zend_hash_get_current_key(ht, &my_key, &num_index);
+- if(res == HASH_KEY_IS_LONG) {
+- if(bStruct) {
+- bMixed = 1;
+- break;
+- }
+- bArray = 1;
+- }
+- else if(res == HASH_KEY_NON_EXISTANT) {
+- break;
+- }
+- else if(res == HASH_KEY_IS_STRING) {
+- if(bArray) {
+- bMixed = 1;
+- break;
+- }
+- bStruct = 1;
+- }
++ zend_hash_internal_pointer_reset(ht);
++ while(1) {
++ int res = my_zend_hash_get_current_key(ht, &my_key, &num_index);
++ if(res == HASH_KEY_IS_LONG) {
++ if(bStruct) {
++ bMixed = 1;
++ break;
++ }
++ bArray = 1;
++ }
++ else if(res == HASH_KEY_NON_EXISTANT) {
++ break;
++ }
++ else if(res == HASH_KEY_IS_STRING) {
++ if(bArray) {
++ bMixed = 1;
++ break;
++ }
++ bStruct = 1;
++ }
+
+- zend_hash_move_forward(ht);
+- }
++ zend_hash_move_forward(ht);
++ }
+ return bMixed ? xmlrpc_vector_mixed : (bStruct ? xmlrpc_vector_struct : xmlrpc_vector_array);
+ }
+
+ /* recursively convert php values into xmlrpc values */
+ static XMLRPC_VALUE PHP_to_XMLRPC_worker (const char* key, zval* in_val, int depth TSRMLS_DC)
+ {
+- XMLRPC_VALUE xReturn = NULL;
+- if(in_val) {
+- zval* val = NULL;
+- XMLRPC_VALUE_TYPE type = get_zval_xmlrpc_type(in_val, &val);
+- if(val) {
+- switch(type) {
+- case xmlrpc_base64:
+- if(Z_TYPE_P(val) == IS_NULL) {
+- xReturn = XMLRPC_CreateValueEmpty();
++ XMLRPC_VALUE xReturn = NULL;
++ if(in_val) {
++ zval* val = NULL;
++ XMLRPC_VALUE_TYPE type = get_zval_xmlrpc_type(in_val, &val);
++ if(val) {
++ switch(type) {
++ case xmlrpc_base64:
++ if(Z_TYPE_P(val) == IS_NULL) {
++ xReturn = XMLRPC_CreateValueEmpty();
+ XMLRPC_SetValueID(xReturn, key, 0);
+- }
+- else {
+- xReturn = XMLRPC_CreateValueBase64(key, Z_STRVAL_P(val), Z_STRLEN_P(val));
+- }
+- break;
+- case xmlrpc_datetime:
+- convert_to_string(val);
+- xReturn = XMLRPC_CreateValueDateTime_ISO8601(key, Z_STRVAL_P(val));
+- break;
+- case xmlrpc_boolean:
+- convert_to_boolean(val);
+- xReturn = XMLRPC_CreateValueBoolean(key, Z_LVAL_P(val));
+- break;
+- case xmlrpc_int:
+- convert_to_long(val);
+- xReturn = XMLRPC_CreateValueInt(key, Z_LVAL_P(val));
+- break;
+- case xmlrpc_double:
+- convert_to_double(val);
+- xReturn = XMLRPC_CreateValueDouble(key, Z_DVAL_P(val));
+- break;
+- case xmlrpc_string:
+- convert_to_string(val);
+- xReturn = XMLRPC_CreateValueString(key, Z_STRVAL_P(val), Z_STRLEN_P(val));
+- break;
+- case xmlrpc_vector:
+- {
+- unsigned long num_index;
+- zval** pIter;
+- char* my_key;
+- HashTable *ht = NULL;
++ } else {
++ xReturn = XMLRPC_CreateValueBase64(key, Z_STRVAL_P(val), Z_STRLEN_P(val));
++ }
++ break;
++ case xmlrpc_datetime:
++ convert_to_string(val);
++ xReturn = XMLRPC_CreateValueDateTime_ISO8601(key, Z_STRVAL_P(val));
++ break;
++ case xmlrpc_boolean:
++ convert_to_boolean(val);
++ xReturn = XMLRPC_CreateValueBoolean(key, Z_LVAL_P(val));
++ break;
++ case xmlrpc_int:
++ convert_to_long(val);
++ xReturn = XMLRPC_CreateValueInt(key, Z_LVAL_P(val));
++ break;
++ case xmlrpc_double:
++ convert_to_double(val);
++ xReturn = XMLRPC_CreateValueDouble(key, Z_DVAL_P(val));
++ break;
++ case xmlrpc_string:
++ convert_to_string(val);
++ xReturn = XMLRPC_CreateValueString(key, Z_STRVAL_P(val), Z_STRLEN_P(val));
++ break;
++ case xmlrpc_vector: {
++ unsigned long num_index;
++ zval** pIter;
++ char* my_key;
++ HashTable *ht = NULL;
+
+- ht = HASH_OF(val);
+- if (ht && ht->nApplyCount > 1) {
+- php_error_docref(NULL TSRMLS_CC, E_ERROR, "XML-RPC doesn't support circular references");
+- return NULL;
+- }
+-
+- convert_to_array(val);
+- xReturn = XMLRPC_CreateVector(key, determine_vector_type(Z_ARRVAL_P(val)));
++ ht = HASH_OF(val);
++ if (ht && ht->nApplyCount > 1) {
++ php_error_docref(NULL TSRMLS_CC, E_ERROR, "XML-RPC doesn't support circular references");
++ return NULL;
++ }
+
+- zend_hash_internal_pointer_reset(Z_ARRVAL_P(val));
+- while(zend_hash_get_current_data(Z_ARRVAL_P(val), (void**)&pIter) == SUCCESS) {
+- int res = my_zend_hash_get_current_key(Z_ARRVAL_P(val), &my_key, &num_index);
++ convert_to_array(val);
++ xReturn = XMLRPC_CreateVector(key, determine_vector_type(Z_ARRVAL_P(val)));
++
++ zend_hash_internal_pointer_reset(Z_ARRVAL_P(val));
++ while(zend_hash_get_current_data(Z_ARRVAL_P(val), (void**)&pIter) == SUCCESS) {
++ int res = my_zend_hash_get_current_key(Z_ARRVAL_P(val), &my_key, &num_index);
+
+- switch (res) {
+- case HASH_KEY_NON_EXISTANT:
+- break;
+- case HASH_KEY_IS_STRING:
+- case HASH_KEY_IS_LONG:
+- ht = HASH_OF(*pIter);
+- if (ht) {
+- ht->nApplyCount++;
+- }
+- if (res == HASH_KEY_IS_LONG) {
+- XMLRPC_AddValueToVector(xReturn, PHP_to_XMLRPC_worker(0, *pIter, depth++ TSRMLS_CC));
+- }
+- else {
+- XMLRPC_AddValueToVector(xReturn, PHP_to_XMLRPC_worker(my_key, *pIter, depth++ TSRMLS_CC));
+- }
+- if (ht) {
+- ht->nApplyCount--;
+- }
+- break;
+- }
+- zend_hash_move_forward(Z_ARRVAL_P(val));
+- }
+- }
+- break;
+- default:
+- break;
+- }
+- }
+- }
++ switch (res) {
++ case HASH_KEY_NON_EXISTANT:
++ break;
++ case HASH_KEY_IS_STRING:
++ case HASH_KEY_IS_LONG:
++ ht = HASH_OF(*pIter);
++ if (ht) {
++ ht->nApplyCount++;
++ }
++ if (res == HASH_KEY_IS_LONG) {
++ XMLRPC_AddValueToVector(xReturn, PHP_to_XMLRPC_worker(0, *pIter, depth++ TSRMLS_CC));
++ } else {
++ XMLRPC_AddValueToVector(xReturn, PHP_to_XMLRPC_worker(my_key, *pIter, depth++ TSRMLS_CC));
++ }
++ if (ht) {
++ ht->nApplyCount--;
++ }
++ break;
++ }
++ zend_hash_move_forward(Z_ARRVAL_P(val));
++ }
++ }
++ break;
++ default:
++ break;
++ }
++ }
++ }
+ return xReturn;
+ }
+
+ static XMLRPC_VALUE PHP_to_XMLRPC(zval* root_val TSRMLS_DC)
+ {
+- return PHP_to_XMLRPC_worker(NULL, root_val, 0 TSRMLS_CC);
++ return PHP_to_XMLRPC_worker(NULL, root_val, 0 TSRMLS_CC);
+ }
+
+ /* recursively convert xmlrpc values into php values */
+ static zval* XMLRPC_to_PHP(XMLRPC_VALUE el)
+ {
+- zval* elem = NULL;
+- const char* pStr;
++ zval* elem = NULL;
++ const char* pStr;
+
+- if(el) {
+- XMLRPC_VALUE_TYPE type = XMLRPC_GetValueType(el);
++ if(el) {
++ XMLRPC_VALUE_TYPE type = XMLRPC_GetValueType(el);
+
+- MAKE_STD_ZVAL(elem); /* init. very important. spent a frustrating day finding this out. */
++ MAKE_STD_ZVAL(elem); /* init. very important. spent a frustrating day finding this out. */
+
+- switch(type) {
+- case xmlrpc_empty:
+- Z_TYPE_P(elem) = IS_NULL;
+- break;
+- case xmlrpc_string:
+- pStr = XMLRPC_GetValueString(el);
+- if(pStr) {
+- Z_STRLEN_P(elem) = XMLRPC_GetValueStringLen(el);
+- Z_STRVAL_P(elem) = estrndup(pStr, Z_STRLEN_P(elem));
+- Z_TYPE_P(elem) = IS_STRING;
+- }
+- break;
+- case xmlrpc_int:
+- Z_LVAL_P(elem) = XMLRPC_GetValueInt(el);
+- Z_TYPE_P(elem) = IS_LONG;
+- break;
+- case xmlrpc_boolean:
+- Z_LVAL_P(elem) = XMLRPC_GetValueBoolean(el);
+- Z_TYPE_P(elem) = IS_BOOL;
+- break;
+- case xmlrpc_double:
+- Z_DVAL_P(elem) = XMLRPC_GetValueDouble(el);
+- Z_TYPE_P(elem) = IS_DOUBLE;
+- break;
+- case xmlrpc_datetime:
+- Z_STRLEN_P(elem) = XMLRPC_GetValueStringLen(el);
+- Z_STRVAL_P(elem) = estrndup(XMLRPC_GetValueDateTime_ISO8601(el), Z_STRLEN_P(elem));
+- Z_TYPE_P(elem) = IS_STRING;
+- break;
+- case xmlrpc_base64:
+- pStr = XMLRPC_GetValueBase64(el);
+- if(pStr) {
+- Z_STRLEN_P(elem) = XMLRPC_GetValueStringLen(el);
+- Z_STRVAL_P(elem) = estrndup(pStr, Z_STRLEN_P(elem));
+- Z_TYPE_P(elem) = IS_STRING;
+- }
+- break;
+- case xmlrpc_vector:
+- array_init(elem);
+- {
+- XMLRPC_VALUE xIter = XMLRPC_VectorRewind(el);
++ switch(type) {
++ case xmlrpc_empty:
++ Z_TYPE_P(elem) = IS_NULL;
++ break;
++ case xmlrpc_string:
++ pStr = XMLRPC_GetValueString(el);
++ if(pStr) {
++ Z_STRLEN_P(elem) = XMLRPC_GetValueStringLen(el);
++ Z_STRVAL_P(elem) = estrndup(pStr, Z_STRLEN_P(elem));
++ Z_TYPE_P(elem) = IS_STRING;
++ }
++ break;
++ case xmlrpc_int:
++ Z_LVAL_P(elem) = XMLRPC_GetValueInt(el);
++ Z_TYPE_P(elem) = IS_LONG;
++ break;
++ case xmlrpc_boolean:
++ Z_LVAL_P(elem) = XMLRPC_GetValueBoolean(el);
++ Z_TYPE_P(elem) = IS_BOOL;
++ break;
++ case xmlrpc_double:
++ Z_DVAL_P(elem) = XMLRPC_GetValueDouble(el);
++ Z_TYPE_P(elem) = IS_DOUBLE;
++ break;
++ case xmlrpc_datetime:
++ Z_STRLEN_P(elem) = XMLRPC_GetValueStringLen(el);
++ Z_STRVAL_P(elem) = estrndup(XMLRPC_GetValueDateTime_ISO8601(el), Z_STRLEN_P(elem));
++ Z_TYPE_P(elem) = IS_STRING;
++ break;
++ case xmlrpc_base64:
++ pStr = XMLRPC_GetValueBase64(el);
++ if(pStr) {
++ Z_STRLEN_P(elem) = XMLRPC_GetValueStringLen(el);
++ Z_STRVAL_P(elem) = estrndup(pStr, Z_STRLEN_P(elem));
++ Z_TYPE_P(elem) = IS_STRING;
++ }
++ break;
++ case xmlrpc_vector:
++ array_init(elem);
++ {
++ XMLRPC_VALUE xIter = XMLRPC_VectorRewind(el);
+
+- while( xIter ) {
+- zval *val = XMLRPC_to_PHP(xIter);
+- if (val) {
+- add_zval(elem, XMLRPC_GetValueID(xIter), &val);
++ while( xIter ) {
++ zval *val = XMLRPC_to_PHP(xIter);
++ if (val) {
++ add_zval(elem, XMLRPC_GetValueID(xIter), &val);
++ }
++ xIter = XMLRPC_VectorNext(el);
++ }
+ }
+- xIter = XMLRPC_VectorNext(el);
+- }
+- }
+- break;
+- default:
+- break;
+- }
+- set_zval_xmlrpc_type(elem, type);
+- }
+- return elem;
++ break;
++ default:
++ break;
++ }
++ set_zval_xmlrpc_type(elem, type);
++ }
++ return elem;
+ }
+
+ /* {{{ proto string xmlrpc_encode_request(string method, mixed params)
+@@ -705,30 +698,30 @@
+
+ zval* decode_request_worker (zval* xml_in, zval* encoding_in, zval* method_name_out)
+ {
+- zval* retval = NULL;
+- XMLRPC_REQUEST response;
+- STRUCT_XMLRPC_REQUEST_INPUT_OPTIONS opts = {{0}};
+- opts.xml_elem_opts.encoding = encoding_in ? utf8_get_encoding_id_from_string(Z_STRVAL_P(encoding_in)) : ENCODING_DEFAULT;
++ zval* retval = NULL;
++ XMLRPC_REQUEST response;
++ STRUCT_XMLRPC_REQUEST_INPUT_OPTIONS opts = {{0}};
++ opts.xml_elem_opts.encoding = encoding_in ? utf8_get_encoding_id_from_string(Z_STRVAL_P(encoding_in)) : ENCODING_DEFAULT;
+
+- /* generate XMLRPC_REQUEST from raw xml */
+- response = XMLRPC_REQUEST_FromXML(Z_STRVAL_P(xml_in), Z_STRLEN_P(xml_in), &opts);
+- if(response) {
+- /* convert xmlrpc data to native php types */
+- retval = XMLRPC_to_PHP(XMLRPC_RequestGetData(response));
++ /* generate XMLRPC_REQUEST from raw xml */
++ response = XMLRPC_REQUEST_FromXML(Z_STRVAL_P(xml_in), Z_STRLEN_P(xml_in), &opts);
++ if(response) {
++ /* convert xmlrpc data to native php types */
++ retval = XMLRPC_to_PHP(XMLRPC_RequestGetData(response));
+
+- if(XMLRPC_RequestGetRequestType(response) == xmlrpc_request_call) {
+- if(method_name_out) {
+- zval_dtor(method_name_out);
+- Z_TYPE_P(method_name_out) = IS_STRING;
+- Z_STRVAL_P(method_name_out) = estrdup(XMLRPC_RequestGetMethodName(response));
+- Z_STRLEN_P(method_name_out) = strlen(Z_STRVAL_P(method_name_out));
+- }
+- }
++ if(XMLRPC_RequestGetRequestType(response) == xmlrpc_request_call) {
++ if(method_name_out) {
++ zval_dtor(method_name_out);
++ Z_TYPE_P(method_name_out) = IS_STRING;
++ Z_STRVAL_P(method_name_out) = estrdup(XMLRPC_RequestGetMethodName(response));
++ Z_STRLEN_P(method_name_out) = strlen(Z_STRVAL_P(method_name_out));
++ }
++ }
+
+- /* dust, sweep, and mop */
+- XMLRPC_RequestFree(response, 1);
+- }
+- return retval;
++ /* dust, sweep, and mop */
++ XMLRPC_RequestFree(response, 1);
++ }
++ return retval;
+ }
+
+ /* {{{ proto array xmlrpc_decode_request(string xml, string& method [, string encoding])
+@@ -854,29 +847,29 @@
+ */
+ static XMLRPC_VALUE php_xmlrpc_callback(XMLRPC_SERVER server, XMLRPC_REQUEST xRequest, void* data)
+ {
+- xmlrpc_callback_data* pData = (xmlrpc_callback_data*)data;
+- zval* xmlrpc_params;
+- zval* callback_params[3];
+- TSRMLS_FETCH();
+-
+- /* convert xmlrpc to native php types */
+- xmlrpc_params = XMLRPC_to_PHP(XMLRPC_RequestGetData(xRequest));
++ xmlrpc_callback_data* pData = (xmlrpc_callback_data*)data;
++ zval* xmlrpc_params;
++ zval* callback_params[3];
++ TSRMLS_FETCH();
+
+- /* setup data hoojum */
+- callback_params[0] = pData->xmlrpc_method;
+- callback_params[1] = xmlrpc_params;
+- callback_params[2] = pData->caller_params;
++ /* convert xmlrpc to native php types */
++ xmlrpc_params = XMLRPC_to_PHP(XMLRPC_RequestGetData(xRequest));
+
+- /* Use same C function for all methods */
++ /* setup data hoojum */
++ callback_params[0] = pData->xmlrpc_method;
++ callback_params[1] = xmlrpc_params;
++ callback_params[2] = pData->caller_params;
+
+- /* php func prototype: function user_func($method_name, $xmlrpc_params, $user_params) */
+- call_user_function(CG(function_table), NULL, pData->php_function, pData->return_data, 3, callback_params TSRMLS_CC);
++ /* Use same C function for all methods */
+
+- pData->php_executed = 1;
++ /* php func prototype: function user_func($method_name, $xmlrpc_params, $user_params) */
++ call_user_function(CG(function_table), NULL, pData->php_function, pData->return_data, 3, callback_params TSRMLS_CC);
+
+- zval_ptr_dtor(&xmlrpc_params);
++ pData->php_executed = 1;
+
+- return NULL;
++ zval_ptr_dtor(&xmlrpc_params);
++
++ return NULL;
+ }
+
+ /* called by the C server when it first receives an introspection request. We pass this on to
+@@ -884,66 +877,64 @@
+ */
+ static void php_xmlrpc_introspection_callback(XMLRPC_SERVER server, void* data)
+ {
+- zval *retval_ptr, **php_function;
+- zval* callback_params[1];
+- xmlrpc_callback_data* pData = (xmlrpc_callback_data*)data;
+- TSRMLS_FETCH();
+-
+- MAKE_STD_ZVAL(retval_ptr);
+- Z_TYPE_P(retval_ptr) = IS_NULL;
++ zval *retval_ptr, **php_function;
++ zval* callback_params[1];
++ char *php_function_name;
++ xmlrpc_callback_data* pData = (xmlrpc_callback_data*)data;
++ TSRMLS_FETCH();
+
+- /* setup data hoojum */
+- callback_params[0] = pData->caller_params;
++ MAKE_STD_ZVAL(retval_ptr);
++ Z_TYPE_P(retval_ptr) = IS_NULL;
+
+- /* loop through and call all registered callbacks */
+- zend_hash_internal_pointer_reset(Z_ARRVAL_P(pData->server->introspection_map));
+- while(1) {
+- if(zend_hash_get_current_data(Z_ARRVAL_P(pData->server->introspection_map),
+- (void**)&php_function) == SUCCESS) {
++ /* setup data hoojum */
++ callback_params[0] = pData->caller_params;
+
+- /* php func prototype: function string user_func($user_params) */
+- if(call_user_function(CG(function_table), NULL, *php_function,
+- retval_ptr, 1, callback_params TSRMLS_CC) == SUCCESS) {
+- XMLRPC_VALUE xData;
+- STRUCT_XMLRPC_ERROR err = {0};
++ /* loop through and call all registered callbacks */
++ zend_hash_internal_pointer_reset(Z_ARRVAL_P(pData->server->introspection_map));
++ while(1) {
++ if(zend_hash_get_current_data(Z_ARRVAL_P(pData->server->introspection_map), (void**)&php_function) == SUCCESS) {
+
+- /* return value should be a string */
+- convert_to_string(retval_ptr);
++ if (zend_is_callable(*php_function, 0, &php_function_name)) {
++ /* php func prototype: function string user_func($user_params) */
++ if (call_user_function(CG(function_table), NULL, *php_function, retval_ptr, 1, callback_params TSRMLS_CC) == SUCCESS) {
++ XMLRPC_VALUE xData;
++ STRUCT_XMLRPC_ERROR err = {0};
+
+- xData = XMLRPC_IntrospectionCreateDescription(Z_STRVAL_P(retval_ptr), &err);
++ /* return value should be a string */
++ convert_to_string(retval_ptr);
+
+- if(xData) {
+- if(!XMLRPC_ServerAddIntrospectionData(server, xData)) {
+- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to add introspection data returned from %s(), improper element structure", Z_STRVAL_PP(php_function));
+- }
+- XMLRPC_CleanupValue(xData);
+- }
+- else {
+- /* could not create description */
+- if(err.xml_elem_error.parser_code) {
+- php_error_docref(NULL TSRMLS_CC, E_WARNING, "xml parse error: [line %ld, column %ld, message: %s] Unable to add introspection data returned from %s()",
+- err.xml_elem_error.column, err.xml_elem_error.line, err.xml_elem_error.parser_error, Z_STRVAL_PP(php_function));
+- }
+- else {
+- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to add introspection data returned from %s()",
+- Z_STRVAL_PP(php_function));
+- }
+- }
+- }
+- else {
+- /* user func failed */
+- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error calling user introspection callback: %s()", Z_STRVAL_PP(php_function));
+- }
+- }
+- else {
+- break;
+- }
++ xData = XMLRPC_IntrospectionCreateDescription(Z_STRVAL_P(retval_ptr), &err);
+
+- zend_hash_move_forward(Z_ARRVAL_P(pData->server->introspection_map));
+- }
++ if(xData) {
++ if(!XMLRPC_ServerAddIntrospectionData(server, xData)) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to add introspection data returned from %s(), improper element structure", php_function_name);
++ }
++ XMLRPC_CleanupValue(xData);
++ } else {
++ /* could not create description */
++ if(err.xml_elem_error.parser_code) {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "xml parse error: [line %ld, column %ld, message: %s] Unable to add introspection data returned from %s()",
++ err.xml_elem_error.column, err.xml_elem_error.line, err.xml_elem_error.parser_error, php_function_name);
++ } else {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to add introspection data returned from %s()", php_function_name);
++ }
++ }
++ } else {
++ /* user func failed */
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error calling user introspection callback: %s()", php_function_name);
++ }
++ } else {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid callback '%s' passed", php_function_name);
++ }
++ efree(php_function_name);
++ } else {
++ break;
++ }
++ zend_hash_move_forward(Z_ARRVAL_P(pData->server->introspection_map));
++ }
+
+- /* so we don't call the same callbacks ever again */
+- zend_hash_clean(Z_ARRVAL_P(pData->server->introspection_map));
++ /* so we don't call the same callbacks ever again */
++ zend_hash_clean(Z_ARRVAL_P(pData->server->introspection_map));
+ }
+
+ /* {{{ proto bool xmlrpc_server_register_method(resource server, string method_name, string function)
+@@ -1218,70 +1209,70 @@
+ /* return a string matching a given xmlrpc type */
+ static const char** get_type_str_mapping(void)
+ {
+- static const char* str_mapping[TYPE_STR_MAP_SIZE];
+- static int first = 1;
+- if (first) {
+- /* warning. do not add/delete without changing size define */
+- str_mapping[xmlrpc_none] = "none";
+- str_mapping[xmlrpc_empty] = "empty";
+- str_mapping[xmlrpc_base64] = "base64";
+- str_mapping[xmlrpc_boolean] = "boolean";
+- str_mapping[xmlrpc_datetime] = "datetime";
+- str_mapping[xmlrpc_double] = "double";
+- str_mapping[xmlrpc_int] = "int";
+- str_mapping[xmlrpc_string] = "string";
+- str_mapping[xmlrpc_vector] = "vector";
+- str_mapping[XMLRPC_TYPE_COUNT + xmlrpc_vector_none] = "none";
+- str_mapping[XMLRPC_TYPE_COUNT + xmlrpc_vector_array] = "array";
+- str_mapping[XMLRPC_TYPE_COUNT + xmlrpc_vector_mixed] = "mixed";
+- str_mapping[XMLRPC_TYPE_COUNT + xmlrpc_vector_struct] = "struct";
+- first = 0;
+- }
+- return (const char**)str_mapping;
++ static const char* str_mapping[TYPE_STR_MAP_SIZE];
++ static int first = 1;
++ if (first) {
++ /* warning. do not add/delete without changing size define */
++ str_mapping[xmlrpc_none] = "none";
++ str_mapping[xmlrpc_empty] = "empty";
++ str_mapping[xmlrpc_base64] = "base64";
++ str_mapping[xmlrpc_boolean] = "boolean";
++ str_mapping[xmlrpc_datetime] = "datetime";
++ str_mapping[xmlrpc_double] = "double";
++ str_mapping[xmlrpc_int] = "int";
++ str_mapping[xmlrpc_string] = "string";
++ str_mapping[xmlrpc_vector] = "vector";
++ str_mapping[XMLRPC_TYPE_COUNT + xmlrpc_vector_none] = "none";
++ str_mapping[XMLRPC_TYPE_COUNT + xmlrpc_vector_array] = "array";
++ str_mapping[XMLRPC_TYPE_COUNT + xmlrpc_vector_mixed] = "mixed";
++ str_mapping[XMLRPC_TYPE_COUNT + xmlrpc_vector_struct] = "struct";
++ first = 0;
++ }
++ return (const char**)str_mapping;
+ }
+
+ /* map an xmlrpc type to a string */
+ const char* xmlrpc_type_as_str(XMLRPC_VALUE_TYPE type, XMLRPC_VECTOR_TYPE vtype)
+ {
+- const char** str_mapping = get_type_str_mapping();
++ const char** str_mapping = get_type_str_mapping();
+
+- if (vtype == xmlrpc_vector_none) {
+- return str_mapping[type];
+- } else {
+- return str_mapping[XMLRPC_TYPE_COUNT + vtype];
+- }
++ if (vtype == xmlrpc_vector_none) {
++ return str_mapping[type];
++ } else {
++ return str_mapping[XMLRPC_TYPE_COUNT + vtype];
++ }
+ }
+
+ /* map a string to an xmlrpc type */
+ XMLRPC_VALUE_TYPE xmlrpc_str_as_type(const char* str)
+ {
+- const char** str_mapping = get_type_str_mapping();
+- int i;
++ const char** str_mapping = get_type_str_mapping();
++ int i;
+
+- if (str) {
+- for (i = 0; i < XMLRPC_TYPE_COUNT; i++) {
+- if (!strcmp(str_mapping[i], str)) {
+- return (XMLRPC_VALUE_TYPE) i;
+- }
+- }
+- }
+- return xmlrpc_none;
++ if (str) {
++ for (i = 0; i < XMLRPC_TYPE_COUNT; i++) {
++ if (!strcmp(str_mapping[i], str)) {
++ return (XMLRPC_VALUE_TYPE) i;
++ }
++ }
++ }
++ return xmlrpc_none;
+ }
+
+ /* map a string to an xmlrpc vector type */
+ XMLRPC_VECTOR_TYPE xmlrpc_str_as_vector_type(const char* str)
+ {
+- const char** str_mapping = get_type_str_mapping();
+- int i;
++ const char** str_mapping = get_type_str_mapping();
++ int i;
+
+- if (str) {
+- for (i = XMLRPC_TYPE_COUNT; i < TYPE_STR_MAP_SIZE; i++) {
+- if (!strcmp(str_mapping[i], str)) {
+- return (XMLRPC_VECTOR_TYPE) (i - XMLRPC_TYPE_COUNT);
+- }
+- }
+- }
+- return xmlrpc_none;
++ if (str) {
++ for (i = XMLRPC_TYPE_COUNT; i < TYPE_STR_MAP_SIZE; i++) {
++ if (!strcmp(str_mapping[i], str)) {
++ return (XMLRPC_VECTOR_TYPE) (i - XMLRPC_TYPE_COUNT);
++ }
++ }
++ }
++ return xmlrpc_none;
+ }
+
+
+@@ -1291,107 +1282,106 @@
+ */
+ int set_zval_xmlrpc_type(zval* value, XMLRPC_VALUE_TYPE newtype)
+ {
+- int bSuccess = FAILURE;
+- TSRMLS_FETCH();
++ int bSuccess = FAILURE;
++ TSRMLS_FETCH();
+
+- /* we only really care about strings because they can represent
+- * base64 and datetime. all other types have corresponding php types
+- */
+- if (Z_TYPE_P(value) == IS_STRING) {
+- if (newtype == xmlrpc_base64 || newtype == xmlrpc_datetime) {
+- const char* typestr = xmlrpc_type_as_str(newtype, xmlrpc_vector_none);
+- zval* type;
++ /* we only really care about strings because they can represent
++ * base64 and datetime. all other types have corresponding php types
++ */
++ if (Z_TYPE_P(value) == IS_STRING) {
++ if (newtype == xmlrpc_base64 || newtype == xmlrpc_datetime) {
++ const char* typestr = xmlrpc_type_as_str(newtype, xmlrpc_vector_none);
++ zval* type;
+
+- MAKE_STD_ZVAL(type);
++ MAKE_STD_ZVAL(type);
+
+- Z_TYPE_P(type) = IS_STRING;
+- Z_STRVAL_P(type) = estrdup(typestr);
+- Z_STRLEN_P(type) = strlen(typestr);
++ Z_TYPE_P(type) = IS_STRING;
++ Z_STRVAL_P(type) = estrdup(typestr);
++ Z_STRLEN_P(type) = strlen(typestr);
+
+- if(newtype == xmlrpc_datetime) {
+- XMLRPC_VALUE v = XMLRPC_CreateValueDateTime_ISO8601(NULL, value->value.str.val);
+- if(v) {
+- time_t timestamp = XMLRPC_GetValueDateTime(v);
+- if(timestamp) {
+- zval* ztimestamp;
++ if(newtype == xmlrpc_datetime) {
++ XMLRPC_VALUE v = XMLRPC_CreateValueDateTime_ISO8601(NULL, value->value.str.val);
++ if(v) {
++ time_t timestamp = XMLRPC_GetValueDateTime(v);
++ if(timestamp) {
++ zval* ztimestamp;
+
+- MAKE_STD_ZVAL(ztimestamp);
++ MAKE_STD_ZVAL(ztimestamp);
+
+- ztimestamp->type = IS_LONG;
+- ztimestamp->value.lval = timestamp;
++ ztimestamp->type = IS_LONG;
++ ztimestamp->value.lval = timestamp;
+
+- convert_to_object(value);
+- if(SUCCESS == zend_hash_update(Z_OBJPROP_P(value), OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR), (void *) &type, sizeof(zval *), NULL)) {
+- bSuccess = zend_hash_update(Z_OBJPROP_P(value), OBJECT_VALUE_TS_ATTR, sizeof(OBJECT_VALUE_TS_ATTR), (void *) &ztimestamp, sizeof(zval *), NULL);
+- }
+- } else {
+- zval_ptr_dtor(&type);
+- }
+- XMLRPC_CleanupValue(v);
+- } else {
+- zval_ptr_dtor(&type);
+- }
+- }
+- else {
+- convert_to_object(value);
+- bSuccess = zend_hash_update(Z_OBJPROP_P(value), OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR), (void *) &type, sizeof(zval *), NULL);
+- }
+- }
+- }
++ convert_to_object(value);
++ if(SUCCESS == zend_hash_update(Z_OBJPROP_P(value), OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR), (void *) &type, sizeof(zval *), NULL)) {
++ bSuccess = zend_hash_update(Z_OBJPROP_P(value), OBJECT_VALUE_TS_ATTR, sizeof(OBJECT_VALUE_TS_ATTR), (void *) &ztimestamp, sizeof(zval *), NULL);
++ }
++ } else {
++ zval_ptr_dtor(&type);
++ }
++ XMLRPC_CleanupValue(v);
++ } else {
++ zval_ptr_dtor(&type);
++ }
++ } else {
++ convert_to_object(value);
++ bSuccess = zend_hash_update(Z_OBJPROP_P(value), OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR), (void *) &type, sizeof(zval *), NULL);
++ }
++ }
++ }
+
+- return bSuccess;
++ return bSuccess;
+ }
+
+ /* return xmlrpc type of a php value */
+ XMLRPC_VALUE_TYPE get_zval_xmlrpc_type(zval* value, zval** newvalue)
+ {
+- XMLRPC_VALUE_TYPE type = xmlrpc_none;
+- TSRMLS_FETCH();
++ XMLRPC_VALUE_TYPE type = xmlrpc_none;
++ TSRMLS_FETCH();
+
+- if (value) {
+- switch (Z_TYPE_P(value)) {
+- case IS_NULL:
+- type = xmlrpc_base64;
+- break;
++ if (value) {
++ switch (Z_TYPE_P(value)) {
++ case IS_NULL:
++ type = xmlrpc_base64;
++ break;
+ #ifndef BOOL_AS_LONG
+
+- /* Right thing to do, but it breaks some legacy code. */
+- case IS_BOOL:
+- type = xmlrpc_boolean;
+- break;
++ /* Right thing to do, but it breaks some legacy code. */
++ case IS_BOOL:
++ type = xmlrpc_boolean;
++ break;
+ #else
+- case IS_BOOL:
++ case IS_BOOL:
+ #endif
+- case IS_LONG:
+- case IS_RESOURCE:
+- type = xmlrpc_int;
+- break;
+- case IS_DOUBLE:
+- type = xmlrpc_double;
+- break;
+- case IS_CONSTANT:
+- type = xmlrpc_string;
+- break;
+- case IS_STRING:
+- type = xmlrpc_string;
+- break;
+- case IS_ARRAY:
+- case IS_CONSTANT_ARRAY:
+- type = xmlrpc_vector;
+- break;
+- case IS_OBJECT:
+- {
+- zval** attr;
+- type = xmlrpc_vector;
++ case IS_LONG:
++ case IS_RESOURCE:
++ type = xmlrpc_int;
++ break;
++ case IS_DOUBLE:
++ type = xmlrpc_double;
++ break;
++ case IS_CONSTANT:
++ type = xmlrpc_string;
++ break;
++ case IS_STRING:
++ type = xmlrpc_string;
++ break;
++ case IS_ARRAY:
++ case IS_CONSTANT_ARRAY:
++ type = xmlrpc_vector;
++ break;
++ case IS_OBJECT:
++ {
++ zval** attr;
++ type = xmlrpc_vector;
+
+- if (zend_hash_find(Z_OBJPROP_P(value), OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR), (void**) &attr) == SUCCESS) {
+- if (Z_TYPE_PP(attr) == IS_STRING) {
+- type = xmlrpc_str_as_type(Z_STRVAL_PP(attr));
+- }
+- }
+- break;
+- }
+- }
++ if (zend_hash_find(Z_OBJPROP_P(value), OBJECT_TYPE_ATTR, sizeof(OBJECT_TYPE_ATTR), (void**) &attr) == SUCCESS) {
++ if (Z_TYPE_PP(attr) == IS_STRING) {
++ type = xmlrpc_str_as_type(Z_STRVAL_PP(attr));
++ }
++ }
++ break;
++ }
++ }
+
+ /* if requested, return an unmolested (magic removed) copy of the value */
+ if (newvalue) {
+@@ -1406,7 +1396,6 @@
+ }
+ }
+ }
+-
+ return type;
+ }
+
Index: patches/gentoo/019_new-memory-corruption.patch
===================================================================
--- patches/gentoo/019_new-memory-corruption.patch (revision 0)
+++ patches/gentoo/019_new-memory-corruption.patch (revision 0)
@@ -0,0 +1,220 @@
+Memory corruption/leaks on assignment result of "new" by reference
+Patch by upstream
+
+http://bugs.php.net/45178
+http://cvs.php.net/viewvc.cgi/ZendEngine2/tests/bug45178.phpt?revision=1.1.2.1&view=markup
+http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_compile.c?r1=1.647.2.27.2.49&r2=1.647.2.27.2.50&diff_format=u
+http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_compile.h?r1=1.316.2.8.2.13&r2=1.316.2.8.2.14&diff_format=u
+http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_language_parser.y?r1=1.160.2.4.2.10&r2=1.160.2.4.2.11&diff_format=u
+http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_def.h?r1=1.59.2.29.2.56&r2=1.59.2.29.2.57&diff_format=u
+http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_vm_execute.h?r1=1.62.2.30.2.59&r2=1.62.2.30.2.60&diff_format=u
+
+diff -r c22215132ef9 -r 1927a5178496 Zend/tests/bug45178.phpt
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ b/Zend/tests/bug45178.phpt Thu Aug 07 12:56:24 2008 +0200
+@@ -0,0 +1,29 @@
++--TEST--
++Bug #45178 memory corruption on assignment result of "new" by reference
++--FILE--
++<?php
++class Foo {
++ function __construct() {
++ $this->error = array($this,$this);
++ }
++}
++$a =& new Foo();
++
++class Bar {
++ function __construct() {
++ $this->_rme2 = $this;
++ }
++}
++
++$b =& new Bar();
++$b->_rme2 = 0;
++var_dump($b);
++?>
++--EXPECTF--
++Strict Standards: Assigning the return value of new by reference is deprecated in %sbug45178.php on line 7
++
++Strict Standards: Assigning the return value of new by reference is deprecated in %sbug45178.php on line 15
++object(Bar)#%d (1) {
++ ["_rme2"]=>
++ int(0)
++}
+diff -r c22215132ef9 -r 1927a5178496 Zend/zend_compile.c
+--- a/Zend/zend_compile.c Wed Aug 06 17:56:24 2008 +0200
++++ b/Zend/zend_compile.c Thu Aug 07 12:56:24 2008 +0200
+@@ -655,6 +655,8 @@
+ opline->opcode = ZEND_ASSIGN_REF;
+ if (zend_is_function_or_method_call(rvar)) {
+ opline->extended_value = ZEND_RETURNS_FUNCTION;
++ } else if (rvar->u.EA.type & ZEND_PARSED_NEW) {
++ opline->extended_value = ZEND_RETURNS_NEW;
+ } else {
+ opline->extended_value = 0;
+ }
+diff -r c22215132ef9 -r 1927a5178496 Zend/zend_compile.h
+--- a/Zend/zend_compile.h Wed Aug 06 17:56:24 2008 +0200
++++ b/Zend/zend_compile.h Thu Aug 07 12:56:24 2008 +0200
+@@ -17,7 +17,7 @@
+ +----------------------------------------------------------------------+
+ */
+
+-/* $Id: zend_compile.h,v 1.316.2.8.2.13 2007/12/31 07:20:02 sebastian Exp $ */
++/* $Id: zend_compile.h,v 1.316.2.8.2.14 2008/07/24 11:47:12 dmitry Exp $ */
+
+ #ifndef ZEND_COMPILE_H
+ #define ZEND_COMPILE_H
+@@ -600,6 +600,7 @@
+ #define ZEND_PARSED_FUNCTION_CALL (1<<3)
+ #define ZEND_PARSED_VARIABLE (1<<4)
+ #define ZEND_PARSED_REFERENCE_VARIABLE (1<<5)
++#define ZEND_PARSED_NEW (1<<6)
+
+
+ /* unset types */
+@@ -685,6 +686,7 @@
+
+
+ #define ZEND_RETURNS_FUNCTION 1<<0
++#define ZEND_RETURNS_NEW 1<<1
+
+ END_EXTERN_C()
+
+diff -r c22215132ef9 -r 1927a5178496 Zend/zend_language_parser.y
+--- a/Zend/zend_language_parser.y Wed Aug 06 17:56:24 2008 +0200
++++ b/Zend/zend_language_parser.y Thu Aug 07 12:56:24 2008 +0200
+@@ -18,7 +18,7 @@
+ +----------------------------------------------------------------------+
+ */
+
+-/* $Id: zend_language_parser.y,v 1.160.2.4.2.10 2008/03/10 14:54:47 felipe Exp $ */
++/* $Id: zend_language_parser.y,v 1.160.2.4.2.11 2008/07/24 11:47:12 dmitry Exp $ */
+
+ /*
+ * LALR shift/reduce conflicts and how they are resolved:
+@@ -553,7 +553,7 @@
+ T_LIST '(' { zend_do_list_init(TSRMLS_C); } assignment_list ')' '=' expr { zend_do_list_end(&$$, &$7 TSRMLS_CC); }
+ | variable '=' expr { zend_check_writable_variable(&$1); zend_do_assign(&$$, &$1, &$3 TSRMLS_CC); }
+ | variable '=' '&' variable { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$4 TSRMLS_CC); }
+- | variable '=' '&' T_NEW class_name_reference { zend_error(E_STRICT, "Assigning the return value of new by reference is deprecated"); zend_check_writable_variable(&$1); zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$4, &$5 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$3, &$4, &$7 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$3 TSRMLS_CC); }
++ | variable '=' '&' T_NEW class_name_reference { zend_error(E_STRICT, "Assigning the return value of new by reference is deprecated"); zend_check_writable_variable(&$1); zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$4, &$5 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$3, &$4, &$7 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); $3.u.EA.type = ZEND_PARSED_NEW; zend_do_assign_ref(&$$, &$1, &$3 TSRMLS_CC); }
+ | T_NEW class_name_reference { zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$1, &$2 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$$, &$1, &$4 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+ | T_CLONE expr { zend_do_clone(&$$, &$2 TSRMLS_CC); }
+ | variable T_PLUS_EQUAL expr { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_ADD, &$$, &$1, &$3 TSRMLS_CC); }
+diff -r c22215132ef9 -r 1927a5178496 Zend/zend_vm_def.h
+--- a/Zend/zend_vm_def.h Wed Aug 06 17:56:24 2008 +0200
++++ b/Zend/zend_vm_def.h Thu Aug 07 12:56:24 2008 +0200
+@@ -18,7 +18,7 @@
+ +----------------------------------------------------------------------+
+ */
+
+-/* $Id: zend_vm_def.h,v 1.59.2.29.2.56 2008/03/04 11:46:09 dmitry Exp $ */
++/* $Id: zend_vm_def.h,v 1.59.2.29.2.57 2008/07/24 11:47:12 dmitry Exp $ */
+
+ /* If you change this file, please regenerate the zend_vm_execute.h and
+ * zend_vm_opcodes.h files by running:
+@@ -1483,6 +1483,8 @@
+ }
+ zend_error(E_STRICT, "Only variables should be assigned by reference");
+ ZEND_VM_DISPATCH_TO_HANDLER(ZEND_ASSIGN);
++ } else if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
++ PZVAL_LOCK(*value_ptr_ptr);
+ }
+ if (OP1_TYPE == IS_VAR && EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
+ zend_error(E_ERROR, "Cannot assign by reference to overloaded object");
+@@ -1490,6 +1492,10 @@
+
+ variable_ptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+ zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
++
++ if (OP2_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
++ (*variable_ptr_ptr)->refcount--;
++ }
+
+ if (!RETURN_VALUE_UNUSED(&opline->result)) {
+ EX_T(opline->result.u.var).var.ptr_ptr = variable_ptr_ptr;
+diff -r c22215132ef9 -r 1927a5178496 Zend/zend_vm_execute.h
+--- a/Zend/zend_vm_execute.h Wed Aug 06 17:56:24 2008 +0200
++++ b/Zend/zend_vm_execute.h Thu Aug 07 12:56:24 2008 +0200
+@@ -12386,6 +12386,8 @@
+ }
+ zend_error(E_STRICT, "Only variables should be assigned by reference");
+ return ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
++ } else if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
++ PZVAL_LOCK(*value_ptr_ptr);
+ }
+ if (IS_VAR == IS_VAR && EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
+ zend_error(E_ERROR, "Cannot assign by reference to overloaded object");
+@@ -12393,6 +12395,10 @@
+
+ variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
+ zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
++
++ if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
++ (*variable_ptr_ptr)->refcount--;
++ }
+
+ if (!RETURN_VALUE_UNUSED(&opline->result)) {
+ EX_T(opline->result.u.var).var.ptr_ptr = variable_ptr_ptr;
+@@ -14388,6 +14394,8 @@
+ }
+ zend_error(E_STRICT, "Only variables should be assigned by reference");
+ return ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
++ } else if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
++ PZVAL_LOCK(*value_ptr_ptr);
+ }
+ if (IS_VAR == IS_VAR && EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
+ zend_error(E_ERROR, "Cannot assign by reference to overloaded object");
+@@ -14395,6 +14403,10 @@
+
+ variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
+ zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
++
++ if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
++ (*variable_ptr_ptr)->refcount--;
++ }
+
+ if (!RETURN_VALUE_UNUSED(&opline->result)) {
+ EX_T(opline->result.u.var).var.ptr_ptr = variable_ptr_ptr;
+@@ -24495,6 +24507,8 @@
+ }
+ zend_error(E_STRICT, "Only variables should be assigned by reference");
+ return ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
++ } else if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
++ PZVAL_LOCK(*value_ptr_ptr);
+ }
+ if (IS_CV == IS_VAR && EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
+ zend_error(E_ERROR, "Cannot assign by reference to overloaded object");
+@@ -24502,6 +24516,10 @@
+
+ variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
+ zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
++
++ if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
++ (*variable_ptr_ptr)->refcount--;
++ }
+
+ if (!RETURN_VALUE_UNUSED(&opline->result)) {
+ EX_T(opline->result.u.var).var.ptr_ptr = variable_ptr_ptr;
+@@ -26487,6 +26505,8 @@
+ }
+ zend_error(E_STRICT, "Only variables should be assigned by reference");
+ return ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
++ } else if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
++ PZVAL_LOCK(*value_ptr_ptr);
+ }
+ if (IS_CV == IS_VAR && EX_T(opline->op1.u.var).var.ptr_ptr == &EX_T(opline->op1.u.var).var.ptr) {
+ zend_error(E_ERROR, "Cannot assign by reference to overloaded object");
+@@ -26494,6 +26514,10 @@
+
+ variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
+ zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
++
++ if (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) {
++ (*variable_ptr_ptr)->refcount--;
++ }
+
+ if (!RETURN_VALUE_UNUSED(&opline->result)) {
+ EX_T(opline->result.u.var).var.ptr_ptr = variable_ptr_ptr;
Index: patches/gentoo/freetds-compat.patch
===================================================================
--- patches/gentoo/freetds-compat.patch (revision 0)
+++ patches/gentoo/freetds-compat.patch (revision 0)
@@ -0,0 +1,88 @@
+Allow ext/mssql and ext/pdo_dblib to build with >=freetds-0.82
+Original patch by jklowden at freetds dot org
+ext/pdo_dblib patch by matthias at dsx ado at
+Rediffed for Gentoo (wrong direction)
+http://bugs.php.net/bug.php?id=44991
+
+diff -r 57e37b68a255 -r f1222f67e562 ext/mssql/config.m4
+--- a/ext/mssql/config.m4 Tue Jul 01 19:37:24 2008 +0200
++++ b/ext/mssql/config.m4 Thu Jul 17 11:35:57 2008 +0200
+@@ -10,11 +10,11 @@
+
+ if test "$PHP_MSSQL" = "yes"; then
+ for i in /usr/local /usr; do
+- if test -f $i/include/tds.h; then
++ if test -f $i/include/sybdb.h; then
+ FREETDS_INSTALLATION_DIR=$i
+ FREETDS_INCLUDE_DIR=$i/include
+ break
+- elif test -f $i/include/freetds/tds.h; then
++ elif test -f $i/include/freetds/sybdb.h; then
+ FREETDS_INSTALLATION_DIR=$i
+ FREETDS_INCLUDE_DIR=$i/include/freetds
+ break
+@@ -27,10 +27,10 @@
+
+ elif test "$PHP_MSSQL" != "no"; then
+
+- if test -f $PHP_MSSQL/include/tds.h; then
++ if test -f $PHP_MSSQL/include/sybdb.h; then
+ FREETDS_INSTALLATION_DIR=$PHP_MSSQL
+ FREETDS_INCLUDE_DIR=$PHP_MSSQL/include
+- elif test -f $PHP_MSSQL/include/freetds/tds.h; then
++ elif test -f $PHP_MSSQL/include/freetds/sybdb.h; then
+ FREETDS_INSTALLATION_DIR=$PHP_MSSQL
+ FREETDS_INCLUDE_DIR=$PHP_MSSQL/include/freetds
+ else
+@@ -38,8 +38,8 @@
+ fi
+ fi
+
+- if test ! -r "$FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libtds.a" && test ! -r "$FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libtds.so"; then
+- AC_MSG_ERROR(Could not find $FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libtds.[a|so])
++ if test ! -r "$FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libsybdb.a" && test ! -r "$FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libsybdb.so"; then
++ AC_MSG_ERROR(Could not find $FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libsybdb.[a|so])
+ fi
+
+ PHP_ADD_INCLUDE($FREETDS_INCLUDE_DIR)
+diff -r 57e37b68a255 -r f1222f67e562 ext/pdo_dblib/config.m4
+--- a/ext/pdo_dblib/config.m4 Tue Jul 01 19:37:24 2008 +0200
++++ b/ext/pdo_dblib/config.m4 Thu Jul 17 11:35:57 2008 +0200
+@@ -13,11 +13,11 @@
+ if test "$PHP_PDO_DBLIB" = "yes"; then
+
+ for i in /usr/local /usr; do
+- if test -f $i/include/tds.h; then
++ if test -f $i/include/sybdb.h; then
+ PDO_FREETDS_INSTALLATION_DIR=$i
+ PDO_FREETDS_INCLUDE_DIR=$i/include
+ break
+- elif test -f $i/include/freetds/tds.h; then
++ elif test -f $i/include/freetds/sybdb.h; then
+ PDO_FREETDS_INSTALLATION_DIR=$i
+ PDO_FREETDS_INCLUDE_DIR=$i/include/freetds
+ break;
+@@ -30,10 +30,10 @@
+
+ elif test "$PHP_PDO_DBLIB" != "no"; then
+
+- if test -f $PHP_PDO_DBLIB/include/tds.h; then
++ if test -f $PHP_PDO_DBLIB/include/sybdb.h; then
+ PDO_FREETDS_INSTALLATION_DIR=$PHP_PDO_DBLIB
+ PDO_FREETDS_INCLUDE_DIR=$PHP_PDO_DBLIB/include
+- elif test -f $PHP_PDO_DBLIB/include/freetds/tds.h; then
++ elif test -f $PHP_PDO_DBLIB/include/freetds/sybdb.h; then
+ PDO_FREETDS_INSTALLATION_DIR=$PHP_PDO_DBLIB
+ PDO_FREETDS_INCLUDE_DIR=$PHP_PDO_DBLIB/include/freetds
+ else
+@@ -45,8 +45,8 @@
+ PHP_LIBDIR=lib
+ fi
+
+- if test ! -r "$PDO_FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libtds.a" && test ! -r "$PDO_FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libtds.so"; then
+- AC_MSG_ERROR(Could not find $PDO_FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libtds.[a|so])
++ if test ! -r "$PDO_FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libsybdb.a" && test ! -r "$PDO_FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libsybdb.so"; then
++ AC_MSG_ERROR(Could not find $PDO_FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libsybdb.[a|so])
+ fi
+
+ PHP_ADD_INCLUDE($PDO_FREETDS_INCLUDE_DIR)
Index: patches/gentoo/006_PDORow-crash.patch
===================================================================
--- patches/gentoo/006_PDORow-crash.patch (revision 0)
+++ patches/gentoo/006_PDORow-crash.patch (revision 0)
@@ -0,0 +1,32 @@
+Add check for avoid segfault when trying instantiate PDORow manually
+http://cvs.php.net/viewvc.cgi/php-src/ext/pdo/pdo_stmt.c?r1=1.118.2.38.2.34&r2=1.118.2.38.2.35&diff_format=u
+
+diff -r 34abf22f19f9 ext/pdo/pdo_stmt.c
+--- a/ext/pdo/pdo_stmt.c Wed Jun 18 18:41:22 2008 +0200
++++ b/ext/pdo/pdo_stmt.c Wed Jun 18 18:59:15 2008 +0200
+@@ -18,7 +18,7 @@
+ +----------------------------------------------------------------------+
+ */
+
+-/* $Id: pdo_stmt.c,v 1.118.2.38.2.34 2008/02/26 00:14:04 iliaa Exp $ */
++/* $Id: pdo_stmt.c,v 1.118.2.38.2.35 2008/05/14 12:34:10 felipe Exp $ */
+
+ /* The PDO Statement Handle Class */
+
+@@ -2711,10 +2711,12 @@
+
+ void pdo_row_free_storage(pdo_stmt_t *stmt TSRMLS_DC)
+ {
+- ZVAL_NULL(&stmt->lazy_object_ref);
+-
+- if (--stmt->refcount == 0) {
+- free_statement(stmt TSRMLS_CC);
++ if (stmt) {
++ ZVAL_NULL(&stmt->lazy_object_ref);
++
++ if (--stmt->refcount == 0) {
++ free_statement(stmt TSRMLS_CC);
++ }
+ }
+ }
+
Index: patches/gentoo/009_array-function-crashes.patch
===================================================================
--- patches/gentoo/009_array-function-crashes.patch (revision 0)
+++ patches/gentoo/009_array-function-crashes.patch (revision 0)
@@ -0,0 +1,208 @@
+Fixed bug #45312 (Segmentation fault on second request for array functions).
+http://cvs.php.net/viewvc.cgi/php-src/ext/standard/array.c?r1=1.308.2.21.2.57&r2=1.308.2.21.2.58&diff_format=u
+http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/array/bug45312.phpt?revision=1.1.2.1&view=markup
+
+diff -r b542651437b3 ext/standard/array.c
+--- a/ext/standard/array.c Wed Jun 18 20:03:11 2008 +0200
++++ b/ext/standard/array.c Thu Jun 19 18:24:36 2008 +0200
+@@ -667,6 +667,7 @@
+ PHP_ARRAY_CMP_FUNC_RESTORE();
+ WRONG_PARAM_COUNT;
+ }
++
+ target_hash = HASH_OF(*array);
+ if (!target_hash) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array");
+@@ -675,6 +676,7 @@
+ }
+
+ PHP_ARRAY_CMP_FUNC_CHECK(BG(user_compare_func_name))
++ BG(user_compare_fci_cache).initialized = 0;
+
+ if (zend_hash_sort(target_hash, zend_qsort, array_user_compare, 1 TSRMLS_CC) == FAILURE) {
+ PHP_ARRAY_CMP_FUNC_RESTORE();
+@@ -707,6 +709,7 @@
+ }
+
+ PHP_ARRAY_CMP_FUNC_CHECK(BG(user_compare_func_name))
++ BG(user_compare_fci_cache).initialized = 0;
+
+ if (zend_hash_sort(target_hash, zend_qsort, array_user_compare, 0 TSRMLS_CC) == FAILURE) {
+ PHP_ARRAY_CMP_FUNC_RESTORE();
+@@ -790,6 +793,7 @@
+ }
+
+ PHP_ARRAY_CMP_FUNC_CHECK(BG(user_compare_func_name))
++ BG(user_compare_fci_cache).initialized = 0;
+
+ if (zend_hash_sort(target_hash, zend_qsort, array_user_key_compare, 0 TSRMLS_CC) == FAILURE) {
+ PHP_ARRAY_CMP_FUNC_RESTORE();
+@@ -2988,6 +2992,7 @@
+ efree(callback_name);
+ intersect_data_compare_func = zval_user_compare;
+ BG(user_compare_func_name) = args[argc];
++ BG(user_compare_fci_cache).initialized = 0;
+ } else if (data_compare_type == INTERSECT_COMP_DATA_INTERNAL) {
+ intersect_data_compare_func = zval_compare;
+ }
+@@ -3099,6 +3104,7 @@
+ efree(callback_name);
+
+ BG(user_compare_func_name) = args[arr_argc];
++ BG(user_compare_fci_cache).initialized = 0;
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "data_compare_type is %d. This should never happen. Please report as a bug", data_compare_type);
+ return;
+@@ -3160,6 +3166,7 @@
+ intersect_key_compare_func = array_user_key_compare;
+ intersect_data_compare_func = array_data_compare;
+ BG(user_compare_func_name) = args[arr_argc];
++ BG(user_compare_fci_cache).initialized = 0;
+ } else if (data_compare_type == INTERSECT_COMP_DATA_USER
+ &&
+ key_compare_type == INTERSECT_COMP_KEY_USER) {
+@@ -3187,6 +3194,7 @@
+ intersect_key_compare_func = array_user_key_compare;
+ intersect_data_compare_func = array_user_compare;
+ BG(user_compare_func_name) = args[arr_argc + 1];/* data - key */
++ BG(user_compare_fci_cache).initialized = 0;
+ } else {
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "data_compare_type is %d. key_compare_type is %d. This should never happen. Please report as a bug", data_compare_type, key_compare_type);
+@@ -3245,6 +3253,7 @@
+ if ((behavior & INTERSECT_NORMAL) && data_compare_type == INTERSECT_COMP_DATA_USER) {
+ /* array_uintersect() */
+ BG(user_compare_func_name) = args[arr_argc];
++ BG(user_compare_fci_cache).initialized = 0;
+ }
+
+ /* go through the lists and look for common values */
+@@ -3254,6 +3263,7 @@
+ key_compare_type == INTERSECT_COMP_KEY_USER) {
+
+ BG(user_compare_func_name) = args[argc - 1];
++ BG(user_compare_fci_cache).initialized = 0;
+ }
+
+ for (i = 1; i < arr_argc; i++) {
+@@ -3275,11 +3285,13 @@
+ */
+ if (data_compare_type == INTERSECT_COMP_DATA_USER) {
+ BG(user_compare_func_name) = args[arr_argc];
++ BG(user_compare_fci_cache).initialized = 0;
+ }
+ if (intersect_data_compare_func(ptrs[0], ptrs[i] TSRMLS_CC) != 0) {
+ c = 1;
+ if (key_compare_type == INTERSECT_COMP_KEY_USER) {
+ BG(user_compare_func_name) = args[argc - 1];
++ BG(user_compare_fci_cache).initialized = 0;
+ /* When KEY_USER, the last parameter is always the callback */
+ }
+ /* we are going to the break */
+@@ -3466,6 +3478,7 @@
+ efree(callback_name);
+ diff_data_compare_func = zval_user_compare;
+ BG(user_compare_func_name) = args[argc];
++ BG(user_compare_fci_cache).initialized = 0;
+ } else if (data_compare_type == DIFF_COMP_DATA_INTERNAL) {
+ diff_data_compare_func = zval_compare;
+ }
+@@ -3577,6 +3590,7 @@
+ efree(callback_name);
+
+ BG(user_compare_func_name) = args[arr_argc];
++ BG(user_compare_fci_cache).initialized = 0;
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "data_compare_type is %d. This should never happen. Please report as a bug", data_compare_type);
+ return;
+@@ -3638,6 +3652,7 @@
+ diff_key_compare_func = array_user_key_compare;
+ diff_data_compare_func = array_data_compare;
+ BG(user_compare_func_name) = args[arr_argc];
++ BG(user_compare_fci_cache).initialized = 0;
+ } else if (data_compare_type == DIFF_COMP_DATA_USER
+ &&
+ key_compare_type == DIFF_COMP_KEY_USER) {
+@@ -3665,6 +3680,7 @@
+ diff_key_compare_func = array_user_key_compare;
+ diff_data_compare_func = array_user_compare;
+ BG(user_compare_func_name) = args[arr_argc + 1];/* data - key*/
++ BG(user_compare_fci_cache).initialized = 0;
+ } else {
+ efree(args);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "data_compare_type is %d. key_compare_type is %d. This should never happen. Please report as a bug", data_compare_type, key_compare_type);
+@@ -3723,6 +3739,7 @@
+ if (behavior == DIFF_NORMAL && data_compare_type == DIFF_COMP_DATA_USER) {
+ /* array_udiff() */
+ BG(user_compare_func_name) = args[arr_argc];
++ BG(user_compare_fci_cache).initialized = 0;
+ }
+
+ /* go through the lists and look for values of ptr[0] that are not in the others */
+@@ -3732,6 +3749,7 @@
+ key_compare_type == DIFF_COMP_KEY_USER) {
+
+ BG(user_compare_func_name) = args[argc - 1];
++ BG(user_compare_fci_cache).initialized = 0;
+ }
+ c = 1;
+ for (i = 1; i < arr_argc; i++) {
+@@ -3759,12 +3777,14 @@
+ if (*ptr) {
+ if (data_compare_type == DIFF_COMP_DATA_USER) {
+ BG(user_compare_func_name) = args[arr_argc];
++ BG(user_compare_fci_cache).initialized = 0;
+ }
+ if (diff_data_compare_func(ptrs[0], ptr TSRMLS_CC) != 0) {
+ /* the data is not the same */
+ c = -1;
+ if (key_compare_type == DIFF_COMP_KEY_USER) {
+ BG(user_compare_func_name) = args[argc - 1];
++ BG(user_compare_fci_cache).initialized = 0;
+ }
+ } else {
+ break;
+diff -r b542651437b3 ext/standard/tests/array/bug45312.phpt
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ b/ext/standard/tests/array/bug45312.phpt Thu Jun 19 18:24:36 2008 +0200
+@@ -0,0 +1,40 @@
++--TEST--
++Bug #45312 (Segmentation fault on second request for array functions)
++--FILE--
++<?php
++class cr {
++ private $priv_member;
++ function cr($val) {
++ $this->priv_member = $val;
++ }
++ static function comp_func_cr($a, $b) {
++ if ($a->priv_member === $b->priv_member) return 0;
++ return ($a->priv_member > $b->priv_member) ? 1 : -1;
++ }
++ static function comp_func_cr2($a, $b) {
++ echo ".";
++ if ($a->priv_member === $b->priv_member) return 0;
++ return ($a->priv_member < $b->priv_member) ? 1 : -1;
++ }
++ function dump() {
++ echo $this->priv_member . "\n";
++ }
++}
++$a = array("0.1" => new cr(9), "0.5" => new cr(12), 0 => new cr(23), 1 => new cr(4), 2 => new cr(-15),);
++$b = array("0.2" => new cr(9), "0.5" => new cr(22), 0 => new cr(3), 1 => new cr(4), 2 => new cr(-15),);
++$result = array_udiff_assoc($a, $b, array("cr", "comp_func_cr"));
++foreach($result as $val) {
++ $val->dump();
++}
++$result = array_udiff_assoc($a, $b, array("cr", "comp_func_cr2"));
++foreach($result as $val) {
++ $val->dump();
++}
++?>
++--EXPECT--
++9
++12
++23
++....9
++12
++23
Index: patches/gentoo/005_stream_context_set_params-crash.patch
===================================================================
--- patches/gentoo/005_stream_context_set_params-crash.patch (revision 0)
+++ patches/gentoo/005_stream_context_set_params-crash.patch (revision 0)
@@ -0,0 +1,38 @@
+Fixed bug #44712 (stream_context_set_params segfaults on invalid
+arguments).
+http://cvs.php.net/viewvc.cgi/php-src/ext/standard/streamsfuncs.c?r1=1.58.2.6.2.20&r2=1.58.2.6.2.21&diff_format=u
+
+diff -r 971fde6685fa -r 34abf22f19f9 ext/standard/streamsfuncs.c
+--- a/ext/standard/streamsfuncs.c Wed Jun 18 18:37:26 2008 +0200
++++ b/ext/standard/streamsfuncs.c Wed Jun 18 18:41:22 2008 +0200
+@@ -879,7 +879,7 @@
+ return ret;
+ }
+
+-static int parse_context_params(php_stream_context *context, zval *params)
++static int parse_context_params(php_stream_context *context, zval *params TSRMLS_DC)
+ {
+ int ret = SUCCESS;
+ zval **tmp;
+@@ -898,7 +898,11 @@
+ context->notifier->dtor = user_space_stream_notifier_dtor;
+ }
+ if (SUCCESS == zend_hash_find(Z_ARRVAL_P(params), "options", sizeof("options"), (void**)&tmp)) {
+- parse_context_options(context, *tmp);
++ if (Z_TYPE_PP(tmp) == IS_ARRAY) {
++ parse_context_options(context, *tmp);
++ } else {
++ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid stream/context parameter");
++ }
+ }
+
+ return ret;
+@@ -1006,7 +1010,7 @@
+ RETURN_FALSE;
+ }
+
+- RETVAL_BOOL(parse_context_params(context, params) == SUCCESS);
++ RETVAL_BOOL(parse_context_params(context, params TSRMLS_CC) == SUCCESS);
+ }
+ /* }}} */
+
Index: patches/deprecated_freetds_check.patch
===================================================================
--- patches/deprecated_freetds_check.patch (revision 1170)
+++ patches/deprecated_freetds_check.patch (working copy)
@@ -1,88 +0,0 @@
-Allow ext/mssql and ext/pdo_dblib to build with >=freetds-0.82
-Original patch by jklowden at freetds dot org
-ext/pdo_dblib patch by matthias at dsx ado at
-Rediffed for Gentoo (wrong direction)
-http://bugs.php.net/bug.php?id=44991
-
-diff -r 57e37b68a255 -r f1222f67e562 ext/mssql/config.m4
---- a/ext/mssql/config.m4 Tue Jul 01 19:37:24 2008 +0200
-+++ b/ext/mssql/config.m4 Thu Jul 17 11:35:57 2008 +0200
-@@ -10,11 +10,11 @@
-
- if test "$PHP_MSSQL" = "yes"; then
- for i in /usr/local /usr; do
-- if test -f $i/include/tds.h; then
-+ if test -f $i/include/sybdb.h; then
- FREETDS_INSTALLATION_DIR=$i
- FREETDS_INCLUDE_DIR=$i/include
- break
-- elif test -f $i/include/freetds/tds.h; then
-+ elif test -f $i/include/freetds/sybdb.h; then
- FREETDS_INSTALLATION_DIR=$i
- FREETDS_INCLUDE_DIR=$i/include/freetds
- break
-@@ -27,10 +27,10 @@
-
- elif test "$PHP_MSSQL" != "no"; then
-
-- if test -f $PHP_MSSQL/include/tds.h; then
-+ if test -f $PHP_MSSQL/include/sybdb.h; then
- FREETDS_INSTALLATION_DIR=$PHP_MSSQL
- FREETDS_INCLUDE_DIR=$PHP_MSSQL/include
-- elif test -f $PHP_MSSQL/include/freetds/tds.h; then
-+ elif test -f $PHP_MSSQL/include/freetds/sybdb.h; then
- FREETDS_INSTALLATION_DIR=$PHP_MSSQL
- FREETDS_INCLUDE_DIR=$PHP_MSSQL/include/freetds
- else
-@@ -38,8 +38,8 @@
- fi
- fi
-
-- if test ! -r "$FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libtds.a" && test ! -r "$FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libtds.so"; then
-- AC_MSG_ERROR(Could not find $FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libtds.[a|so])
-+ if test ! -r "$FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libsybdb.a" && test ! -r "$FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libsybdb.so"; then
-+ AC_MSG_ERROR(Could not find $FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libsybdb.[a|so])
- fi
-
- PHP_ADD_INCLUDE($FREETDS_INCLUDE_DIR)
-diff -r 57e37b68a255 -r f1222f67e562 ext/pdo_dblib/config.m4
---- a/ext/pdo_dblib/config.m4 Tue Jul 01 19:37:24 2008 +0200
-+++ b/ext/pdo_dblib/config.m4 Thu Jul 17 11:35:57 2008 +0200
-@@ -13,11 +13,11 @@
- if test "$PHP_PDO_DBLIB" = "yes"; then
-
- for i in /usr/local /usr; do
-- if test -f $i/include/tds.h; then
-+ if test -f $i/include/sybdb.h; then
- PDO_FREETDS_INSTALLATION_DIR=$i
- PDO_FREETDS_INCLUDE_DIR=$i/include
- break
-- elif test -f $i/include/freetds/tds.h; then
-+ elif test -f $i/include/freetds/sybdb.h; then
- PDO_FREETDS_INSTALLATION_DIR=$i
- PDO_FREETDS_INCLUDE_DIR=$i/include/freetds
- break;
-@@ -30,10 +30,10 @@
-
- elif test "$PHP_PDO_DBLIB" != "no"; then
-
-- if test -f $PHP_PDO_DBLIB/include/tds.h; then
-+ if test -f $PHP_PDO_DBLIB/include/sybdb.h; then
- PDO_FREETDS_INSTALLATION_DIR=$PHP_PDO_DBLIB
- PDO_FREETDS_INCLUDE_DIR=$PHP_PDO_DBLIB/include
-- elif test -f $PHP_PDO_DBLIB/include/freetds/tds.h; then
-+ elif test -f $PHP_PDO_DBLIB/include/freetds/sybdb.h; then
- PDO_FREETDS_INSTALLATION_DIR=$PHP_PDO_DBLIB
- PDO_FREETDS_INCLUDE_DIR=$PHP_PDO_DBLIB/include/freetds
- else
-@@ -45,8 +45,8 @@
- PHP_LIBDIR=lib
- fi
-
-- if test ! -r "$PDO_FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libtds.a" && test ! -r "$PDO_FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libtds.so"; then
-- AC_MSG_ERROR(Could not find $PDO_FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libtds.[a|so])
-+ if test ! -r "$PDO_FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libsybdb.a" && test ! -r "$PDO_FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libsybdb.so"; then
-+ AC_MSG_ERROR(Could not find $PDO_FREETDS_INSTALLATION_DIR/$PHP_LIBDIR/libsybdb.[a|so])
- fi
-
- PHP_ADD_INCLUDE($PDO_FREETDS_INCLUDE_DIR)
Reply to: