Skip to content

Commit 717f1ed

Browse files
committed
Fix #79908: json_encode encodes negative zero as int
Encoding a negative zero as `-0` is likely to loose the sign when decoding (at least it does with `json_decode()`). Therefore, we encode it as if `JSON_PRESERVE_ZERO_FRACTION` was specified, i.e. as `-0.0`. Closes phpGH-7234.
1 parent 9db3eda commit 717f1ed

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

NEWS

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ PHP NEWS
2121
. Fixed bug #68471 (IntlDateFormatter fails for "GMT+00:00" timezone). (cmb)
2222
. Fixed bug #74264 (grapheme_strrpos() broken for negative offsets). (cmb)
2323

24+
- JSON:
25+
. Fixed bug #79908 (json_encode encodes negative zero as int). (cmb)
26+
2427
- OpenSSL:
2528
. Fixed bug #52093 (openssl_csr_sign truncates $serial). (cmb)
2629

ext/json/json_encoder.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ static inline void php_json_encode_double(smart_str *buf, double d, int options)
104104

105105
php_gcvt(d, (int)PG(serialize_precision), '.', 'e', num);
106106
len = strlen(num);
107-
if (options & PHP_JSON_PRESERVE_ZERO_FRACTION && strchr(num, '.') == NULL && len < PHP_DOUBLE_MAX_LENGTH - 2) {
107+
if ((options & PHP_JSON_PRESERVE_ZERO_FRACTION && strchr(num, '.') == NULL && len < PHP_DOUBLE_MAX_LENGTH - 2)
108+
|| (UNEXPECTED(len == 2 && num[0] == '-' && num[1] == '0'))) {
108109
num[len++] = '.';
109110
num[len++] = '0';
110111
num[len] = '\0';

ext/json/tests/bug79908.phpt

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
Bug #79908 (json_encode encodes negative zero as int)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('json')) die("skip json extension not available");
6+
?>
7+
--FILE--
8+
<?php
9+
var_dump(json_encode(-0.));
10+
?>
11+
--EXPECT--
12+
string(4) "-0.0"

0 commit comments

Comments
 (0)