Bug 66425: Avoid a ClassCastException found via oss-fuzz

We try to avoid throwing ClassCastException, but it was possible
to trigger one here with a specially crafted input-file

Should fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=61243

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1911507 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Dominik Stadler 2023-08-07 12:09:31 +00:00
parent ed12f1bb49
commit f6b1435db1
6 changed files with 45 additions and 21 deletions

View File

@ -43,8 +43,6 @@ import org.apache.poi.util.TempFile;
import org.junit.jupiter.api.Test;
public class HPSFFileHandler extends POIFSFileHandler {
private static final String NL = System.getProperty("line.separator");
private static final ThreadLocal<File> copyOutput = ThreadLocal.withInitial(HPSFFileHandler::getTempFile);
static final Set<String> EXCLUDES_HANDLE_ADD = StressTestUtils.unmodifiableHashSet(
@ -140,12 +138,10 @@ public class HPSFFileHandler extends POIFSFileHandler {
try (InputStream stream = new FileInputStream(path)) {
handleFile(stream, path);
}
}
// a test-case to test this locally without executing the full TestAllFiles
@Test
void testExtractor() {
File file = new File("test-data/hpsf/TestBug44375.xls");
File file = new File(path);
assertDoesNotThrow(() -> handleExtracting(file));
handleAdditional(file);
}
}

View File

@ -47,6 +47,7 @@ import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.DirectoryNode;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.poifs.filesystem.DocumentInputStream;
import org.apache.poi.poifs.filesystem.Entry;
import org.apache.poi.poifs.filesystem.FileMagic;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.IOUtils;
@ -337,7 +338,11 @@ public abstract class HWPFDocumentCore extends POIDocument {
*/
protected byte[] getDocumentEntryBytes(String name, int encryptionOffset, final int len) throws IOException {
DirectoryNode dir = getDirectory();
DocumentEntry documentProps = (DocumentEntry)dir.getEntry(name);
final Entry entry = dir.getEntry(name);
if (!(entry instanceof DocumentEntry)) {
throw new IllegalArgumentException("Had unexpected type of entry for name: " + name + ": " + entry);
}
DocumentEntry documentProps = (DocumentEntry) entry;
int streamSize = documentProps.getSize();
boolean isEncrypted = (encryptionOffset > -1 && getEncryptionInfo() != null);

View File

@ -23,6 +23,7 @@ import java.io.FilenameFilter;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.stream.Stream;
import javax.xml.transform.OutputKeys;
@ -52,16 +53,26 @@ public class TestWordToConverterSuite
"password_password_cryptoapi.doc",
// WORD 2.0 file
"word2.doc",
// Corrupt file
"Fuzzed.doc"
// Excel file
"TestRobert_Flaherty.doc",
// Corrupt files
"Fuzzed.doc",
"clusterfuzz-testcase-minimized-POIHWPFFuzzer-5418937293340672.doc",
"TestHPSFWritingFunctionality.doc"
);
public static Stream<Arguments> files() {
File directory = POIDataSamples.getDocumentInstance().getFile("../document" );
FilenameFilter ff = (dir, name) -> name.endsWith(".doc") && !failingFiles.contains(name);
return Stream.concat(
Arrays.stream(getFiles(POIDataSamples.getDocumentInstance().getFile(""))),
Arrays.stream(getFiles(POIDataSamples.getHPSFInstance().getFile("")))
).map(Arguments::of);
}
private static File[] getFiles(File directory) {
FilenameFilter ff = (dir, name) -> name.toLowerCase(Locale.ROOT).endsWith(".doc") && !failingFiles.contains(name);
File[] docs = directory.listFiles(ff);
assertNotNull(docs);
return Arrays.stream(docs).map(Arguments::of);
return docs;
}
@ParameterizedTest

View File

@ -25,9 +25,10 @@ import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.stream.Stream;
import org.apache.commons.io.filefilter.SuffixFileFilter;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.EncryptedDocumentException;
@ -44,6 +45,14 @@ import org.junit.jupiter.params.provider.MethodSource;
public class TestWordToTextConverter {
private static final Logger LOG = LogManager.getLogger(WordToTextConverter.class);
private static final List<String> failingFiles = Arrays.asList(
// Excel file
"TestRobert_Flaherty.doc",
// Corrupt files
"clusterfuzz-testcase-minimized-POIHWPFFuzzer-5418937293340672.doc",
"TestHPSFWritingFunctionality.doc"
);
/**
* [FAILING] Bug 47731 - Word Extractor considers text copied from some
* website as an embedded object
@ -104,13 +113,16 @@ public class TestWordToTextConverter {
}
public static Stream<Arguments> files() {
String dataDirName = System.getProperty(POIDataSamples.TEST_PROPERTY,
new File("test-data").exists() ? "test-data" : "../test-data");
return Stream.concat(
Arrays.stream(getFiles(POIDataSamples.getDocumentInstance().getFile(""))),
Arrays.stream(getFiles(POIDataSamples.getHPSFInstance().getFile("")))
).map(Arguments::of);
}
File[] documents = new File(dataDirName, "document").listFiles(
(FilenameFilter) new SuffixFileFilter(".doc"));
assertNotNull(documents);
return Arrays.stream(documents).map(Arguments::of);
private static File[] getFiles(File directory) {
FilenameFilter ff = (dir, name) -> name.toLowerCase(Locale.ROOT).endsWith(".doc") && !failingFiles.contains(name);
File[] docs = directory.listFiles(ff);
assertNotNull(docs);
return docs;
}
}

Binary file not shown.