Xls Writer Parser Mis-handling TRUE/FALSE As VLOOKUP Arguments

Fix #4331. Parser treats TRUE/FALSE as functions rather than constants, which is nominally harmless, but it then expects an argument count of 0 and instead sees null-string. Changed to recognize this situation and leave TRUE/FALSE/TRUE()/FALSE() unchanged.
This commit is contained in:
oleibman
2025-01-28 20:24:41 -08:00
parent 414f8a2aa1
commit a0f1efea42
2 changed files with 59 additions and 1 deletions
+3 -1
View File
@@ -1624,7 +1624,9 @@ class Parser
}
// add its left subtree and return.
return $left_tree . $this->convertFunction($tree['value'], $tree['right']);
if ($left_tree !== '' || $tree['right'] !== '') {
return $left_tree . $this->convertFunction($tree['value'], $tree['right'] ?: 0);
}
}
$converted_tree = $this->convert($tree['value']);
@@ -0,0 +1,56 @@
<?php
declare(strict_types=1);
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xls;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
class Issue4331Test extends AbstractFunctional
{
public function testIssue4331(): void
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$c3 = '=VLOOKUP(B3,$B$10:$C$13,2,FALSE)';
$d3 = '=VLOOKUP("intermediate",$B$10:$C$13,2,TRUE)';
$c4 = '=VLOOKUP(B3,$B$10:$C$13,2,FALSE())';
$d4 = '=VLOOKUP("intermediate",$B$10:$C$13,2,TRUE())';
$sheet->fromArray(
[
['level', 'result'],
['medium', $c3, $d3],
[null, $c4, $d4],
],
null,
'B2',
true
);
$sheet->fromArray(
[
['high', 6],
['low', 2],
['medium', 4],
['none', 0],
],
null,
'B10',
true
);
$reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xls');
$spreadsheet->disconnectWorksheets();
$worksheet = $reloadedSpreadsheet->getActiveSheet();
self::assertSame($c3, $worksheet->getCell('C3')->getValue());
self::assertSame(4, $worksheet->getCell('C3')->getCalculatedValue());
self::assertSame($d3, $worksheet->getCell('D3')->getValue());
self::assertSame(6, $worksheet->getCell('D3')->getCalculatedValue());
self::assertSame($c4, $worksheet->getCell('C4')->getValue());
self::assertSame(4, $worksheet->getCell('C4')->getCalculatedValue());
self::assertSame($d4, $worksheet->getCell('D4')->getValue());
self::assertSame(6, $worksheet->getCell('D4')->getCalculatedValue());
$reloadedSpreadsheet->disconnectWorksheets();
}
}