Bug #74545 [Opn]: Casting arrays to objects allows creation of attributes that start with \0

From: Date: Fri, 05 May 2017 12:12:44 +0000
Subject: Bug #74545 [Opn]: Casting arrays to objects allows creation of attributes that start with \0
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-208962@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=74545&edit=1

 ID:                 74545
 User updated by:    daniil at daniil dot it
 Reported by:        daniil at daniil dot it
 Summary:            Casting arrays to objects allows creation of
                     attributes that start with \0
 Status:             Open
 Type:               Bug
 Package:            Class/Object related
 PHP Version:        Irrelevant
 Block user comment: N
 Private report:     N

 New Comment:

Whoops, the object cast is actually
$object = (object)[chr(0).'a' => 'c', chr(0) => 'b'];


Previous Comments:
------------------------------------------------------------------------
[2017-05-05 08:58:51] daniil at daniil dot it

Description:
------------
Similar to #67300.
Due to the reasons described in http://stackoverflow.com/a/5484777, we cannot read or
write to/from class attributes with names that start with \0 (chr(0) or the null char).

But casting arrays with keys that start with \0 to objects does not throw any kind of error or
exception.

If the resulting object is var_dumped, Illegal member variable name notices are emitted.
The same happens if we iterate over the object using foreach.
If we try to access any of such properties directly, we get a fatal error with message "Cannot
access property started with '\0'".

But, if we reconvert the object back to an array using get_object_vars or an array cast, the values
can still be read.


Test script:
---------------
<?php
$object = (object)[chr(0).'a' => 'a', chr(0) => 'b'];

var_dump($object);

echo "\nenum properties:\n";
foreach ($object as $p => $v) {
    var_export($p);
}

echo "\nget value under key chr(0) with get_object_vars()\n";
var_dump(get_object_vars($object)[chr(0)]);
echo "\nget value under key chr(0).'a' with get_object_vars()\n";
var_dump(get_object_vars($object)[chr(0).'a']);

echo "\nget value under key chr(0) with array cast\n";
var_dump(((array)$object)[chr(0)]);
echo "\nget value under key chr(0).'a' with array cast\n";
var_dump(((array)$object)[chr(0).'a']);

echo "\nget value under key chr(0) directly\n";
var_dump($object->{chr(0)}); // FATAL ERROR

Expected result:
----------------
A fatal error while casting such arrays, or, if possible, removal of the code that prevents
accessing properties that start with \0.

Actual result:
--------------
object(stdClass)#1 (2) {
PHP Notice:  Illegal member variable name in /home/pwrtelegram/aaa.php on line 4
  ["a"]=>
  string(1) "c"
PHP Notice:  Illegal member variable name in /home/pwrtelegram/aaa.php on line 4
  [""]=>
  string(1) "b"
}

enum properties:
PHP Notice:  Illegal member variable name in /home/pwrtelegram/aaa.php on line 7
PHP Notice:  Illegal member variable name in /home/pwrtelegram/aaa.php on line 7

get value under key chr(0) with get_object_vars()
string(1) "b"

get value under key chr(0).'a' with get_object_vars()
string(1) "c"

get value under key chr(0) with array cast
string(1) "b"

get value under key chr(0).'a' with array cast
string(1) "c"

get value under key chr(0) directly
PHP Fatal error:  Uncaught Error: Cannot access property started with '\0' in
/home/pwrtelegram/aaa.php:22
Stack trace:
#0 {main}
  thrown in /home/pwrtelegram/aaa.php on line 22


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



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


Thread (2 messages)

« previous php.bugs (#208962) next »