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]
