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'); |