From:             fredrik at wangel dot net
Operating system: Irrelevant
PHP version:      6CVS-2006-12-13 (snap)
PHP Bug Type:     SOAP related
Bug description:  to_zval_double() in ext/soap/php_encoding.c is not 
locale-independent

Description:
------------
[Note: This is an inherent problem within a PHP extension's C code, not
with a PHP script]

Problem: The SOAPClient/SOAPServer converts xsd:float values in a
locale-dependent fashion, causing serious issues when the caller's locale
is not English.

According to "XML Schema Part 2: Datatypes", a decimal (either xsd:float
or xsd:double) is always written using a period (.) as a decimal indicator
[See http://www.w3.org/TR/xmlschema-2/#decimal]

However, SOAPServer writes decimals using the current locale's
(LC_NUMERIC) formatting rules, which is a violation of the standard.
Likewise, on the client side, the function to_zval_double() in
ext/soap/php_encoding.c uses atof() which parses a string according to the
current locale. Since the server and client can have totally different
settings for locale, the conversion fails.

Hence, if the SOAP server's locale is set to "sv_SE" (Swedish) or some
other language that does not use period as decimal indicator, and the SOAP
client is in English, the resulting float is truncated into an integer
value.

Suggested fix is to either either temporarily change LC_NUMERIC [via
setlocale()] into "POSIX" (or "C"), or use zend_strtod() for conversion
from XML. When converting to XML [using convert_to_string()] the simplest
solution should be to change LC_NUMERIC temporarily, since zend_sprintf()
also uses current locale settings.

PLEASE NOTE: If you do not have the locales from the example (sv_SE and
en_US) on your test server, this will likely fallback into C locale, and
thus the result always looks good. Verify that your test server formats
123.456 into "123,456". Try "se" or "Swedish" if "sv_SE" fails.

Reproduce code:
---------------
-- SERVER --
class Server {function getValue(){return (float)123.456;}}
setlocale(LC_ALL,"sv_SE");
$server = new SoapServer(null,array('uri'=>'http://localhost/',
'soap_version'=>SOAP_1_2, 'encoding'=>'ISO-8859-1'));
$server->setClass("Server");
$server->handle();

--- CLIENT --
$client = new
SoapClient(null,array('location'=>'http://localhost/soap/Server.php',
'uri'=>'http://localhost/', 'soap_version'=>SOAP_1_2,
'encoding'=>'ISO-8859-1'));
header("Content-Type: text/plain; charset=ISO-8859-1");
setlocale(LC_ALL,"sv_SE");
print((float)123.456 . "\n");
setlocale(LC_ALL,"en_US");
$value = $client->getValue();
var_dump($value);


Expected result:
----------------
123,456
float(123.456)

Actual result:
--------------
123,456
float(123)

-- 
Edit bug report at http://bugs.php.net/?id=39815&edit=1
-- 
Try a CVS snapshot (PHP 4.4): 
http://bugs.php.net/fix.php?id=39815&r=trysnapshot44
Try a CVS snapshot (PHP 5.2): 
http://bugs.php.net/fix.php?id=39815&r=trysnapshot52
Try a CVS snapshot (PHP 6.0): 
http://bugs.php.net/fix.php?id=39815&r=trysnapshot60
Fixed in CVS:                 http://bugs.php.net/fix.php?id=39815&r=fixedcvs
Fixed in release:             
http://bugs.php.net/fix.php?id=39815&r=alreadyfixed
Need backtrace:               http://bugs.php.net/fix.php?id=39815&r=needtrace
Need Reproduce Script:        http://bugs.php.net/fix.php?id=39815&r=needscript
Try newer version:            http://bugs.php.net/fix.php?id=39815&r=oldversion
Not developer issue:          http://bugs.php.net/fix.php?id=39815&r=support
Expected behavior:            http://bugs.php.net/fix.php?id=39815&r=notwrong
Not enough info:              
http://bugs.php.net/fix.php?id=39815&r=notenoughinfo
Submitted twice:              
http://bugs.php.net/fix.php?id=39815&r=submittedtwice
register_globals:             http://bugs.php.net/fix.php?id=39815&r=globals
PHP 3 support discontinued:   http://bugs.php.net/fix.php?id=39815&r=php3
Daylight Savings:             http://bugs.php.net/fix.php?id=39815&r=dst
IIS Stability:                http://bugs.php.net/fix.php?id=39815&r=isapi
Install GNU Sed:              http://bugs.php.net/fix.php?id=39815&r=gnused
Floating point limitations:   http://bugs.php.net/fix.php?id=39815&r=float
No Zend Extensions:           http://bugs.php.net/fix.php?id=39815&r=nozend
MySQL Configuration Error:    http://bugs.php.net/fix.php?id=39815&r=mysqlcfg

Reply via email to