From 02c6e8cfa81bc4c9e400a76af38a917e67761790 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 17 Jun 2022 13:34:20 +0200 Subject: [PATCH] Escape double quotes in worksheet names for column range and row range references --- src/PhpSpreadsheet/Calculation/Calculation.php | 6 +++++- .../PhpSpreadsheetTests/Calculation/ParseFormulaTest.php | 8 ++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 6fbf5da4..1b7f985e 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -4203,7 +4203,7 @@ class Calculation $expectingOperator = false; } $stack->push('Brace', '('); - } elseif (preg_match('/^' . self::CALCULATION_REGEXP_CELLREF . '$/i', $val, $matches)) { + } elseif (preg_match('/^' . self::CALCULATION_REGEXP_CELLREF . '$/miu', $val, $matches)) { // Watch for this case-change when modifying to allow cell references in different worksheets... // Should only be applied to the actual cell column, not the worksheet name // If the last entry on the stack was a : operator, then we have a cell range reference @@ -4326,6 +4326,8 @@ class Calculation $val = $rowRangeReference[1]; $length = strlen($rowRangeReference[1]); $stackItemType = 'Row Reference'; + // unescape any apostrophes or double quotes in worksheet name + $val = str_replace(["''", '""'], ["'", '"'], $val); $column = 'A'; if (($testPrevOp !== null && $testPrevOp['value'] === ':') && $pCellParent !== null) { $column = $pCellParent->getHighestDataColumn($val); @@ -4338,6 +4340,8 @@ class Calculation $val = $columnRangeReference[1]; $length = strlen($val); $stackItemType = 'Column Reference'; + // unescape any apostrophes or double quotes in worksheet name + $val = str_replace(["''", '""'], ["'", '"'], $val); $row = '1'; if (($testPrevOp !== null && $testPrevOp['value'] === ':') && $pCellParent !== null) { $row = $pCellParent->getHighestDataRow($val); diff --git a/tests/PhpSpreadsheetTests/Calculation/ParseFormulaTest.php b/tests/PhpSpreadsheetTests/Calculation/ParseFormulaTest.php index a9b79710..0ecb3f8b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/ParseFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/ParseFormulaTest.php @@ -176,8 +176,8 @@ class ParseFormulaTest extends TestCase ], 'Combined Cell Reference and Column Range with quote' => [ [ - ['type' => 'Column Reference', 'value' => "'Mark''s sheet1'!A1", 'reference' => "'Mark''s sheet1'!A1"], - ['type' => 'Column Reference', 'value' => "'Mark''s sheet1'!A1048576", 'reference' => "'Mark''s sheet1'!A1048576"], + ['type' => 'Column Reference', 'value' => "'Mark's sheet1'!A1", 'reference' => "'Mark's sheet1'!A1"], + ['type' => 'Column Reference', 'value' => "'Mark's sheet1'!A1048576", 'reference' => "'Mark's sheet1'!A1048576"], ['type' => 'Binary Operator', 'value' => ':', 'reference' => null], ['type' => 'Operand Count for Function MIN()', 'value' => 1, 'reference' => null], ['type' => 'Function', 'value' => 'MIN(', 'reference' => null], @@ -213,8 +213,8 @@ class ParseFormulaTest extends TestCase 'Combined Column Range and Cell Reference with quote' => [ [ ['type' => 'Cell Reference', 'value' => "'Mark's sheet1'!A1", 'reference' => "'Mark's sheet1'!A1"], - ['type' => 'Column Reference', 'value' => "'Mark''s sheet1'!A1", 'reference' => "'Mark''s sheet1'!A1"], - ['type' => 'Column Reference', 'value' => "'Mark''s sheet1'!A1048576", 'reference' => "'Mark''s sheet1'!A1048576"], + ['type' => 'Column Reference', 'value' => "'Mark's sheet1'!A1", 'reference' => "'Mark's sheet1'!A1"], + ['type' => 'Column Reference', 'value' => "'Mark's sheet1'!A1048576", 'reference' => "'Mark's sheet1'!A1048576"], ['type' => 'Binary Operator', 'value' => ':', 'reference' => null], ['type' => 'Operand Count for Function MIN()', 'value' => 1, 'reference' => null], ['type' => 'Function', 'value' => 'MIN(', 'reference' => null],