This is an automated email from the ASF dual-hosted git repository.

centic pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/poi.git

commit 90560c33b6f78a4b84e03a9fd8b7feaedb1e49c3
Author: Dominik Stadler <[email protected]>
AuthorDate: Sat Mar 7 09:27:07 2026 +0100

    Move fuzz-targets from oss-fuzz to Apache POI
    
    It's better if we keep the fuzz-targets "near" the sources
    so we can adjust them along other changes.
    
    This will need a change in oss-fuzz to switch to these and
    remove these fuzz-targets there.
---
 poi-fuzz/build.gradle                              |   7 +
 .../org/apache/poi/fuzz/EncryptDecryptFuzzer.java  | 105 ++++++++++++
 .../org/apache/poi/fuzz/POIFileHandlerFuzzer.java  | 139 +++++++++++++++
 .../main/java/org/apache/poi/fuzz/POIFuzzer.java   | 190 +++++++++++++++++++++
 .../java/org/apache/poi/fuzz/POIHDGFFuzzer.java    |  50 ++++++
 .../java/org/apache/poi/fuzz/POIHMEFFuzzer.java}   |  47 +++--
 .../java/org/apache/poi/fuzz/POIHPBFFuzzer.java    |  54 ++++++
 .../java/org/apache/poi/fuzz/POIHPSFFuzzer.java    |  60 +++++++
 .../java/org/apache/poi/fuzz/POIHSLFFuzzer.java    |  73 ++++++++
 .../java/org/apache/poi/fuzz/POIHSMFFuzzer.java    |  56 ++++++
 .../java/org/apache/poi/fuzz/POIHSSFFuzzer.java    |  61 +++++++
 .../java/org/apache/poi/fuzz/POIHWPFFuzzer.java    |  59 +++++++
 .../org/apache/poi/fuzz/POIOldExcelFuzzer.java     |  47 +++++
 .../java/org/apache/poi/fuzz/POIVisioFuzzer.java   |  60 +++++++
 .../java/org/apache/poi/fuzz/POIXSLFFuzzer.java    |  66 +++++++
 .../java/org/apache/poi/fuzz/POIXSSFFuzzer.java    |  62 +++++++
 .../java/org/apache/poi/fuzz/POIXWPFFuzzer.java    |  66 +++++++
 .../java/org/apache/poi/fuzz/XLSX2CSVFuzzer.java   |  51 ++++++
 18 files changed, 1236 insertions(+), 17 deletions(-)

diff --git a/poi-fuzz/build.gradle b/poi-fuzz/build.gradle
index 95456641c4..e2ca23203e 100644
--- a/poi-fuzz/build.gradle
+++ b/poi-fuzz/build.gradle
@@ -21,6 +21,13 @@
 
 dependencies {
     implementation project(':poi')
+    implementation project(':poi-scratchpad')
+    implementation project(':poi-examples')
+    implementation project(path:':poi-integration', configuration:'tests')
+
+    implementation "org.apache.logging.log4j:log4j-core:${log4jVersion}"
+    implementation 'org.apache.commons:commons-lang3:3.20.0'
+    implementation 'org.opentest4j:opentest4j:1.2.0'
 
     compileOnly 'com.code-intelligence:jazzer-api:0.22.0'
 }
