php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #68546 json_decode() Fatal error: Cannot access property started with '\0'
Submitted: 2014-12-04 16:37 UTC Modified: 2015-06-21 14:37 UTC
From: j dot tvr at centrum dot cz Assigned: bukka
Status: Closed Package: JSON related
PHP Version: 5.6.3 OS:
Private report: No CVE-ID:
 [2014-12-04 16:37 UTC] j dot tvr at centrum dot cz
Description:
------------
Calling json_decode may result in fatal error.

Test script:
---------------
json_decode('{"\u0000": 1}');

Expected result:
----------------
It should not result in fatal error.


Patches

json-0 (last revision 2015-05-28 00:54 UTC) by cmb@php.net)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-12-04 18:52 UTC] requinix@php.net
-Status: Open +Status: Not a bug
 [2014-12-04 18:52 UTC] requinix@php.net
*That* code works fine. $obj->{"\x00"} won't, which I assume is what you're actually trying to report.

If you think your keys may have control characters, or in general characters not valid for property/variable names, then decode to an array instead. Just because JSON supports certain object keys doesn't mean PHP should too.
 [2014-12-04 22:57 UTC] j dot tvr at centrum dot cz
That code does NOT work fine, it is a bug in ext-json. Both jsonc (http://pecl.php.net/package/jsonc) and jsond (http://pecl.php.net/package/jsond) do not result in fatal error for the very same input.
 [2014-12-04 23:42 UTC] aharvey@php.net
-Status: Not a bug +Status: Re-Opened
 [2014-12-04 23:42 UTC] aharvey@php.net
It does fail for me in the json_decode as well, although I'm _very_ on the fence about whether this is actually worth fixing.
 [2014-12-05 01:54 UTC] requinix@php.net
Ah, sorry, I forgot that json is an awkward extension with multiple underlying implementations. I was using jsonc on Ubuntu where it worked, but it does fail on Windows.

Given that JSON is often passed as user input, I'd really like it if I could decode strings without worrying about fatal errors and continue with my input validation normally.
 [2014-12-05 02:41 UTC] yohgaki@php.net
http://3v4l.org/imJSu

I agree that this should not result in E_ERROR. Ignoring offensive data and raise E_WARNING is nicer.
 [2014-12-05 03:00 UTC] yohgaki@php.net
<?php
var_dump(json_decode('{"a": 1}'));
var_dump(json_decode('{"1": 1}'));
var_dump(json_decode('{a: 1, "a": 1}'));  // invalid JSON
var_dump(json_decode('{"a\u0000b: 1}'));  // invalid JSON
?>

http://3v4l.org/nncBo

E_WARNING may be too much. Just returning NULL seems to be enough and leave users to handle errors.
 [2014-12-05 03:08 UTC] yohgaki@php.net
I'm not sure current implementation, but RFC 7259 defines "string" as

http://tools.ietf.org/html/rfc7159#page-5

      string = quotation-mark *char quotation-mark

      char = unescaped /
          escape (
              %x22 /          ; "    quotation mark  U+0022
              %x5C /          ; \    reverse solidus U+005C
              %x2F /          ; /    solidus         U+002F
              %x62 /          ; b    backspace       U+0008
              %x66 /          ; f    form feed       U+000C
              %x6E /          ; n    line feed       U+000A
              %x72 /          ; r    carriage return U+000D
              %x74 /          ; t    tab             U+0009
              %x75 4HEXDIG )  ; uXXXX                U+XXXX

      escape = %x5C              ; \

      quotation-mark = %x22      ; "

      unescaped = %x20-21 / %x23-5B / %x5D-10FFFF

Anything other than this spec should result in error. i.e. NULL
It would be depended on underlying library, though.
 [2015-05-27 22:24 UTC] cmb@php.net
This issue is not particularly related to JSON. It is, as requinix
pointed out, related to the fact, that an object property must not
start with a null byte: <http://3v4l.org/oEMRC>.

Presumably, this restriction is there for a good reason. Anyhow,
letting json_decode() with $assoc=false accept such input would
require the Zend object implementation to change (at least if the
property should be accessible, what seems to be the very point).

Actually, I don't consider this to be a bug in json_decode(). The
(proposed) standard, RFC 7159, states:

| A JSON parser MUST accept all texts that conform to the JSON
| grammar.

json_decode() does, AFAIK, when the $assoc parameter is false.
 [2015-05-27 23:50 UTC] j dot tvr at centrum dot cz
json_decode should return FALSE because the input can not be decoded to object, but MUST NOT trigger fatal error. Imagine an API which accepts arbitrary JSON from HTTP request. User should never be able to force PHP to trigger fatal error.
 [2015-05-28 00:54 UTC] cmb@php.net
The following patch has been added/updated:

Patch Name: json-0
Revision:   1432774448
URL:        https://bugs.php.net/patch-display.php?bug=68546&patch=json-0&revision=1432774448
 [2015-05-28 00:55 UTC] cmb@php.net
There are worse things possible than a fatal error if arbitrary
user input is passed to inappropriate functions. Then again, it
doesn't seem to be hard to check for this particular condition and
to return NULL (what is the customary error return value for
json_decode) and to set the error state to JSON_ERROR_CTRL_CHAR (a
new constant might be more approriate), so that it can be
retrieved with json_last_error. I've attached a respective patch
for PHP 5 (PHP 7 would have to be catered to differently).
 [2015-05-28 06:07 UTC] yohgaki@php.net
Just an additional comment on this.

PostgreSQL even made "\0" a invalid/unacceptable character for JSONB type.
http://www.postgresql.org/docs/9.4/static/datatype-json.html

PHP has rules on variable names. It's good to enforce the rule to JSON data parsed by PHP's standard JSON library. IMHO.
 [2015-05-28 18:54 UTC] bukka@php.net
-Status: Re-Opened +Status: Assigned -Assigned To: +Assigned To: bukka
 [2015-05-28 18:54 UTC] bukka@php.net
I just emailed about this on internals. The problem is the fatal error and I would like to introduce a new error called JSON_ERROR_MANGLED_PROPERTY_NAME
 [2015-06-21 14:32 UTC] bukka@php.net
Automatic comment on behalf of bukka
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f3df3df8737ace9f4431416fdd0d312cb0ee9cfd
Log: Fix bug #68546 (json_decode cannot access property started with \0)
 [2015-06-21 14:32 UTC] bukka@php.net
-Status: Assigned +Status: Closed
 [2015-06-21 14:37 UTC] bukka@php.net
FYI: I decided to go for JSON_ERROR_INVALID_PROPERTY_NAME as suggested by Christoph in internals discussion. It's a better name for the error IMHO.
 [2015-06-23 18:04 UTC] ab@php.net
Automatic comment on behalf of bukka
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f3df3df8737ace9f4431416fdd0d312cb0ee9cfd
Log: Fix bug #68546 (json_decode cannot access property started with \0)
 [2016-07-20 11:38 UTC] davey@php.net
Automatic comment on behalf of bukka
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f3df3df8737ace9f4431416fdd0d312cb0ee9cfd
Log: Fix bug #68546 (json_decode cannot access property started with \0)
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Tue Feb 21 14:01:44 2017 UTC