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
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: francois@php.net
New email:
PHP Version: OS:

 

 [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: Tue Nov 12 20:01:30 2024 UTC