Skip to content

Commit a0f1efe

Browse files
committed
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.
1 parent 414f8a2 commit a0f1efe

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

src/PhpSpreadsheet/Writer/Xls/Parser.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1624,7 +1624,9 @@ public function toReversePolish(array $tree = []): string
16241624
}
16251625

16261626
// add its left subtree and return.
1627-
return $left_tree . $this->convertFunction($tree['value'], $tree['right']);
1627+
if ($left_tree !== '' || $tree['right'] !== '') {
1628+
return $left_tree . $this->convertFunction($tree['value'], $tree['right'] ?: 0);
1629+
}
16281630
}
16291631
$converted_tree = $this->convert($tree['value']);
16301632

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpOffice\PhpSpreadsheetTests\Writer\Xls;
6+
7+
use PhpOffice\PhpSpreadsheet\Spreadsheet;
8+
use PhpOffice\PhpSpreadsheetTests\Functional\AbstractFunctional;
9+
10+
class Issue4331Test extends AbstractFunctional
11+
{
12+
public function testIssue4331(): void
13+
{
14+
$spreadsheet = new Spreadsheet();
15+
$sheet = $spreadsheet->getActiveSheet();
16+
$c3 = '=VLOOKUP(B3,$B$10:$C$13,2,FALSE)';
17+
$d3 = '=VLOOKUP("intermediate",$B$10:$C$13,2,TRUE)';
18+
$c4 = '=VLOOKUP(B3,$B$10:$C$13,2,FALSE())';
19+
$d4 = '=VLOOKUP("intermediate",$B$10:$C$13,2,TRUE())';
20+
$sheet->fromArray(
21+
[
22+
['level', 'result'],
23+
['medium', $c3, $d3],
24+
[null, $c4, $d4],
25+
],
26+
null,
27+
'B2',
28+
true
29+
);
30+
$sheet->fromArray(
31+
[
32+
['high', 6],
33+
['low', 2],
34+
['medium', 4],
35+
['none', 0],
36+
],
37+
null,
38+
'B10',
39+
true
40+
);
41+
42+
$reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xls');
43+
$spreadsheet->disconnectWorksheets();
44+
45+
$worksheet = $reloadedSpreadsheet->getActiveSheet();
46+
self::assertSame($c3, $worksheet->getCell('C3')->getValue());
47+
self::assertSame(4, $worksheet->getCell('C3')->getCalculatedValue());
48+
self::assertSame($d3, $worksheet->getCell('D3')->getValue());
49+
self::assertSame(6, $worksheet->getCell('D3')->getCalculatedValue());
50+
self::assertSame($c4, $worksheet->getCell('C4')->getValue());
51+
self::assertSame(4, $worksheet->getCell('C4')->getCalculatedValue());
52+
self::assertSame($d4, $worksheet->getCell('D4')->getValue());
53+
self::assertSame(6, $worksheet->getCell('D4')->getCalculatedValue());
54+
$reloadedSpreadsheet->disconnectWorksheets();
55+
}
56+
}

0 commit comments

Comments
 (0)