diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java index a62bbfb7394..acfd39f562a 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java @@ -1213,11 +1213,29 @@ public String getPrintArea(int sheetIndex) { * If there are multiple matches, the first sheet from the list * of sheets is returned. * + *
+ * Note that Excel and the underlying Apache POI library limit sheet names + * to **31 characters**. This method will throw an exception if the + * provided {@code name} is longer than 31 characters, as such a sheet + * cannot exist in a valid Excel workbook. + *
+ * * @param name of the sheet * @return XSSFSheet with the name provided or {@code null} if it does not exist + * @throws IllegalArgumentException if the sheet name is longer than 31 characters */ @Override public XSSFSheet getSheet(String name) { + + if (name == null || name.isEmpty()) { + return null; + } + + if(name.length() > MAX_SENSITIVE_SHEET_NAME_LEN) { + throw new IllegalArgumentException("Sheet name must not be longer than " + + MAX_SENSITIVE_SHEET_NAME_LEN + " characters. Otherwise it cannot exist in Excel."); + } + for (XSSFSheet sheet : sheets) { if (name.equalsIgnoreCase(sheet.getSheetName())) { return sheet; diff --git a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java index 6a162273357..482f98ed688 100644 --- a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java +++ b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java @@ -1245,6 +1245,26 @@ void testRightToLeft() throws IOException { } } + /** + * Getting a sheet by name that exceeds 31 characters should throw + * an IllegalArgumentException + */ + @Test + void testGetSheetWithNameExceeding31Characters() throws IOException { + try (XSSFWorkbook wb = new XSSFWorkbook()) { + + // Attempting to GET a sheet with a name > 31 chars should throw + String sheetName = "ThisIsAVeryLongSheetNameExceeding31Chars"; + IllegalArgumentException exception = assertThrows( + IllegalArgumentException.class, + () -> wb.getSheet(sheetName), + "getSheet() should reject names longer than 31 characters" + ); + + assertTrue(exception.getMessage().contains("31 characters")); + } + } + @Test void test501RC1Failure() throws Exception { String filename = "0-www-crossref-org.lib.rivier.edu_education-files_suffix-generator.xlsm"; diff --git a/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index f80383b52c4..e81d902e1e5 100644 --- a/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -1061,11 +1061,29 @@ public HSSFSheet getSheetAt(int index) { * If there are multiple matches, the first sheet from the list * of sheets is returned. * + *+ * Note that Excel and the underlying Apache POI library limit sheet names + * to **31 characters**. This method will throw an exception if the + * provided {@code name} is longer than 31 characters, as such a sheet + * cannot exist in a valid Excel workbook. + *
+ * * @param name of the sheet * @return HSSFSheet with the name provided or {@code null} if it does not exist + * @throws IllegalArgumentException if the sheet name is longer than 31 characters */ @Override public HSSFSheet getSheet(String name) { + + if (name == null || name.isEmpty()) { + return null; + } + + if(name.length() > MAX_SENSITIVE_SHEET_NAME_LEN) { + throw new IllegalArgumentException("Sheet name must not be longer than " + + MAX_SENSITIVE_SHEET_NAME_LEN + " characters. Otherwise it cannot exist in Excel."); + } + for (int k = 0; k < _sheets.size(); k++) { String sheetname = workbook.getSheetName(k); diff --git a/poi/src/test/java/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java b/poi/src/test/java/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java index 9d99627674c..b2859b1a866 100644 --- a/poi/src/test/java/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java +++ b/poi/src/test/java/org/apache/poi/hssf/usermodel/TestHSSFWorkbook.java @@ -395,6 +395,26 @@ void sheetSerializeSizeMismatch_bug45066() throws IOException { } } + /** + * Getting a sheet by name that exceeds 31 characters should throw + * an IllegalArgumentException + */ + @Test + void testGetSheetWithNameExceeding31Characters() throws IOException { + try (HSSFWorkbook wb = new HSSFWorkbook()) { + + // Attempting to GET a sheet with a name > 31 chars should throw + String sheetName = "ThisIsAVeryLongSheetNameExceeding31Chars"; + IllegalArgumentException exception = assertThrows( + IllegalArgumentException.class, + () -> wb.getSheet(sheetName), + "getSheet() should reject names longer than 31 characters" + ); + + assertTrue(exception.getMessage().contains("31 characters")); + } + } + /** * Checks that us and HSSFName play nicely with named ranges * that point to deleted sheets