mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Propagate UTF-8 flag during Rope operations (#10915)
This commit is contained in:
parent
a7f91e37de
commit
d7c351ea54
5 changed files with 50 additions and 14 deletions
|
@ -3330,8 +3330,6 @@ ZEND_VM_HANDLER(56, ZEND_ROPE_END, TMP, CONST|TMPVAR|CV, NUM)
|
||||||
zend_string **rope;
|
zend_string **rope;
|
||||||
zval *var, *ret;
|
zval *var, *ret;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
size_t len = 0;
|
|
||||||
char *target;
|
|
||||||
|
|
||||||
rope = (zend_string**)EX_VAR(opline->op1.var);
|
rope = (zend_string**)EX_VAR(opline->op1.var);
|
||||||
if (OP2_TYPE == IS_CONST) {
|
if (OP2_TYPE == IS_CONST) {
|
||||||
|
@ -3364,12 +3362,18 @@ ZEND_VM_HANDLER(56, ZEND_ROPE_END, TMP, CONST|TMPVAR|CV, NUM)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t len = 0;
|
||||||
|
uint32_t flags = ZSTR_COPYABLE_CONCAT_PROPERTIES;
|
||||||
for (i = 0; i <= opline->extended_value; i++) {
|
for (i = 0; i <= opline->extended_value; i++) {
|
||||||
|
flags &= ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(rope[i]);
|
||||||
len += ZSTR_LEN(rope[i]);
|
len += ZSTR_LEN(rope[i]);
|
||||||
}
|
}
|
||||||
ret = EX_VAR(opline->result.var);
|
ret = EX_VAR(opline->result.var);
|
||||||
ZVAL_STR(ret, zend_string_alloc(len, 0));
|
ZVAL_STR(ret, zend_string_alloc(len, 0));
|
||||||
target = Z_STRVAL_P(ret);
|
GC_ADD_FLAGS(Z_STR_P(ret), flags);
|
||||||
|
|
||||||
|
char *target = Z_STRVAL_P(ret);
|
||||||
for (i = 0; i <= opline->extended_value; i++) {
|
for (i = 0; i <= opline->extended_value; i++) {
|
||||||
memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i]));
|
memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i]));
|
||||||
target += ZSTR_LEN(rope[i]);
|
target += ZSTR_LEN(rope[i]);
|
||||||
|
|
30
Zend/zend_vm_execute.h
generated
30
Zend/zend_vm_execute.h
generated
|
@ -19867,8 +19867,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_CONST_HANDLE
|
||||||
zend_string **rope;
|
zend_string **rope;
|
||||||
zval *var, *ret;
|
zval *var, *ret;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
size_t len = 0;
|
|
||||||
char *target;
|
|
||||||
|
|
||||||
rope = (zend_string**)EX_VAR(opline->op1.var);
|
rope = (zend_string**)EX_VAR(opline->op1.var);
|
||||||
if (IS_CONST == IS_CONST) {
|
if (IS_CONST == IS_CONST) {
|
||||||
|
@ -19901,12 +19899,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_CONST_HANDLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t len = 0;
|
||||||
|
uint32_t flags = ZSTR_COPYABLE_CONCAT_PROPERTIES;
|
||||||
for (i = 0; i <= opline->extended_value; i++) {
|
for (i = 0; i <= opline->extended_value; i++) {
|
||||||
|
flags &= ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(rope[i]);
|
||||||
len += ZSTR_LEN(rope[i]);
|
len += ZSTR_LEN(rope[i]);
|
||||||
}
|
}
|
||||||
ret = EX_VAR(opline->result.var);
|
ret = EX_VAR(opline->result.var);
|
||||||
ZVAL_STR(ret, zend_string_alloc(len, 0));
|
ZVAL_STR(ret, zend_string_alloc(len, 0));
|
||||||
target = Z_STRVAL_P(ret);
|
GC_ADD_FLAGS(Z_STR_P(ret), flags);
|
||||||
|
|
||||||
|
char *target = Z_STRVAL_P(ret);
|
||||||
for (i = 0; i <= opline->extended_value; i++) {
|
for (i = 0; i <= opline->extended_value; i++) {
|
||||||
memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i]));
|
memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i]));
|
||||||
target += ZSTR_LEN(rope[i]);
|
target += ZSTR_LEN(rope[i]);
|
||||||
|
@ -20344,8 +20348,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_TMPVAR_HANDL
|
||||||
zend_string **rope;
|
zend_string **rope;
|
||||||
zval *var, *ret;
|
zval *var, *ret;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
size_t len = 0;
|
|
||||||
char *target;
|
|
||||||
|
|
||||||
rope = (zend_string**)EX_VAR(opline->op1.var);
|
rope = (zend_string**)EX_VAR(opline->op1.var);
|
||||||
if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
|
if ((IS_TMP_VAR|IS_VAR) == IS_CONST) {
|
||||||
|
@ -20378,12 +20380,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_TMPVAR_HANDL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t len = 0;
|
||||||
|
uint32_t flags = ZSTR_COPYABLE_CONCAT_PROPERTIES;
|
||||||
for (i = 0; i <= opline->extended_value; i++) {
|
for (i = 0; i <= opline->extended_value; i++) {
|
||||||
|
flags &= ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(rope[i]);
|
||||||
len += ZSTR_LEN(rope[i]);
|
len += ZSTR_LEN(rope[i]);
|
||||||
}
|
}
|
||||||
ret = EX_VAR(opline->result.var);
|
ret = EX_VAR(opline->result.var);
|
||||||
ZVAL_STR(ret, zend_string_alloc(len, 0));
|
ZVAL_STR(ret, zend_string_alloc(len, 0));
|
||||||
target = Z_STRVAL_P(ret);
|
GC_ADD_FLAGS(Z_STR_P(ret), flags);
|
||||||
|
|
||||||
|
char *target = Z_STRVAL_P(ret);
|
||||||
for (i = 0; i <= opline->extended_value; i++) {
|
for (i = 0; i <= opline->extended_value; i++) {
|
||||||
memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i]));
|
memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i]));
|
||||||
target += ZSTR_LEN(rope[i]);
|
target += ZSTR_LEN(rope[i]);
|
||||||
|
@ -21205,8 +21213,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_CV_HANDLER(Z
|
||||||
zend_string **rope;
|
zend_string **rope;
|
||||||
zval *var, *ret;
|
zval *var, *ret;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
size_t len = 0;
|
|
||||||
char *target;
|
|
||||||
|
|
||||||
rope = (zend_string**)EX_VAR(opline->op1.var);
|
rope = (zend_string**)EX_VAR(opline->op1.var);
|
||||||
if (IS_CV == IS_CONST) {
|
if (IS_CV == IS_CONST) {
|
||||||
|
@ -21239,12 +21245,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_CV_HANDLER(Z
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t len = 0;
|
||||||
|
uint32_t flags = ZSTR_COPYABLE_CONCAT_PROPERTIES;
|
||||||
for (i = 0; i <= opline->extended_value; i++) {
|
for (i = 0; i <= opline->extended_value; i++) {
|
||||||
|
flags &= ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(rope[i]);
|
||||||
len += ZSTR_LEN(rope[i]);
|
len += ZSTR_LEN(rope[i]);
|
||||||
}
|
}
|
||||||
ret = EX_VAR(opline->result.var);
|
ret = EX_VAR(opline->result.var);
|
||||||
ZVAL_STR(ret, zend_string_alloc(len, 0));
|
ZVAL_STR(ret, zend_string_alloc(len, 0));
|
||||||
target = Z_STRVAL_P(ret);
|
GC_ADD_FLAGS(Z_STR_P(ret), flags);
|
||||||
|
|
||||||
|
char *target = Z_STRVAL_P(ret);
|
||||||
for (i = 0; i <= opline->extended_value; i++) {
|
for (i = 0; i <= opline->extended_value; i++) {
|
||||||
memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i]));
|
memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i]));
|
||||||
target += ZSTR_LEN(rope[i]);
|
target += ZSTR_LEN(rope[i]);
|
||||||
|
|
|
@ -3104,13 +3104,16 @@ static zend_string* ZEND_FASTCALL zend_jit_rope_end(zend_string **rope, uint32_t
|
||||||
zend_string *ret;
|
zend_string *ret;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
char *target;
|
|
||||||
|
|
||||||
|
uint32_t flags = ZSTR_COPYABLE_CONCAT_PROPERTIES;
|
||||||
for (i = 0; i <= count; i++) {
|
for (i = 0; i <= count; i++) {
|
||||||
|
flags &= ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(rope[i]);
|
||||||
len += ZSTR_LEN(rope[i]);
|
len += ZSTR_LEN(rope[i]);
|
||||||
}
|
}
|
||||||
ret = zend_string_alloc(len, 0);
|
ret = zend_string_alloc(len, 0);
|
||||||
target = ZSTR_VAL(ret);
|
GC_ADD_FLAGS(ret, flags);
|
||||||
|
|
||||||
|
char *target = ZSTR_VAL(ret);
|
||||||
for (i = 0; i <= count; i++) {
|
for (i = 0; i <= count; i++) {
|
||||||
memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i]));
|
memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i]));
|
||||||
target += ZSTR_LEN(rope[i]);
|
target += ZSTR_LEN(rope[i]);
|
||||||
|
|
|
@ -107,6 +107,13 @@ $s = $o . $o;
|
||||||
var_dump($s);
|
var_dump($s);
|
||||||
var_dump(zend_test_is_string_marked_as_valid_utf8($s));
|
var_dump(zend_test_is_string_marked_as_valid_utf8($s));
|
||||||
|
|
||||||
|
echo "Rope concat:\n";
|
||||||
|
$foo = 'f';
|
||||||
|
$bar = 'b';
|
||||||
|
$baz = 'a';
|
||||||
|
$rope = "$foo$bar$baz";
|
||||||
|
var_dump(zend_test_is_string_marked_as_valid_utf8($rope));
|
||||||
|
|
||||||
echo "str_repeat:\n";
|
echo "str_repeat:\n";
|
||||||
$string = "a";
|
$string = "a";
|
||||||
$string_concat = str_repeat($string, 100);
|
$string_concat = str_repeat($string, 100);
|
||||||
|
@ -183,6 +190,8 @@ bool(true)
|
||||||
Concatenation of objects:
|
Concatenation of objects:
|
||||||
string(2) "zz"
|
string(2) "zz"
|
||||||
bool(true)
|
bool(true)
|
||||||
|
Rope concat:
|
||||||
|
bool(true)
|
||||||
str_repeat:
|
str_repeat:
|
||||||
bool(true)
|
bool(true)
|
||||||
bool(false)
|
bool(false)
|
||||||
|
|
|
@ -102,6 +102,12 @@ $s = $o . $o;
|
||||||
$s = $s . $non_utf8;
|
$s = $s . $non_utf8;
|
||||||
var_dump(zend_test_is_string_marked_as_valid_utf8($s));
|
var_dump(zend_test_is_string_marked_as_valid_utf8($s));
|
||||||
|
|
||||||
|
echo "Rope concat:\n";
|
||||||
|
$foo = 'f';
|
||||||
|
$bar = "\xc3";
|
||||||
|
$baz = 'a';
|
||||||
|
$rope = "$foo$bar$baz";
|
||||||
|
var_dump(zend_test_is_string_marked_as_valid_utf8($rope));
|
||||||
?>
|
?>
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
Integer cast to string concatenated to invalid UTF-8:
|
Integer cast to string concatenated to invalid UTF-8:
|
||||||
|
@ -129,3 +135,5 @@ Concatenation in loop (compound assignment):
|
||||||
bool(false)
|
bool(false)
|
||||||
Concatenation of objects:
|
Concatenation of objects:
|
||||||
bool(false)
|
bool(false)
|
||||||
|
Rope concat:
|
||||||
|
bool(false)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue