com php-src: Fix bug #71572: NEWS Zend/tests/bug71572.phpt Zend/zend_execute.c
| From: | Nikita Popov | Date: | Sun, 14 Feb 2016 12:18:23 +0000 |
| Subject: | com php-src: Fix bug #71572: NEWS Zend/tests/bug71572.phpt Zend/zend_execute.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-91010@lists.php.net to get a copy of this message | ||
Commit: be607e724c69c92f8cda72a45a13a26e7c439aec
Author: Francois Laupretre <francois@tekwire.net> Fri, 12 Feb 2016 00:01:59 +0100
Committer: Nikita Popov <nikic@php.net> Sun, 14 Feb 2016 13:18:23 +0100
Parents: d10911afde4dfb9d66c60a05b387491eb6c70236
Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=be607e724c69c92f8cda72a45a13a26e7c439aec
Log:
Fix bug #71572
Discussed on the internals list as part of
http://markmail.org/message/fa625yc2eegk2dio.
Bugs:
https://bugs.php.net/71572
Changed paths:
M NEWS
A Zend/tests/bug71572.phpt
M Zend/zend_execute.c
Diff:
diff --git a/NEWS b/NEWS
index 0ae66b8..b0ee6b8 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@ PHP NEWS
- Core:
. Fixed bug #62210 (Exceptions can leak temporary variables). (Dmitry, Bob)
. Fixed bug #69989 (Generators don't participate in cycle GC). (Nikita)
+ . Fixed buf #71572 (String offset assignment from an empty string inserts
+ null byte). (Francois)
. Implemented the RFC
Support Class Constant Visibility. (Sean DuBois,
Reeze Xia, Dmitry)
. Added void return type. (Andrea)
diff --git a/Zend/tests/bug71572.phpt b/Zend/tests/bug71572..phpt
new file mode 100644
index 0000000..4a823ec
--- /dev/null
+++ b/Zend/tests/bug71572.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Bug #71572: String offset assignment from an empty string inserts null byte
+--FILE--
+<?php
+
+$str = "abc";
+var_dump($str{0} = "");
+var_dump($str{1} = "");
+var_dump($str{3} = "");
+var_dump($str{10} = "");
+var_dump($str);
+?>
+==DONE==
+--EXPECTF--
+Warning: Cannot assign an empty string to a string offset in %s on line %d
+NULL
+
+Warning: Cannot assign an empty string to a string offset in %s on line %d
+NULL
+
+Warning: Cannot assign an empty string to a string offset in %s on line %d
+NULL
+
+Warning: Cannot assign an empty string to a string offset in %s on line %d
+NULL
+string(3) "abc"
+==DONE==
\ No newline at end of file
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 63fc5e6..69326ab 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -1169,8 +1169,11 @@ static zend_never_inline void zend_binary_assign_op_obj_dim(zval *object,
zval *
static void zend_assign_to_string_offset(zval *str, zend_long offset, zval *value, zval *result)
{
zend_string *old_str;
+ zend_uchar c;
+ size_t string_len;
if (offset < 0) {
+ /* Error on negative offset */
zend_error(E_WARNING, "Illegal string offset: " ZEND_LONG_FMT, offset);
zend_string_release(Z_STR_P(str));
if (result) {
@@ -1179,8 +1182,31 @@ static void zend_assign_to_string_offset(zval *str, zend_long offset, zval
*valu
return;
}
+ if (Z_TYPE_P(value) != IS_STRING) {
+ /* Convert to string, just the time to pick the 1st byte */
+ zend_string *tmp = zval_get_string(value);
+
+ string_len = ZSTR_LEN(tmp);
+ c = (zend_uchar)ZSTR_VAL(tmp)[0];
+ zend_string_release(tmp);
+ } else {
+ string_len = Z_STRLEN_P(value);
+ c = (zend_uchar)Z_STRVAL_P(value)[0];
+ }
+
+ if (string_len == 0) {
+ /* Error on empty input string */
+ zend_error(E_WARNING, "Cannot assign an empty string to a string offset");
+ zend_string_release(Z_STR_P(str));
+ if (result) {
+ ZVAL_NULL(result);
+ }
+ return;
+ }
+
old_str = Z_STR_P(str);
if ((size_t)offset >= Z_STRLEN_P(str)) {
+ /* Extend string if needed */
zend_long old_len = Z_STRLEN_P(str);
Z_STR_P(str) = zend_string_extend(Z_STR_P(str), offset + 1, 0);
Z_TYPE_INFO_P(str) = IS_STRING_EX;
@@ -1191,23 +1217,11 @@ static void zend_assign_to_string_offset(zval *str, zend_long offset, zval
*valu
Z_TYPE_INFO_P(str) = IS_STRING_EX;
}
- if (Z_TYPE_P(value) != IS_STRING) {
- zend_string *tmp = zval_get_string(value);
-
- Z_STRVAL_P(str)[offset] = ZSTR_VAL(tmp)[0];
- zend_string_release(tmp);
- } else {
- Z_STRVAL_P(str)[offset] = Z_STRVAL_P(value)[0];
- }
- /*
- * the value of an assignment to a string offset is undefined
- T(result->u.var).var = &T->str_offset.str;
- */
+ Z_STRVAL_P(str)[offset] = c;
zend_string_release(old_str);
if (result) {
- zend_uchar c = (zend_uchar)Z_STRVAL_P(str)[offset];
-
+ /* Return the new character */
if (CG(one_char_string)[c]) {
ZVAL_INTERNED_STR(result, CG(one_char_string)[c]);
} else {