Skip to content

Commit bfe3f93

Browse files
committed
Add warning and convert to exception in string offset assignment:
Convert the empty string assignment to an Error as per RFC [1] Add a warning that only the first byte will be assigned to the offset if provided a needle that is longer than one byte. [1] https://wiki.php.net/rfc/engine_warnings
1 parent b8609e2 commit bfe3f93

File tree

6 files changed

+55
-33
lines changed

6 files changed

+55
-33
lines changed

Zend/tests/bug71572.phpt

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,31 @@ Bug #71572: String offset assignment from an empty string inserts null byte
44
<?php
55

66
$str = "abc";
7-
var_dump($str[0] = "");
8-
var_dump($str[1] = "");
9-
var_dump($str[3] = "");
10-
var_dump($str[10] = "");
7+
try {
8+
var_dump($str[0] = "");
9+
} catch (\Error $e) {
10+
echo $e->getMessage() . \PHP_EOL;
11+
}
12+
try {
13+
var_dump($str[1] = "");
14+
} catch (\Error $e) {
15+
echo $e->getMessage() . \PHP_EOL;
16+
}
17+
try {
18+
var_dump($str[3] = "");
19+
} catch (\Error $e) {
20+
echo $e->getMessage() . \PHP_EOL;
21+
}
22+
try {
23+
var_dump($str[10] = "");
24+
} catch (\Error $e) {
25+
echo $e->getMessage() . \PHP_EOL;
26+
}
1127
var_dump($str);
1228
?>
13-
--EXPECTF--
14-
Warning: Cannot assign an empty string to a string offset in %s on line %d
15-
NULL
16-
17-
Warning: Cannot assign an empty string to a string offset in %s on line %d
18-
NULL
19-
20-
Warning: Cannot assign an empty string to a string offset in %s on line %d
21-
NULL
22-
23-
Warning: Cannot assign an empty string to a string offset in %s on line %d
24-
NULL
29+
--EXPECT--
30+
Cannot assign an empty string to a string offset
31+
Cannot assign an empty string to a string offset
32+
Cannot assign an empty string to a string offset
33+
Cannot assign an empty string to a string offset
2534
string(3) "abc"

Zend/tests/indexing_001.phpt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ foreach ($testvalues as $testvalue) {
5151
var_dump ($testvalue);
5252
}
5353

54-
55-
echo "\nDone";
5654
?>
5755
--EXPECTF--
5856
*** Indexing - Testing value assignment with key ***
@@ -80,11 +78,15 @@ array(1) {
8078
Warning: Illegal string offset 'foo' in %s on line %d
8179

8280
Warning: Array to string conversion in %s on line %d
81+
82+
Warning: Only the first byte will be assigned to the string offset in %s on line %d
8383
string(1) "A"
8484

8585
Warning: Illegal string offset 'foo' in %s on line %d
8686

8787
Warning: Array to string conversion in %s on line %d
88+
89+
Warning: Only the first byte will be assigned to the string offset in %s on line %d
8890
string(1) "A"
8991
Cannot use a scalar value as an array
9092
float(0.1)
@@ -187,5 +189,3 @@ array(1) {
187189
int(1)
188190
}
189191
}
190-
191-
Done

Zend/tests/str_offset_004.phpt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,7 @@ Warning: Illegal string offset: -20 in %sstr_offset_004.php on line %d
4545
string(15) "abCZefghijPQmno"
4646
string(15) "AbCZefghijPQmno"
4747
string(21) "AbCZefghijPQmno N"
48+
49+
Warning: Only the first byte will be assigned to the string offset in %s on line %d
4850
string(21) "AbCZefghijPQmno UN"
4951
string(21) "AbCZefghijPQmno nUN"

Zend/zend_execute.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,14 +1597,18 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim,
15971597
string_len = Z_STRLEN_P(value);
15981598
c = (zend_uchar)Z_STRVAL_P(value)[0];
15991599
}
1600-
1601-
if (string_len == 0) {
1602-
/* Error on empty input string */
1603-
zend_error(E_WARNING, "Cannot assign an empty string to a string offset");
1604-
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1605-
ZVAL_NULL(EX_VAR(opline->result.var));
1600+
1601+
if (string_len != 1) {
1602+
if (string_len == 0) {
1603+
/* Error on empty input string */
1604+
zend_throw_error(NULL, "Cannot assign an empty string to a string offset");
1605+
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
1606+
ZVAL_NULL(EX_VAR(opline->result.var));
1607+
}
1608+
return;
16061609
}
1607-
return;
1610+
1611+
zend_error(E_WARNING, "Only the first byte will be assigned to the string offset");
16081612
}
16091613

16101614
if (offset < 0) { /* Handle negative offset */

ext/opcache/jit/zend_jit_helpers.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -895,13 +895,18 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim,
895895
c = (zend_uchar)Z_STRVAL_P(value)[0];
896896
}
897897

898-
if (string_len == 0) {
899-
/* Error on empty input string */
900-
zend_error(E_WARNING, "Cannot assign an empty string to a string offset");
901-
if (result) {
902-
ZVAL_NULL(result);
898+
899+
if (string_len != 1) {
900+
if (string_len == 0) {
901+
/* Error on empty input string */
902+
zend_throw_error(NULL, "Cannot assign an empty string to a string offset");
903+
if (result) {
904+
ZVAL_NULL(result);
905+
}
906+
return;
903907
}
904-
return;
908+
909+
zend_error(E_WARNING, "Only the first byte will be assigned to the string offset");
905910
}
906911

907912
if (offset < 0) { /* Handle negative offset */

tests/lang/bug22592.phpt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,11 @@ var_dump($result);
3939
string(5) "* *-*"
4040
string(7) "* *-* *"
4141
string(7) "*4*-* *"
42+
[Only the first byte will be assigned to the string offset]
4243
string(7) "*4*s* *"
4344
string(8) "*4*s* *0"
4445
string(8) "*-*-* *0"
46+
[Only the first byte will be assigned to the string offset]
4547
string(8) "*-*s*s*0"
4648
string(8) "4-4s4s*0"
4749
string(9) "4-4s4s505"

0 commit comments

Comments
 (0)