diff options
author | Stanislav Malyshev <stas@php.net> | 2015-01-19 10:05:57 -0800 |
---|---|---|
committer | Stanislav Malyshev <stas@php.net> | 2015-01-19 10:05:57 -0800 |
commit | 1fdd558e39beeeca9166eef4311b98f1926f642b (patch) | |
tree | 8e0ffff2fdfa5ff5debb65bed15e5fdee5ed6d9f /ext/json/json.c | |
parent | 1b53a99fbf847ce346e24bb2f25a0ca2298b94a1 (diff) | |
parent | ac7cfad3b54b04b7ff2d0e4bfd26e8b61d233613 (diff) | |
download | php-git-1fdd558e39beeeca9166eef4311b98f1926f642b.tar.gz |
Merge branch 'PHP-5.6'
* PHP-5.6:
Fixed bug #50224 where float without decimals were converted to integer
Updated NEWS for #68371
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 22c6353803..baad4bc399 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); @@ -407,10 +416,17 @@ static void json_escape_string(smart_str *buf, char *s, size_t len, int options) 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'); @@ -627,14 +643,19 @@ again: 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'); |