From 85d6f81076332ddfd73e124644ceec110d855d53 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Sun, 30 Dec 2018 22:44:40 +0000 Subject: [PATCH] Bug 60460: Handle null workbook or sheet names and emit #REF as Excel does instead of throwing NullPointerException git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1850008 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/stress/SpreadsheetHandler.java | 9 +- .../poi/ss/formula/SheetNameFormatter.java | 177 ++++++++++-------- .../SheetRangeAndWorkbookIndexFormatter.java | 4 +- .../formula/ptg/ExternSheetNameResolver.java | 2 +- .../apache/poi/hssf/usermodel/TestBugs.java | 17 ++ .../ss/formula/TestSheetNameFormatter.java | 117 +++++++++++- test-data/spreadsheet/60460.xls | Bin 0 -> 68096 bytes 7 files changed, 239 insertions(+), 87 deletions(-) create mode 100644 test-data/spreadsheet/60460.xls diff --git a/src/integrationtest/org/apache/poi/stress/SpreadsheetHandler.java b/src/integrationtest/org/apache/poi/stress/SpreadsheetHandler.java index 05147ff6d0..38f633b4cd 100644 --- a/src/integrationtest/org/apache/poi/stress/SpreadsheetHandler.java +++ b/src/integrationtest/org/apache/poi/stress/SpreadsheetHandler.java @@ -22,10 +22,10 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.ss.extractor.EmbeddedData; import org.apache.poi.ss.extractor.EmbeddedExtractor; import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Name; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; @@ -91,6 +91,13 @@ public abstract class SpreadsheetHandler extends AbstractFileHandler { } } } + + for (Name name : wb.getAllNames()) { + // this sometimes caused exceptions + if(!name.isFunctionName()) { + name.getRefersToFormula(); + } + } } private void extractEmbedded(Workbook wb) throws IOException { diff --git a/src/java/org/apache/poi/ss/formula/SheetNameFormatter.java b/src/java/org/apache/poi/ss/formula/SheetNameFormatter.java index 6e10e67c58..37daee5165 100644 --- a/src/java/org/apache/poi/ss/formula/SheetNameFormatter.java +++ b/src/java/org/apache/poi/ss/formula/SheetNameFormatter.java @@ -17,11 +17,13 @@ package org.apache.poi.ss.formula; +import java.io.IOException; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.poi.ss.util.CellReference; import org.apache.poi.ss.SpreadsheetVersion; +import org.apache.poi.util.Removal; /** * Formats sheet names for use in formula expressions. @@ -47,106 +49,134 @@ public final class SheetNameFormatter { * sheet name will be converted to double single quotes (''). */ public static String format(String rawSheetName) { - StringBuilder sb = new StringBuilder(rawSheetName.length() + 2); + StringBuilder sb = new StringBuilder((rawSheetName == null ? 0 : rawSheetName.length()) + 2); appendFormat(sb, rawSheetName); return sb.toString(); } - - /** - * Convenience method for ({@link #format(String)}) when a StringBuffer is already available. - * - * @param out - sheet name will be appended here possibly with delimiting quotes - * @param rawSheetName - sheet name - * @deprecated use appendFormat(StringBuilder out, String rawSheetName) instead - */ - @Deprecated - public static void appendFormat(StringBuffer out, String rawSheetName) { - boolean needsQuotes = needsDelimiting(rawSheetName); - if(needsQuotes) { - out.append(DELIMITER); - appendAndEscape(out, rawSheetName); - out.append(DELIMITER); - } else { - out.append(rawSheetName); - } - } /** - * @deprecated use appendFormat(StringBuilder out, String workbookName, String rawSheetName) instead + * @deprecated Only kept for binary compatibility, will be replaced by the version with Appendable as parameter */ @Deprecated - public static void appendFormat(StringBuffer out, String workbookName, String rawSheetName) { - boolean needsQuotes = needsDelimiting(workbookName) || needsDelimiting(rawSheetName); - if(needsQuotes) { - out.append(DELIMITER); - out.append('['); - appendAndEscape(out, workbookName.replace('[', '(').replace(']', ')')); - out.append(']'); - appendAndEscape(out, rawSheetName); - out.append(DELIMITER); - } else { - out.append('['); - out.append(workbookName); - out.append(']'); - out.append(rawSheetName); + @Removal(version="5.0.0") + public static void appendFormat(StringBuffer out, String rawSheetName) { + appendFormat((Appendable)out, rawSheetName); + } + + /** + * @deprecated Only kept for binary compatibility, will be replaced by the version with Appendable as parameter + */ + @Deprecated + @Removal(version="5.0.0") + public static void appendFormat(StringBuffer out, String workbookName, String rawSheetName) { + appendFormat((Appendable)out, workbookName, rawSheetName); + } + + /** + * Only kept for binary compatibility, will be replaced by the version with Appendable as parameter + */ + @Removal(version="5.0.0") + public static void appendFormat(StringBuilder out, String rawSheetName) { + appendFormat((Appendable)out, rawSheetName); + } + + /** + * Only kept for binary compatibility, will be replaced by the version with Appendable as parameter + */ + @Removal(version="5.0.0") + public static void appendFormat(StringBuilder out, String workbookName, String rawSheetName) { + appendFormat((Appendable)out, workbookName, rawSheetName); + } + + /** + * Convenience method for ({@link #format(String)}) when a StringBuffer is already available. + * + * @param out - sheet name will be appended here possibly with delimiting quotes + * @param rawSheetName - sheet name + */ + public static void appendFormat(Appendable out, String rawSheetName) { + try { + boolean needsQuotes = needsDelimiting(rawSheetName); + if(needsQuotes) { + out.append(DELIMITER); + appendAndEscape(out, rawSheetName); + out.append(DELIMITER); + } else { + appendAndEscape(out, rawSheetName); + } + } catch (Exception e) { + throw new RuntimeException(e); } } /** - * Convenience method for ({@link #format(String)}) when a StringBuilder is already available. + * Convenience method for ({@link #format(String)}) when a StringBuffer is already available. * * @param out - sheet name will be appended here possibly with delimiting quotes - * @param rawSheetName - sheet name + * @param workbookName - workbook name + * @param rawSheetName - sheet name */ - public static void appendFormat(StringBuilder out, String rawSheetName) { - boolean needsQuotes = needsDelimiting(rawSheetName); - if(needsQuotes) { - out.append(DELIMITER); - appendAndEscape(out, rawSheetName); - out.append(DELIMITER); - } else { - out.append(rawSheetName); + public static void appendFormat(Appendable out, String workbookName, String rawSheetName) { + try { + boolean needsQuotes = needsDelimiting(workbookName) || needsDelimiting(rawSheetName); + if(needsQuotes) { + out.append(DELIMITER); + out.append('['); + appendAndEscape(out, workbookName.replace('[', '(').replace(']', ')')); + out.append(']'); + appendAndEscape(out, rawSheetName); + out.append(DELIMITER); + } else { + out.append('['); + appendOrREF(out, workbookName); + out.append(']'); + appendOrREF(out, rawSheetName); + } + } catch (Exception e) { + throw new RuntimeException(e); } } - public static void appendFormat(StringBuilder out, String workbookName, String rawSheetName) { - boolean needsQuotes = needsDelimiting(workbookName) || needsDelimiting(rawSheetName); - if(needsQuotes) { - out.append(DELIMITER); - out.append('['); - appendAndEscape(out, workbookName.replace('[', '(').replace(']', ')')); - out.append(']'); - appendAndEscape(out, rawSheetName); - out.append(DELIMITER); + + private static void appendOrREF(Appendable out, String name) throws IOException { + if(name == null) { + out.append("#REF"); } else { - out.append('['); - out.append(workbookName); - out.append(']'); - out.append(rawSheetName); + out.append(name); } } - static void appendAndEscape(Appendable sb, String rawSheetName) { - int len = rawSheetName.length(); - for(int i=0; itrue if the presence of the specified character in a sheet name would * require the sheet name to be delimited in formulas. This includes every non-alphanumeric diff --git a/src/java/org/apache/poi/ss/formula/SheetRangeAndWorkbookIndexFormatter.java b/src/java/org/apache/poi/ss/formula/SheetRangeAndWorkbookIndexFormatter.java index 24d39cf274..3ee1d77df5 100644 --- a/src/java/org/apache/poi/ss/formula/SheetRangeAndWorkbookIndexFormatter.java +++ b/src/java/org/apache/poi/ss/formula/SheetRangeAndWorkbookIndexFormatter.java @@ -66,8 +66,8 @@ public class SheetRangeAndWorkbookIndexFormatter { } private static boolean anySheetNameNeedsEscaping(String firstSheetName, String lastSheetName) { - boolean anySheetNameNeedsDelimiting = firstSheetName != null && SheetNameFormatter.needsDelimiting(firstSheetName); - anySheetNameNeedsDelimiting |= lastSheetName != null && SheetNameFormatter.needsDelimiting(lastSheetName); + boolean anySheetNameNeedsDelimiting = SheetNameFormatter.needsDelimiting(firstSheetName); + anySheetNameNeedsDelimiting |= SheetNameFormatter.needsDelimiting(lastSheetName); return anySheetNameNeedsDelimiting; } } diff --git a/src/java/org/apache/poi/ss/formula/ptg/ExternSheetNameResolver.java b/src/java/org/apache/poi/ss/formula/ptg/ExternSheetNameResolver.java index c1989e17db..2717662d2b 100644 --- a/src/java/org/apache/poi/ss/formula/ptg/ExternSheetNameResolver.java +++ b/src/java/org/apache/poi/ss/formula/ptg/ExternSheetNameResolver.java @@ -37,7 +37,7 @@ final class ExternSheetNameResolver { String wbName = externalSheet.getWorkbookName(); String sheetName = externalSheet.getSheetName(); if (wbName != null) { - sb = new StringBuilder(wbName.length() + sheetName.length() + cellRefText.length() + 4); + sb = new StringBuilder(wbName.length() + (sheetName == null ? 0 : sheetName.length()) + cellRefText.length() + 4); SheetNameFormatter.appendFormat(sb, wbName, sheetName); } else { sb = new StringBuilder(sheetName.length() + cellRefText.length() + 4); diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java index fda515f7ce..333704fd82 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java @@ -3135,4 +3135,21 @@ public final class TestBugs extends BaseTestBugzillaIssues { assertEquals("\uFF2D\uFF33 \uFF30\u30B4\u30B7\u30C3\u30AF", font.getFontName()); } } + + @Test + public void test60460() throws IOException { + final Workbook wb = HSSFTestDataSamples.openSampleWorkbook("60460.xls"); + + assertEquals(2, wb.getAllNames().size()); + + Name rangedName = wb.getAllNames().get(0); + assertFalse(rangedName.isFunctionName()); + assertEquals("'[\\\\HEPPC3/gt$/Teaching/Syn/physyn.xls]#REF'!$AK$70:$AL$70", rangedName.getRefersToFormula()); + + rangedName = wb.getAllNames().get(1); + assertFalse(rangedName.isFunctionName()); + assertEquals("Questionnaire!$A$1:$L$65", rangedName.getRefersToFormula()); + + wb.close(); + } } diff --git a/src/testcases/org/apache/poi/ss/formula/TestSheetNameFormatter.java b/src/testcases/org/apache/poi/ss/formula/TestSheetNameFormatter.java index 2125810923..76a4fc7ac2 100644 --- a/src/testcases/org/apache/poi/ss/formula/TestSheetNameFormatter.java +++ b/src/testcases/org/apache/poi/ss/formula/TestSheetNameFormatter.java @@ -17,22 +17,23 @@ package org.apache.poi.ss.formula; -import junit.framework.TestCase; +import org.junit.Test; + +import java.io.IOException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; /** * Tests for {@link SheetNameFormatter} * * @author Josh Micich */ -public final class TestSheetNameFormatter extends TestCase { - - private static void confirmFormat(String rawSheetName, String expectedSheetNameEncoding) { - assertEquals(expectedSheetNameEncoding, SheetNameFormatter.format(rawSheetName)); - } - +public final class TestSheetNameFormatter { /** * Tests main public method 'format' */ + @Test public void testFormat() { confirmFormat("abc", "abc"); @@ -43,14 +44,108 @@ public final class TestSheetNameFormatter extends TestCase { confirmFormat("O'Brian", "'O''Brian'"); // single quote gets doubled - confirmFormat("3rdTimeLucky", "'3rdTimeLucky'"); // digit in first pos confirmFormat("_", "_"); // plain underscore OK confirmFormat("my_3rd_sheet", "my_3rd_sheet"); // underscores and digits OK confirmFormat("A12220", "'A12220'"); - confirmFormat("TAXRETURN19980415", "TAXRETURN19980415"); + confirmFormat("TAXRETURN19980415", "TAXRETURN19980415"); + + confirmFormat(null, "#REF"); } - + + private static void confirmFormat(String rawSheetName, String expectedSheetNameEncoding) { + // test all variants + + assertEquals(expectedSheetNameEncoding, SheetNameFormatter.format(rawSheetName)); + + StringBuilder sb = new StringBuilder(); + SheetNameFormatter.appendFormat(sb, rawSheetName); + assertEquals(expectedSheetNameEncoding, sb.toString()); + + sb = new StringBuilder(); + SheetNameFormatter.appendFormat((Appendable)sb, rawSheetName); + assertEquals(expectedSheetNameEncoding, sb.toString()); + + StringBuffer sbf = new StringBuffer(); + //noinspection deprecation + SheetNameFormatter.appendFormat(sbf, rawSheetName); + assertEquals(expectedSheetNameEncoding, sbf.toString()); + } + + @Test + public void testFormatWithWorkbookName() { + + confirmFormat("abc", "abc", "[abc]abc"); + confirmFormat("abc", "123", "'[abc]123'"); + + confirmFormat("abc", "my sheet", "'[abc]my sheet'"); // space + confirmFormat("abc", "A:MEM", "'[abc]A:MEM'"); // colon + + confirmFormat("abc", "O'Brian", "'[abc]O''Brian'"); // single quote gets doubled + + confirmFormat("abc", "3rdTimeLucky", "'[abc]3rdTimeLucky'"); // digit in first pos + confirmFormat("abc", "_", "[abc]_"); // plain underscore OK + confirmFormat("abc", "my_3rd_sheet", "[abc]my_3rd_sheet"); // underscores and digits OK + confirmFormat("abc", "A12220", "'[abc]A12220'"); + confirmFormat("abc", "TAXRETURN19980415", "[abc]TAXRETURN19980415"); + + confirmFormat("abc", null, "[abc]#REF"); + confirmFormat(null, "abc", "[#REF]abc"); + confirmFormat(null, null, "[#REF]#REF"); + } + + private static void confirmFormat(String workbookName, String rawSheetName, String expectedSheetNameEncoding) { + // test all variants + + StringBuilder sb = new StringBuilder(); + SheetNameFormatter.appendFormat(sb, workbookName, rawSheetName); + assertEquals(expectedSheetNameEncoding, sb.toString()); + + sb = new StringBuilder(); + SheetNameFormatter.appendFormat((Appendable)sb, workbookName, rawSheetName); + assertEquals(expectedSheetNameEncoding, sb.toString()); + + StringBuffer sbf = new StringBuffer(); + //noinspection deprecation + SheetNameFormatter.appendFormat(sbf, workbookName, rawSheetName); + assertEquals(expectedSheetNameEncoding, sbf.toString()); + } + + @Test + public void testFormatException() { + Appendable mock = new Appendable() { + @Override + public Appendable append(CharSequence csq) throws IOException { + throw new IOException("Test exception"); + } + + @Override + public Appendable append(CharSequence csq, int start, int end) throws IOException { + throw new IOException("Test exception"); + } + + @Override + public Appendable append(char c) throws IOException { + throw new IOException("Test exception"); + } + }; + + try { + SheetNameFormatter.appendFormat(mock, null, null); + fail("Should catch exception here"); + } catch (RuntimeException e) { + // expected here + } + + try { + SheetNameFormatter.appendFormat(mock, null); + fail("Should catch exception here"); + } catch (RuntimeException e) { + // expected here + } + } + + @Test public void testBooleanLiterals() { confirmFormat("TRUE", "'TRUE'"); confirmFormat("FALSE", "'FALSE'"); @@ -69,6 +164,7 @@ public final class TestSheetNameFormatter extends TestCase { * Tests functionality to determine whether a sheet name containing only letters and digits * would look (to Excel) like a cell name. */ + @Test public void testLooksLikePlainCellReference() { confirmCellNameMatch("A1", true); @@ -91,6 +187,7 @@ public final class TestSheetNameFormatter extends TestCase { * Tests exact boundaries for names that look very close to cell names (i.e. contain 1 or more * letters followed by one or more digits). */ + @Test public void testCellRange() { confirmCellRange("A1", 1, true); confirmCellRange("a111", 1, true); diff --git a/test-data/spreadsheet/60460.xls b/test-data/spreadsheet/60460.xls new file mode 100644 index 0000000000000000000000000000000000000000..73fad8aa84838b3d915fbba0311191fb0e0e485e GIT binary patch literal 68096 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˂k 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 C7|tC4 literal 0 HcmV?d00001 -- 2.39.5