dmitry Tue Dec 19 11:54:38 2006 UTC
Added files: (Branch: PHP_5_2)
/php-src/ext/soap/tests/bugs bug39815.phpt
Modified files:
/php-src NEWS
/php-src/main snprintf.c snprintf.h spprintf.c
/php-src/ext/standard formatted_print.c
/php-src/ext/soap php_encoding.c
/php-src/ext/soap/tests/interop/Round3/GroupD
r3_groupD_compound2_001w.phpt
Log:
Fixed bug #39815 (SOAP double encoding is not locale-independent)
http://cvs.php.net/viewvc.cgi/php-src/NEWS?r1=1.2027.2.547.2.442&r2=1.2027.2.547.2.443&diff_format=u
Index: php-src/NEWS
diff -u php-src/NEWS:1.2027.2.547.2.442 php-src/NEWS:1.2027.2.547.2.443
--- php-src/NEWS:1.2027.2.547.2.442 Tue Dec 19 09:17:04 2006
+++ php-src/NEWS Tue Dec 19 11:54:37 2006
@@ -14,6 +14,7 @@
when trying to open "php://wrong"). (Tony)
- Fixed bug #39832 (SOAP Server: parameter not matching the WSDL specified type
are set to 0). (Dmitry)
+- Fixed bug #39815 (SOAP double encoding is not locale-independent). (Dmitry)
14 Dec 2006, PHP 5.2.1RC1
- Added a meta tag to phpinfo() output to prevent search engines from indexing
http://cvs.php.net/viewvc.cgi/php-src/main/snprintf.c?r1=1.37.2.4.2.3&r2=1.37.2.4.2.4&diff_format=u
Index: php-src/main/snprintf.c
diff -u php-src/main/snprintf.c:1.37.2.4.2.3
php-src/main/snprintf.c:1.37.2.4.2.4
--- php-src/main/snprintf.c:1.37.2.4.2.3 Mon Dec 18 09:26:54 2006
+++ php-src/main/snprintf.c Tue Dec 19 11:54:38 2006
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: snprintf.c,v 1.37.2.4.2.3 2006/12/18 09:26:54 bjori Exp $ */
+/* $Id: snprintf.c,v 1.37.2.4.2.4 2006/12/19 11:54:38 dmitry Exp $ */
#include "php.h"
@@ -115,23 +115,20 @@
return(s);
}
-char *bsd_ecvt(double value, int ndigit, int *decpt, int *sign)
+static inline char *php_ecvt(double value, int ndigit, int *decpt, int *sign)
{
return(__cvt(value, ndigit, decpt, sign, 0, 1));
}
-char *bsd_fcvt(double value, int ndigit, int *decpt, int *sign)
+static inline char *php_fcvt(double value, int ndigit, int *decpt, int *sign)
{
return(__cvt(value, ndigit, decpt, sign, 1, 1));
}
-char *bsd_gcvt(double value, int ndigit, char *buf)
+PHPAPI char *php_gcvt(double value, int ndigit, char dec_point, char exponent,
char *buf)
{
char *digits, *dst, *src;
int i, decpt, sign;
- struct lconv *lconv;
-
- lconv = localeconv();
digits = zend_dtoa(value, 2, ndigit, &decpt, &sign, NULL);
if (decpt == 9999) {
@@ -161,7 +158,7 @@
sign = 0;
src = digits;
*dst++ = *src++;
- *dst++ = *lconv->decimal_point;
+ *dst++ = dec_point;
if (*src == '\0') {
*dst++ = '0';
} else {
@@ -169,7 +166,7 @@
*dst++ = *src++;
} while (*src != '\0');
}
- *dst++ = 'e';
+ *dst++ = exponent;
if (sign)
*dst++ = '-';
else
@@ -190,7 +187,7 @@
} else if (decpt < 0) {
/* standard format 0. */
*dst++ = '0'; /* zero before decimal point */
- *dst++ = *lconv->decimal_point;
+ *dst++ = dec_point;
do {
*dst++ = '0';
} while (++decpt < 0);
@@ -210,7 +207,7 @@
if (*src != '\0') {
if (src == digits)
*dst++ = '0'; /* zero before decimal point */
- *dst++ = *lconv->decimal_point;
+ *dst++ = dec_point;
for (i = decpt; digits[i] != '\0'; i++) {
*dst++ = digits[i];
}
@@ -357,29 +354,21 @@
* The sign is returned in the is_negative argument (and is not placed
* in buf).
*/
-char * ap_php_conv_fp(register char format, register double num,
- boolean_e add_dp, int precision, bool_int * is_negative, char
*buf, int *len)
+PHPAPI char * php_conv_fp(register char format, register double num,
+ boolean_e add_dp, int precision, char dec_point, bool_int *
is_negative, char *buf, int *len)
{
register char *s = buf;
register char *p, *p_orig;
int decimal_point;
- char dec_point = '.';
-
- if (format == 'f') {
- struct lconv *lconv;
- lconv = localeconv();
- dec_point = *lconv->decimal_point;
- format = 'F';
- }
if (precision >= NDIG - 1) {
precision = NDIG - 2;
}
if (format == 'F')
- p_orig = p = bsd_fcvt(num, precision, &decimal_point,
is_negative);
+ p_orig = p = php_fcvt(num, precision, &decimal_point,
is_negative);
else /* either e or E format
*/
- p_orig = p = bsd_ecvt(num, precision + 1, &decimal_point,
is_negative);
+ p_orig = p = php_ecvt(num, precision + 1, &decimal_point,
is_negative);
/*
* Check for Infinity and NaN
@@ -595,6 +584,8 @@
char num_buf[NUM_BUF_SIZE];
char char_buf[2]; /* for printing %% and
%<unknown> */
+ struct lconv *lconv = NULL;
+
/*
* Flag variables
*/
@@ -930,6 +921,7 @@
case 'f':
+ case 'F':
case 'e':
case 'E':
switch(modifier) {
@@ -950,8 +942,12 @@
s = "inf";
s_len = 3;
} else {
- s = ap_php_conv_fp(*fmt,
fp_num, alternate_form,
+ if (!lconv) {
+ lconv = localeconv();
+ }
+ s = php_conv_fp((*fmt ==
'f')?'F':*fmt, fp_num, alternate_form,
(adjust_precision == NO) ?
FLOAT_DIGITS : precision,
+ (*fmt ==
'f')?(*lconv->decimal_point):'.',
&is_negative, &num_buf[1], &s_len);
if (is_negative)
prefix_char = '-';
@@ -998,7 +994,10 @@
/*
* * We use &num_buf[ 1 ], so that we
have room for the sign
*/
- s = bsd_gcvt(fp_num, precision,
&num_buf[1]);
+ if (!lconv) {
+ lconv = localeconv();
+ }
+ s = php_gcvt(fp_num, precision,
*lconv->decimal_point, (*fmt == 'G')?'E':'e', &num_buf[1]);
if (*s == '-')
prefix_char = *s++;
else if (print_sign)
@@ -1010,8 +1009,6 @@
if (alternate_form && (q = strchr(s,
'.')) == NULL)
s[s_len++] = '.';
- if (*fmt == 'G' && (q = strchr(s, 'e'))
!= NULL)
- *q = 'E';
break;
http://cvs.php.net/viewvc.cgi/php-src/main/snprintf.h?r1=1.32.2.3.2.1&r2=1.32.2.3.2.2&diff_format=u
Index: php-src/main/snprintf.h
diff -u php-src/main/snprintf.h:1.32.2.3.2.1
php-src/main/snprintf.h:1.32.2.3.2.2
--- php-src/main/snprintf.h:1.32.2.3.2.1 Wed Dec 6 09:52:51 2006
+++ php-src/main/snprintf.h Tue Dec 19 11:54:38 2006
@@ -17,7 +17,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: snprintf.h,v 1.32.2.3.2.1 2006/12/06 09:52:51 tony2001 Exp $ */
+/* $Id: snprintf.h,v 1.32.2.3.2.2 2006/12/19 11:54:38 dmitry Exp $ */
/*
@@ -65,10 +65,21 @@
#ifndef SNPRINTF_H
#define SNPRINTF_H
+typedef int bool_int;
+
+typedef enum {
+ NO = 0, YES = 1
+} boolean_e;
+
+
BEGIN_EXTERN_C()
PHPAPI int ap_php_snprintf(char *, size_t, const char *, ...)
PHP_ATTRIBUTE_FORMAT(printf, 3, 4);
PHPAPI int ap_php_vsnprintf(char *, size_t, const char *, va_list ap)
PHP_ATTRIBUTE_FORMAT(printf, 3, 0);
PHPAPI int php_sprintf (char* s, const char* format, ...)
PHP_ATTRIBUTE_FORMAT(printf, 2, 3);
+PHPAPI char * php_gcvt(double value, int ndigit, char dec_point, char
exponent, char *buf);
+PHPAPI char * php_conv_fp(register char format, register double num,
+ boolean_e add_dp, int precision, char dec_point, bool_int *
is_negative, char *buf, int *len);
+
END_EXTERN_C()
#ifdef snprintf
@@ -87,10 +98,6 @@
#define sprintf php_sprintf
typedef enum {
- NO = 0, YES = 1
-} boolean_e;
-
-typedef enum {
LM_STD = 0,
#if SIZEOF_INTMAX_T
LM_INTMAX_T,
@@ -118,21 +125,12 @@
typedef WIDE_INT wide_int;
typedef unsigned WIDE_INT u_wide_int;
-typedef int bool_int;
-
extern char * ap_php_conv_10(register wide_int num, register bool_int
is_unsigned,
register bool_int * is_negative, char *buf_end, register int *len);
-extern char * ap_php_conv_fp(register char format, register double num,
- boolean_e add_dp, int precision, bool_int * is_negative, char
*buf, int *len);
-
extern char * ap_php_conv_p2(register u_wide_int num, register int nbits,
char format, char *buf_end, register int *len);
-extern char * bsd_ecvt(double value, int ndigit, int *decpt, int *sign);
-extern char * bsd_fcvt(double value, int ndigit, int *decpt, int *sign);
-extern char * bsd_gcvt(double value, int ndigit, char *buf);
-
#endif /* SNPRINTF_H */
/*
http://cvs.php.net/viewvc.cgi/php-src/main/spprintf.c?r1=1.25.2.2.2.2&r2=1.25.2.2.2.3&diff_format=u
Index: php-src/main/spprintf.c
diff -u php-src/main/spprintf.c:1.25.2.2.2.2
php-src/main/spprintf.c:1.25.2.2.2.3
--- php-src/main/spprintf.c:1.25.2.2.2.2 Wed Dec 6 09:52:51 2006
+++ php-src/main/spprintf.c Tue Dec 19 11:54:38 2006
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: spprintf.c,v 1.25.2.2.2.2 2006/12/06 09:52:51 tony2001 Exp $ */
+/* $Id: spprintf.c,v 1.25.2.2.2.3 2006/12/19 11:54:38 dmitry Exp $ */
/* This is the spprintf implementation.
* It has emerged from apache snprintf. See original header:
@@ -90,6 +90,10 @@
#include <inttypes.h>
#endif
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
#include "snprintf.h"
#define FALSE 0
@@ -195,6 +199,8 @@
char num_buf[NUM_BUF_SIZE];
char char_buf[2]; /* for printing %% and
%<unknown> */
+ struct lconv *lconv = NULL;
+
/*
* Flag variables
*/
@@ -527,6 +533,7 @@
case 'f':
+ case 'F':
case 'e':
case 'E':
switch(modifier) {
@@ -547,8 +554,12 @@
s = "inf";
s_len = 3;
} else {
- s = ap_php_conv_fp(*fmt,
fp_num, alternate_form,
+ if (!lconv) {
+ lconv = localeconv();
+ }
+ s = php_conv_fp((*fmt ==
'f')?'F':*fmt, fp_num, alternate_form,
(adjust_precision == NO) ?
FLOAT_DIGITS : precision,
+ (*fmt ==
'f')?(*lconv->decimal_point):'.',
&is_negative, &num_buf[1], &s_len);
if (is_negative)
prefix_char = '-';
@@ -595,7 +606,10 @@
/*
* * We use &num_buf[ 1 ], so that we
have room for the sign
*/
- s = bsd_gcvt(fp_num, precision,
&num_buf[1]);
+ if (!lconv) {
+ lconv = localeconv();
+ }
+ s = php_gcvt(fp_num, precision,
*lconv->decimal_point, (*fmt == 'G')?'E':'e', &num_buf[1]);
if (*s == '-')
prefix_char = *s++;
else if (print_sign)
@@ -607,8 +621,6 @@
if (alternate_form && (q = strchr(s,
'.')) == NULL)
s[s_len++] = '.';
- if (*fmt == 'G' && (q = strchr(s, 'e'))
!= NULL)
- *q = 'E';
break;
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/formatted_print.c?r1=1.82.2.1.2.7&r2=1.82.2.1.2.8&diff_format=u
Index: php-src/ext/standard/formatted_print.c
diff -u php-src/ext/standard/formatted_print.c:1.82.2.1.2.7
php-src/ext/standard/formatted_print.c:1.82.2.1.2.8
--- php-src/ext/standard/formatted_print.c:1.82.2.1.2.7 Mon Dec 18 10:19:52 2006
+++ php-src/ext/standard/formatted_print.c Tue Dec 19 11:54:38 2006
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: formatted_print.c,v 1.82.2.1.2.7 2006/12/18 10:19:52 tony2001 Exp $ */
+/* $Id: formatted_print.c,v 1.82.2.1.2.8 2006/12/19 11:54:38 dmitry Exp $ */
#include <math.h> /* modf() */
#include "php.h"
@@ -196,8 +196,9 @@
TSRMLS_DC)
{
char num_buf[NUM_BUF_SIZE];
- char *s = NULL, *q;
+ char *s = NULL;
int s_len = 0, is_negative = 0;
+ struct lconv *lconv;
PRINTF_DEBUG(("sprintf: appenddouble(%x, %x, %x, %f, %d, '%c', %d,
%c)\n",
*buffer, pos, size, number, width, padding,
alignment, fmt));
@@ -229,7 +230,9 @@
case 'E':
case 'f':
case 'F':
- s = ap_php_conv_fp(fmt, number, 0, precision,
+ lconv = localeconv();
+ s = php_conv_fp((fmt == 'f')?'F':fmt, number, 0,
precision,
+ (fmt ==
'f')?(*lconv->decimal_point):'.',
&is_negative, &num_buf[1],
&s_len);
if (is_negative) {
num_buf[0] = '-';
@@ -249,7 +252,8 @@
/*
* * We use &num_buf[ 1 ], so that we have room for the
sign
*/
- s = bsd_gcvt(number, precision, &num_buf[1]);
+ lconv = localeconv();
+ s = php_gcvt(number, precision, *lconv->decimal_point,
(fmt == 'G')?'E':'e', &num_buf[1]);
is_negative = 0;
if (*s == '-') {
is_negative = 1;
@@ -260,10 +264,6 @@
}
s_len = strlen(s);
-
- if (fmt == 'G' && (q = strchr(s, 'e')) != NULL) {
- *q = 'E';
- }
break;
}
http://cvs.php.net/viewvc.cgi/php-src/ext/soap/php_encoding.c?r1=1.103.2.21.2.17&r2=1.103.2.21.2.18&diff_format=u
Index: php-src/ext/soap/php_encoding.c
diff -u php-src/ext/soap/php_encoding.c:1.103.2.21.2.17
php-src/ext/soap/php_encoding.c:1.103.2.21.2.18
--- php-src/ext/soap/php_encoding.c:1.103.2.21.2.17 Mon Dec 18 14:39:23 2006
+++ php-src/ext/soap/php_encoding.c Tue Dec 19 11:54:38 2006
@@ -17,7 +17,7 @@
| Dmitry Stogov <[EMAIL PROTECTED]> |
+----------------------------------------------------------------------+
*/
-/* $Id: php_encoding.c,v 1.103.2.21.2.17 2006/12/18 14:39:23 dmitry Exp $ */
+/* $Id: php_encoding.c,v 1.103.2.21.2.18 2006/12/19 11:54:38 dmitry Exp $ */
#include <time.h>
@@ -961,19 +961,23 @@
{
xmlNodePtr ret;
zval tmp;
+ char *str;
+ TSRMLS_FETCH();
ret = xmlNewNode(NULL, BAD_CAST("BOGUS"));
xmlAddChild(parent, ret);
FIND_ZVAL_NULL(data, ret, style);
tmp = *data;
- zval_copy_ctor(&tmp);
if (Z_TYPE(tmp) != IS_DOUBLE) {
+ zval_copy_ctor(&tmp);
convert_to_double(&tmp);
}
- convert_to_string(&tmp);
- xmlNodeSetContentLen(ret, BAD_CAST(Z_STRVAL(tmp)), Z_STRLEN(tmp));
- zval_dtor(&tmp);
+
+ str = (char *) emalloc(MAX_LENGTH_OF_DOUBLE + EG(precision) + 1);
+ php_gcvt(Z_DVAL(tmp), EG(precision), '.', 'E', str);
+ xmlNodeSetContentLen(ret, BAD_CAST(str), strlen(str));
+ efree(str);
if (style == SOAP_ENCODED) {
set_ns_and_type(ret, type);
http://cvs.php.net/viewvc.cgi/php-src/ext/soap/tests/interop/Round3/GroupD/r3_groupD_compound2_001w.phpt?r1=1.1.2.1&r2=1.1.2.1.2.1&diff_format=u
Index:
php-src/ext/soap/tests/interop/Round3/GroupD/r3_groupD_compound2_001w.phpt
diff -u
php-src/ext/soap/tests/interop/Round3/GroupD/r3_groupD_compound2_001w.phpt:1.1.2.1
php-src/ext/soap/tests/interop/Round3/GroupD/r3_groupD_compound2_001w.phpt:1.1.2.1.2.1
---
php-src/ext/soap/tests/interop/Round3/GroupD/r3_groupD_compound2_001w.phpt:1.1.2.1
Wed Aug 24 11:46:11 2005
+++ php-src/ext/soap/tests/interop/Round3/GroupD/r3_groupD_compound2_001w.phpt
Tue Dec 19 11:54:38 2006
@@ -31,7 +31,7 @@
?>
--EXPECT--
<?xml version="1.0" encoding="UTF-8"?>
-<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://soapinterop.org/person"
xmlns:ns2="http://soapinterop.org/employee"><SOAP-ENV:Body><ns2:x_Employee><ns2:person><ns1:Name>Shane</ns1:Name><ns1:Male>true</ns1:Male></ns2:person><ns2:salary>1000000</ns2:salary><ns2:ID>12345</ns2:ID></ns2:x_Employee></SOAP-ENV:Body></SOAP-ENV:Envelope>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://soapinterop.org/person"
xmlns:ns2="http://soapinterop.org/employee"><SOAP-ENV:Body><ns2:x_Employee><ns2:person><ns1:Name>Shane</ns1:Name><ns1:Male>true</ns1:Male></ns2:person><ns2:salary>1.0E+6</ns2:salary><ns2:ID>12345</ns2:ID></ns2:x_Employee></SOAP-ENV:Body></SOAP-ENV:Envelope>
<?xml version="1.0" encoding="UTF-8"?>
-<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://soapinterop.org/person"
xmlns:ns2="http://soapinterop.org/employee"><SOAP-ENV:Body><ns2:result_Employee><ns2:person><ns1:Name>Shane</ns1:Name><ns1:Male>true</ns1:Male></ns2:person><ns2:salary>1000000</ns2:salary><ns2:ID>12345</ns2:ID></ns2:result_Employee></SOAP-ENV:Body></SOAP-ENV:Envelope>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://soapinterop.org/person"
xmlns:ns2="http://soapinterop.org/employee"><SOAP-ENV:Body><ns2:result_Employee><ns2:person><ns1:Name>Shane</ns1:Name><ns1:Male>true</ns1:Male></ns2:person><ns2:salary>1.0E+6</ns2:salary><ns2:ID>12345</ns2:ID></ns2:result_Employee></SOAP-ENV:Body></SOAP-ENV:Envelope>
ok
http://cvs.php.net/viewvc.cgi/php-src/ext/soap/tests/bugs/bug39815.phpt?view=markup&rev=1.1
Index: php-src/ext/soap/tests/bugs/bug39815.phpt
+++ php-src/ext/soap/tests/bugs/bug39815.phpt
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php