Skip to content

Commit f943daf

Browse files
yohgakibukka
authored andcommitted
Initial patch for 0 mode float conversion. The magic number is better to be improved. Any suggestion where to define it?
1 parent 8de8636 commit f943daf

File tree

5 files changed

+61
-17
lines changed

5 files changed

+61
-17
lines changed

ext/json/json_encoder.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,11 @@ static inline void php_json_encode_double(smart_str *buf, double d, int options)
104104
{
105105
size_t len;
106106
char num[PHP_JSON_DOUBLE_MAX_LENGTH];
107-
php_gcvt(d, (int)EG(precision), '.', 'e', &num[0]);
107+
if (PG(serialize_precision) == -1) {
108+
php_0cvt(d, 17, '.', 'e', num);
109+
} else {
110+
php_gcvt(d, PG(serialize_precision), '.', 'e', num);
111+
}
108112
len = strlen(num);
109113
if (options & PHP_JSON_PRESERVE_ZERO_FRACTION && strchr(num, '.') == NULL && len < PHP_JSON_DOUBLE_MAX_LENGTH - 2) {
110114
num[len++] = '.';

ext/standard/var.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -436,8 +436,7 @@ static void php_object_element_export(zval *zv, zend_ulong index, zend_string *k
436436
PHPAPI void php_var_export_ex(zval *struc, int level, smart_str *buf) /* {{{ */
437437
{
438438
HashTable *myht;
439-
char *tmp_str;
440-
size_t tmp_len;
439+
char tmp_str[2048]; /* Use the same magic number of spprintf.c NUM_BUF_SIZE */
441440
zend_string *ztmp, *ztmp2;
442441
zend_ulong index;
443442
zend_string *key;
@@ -458,18 +457,26 @@ PHPAPI void php_var_export_ex(zval *struc, int level, smart_str *buf) /* {{{ */
458457
smart_str_append_long(buf, Z_LVAL_P(struc));
459458
break;
460459
case IS_DOUBLE:
460+
/* TODO: check INF, -INF and NAN in the new logic
461461
tmp_len = spprintf(&tmp_str, 0,"%.*H", PG(serialize_precision), Z_DVAL_P(struc));
462462
smart_str_appendl(buf, tmp_str, tmp_len);
463-
/* Without a decimal point, PHP treats a number literal as an int.
463+
* Without a decimal point, PHP treats a number literal as an int.
464464
* This check even works for scientific notation, because the
465465
* mantissa always contains a decimal point.
466466
* We need to check for finiteness, because INF, -INF and NAN
467467
* must not have a decimal point added.
468-
*/
468+
*
469469
if (zend_finite(Z_DVAL_P(struc)) && NULL == strchr(tmp_str, '.')) {
470470
smart_str_appendl(buf, ".0", 2);
471471
}
472472
efree(tmp_str);
473+
*/
474+
if (PG(serialize_precision < 0)) {
475+
php_0cvt(Z_DVAL_P(struc), 17, '.', 'E', tmp_str);
476+
} else {
477+
php_gcvt(Z_DVAL_P(struc), (int)PG(serialize_precision), '.', 'E', tmp_str);
478+
}
479+
smart_str_appends(buf, tmp_str);
473480
break;
474481
case IS_STRING:
475482
ztmp = php_addcslashes(Z_STR_P(struc), 0, "'\\", 2);
@@ -844,16 +851,17 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_
844851
return;
845852

846853
case IS_DOUBLE: {
847-
char *s;
848-
849-
smart_str_appendl(buf, "d:", 2);
850-
s = (char *) safe_emalloc(PG(serialize_precision), 1, MAX_LENGTH_OF_DOUBLE + 1);
851-
php_gcvt(Z_DVAL_P(struc), (int)PG(serialize_precision), '.', 'E', s);
852-
smart_str_appends(buf, s);
853-
smart_str_appendc(buf, ';');
854-
efree(s);
855-
return;
854+
char tmp_str[2048]; /* Use the same magic number of spprintf.c NUM_BUF_SIZE */
855+
smart_str_appendl(buf, "d:", 2);
856+
if (PG(serialize_precision < 0)) {
857+
php_0cvt(Z_DVAL_P(struc), 17, '.', 'E', tmp_str);
858+
} else {
859+
php_gcvt(Z_DVAL_P(struc), (int)PG(serialize_precision), '.', 'E', tmp_str);
856860
}
861+
smart_str_appends(buf, tmp_str);
862+
smart_str_appendc(buf, ';');
863+
return;
864+
}
857865

858866
case IS_STRING:
859867
php_var_serialize_string(buf, Z_STRVAL_P(struc), Z_STRLEN_P(struc));

main/main.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,23 @@ static PHP_INI_MH(OnSetPrecision)
140140
}
141141
/* }}} */
142142

143+
/* {{{ PHP_INI_MH
144+
*/
145+
static PHP_INI_MH(OnSetSerializePrecision)
146+
{
147+
zend_long i;
148+
149+
ZEND_ATOL(i, ZSTR_VAL(new_value));
150+
if (i >= -1) {
151+
PG(serialize_precision) = i;
152+
return SUCCESS;
153+
} else {
154+
return FAILURE;
155+
}
156+
}
157+
/* }}} */
158+
159+
143160
/* {{{ PHP_INI_MH
144161
*/
145162
static PHP_INI_MH(OnChangeMemoryLimit)
@@ -533,7 +550,7 @@ PHP_INI_BEGIN()
533550
STD_PHP_INI_BOOLEAN("track_errors", "0", PHP_INI_ALL, OnUpdateBool, track_errors, php_core_globals, core_globals)
534551

535552
STD_PHP_INI_ENTRY("unserialize_callback_func", NULL, PHP_INI_ALL, OnUpdateString, unserialize_callback_func, php_core_globals, core_globals)
536-
STD_PHP_INI_ENTRY("serialize_precision", "17", PHP_INI_ALL, OnUpdateLongGEZero, serialize_precision, php_core_globals, core_globals)
553+
STD_PHP_INI_ENTRY("serialize_precision", "-1", PHP_INI_ALL, OnSetSerializePrecision, serialize_precision, php_core_globals, core_globals)
537554
STD_PHP_INI_ENTRY("arg_separator.output", "&", PHP_INI_ALL, OnUpdateStringUnempty, arg_separator.output, php_core_globals, core_globals)
538555
STD_PHP_INI_ENTRY("arg_separator.input", "&", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateStringUnempty, arg_separator.input, php_core_globals, core_globals)
539556

main/snprintf.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,12 @@ static inline char *php_fcvt(double value, int ndigit, int *decpt, int *sign) /*
139139
}
140140
/* }}} */
141141

142-
PHPAPI char *php_gcvt(double value, int ndigit, char dec_point, char exponent, char *buf) /* {{{ */
142+
static inline char *_php_cvt(double value, int ndigit, char dec_point, char exponent, char *buf, int mode) /* {{{ */
143143
{
144144
char *digits, *dst, *src;
145145
int i, decpt, sign;
146146

147-
digits = zend_dtoa(value, 2, ndigit, &decpt, &sign, NULL);
147+
digits = zend_dtoa(value, mode, ndigit, &decpt, &sign, NULL);
148148
if (decpt == 9999) {
149149
/*
150150
* 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
234234
}
235235
/* }}} */
236236

237+
PHPAPI char *php_gcvt(double value, int ndigit, char dec_point, char exponent, char *buf) /* {{{ */
238+
{
239+
return _php_cvt(value, ndigit, dec_point, exponent, buf, 2);
240+
}
241+
/* }}} */
242+
243+
PHPAPI char *php_0cvt(double value, int ndigit, char dec_point, char exponent, char *buf) /* {{{ */
244+
{
245+
return _php_cvt(value, ndigit, dec_point, exponent, buf, 0);
246+
}
247+
/* }}} */
248+
249+
250+
237251
/* {{{ Apache license */
238252
/* ====================================================================
239253
* Copyright (c) 1995-1998 The Apache Group. All rights reserved.

main/snprintf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ PHPAPI int ap_php_vasprintf(char **buf, const char *format, va_list ap);
8686
PHPAPI int ap_php_asprintf(char **buf, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
8787
PHPAPI int php_sprintf (char* s, const char* format, ...) PHP_ATTRIBUTE_FORMAT(printf, 2, 3);
8888
PHPAPI char * php_gcvt(double value, int ndigit, char dec_point, char exponent, char *buf);
89+
PHPAPI char * php_0cvt(double value, int ndigit, char dec_point, char exponent, char *buf);
8990
PHPAPI char * php_conv_fp(char format, double num,
9091
boolean_e add_dp, int precision, char dec_point, bool_int * is_negative, char *buf, size_t *len);
9192

0 commit comments

Comments
 (0)