fix(parser): safely omit empty concat literals

pull/19/head
韩天峰 2 months ago
parent 5af5cbb837
commit 20b54e3961
  1. 16
      src/Parser/BinaryOpTrait.php
  2. 21
      tests/compiler/concat_empty.phpt

@ -264,17 +264,17 @@ trait BinaryOpTrait
$this->flattenConcatExpr($expr, $items); $this->flattenConcatExpr($expr, $items);
$argList = $prefixExpressions; $argList = $prefixExpressions;
foreach ($items as $index => $item) { foreach ($items as $item) {
// 在字符串拼接中,除了第一个元素之外,剩下的字符串如果出现空字符串,忽略这个字符串 // Keep one operand so concat still performs PHP string coercion.
if ($index > 0 && $item->value == '') { // Prefix expressions are operands too (for example, the left-hand
// value of `.=`), so an empty RHS literal can be omitted there.
if ($argList !== [] && $this->isScalarString($item) && $item->value === '') {
continue; continue;
} }
$argList[] = $this->prepareConcatOperand($this->parseExprAsValue($item), $this->detectTypeOfExpr($item)); $type = $this->detectTypeOfExpr($item);
} $parsed = $this->parseExprAsValue($item);
$argList[] = $this->prepareConcatOperand($parsed, $type);
if (sizeof($argList) == 1) {
return $argList[0];
} }
return Symbol::concat() . '({' . implode(', ', $argList) . '})'; return Symbol::concat() . '({' . implode(', ', $argList) . '})';

@ -5,8 +5,29 @@ Concat empty strings
function main() { function main() {
var_dump('' . 1 . '' . 'a' . ''); var_dump('' . 1 . '' . 'a' . '');
var_dump('' . 1); var_dump('' . 1);
var_dump(1 . '');
var_dump(false . '');
var_dump('' . '' . '');
$value = 'value';
var_dump('' . $value . '');
var_dump('' . get_value() . '');
$number = 1;
$number .= '';
var_dump($number);
}
function get_value(): string {
return 'called';
} }
?> ?>
--EXPECT-- --EXPECT--
string(2) "1a" string(2) "1a"
string(1) "1" string(1) "1"
string(1) "1"
string(0) ""
string(0) ""
string(5) "value"
string(6) "called"
string(1) "1"

Loading…
Cancel
Save