[bug-66022] issue in Formula Parser with some sheet names

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1901162 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2022-05-23 10:55:22 +00:00
parent 435dc86896
commit 04be6fcccb
3 changed files with 34 additions and 8 deletions

View File

@ -407,6 +407,7 @@ public final class TestXSSFFormulaParser {
Sheet sheet1 = wb.createSheet("Sheet1"); Sheet sheet1 = wb.createSheet("Sheet1");
Sheet sheet2 = wb.createSheet("Sheet2"); Sheet sheet2 = wb.createSheet("Sheet2");
Sheet sheet3 = wb.createSheet("Sheet 3"); Sheet sheet3 = wb.createSheet("Sheet 3");
Sheet sheet4 = wb.createSheet("Sheet4>");
Row tempRow = sheet1.createRow(0); Row tempRow = sheet1.createRow(0);
tempRow.createCell(0).setCellValue(1); tempRow.createCell(0).setCellValue(1);
@ -420,6 +421,10 @@ public final class TestXSSFFormulaParser {
tempRow.createCell(0).setCellValue(5); tempRow.createCell(0).setCellValue(5);
tempRow.createCell(1).setCellValue(6); tempRow.createCell(1).setCellValue(6);
tempRow = sheet4.createRow(0);
tempRow.createCell(0).setCellValue(5);
tempRow.createCell(1).setCellValue(6);
Cell cell = tempRow.createCell(2); Cell cell = tempRow.createCell(2);
// unquoted sheet names // unquoted sheet names
@ -441,6 +446,20 @@ public final class TestXSSFFormulaParser {
cell.setCellFormula(formula); cell.setCellFormula(formula);
cellFormula = cell.getCellFormula(); cellFormula = cell.getCellFormula();
assertEquals(formula, cellFormula); assertEquals(formula, cellFormula);
// quoted sheet names with special character
cell = tempRow.createCell(5);
formula = "SUM('Sheet1:Sheet4>'!A1:B1)";
cell.setCellFormula(formula);
cellFormula = cell.getCellFormula();
assertEquals(formula, cellFormula);
// quoted sheet names with special character #2
// cell = tempRow.createCell(6);
// formula = "SUM('Sheet 3:Sheet4>'!A1:B1)";
// cell.setCellFormula(formula);
// cellFormula = cell.getCellFormula();
// assertEquals(formula, cellFormula);
} }
} }

View File

@ -465,7 +465,7 @@ public final class FormulaParser {
private ParseNode parseRangeable() { private ParseNode parseRangeable() {
SkipWhite(); SkipWhite();
int savePointer = _pointer; int savePointer = _pointer;
SheetIdentifier sheetIden = parseSheetName(); SheetIdentifier sheetIden = parseSheetName(false);
if (sheetIden == null) { if (sheetIden == null) {
resetPointer(savePointer); resetPointer(savePointer);
@ -1154,7 +1154,7 @@ public final class FormulaParser {
* Note - caller should reset {@link #_pointer} upon {@code null} result * Note - caller should reset {@link #_pointer} upon {@code null} result
* @return The sheet name as an identifier {@code null} if '!' is not found in the right place * @return The sheet name as an identifier {@code null} if '!' is not found in the right place
*/ */
private SheetIdentifier parseSheetName() { private SheetIdentifier parseSheetName(boolean isSndPartOfQuotedRange) {
String bookName; String bookName;
if (look == '[') { if (look == '[') {
bookName = getBookName(); bookName = getBookName();
@ -1162,8 +1162,10 @@ public final class FormulaParser {
bookName = null; bookName = null;
} }
if (look == '\'') { if (look == '\'' || isSndPartOfQuotedRange) {
Match('\''); if (!isSndPartOfQuotedRange) {
Match('\'');
}
if (look == '[') if (look == '[')
bookName = getBookName(); bookName = getBookName();
@ -1197,7 +1199,7 @@ public final class FormulaParser {
} }
// See if it's a multi-sheet range, eg Sheet1:Sheet3!A1 // See if it's a multi-sheet range, eg Sheet1:Sheet3!A1
if (look == ':') { if (look == ':') {
return parseSheetRange(bookName, iden); return parseSheetRange(bookName, iden, true);
} }
return null; return null;
} }
@ -1221,7 +1223,7 @@ public final class FormulaParser {
} }
// See if it's a multi-sheet range, eg Sheet1:Sheet3!A1 // See if it's a multi-sheet range, eg Sheet1:Sheet3!A1
if (look == ':') { if (look == ':') {
return parseSheetRange(bookName, iden); return parseSheetRange(bookName, iden, false);
} }
return null; return null;
} }
@ -1237,9 +1239,9 @@ public final class FormulaParser {
* If we have something that looks like [book]Sheet1: or * If we have something that looks like [book]Sheet1: or
* Sheet1, see if it's actually a range eg Sheet1:Sheet2! * Sheet1, see if it's actually a range eg Sheet1:Sheet2!
*/ */
private SheetIdentifier parseSheetRange(String bookname, NameIdentifier sheet1Name) { private SheetIdentifier parseSheetRange(String bookname, NameIdentifier sheet1Name, boolean isSndPartOfQuotedRange) {
GetChar(); GetChar();
SheetIdentifier sheet2 = parseSheetName(); SheetIdentifier sheet2 = parseSheetName(isSndPartOfQuotedRange);
if (sheet2 != null) { if (sheet2 != null) {
return new SheetRangeIdentifier(bookname, sheet1Name, sheet2.getSheetIdentifier()); return new SheetRangeIdentifier(bookname, sheet1Name, sheet2.getSheetIdentifier());
} }

View File

@ -515,6 +515,7 @@ final class TestFormulaParser {
wb.createSheet("Cash_Flow"); wb.createSheet("Cash_Flow");
wb.createSheet("Test Sheet"); wb.createSheet("Test Sheet");
wb.createSheet("Sheet 3>");
HSSFSheet sheet = wb.createSheet("Test"); HSSFSheet sheet = wb.createSheet("Test");
HSSFRow row = sheet.createRow(0); HSSFRow row = sheet.createRow(0);
@ -539,6 +540,10 @@ final class TestFormulaParser {
formula = cell.getCellFormula(); formula = cell.getCellFormula();
assertEquals("'Cash_Flow:Test Sheet'!A1", formula); assertEquals("'Cash_Flow:Test Sheet'!A1", formula);
// special character
cell.setCellFormula("'Cash_Flow:Sheet 3>'!A1");
formula = cell.getCellFormula();
assertEquals("'Cash_Flow:Sheet 3>'!A1", formula);
// References to a range (area) of cells: // References to a range (area) of cells: