From 0dea4a301c971c42ceaf0ed43cc6a3545026507e Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Thu, 18 Jul 2024 07:09:32 +0000 Subject: [PATCH] Bug 66425: Avoid exceptions found via poi-fuzz Processing formats uses regular expressions. Very complex formats can recurse very deeply and thus can cause StackOVerflows depending on the used stack-size. In order to handle this a bit more gracefully, we now catch this and report a better exception with details about the parsed format and potential mitigation. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=66137 git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1919342 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/stress/TestAllFiles.java | 1 + .../converter/TestExcelConverterSuite.java | 3 +- .../org/apache/poi/ss/format/CellFormat.java | 30 +++++++++++------- .../hssf/extractor/TestExcelExtractor.java | 12 +++++++ ...nimized-POIHSSFFuzzer-4657005060816896.xls | Bin 0 -> 66050 bytes test-data/spreadsheet/stress.xls | Bin 109568 -> 110080 bytes 6 files changed, 34 insertions(+), 12 deletions(-) create mode 100644 test-data/spreadsheet/clusterfuzz-testcase-minimized-POIHSSFFuzzer-4657005060816896.xls diff --git a/poi-integration/src/test/java/org/apache/poi/stress/TestAllFiles.java b/poi-integration/src/test/java/org/apache/poi/stress/TestAllFiles.java index 19b38600ac..54f97e5e7b 100644 --- a/poi-integration/src/test/java/org/apache/poi/stress/TestAllFiles.java +++ b/poi-integration/src/test/java/org/apache/poi/stress/TestAllFiles.java @@ -136,6 +136,7 @@ public class TestAllFiles { "spreadsheet/clusterfuzz-testcase-minimized-POIHSSFFuzzer-4977868385681408.xls", "spreadsheet/clusterfuzz-testcase-minimized-POIHSSFFuzzer-4651309315719168.xls", "document/clusterfuzz-testcase-POIHWPFFuzzer-5696094627495936.doc", + "spreadsheet/clusterfuzz-testcase-minimized-POIHSSFFuzzer-4657005060816896.xls" }); private static final Set EXPECTED_FAILURES = StressTestUtils.unmodifiableHashSet( diff --git a/poi-scratchpad/src/test/java/org/apache/poi/hssf/converter/TestExcelConverterSuite.java b/poi-scratchpad/src/test/java/org/apache/poi/hssf/converter/TestExcelConverterSuite.java index 980e1298b8..45c75ffc87 100644 --- a/poi-scratchpad/src/test/java/org/apache/poi/hssf/converter/TestExcelConverterSuite.java +++ b/poi-scratchpad/src/test/java/org/apache/poi/hssf/converter/TestExcelConverterSuite.java @@ -46,7 +46,8 @@ public class TestExcelConverterSuite { // not failing, but requires more memory "ex45698-22488.xls", // broken documents - "clusterfuzz-testcase-minimized-POIHSSFFuzzer-5436547081830400.xls" + "clusterfuzz-testcase-minimized-POIHSSFFuzzer-5436547081830400.xls", + "clusterfuzz-testcase-minimized-POIHSSFFuzzer-4657005060816896.xls" ); public static Stream files() { diff --git a/poi/src/main/java/org/apache/poi/ss/format/CellFormat.java b/poi/src/main/java/org/apache/poi/ss/format/CellFormat.java index c95caca273..9a420540a5 100644 --- a/poi/src/main/java/org/apache/poi/ss/format/CellFormat.java +++ b/poi/src/main/java/org/apache/poi/ss/format/CellFormat.java @@ -28,7 +28,6 @@ import java.util.regex.Pattern; import javax.swing.JLabel; -import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.poi.ss.usermodel.Cell; @@ -182,19 +181,28 @@ public class CellFormat { Matcher m = ONE_PART.matcher(format); List parts = new ArrayList<>(); - while (m.find()) { - try { - String valueDesc = m.group(); + try { + while (m.find()) { + try { + String valueDesc = m.group(); - // Strip out the semicolon if it's there - if (valueDesc.endsWith(";")) - valueDesc = valueDesc.substring(0, valueDesc.length() - 1); + // Strip out the semicolon if it's there + if (valueDesc.endsWith(";")) + valueDesc = valueDesc.substring(0, valueDesc.length() - 1); - parts.add(new CellFormatPart(locale, valueDesc)); - } catch (RuntimeException e) { - LOG.warn("Invalid format: {}", CellFormatter.quote(m.group()), e); - parts.add(null); + parts.add(new CellFormatPart(locale, valueDesc)); + } catch (RuntimeException e) { + LOG.warn("Invalid format: {}", CellFormatter.quote(m.group()), e); + parts.add(null); + } } + } catch (StackOverflowError e) { + // very complex formats can cause the regex-parsing to exceed the available stack + // we want to handle this more gracefully by catching it and reporting a bit more + // details in the error message + throw new IllegalStateException("The provided format is too complex: " + format + + ", you can try to increase Java Stack size via commandline argument '-Xss' " + + "to allow handling this format"); } formatPartCount = parts.size(); diff --git a/poi/src/test/java/org/apache/poi/hssf/extractor/TestExcelExtractor.java b/poi/src/test/java/org/apache/poi/hssf/extractor/TestExcelExtractor.java index 495ceb9837..8e27789f97 100644 --- a/poi/src/test/java/org/apache/poi/hssf/extractor/TestExcelExtractor.java +++ b/poi/src/test/java/org/apache/poi/hssf/extractor/TestExcelExtractor.java @@ -382,4 +382,16 @@ final class TestExcelExtractor { assertContains(txt, "Macro2"); } } + + @Test + void testStackOverflowInRegex() throws IOException { + try (ExcelExtractor extractor = createExtractor("clusterfuzz-testcase-minimized-POIHSSFFuzzer-4657005060816896.xls")) { + extractor.getText(); + } catch (IllegalStateException e) { + // we either get a StackOverflow or a parsing error depending on the stack-size of the current JVM, + // so we expect both here + assertTrue(e.getMessage().contains("Provided formula is too complex") || + e.getMessage().contains("Did not have a ExtendedFormatRecord")); + } + } } diff --git a/test-data/spreadsheet/clusterfuzz-testcase-minimized-POIHSSFFuzzer-4657005060816896.xls b/test-data/spreadsheet/clusterfuzz-testcase-minimized-POIHSSFFuzzer-4657005060816896.xls new file mode 100644 index 0000000000000000000000000000000000000000..baa032472ee3b2bc31785c9c3699798b7c3a9801 GIT binary patch literal 66050 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 delta 9714 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 E56ksx4FCWD -- 2.39.5