diff options
| author | Juan Basso <jrbasso@gmail.com> | 2014-03-29 19:41:48 -0400 | 
|---|---|---|
| committer | Stanislav Malyshev <stas@php.net> | 2015-01-19 00:46:02 -0800 | 
| commit | ac7cfad3b54b04b7ff2d0e4bfd26e8b61d233613 (patch) | |
| tree | 1c24d1096945799cf9b856a0749b29b89a3ef595 /ext/json/json.c | |
| parent | 6de149e47c1e9050fef39640e2da8a230fda76cf (diff) | |
| download | php-git-ac7cfad3b54b04b7ff2d0e4bfd26e8b61d233613.tar.gz | |
Fixed bug #50224 where float without decimals were converted to integer
Diffstat (limited to 'ext/json/json.c')
| -rw-r--r-- | ext/json/json.c | 37 | 
1 files changed, 29 insertions, 8 deletions
| diff --git a/ext/json/json.c b/ext/json/json.c index f9765ab3ff..a28f99e10e 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -31,6 +31,14 @@  #include "php_json.h"  #include <zend_exceptions.h> +#include <float.h> +#if defined(DBL_MANT_DIG) && defined(DBL_MIN_EXP) +#define NUM_BUF_SIZE (3 + DBL_MANT_DIG - DBL_MIN_EXP) +#else +#define NUM_BUF_SIZE 1080 +#endif + +  static PHP_MINFO_FUNCTION(json);  static PHP_FUNCTION(json_encode);  static PHP_FUNCTION(json_decode); @@ -103,6 +111,7 @@ static PHP_MINIT_FUNCTION(json)  	REGISTER_LONG_CONSTANT("JSON_PRETTY_PRINT", PHP_JSON_PRETTY_PRINT, CONST_CS | CONST_PERSISTENT);  	REGISTER_LONG_CONSTANT("JSON_UNESCAPED_UNICODE", PHP_JSON_UNESCAPED_UNICODE, CONST_CS | CONST_PERSISTENT);  	REGISTER_LONG_CONSTANT("JSON_PARTIAL_OUTPUT_ON_ERROR", PHP_JSON_PARTIAL_OUTPUT_ON_ERROR, CONST_CS | CONST_PERSISTENT); +	REGISTER_LONG_CONSTANT("JSON_PRESERVE_ZERO_FRACTION", PHP_JSON_PRESERVE_ZERO_FRACTION, CONST_CS | CONST_PERSISTENT);  	REGISTER_LONG_CONSTANT("JSON_ERROR_NONE", PHP_JSON_ERROR_NONE, CONST_CS | CONST_PERSISTENT);  	REGISTER_LONG_CONSTANT("JSON_ERROR_DEPTH", PHP_JSON_ERROR_DEPTH, CONST_CS | CONST_PERSISTENT); @@ -420,10 +429,17 @@ static void json_escape_string(smart_str *buf, char *s, int len, int options TSR  				smart_str_append_long(buf, p);  			} else if (type == IS_DOUBLE) {  				if (!zend_isinf(d) && !zend_isnan(d)) { -					char *tmp; -					int l = spprintf(&tmp, 0, "%.*k", (int) EG(precision), d); -					smart_str_appendl(buf, tmp, l); -					efree(tmp); +					char num[NUM_BUF_SIZE]; +					int l; + +					php_gcvt(d, EG(precision), '.', 'e', (char *)num); +					l = strlen(num); +					if (options & PHP_JSON_PRESERVE_ZERO_FRACTION && strchr(num, '.') == NULL && l < NUM_BUF_SIZE - 2) { +						num[l++] = '.'; +						num[l++] = '0'; +						num[l] = '\0'; +					} +					smart_str_appendl(buf, num, l);  				} else {  					JSON_G(error_code) = PHP_JSON_ERROR_INF_OR_NAN;  					smart_str_appendc(buf, '0'); @@ -624,14 +640,19 @@ PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_  		case IS_DOUBLE:  			{ -				char *d = NULL; +				char num[NUM_BUF_SIZE];  				int len;  				double dbl = Z_DVAL_P(val);  				if (!zend_isinf(dbl) && !zend_isnan(dbl)) { -					len = spprintf(&d, 0, "%.*k", (int) EG(precision), dbl); -					smart_str_appendl(buf, d, len); -					efree(d); +					php_gcvt(dbl, EG(precision), '.', 'e', (char *)num); +					len = strlen(num); +					if (options & PHP_JSON_PRESERVE_ZERO_FRACTION && strchr(num, '.') == NULL && len < NUM_BUF_SIZE - 2) { +						num[len++] = '.'; +						num[len++] = '0'; +						num[len] = '\0'; +					} +					smart_str_appendl(buf, num, len);  				} else {  					JSON_G(error_code) = PHP_JSON_ERROR_INF_OR_NAN;  					smart_str_appendc(buf, '0'); | 
