From 71ef7c1d7eaa1b0465a1c8b79860d80156886e8d Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Wed, 5 Aug 2015 08:12:10 +0900 Subject: [PATCH 01/10] Initial patch for 0 mode float conversion. The magic number is better to be improved. Any suggestion where to define it? --- ext/json/json_encoder.c | 6 +++++- ext/standard/var.c | 31 +++++++++++++++++-------------- main/main.c | 19 ++++++++++++++++++- main/snprintf.c | 18 ++++++++++++++++-- main/snprintf.h | 1 + 5 files changed, 57 insertions(+), 18 deletions(-) diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index c3aa34862649b..a3a739b997b06 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -104,7 +104,11 @@ static inline void php_json_encode_double(smart_str *buf, double d, int options) { size_t len; char num[PHP_JSON_DOUBLE_MAX_LENGTH]; - php_gcvt(d, (int)EG(precision), '.', 'e', &num[0]); + if (PG(serialize_precision) == -1) { + php_0cvt(d, 17, '.', 'e', num); + } else { + php_gcvt(d, PG(serialize_precision), '.', 'e', num); + } len = strlen(num); if (options & PHP_JSON_PRESERVE_ZERO_FRACTION && strchr(num, '.') == NULL && len < PHP_JSON_DOUBLE_MAX_LENGTH - 2) { num[len++] = '.'; diff --git a/ext/standard/var.c b/ext/standard/var.c index 7eaff117149a7..95f3341e9401c 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -452,8 +452,7 @@ static void php_object_element_export(zval *zv, zend_ulong index, zend_string *k PHPAPI void php_var_export_ex(zval *struc, int level, smart_str *buf) /* {{{ */ { HashTable *myht; - char *tmp_str; - size_t tmp_len; + char tmp_str[2048]; /* Use the same magic number of spprintf.c NUM_BUF_SIZE */ zend_string *ztmp, *ztmp2; zend_ulong index; zend_string *key; @@ -474,9 +473,12 @@ PHPAPI void php_var_export_ex(zval *struc, int level, smart_str *buf) /* {{{ */ smart_str_append_long(buf, Z_LVAL_P(struc)); break; case IS_DOUBLE: - tmp_len = spprintf(&tmp_str, 0,"%.*H", PG(serialize_precision), Z_DVAL_P(struc)); - smart_str_appendl(buf, tmp_str, tmp_len); - efree(tmp_str); + if (PG(serialize_precision < 0)) { + php_0cvt(Z_DVAL_P(struc), 17, '.', 'E', tmp_str); + } else { + php_gcvt(Z_DVAL_P(struc), (int)PG(serialize_precision), '.', 'E', tmp_str); + } + smart_str_appends(buf, tmp_str); break; case IS_STRING: ztmp = php_addcslashes(Z_STR_P(struc), 0, "'\\", 2); @@ -817,16 +819,17 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_ return; case IS_DOUBLE: { - char *s; - - smart_str_appendl(buf, "d:", 2); - s = (char *) safe_emalloc(PG(serialize_precision), 1, MAX_LENGTH_OF_DOUBLE + 1); - php_gcvt(Z_DVAL_P(struc), (int)PG(serialize_precision), '.', 'E', s); - smart_str_appends(buf, s); - smart_str_appendc(buf, ';'); - efree(s); - return; + char tmp_str[2048]; /* Use the same magic number of spprintf.c NUM_BUF_SIZE */ + smart_str_appendl(buf, "d:", 2); + if (PG(serialize_precision < 0)) { + php_0cvt(Z_DVAL_P(struc), 17, '.', 'E', tmp_str); + } else { + php_gcvt(Z_DVAL_P(struc), (int)PG(serialize_precision), '.', 'E', tmp_str); } + smart_str_appends(buf, tmp_str); + smart_str_appendc(buf, ';'); + return; + } case IS_STRING: php_var_serialize_string(buf, Z_STRVAL_P(struc), Z_STRLEN_P(struc)); diff --git a/main/main.c b/main/main.c index 26b2531724187..f2bb0ed010388 100644 --- a/main/main.c +++ b/main/main.c @@ -140,6 +140,23 @@ static PHP_INI_MH(OnSetPrecision) } /* }}} */ +/* {{{ PHP_INI_MH + */ +static PHP_INI_MH(OnSetSerializePrecision) +{ + zend_long i; + + ZEND_ATOL(i, ZSTR_VAL(new_value)); + if (i >= -1) { + PG(serialize_precision) = i; + return SUCCESS; + } else { + return FAILURE; + } +} +/* }}} */ + + /* {{{ PHP_INI_MH */ static PHP_INI_MH(OnChangeMemoryLimit) @@ -516,7 +533,7 @@ PHP_INI_BEGIN() STD_PHP_INI_BOOLEAN("track_errors", "0", PHP_INI_ALL, OnUpdateBool, track_errors, php_core_globals, core_globals) STD_PHP_INI_ENTRY("unserialize_callback_func", NULL, PHP_INI_ALL, OnUpdateString, unserialize_callback_func, php_core_globals, core_globals) - STD_PHP_INI_ENTRY("serialize_precision", "17", PHP_INI_ALL, OnUpdateLongGEZero, serialize_precision, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("serialize_precision", "-1", PHP_INI_ALL, OnSetSerializePrecision, serialize_precision, php_core_globals, core_globals) STD_PHP_INI_ENTRY("arg_separator.output", "&", PHP_INI_ALL, OnUpdateStringUnempty, arg_separator.output, php_core_globals, core_globals) STD_PHP_INI_ENTRY("arg_separator.input", "&", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateStringUnempty, arg_separator.input, php_core_globals, core_globals) diff --git a/main/snprintf.c b/main/snprintf.c index aff6a8cbdad5a..32272dd279ded 100644 --- a/main/snprintf.c +++ b/main/snprintf.c @@ -139,12 +139,12 @@ static inline char *php_fcvt(double value, int ndigit, int *decpt, int *sign) /* } /* }}} */ -PHPAPI char *php_gcvt(double value, int ndigit, char dec_point, char exponent, char *buf) /* {{{ */ +static inline char *_php_cvt(double value, int ndigit, char dec_point, char exponent, char *buf, int mode) /* {{{ */ { char *digits, *dst, *src; int i, decpt, sign; - digits = zend_dtoa(value, 2, ndigit, &decpt, &sign, NULL); + digits = zend_dtoa(value, mode, ndigit, &decpt, &sign, NULL); if (decpt == 9999) { /* * Infinity or NaN, convert to inf or nan with sign. @@ -234,6 +234,20 @@ PHPAPI char *php_gcvt(double value, int ndigit, char dec_point, char exponent, c } /* }}} */ +PHPAPI char *php_gcvt(double value, int ndigit, char dec_point, char exponent, char *buf) /* {{{ */ +{ + return _php_cvt(value, ndigit, dec_point, exponent, buf, 2); +} +/* }}} */ + +PHPAPI char *php_0cvt(double value, int ndigit, char dec_point, char exponent, char *buf) /* {{{ */ +{ + return _php_cvt(value, ndigit, dec_point, exponent, buf, 0); +} +/* }}} */ + + + /* {{{ Apache license */ /* ==================================================================== * Copyright (c) 1995-1998 The Apache Group. All rights reserved. diff --git a/main/snprintf.h b/main/snprintf.h index c40147ec2d6a0..105e08725ffa8 100644 --- a/main/snprintf.h +++ b/main/snprintf.h @@ -86,6 +86,7 @@ PHPAPI int ap_php_vasprintf(char **buf, const char *format, va_list ap); PHPAPI int ap_php_asprintf(char **buf, const char *format, ...); PHPAPI int php_sprintf (char* s, const char* format, ...) PHP_ATTRIBUTE_FORMAT(printf, 2, 3); PHPAPI char * php_gcvt(double value, int ndigit, char dec_point, char exponent, char *buf); +PHPAPI char * php_0cvt(double value, int ndigit, char dec_point, char exponent, char *buf); PHPAPI char * php_conv_fp(register char format, register double num, boolean_e add_dp, int precision, char dec_point, bool_int * is_negative, char *buf, size_t *len); From 08ac858676daa0b2e4e6ec2b58d3d689403db41f Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Wed, 5 Aug 2015 14:36:37 +0900 Subject: [PATCH 02/10] Add JSON_G(precision) --- ext/json/json.c | 38 +++++++++++++++++++++++++++++++++++++- ext/json/json_encoder.c | 4 ++-- ext/json/php_json.h | 1 + 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/ext/json/json.c b/ext/json/json.c index 79b9278513ec7..3457fa29545fa 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -92,11 +92,37 @@ static const zend_function_entry json_serializable_interface[] = { }; /* }}} */ +/* {{{ PHP_INI_MH + */ +static PHP_INI_MH(OnSetJsonPrecision) +{ + zend_long i; + + ZEND_ATOL(i, ZSTR_VAL(new_value)); + if (i >= -1) { + JSON_G(precision) = i; + return SUCCESS; + } else { + return FAILURE; + } +} +/* }}} */ + + +/* {{{ PHP_INI + */ +PHP_INI_BEGIN() +STD_PHP_INI_ENTRY("json.precision", "-1", PHP_INI_ALL, OnSetJsonPrecision, precision, zend_json_globals, json_globals) +PHP_INI_END() +/* }}} */ + /* {{{ MINIT */ static PHP_MINIT_FUNCTION(json) { zend_class_entry ce; + REGISTER_INI_ENTRIES(); + INIT_CLASS_ENTRY(ce, "JsonSerializable", json_serializable_interface); php_json_serializable_ce = zend_register_internal_interface(&ce); @@ -144,6 +170,16 @@ static PHP_GINIT_FUNCTION(json) } /* }}} */ +/* {{{ PHP_MSHUTDOWN_FUNCTION +*/ +static PHP_MSHUTDOWN_FUNCTION(json) +{ + UNREGISTER_INI_ENTRIES(); + + return SUCCESS; +} +/* }}} */ + /* {{{ json_module_entry */ @@ -152,7 +188,7 @@ zend_module_entry json_module_entry = { "json", json_functions, PHP_MINIT(json), - NULL, + PHP_MSHUTDOWN(json), NULL, NULL, PHP_MINFO(json), diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index a3a739b997b06..05a9cab99bcf0 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -104,10 +104,10 @@ static inline void php_json_encode_double(smart_str *buf, double d, int options) { size_t len; char num[PHP_JSON_DOUBLE_MAX_LENGTH]; - if (PG(serialize_precision) == -1) { + if (JSON_G(precision) == -1) { php_0cvt(d, 17, '.', 'e', num); } else { - php_gcvt(d, PG(serialize_precision), '.', 'e', num); + php_gcvt(d, JSON_G(precision), '.', 'e', num); } len = strlen(num); if (options & PHP_JSON_PRESERVE_ZERO_FRACTION && strchr(num, '.') == NULL && len < PHP_JSON_DOUBLE_MAX_LENGTH - 2) { diff --git a/ext/json/php_json.h b/ext/json/php_json.h index fccab62fb8dda..783c8af59a722 100644 --- a/ext/json/php_json.h +++ b/ext/json/php_json.h @@ -76,6 +76,7 @@ typedef enum { #define PHP_JSON_PARSER_DEFAULT_DEPTH 512 ZEND_BEGIN_MODULE_GLOBALS(json) + zend_long precision; int encoder_depth; int encode_max_depth; php_json_error_code error_code; From 0e32bc72a93e99872b99a2b498f75a84fae70d50 Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Sun, 30 Aug 2015 17:13:24 +0900 Subject: [PATCH 03/10] Simply use ndigit for flag for zend_dtoa mode --- ext/json/json_encoder.c | 7 ++----- ext/standard/var.c | 12 ++---------- main/snprintf.c | 18 +++++------------- main/snprintf.h | 1 - 4 files changed, 9 insertions(+), 29 deletions(-) diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index 05a9cab99bcf0..5ee41b738a2c0 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -104,11 +104,8 @@ static inline void php_json_encode_double(smart_str *buf, double d, int options) { size_t len; char num[PHP_JSON_DOUBLE_MAX_LENGTH]; - if (JSON_G(precision) == -1) { - php_0cvt(d, 17, '.', 'e', num); - } else { - php_gcvt(d, JSON_G(precision), '.', 'e', num); - } + + php_gcvt(d, JSON_G(precision), '.', 'e', num); len = strlen(num); if (options & PHP_JSON_PRESERVE_ZERO_FRACTION && strchr(num, '.') == NULL && len < PHP_JSON_DOUBLE_MAX_LENGTH - 2) { num[len++] = '.'; diff --git a/ext/standard/var.c b/ext/standard/var.c index 95f3341e9401c..8c50750051a4f 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -473,11 +473,7 @@ PHPAPI void php_var_export_ex(zval *struc, int level, smart_str *buf) /* {{{ */ smart_str_append_long(buf, Z_LVAL_P(struc)); break; case IS_DOUBLE: - if (PG(serialize_precision < 0)) { - php_0cvt(Z_DVAL_P(struc), 17, '.', 'E', tmp_str); - } else { - php_gcvt(Z_DVAL_P(struc), (int)PG(serialize_precision), '.', 'E', tmp_str); - } + php_gcvt(Z_DVAL_P(struc), (int)PG(serialize_precision), '.', 'E', tmp_str); smart_str_appends(buf, tmp_str); break; case IS_STRING: @@ -821,11 +817,7 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_ case IS_DOUBLE: { char tmp_str[2048]; /* Use the same magic number of spprintf.c NUM_BUF_SIZE */ smart_str_appendl(buf, "d:", 2); - if (PG(serialize_precision < 0)) { - php_0cvt(Z_DVAL_P(struc), 17, '.', 'E', tmp_str); - } else { - php_gcvt(Z_DVAL_P(struc), (int)PG(serialize_precision), '.', 'E', tmp_str); - } + php_gcvt(Z_DVAL_P(struc), (int)PG(serialize_precision), '.', 'E', tmp_str); smart_str_appends(buf, tmp_str); smart_str_appendc(buf, ';'); return; diff --git a/main/snprintf.c b/main/snprintf.c index 32272dd279ded..b80c055ae493e 100644 --- a/main/snprintf.c +++ b/main/snprintf.c @@ -139,11 +139,15 @@ static inline char *php_fcvt(double value, int ndigit, int *decpt, int *sign) /* } /* }}} */ -static inline char *_php_cvt(double value, int ndigit, char dec_point, char exponent, char *buf, int mode) /* {{{ */ +PHPAPI char *php_gcvt(double value, int ndigit, char dec_point, char exponent, char *buf) /* {{{ */ { char *digits, *dst, *src; int i, decpt, sign; + int mode = ndigit > 0 ? 2 : 0; + if (mode == 0) { + ndigit = 17; + } digits = zend_dtoa(value, mode, ndigit, &decpt, &sign, NULL); if (decpt == 9999) { /* @@ -234,18 +238,6 @@ static inline char *_php_cvt(double value, int ndigit, char dec_point, char expo } /* }}} */ -PHPAPI char *php_gcvt(double value, int ndigit, char dec_point, char exponent, char *buf) /* {{{ */ -{ - return _php_cvt(value, ndigit, dec_point, exponent, buf, 2); -} -/* }}} */ - -PHPAPI char *php_0cvt(double value, int ndigit, char dec_point, char exponent, char *buf) /* {{{ */ -{ - return _php_cvt(value, ndigit, dec_point, exponent, buf, 0); -} -/* }}} */ - /* {{{ Apache license */ diff --git a/main/snprintf.h b/main/snprintf.h index 105e08725ffa8..c40147ec2d6a0 100644 --- a/main/snprintf.h +++ b/main/snprintf.h @@ -86,7 +86,6 @@ PHPAPI int ap_php_vasprintf(char **buf, const char *format, va_list ap); PHPAPI int ap_php_asprintf(char **buf, const char *format, ...); PHPAPI int php_sprintf (char* s, const char* format, ...) PHP_ATTRIBUTE_FORMAT(printf, 2, 3); PHPAPI char * php_gcvt(double value, int ndigit, char dec_point, char exponent, char *buf); -PHPAPI char * php_0cvt(double value, int ndigit, char dec_point, char exponent, char *buf); PHPAPI char * php_conv_fp(register char format, register double num, boolean_e add_dp, int precision, char dec_point, bool_int * is_negative, char *buf, size_t *len); From 75eb88c83f12c7627ca8fd4308bbd0b6d5b925c8 Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Mon, 31 Aug 2015 15:50:15 +0900 Subject: [PATCH 04/10] Enable 0 mode for echo/print --- main/main.c | 2 +- main/spprintf.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/main/main.c b/main/main.c index f2bb0ed010388..92fd8d0b79a43 100644 --- a/main/main.c +++ b/main/main.c @@ -131,7 +131,7 @@ static PHP_INI_MH(OnSetPrecision) zend_long i; ZEND_ATOL(i, ZSTR_VAL(new_value)); - if (i >= 0) { + if (i >= -1) { EG(precision) = i; return SUCCESS; } else { diff --git a/main/spprintf.c b/main/spprintf.c index 4594fb7605ebd..af2420eb02de9 100644 --- a/main/spprintf.c +++ b/main/spprintf.c @@ -306,8 +306,8 @@ static void xbuf_format_converter(void *xbuf, zend_bool is_char, const char *fmt } else if (*fmt == '*') { precision = va_arg(ap, int); fmt++; - if (precision < 0) - precision = 0; + if (precision < -1) + precision = -1; } else precision = 0; From 64cc35bde86f4797673b80db80c7b83d076389e3 Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Mon, 31 Aug 2015 16:10:32 +0900 Subject: [PATCH 05/10] Add cast --- ext/json/json_encoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index 5ee41b738a2c0..16de60ea2736b 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -105,7 +105,7 @@ static inline void php_json_encode_double(smart_str *buf, double d, int options) size_t len; char num[PHP_JSON_DOUBLE_MAX_LENGTH]; - php_gcvt(d, JSON_G(precision), '.', 'e', num); + php_gcvt(d, (int)JSON_G(precision), '.', 'e', num); len = strlen(num); if (options & PHP_JSON_PRESERVE_ZERO_FRACTION && strchr(num, '.') == NULL && len < PHP_JSON_DOUBLE_MAX_LENGTH - 2) { num[len++] = '.'; From 7fc62f5e071ffc4e97b79cb081ad8256f1f319fa Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Mon, 31 Aug 2015 18:59:32 +0900 Subject: [PATCH 06/10] Fix mode when precision=0. Add test --- main/snprintf.c | 2 +- tests/basic/precision.phpt | 171 +++++++++++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 tests/basic/precision.phpt diff --git a/main/snprintf.c b/main/snprintf.c index b80c055ae493e..0ecceda593388 100644 --- a/main/snprintf.c +++ b/main/snprintf.c @@ -143,7 +143,7 @@ PHPAPI char *php_gcvt(double value, int ndigit, char dec_point, char exponent, c { char *digits, *dst, *src; int i, decpt, sign; - int mode = ndigit > 0 ? 2 : 0; + int mode = ndigit >= 0 ? 2 : 0; if (mode == 0) { ndigit = 17; diff --git a/tests/basic/precision.phpt b/tests/basic/precision.phpt new file mode 100644 index 0000000000000..1d7dbdd4438ae --- /dev/null +++ b/tests/basic/precision.phpt @@ -0,0 +1,171 @@ +--TEST-- +precision setting test +--INI-- +precision=14 +serialize_precision=17 +--FILE-- + 123456789.01234567, + 1 => 3.3333333333333335, + 2 => 9.87E+102, +) +INI +0 +0 +OUTPUTS +1.0E+8 3 1.0E+103 +1.0E+8 3 1.0E+103 +string(47) "a:3:{i:0;d:1.0E+8;i:1;d:3.0E+0;i:2;d:1.0E+103;}" +array ( + 0 => 1.0E+8, + 1 => 3.0E+0, + 2 => 1.0E+103, +) +INI +9 +9 +OUTPUTS +123456789 3.33333333 9.87E+102 +123456789 3.33333333 9.87E+102 +string(55) "a:3:{i:0;d:123456789;i:1;d:3.33333333;i:2;d:9.87E+102;}" +array ( + 0 => 123456789, + 1 => 3.33333333, + 2 => 9.87E+102, +) +INI +14 +14 +OUTPUTS +123456789.01235 3.3333333333333 9.87E+102 +123456789.01235 3.3333333333333 9.87E+102 +string(66) "a:3:{i:0;d:123456789.01235;i:1;d:3.3333333333333;i:2;d:9.87E+102;}" +array ( + 0 => 123456789.01235, + 1 => 3.3333333333333, + 2 => 9.87E+102, +) +INI +17 +17 +OUTPUTS +123456789.01234567 3.3333333333333335 9.8700000000000007E+102 +123456789.01234567 3.3333333333333335 9.8700000000000007E+102 +string(86) "a:3:{i:0;d:123456789.01234567;i:1;d:3.3333333333333335;i:2;d:9.8700000000000007E+102;}" +array ( + 0 => 123456789.01234567, + 1 => 3.3333333333333335, + 2 => 9.8700000000000007E+102, +) +INI +25 +25 +OUTPUTS +123456789.0123456716537476 3.33333333333333348136307 9.870000000000000687310143E+102 +123456789.0123456716537476 3.33333333333333348136307 9.870000000000000687310143E+102 +string(109) "a:3:{i:0;d:123456789.0123456716537476;i:1;d:3.33333333333333348136307;i:2;d:9.870000000000000687310143E+102;}" +array ( + 0 => 123456789.0123456716537476, + 1 => 3.33333333333333348136307, + 2 => 9.870000000000000687310143E+102, +) +INI +100 +100 +OUTPUTS +123456789.01234567165374755859375 3.333333333333333481363069950020872056484222412109375 9.87000000000000068731014283095442748328521861543465424509123736073120616987695396574376473706259651E+102 +123456789.01234567165374755859375 3.333333333333333481363069950020872056484222412109375 9.87000000000000068731014283095442748328521861543465424509123736073120616987695396574376473706259651E+102 +string(218) "a:3:{i:0;d:123456789.01234567165374755859375;i:1;d:3.333333333333333481363069950020872056484222412109375;i:2;d:9.87000000000000068731014283095442748328521861543465424509123736073120616987695396574376473706259651E+102;}" +array ( + 0 => 123456789.01234567165374755859375, + 1 => 3.333333333333333481363069950020872056484222412109375, + 2 => 9.87000000000000068731014283095442748328521861543465424509123736073120616987695396574376473706259651E+102, +) From 9e61d2f3969ab75126219400cb9b2cdc124a2deb Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Mon, 31 Aug 2015 19:07:17 +0900 Subject: [PATCH 07/10] Remove unneeded output from test --- tests/basic/precision.phpt | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/tests/basic/precision.phpt b/tests/basic/precision.phpt index 1d7dbdd4438ae..097e2c4eb3641 100644 --- a/tests/basic/precision.phpt +++ b/tests/basic/precision.phpt @@ -14,7 +14,6 @@ echo ini_get('precision'), PHP_EOL; echo ini_get('serialize_precision'), PHP_EOL; echo "OUTPUTS".PHP_EOL; echo join($v, ' ').PHP_EOL; -print join($v, ' ').PHP_EOL; var_dump(serialize($v)); var_export($v);echo PHP_EOL; @@ -26,7 +25,6 @@ echo ini_get('precision'), PHP_EOL; echo ini_get('serialize_precision'), PHP_EOL; echo "OUTPUTS".PHP_EOL; echo join($v, ' ').PHP_EOL; -print join($v, ' ').PHP_EOL; var_dump(serialize($v)); var_export($v);echo PHP_EOL; @@ -37,7 +35,6 @@ echo ini_get('precision'), PHP_EOL; echo ini_get('serialize_precision'), PHP_EOL; echo "OUTPUTS".PHP_EOL; echo join($v, ' ').PHP_EOL; -print join($v, ' ').PHP_EOL; var_dump(serialize($v)); var_export($v);echo PHP_EOL; @@ -48,7 +45,6 @@ echo ini_get('precision'), PHP_EOL; echo ini_get('serialize_precision'), PHP_EOL; echo "OUTPUTS".PHP_EOL; echo join($v, ' ').PHP_EOL; -print join($v, ' ').PHP_EOL; var_dump(serialize($v)); var_export($v);echo PHP_EOL; @@ -59,7 +55,6 @@ echo ini_get('precision'), PHP_EOL; echo ini_get('serialize_precision'), PHP_EOL; echo "OUTPUTS".PHP_EOL; echo join($v, ' ').PHP_EOL; -print join($v, ' ').PHP_EOL; var_dump(serialize($v)); var_export($v);echo PHP_EOL; @@ -70,7 +65,6 @@ echo ini_get('precision'), PHP_EOL; echo ini_get('serialize_precision'), PHP_EOL; echo "OUTPUTS".PHP_EOL; echo join($v, ' ').PHP_EOL; -print join($v, ' ').PHP_EOL; var_dump(serialize($v)); var_export($v);echo PHP_EOL; @@ -81,7 +75,6 @@ echo ini_get('precision'), PHP_EOL; echo ini_get('serialize_precision'), PHP_EOL; echo "OUTPUTS".PHP_EOL; echo join($v, ' ').PHP_EOL; -print join($v, ' ').PHP_EOL; var_dump(serialize($v)); var_export($v);echo PHP_EOL; --EXPECT-- @@ -90,7 +83,6 @@ INI -1 OUTPUTS 123456789.01234567 3.3333333333333335 9.87E+102 -123456789.01234567 3.3333333333333335 9.87E+102 string(72) "a:3:{i:0;d:123456789.01234567;i:1;d:3.3333333333333335;i:2;d:9.87E+102;}" array ( 0 => 123456789.01234567, @@ -102,7 +94,6 @@ INI 0 OUTPUTS 1.0E+8 3 1.0E+103 -1.0E+8 3 1.0E+103 string(47) "a:3:{i:0;d:1.0E+8;i:1;d:3.0E+0;i:2;d:1.0E+103;}" array ( 0 => 1.0E+8, @@ -114,7 +105,6 @@ INI 9 OUTPUTS 123456789 3.33333333 9.87E+102 -123456789 3.33333333 9.87E+102 string(55) "a:3:{i:0;d:123456789;i:1;d:3.33333333;i:2;d:9.87E+102;}" array ( 0 => 123456789, @@ -126,7 +116,6 @@ INI 14 OUTPUTS 123456789.01235 3.3333333333333 9.87E+102 -123456789.01235 3.3333333333333 9.87E+102 string(66) "a:3:{i:0;d:123456789.01235;i:1;d:3.3333333333333;i:2;d:9.87E+102;}" array ( 0 => 123456789.01235, @@ -138,7 +127,6 @@ INI 17 OUTPUTS 123456789.01234567 3.3333333333333335 9.8700000000000007E+102 -123456789.01234567 3.3333333333333335 9.8700000000000007E+102 string(86) "a:3:{i:0;d:123456789.01234567;i:1;d:3.3333333333333335;i:2;d:9.8700000000000007E+102;}" array ( 0 => 123456789.01234567, @@ -150,7 +138,6 @@ INI 25 OUTPUTS 123456789.0123456716537476 3.33333333333333348136307 9.870000000000000687310143E+102 -123456789.0123456716537476 3.33333333333333348136307 9.870000000000000687310143E+102 string(109) "a:3:{i:0;d:123456789.0123456716537476;i:1;d:3.33333333333333348136307;i:2;d:9.870000000000000687310143E+102;}" array ( 0 => 123456789.0123456716537476, @@ -162,7 +149,6 @@ INI 100 OUTPUTS 123456789.01234567165374755859375 3.333333333333333481363069950020872056484222412109375 9.87000000000000068731014283095442748328521861543465424509123736073120616987695396574376473706259651E+102 -123456789.01234567165374755859375 3.333333333333333481363069950020872056484222412109375 9.87000000000000068731014283095442748328521861543465424509123736073120616987695396574376473706259651E+102 string(218) "a:3:{i:0;d:123456789.01234567165374755859375;i:1;d:3.333333333333333481363069950020872056484222412109375;i:2;d:9.87000000000000068731014283095442748328521861543465424509123736073120616987695396574376473706259651E+102;}" array ( 0 => 123456789.01234567165374755859375, From 01e59c67a9b0e457031d8e2fcd1fb55ebfcadffa Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Mon, 31 Aug 2015 19:12:21 +0900 Subject: [PATCH 08/10] Remove unneeded WS change --- main/snprintf.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/main/snprintf.c b/main/snprintf.c index 0ecceda593388..b73bb87505d49 100644 --- a/main/snprintf.c +++ b/main/snprintf.c @@ -238,8 +238,6 @@ PHPAPI char *php_gcvt(double value, int ndigit, char dec_point, char exponent, c } /* }}} */ - - /* {{{ Apache license */ /* ==================================================================== * Copyright (c) 1995-1998 The Apache Group. All rights reserved. From d713c7ba2e6e5de7cb6e5272b7ab2ddcfd887893 Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Mon, 31 Aug 2015 19:20:28 +0900 Subject: [PATCH 09/10] Add better value to test --- tests/basic/precision.phpt | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/tests/basic/precision.phpt b/tests/basic/precision.phpt index 097e2c4eb3641..9c50fa7608f37 100644 --- a/tests/basic/precision.phpt +++ b/tests/basic/precision.phpt @@ -5,7 +5,7 @@ precision=14 serialize_precision=17 --FILE-- 123456789.01234567, 1 => 3.3333333333333335, 2 => 9.87E+102, + 3 => 10.0000001, ) INI 0 0 OUTPUTS -1.0E+8 3 1.0E+103 -string(47) "a:3:{i:0;d:1.0E+8;i:1;d:3.0E+0;i:2;d:1.0E+103;}" +1.0E+8 3 1.0E+103 1.0E+1 +string(60) "a:4:{i:0;d:1.0E+8;i:1;d:3.0E+0;i:2;d:1.0E+103;i:3;d:1.0E+1;}" array ( 0 => 1.0E+8, 1 => 3.0E+0, 2 => 1.0E+103, + 3 => 1.0E+1, ) INI 9 9 OUTPUTS -123456789 3.33333333 9.87E+102 -string(55) "a:3:{i:0;d:123456789;i:1;d:3.33333333;i:2;d:9.87E+102;}" +123456789 3.33333333 9.87E+102 10.0000001 +string(72) "a:4:{i:0;d:123456789;i:1;d:3.33333333;i:2;d:9.87E+102;i:3;d:10.0000001;}" array ( 0 => 123456789, 1 => 3.33333333, 2 => 9.87E+102, + 3 => 10.0000001, ) INI 14 14 OUTPUTS -123456789.01235 3.3333333333333 9.87E+102 -string(66) "a:3:{i:0;d:123456789.01235;i:1;d:3.3333333333333;i:2;d:9.87E+102;}" +123456789.01235 3.3333333333333 9.87E+102 10.0000001 +string(83) "a:4:{i:0;d:123456789.01235;i:1;d:3.3333333333333;i:2;d:9.87E+102;i:3;d:10.0000001;}" array ( 0 => 123456789.01235, 1 => 3.3333333333333, 2 => 9.87E+102, + 3 => 10.0000001, ) INI 17 17 OUTPUTS -123456789.01234567 3.3333333333333335 9.8700000000000007E+102 -string(86) "a:3:{i:0;d:123456789.01234567;i:1;d:3.3333333333333335;i:2;d:9.8700000000000007E+102;}" +123456789.01234567 3.3333333333333335 9.8700000000000007E+102 10.000000099999999 +string(111) "a:4:{i:0;d:123456789.01234567;i:1;d:3.3333333333333335;i:2;d:9.8700000000000007E+102;i:3;d:10.000000099999999;}" array ( 0 => 123456789.01234567, 1 => 3.3333333333333335, 2 => 9.8700000000000007E+102, + 3 => 10.000000099999999, ) INI 25 25 OUTPUTS -123456789.0123456716537476 3.33333333333333348136307 9.870000000000000687310143E+102 -string(109) "a:3:{i:0;d:123456789.0123456716537476;i:1;d:3.33333333333333348136307;i:2;d:9.870000000000000687310143E+102;}" +123456789.0123456716537476 3.33333333333333348136307 9.870000000000000687310143E+102 10.0000000999999993922529 +string(141) "a:4:{i:0;d:123456789.0123456716537476;i:1;d:3.33333333333333348136307;i:2;d:9.870000000000000687310143E+102;i:3;d:10.0000000999999993922529;}" array ( 0 => 123456789.0123456716537476, 1 => 3.33333333333333348136307, 2 => 9.870000000000000687310143E+102, + 3 => 10.0000000999999993922529, ) INI 100 100 OUTPUTS -123456789.01234567165374755859375 3.333333333333333481363069950020872056484222412109375 9.87000000000000068731014283095442748328521861543465424509123736073120616987695396574376473706259651E+102 -string(218) "a:3:{i:0;d:123456789.01234567165374755859375;i:1;d:3.333333333333333481363069950020872056484222412109375;i:2;d:9.87000000000000068731014283095442748328521861543465424509123736073120616987695396574376473706259651E+102;}" +123456789.01234567165374755859375 3.333333333333333481363069950020872056484222412109375 9.87000000000000068731014283095442748328521861543465424509123736073120616987695396574376473706259651E+102 10.0000000999999993922529029077850282192230224609375 +string(277) "a:4:{i:0;d:123456789.01234567165374755859375;i:1;d:3.333333333333333481363069950020872056484222412109375;i:2;d:9.87000000000000068731014283095442748328521861543465424509123736073120616987695396574376473706259651E+102;i:3;d:10.0000000999999993922529029077850282192230224609375;}" array ( 0 => 123456789.01234567165374755859375, 1 => 3.333333333333333481363069950020872056484222412109375, 2 => 9.87000000000000068731014283095442748328521861543465424509123736073120616987695396574376473706259651E+102, + 3 => 10.0000000999999993922529029077850282192230224609375, ) From baf3207df5eb4d7af0a032df49580a45b4a11beb Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Fri, 4 Sep 2015 07:17:44 +0900 Subject: [PATCH 10/10] Avoid magic number. NUM_BUF_SIZE may be in header. Suggestions are appreciated --- ext/standard/var.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/ext/standard/var.c b/ext/standard/var.c index 2f62bd3146683..516d13aca3875 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -31,9 +31,20 @@ #include "zend_smart_str.h" #include "basic_functions.h" #include "php_incomplete_class.h" +/* }}} */ #define COMMON (is_ref ? "&" : "") -/* }}} */ + +/* Copied from main/spprintf.c and use the same buffer size + * + * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions + * + * XXX: this is a magic number; do not decrease it + * Emax = 1023 + * NDIG = 320 + * NUM_BUF_SIZE >= strlen("-") + Emax + strlrn(".") + NDIG + strlen("E+1023") + 1; + */ +#define NUM_BUF_SIZE 2048 static uint32_t zend_obj_num_elements(HashTable *ht) /* {{{ */ { @@ -455,7 +466,7 @@ static void php_object_element_export(zval *zv, zend_ulong index, zend_string *k PHPAPI void php_var_export_ex(zval *struc, int level, smart_str *buf) /* {{{ */ { HashTable *myht; - char tmp_str[2048]; /* Use the same magic number of spprintf.c NUM_BUF_SIZE */ + char tmp_str[NUM_BUF_SIZE]; zend_string *ztmp, *ztmp2; zend_ulong index; zend_string *key; @@ -827,7 +838,7 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_ return; case IS_DOUBLE: { - char tmp_str[2048]; /* Use the same magic number of spprintf.c NUM_BUF_SIZE */ + char tmp_str[NUM_BUF_SIZE]; smart_str_appendl(buf, "d:", 2); php_gcvt(Z_DVAL_P(struc), (int)PG(serialize_precision), '.', 'E', tmp_str); smart_str_appends(buf, tmp_str);