php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #71572 String offset assignment from an empty string inserts null byte
Submitted: 2016-02-11 22:12 UTC Modified: 2016-02-11 22:13 UTC
From: francois@php.net Assigned: francois (profile)
Status: Closed Package: Strings related
PHP Version: 7.0.3 OS: Any
Private report: No CVE-ID: None
 [2016-02-11 22:12 UTC] francois@php.net
Description:
------------
When assigning to a string offset from an empty string, the corresponding byte is set to a null value.

In zend_assign_to_string_offset(), the length of the input string should be checked. If 0, a warning should be raised and the string shouldn't be modified.


Test script:
---------------
$str = "abc";
$str{0} = "";
var_dump($str);


Expected result:
----------------
PHP Fatal error:  Uncaught Error: Cannot assign an empty string to a string offset in ...


Actual result:
--------------
string(3) "bc" (read as "\0bc")


Patches

Pull Requests

Pull requests:

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-02-11 22:13 UTC] francois@php.net
-Assigned To: +Assigned To: francois
 [2016-02-12 08:53 UTC] salsi at icosaedro dot it
My survey of several oddities and undefined behaviors in string single-byte assignment which are strictly relates to this same topic I have collected from the discussions of these days that should be addressed as a whole in some consistent way:

<?php

// Set char in string oddities (PHP 5.6.3, PHP 7.1.0-dev).
error_reporting(-1);

// Replacing a single byte.
$s = "abc";
$s[1] = "x";
echo "replace byte: ", rawurlencode($s), "\n"; // -> axc (expected)

// Set single byte with empty replacement string (undefined behavior).
// https://bugs.php.net/bug.php?id=71572
// Expected: some error.
// Actual: replaces with byte 0.
$s = "abc";
$s[1] = ""; // empty string
echo "set empty byte: ", rawurlencode($s), "\n"; // --> a%00c

// Set single byte with 2+ bytes long replacement string (undefined behavior).
// Expected: some error.
// Actual: replaces with the first byte of the replacement string.
$s = "abc";
$s[1] = "xyz";
echo "set multiple bytes: ", rawurlencode($s), "\n"; // --> axc

// Set single byte on empty string (undefined behavior).
// Expected: some error because undefined behavior (no char to replace at
// the given offset).
// Actual: type switch to array.
$s = ""; // Empty string
$s[1] = "z";
echo "set on empty string: "; var_dump($s); // -> array(1) { [1]=>string(1) "z" }

// Append to empty string.
// Expected: append "z" to empty string resulting in "z".
// Actual: type switch to array.
$s = "";
$s[] = 'z';
echo "append on empty string: "; var_dump($s); // -> array(1) { [0]=>string(1) "z" }

// Append on non-empty string.
// Expected: append "z" to "a" resulting in "az".
// Actual: fatal error.
$s = "a";
$s[] = 'z'; // -> Fatal error : [] operator not supported for strings
?>

In my opinion, the simplest thing to do is to define the "string single-byte assignment" as the replacement of the existing byte at the given offset with the first byte of the replacement string, any other case causing E_WARNING; appending $s[] = ... not allowed (there is the . operator already); unexpected conversion to array absolutely to fix!
 [2016-02-14 12:21 UTC] nikic@php.net
Automatic comment on behalf of francois@tekwire.net
Revision: http://git.php.net/?p=php-src.git;a=commit;h=be607e724c69c92f8cda72a45a13a26e7c439aec
Log: Fix bug #71572
 [2016-02-14 12:21 UTC] nikic@php.net
-Status: Assigned +Status: Closed
 [2016-04-18 09:29 UTC] bwoebi@php.net
Automatic comment on behalf of francois@tekwire.net
Revision: http://git.php.net/?p=php-src.git;a=commit;h=be607e724c69c92f8cda72a45a13a26e7c439aec
Log: Fix bug #71572
 [2016-07-20 11:33 UTC] davey@php.net
Automatic comment on behalf of francois@tekwire.net
Revision: http://git.php.net/?p=php-src.git;a=commit;h=be607e724c69c92f8cda72a45a13a26e7c439aec
Log: Fix bug #71572
 [2016-09-14 11:10 UTC] cmb@php.net
Automatic comment from SVN on behalf of cmb
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=340031
Log: Fix docs wrt. bug #71572
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Oct 09 23:01:26 2024 UTC