diff options
author | Juan Basso <jrbasso@gmail.com> | 2015-01-12 21:29:52 -0500 |
---|---|---|
committer | Juan Basso <jrbasso@gmail.com> | 2015-01-12 21:29:52 -0500 |
commit | 95cef47afb0b5329915a178d34cf27efcb54607b (patch) | |
tree | f8a1ff72cb29166cbad04df3ec035dc18dad40e0 /ext | |
parent | e6fb493e5dbafdad37ba5334c986636342b5d9aa (diff) | |
download | php-git-95cef47afb0b5329915a178d34cf27efcb54607b.tar.gz |
Porting implementation of RFC json_preserve_fractional_part
Diffstat (limited to 'ext')
-rw-r--r-- | ext/json/json.c | 1 | ||||
-rw-r--r-- | ext/json/json_encoder.c | 11 | ||||
-rw-r--r-- | ext/json/php_json.h | 1 | ||||
-rw-r--r-- | ext/json/tests/bug50224.phpt | 60 |
4 files changed, 70 insertions, 3 deletions
diff --git a/ext/json/json.c b/ext/json/json.c index 819a6dfe8e..7db6136e87 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -102,6 +102,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); diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index 8657fd2cdb..510163d823 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -95,13 +95,18 @@ static inline void php_json_pretty_print_indent(smart_str *buf, int options) /* /* }}} */ -static inline void php_json_encode_double(smart_str *buf, double d) /* {{{ */ +static inline void php_json_encode_double(smart_str *buf, double d, int options) /* {{{ */ { if (!zend_isinf(d) && !zend_isnan(d)) { size_t len; char num[PHP_JSON_DOUBLE_MAX_LENGTH]; php_gcvt(d, EG(precision), '.', 'e', &num[0]); len = strlen(num); + if (options & PHP_JSON_PRESERVE_ZERO_FRACTION && strchr(num, '.') == NULL && len < PHP_JSON_DOUBLE_MAX_LENGTH - 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; @@ -290,7 +295,7 @@ static void php_json_escape_string(smart_str *buf, char *s, size_t len, int opti if (type == IS_LONG) { smart_str_append_long(buf, p); } else if (type == IS_DOUBLE) { - php_json_encode_double(buf, d); + php_json_encode_double(buf, d, options); } return; } @@ -502,7 +507,7 @@ again: break; case IS_DOUBLE: - php_json_encode_double(buf, Z_DVAL_P(val)); + php_json_encode_double(buf, Z_DVAL_P(val), options); break; case IS_STRING: diff --git a/ext/json/php_json.h b/ext/json/php_json.h index 25c799b383..2a26b97181 100644 --- a/ext/json/php_json.h +++ b/ext/json/php_json.h @@ -64,6 +64,7 @@ typedef enum { #define PHP_JSON_PRETTY_PRINT (1<<7) #define PHP_JSON_UNESCAPED_UNICODE (1<<8) #define PHP_JSON_PARTIAL_OUTPUT_ON_ERROR (1<<9) +#define PHP_JSON_PRESERVE_ZERO_FRACTION (1<<10) /* Internal flags */ #define PHP_JSON_OUTPUT_ARRAY 0 diff --git a/ext/json/tests/bug50224.phpt b/ext/json/tests/bug50224.phpt new file mode 100644 index 0000000000..3408ac906f --- /dev/null +++ b/ext/json/tests/bug50224.phpt @@ -0,0 +1,60 @@ +--TEST-- +bug #50224 (json_encode() does not always encode a float as a float) +--SKIPIF-- +<?php if (!extension_loaded("json")) print "skip"; ?> +--FILE-- +<?php +echo "* Testing JSON output\n\n"; +var_dump(json_encode(12.3, JSON_PRESERVE_ZERO_FRACTION)); +var_dump(json_encode(12, JSON_PRESERVE_ZERO_FRACTION)); +var_dump(json_encode(12.0, JSON_PRESERVE_ZERO_FRACTION)); +var_dump(json_encode(0.0, JSON_PRESERVE_ZERO_FRACTION)); +var_dump(json_encode(array(12, 12.0, 12.3), JSON_PRESERVE_ZERO_FRACTION)); +var_dump(json_encode((object)array('float' => 12.0, 'integer' => 12), JSON_PRESERVE_ZERO_FRACTION)); + +echo "\n* Testing encode/decode symmetry\n\n"; + +var_dump(json_decode(json_encode(12.3, JSON_PRESERVE_ZERO_FRACTION))); +var_dump(json_decode(json_encode(12, JSON_PRESERVE_ZERO_FRACTION))); +var_dump(json_decode(json_encode(12.0, JSON_PRESERVE_ZERO_FRACTION))); +var_dump(json_decode(json_encode(0.0, JSON_PRESERVE_ZERO_FRACTION))); +var_dump(json_decode(json_encode(array(12, 12.0, 12.3), JSON_PRESERVE_ZERO_FRACTION))); +var_dump(json_decode(json_encode((object)array('float' => 12.0, 'integer' => 12), JSON_PRESERVE_ZERO_FRACTION))); +var_dump(json_decode(json_encode((object)array('float' => 12.0, 'integer' => 12), JSON_PRESERVE_ZERO_FRACTION), true)); +?> +--EXPECTF-- +* Testing JSON output + +string(4) "12.3" +string(2) "12" +string(4) "12.0" +string(3) "0.0" +string(14) "[12,12.0,12.3]" +string(27) "{"float":12.0,"integer":12}" + +* Testing encode/decode symmetry + +float(12.3) +int(12) +float(12) +float(0) +array(3) { + [0]=> + int(12) + [1]=> + float(12) + [2]=> + float(12.3) +} +object(stdClass)#%d (2) { + ["float"]=> + float(12) + ["integer"]=> + int(12) +} +array(2) { + ["float"]=> + float(12) + ["integer"]=> + int(12) +}
\ No newline at end of file |