|
30 | 30 | #include "php_json.h"
|
31 | 31 | #include <zend_exceptions.h>
|
32 | 32 |
|
| 33 | +/* double limits */ |
| 34 | +#include <float.h> |
| 35 | +#if defined(DBL_MANT_DIG) && defined(DBL_MIN_EXP) |
| 36 | +#define PHP_JSON_DOUBLE_MAX_LENGTH (1 + DBL_MANT_DIG - DBL_MIN_EXP) |
| 37 | +#else |
| 38 | +#define PHP_JSON_DOUBLE_MAX_LENGTH 1078 |
| 39 | +#endif |
| 40 | + |
33 | 41 | ZEND_DECLARE_MODULE_GLOBALS(json)
|
34 | 42 |
|
35 | 43 | static const char digits[] = "0123456789abcdef";
|
@@ -87,6 +95,21 @@ static inline void php_json_pretty_print_indent(smart_str *buf, int options) /*
|
87 | 95 |
|
88 | 96 | /* }}} */
|
89 | 97 |
|
| 98 | +static inline void php_json_encode_double(smart_str *buf, double d) /* {{{ */ |
| 99 | +{ |
| 100 | + if (!zend_isinf(d) && !zend_isnan(d)) { |
| 101 | + size_t len; |
| 102 | + char num[PHP_JSON_DOUBLE_MAX_LENGTH]; |
| 103 | + php_gcvt(d, EG(precision), '.', 'e', &num[0]); |
| 104 | + len = strlen(num); |
| 105 | + smart_str_appendl(buf, num, len); |
| 106 | + } else { |
| 107 | + JSON_G(error_code) = PHP_JSON_ERROR_INF_OR_NAN; |
| 108 | + smart_str_appendc(buf, '0'); |
| 109 | + } |
| 110 | +} |
| 111 | +/* }}} */ |
| 112 | + |
90 | 113 | static void php_json_encode_array(smart_str *buf, zval *val, int options) /* {{{ */
|
91 | 114 | {
|
92 | 115 | int i, r, need_comma = 0;
|
@@ -267,15 +290,7 @@ static void php_json_escape_string(smart_str *buf, char *s, size_t len, int opti
|
267 | 290 | if (type == IS_LONG) {
|
268 | 291 | smart_str_append_long(buf, p);
|
269 | 292 | } else if (type == IS_DOUBLE) {
|
270 |
| - if (!zend_isinf(d) && !zend_isnan(d)) { |
271 |
| - char *tmp; |
272 |
| - int l = spprintf(&tmp, 0, "%.*k", (int) EG(precision), d); |
273 |
| - smart_str_appendl(buf, tmp, l); |
274 |
| - efree(tmp); |
275 |
| - } else { |
276 |
| - JSON_G(error_code) = PHP_JSON_ERROR_INF_OR_NAN; |
277 |
| - smart_str_appendc(buf, '0'); |
278 |
| - } |
| 293 | + php_json_encode_double(buf, d); |
279 | 294 | }
|
280 | 295 | return;
|
281 | 296 | }
|
@@ -487,20 +502,7 @@ void php_json_encode_zval(smart_str *buf, zval *val, int options) /* {{{ */
|
487 | 502 | break;
|
488 | 503 |
|
489 | 504 | case IS_DOUBLE:
|
490 |
| - { |
491 |
| - char *d = NULL; |
492 |
| - int len; |
493 |
| - double dbl = Z_DVAL_P(val); |
494 |
| - |
495 |
| - if (!zend_isinf(dbl) && !zend_isnan(dbl)) { |
496 |
| - len = spprintf(&d, 0, "%.*k", (int) EG(precision), dbl); |
497 |
| - smart_str_appendl(buf, d, len); |
498 |
| - efree(d); |
499 |
| - } else { |
500 |
| - JSON_G(error_code) = PHP_JSON_ERROR_INF_OR_NAN; |
501 |
| - smart_str_appendc(buf, '0'); |
502 |
| - } |
503 |
| - } |
| 505 | + php_json_encode_double(buf, Z_DVAL_P(val)); |
504 | 506 | break;
|
505 | 507 |
|
506 | 508 | case IS_STRING:
|
|
0 commit comments