Bug #63898 [Ver->Csd]: json_encode sets string to null for invalid characters

From: Date: Sun, 20 Aug 2017 17:21:30 +0000
Subject: Bug #63898 [Ver->Csd]: json_encode sets string to null for invalid characters
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-210759@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=63898&edit=1

 ID:                 63898
 Updated by:         bukka@php.net
 Reported by:        sreed at ontraport dot com
 Summary:            json_encode sets string to null for invalid
                     characters
-Status:             Verified
+Status:             Closed
 Type:               Bug
 Package:            JSON related
 Operating System:   All
 PHP Version:        5.4.10
-Assigned To:        
+Assigned To:        bukka
 Block user comment: N
 Private report:     N

 New Comment:

This is no longer an issue in PHP 7.x (the only release receiving bug fixes like this). In addition
PHP 7.2 introduces a new constants for replacing or ignoring invalid UTF-8 characters.


Previous Comments:
------------------------------------------------------------------------
[2016-08-08 12:35:13] cmb@php.net

For reference: <https://3v4l.org/gMA2I>.

The behavior as of PHP 7.0.0 is okay (it would have to be
documented that also NULL can be returned on failure), but the
behavior of PHP 5.6 seems to be erroneous.

------------------------------------------------------------------------
[2014-01-28 18:34:16] gbarros at yahoo-inc dot com

I think this is now a duplicate of https://bugs.php.net/bug.php?id=65082 ?

------------------------------------------------------------------------
[2014-01-27 23:50:19] gbarros at yahoo-inc dot com

I tried the code in git/svn HEAD right now (last commit 
aafce7353e "merge branch 5.6") so I assume whichever code discussed here is included (no
patch on this report).

I added a test with a string with a tab and it does not return false. I think it should remove
inescapable chars (and maybe issue a log warning) and for chars with a escape sequence, it should
just encode it.


--TEST--
json_decode() tests
--SKIPIF--
<?php if (!extension_loaded("json")) print "skip"; ?>
--FILE--
<?php
var_dump(json_encode('a'.chr(9).'b')); // char with usable escape sequence (tab)
var_dump(json_encode('a'.chr(1).'b')); // char with no usable escape sequecne
?>                                                                                               
                                                    --EXPECTREGEX--
string\(4\) \"a\tb\"
string\(2\) \"ab\"

------------------------------------------------------------------------
[2013-03-30 18:53:32] programming at stefan-koch dot name

Fixed in the current git master (see rev in my comment above). So it will be fixed in PHP 5.5
Just compiled from git and it returns 'false' when there are illegal characters.

Will return false in all cases when there is an error (check in implementation of json_encode).

------------------------------------------------------------------------
[2013-03-30 17:08:28] programming at stefan-koch dot name

I was able to locate the bug, but I am too unknown in the PHP source to know how to fix it best.

For keys, just like for values, "json_escape_string" is being used. In PHP 5.4 (unlike PHP
5.2) there's a check for invalid UTF-8 sequences. In PHP 5.2.0 this special check did not
exist, instead when something was either wrong or empty, an empty string was printed.

So the location of the problem is line 432 in ext/json/json.c (PHP 5.4.12) or around line 442 in git
master (commit ac9f53dd9c0b184bab14d669c72971c0405ed488).

My idea would be - if one wants to maintain the 'null' printing - to pass an additional
argument to "json_escape_string" to tell whether this is a key or a value (since they seem
to need different treatment, as null is not allowed for keys in JSON).
Alternative would be to insert empty string in case of invalid UTF8 sequence. This would be a very
easy fix going back to the old state. However, I guess somebody introduced null for some reason.
Or you could return false if some error occured, but from my Python knowledge I really dislike this
treatment. It's correct, but it leads to non-working code due to encoding problems very often,
at least when you receive data from somewhere else).

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=63898


--
Edit this bug report at https://bugs.php.net/bug.php?id=63898&edit=1


Thread (9 messages)

« previous php.bugs (#210759) next »