You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ce...@apache.org on 2026/01/16 17:52:33 UTC
(poi) branch trunk updated (d60edd21a3 -> d72e3a608c)
This is an automated email from the ASF dual-hosted git repository.
centic pushed a change to branch trunk
in repository https://gitbox.apache.org/repos/asf/poi.git
from d60edd21a3 Bump net.bytebuddy:byte-buddy from 1.18.3 to 1.18.4 (#998)
new 2acb5cf66a Avoid several NPEs
new b09bf904d7 Fix running integration-tests without scratchpad-libraries
new 9c2f487c98 Bug 69927: Avoid NPE when parsing wmf-file
new 22531fe638 Prevent invalid height/width in wmf-images exhausting memory
new 1910fff53e Add a file-handler for .wmf files
new d72e3a608c Add a file-handler for .emf files
The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../org/apache/poi/stress/FileHandlerKnown.java | 2 +
.../org/apache/poi/stress/HEMFFileHandler.java | 85 +++++++++++++++++++
.../org/apache/poi/stress/HWMFFileHandler.java | 93 +++++++++++++++++++++
.../org/apache/poi/stress/SpreadsheetHandler.java | 2 +
.../java/org/apache/poi/stress/TestAllFiles.java | 4 +-
.../org/apache/poi/ooxml/POIXMLDocumentPart.java | 4 +-
.../org/apache/poi/xslf/usermodel/XSLFTable.java | 3 +
.../org/apache/poi/xssf/usermodel/XSSFPicture.java | 7 +-
.../apache/poi/xslf/draw/geom/TestXSLFArcTo.java | 62 ++++++++++++++
.../apache/poi/xslf/usermodel/TestXSLFTable.java | 19 +++--
poi-ooxml/src/test/java9/module-info.java | 1 +
.../org/apache/poi/hwmf/record/HwmfBitmapDib.java | 34 +++++++-
.../java/org/apache/poi/hwmf/TestHwmfParsing.java | 3 +-
.../org/apache/poi/hssf/model/InternalSheet.java | 7 ++
.../org/apache/poi/hssf/usermodel/HSSFPicture.java | 32 +++----
.../org/apache/poi/hssf/usermodel/HSSFShape.java | 4 +
.../org/apache/poi/sl/draw/DrawTextParagraph.java | 4 +-
.../apache/poi/sl/draw/geom/ArcToCommandIf.java | 4 +
.../apache/poi/ss/extractor/EmbeddedExtractor.java | 2 +-
.../apache/poi/hssf/model/TestInternalSheet.java | 72 ++++++++++++++++
.../apache/poi/hssf/usermodel/TestHSSFComment.java | 10 +++
.../apache/poi/hssf/usermodel/TestHSSFPicture.java | 26 ++++++
test-data/slideshow/file-45.wmf | Bin 0 -> 24890 bytes
...tent_4_evaluation_module_decouverte_qesamed.xls | Bin 0 -> 425984 bytes
test-data/spreadsheet/stress.xls | Bin 75776 -> 76800 bytes
25 files changed, 451 insertions(+), 29 deletions(-)
create mode 100644 poi-integration/src/test/java/org/apache/poi/stress/HEMFFileHandler.java
create mode 100644 poi-integration/src/test/java/org/apache/poi/stress/HWMFFileHandler.java
create mode 100644 poi-ooxml/src/test/java/org/apache/poi/xslf/draw/geom/TestXSLFArcTo.java
create mode 100644 poi/src/test/java/org/apache/poi/hssf/model/TestInternalSheet.java
create mode 100644 test-data/slideshow/file-45.wmf
create mode 100644 test-data/spreadsheet/moodle.iamm.fr_pluginfile.php_2971_mod_resource_content_4_evaluation_module_decouverte_qesamed.xls
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org
(poi) 03/06: Bug 69927: Avoid NPE when parsing wmf-file
Posted by ce...@apache.org.
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 9c2f487c98a36b9b7036bd64a4576bd5a3085336
Author: Dominik Stadler <do...@gmx.at>
AuthorDate: Fri Jan 16 07:53:47 2026 +0100
Bug 69927: Avoid NPE when parsing wmf-file
headerBitCount can be null if the header contains an
invalid flag
---
.../java/org/apache/poi/hwmf/record/HwmfBitmapDib.java | 7 ++++++-
.../test/java/org/apache/poi/hwmf/TestHwmfParsing.java | 3 ++-
test-data/slideshow/file-45.wmf | Bin 0 -> 24890 bytes
3 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hwmf/record/HwmfBitmapDib.java b/poi-scratchpad/src/main/java/org/apache/poi/hwmf/record/HwmfBitmapDib.java
index b6c59a2dfe..bb2e66bfa2 100644
--- a/poi-scratchpad/src/main/java/org/apache/poi/hwmf/record/HwmfBitmapDib.java
+++ b/poi-scratchpad/src/main/java/org/apache/poi/hwmf/record/HwmfBitmapDib.java
@@ -243,7 +243,8 @@ public class HwmfBitmapDib implements GenericRecord {
// The size and format of this data is determined by information in the DIBHeaderInfo field. If
// it is a BitmapCoreHeader, the size in bytes MUST be calculated as follows:
- int bodySize = ((((headerWidth * headerPlanes * headerBitCount.flag + 31) & ~31) / 8) * Math.abs(headerHeight));
+ int bodySize = ((((headerWidth * headerPlanes *
+ (headerBitCount == null ? 0 : headerBitCount.flag) + 31) & ~31) / 8) * Math.abs(headerHeight));
// This formula SHOULD also be used to calculate the size of aData when DIBHeaderInfo is a
// BitmapInfoHeader Object, using values from that object, but only if its Compression value is
@@ -348,6 +349,10 @@ public class HwmfBitmapDib implements GenericRecord {
}
protected int readColors(LittleEndianInputStream leis) throws IOException {
+ if (headerBitCount == null) {
+ return 0;
+ }
+
switch (headerBitCount) {
default:
case BI_BITCOUNT_0:
diff --git a/poi-scratchpad/src/test/java/org/apache/poi/hwmf/TestHwmfParsing.java b/poi-scratchpad/src/test/java/org/apache/poi/hwmf/TestHwmfParsing.java
index dff936b099..3f8e270896 100644
--- a/poi-scratchpad/src/test/java/org/apache/poi/hwmf/TestHwmfParsing.java
+++ b/poi-scratchpad/src/test/java/org/apache/poi/hwmf/TestHwmfParsing.java
@@ -54,7 +54,8 @@ public class TestHwmfParsing {
@CsvSource({
"santa.wmf, 581",
/* Bug 65063 */
- "empty-polygon-close.wmf, 272"
+ "empty-polygon-close.wmf, 272",
+ "file-45.wmf, 1315"
})
void parse(String file, int recordCnt) throws IOException {
try (InputStream fis = samples.openResourceAsStream(file)) {
diff --git a/test-data/slideshow/file-45.wmf b/test-data/slideshow/file-45.wmf
new file mode 100644
index 0000000000..6293588017
Binary files /dev/null and b/test-data/slideshow/file-45.wmf differ
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org
(poi) 02/06: Fix running integration-tests without scratchpad-libraries
Posted by ce...@apache.org.
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 b09bf904d776924e6ac4784c42ee79b7344a1adb
Author: Dominik Stadler <do...@gmx.at>
AuthorDate: Mon Jan 12 08:18:02 2026 +0100
Fix running integration-tests without scratchpad-libraries
---
poi-integration/src/test/java/org/apache/poi/stress/TestAllFiles.java | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
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 b73914f09e..8b32ba8681 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
@@ -144,7 +144,9 @@ public class TestAllFiles {
"document/clusterfuzz-testcase-POIHWPFFuzzer-5696094627495936.doc",
"spreadsheet/clusterfuzz-testcase-minimized-POIHSSFFuzzer-4657005060816896.xls",
"diagram/clusterfuzz-testcase-minimized-POIHDGFFuzzer-4913778037489664.vsd",
- "diagram/clusterfuzz-testcase-minimized-POIHDGFFuzzer-6478389109981184.vsd"
+ "diagram/clusterfuzz-testcase-minimized-POIHDGFFuzzer-6478389109981184.vsd",
+ "publisher/clusterfuzz-testcase-minimized-POIHPBFFuzzer-4918886059278336.pub",
+ "publisher/clusterfuzz-testcase-minimized-POIHPBFFuzzer-4918886059278336.pub"
});
private static final Set<String> EXPECTED_FAILURES = StressTestUtils.unmodifiableHashSet(
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org
(poi) 05/06: Add a file-handler for .wmf files
Posted by ce...@apache.org.
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 1910fff53edf7eb5da010ff642a38392cce9704c
Author: Dominik Stadler <do...@gmx.at>
AuthorDate: Fri Jan 16 08:56:42 2026 +0100
Add a file-handler for .wmf files
These can be embedded in slideshows and POI supports
some handling of them.
Also Tika uses this code to extract some textual information
from such images.
---
.../org/apache/poi/stress/FileHandlerKnown.java | 1 +
.../org/apache/poi/stress/HWMFFileHandler.java | 93 +++++++++++++++++++++
test-data/spreadsheet/stress.xls | Bin 75776 -> 76288 bytes
3 files changed, 94 insertions(+)
diff --git a/poi-integration/src/test/java/org/apache/poi/stress/FileHandlerKnown.java b/poi-integration/src/test/java/org/apache/poi/stress/FileHandlerKnown.java
index c3f1e11137..dc2af11ba9 100644
--- a/poi-integration/src/test/java/org/apache/poi/stress/FileHandlerKnown.java
+++ b/poi-integration/src/test/java/org/apache/poi/stress/FileHandlerKnown.java
@@ -29,6 +29,7 @@ public enum FileHandlerKnown {
HSLF,
HSMF,
HSSF,
+ HWMF,
HWPF,
OPC,
POIFS,
diff --git a/poi-integration/src/test/java/org/apache/poi/stress/HWMFFileHandler.java b/poi-integration/src/test/java/org/apache/poi/stress/HWMFFileHandler.java
new file mode 100644
index 0000000000..3429844bfb
--- /dev/null
+++ b/poi-integration/src/test/java/org/apache/poi/stress/HWMFFileHandler.java
@@ -0,0 +1,93 @@
+/* ====================================================================
+ 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.stress;
+
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+
+import java.awt.image.BufferedImage;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+
+import org.apache.poi.hwmf.record.HwmfFont;
+import org.apache.poi.hwmf.record.HwmfRecord;
+import org.apache.poi.hwmf.record.HwmfRecordType;
+import org.apache.poi.hwmf.record.HwmfText;
+import org.apache.poi.hwmf.usermodel.HwmfPicture;
+import org.apache.poi.util.LocaleUtil;
+import org.junit.jupiter.api.Test;
+
+public class HWMFFileHandler implements FileHandler {
+
+ @Override
+ public void handleExtracting(File file) throws Exception {
+ try (InputStream stream = new BufferedInputStream(new FileInputStream(file))) {
+ HwmfPicture picture = new HwmfPicture(stream);
+ Charset charset = LocaleUtil.CHARSET_1252;
+
+ // mimic a bit what e.g. Tika does to extract some information from .wmf files
+ for (HwmfRecord record : picture.getRecords()) {
+ if (record.getWmfRecordType().equals(HwmfRecordType.createFontIndirect)) {
+ HwmfFont font = ((HwmfText.WmfCreateFontIndirect) record).getFont();
+ charset = (font.getCharset() == null || font.getCharset().getCharset() == null) ?
+ LocaleUtil.CHARSET_1252 : font.getCharset().getCharset();
+ }
+
+ if (record.getWmfRecordType().equals(HwmfRecordType.extTextOut)) {
+ assertInstanceOf(HwmfText.WmfExtTextOut.class, record);
+ HwmfText.WmfExtTextOut textOut = (HwmfText.WmfExtTextOut) record;
+ textOut.getText(charset);
+ } else if (record.getWmfRecordType().equals(HwmfRecordType.textOut)) {
+ assertInstanceOf(HwmfText.WmfTextOut.class, record);
+ HwmfText.WmfTextOut textOut = (HwmfText.WmfTextOut) record;
+ textOut.getText(charset);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void handleAdditional(File file) throws Exception {
+ // no additional checks for now
+ }
+
+ @Override
+ public void handleFile(InputStream stream, String path) throws Exception {
+ HwmfPicture picture = new HwmfPicture(stream);
+
+ for (HwmfRecord record : picture.getRecords()) {
+ record.getWmfRecordType();
+ record.getGenericRecordType();
+ }
+
+ BufferedImage dest = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
+ picture.draw(dest.createGraphics());
+ }
+
+ @Test
+ void test() throws Exception {
+ String file = "test-data/slideshow/santa.wmf";
+
+ try (InputStream stream = new BufferedInputStream(new FileInputStream(file))) {
+ handleFile(stream, file);
+ }
+
+ handleExtracting(new File(file));
+ }
+}
diff --git a/test-data/spreadsheet/stress.xls b/test-data/spreadsheet/stress.xls
index 17d8e2afca..a9d24e8244 100644
Binary files a/test-data/spreadsheet/stress.xls and b/test-data/spreadsheet/stress.xls differ
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org
(poi) 06/06: Add a file-handler for .emf files
Posted by ce...@apache.org.
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 d72e3a608ce4b46490542f85b80c3b5409488357
Author: Dominik Stadler <do...@gmx.at>
AuthorDate: Fri Jan 16 09:16:09 2026 +0100
Add a file-handler for .emf files
These can be embedded in slideshows and POI supports
some handling of them.
Also Tika uses this code to extract some textual information
from such images.
---
.../org/apache/poi/stress/FileHandlerKnown.java | 1 +
.../org/apache/poi/stress/HEMFFileHandler.java | 85 +++++++++++++++++++++
test-data/spreadsheet/stress.xls | Bin 76288 -> 76800 bytes
3 files changed, 86 insertions(+)
diff --git a/poi-integration/src/test/java/org/apache/poi/stress/FileHandlerKnown.java b/poi-integration/src/test/java/org/apache/poi/stress/FileHandlerKnown.java
index dc2af11ba9..1e113c714a 100644
--- a/poi-integration/src/test/java/org/apache/poi/stress/FileHandlerKnown.java
+++ b/poi-integration/src/test/java/org/apache/poi/stress/FileHandlerKnown.java
@@ -29,6 +29,7 @@ public enum FileHandlerKnown {
HSLF,
HSMF,
HSSF,
+ HEMF,
HWMF,
HWPF,
OPC,
diff --git a/poi-integration/src/test/java/org/apache/poi/stress/HEMFFileHandler.java b/poi-integration/src/test/java/org/apache/poi/stress/HEMFFileHandler.java
new file mode 100644
index 0000000000..dd0e5fbe27
--- /dev/null
+++ b/poi-integration/src/test/java/org/apache/poi/stress/HEMFFileHandler.java
@@ -0,0 +1,85 @@
+/* ====================================================================
+ 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.stress;
+
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.apache.poi.hemf.record.emf.HemfRecord;
+import org.apache.poi.hemf.record.emf.HemfRecordType;
+import org.apache.poi.hemf.record.emf.HemfText;
+import org.apache.poi.hemf.usermodel.HemfPicture;
+import org.junit.jupiter.api.Test;
+
+public class HEMFFileHandler implements FileHandler {
+
+ @Override
+ public void handleExtracting(File file) throws Exception {
+ try (InputStream stream = new BufferedInputStream(new FileInputStream(file))) {
+ HemfPicture picture = new HemfPicture(stream);
+
+ // mimic a bit what e.g. Tika does to extract some information from .emf files
+ for (HemfRecord record : picture.getRecords()) {
+ if (record.getEmfRecordType().equals(HemfRecordType.extTextOutW)) {
+ assertInstanceOf(HemfText.EmfExtTextOutW.class, record);
+ HemfText.EmfExtTextOutW textOut = (HemfText.EmfExtTextOutW) record;
+ textOut.getText(StandardCharsets.UTF_16LE);
+ } else if (record.getEmfRecordType().equals(HemfRecordType.extTextOutA)) {
+ assertInstanceOf(HemfText.EmfExtTextOutA.class, record);
+ HemfText.EmfExtTextOutA textOut = (HemfText.EmfExtTextOutA) record;
+ textOut.getText(StandardCharsets.UTF_8);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void handleAdditional(File file) throws Exception {
+ // no additional checks for now
+ }
+
+ @Override
+ public void handleFile(InputStream stream, String path) throws Exception {
+ HemfPicture picture = new HemfPicture(stream);
+
+ for (HemfRecord record : picture.getRecords()) {
+ record.getEmfRecordType();
+ record.getGenericRecordType();
+ }
+
+ BufferedImage dest = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
+ picture.draw(dest.createGraphics(), new Rectangle2D.Double(0, 0, 256, 256));
+ }
+
+ @Test
+ void test() throws Exception {
+ String file = "test-data/slideshow/wrench.emf";
+
+ try (InputStream stream = new BufferedInputStream(new FileInputStream(file))) {
+ handleFile(stream, file);
+ }
+
+ handleExtracting(new File(file));
+ }
+}
diff --git a/test-data/spreadsheet/stress.xls b/test-data/spreadsheet/stress.xls
index a9d24e8244..a03baec081 100644
Binary files a/test-data/spreadsheet/stress.xls and b/test-data/spreadsheet/stress.xls differ
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org
(poi) 01/06: Avoid several NPEs
Posted by ce...@apache.org.
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 2acb5cf66abb62d55ee42b5d2764f26ee5408c8a
Author: Dominik Stadler <do...@gmx.at>
AuthorDate: Mon Jan 12 07:14:48 2026 +0100
Avoid several NPEs
When retrieving picture data
When retrieving text in slides
When handling XSLFTableStyles
In EmbeddedExtractor if ShapeName is not set
In HSSF with invalid EscherSpRecord
In HSSF with invalid RecordStreams
When drawing arcs for shapes in slides
In HSSFPicture.getPictureIndex
Adjust "opens" for tests in poi-ooxml
Either handle it gracefully or throw
IllegalStateException instead for broken files
---
.../org/apache/poi/stress/SpreadsheetHandler.java | 2 +
.../org/apache/poi/ooxml/POIXMLDocumentPart.java | 4 +-
.../org/apache/poi/xslf/usermodel/XSLFTable.java | 3 +
.../org/apache/poi/xssf/usermodel/XSSFPicture.java | 7 +-
.../apache/poi/xslf/draw/geom/TestXSLFArcTo.java | 62 ++++++++++++++++++
.../apache/poi/xslf/usermodel/TestXSLFTable.java | 19 ++++--
poi-ooxml/src/test/java9/module-info.java | 1 +
.../org/apache/poi/hssf/model/InternalSheet.java | 7 ++
.../org/apache/poi/hssf/usermodel/HSSFPicture.java | 32 ++++-----
.../org/apache/poi/hssf/usermodel/HSSFShape.java | 4 ++
.../org/apache/poi/sl/draw/DrawTextParagraph.java | 4 +-
.../apache/poi/sl/draw/geom/ArcToCommandIf.java | 4 ++
.../apache/poi/ss/extractor/EmbeddedExtractor.java | 2 +-
.../apache/poi/hssf/model/TestInternalSheet.java | 72 +++++++++++++++++++++
.../apache/poi/hssf/usermodel/TestHSSFComment.java | 10 +++
.../apache/poi/hssf/usermodel/TestHSSFPicture.java | 26 ++++++++
...tent_4_evaluation_module_decouverte_qesamed.xls | Bin 0 -> 425984 bytes
test-data/spreadsheet/stress.xls | Bin 75776 -> 75776 bytes
18 files changed, 233 insertions(+), 26 deletions(-)
diff --git a/poi-integration/src/test/java/org/apache/poi/stress/SpreadsheetHandler.java b/poi-integration/src/test/java/org/apache/poi/stress/SpreadsheetHandler.java
index 1e57bb856a..40f103b523 100644
--- a/poi-integration/src/test/java/org/apache/poi/stress/SpreadsheetHandler.java
+++ b/poi-integration/src/test/java/org/apache/poi/stress/SpreadsheetHandler.java
@@ -37,6 +37,8 @@ public abstract class SpreadsheetHandler extends AbstractFileHandler {
// try to access some of the content
readContent(wb);
+ extractEmbedded(wb);
+
// write out the file
writeToArray(wb);
diff --git a/poi-ooxml/src/main/java/org/apache/poi/ooxml/POIXMLDocumentPart.java b/poi-ooxml/src/main/java/org/apache/poi/ooxml/POIXMLDocumentPart.java
index 9a619a410f..56dda3039f 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/ooxml/POIXMLDocumentPart.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/ooxml/POIXMLDocumentPart.java
@@ -259,7 +259,7 @@ public class POIXMLDocumentPart {
*/
public final POIXMLDocumentPart getRelationById(String id) {
RelationPart rp = getRelationPartById(id);
- return (rp == null) ? null : rp.getDocumentPart();
+ return rp == null ? null : rp.getDocumentPart();
}
/**
@@ -797,7 +797,7 @@ public class POIXMLDocumentPart {
* @since 5.3.0
*/
public final HyperlinkRelationship createHyperlink(URI uri, boolean isExternal, String relId) {
- PackageRelationship pr = packagePart.addRelationship(uri, isExternal ? TargetMode.EXTERNAL : TargetMode.INTERNAL,
+ packagePart.addRelationship(uri, isExternal ? TargetMode.EXTERNAL : TargetMode.INTERNAL,
PackageRelationshipTypes.HYPERLINK_PART, relId);
HyperlinkRelationship hyperlink = new HyperlinkRelationship(this, uri, isExternal, relId);
referenceRelationships.put(relId, hyperlink);
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTable.java b/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTable.java
index eb02744437..eeb48af8a7 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTable.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTable.java
@@ -340,6 +340,9 @@ public class XSLFTable extends XSLFGraphicFrame implements Iterable<XSLFTableRow
String styleId = tab.getTblPr().getTableStyleId();
XSLFTableStyles styles = getSheet().getSlideShow().getTableStyles();
+ if (styles == null) {
+ return null;
+ }
for (XSLFTableStyle style : styles.getStyles()) {
if (style.getStyleId().equals(styleId)) {
return style;
diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFPicture.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFPicture.java
index fe59d4c6b6..da377e7ab9 100644
--- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFPicture.java
+++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFPicture.java
@@ -263,10 +263,15 @@ public final class XSSFPicture extends XSSFShape implements Picture {
/**
* Return picture data for this shape
*
- * @return picture data for this shape
+ * @return picture data for this shape or null if
+ * the data cannot be retrieved
*/
@Override
public XSSFPictureData getPictureData() {
+ if (ctPicture.getBlipFill().getBlip() == null) {
+ return null;
+ }
+
String blipId = ctPicture.getBlipFill().getBlip().getEmbed();
return (XSSFPictureData)getDrawing().getRelationById(blipId);
}
diff --git a/poi-ooxml/src/test/java/org/apache/poi/xslf/draw/geom/TestXSLFArcTo.java b/poi-ooxml/src/test/java/org/apache/poi/xslf/draw/geom/TestXSLFArcTo.java
new file mode 100644
index 0000000000..44fe8f0b3b
--- /dev/null
+++ b/poi-ooxml/src/test/java/org/apache/poi/xslf/draw/geom/TestXSLFArcTo.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.xslf.draw.geom;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.awt.geom.Path2D;
+
+import org.apache.poi.sl.draw.geom.ArcToCommand;
+import org.apache.poi.sl.draw.geom.Context;
+import org.apache.poi.sl.draw.geom.CustomGeometry;
+import org.junit.jupiter.api.Test;
+
+class TestXSLFArcTo {
+ @Test
+ void test() {
+ ArcToCommand arc = new ArcToCommand();
+ CustomGeometry geom = new CustomGeometry();
+ Context ctx = new Context(geom, null, null) {
+
+ @Override
+ public double getValue(String key) {
+ return 1.0;
+ }
+ };
+
+ Path2D.Double path = new Path2D.Double();
+ path.moveTo(1.0, 1.0);
+ path.lineTo(2.0, 2.0);
+ arc.execute(path, ctx);
+ }
+
+ @Test
+ void testPointFails() {
+ ArcToCommand arc = new ArcToCommand();
+ CustomGeometry geom = new CustomGeometry();
+ Context ctx = new Context(geom, null, null) {
+
+ @Override
+ public double getValue(String key) {
+ return 1.0;
+ }
+ };
+
+ assertThrows(IllegalStateException.class,
+ () -> arc.execute(new Path2D.Double(), ctx));
+ }
+}
diff --git a/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFTable.java b/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFTable.java
index 827bed7243..9529309a2a 100644
--- a/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFTable.java
+++ b/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFTable.java
@@ -19,6 +19,7 @@ package org.apache.poi.xslf.usermodel;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
@@ -80,6 +81,7 @@ class TestXSLFTable {
tab.removeColumn(0);
tab.removeColumn(tab.getNumberOfColumns() - 1);
assertEquals(data[0].length, tab.getNumberOfColumns());
+ assertNull(tab.getTableStyle());
int startRow = rowIdx-1;
@@ -163,7 +165,7 @@ class TestXSLFTable {
XSLFSlide slide = ppt.getSlides().get(3);
List<XSLFShape> shapes = slide.getShapes();
assertEquals(1, shapes.size());
- assertTrue(shapes.get(0) instanceof XSLFTable);
+ assertInstanceOf(XSLFTable.class, shapes.get(0));
XSLFTable tbl = (XSLFTable)shapes.get(0);
assertEquals(3, tbl.getNumberOfColumns());
assertEquals(6, tbl.getNumberOfRows());
@@ -175,6 +177,7 @@ class TestXSLFTable {
assertEquals(90.0, tbl.getColumnWidth(0), 0);
assertEquals(240.0, tbl.getColumnWidth(1), 0);
assertEquals(150.0, tbl.getColumnWidth(2), 0);
+ assertNotNull(tbl.getTableStyle());
for(XSLFTableRow row : tbl){
// all rows have the same height
@@ -207,7 +210,7 @@ class TestXSLFTable {
assertNotNull(tbl.getCTTable());
assertNotNull(tbl.getCTTable().getTblGrid());
assertNotNull(tbl.getCTTable().getTblPr());
- assertTrue(tbl.getXmlObject() instanceof CTGraphicalObjectFrame);
+ assertInstanceOf(CTGraphicalObjectFrame.class, tbl.getXmlObject());
assertEquals("Table 2", tbl.getShapeName());
assertEquals(2, tbl.getShapeId());
assertEquals(0, tbl.getRows().size());
@@ -216,6 +219,7 @@ class TestXSLFTable {
assertEquals(0, tbl.getNumberOfColumns());
assertEquals(0, tbl.getNumberOfRows());
+ assertNull(tbl.getTableStyle());
XSLFTableRow row0 = tbl.addRow();
assertNotNull(row0.getXmlObject());
@@ -281,6 +285,7 @@ class TestXSLFTable {
XMLSlideShow ss = XSLFTestDataSamples.openSampleDocument("shapes.pptx");
XSLFSlide sl = ss.getSlides().get(0);
XSLFTable tab = (XSLFTable)sl.getShapes().get(4);
+ assertNotNull(tab.getTableStyle());
sl.removeShape(tab);
XMLSlideShow ss2 = XSLFTestDataSamples.writeOutAndReadBack(ss);
@@ -305,6 +310,7 @@ class TestXSLFTable {
XSLFTableCell tc0 = tr.addCell();
tc0.setText("bla bla bla bla");
tab.setColumnWidth(0, 50);
+ assertNull(tab.getTableStyle());
// usually text height == 88, but font rendering is platform dependent
// so we use something more reliable
@@ -355,13 +361,14 @@ class TestXSLFTable {
new DrawTableShape(newTable).setAllBorders(3., StrokeStyle.LineDash.LG_DASH_DOT, Color.BLUE);
assertEquals(3, newTable.getCTTable().getTblGrid().sizeOfGridColArray());
+ assertNull(newTable.getTableStyle());
}
}
private void verifyTableCellStyleColors(XSLFTableCell cell, String text, Color fontColor, Color fillColor) {
assertEquals(text, cell.getText());
PaintStyle colorText1 = cell.getTextParagraphs().get(0).getTextRuns().get(0).getFontColor();
- assertTrue(colorText1 instanceof PaintStyle.SolidPaint);
+ assertInstanceOf(PaintStyle.SolidPaint.class, colorText1);
assertEquals(fontColor, ((PaintStyle.SolidPaint)colorText1).getSolidColor().getColor());
assertEquals(fillColor, cell.getFillColor());
}
@@ -374,11 +381,12 @@ class TestXSLFTable {
List<XSLFShape> shapes = ppt.getSlides().get(0).getShapes();
assertEquals(1, shapes.size());
- assertTrue(shapes.get(0) instanceof XSLFTable);
+ assertInstanceOf(XSLFTable.class, shapes.get(0));
XSLFTable tbl = (XSLFTable)shapes.get(0);
assertEquals(4, tbl.getNumberOfColumns());
assertEquals(4, tbl.getNumberOfRows());
assertNotNull(tbl.getCTTable());
+ assertNotNull(tbl.getTableStyle());
// Yellow font color due to "first row" table style
verifyTableCellStyleColors(tbl.getRows().get(0).getCells().get(0), "Text 1",
@@ -403,11 +411,12 @@ class TestXSLFTable {
shapes = ppt.getSlides().get(1).getShapes();
assertEquals(1, shapes.size());
- assertTrue(shapes.get(0) instanceof XSLFTable);
+ assertInstanceOf(XSLFTable.class, shapes.get(0));
tbl = (XSLFTable)shapes.get(0);
assertEquals(4, tbl.getNumberOfColumns());
assertEquals(4, tbl.getNumberOfRows());
assertNotNull(tbl.getCTTable());
+ assertNotNull(tbl.getTableStyle());
// Green font color due to "first column" table style
verifyTableCellStyleColors(tbl.getRows().get(0).getCells().get(0), "Text 1",
diff --git a/poi-ooxml/src/test/java9/module-info.java b/poi-ooxml/src/test/java9/module-info.java
index ab8306e8a1..bd058c8243 100644
--- a/poi-ooxml/src/test/java9/module-info.java
+++ b/poi-ooxml/src/test/java9/module-info.java
@@ -200,6 +200,7 @@ module org.apache.poi.ooxml {
opens org.apache.poi.xssf.streaming to org.junit.platform.commons;
opens org.apache.poi.xssf.util to org.junit.platform.commons;
opens org.apache.poi.xslf.draw to org.junit.platform.commons;
+ opens org.apache.poi.xslf.draw.geom to org.junit.platform.commons;
opens org.apache.poi.xslf.usermodel to org.junit.platform.commons;
opens org.apache.poi.xslf.model to org.junit.platform.commons;
opens org.apache.poi.xslf.util to org.junit.platform.commons;
diff --git a/poi/src/main/java/org/apache/poi/hssf/model/InternalSheet.java b/poi/src/main/java/org/apache/poi/hssf/model/InternalSheet.java
index 570494d830..d50dabfcbb 100644
--- a/poi/src/main/java/org/apache/poi/hssf/model/InternalSheet.java
+++ b/poi/src/main/java/org/apache/poi/hssf/model/InternalSheet.java
@@ -1075,6 +1075,10 @@ public final class InternalSheet {
}
private void setColumn(int column, Short xfStyle, Integer width, Integer level, Boolean hidden, Boolean collapsed) {
+ if (_columnInfos == null) {
+ throw new IllegalStateException("Cannot group column range with missing column-infos");
+ }
+
_columnInfos.setColumn( column, xfStyle, width, level, hidden, collapsed );
}
@@ -1087,6 +1091,9 @@ public final class InternalSheet {
* if false indenting will be removed by one level.
*/
public void groupColumnRange(int fromColumn, int toColumn, boolean indent) {
+ if (_columnInfos == null) {
+ throw new IllegalStateException("Cannot group column range with missing column-infos");
+ }
// Set the level for each column
_columnInfos.groupColumnRange( fromColumn, toColumn, indent);
diff --git a/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFPicture.java b/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFPicture.java
index 48269513d0..3b2cd4505d 100644
--- a/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFPicture.java
+++ b/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFPicture.java
@@ -52,25 +52,27 @@ public class HSSFPicture extends HSSFSimpleShape implements Picture {
/**
* Constructs a picture object.
*/
- public HSSFPicture( HSSFShape parent, HSSFAnchor anchor )
- {
+ public HSSFPicture( HSSFShape parent, HSSFAnchor anchor ) {
super( parent, anchor );
super.setShapeType(OBJECT_TYPE_PICTURE);
CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) getObjRecord().getSubRecords().get(0);
cod.setObjectType(CommonObjectDataSubRecord.OBJECT_TYPE_PICTURE);
}
- public int getPictureIndex()
- {
- EscherSimpleProperty property = getOptRecord().lookup(EscherPropertyTypes.BLIP__BLIPTODISPLAY);
- if (null == property){
+ public int getPictureIndex() {
+ EscherOptRecord optRecord = getOptRecord();
+ if (optRecord == null) {
+ return -1;
+ }
+
+ EscherSimpleProperty property = optRecord.lookup(EscherPropertyTypes.BLIP__BLIPTODISPLAY);
+ if (null == property) {
return -1;
}
return property.getPropertyValue();
}
- public void setPictureIndex( int pictureIndex )
- {
+ public void setPictureIndex( int pictureIndex ) {
setPropertyValue(new EscherSimpleProperty( EscherPropertyTypes.BLIP__BLIPTODISPLAY, false, true, pictureIndex));
}
@@ -95,7 +97,7 @@ public class HSSFPicture extends HSSFSimpleShape implements Picture {
* </p>
*/
@Override
- public void resize(){
+ public void resize() {
resize(Double.MAX_VALUE);
}
@@ -152,7 +154,7 @@ public class HSSFPicture extends HSSFSimpleShape implements Picture {
* @since 3.0.2
*/
@Override
- public HSSFClientAnchor getPreferredSize(){
+ public HSSFClientAnchor getPreferredSize() {
return getPreferredSize(1.0);
}
@@ -163,7 +165,7 @@ public class HSSFPicture extends HSSFSimpleShape implements Picture {
* @return HSSFClientAnchor with the preferred size for this image
* @since 3.0.2
*/
- public HSSFClientAnchor getPreferredSize(double scale){
+ public HSSFClientAnchor getPreferredSize(double scale) {
return getPreferredSize(scale, scale);
}
@@ -176,7 +178,7 @@ public class HSSFPicture extends HSSFSimpleShape implements Picture {
* @since 3.11
*/
@Override
- public HSSFClientAnchor getPreferredSize(double scaleX, double scaleY){
+ public HSSFClientAnchor getPreferredSize(double scaleX, double scaleY) {
ImageUtils.setPreferredSize(this, scaleX, scaleY);
return getClientAnchor();
}
@@ -187,7 +189,7 @@ public class HSSFPicture extends HSSFSimpleShape implements Picture {
* @return image dimension in pixels
*/
@Override
- public Dimension getImageDimension(){
+ public Dimension getImageDimension() {
InternalWorkbook iwb = getPatriarch().getSheet().getWorkbook().getWorkbook();
EscherBSERecord bse = iwb.getBSERecord(getPictureIndex());
byte[] data = bse.getBlipRecord().getPicturedata();
@@ -206,7 +208,7 @@ public class HSSFPicture extends HSSFSimpleShape implements Picture {
* @return picture data for this shape or {@code null} if picture wasn't embedded, i.e. external linked
*/
@Override
- public HSSFPictureData getPictureData(){
+ public HSSFPictureData getPictureData() {
int picIdx = getPictureIndex();
if (picIdx == -1) {
return null;
@@ -249,7 +251,7 @@ public class HSSFPicture extends HSSFSimpleShape implements Picture {
: StringUtil.getFromUnicodeLE(propFile.getComplexData()).trim();
}
- public void setFileName(String data){
+ public void setFileName(String data) {
// TODO: add trailing \u0000?
byte[] bytes = StringUtil.getToUnicodeLE(data);
EscherComplexProperty prop = new EscherComplexProperty(EscherPropertyTypes.BLIP__BLIPFILENAME, true, bytes.length);
diff --git a/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFShape.java b/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFShape.java
index d9c98e3063..5946403a96 100644
--- a/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFShape.java
+++ b/poi/src/main/java/org/apache/poi/hssf/usermodel/HSSFShape.java
@@ -115,6 +115,10 @@ public abstract class HSSFShape implements Shape {
*/
void setShapeId(int shapeId){
EscherSpRecord spRecord = _escherContainer.getChildById(EscherSpRecord.RECORD_ID);
+ if (spRecord == null) {
+ throw new IllegalStateException("Did not have an EscherSpRecord, cannot set shape id " + shapeId);
+ }
+
spRecord.setShapeId(shapeId);
CommonObjectDataSubRecord cod = (CommonObjectDataSubRecord) _objRecord.getSubRecords().get(0);
cod.setObjectId((short) (shapeId%1024));
diff --git a/poi/src/main/java/org/apache/poi/sl/draw/DrawTextParagraph.java b/poi/src/main/java/org/apache/poi/sl/draw/DrawTextParagraph.java
index 189f9eabfe..28c43e6a95 100644
--- a/poi/src/main/java/org/apache/poi/sl/draw/DrawTextParagraph.java
+++ b/poi/src/main/java/org/apache/poi/sl/draw/DrawTextParagraph.java
@@ -591,10 +591,10 @@ public class DrawTextParagraph implements Drawable {
final Map<Attribute,Object> att = new HashMap<>();
final List<AttributedStringData> attList = new ArrayList<>();
- for (TextRun run : paragraph){
+ for (TextRun run : paragraph) {
String runText = getRenderableText(graphics, run);
// skip empty runs
- if (runText.isEmpty()) {
+ if (runText == null || runText.isEmpty()) {
continue;
}
diff --git a/poi/src/main/java/org/apache/poi/sl/draw/geom/ArcToCommandIf.java b/poi/src/main/java/org/apache/poi/sl/draw/geom/ArcToCommandIf.java
index 6e5942ea89..17b6d99191 100644
--- a/poi/src/main/java/org/apache/poi/sl/draw/geom/ArcToCommandIf.java
+++ b/poi/src/main/java/org/apache/poi/sl/draw/geom/ArcToCommandIf.java
@@ -60,6 +60,10 @@ public interface ArcToCommandIf extends PathCommand {
double invStart = Math.atan2(rx * Math.sin(radStart), ry * Math.cos(radStart));
Point2D pt = path.getCurrentPoint();
+ if (pt == null) {
+ throw new IllegalStateException("Cannot draw arc without valid point");
+ }
+
// calculate top/left corner
double x0 = pt.getX() - rx * Math.cos(invStart) - rx;
double y0 = pt.getY() - ry * Math.sin(invStart) - ry;
diff --git a/poi/src/main/java/org/apache/poi/ss/extractor/EmbeddedExtractor.java b/poi/src/main/java/org/apache/poi/ss/extractor/EmbeddedExtractor.java
index a59d8368e4..aa895e7fee 100644
--- a/poi/src/main/java/org/apache/poi/ss/extractor/EmbeddedExtractor.java
+++ b/poi/src/main/java/org/apache/poi/ss/extractor/EmbeddedExtractor.java
@@ -260,7 +260,7 @@ public class EmbeddedExtractor implements Iterable<EmbeddedExtractor> {
int pictureBytesLen = idxEnd-idxStart+6;
byte[] pdfBytes = IOUtils.safelyClone(pictureBytes, idxStart, pictureBytesLen, MAX_RECORD_LENGTH);
- String filename = source.getShapeName().trim();
+ String filename = source.getShapeName() == null ? "empty" : source.getShapeName().trim();
if (!endsWithIgnoreCase(filename, ".pdf")) {
filename += ".pdf";
}
diff --git a/poi/src/test/java/org/apache/poi/hssf/model/TestInternalSheet.java b/poi/src/test/java/org/apache/poi/hssf/model/TestInternalSheet.java
new file mode 100644
index 0000000000..db82c1ec7e
--- /dev/null
+++ b/poi/src/test/java/org/apache/poi/hssf/model/TestInternalSheet.java
@@ -0,0 +1,72 @@
+/* ====================================================================
+ 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.hssf.model;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.List;
+
+import org.apache.poi.hssf.record.BOFRecord;
+import org.apache.poi.hssf.record.EOFRecord;
+import org.apache.poi.hssf.record.WindowTwoRecord;
+import org.apache.poi.util.RecordFormatException;
+import org.junit.jupiter.api.Test;
+
+class TestInternalSheet {
+ @Test
+ void testEmptySheet() {
+ InternalSheet sheet = InternalSheet.createSheet();
+ sheet.groupColumnRange(0, 0, true);
+ sheet.groupRowRange(0, 0, true);
+ sheet.setDefaultColumnStyle(0, 0);
+ }
+
+ @Test
+ void testMissingBOFRecord() {
+ assertThrows(RecordFormatException.class,
+ () -> InternalSheet.createSheet(new RecordStream(
+ List.of(new BOFRecord()), 0)));
+ }
+
+
+ @Test
+ void testInvalidBOFRecord() {
+ assertThrows(RecordFormatException.class,
+ () -> InternalSheet.createSheet(new RecordStream(
+ List.of(new BOFRecord()), 0)));
+ }
+
+ @Test
+ void testInvalidBOFRecord2() {
+ assertThrows(RecordFormatException.class,
+ () -> InternalSheet.createSheet(new RecordStream(
+ List.of(BOFRecord.createSheetBOF()), 0)));
+ }
+
+ @Test
+ void testEmptyRecordStream() {
+ InternalSheet sheet = InternalSheet.createSheet(new RecordStream(
+ List.of(BOFRecord.createSheetBOF(),
+ new WindowTwoRecord(),
+ EOFRecord.instance), 0));
+ assertThrows(IllegalStateException.class,
+ () -> sheet.groupColumnRange(0, 0, true));
+ sheet.groupRowRange(0, 0, true);
+ assertThrows(IllegalStateException.class,
+ () -> sheet.setDefaultColumnStyle(0, 0));
+ }
+}
diff --git a/poi/src/test/java/org/apache/poi/hssf/usermodel/TestHSSFComment.java b/poi/src/test/java/org/apache/poi/hssf/usermodel/TestHSSFComment.java
index 5644733467..0420827997 100644
--- a/poi/src/test/java/org/apache/poi/hssf/usermodel/TestHSSFComment.java
+++ b/poi/src/test/java/org/apache/poi/hssf/usermodel/TestHSSFComment.java
@@ -22,10 +22,12 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
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.IOException;
+import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherSpRecord;
import org.apache.poi.hssf.HSSFITestDataProvider;
import org.apache.poi.hssf.HSSFTestDataSamples;
@@ -362,6 +364,7 @@ final class TestHSSFComment extends BaseTestCellComment {
void existingFileWithComment() throws IOException {
try (HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("drawings.xls")) {
HSSFSheet sheet = wb.getSheet("comments");
+ assertNotNull(sheet);
HSSFPatriarch drawing = sheet.getDrawingPatriarch();
assertEquals(1, drawing.getChildren().size());
HSSFComment comment = (HSSFComment) drawing.getChildren().get(0);
@@ -434,4 +437,11 @@ final class TestHSSFComment extends BaseTestCellComment {
assertEquals(2024, comment.getNoteRecord().getShapeId());
}
}
+
+ @Test
+ void getEmptyShape() throws IOException {
+ HSSFComment shape = new HSSFComment(new EscherContainerRecord(), null, null, null);
+ assertThrows(IllegalStateException.class,
+ () -> shape.setShapeId(1));
+ }
}
diff --git a/poi/src/test/java/org/apache/poi/hssf/usermodel/TestHSSFPicture.java b/poi/src/test/java/org/apache/poi/hssf/usermodel/TestHSSFPicture.java
index 3ff14c846e..aa5d42ba2f 100644
--- a/poi/src/test/java/org/apache/poi/hssf/usermodel/TestHSSFPicture.java
+++ b/poi/src/test/java/org/apache/poi/hssf/usermodel/TestHSSFPicture.java
@@ -21,6 +21,7 @@ import static org.apache.poi.hssf.HSSFTestDataSamples.openSampleWorkbook;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
import java.io.IOException;
import java.util.Arrays;
@@ -28,6 +29,10 @@ import java.util.List;
import org.apache.poi.POIDataSamples;
import org.apache.poi.ddf.EscherBSERecord;
+import org.apache.poi.ddf.EscherContainerRecord;
+import org.apache.poi.ddf.EscherOptRecord;
+import org.apache.poi.ddf.EscherPropertyTypes;
+import org.apache.poi.ddf.EscherTextboxRecord;
import org.apache.poi.hssf.HSSFITestDataProvider;
import org.apache.poi.hssf.HSSFTestDataSamples;
import org.apache.poi.hssf.model.InternalSheet;
@@ -285,4 +290,25 @@ final class TestHSSFPicture extends BaseTestPicture {
}
}
+ @Test
+ void testEmptyOptRecord() throws IOException {
+ try (HSSFWorkbook wb = new HSSFWorkbook()) {
+ HSSFSheet sh = wb.createSheet("Pictures");
+ HSSFPatriarch dr = sh.createDrawingPatriarch();
+ HSSFShapeGroup gr = dr.createGroup(new HSSFClientAnchor());
+ HSSFPicture pic = new HSSFPicture(gr, new HSSFClientAnchor()) {
+ @Override
+ protected EscherContainerRecord createSpContainer() {
+ EscherContainerRecord spContainer = super.createSpContainer();
+ EscherOptRecord opt = spContainer.getChildById(EscherOptRecord.RECORD_ID);
+ spContainer.removeChildRecord(opt);
+ spContainer.removeChildRecord(spContainer.getChildById(EscherTextboxRecord.RECORD_ID));
+ return spContainer;
+ }
+ };
+
+ assertNull(pic.getOptRecord());
+ assertEquals(-1, pic.getPictureIndex());
+ }
+ }
}
diff --git a/test-data/spreadsheet/moodle.iamm.fr_pluginfile.php_2971_mod_resource_content_4_evaluation_module_decouverte_qesamed.xls b/test-data/spreadsheet/moodle.iamm.fr_pluginfile.php_2971_mod_resource_content_4_evaluation_module_decouverte_qesamed.xls
new file mode 100644
index 0000000000..747d3370c0
Binary files /dev/null and b/test-data/spreadsheet/moodle.iamm.fr_pluginfile.php_2971_mod_resource_content_4_evaluation_module_decouverte_qesamed.xls differ
diff --git a/test-data/spreadsheet/stress.xls b/test-data/spreadsheet/stress.xls
index 0ff3b117ca..17d8e2afca 100644
Binary files a/test-data/spreadsheet/stress.xls and b/test-data/spreadsheet/stress.xls differ
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org
(poi) 04/06: Prevent invalid height/width in wmf-images exhausting memory
Posted by ce...@apache.org.
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 22531fe63852e124036106d3e5bbe4b03b9e2faf
Author: Dominik Stadler <do...@gmx.at>
AuthorDate: Fri Jan 16 08:55:27 2026 +0100
Prevent invalid height/width in wmf-images exhausting memory
Introduce an adjustable limit of maximum number of pixels
for when drawing the image
---
.../org/apache/poi/hwmf/record/HwmfBitmapDib.java | 27 ++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hwmf/record/HwmfBitmapDib.java b/poi-scratchpad/src/main/java/org/apache/poi/hwmf/record/HwmfBitmapDib.java
index bb2e66bfa2..cfe5804ee3 100644
--- a/poi-scratchpad/src/main/java/org/apache/poi/hwmf/record/HwmfBitmapDib.java
+++ b/poi-scratchpad/src/main/java/org/apache/poi/hwmf/record/HwmfBitmapDib.java
@@ -51,6 +51,9 @@ import org.apache.poi.util.RecordFormatException;
* The DeviceIndependentBitmap Object defines an image in device-independent bitmap (DIB) format.
*/
public class HwmfBitmapDib implements GenericRecord {
+ // arbitrarily selected; may need to increase
+ private static final int DEFAULT_MAX_HEIGHT_WIDTH = 10_000;
+ protected static int MAX_HEIGHT_WIDTH = DEFAULT_MAX_HEIGHT_WIDTH;
private static final Logger LOG = PoiLogManager.getLogger(HwmfBitmapDib.class);
private static final int BMP_HEADER_SIZE = 14;
@@ -532,6 +535,13 @@ public class HwmfBitmapDib implements GenericRecord {
return new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
}
+ if (headerHeight > MAX_HEIGHT_WIDTH || headerWidth > MAX_HEIGHT_WIDTH) {
+ throw new RecordFormatException("The width or height specified in the header exceed the current "
+ + "limit. Height: " + headerHeight + ", width: " + headerWidth +
+ ", Max width/height: " + MAX_HEIGHT_WIDTH +
+ ". Limits can be adjusted via 'HwmfBitmapDib.setMaxHeightWidth'");
+ }
+
BufferedImage bi = new BufferedImage(headerWidth, headerHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bi.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
@@ -559,4 +569,21 @@ public class HwmfBitmapDib implements GenericRecord {
g.dispose();
return bi;
}
+
+ /**
+ * Adjust limit to prevent broken images from exceeding available
+ * memory when being drawn.
+ *
+ * @param length the max number of pixel of width/height to allow for images
+ */
+ public static void setMaxHeightWidth(int length) {
+ MAX_HEIGHT_WIDTH = length;
+ }
+
+ /**
+ * @return the max number of pixel of width/height to allow for images
+ */
+ public static int getMaxHeightWidth() {
+ return MAX_HEIGHT_WIDTH;
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org