diff --git 
a/poi-fuzz/src/main/java/org/apache/poi/fuzz/EncryptDecryptFuzzer.java 
b/poi-fuzz/src/main/java/org/apache/poi/fuzz/EncryptDecryptFuzzer.java
new file mode 100644
index 0000000000..f6f856dff1
--- /dev/null
+++ b/poi-fuzz/src/main/java/org/apache/poi/fuzz/EncryptDecryptFuzzer.java
@@ -0,0 +1,105 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.fuzz;
+
+import static org.apache.poi.poifs.crypt.Decryptor.DEFAULT_POIFS_ENTRY;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.security.GeneralSecurityException;
+import java.util.Arrays;
+
+import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream;
+import org.apache.poi.EncryptedDocumentException;
+import org.apache.poi.poifs.crypt.Decryptor;
+import org.apache.poi.poifs.crypt.EncryptionInfo;
+import org.apache.poi.poifs.crypt.EncryptionMode;
+import org.apache.poi.poifs.crypt.Encryptor;
+import org.apache.poi.poifs.filesystem.DocumentInputStream;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.util.HexDump;
+import org.apache.poi.util.IOUtils;
+
+import com.code_intelligence.jazzer.api.FuzzedDataProvider;
+
+public class EncryptDecryptFuzzer {
+       public static void fuzzerInitialize() {
+               POIFuzzer.adjustLimits();
+       }
+
+       public static void fuzzerTestOneInput(FuzzedDataProvider data) throws 
IOException, GeneralSecurityException {
+               try {
+                       EncryptionMode encryptionMode = 
EncryptionMode.values()[(data.consumeInt(0, EncryptionMode.values().length - 
1))];
+                       String password = data.consumeString(20);
+                       byte[] testData = data.consumeRemainingAsBytes();
+
+                       EncryptionInfo infoEnc = new 
EncryptionInfo(encryptionMode);
+                       Encryptor enc = infoEnc.getEncryptor();
+                       enc.confirmPassword(password);
+
+                       byte[] encData;
+                       byte[] encDocument;
+                       try (POIFSFileSystem fsEnc = new POIFSFileSystem()) {
+                               try (OutputStream os = 
enc.getDataStream(fsEnc)) {
+                                       os.write(testData);
+                               }
+
+                               UnsynchronizedByteArrayOutputStream bos = 
UnsynchronizedByteArrayOutputStream.builder().get();
+                               fsEnc.writeFilesystem(bos);
+
+                               bos.close();
+                               encData = bos.toByteArray();
+
+                               DocumentInputStream dis = 
fsEnc.getRoot().createDocumentInputStream(DEFAULT_POIFS_ENTRY);
+                               /*long _length =*/
+                               dis.readLong();
+                               encDocument = IOUtils.toByteArray(dis);
+                       }
+
+                       byte[] actualData;
+                       try (POIFSFileSystem fsDec = new POIFSFileSystem(new 
ByteArrayInputStream(encData))) {
+                               EncryptionInfo infoDec = new 
EncryptionInfo(fsDec);
+                               Decryptor dec = infoDec.getDecryptor();
+                               if (!dec.verifyPassword(password)) {
+                                       throw new IllegalStateException("Could 
not verify password when decrypting " + password + "\n" +
+                                                       HexDump.dump(testData, 
0, 0) + " and encrypted \n" +
+                                                       
HexDump.dump(encDocument, 0, 0) + " full encrypted \n" +
+                                                       HexDump.dump(encData, 
0, 0));
+                               }
+                               InputStream is = dec.getDataStream(fsDec);
+
+                               actualData = IOUtils.toByteArray(is);
+                               is.close();
+                       }
+
+                       // input-data and resulting decrypted data should be 
equal
+                       if (!Arrays.equals(testData, actualData)) {
+                               throw new IllegalStateException("Resulting 
array was not equal to input-array, "
+                                               + "having " + testData.length + 
" bytes, had actual length " + actualData.length + " and expected \n" +
+                                               HexDump.dump(testData, 0, 0) + 
" and actual \n" +
+                                               HexDump.dump(actualData, 0, 0) 
+ " encrypted \n" +
+                                               HexDump.dump(encDocument, 0, 0) 
+ " full encrypted \n" +
+                                               HexDump.dump(encData, 0, 0));
+                       }
+               } catch (IOException | EncryptedDocumentException e) {
+                       // expected, e.g. when something is not supported
+               }
+       }
+}
diff --git 
a/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIFileHandlerFuzzer.java 
b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIFileHandlerFuzzer.java
new file mode 100644
index 0000000000..2600d0a091
--- /dev/null
+++ b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIFileHandlerFuzzer.java
@@ -0,0 +1,139 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.fuzz;
+
+import java.awt.AWTError;
+import java.awt.geom.IllegalPathStateException;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.BufferUnderflowException;
+import java.util.NoSuchElementException;
+
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.poi.hslf.exceptions.HSLFException;
+import org.apache.poi.hsmf.exceptions.ChunkNotFoundException;
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.ooxml.POIXMLException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException;
+import org.apache.poi.ss.formula.FormulaParseException;
+import org.apache.poi.ss.formula.eval.NotImplementedException;
+import org.apache.poi.stress.FileHandler;
+import org.apache.poi.stress.HDGFFileHandler;
+import org.apache.poi.stress.HEMFFileHandler;
+import org.apache.poi.stress.HMEFFileHandler;
+import org.apache.poi.stress.HPBFFileHandler;
+import org.apache.poi.stress.HPSFFileHandler;
+import org.apache.poi.stress.HSLFFileHandler;
+import org.apache.poi.stress.HSMFFileHandler;
+import org.apache.poi.stress.HSSFFileHandler;
+import org.apache.poi.stress.HWMFFileHandler;
+import org.apache.poi.stress.HWPFFileHandler;
+import org.apache.poi.stress.OPCFileHandler;
+import org.apache.poi.stress.OWPFFileHandler;
+import org.apache.poi.stress.POIFSFileHandler;
+import org.apache.poi.stress.XDGFFileHandler;
+import org.apache.poi.stress.XSLFFileHandler;
+import org.apache.poi.stress.XSSFBFileHandler;
+import org.apache.poi.stress.XSSFFileHandler;
+import org.apache.poi.stress.XWPFFileHandler;
+import org.apache.poi.util.DocumentFormatException;
+import org.apache.poi.util.RecordFormatException;
+import org.apache.poi.xssf.binary.XSSFBParseException;
+import org.apache.xmlbeans.XmlException;
+import org.opentest4j.AssertionFailedError;
+import org.opentest4j.TestAbortedException;
+import org.xml.sax.SAXException;
+
+/**
+ * A fuzz target which uses the FileHandlers from integration testing of 
Apache POI
+ * to execute a number of additional actions after successfully opening 
documents.
+ *
+ * This should extend coverage to some of the getters and other areas of POI 
which
+ * are currently uncovered.
+ */
+public class POIFileHandlerFuzzer {
+       private static final FileHandler[] HANDLERS = new FileHandler[] {
+               new HDGFFileHandler(),
+               new HEMFFileHandler(),
+               new HMEFFileHandler(),
+               new HPBFFileHandler(),
+               new HPSFFileHandler(),
+               new HSLFFileHandler(),
+               new HSMFFileHandler(),
+               new HSSFFileHandler(),
+               new HWMFFileHandler(),
+               new HWPFFileHandler(),
+               new OPCFileHandler(),
+               new OWPFFileHandler(),
+               new POIFSFileHandler(),
+               new XDGFFileHandler(),
+               new XSLFFileHandler(),
+               new XSSFBFileHandler(),
+               new XSSFFileHandler(),
+               new XWPFFileHandler(),
+       };
+
+       public static void fuzzerInitialize() {
+               POIFuzzer.adjustLimits();
+       }
+
+       public static void fuzzerTestOneInput(byte[] input) throws Exception {
+               ByteArrayInputStream stream = new ByteArrayInputStream(input);
+               for (FileHandler handler : HANDLERS) {
+                       stream.mark(input.length);
+
+                       try {
+                               handler.handleFile(stream, "dummy-file-name");
+                       } catch (POIXMLException | IOException | SAXException | 
XmlException | HSLFException |
+                                        IllegalArgumentException | 
IllegalStateException | IndexOutOfBoundsException | NoSuchElementException |
+                                        UnsupportedOperationException | 
NegativeArraySizeException | BufferUnderflowException |
+                                        ChunkNotFoundException | 
RecordInputStream.LeftoverDataException | RecordFormatException |
+                                        OpenXML4JException | 
OpenXML4JRuntimeException | DocumentFormatException | XSSFBParseException |
+                                        // some FileHandlers perform checks 
via assertions, so we expect this type of exception as well
+                                        AssertionFailedError | 
TestAbortedException |
+                                        NotImplementedException | 
FormulaParseException | IllegalPathStateException | ArithmeticException
+                                       e) {
+                               // expected here
+                       } catch (AWTError e) {
+                               // POI cannot fix it if there is no DISPLAY
+                               if 
(!ExceptionUtils.getStackTrace(e).contains("Can't connect to X11 window 
server")) {
+                                       throw e;
+                               }
+                       } catch (NoClassDefFoundError e) {
+                               // POI cannot fix it if there is no DISPLAY
+                               if 
(!ExceptionUtils.getStackTrace(e).contains("Could not initialize class 
java.awt.GraphicsEnvironment$LocalGE")) {
+                                       throw e;
+                               }
+                       } catch (InternalError e) {
+                               // POI cannot fix it if the font-system is not 
fully installed, so let's ignore
+                               // this for fuzzing
+                               if 
(!ExceptionUtils.getStackTrace(e).contains("Fontconfig head is null")) {
+                                       throw e;
+                               }
+                       } catch (NullPointerException e) {
+                               // can be removed when commons-compress is > 
1.28.0 and changes from COMPRESS-598 are applied
+                               if 
(!ExceptionUtils.getStackTrace(e).contains("ZipArchiveInputStream.read")) {
+                                       throw e;
+                               }
+                       }
+
+                       stream.reset();
+               }
+       }
+}
diff --git a/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIFuzzer.java 
b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIFuzzer.java
new file mode 100644
index 0000000000..f0f4c0b567
--- /dev/null
+++ b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIFuzzer.java
@@ -0,0 +1,190 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.fuzz;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.BufferUnderflowException;
+import java.util.NoSuchElementException;
+
+import org.apache.commons.io.output.NullOutputStream;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.config.AbstractConfiguration;
+import org.apache.poi.ddf.EscherRecord;
+import org.apache.poi.extractor.ExtractorFactory;
+import org.apache.poi.extractor.POIOLE2TextExtractor;
+import org.apache.poi.extractor.POITextExtractor;
+import org.apache.poi.hslf.exceptions.HSLFException;
+import org.apache.poi.hssf.record.RecordFactory;
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.ooxml.POIXMLException;
+import org.apache.poi.ooxml.extractor.POIXMLPropertiesTextExtractor;
+import org.apache.poi.ooxml.extractor.POIXMLTextExtractor;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.usermodel.WorkbookFactory;
+import org.apache.poi.util.DocumentFormatException;
+import org.apache.poi.util.RecordFormatException;
+
+/**
+ * This class provides a simple target for fuzzing Apache POI with Jazzer.
+ *
+ * It uses the byte-array to call various method which parse the various
+ * supported file-formats.
+ *
+ * It catches all exceptions that are currently expected.
+ */
+public class POIFuzzer {
+       public static void fuzzerInitialize() {
+               adjustLimits();
+       }
+
+       public static void fuzzerTestOneInput(byte[] input) {
+               // try to invoke various methods which parse 
documents/workbooks/slide-shows/...
+               // all of these catch expected exceptions and thus any failure 
indicates something
+               // that we should take a look at
+
+               fuzzAny(input);
+
+               POIHDGFFuzzer.fuzzerTestOneInput(input);
+
+               POIHMEFFuzzer.fuzzerTestOneInput(input);
+
+               POIHPBFFuzzer.fuzzerTestOneInput(input);
+
+               POIHPSFFuzzer.fuzzerTestOneInput(input);
+
+               POIHSLFFuzzer.fuzzerTestOneInput(input);
+
+               POIHSMFFuzzer.fuzzerTestOneInput(input);
+
+               POIHSSFFuzzer.fuzzerTestOneInput(input);
+
+               POIHWPFFuzzer.fuzzerTestOneInput(input);
+
+               POIOldExcelFuzzer.fuzzerTestOneInput(input);
+
+               POIVisioFuzzer.fuzzerTestOneInput(input);
+
+               XLSX2CSVFuzzer.fuzzerTestOneInput(input);
+
+               POIXSLFFuzzer.fuzzerTestOneInput(input);
+
+               POIXSSFFuzzer.fuzzerTestOneInput(input);
+
+               POIXWPFFuzzer.fuzzerTestOneInput(input);
+       }
+
+       public static void fuzzAny(byte[] input) {
+               try (Workbook wb = WorkbookFactory.create(new 
ByteArrayInputStream(input))) {
+                       for (Sheet sheet : wb) {
+                               for (Row row : sheet) {
+                                       for (Cell cell : row) {
+                                               cell.getAddress();
+                                               cell.getCellType();
+                                       }
+                               }
+                       }
+
+                       wb.write(NullOutputStream.INSTANCE);
+               } catch (IOException | POIXMLException | 
IllegalArgumentException | RecordFormatException |
+                                IndexOutOfBoundsException | HSLFException | 
RecordInputStream.LeftoverDataException |
+                                IllegalStateException | 
BufferUnderflowException | OpenXML4JRuntimeException |
+                               UnsupportedOperationException | 
NoSuchElementException | NegativeArraySizeException e) {
+                       // expected here
+               }
+
+               ExtractorFactory.setThreadPrefersEventExtractors(true);
+               checkExtractor(input);
+               ExtractorFactory.setAllThreadsPreferEventExtractors(false);
+               checkExtractor(input);
+       }
+
+       public static void checkExtractor(byte[] input) {
+               try (POITextExtractor extractor = 
ExtractorFactory.createExtractor(new ByteArrayInputStream(input))) {
+                       checkExtractor(extractor);
+               } catch (IOException | POIXMLException | 
IllegalArgumentException | RecordFormatException |
+                                IndexOutOfBoundsException | HSLFException | 
RecordInputStream.LeftoverDataException |
+                                NoSuchElementException | IllegalStateException 
| ArithmeticException |
+                                BufferUnderflowException | 
UnsupportedOperationException | DocumentFormatException |
+                               NegativeArraySizeException e) {
+                       // expected here
+               }
+       }
+
+       @SuppressWarnings("DuplicatedCode")
+       public static void checkExtractor(POITextExtractor extractor) throws 
IOException {
+               extractor.getDocument();
+               extractor.getFilesystem();
+               try {
+                       extractor.getMetadataTextExtractor();
+               } catch (IllegalStateException e) {
+                       // can happen here
+               }
+               try {
+                       extractor.getText();
+               } catch (OpenXML4JRuntimeException e) {
+                       // can happen here
+               }
+
+               if (extractor instanceof POIOLE2TextExtractor) {
+                       POIOLE2TextExtractor ole2Extractor = 
(POIOLE2TextExtractor) extractor;
+                       ole2Extractor.getRoot();
+                       ole2Extractor.getSummaryInformation();
+                       ole2Extractor.getDocSummaryInformation();
+
+                       POITextExtractor[] embedded = 
ExtractorFactory.getEmbeddedDocsTextExtractors(ole2Extractor);
+                       for (POITextExtractor poiTextExtractor : embedded) {
+                               poiTextExtractor.getText();
+                               poiTextExtractor.getDocument();
+                               poiTextExtractor.getFilesystem();
+                               POITextExtractor metaData = 
poiTextExtractor.getMetadataTextExtractor();
+                               metaData.getFilesystem();
+                               metaData.getText();
+                       }
+               } else if (extractor instanceof POIXMLTextExtractor) {
+                       POIXMLTextExtractor xmlExtractor = 
(POIXMLTextExtractor) extractor;
+                       xmlExtractor.getCoreProperties();
+                       xmlExtractor.getCustomProperties();
+                       xmlExtractor.getExtendedProperties();
+                       POIXMLPropertiesTextExtractor metaData = 
xmlExtractor.getMetadataTextExtractor();
+                       metaData.getFilesystem();
+                       metaData.getText();
+
+                       xmlExtractor.getPackage();
+               }
+       }
+
+       static void adjustLimits() {
+               // reduce limits so we do not get OOMs with the Xmx settings
+               // that are used for the fuzzing runs
+               RecordFactory.setMaxNumberOfRecords(50_000);
+               EscherRecord.setMaxNumberOfChildren(10_000);
+
+               // remove all appenders to silence log4j output
+               final var ctx = (org.apache.logging.log4j.core.LoggerContext) 
LogManager.getContext(false);
+               final var configuration = (AbstractConfiguration) 
ctx.getConfiguration();
+               final var allAppenders = configuration.getAppenders();
+               for (final var appenderName : allAppenders.keySet()) {
+                       configuration.removeAppender(appenderName);
+               }
+       }
+}
diff --git a/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHDGFFuzzer.java 
b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHDGFFuzzer.java
new file mode 100644
index 0000000000..1907038513
--- /dev/null
+++ b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHDGFFuzzer.java
@@ -0,0 +1,50 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.fuzz;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.BufferUnderflowException;
+import java.util.NoSuchElementException;
+
+import org.apache.commons.io.output.NullOutputStream;
+import org.apache.poi.fuzz.POIFuzzer;
+import org.apache.poi.hdgf.HDGFDiagram;
+import org.apache.poi.hdgf.extractor.VisioTextExtractor;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.util.RecordFormatException;
+
+public class POIHDGFFuzzer {
+       public static void fuzzerInitialize() {
+               POIFuzzer.adjustLimits();
+       }
+
+       public static void fuzzerTestOneInput(byte[] input) {
+               try (HDGFDiagram visio = new HDGFDiagram(new 
POIFSFileSystem(new ByteArrayInputStream(input)))) {
+                       visio.write(NullOutputStream.INSTANCE);
+
+                       try (VisioTextExtractor extractor = new 
VisioTextExtractor(visio)) {
+                               POIFuzzer.checkExtractor(extractor);
+                       }
+               } catch (IOException | IllegalArgumentException | 
IllegalStateException | RecordFormatException |
+                                IndexOutOfBoundsException | 
BufferUnderflowException | ArithmeticException |
+                                NoSuchElementException e) {
+                       // expected here
+               }
+       }
+}
diff --git a/poi-fuzz/build.gradle 
b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHMEFFuzzer.java
similarity index 51%
copy from poi-fuzz/build.gradle
copy to poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHMEFFuzzer.java
index 95456641c4..5e32593f43 100644
--- a/poi-fuzz/build.gradle
+++ b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHMEFFuzzer.java
@@ -15,21 +15,34 @@
    limitations under the License.
 ==================================================================== */
 
-// Fuzz targets for OSS-Fuzz integration.
-// Jazzer is provided at runtime by the OSS-Fuzz build environment; we only
-// need the API jar at compile time.
-
-dependencies {
-    implementation project(':poi')
-
-    compileOnly 'com.code-intelligence:jazzer-api:0.22.0'
+package org.apache.poi.fuzz;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import org.apache.poi.fuzz.POIFuzzer;
+import org.apache.poi.hmef.HMEFMessage;
+import org.apache.poi.util.RecordFormatException;
+
+public class POIHMEFFuzzer {
+       public static void fuzzerInitialize() {
+               POIFuzzer.adjustLimits();
+       }
+
+       public static void fuzzerTestOneInput(byte[] input) {
+               try {
+                       HMEFMessage msg = new HMEFMessage(new 
ByteArrayInputStream(input));
+                       //noinspection ResultOfMethodCallIgnored
+                       msg.getAttachments();
+                       msg.getBody();
+                       //noinspection ResultOfMethodCallIgnored
+                       msg.getMessageAttributes();
+                       msg.getSubject();
+                       //noinspection ResultOfMethodCallIgnored
+                       msg.getMessageMAPIAttributes();
+               } catch (IOException | IllegalArgumentException | 
IllegalStateException | RecordFormatException |
+                               ArrayIndexOutOfBoundsException e) {
+                       // expected here
+               }
+       }
 }
-
-// Fuzz targets are not standard JUnit tests; disable the test task.
-test.enabled = false
-
-javadoc.enabled = false
-sourcesJar.enabled = false
-
-generateMetadataFileForPOIPublication.enabled = false
-publishPOIPublicationToMavenLocal.enabled = false
diff --git a/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHPBFFuzzer.java 
b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHPBFFuzzer.java
new file mode 100644
index 0000000000..f6ec695fa1
--- /dev/null
+++ b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHPBFFuzzer.java
@@ -0,0 +1,54 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.fuzz;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.BufferUnderflowException;
+import java.util.NoSuchElementException;
+
+import org.apache.commons.io.output.NullOutputStream;
+import org.apache.poi.hpbf.HPBFDocument;
+import org.apache.poi.hpbf.extractor.PublisherTextExtractor;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.util.RecordFormatException;
+
+public class POIHPBFFuzzer {
+       public static void fuzzerInitialize() {
+               POIFuzzer.adjustLimits();
+       }
+
+       public static void fuzzerTestOneInput(byte[] input) {
+               try (HPBFDocument wb = new HPBFDocument(new 
ByteArrayInputStream(input))) {
+                       wb.write(NullOutputStream.INSTANCE);
+               } catch (IOException | IllegalArgumentException | 
RecordFormatException | IndexOutOfBoundsException |
+                                BufferUnderflowException | 
IllegalStateException | NoSuchElementException e) {
+                       // expected here
+               }
+
+               try {
+                       try (PublisherTextExtractor extractor = new 
PublisherTextExtractor (
+                                       new POIFSFileSystem(new 
ByteArrayInputStream(input)).getRoot())) {
+                               POIFuzzer.checkExtractor(extractor);
+                       }
+               } catch (IOException | IllegalArgumentException | 
RecordFormatException | IndexOutOfBoundsException |
+                               BufferUnderflowException | 
IllegalStateException | NoSuchElementException e) {
+                       // expected here
+               }
+       }
+}
diff --git a/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHPSFFuzzer.java 
b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHPSFFuzzer.java
new file mode 100644
index 0000000000..022c5cb331
--- /dev/null
+++ b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHPSFFuzzer.java
@@ -0,0 +1,60 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.fuzz;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.BufferUnderflowException;
+import java.util.NoSuchElementException;
+
+import org.apache.commons.io.output.NullOutputStream;
+import org.apache.poi.fuzz.POIFuzzer;
+import org.apache.poi.hpsf.HPSFPropertiesOnlyDocument;
+import org.apache.poi.hpsf.extractor.HPSFPropertiesExtractor;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.util.RecordFormatException;
+
+public class POIHPSFFuzzer {
+       public static void fuzzerInitialize() {
+               POIFuzzer.adjustLimits();
+       }
+
+       public static void fuzzerTestOneInput(byte[] input) {
+               try (POIFSFileSystem fs = new POIFSFileSystem(new 
ByteArrayInputStream(input))) {
+                       String workbookName = 
HSSFWorkbook.getWorkbookDirEntryName(fs.getRoot());
+                       fs.createDocumentInputStream(workbookName);
+
+                       try (HPSFPropertiesOnlyDocument document = new 
HPSFPropertiesOnlyDocument(fs)) {
+                               document.write(NullOutputStream.INSTANCE);
+                       }
+
+                       fs.writeFilesystem(NullOutputStream.INSTANCE);
+               } catch (IOException | IllegalArgumentException | 
IllegalStateException | RecordFormatException |
+                                IndexOutOfBoundsException | 
BufferUnderflowException | NoSuchElementException e) {
+                       // expected here
+               }
+
+               try (HPSFPropertiesExtractor extractor = new 
HPSFPropertiesExtractor(new POIFSFileSystem(new ByteArrayInputStream(input)))) {
+                       POIFuzzer.checkExtractor(extractor);
+               } catch (IOException | IllegalArgumentException | 
IllegalStateException | RecordFormatException |
+                                IndexOutOfBoundsException | 
BufferUnderflowException | NoSuchElementException e) {
+                       // expected
+               }
+       }
+}
diff --git a/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHSLFFuzzer.java 
b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHSLFFuzzer.java
new file mode 100644
index 0000000000..a70c36faf9
--- /dev/null
+++ b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHSLFFuzzer.java
@@ -0,0 +1,73 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.fuzz;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.BufferUnderflowException;
+import java.util.NoSuchElementException;
+
+import org.apache.commons.io.output.NullOutputStream;
+import org.apache.poi.hslf.exceptions.HSLFException;
+import org.apache.poi.hslf.usermodel.HSLFShape;
+import org.apache.poi.hslf.usermodel.HSLFSlideShow;
+import org.apache.poi.hslf.usermodel.HSLFSlideShowImpl;
+import org.apache.poi.hslf.usermodel.HSLFTextParagraph;
+import org.apache.poi.ooxml.POIXMLException;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.sl.extractor.SlideShowExtractor;
+import org.apache.poi.sl.usermodel.SlideShowFactory;
+import org.apache.poi.util.RecordFormatException;
+
+public class POIHSLFFuzzer {
+       public static void fuzzerInitialize() {
+               POIFuzzer.adjustLimits();
+       }
+
+       public static void fuzzerTestOneInput(byte[] input) {
+               try (HSLFSlideShow slides = new HSLFSlideShow(new 
ByteArrayInputStream(input))) {
+                       slides.write(NullOutputStream.INSTANCE);
+               } catch (IOException | IllegalArgumentException | 
RecordFormatException |
+                                IllegalStateException | HSLFException | 
IndexOutOfBoundsException |
+                                BufferUnderflowException | POIXMLException | 
NoSuchElementException |
+                               NegativeArraySizeException e) {
+                       // expected here
+               }
+
+               try (HSLFSlideShowImpl slides = new HSLFSlideShowImpl(new 
ByteArrayInputStream(input))) {
+                       slides.write(NullOutputStream.INSTANCE);
+               } catch (IOException | IllegalArgumentException | 
RecordFormatException |
+                                IllegalStateException | HSLFException | 
IndexOutOfBoundsException |
+                                BufferUnderflowException | POIXMLException | 
NoSuchElementException |
+                                NegativeArraySizeException e) {
+                       // expected here
+               }
+
+               try {
+                       try (SlideShowExtractor<HSLFShape, HSLFTextParagraph> 
extractor =
+                                       new 
SlideShowExtractor<>((HSLFSlideShow) SlideShowFactory.create(
+                                                       new POIFSFileSystem(new 
ByteArrayInputStream(input)).getRoot()))) {
+                               POIFuzzer.checkExtractor(extractor);
+                       }
+               } catch (IOException | IllegalArgumentException | 
RecordFormatException |
+                                IllegalStateException | HSLFException | 
IndexOutOfBoundsException |
+                                BufferUnderflowException | POIXMLException | 
NoSuchElementException e) {
+                       // expected here
+               }
+       }
+}
diff --git a/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHSMFFuzzer.java 
b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHSMFFuzzer.java
new file mode 100644
index 0000000000..a2ecc61bf9
--- /dev/null
+++ b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHSMFFuzzer.java
@@ -0,0 +1,56 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.fuzz;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.BufferUnderflowException;
+import java.util.NoSuchElementException;
+
+import org.apache.poi.hsmf.MAPIMessage;
+import org.apache.poi.hsmf.datatypes.AttachmentChunks;
+import org.apache.poi.hsmf.datatypes.DirectoryChunk;
+import org.apache.poi.hsmf.exceptions.ChunkNotFoundException;
+import org.apache.poi.util.RecordFormatException;
+
+public class POIHSMFFuzzer {
+       public static void fuzzerInitialize() {
+               POIFuzzer.adjustLimits();
+       }
+
+       public static void fuzzerTestOneInput(byte[] input) {
+               try (MAPIMessage mapi = new MAPIMessage(new 
ByteArrayInputStream(input))) {
+                       mapi.getAttachmentFiles();
+                       mapi.getDisplayBCC();
+                       mapi.getMessageDate();
+
+                       AttachmentChunks[] attachments = 
mapi.getAttachmentFiles();
+                       for (AttachmentChunks attachment : attachments) {
+                               DirectoryChunk chunkDirectory = 
attachment.getAttachmentDirectory();
+                               if (chunkDirectory != null) {
+                                       MAPIMessage attachmentMSG = 
chunkDirectory.getAsEmbeddedMessage();
+                                       attachmentMSG.getTextBody();
+                               }
+                       }
+               } catch (IOException | ChunkNotFoundException | 
IllegalArgumentException |
+                                RecordFormatException | 
IndexOutOfBoundsException | NoSuchElementException |
+                                BufferUnderflowException | 
IllegalStateException e) {
+                       // expected here
+               }
+       }
+}
diff --git a/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHSSFFuzzer.java 
b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHSSFFuzzer.java
new file mode 100644
index 0000000000..2c4552a7bf
--- /dev/null
+++ b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHSSFFuzzer.java
@@ -0,0 +1,61 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.fuzz;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.BufferUnderflowException;
+import java.util.NoSuchElementException;
+
+import org.apache.commons.io.output.NullOutputStream;
+import org.apache.poi.fuzz.POIFuzzer;
+import org.apache.poi.hslf.exceptions.HSLFException;
+import org.apache.poi.hssf.extractor.ExcelExtractor;
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.util.RecordFormatException;
+
+public class POIHSSFFuzzer {
+       public static void fuzzerInitialize() {
+               POIFuzzer.adjustLimits();
+       }
+
+       public static void fuzzerTestOneInput(byte[] input) {
+               try (HSSFWorkbook wb = new HSSFWorkbook(new 
ByteArrayInputStream(input))) {
+                       wb.write(NullOutputStream.INSTANCE);
+               } catch (IOException | IllegalArgumentException | 
RecordFormatException | IllegalStateException |
+                                IndexOutOfBoundsException | 
RecordInputStream.LeftoverDataException |
+                                BufferUnderflowException | 
UnsupportedOperationException | NoSuchElementException |
+                               NegativeArraySizeException e) {
+                       // expected here
+               }
+
+               try {
+                       try (ExcelExtractor extractor = new ExcelExtractor(
+                                                       new POIFSFileSystem(new 
ByteArrayInputStream(input)).getRoot())) {
+                               POIFuzzer.checkExtractor(extractor);
+                       }
+               } catch (IOException | IllegalArgumentException | 
RecordFormatException | IllegalStateException |
+                                IndexOutOfBoundsException | 
RecordInputStream.LeftoverDataException |
+                                BufferUnderflowException | 
UnsupportedOperationException | NoSuchElementException |
+                                NegativeArraySizeException | HSLFException e) {
+                       // expected here
+               }
+       }
+}
diff --git a/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHWPFFuzzer.java 
b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHWPFFuzzer.java
new file mode 100644
index 0000000000..d487c131ac
--- /dev/null
+++ b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIHWPFFuzzer.java
@@ -0,0 +1,59 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.fuzz;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.BufferUnderflowException;
+import java.util.NoSuchElementException;
+
+import org.apache.commons.io.output.NullOutputStream;
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.hwpf.HWPFDocument;
+import org.apache.poi.hwpf.extractor.WordExtractor;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.util.DocumentFormatException;
+import org.apache.poi.util.RecordFormatException;
+
+public class POIHWPFFuzzer {
+       public static void fuzzerInitialize() {
+               POIFuzzer.adjustLimits();
+       }
+
+       public static void fuzzerTestOneInput(byte[] input) {
+               try (HWPFDocument doc = new HWPFDocument(new 
ByteArrayInputStream(input))) {
+                       doc.write(NullOutputStream.INSTANCE);
+               } catch (IOException | IllegalArgumentException | 
IndexOutOfBoundsException | BufferUnderflowException |
+                               NoSuchElementException | RecordFormatException 
| IllegalStateException |
+                               UnsupportedOperationException | 
NegativeArraySizeException e) {
+                       // expected here
+               }
+
+               try {
+                       try (WordExtractor extractor = new WordExtractor(
+                                                       new POIFSFileSystem(new 
ByteArrayInputStream(input)).getRoot())) {
+                               POIFuzzer.checkExtractor(extractor);
+                       }
+               } catch (IOException | IllegalArgumentException | 
IndexOutOfBoundsException | BufferUnderflowException |
+                               NoSuchElementException | RecordFormatException 
| IllegalStateException |
+                               DocumentFormatException | 
UnsupportedOperationException | NegativeArraySizeException |
+                               RecordInputStream.LeftoverDataException e) {
+                       // expected here
+               }
+       }
+}
diff --git a/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIOldExcelFuzzer.java 
b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIOldExcelFuzzer.java
new file mode 100644
index 0000000000..1edeae31ed
--- /dev/null
+++ b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIOldExcelFuzzer.java
@@ -0,0 +1,47 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.fuzz;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.BufferUnderflowException;
+import java.util.NoSuchElementException;
+
+import org.apache.poi.hssf.extractor.OldExcelExtractor;
+import org.apache.poi.hssf.record.RecordInputStream;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.util.RecordFormatException;
+
+public class POIOldExcelFuzzer {
+       public static void fuzzerInitialize() {
+               POIFuzzer.adjustLimits();
+       }
+
+       public static void fuzzerTestOneInput(byte[] input) {
+               try {
+                       try (OldExcelExtractor extractor = new 
OldExcelExtractor(
+                                                       new POIFSFileSystem(new 
ByteArrayInputStream(input)).getRoot())) {
+                               POIFuzzer.checkExtractor(extractor);
+                       }
+               } catch (IOException | IllegalArgumentException | 
RecordFormatException | IndexOutOfBoundsException |
+                                RecordInputStream.LeftoverDataException | 
IllegalStateException | BufferUnderflowException |
+                                NoSuchElementException e) {
+                       // expected here
+               }
+       }
+}
diff --git a/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIVisioFuzzer.java 
b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIVisioFuzzer.java
new file mode 100644
index 0000000000..e4db2f80c1
--- /dev/null
+++ b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIVisioFuzzer.java
@@ -0,0 +1,60 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.fuzz;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.BufferUnderflowException;
+import java.util.NoSuchElementException;
+
+import org.apache.commons.io.output.NullOutputStream;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.poi.hdgf.extractor.VisioTextExtractor;
+import org.apache.poi.ooxml.POIXMLException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException;
+import org.apache.poi.util.RecordFormatException;
+import org.apache.poi.xdgf.usermodel.XmlVisioDocument;
+
+public class POIVisioFuzzer {
+       public static void fuzzerInitialize() {
+               POIFuzzer.adjustLimits();
+       }
+
+       public static void fuzzerTestOneInput(byte[] input) {
+               try (XmlVisioDocument visio = new XmlVisioDocument(new 
ByteArrayInputStream(input))) {
+                       visio.write(NullOutputStream.INSTANCE);
+               } catch (IOException | POIXMLException |
+                                BufferUnderflowException | 
RecordFormatException | OpenXML4JRuntimeException |
+                                IllegalArgumentException | 
IndexOutOfBoundsException | IllegalStateException e) {
+                       // expected here
+               } catch (NullPointerException e) {
+                       // can be removed when commons-compress is > 1.28.0 and 
changes from COMPRESS-598 are applied
+                       if 
(!ExceptionUtils.getStackTrace(e).contains("ZipArchiveInputStream.read")) {
+                               throw e;
+                       }
+               }
+
+               try (VisioTextExtractor extractor = new VisioTextExtractor(new 
ByteArrayInputStream(input))) {
+                       POIFuzzer.checkExtractor(extractor);
+               } catch (IOException | POIXMLException | 
IllegalArgumentException | BufferUnderflowException |
+                                RecordFormatException | 
IndexOutOfBoundsException | ArithmeticException | IllegalStateException |
+                                NoSuchElementException e) {
+                       // expected
+               }
+       }
+}
diff --git a/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIXSLFFuzzer.java 
b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIXSLFFuzzer.java
new file mode 100644
index 0000000000..e95ae96c15
--- /dev/null
+++ b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIXSLFFuzzer.java
@@ -0,0 +1,66 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.fuzz;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import org.apache.commons.io.output.NullOutputStream;
+import org.apache.poi.ooxml.POIXMLException;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.util.RecordFormatException;
+import org.apache.poi.xslf.extractor.XSLFExtractor;
+import org.apache.poi.xslf.usermodel.XMLSlideShow;
+import org.apache.poi.xslf.usermodel.XSLFSlideShow;
+import org.apache.xmlbeans.XmlException;
+
+public class POIXSLFFuzzer {
+       public static void fuzzerInitialize() {
+               POIFuzzer.adjustLimits();
+       }
+
+       public static void fuzzerTestOneInput(byte[] input) {
+               try (XMLSlideShow slides = new XMLSlideShow(new 
ByteArrayInputStream(input))) {
+                       slides.write(NullOutputStream.INSTANCE);
+               } catch (IOException | POIXMLException | RecordFormatException 
| OpenXML4JRuntimeException |
+                                IndexOutOfBoundsException | 
IllegalArgumentException e) {
+                       // expected here
+               }
+
+               try (OPCPackage pkg = OPCPackage.open(new 
ByteArrayInputStream(input))) {
+                       try (XSLFSlideShow slides = new XSLFSlideShow(pkg)) {
+                               slides.write(NullOutputStream.INSTANCE);
+                       }
+               } catch (IOException | OpenXML4JException | XmlException | 
IllegalArgumentException | POIXMLException |
+                                RecordFormatException | IllegalStateException 
| OpenXML4JRuntimeException | IndexOutOfBoundsException e) {
+                       // expected here
+               }
+
+               try (OPCPackage pkg = OPCPackage.open(new 
ByteArrayInputStream(input))) {
+                       try (XSLFExtractor extractor = new XSLFExtractor(new 
XMLSlideShow(pkg))) {
+                               POIFuzzer.checkExtractor(extractor);
+                       }
+               } catch (IOException | InvalidFormatException | POIXMLException 
| IllegalArgumentException |
+                               RecordFormatException | IllegalStateException | 
IndexOutOfBoundsException e) {
+                       // expected
+               }
+       }
+}
diff --git a/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIXSSFFuzzer.java 
b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIXSSFFuzzer.java
new file mode 100644
index 0000000000..4cf7f3de12
--- /dev/null
+++ b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIXSSFFuzzer.java
@@ -0,0 +1,62 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.fuzz;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import org.apache.commons.io.output.NullOutputStream;
+import org.apache.poi.ooxml.POIXMLException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.util.RecordFormatException;
+import org.apache.poi.xssf.extractor.XSSFEventBasedExcelExtractor;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.apache.xmlbeans.XmlException;
+
+public class POIXSSFFuzzer {
+       public static void fuzzerInitialize() {
+               POIFuzzer.adjustLimits();
+       }
+
+       public static void fuzzerTestOneInput(byte[] input) {
+               try (XSSFWorkbook wb = new XSSFWorkbook(new 
ByteArrayInputStream(input))) {
+                       try (SXSSFWorkbook swb = new SXSSFWorkbook(wb)) {
+                               swb.write(NullOutputStream.INSTANCE);
+                       }
+               } catch (IOException | POIXMLException | RecordFormatException 
| IllegalStateException |
+                                OpenXML4JRuntimeException | 
IllegalArgumentException | IndexOutOfBoundsException e) {
+                       // expected here
+               }
+
+               try (OPCPackage pkg = OPCPackage.open(new 
ByteArrayInputStream(input))) {
+                       try (XSSFEventBasedExcelExtractor extractor = new 
XSSFEventBasedExcelExtractor(pkg)) {
+                               POIFuzzer.checkExtractor(extractor);
+                       }
+               } catch (IOException | XmlException | OpenXML4JException | 
POIXMLException | RecordFormatException |
+                               IllegalStateException | 
IllegalArgumentException | IndexOutOfBoundsException e) {
+                       // expected
+               } catch (NullPointerException e) {
+                       if (!e.getMessage().startsWith("Cannot invoke 
\"java.io.InputStream.read(byte[], int, int)\"")) {
+                               throw e;
+                       }
+               }
+       }
+}
diff --git a/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIXWPFFuzzer.java 
b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIXWPFFuzzer.java
new file mode 100644
index 0000000000..74daa9a55a
--- /dev/null
+++ b/poi-fuzz/src/main/java/org/apache/poi/fuzz/POIXWPFFuzzer.java
@@ -0,0 +1,66 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.fuzz;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import org.apache.commons.io.output.NullOutputStream;
+import org.apache.poi.ooxml.POIXMLException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException;
+import org.apache.poi.util.RecordFormatException;
+import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
+import org.apache.poi.xwpf.usermodel.XWPFDocument;
+
+public class POIXWPFFuzzer {
+       public static void fuzzerInitialize() {
+               POIFuzzer.adjustLimits();
+       }
+
+       @SuppressWarnings("ResultOfMethodCallIgnored")
+       public static void fuzzerTestOneInput(byte[] input) {
+               try (XWPFDocument doc = new XWPFDocument(new 
ByteArrayInputStream(input))) {
+                       doc.write(NullOutputStream.INSTANCE);
+
+                       // if the document can be parsed, trigger some of the 
getters
+                       try {
+                               doc.getAllEmbeddedParts();
+                               doc.getAllPictures();
+                               doc.getAllPackagePictures();
+                               doc.getPackage();
+                               doc.getPackagePart();
+                               doc.getProperties();
+                               doc.getRelations();
+                               doc.getCharts();
+                               doc.getBodyElements();
+                               doc.getBodyElementsIterator();
+                               doc.getBodyElementsSpliterator();
+                       } catch (OpenXML4JException | POIXMLException e) {
+                               // expected
+                       }
+
+                       try (XWPFWordExtractor extractor = new 
XWPFWordExtractor(doc)) {
+                               POIFuzzer.checkExtractor(extractor);
+                       }
+               } catch (IOException | POIXMLException | RecordFormatException 
| OpenXML4JRuntimeException |
+                                IllegalArgumentException | 
IllegalStateException | IndexOutOfBoundsException e) {
+                       // expected
+               }
+       }
+}
diff --git a/poi-fuzz/src/main/java/org/apache/poi/fuzz/XLSX2CSVFuzzer.java 
b/poi-fuzz/src/main/java/org/apache/poi/fuzz/XLSX2CSVFuzzer.java
new file mode 100644
index 0000000000..0cb610544d
--- /dev/null
+++ b/poi-fuzz/src/main/java/org/apache/poi/fuzz/XLSX2CSVFuzzer.java
@@ -0,0 +1,51 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.fuzz;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.io.output.NullPrintStream;
+import org.apache.poi.fuzz.POIFuzzer;
+import org.apache.poi.examples.xssf.eventusermodel.XLSX2CSV;
+import org.apache.poi.ooxml.POIXMLException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.util.RecordFormatException;
+import org.xml.sax.SAXException;
+
+public class XLSX2CSVFuzzer {
+       public static void fuzzerInitialize() {
+               POIFuzzer.adjustLimits();
+       }
+
+       public static void fuzzerTestOneInput(byte[] input) {
+               try (InputStream in = new ByteArrayInputStream(input)) {
+                       OPCPackage p = OPCPackage.open(in);
+                       XLSX2CSV xlsx2csv = new XLSX2CSV(p, 
NullPrintStream.INSTANCE, 5);
+                       xlsx2csv.process();
+               } catch (IOException | OpenXML4JException | SAXException |
+                                POIXMLException | RecordFormatException |
+                                IllegalStateException | 
IllegalArgumentException |
+                                IndexOutOfBoundsException | 
OpenXML4JRuntimeException e) {
+                       // expected here
+               }
+       }
+}
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to