php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79908 json_encode encodes negative zero as int
Submitted: 2020-07-28 13:02 UTC Modified: 2021-07-19 22:37 UTC
Votes:1
Avg. Score:4.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:1 (100.0%)
From: stefan at HDmeteo dot com Assigned: bukka (profile)
Status: Re-Opened Package: JSON related
PHP Version: 7.4.8 OS:
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2020-07-28 13:02 UTC] stefan at HDmeteo dot com
Description:
------------
While php_encode stores a negative zero float as "-0" and preserves its sign, the subsequent php_decode loses the sign and decodes "-0" as "0".

Test script:
---------------
$array = [round(-0.1), round(0.1)]; // [-0,0]
print_r($array);                    // Array ( [0] => -0 [1] => 0 ) 
$json = json_encode($array, true);  // "[-0,0]"
$array = json_decode($json);        // [0,0]
print_r($array);                    // Array ( [0] => 0 [1] => 0 )




Expected result:
----------------
Array ( [0] => -0 [1] => 0 )

Actual result:
--------------
Array ( [0] => 0 [1] => 0 )

Patches

Add a Patch

Pull Requests

Pull requests:

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2020-07-28 16:15 UTC] cmb@php.net
-Status: Open +Status: Not a bug -Assigned To: +Assigned To: cmb
 [2020-07-28 16:15 UTC] cmb@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

If you want to preserve the floating point number (there are no
integers with value -0), you have to pass JSON_PRESERVE_ZERO_FRACTION;
see <https://3v4l.org/1ZRm8>.
 [2020-07-29 10:57 UTC] stefan at HDmeteo dot com
while JSON_PRESERVE_ZERO_FRACTION solves the problem superficially, the behaviour of json_encode/json_decode is not logically clean.

There are 2 clean solutions:

1. Fix json_encode: 
do not output "-0" as there is no negative integer 0.

encode (float) (-0.0) as "0" without JSON_PRESERVE_ZERO_FRACTION
encode (float) (-0.0) as "-0.0" with JSON_PRESERVE_ZERO_FRACTION

2. Fix json_decode: 
interprete "-0" as negative float 0.0 as there is no negative integer
0.

decode "0" as (int) 0
decode "-0" as (float) (-0.0)
 [2020-07-29 11:45 UTC] cmb@php.net
-Status: Not a bug +Status: Re-Opened -Assigned To: cmb +Assigned To:
 [2020-07-29 11:45 UTC] cmb@php.net
Well, I think it makes sense to check what other JSON
implementations do in this case.
 [2020-07-30 09:32 UTC] stefan at HDmeteo dot com
JavaScript does the decoding as suggested in my solution 2 (decode -0 as float -0.0 or as string "-0"):

https://jsfiddle.net/:

input:
JSON.parse("-0")

output:
-0
 [2021-02-18 11:46 UTC] stasiukaitis dot saulius at gmail dot com
3rd party library stoped working after upgrade to PHP 7.4
This is because it compares data before and after encoding which becomes different.

https://github.com/psecio/jwt/blob/master/src/Psecio/Jwt/Jwt.php#L157
 [2021-07-13 11:15 UTC] cmb@php.net
-Assigned To: +Assigned To: cmb
 [2021-07-13 11:15 UTC] cmb@php.net
The following pull request has been associated:

Patch Name: Fix #79908: json_decode decodes negative zero as positive zero
On GitHub:  https://github.com/php/php-src/pull/7234
Patch:      https://github.com/php/php-src/pull/7234.patch
 [2021-07-13 13:08 UTC] cmb@php.net
-Summary: json_decode decodes negative zero as positive zero +Summary: json_encode encodes negative zero as int
 [2021-07-13 13:34 UTC] git@php.net
Automatic comment on behalf of cmb69
Revision: https://github.com/php/php-src/commit/717f1ed5e4b4b2083907dd085e66b377edad24b7
Log: Fix #79908: json_encode encodes negative zero as int
 [2021-07-13 13:34 UTC] git@php.net
-Status: Re-Opened +Status: Closed
 [2021-07-19 22:37 UTC] cmb@php.net
-Status: Closed +Status: Re-Opened -Assigned To: cmb +Assigned To: bukka
 [2021-07-19 22:37 UTC] cmb@php.net
The fix has been reverted – re-opening.
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Sat Sep 18 18:03:39 2021 UTC