mirror of https://github.com/apache/poi.git
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
This commit is contained in:
parent
0dac5680c3
commit
0dea4a301c
|
@ -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<String> EXPECTED_FAILURES = StressTestUtils.unmodifiableHashSet(
|
||||
|
|
|
@ -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<Arguments> files() {
|
||||
|
|
|
@ -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<CellFormatPart> 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();
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue