Avoid race-condition with sample-file being changed/empty

Also improve output EmptyfileException

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1925190 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Dominik Stadler 2025-04-21 08:51:13 +00:00
parent 3d66281e6d
commit db61f5b4be
2 changed files with 36 additions and 16 deletions

View File

@ -17,7 +17,6 @@
package org.apache.poi.extractor.ooxml;
import static org.apache.poi.POITestCase.assertContains;
import static org.apache.poi.extractor.ExtractorFactory.createExtractor;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
@ -26,12 +25,14 @@ import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Locale;
import java.util.stream.Stream;
import org.apache.poi.EmptyFileException;
import org.apache.poi.POIDataSamples;
import org.apache.poi.extractor.ExtractorFactory;
import org.apache.poi.extractor.POIOLE2TextExtractor;
@ -142,7 +143,7 @@ class TestExtractorFactory {
@ParameterizedTest
@MethodSource("testFileData")
void testFile(String testcase, File file, String extractor, int count) throws Exception {
try (POITextExtractor ext = createExtractor(file)) {
try (POITextExtractor ext = ExtractorFactory.createExtractor(file)) {
assertNotNull(ext);
testExtractor(ext, testcase, extractor, count);
}
@ -154,7 +155,7 @@ class TestExtractorFactory {
// test processing of InputStream
try (FileInputStream fis = new FileInputStream(testFile);
POIFSFileSystem poifs = new POIFSFileSystem(fis);
POITextExtractor ext = createExtractor(poifs)) {
POITextExtractor ext = ExtractorFactory.createExtractor(poifs)) {
assertNotNull(ext);
testExtractor(ext, testcase, extractor, count);
}
@ -165,7 +166,7 @@ class TestExtractorFactory {
void testOOXML(String testcase, File testFile, String extractor, int count) throws Exception {
// test processing of InputStream
try (FileInputStream fis = new FileInputStream(testFile);
POITextExtractor ext = createExtractor(fis)) {
POITextExtractor ext = ExtractorFactory.createExtractor(fis)) {
assertNotNull(ext);
testExtractor(ext, testcase, extractor, count);
}
@ -187,15 +188,31 @@ class TestExtractorFactory {
@Test
void testFileInvalid() {
//noinspection resource
IOException ex = assertThrows(IOException.class, () -> createExtractor(txt));
assertEquals("Can't create extractor - unsupported file type: UNKNOWN", ex.getMessage());
IOException ex = assertThrows(IOException.class, () -> ExtractorFactory.createExtractor(txt));
assertEquals("Can't create extractor - unsupported file type: UNKNOWN", ex.getMessage(),
"Had: " + ex);
}
@Test
void testInputStreamInvalid() throws IOException {
try (FileInputStream fis = new FileInputStream(txt)) {
IOException ex = assertThrows(IOException.class, () -> createExtractor(fis));
assertTrue(ex.getMessage().contains(FileMagic.UNKNOWN.name()));
IOException ex = assertThrows(IOException.class, () -> ExtractorFactory.createExtractor(fis));
assertTrue(ex.getMessage().contains(FileMagic.UNKNOWN.name()), "Had: " + ex);
}
}
@Test
void testInputStreamEmpty() throws IOException {
try (ByteArrayInputStream fis = new ByteArrayInputStream(new byte[0])) {
EmptyFileException ex = assertThrows(EmptyFileException.class, () -> ExtractorFactory.createExtractor(fis));
}
}
@Test
void testInputStreamTooShort() throws IOException {
try (ByteArrayInputStream fis = new ByteArrayInputStream(new byte[] { 0 })) {
IOException ex = assertThrows(IOException.class, () -> ExtractorFactory.createExtractor(fis));
assertTrue(ex.getMessage().contains(FileMagic.UNKNOWN.name()), "Had: " + ex);
}
}
@ -204,7 +221,8 @@ class TestExtractorFactory {
// Not really an Extractor test, but we'll leave it to test POIFS reaction anyway ...
//noinspection resource
IOException ex = assertThrows(IOException.class, () -> new POIFSFileSystem(txt));
assertTrue(ex.getMessage().contains("Invalid header signature; read 0x3D20726F68747541, expected 0xE11AB1A1E011CFD0"));
assertTrue(ex.getMessage().contains("Invalid header signature; read 0x3D20726F68747541, expected 0xE11AB1A1E011CFD0"),
"Had: " + ex);
}
@Test
@ -240,7 +258,7 @@ class TestExtractorFactory {
try {
// Check we get the right extractors now
try (POITextExtractor extractor = createExtractor(new POIFSFileSystem(new FileInputStream(xls)))) {
try (POITextExtractor extractor = ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(xls)))) {
assertInstanceOf(EventBasedExcelExtractor.class, extractor);
assertTrue(extractor.getText().length() > 200);
}
@ -259,7 +277,7 @@ class TestExtractorFactory {
assertNull(ExtractorFactory.getAllThreadsPreferEventExtractors());
// And back
try (POITextExtractor extractor = createExtractor(new POIFSFileSystem(new FileInputStream(xls)))) {
try (POITextExtractor extractor = ExtractorFactory.createExtractor(new POIFSFileSystem(new FileInputStream(xls)))) {
assertInstanceOf(ExcelExtractor.class, extractor);
assertTrue(extractor.getText().length() > 200);
}
@ -298,7 +316,7 @@ class TestExtractorFactory {
void testEmbedded(String format, File file, String expected) throws Exception {
int numWord = 0, numXls = 0, numPpt = 0, numMsg = 0, numWordX = 0;
try (final POIOLE2TextExtractor ext = (POIOLE2TextExtractor) createExtractor(file)) {
try (final POIOLE2TextExtractor ext = (POIOLE2TextExtractor) ExtractorFactory.createExtractor(file)) {
final POITextExtractor[] embeds = ExtractorFactory.getEmbeddedDocsTextExtractors(ext);
for (POITextExtractor embed : embeds) {
@ -470,6 +488,6 @@ class TestExtractorFactory {
}
private static POITextExtractor ex(String filename) throws IOException {
return createExtractor(ssTests.getFile(filename));
return ExtractorFactory.createExtractor(ssTests.getFile(filename));
}
}

View File

@ -42,7 +42,9 @@ import org.apache.poi.util.IOUtils;
import org.apache.poi.util.TempFile;
import org.apache.poi.xssf.XSSFTestDataSamples;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.parallel.Isolated;
@Isolated // testFactoryFromFile() changes sample-files, thus should run in isolation until this is removed
public final class TestXSLFSlideShowFactory extends BaseTestSlideShowFactory {
private static final POIDataSamples _slTests = POIDataSamples.getSlideShowInstance();
private static final String filename = "SampleShow.pptx";
@ -54,7 +56,7 @@ public final class TestXSLFSlideShowFactory extends BaseTestSlideShowFactory {
@Test
void testFactoryFromFile() {
// Remove thrown.* when bug 58779 is resolved
// In the mean time, this function will modify SampleShow.pptx on disk.
// In the meantime, this function will modify SampleShow.pptx on disk.
AssertionError ex = assertThrows(AssertionError.class, () -> testFactoryFromFile(filename),
"Bug 58779: " + removeExpectedExceptionMsg);
assertTrue(ex.getMessage().contains("SampleShow.pptx sample file was modified as a result of closing the slideshow"));
@ -97,7 +99,7 @@ public final class TestXSLFSlideShowFactory extends BaseTestSlideShowFactory {
File file = XSSFTestDataSamples.getSampleFile("workbook.xml");
try (FileInputStream fis = new FileInputStream(file)) {
try {
SlideShow slideShow = SlideShowFactory.create(fis);
SlideShow<?,?> slideShow = SlideShowFactory.create(fis);
if (slideShow != null) slideShow.close();
fail("SlideShowFactory.create should have failed");
} catch (IOException ie) {
@ -105,7 +107,7 @@ public final class TestXSLFSlideShowFactory extends BaseTestSlideShowFactory {
}
}
try {
SlideShow slideShow = SlideShowFactory.create(file);
SlideShow<?,?> slideShow = SlideShowFactory.create(file);
if (slideShow != null) slideShow.close();
fail("SlideShowFactory.create should have failed");
} catch (IOException ie) {