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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to