Propagate UTF-8 flag during Rope operations (#10915)

This commit is contained in:
George Peter Banyard 2023-03-26 14:18:46 +01:00 committed by GitHub
parent a7f91e37de
commit d7c351ea54
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 50 additions and 14 deletions

View file

@ -3330,8 +3330,6 @@ ZEND_VM_HANDLER(56, ZEND_ROPE_END, TMP, CONST|TMPVAR|CV, NUM)
zend_string **rope;
zval *var, *ret;
uint32_t i;
size_t len = 0;
char *target;
rope = (zend_string**)EX_VAR(opline->op1.var);
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++) {
flags &= ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(rope[i]);
len += ZSTR_LEN(rope[i]);
}
ret = EX_VAR(opline->result.var);
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++) {
memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i]));
target += ZSTR_LEN(rope[i]);

30
Zend/zend_vm_execute.h generated
View file

@ -19867,8 +19867,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ROPE_END_SPEC_TMP_CONST_HANDLE
zend_string **rope;
zval *var, *ret;
uint32_t i;
size_t len = 0;
char *target;
rope = (zend_string**)EX_VAR(opline->op1.var);
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++) {
flags &= ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(rope[i]);
len += ZSTR_LEN(rope[i]);
}
ret = EX_VAR(opline->result.var);
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++) {
memcpy(target, ZSTR_VAL(rope[i]), 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;
zval *var, *ret;
uint32_t i;
size_t len = 0;
char *target;
rope = (zend_string**)EX_VAR(opline->op1.var);
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++) {
flags &= ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(rope[i]);
len += ZSTR_LEN(rope[i]);
}
ret = EX_VAR(opline->result.var);
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++) {
memcpy(target, ZSTR_VAL(rope[i]), 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;
zval *var, *ret;
uint32_t i;
size_t len = 0;
char *target;
rope = (zend_string**)EX_VAR(opline->op1.var);
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++) {
flags &= ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(rope[i]);
len += ZSTR_LEN(rope[i]);
}
ret = EX_VAR(opline->result.var);
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++) {
memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i]));
target += ZSTR_LEN(rope[i]);

View file

@ -3104,13 +3104,16 @@ static zend_string* ZEND_FASTCALL zend_jit_rope_end(zend_string **rope, uint32_t
zend_string *ret;
uint32_t i;
size_t len = 0;
char *target;
uint32_t flags = ZSTR_COPYABLE_CONCAT_PROPERTIES;
for (i = 0; i <= count; i++) {
flags &= ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(rope[i]);
len += ZSTR_LEN(rope[i]);
}
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++) {
memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i]));
target += ZSTR_LEN(rope[i]);

View file

@ -107,6 +107,13 @@ $s = $o . $o;
var_dump($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";
$string = "a";
$string_concat = str_repeat($string, 100);
@ -183,6 +190,8 @@ bool(true)
Concatenation of objects:
string(2) "zz"
bool(true)
Rope concat:
bool(true)
str_repeat:
bool(true)
bool(false)

View file

@ -102,6 +102,12 @@ $s = $o . $o;
$s = $s . $non_utf8;
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--
Integer cast to string concatenated to invalid UTF-8:
@ -129,3 +135,5 @@ Concatenation in loop (compound assignment):
bool(false)
Concatenation of objects:
bool(false)
Rope concat:
bool(false)