Fix array to string conversion warning emitted in optimizer

Fixes GH-16408
Closes GH-16380
This commit is contained in:
Ilija Tovilo 2024-10-13 23:50:04 +02:00
parent 34e635f366
commit c5745f40a5
No known key found for this signature in database
GPG key ID: 5050C66BFCD1015A
3 changed files with 29 additions and 3 deletions

4
NEWS
View file

@ -34,6 +34,10 @@ PHP NEWS
. Fixed bug GH-16361 (mb_substr overflow on start/length arguments).
(David Carlier)
- Opcache:
. Fixed bug GH-16408 (Array to string conversion warning emitted in
optimizer). (ilutov)
- OpenSSL:
. Fixed bug GH-16357 (openssl may modify member types of certificate arrays).
(cmb)

View file

@ -34,6 +34,12 @@
#include "zend_execute.h"
#include "zend_vm.h"
#define TO_STRING_NOWARN(val) do { \
if (Z_TYPE_P(val) < IS_ARRAY) { \
convert_to_string(val); \
} \
} while (0)
static void replace_by_const_or_qm_assign(zend_op_array *op_array, zend_op *opline, zval *result) {
if (opline->op1_type == IS_CONST) {
literal_dtor(&ZEND_OP1_LITERAL(opline));
@ -64,10 +70,10 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
case ZEND_CONCAT:
case ZEND_FAST_CONCAT:
if (opline->op1_type == IS_CONST && Z_TYPE(ZEND_OP1_LITERAL(opline)) != IS_STRING) {
convert_to_string(&ZEND_OP1_LITERAL(opline));
TO_STRING_NOWARN(&ZEND_OP1_LITERAL(opline));
}
if (opline->op2_type == IS_CONST && Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_STRING) {
convert_to_string(&ZEND_OP2_LITERAL(opline));
TO_STRING_NOWARN(&ZEND_OP2_LITERAL(opline));
}
ZEND_FALLTHROUGH;
case ZEND_ADD:
@ -100,7 +106,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
case ZEND_ASSIGN_OP:
if (opline->extended_value == ZEND_CONCAT && opline->op2_type == IS_CONST
&& Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_STRING) {
convert_to_string(&ZEND_OP2_LITERAL(opline));
TO_STRING_NOWARN(&ZEND_OP2_LITERAL(opline));
}
break;

16
Zend/tests/gh16408.phpt Normal file
View file

@ -0,0 +1,16 @@
--TEST--
GH-16408: Array to string conversion warning emitted in optimizer
--FILE--
<?php
$counter = 0;
ob_start(function ($buffer) use (&$c, &$counter) {
$c = 0;
++$counter;
}, 1);
$c .= [];
$c .= [];
ob_end_clean();
echo $counter . "\n";
?>
--EXPECT--
3