diff --git a/src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java b/src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java index 61629d5c4..bee33a250 100644 --- a/src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java +++ b/src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java @@ -279,14 +279,19 @@ public class AddDimensionedImage { // The first two parameters are not used currently but could be if the // need arose to extend the functionality of this code by adding the // ability to specify that a clear 'border' be placed around the image. - anchor = new HSSFClientAnchor(0, - 0, - colClientAnchorDetail.getInset(), - rowClientAnchorDetail.getInset(), - (short)colClientAnchorDetail.getFromIndex(), - rowClientAnchorDetail.getFromIndex(), - (short)colClientAnchorDetail.getToIndex(), - rowClientAnchorDetail.getToIndex()); + int dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0; + short col1 = 0, col2 = 0, row1 = 0, row2 = 0; + if (colClientAnchorDetail != null) { + dx2 = colClientAnchorDetail.getInset(); + col1 = (short)colClientAnchorDetail.getFromIndex(); + col2 = (short)colClientAnchorDetail.getToIndex(); + } + if (rowClientAnchorDetail != null) { + dy2 = rowClientAnchorDetail.getInset(); + row1 = (short)rowClientAnchorDetail.getFromIndex(); + row2 = (short)rowClientAnchorDetail.getToIndex(); + } + anchor = new HSSFClientAnchor(dx1, dy1, dx2, dy2, col1, row1, col2, row2); // For now, set the anchor type to do not move or resize the // image as the size of the row/column is adjusted. This could easilly diff --git a/src/java/org/apache/poi/common/usermodel/fonts/FontGroup.java b/src/java/org/apache/poi/common/usermodel/fonts/FontGroup.java index 191b4e004..c8a1a1cc0 100644 --- a/src/java/org/apache/poi/common/usermodel/fonts/FontGroup.java +++ b/src/java/org/apache/poi/common/usermodel/fonts/FontGroup.java @@ -110,8 +110,11 @@ public enum FontGroup { * @param runText the text which font groups are to be analyzed * @return the FontGroup */ - public static List getFontGroupRanges(String runText) { + public static List getFontGroupRanges(final String runText) { List ttrList = new ArrayList<>(); + if (runText == null || runText.isEmpty()) { + return ttrList; + } FontGroupRange ttrLast = null; final int rlen = (runText != null) ? runText.length() : 0; for(int cp, i = 0, charCount; i < rlen; i += charCount) { diff --git a/src/java/org/apache/poi/hssf/model/InternalSheet.java b/src/java/org/apache/poi/hssf/model/InternalSheet.java index 83e1d3790..4e8798e88 100644 --- a/src/java/org/apache/poi/hssf/model/InternalSheet.java +++ b/src/java/org/apache/poi/hssf/model/InternalSheet.java @@ -1377,7 +1377,9 @@ public final class InternalSheet { windowTwo.setFreezePanes(false); windowTwo.setFreezePanesNoSplit(false); SelectionRecord sel = (SelectionRecord) findFirstRecordBySid(SelectionRecord.sid); - sel.setPane(PaneInformation.PANE_UPPER_LEFT); + if (sel != null) { + sel.setPane(PaneInformation.PANE_UPPER_LEFT); + } return; } @@ -1402,8 +1404,9 @@ public final class InternalSheet { windowTwo.setFreezePanesNoSplit(true); SelectionRecord sel = (SelectionRecord) findFirstRecordBySid(SelectionRecord.sid); - sel.setPane((byte)pane.getActivePane()); - + if (sel != null) { + sel.setPane((byte) pane.getActivePane()); + } } /** @@ -1437,7 +1440,9 @@ public final class InternalSheet { windowTwo.setFreezePanesNoSplit(false); SelectionRecord sel = (SelectionRecord) findFirstRecordBySid(SelectionRecord.sid); - sel.setPane(PANE_LOWER_RIGHT); + if (sel != null) { + sel.setPane(PANE_LOWER_RIGHT); + } } diff --git a/src/java/org/apache/poi/hssf/usermodel/EscherGraphics2d.java b/src/java/org/apache/poi/hssf/usermodel/EscherGraphics2d.java index af3eb3463..5235a7022 100644 --- a/src/java/org/apache/poi/hssf/usermodel/EscherGraphics2d.java +++ b/src/java/org/apache/poi/hssf/usermodel/EscherGraphics2d.java @@ -379,7 +379,8 @@ public final class EscherGraphics2d extends Graphics2D { public Rectangle getClipBounds() { if(getDeviceclip() != null) { - return getClip().getBounds(); + final Shape clip = getClip(); + return clip != null ? clip.getBounds() : null; } return null; } diff --git a/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java b/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java index 62835109e..844b5d226 100644 --- a/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java +++ b/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java @@ -218,9 +218,13 @@ public abstract class ChunkedCipherOutputStream extends FilterOutputStream { int ciLen = (doFinal) ? cipher.doFinal(chunk, 0, posInChunk, chunk) : cipher.update(chunk, 0, posInChunk, chunk); - - for (int i = plainByteFlags.nextSetBit(0); i >= 0 && i < posInChunk; i = plainByteFlags.nextSetBit(i+1)) { - chunk[i] = plain[i]; + + if (plain != null) { + int i = plainByteFlags.nextSetBit(0); + while (i >= 0 && i < posInChunk) { + chunk[i] = plain[i]; + i = plainByteFlags.nextSetBit(i+1); + } } return ciLen; diff --git a/src/java/org/apache/poi/poifs/crypt/xor/XOREncryptor.java b/src/java/org/apache/poi/poifs/crypt/xor/XOREncryptor.java index c090fe361..61f06f263 100644 --- a/src/java/org/apache/poi/poifs/crypt/xor/XOREncryptor.java +++ b/src/java/org/apache/poi/poifs/crypt/xor/XOREncryptor.java @@ -164,8 +164,12 @@ public class XOREncryptor extends Encryptor implements Cloneable { chunk[i] = value; } - for (int i = plainBytes.nextSetBit(start); i >= 0 && i < posInChunk; i = plainBytes.nextSetBit(i+1)) { - chunk[i] = plain[i]; + if (plain != null) { + int i = plainBytes.nextSetBit(start); + while (i >= 0 && i < posInChunk) { + chunk[i] = plain[i]; + i = plainBytes.nextSetBit(i + 1); + } } return posInChunk; diff --git a/src/java/org/apache/poi/poifs/filesystem/ODocumentInputStream.java b/src/java/org/apache/poi/poifs/filesystem/ODocumentInputStream.java index 97225805a..944e3f322 100644 --- a/src/java/org/apache/poi/poifs/filesystem/ODocumentInputStream.java +++ b/src/java/org/apache/poi/poifs/filesystem/ODocumentInputStream.java @@ -18,6 +18,7 @@ package org.apache.poi.poifs.filesystem; import java.io.IOException; +import java.util.function.Function; import org.apache.poi.poifs.storage.DataInputBlock; import org.apache.poi.util.RecordFormatException; @@ -214,40 +215,57 @@ public final class ODocumentInputStream extends DocumentInputStream { @Override public void readFully(byte[] buf, int off, int len) { checkAvaliable(len); - int blockAvailable = _currentBlock.available(); + + Function nextDataInputBlock = (offset) -> { + if (offset >= _document_size) { + _currentBlock = null; + } else if (offset != _current_offset) { + _currentBlock = getDataInputBlock(offset); + } + return _currentBlock; + }; + + _current_offset = readFullyInternal(buf, off, len, _current_offset, _document_size, nextDataInputBlock); + } + + /* package */ static int readFullyInternal(byte[] buf, int off, int len, int currentOffset, int maxSize, Function nextDataInputBlock) { + DataInputBlock currentBlock = nextDataInputBlock.apply(currentOffset); + if (currentBlock == null) { + throw new IllegalStateException("reached end of document stream unexpectedly"); + } + int blockAvailable = currentBlock.available(); if (blockAvailable > len) { - _currentBlock.readFully(buf, off, len); - _current_offset += len; - return; + currentBlock.readFully(buf, off, len); + return currentOffset + len; } // else read big amount in chunks int remaining = len; int writePos = off; + int offset = currentOffset; while (remaining > 0) { - boolean blockIsExpiring = remaining >= blockAvailable; - int reqSize; - if (blockIsExpiring) { - reqSize = blockAvailable; - } else { - reqSize = remaining; - } - _currentBlock.readFully(buf, writePos, reqSize); + final boolean blockIsExpiring = remaining >= blockAvailable; + final int reqSize = (blockIsExpiring) ? blockAvailable : remaining; + currentBlock.readFully(buf, writePos, reqSize); remaining -= reqSize; writePos += reqSize; - _current_offset += reqSize; + offset += reqSize; if (blockIsExpiring) { - if (_current_offset == _document_size) { + if (offset >= maxSize) { if (remaining > 0) { throw new IllegalStateException( "reached end of document stream unexpectedly"); } - _currentBlock = null; break; } - _currentBlock = getDataInputBlock(_current_offset); - blockAvailable = _currentBlock.available(); + currentBlock = nextDataInputBlock.apply(offset); + if (currentBlock == null) { + throw new IllegalStateException( + "reached end of document stream unexpectedly"); + } + blockAvailable = currentBlock.available(); } } + return offset; } @Override diff --git a/src/java/org/apache/poi/poifs/filesystem/OPOIFSDocument.java b/src/java/org/apache/poi/poifs/filesystem/OPOIFSDocument.java index bffc74454..43820ab53 100644 --- a/src/java/org/apache/poi/poifs/filesystem/OPOIFSDocument.java +++ b/src/java/org/apache/poi/poifs/filesystem/OPOIFSDocument.java @@ -25,6 +25,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.function.Function; import org.apache.poi.poifs.common.POIFSBigBlockSize; import org.apache.poi.poifs.common.POIFSConstants; @@ -228,43 +229,7 @@ public final class OPOIFSDocument implements BATManaged, BlockWritable, POIFSVie * This method is currently (Oct 2008) only used by test code. Perhaps it can be deleted */ void read(byte[] buffer, int offset) { - int len = buffer.length; - - DataInputBlock currentBlock = getDataInputBlock(offset); - - int blockAvailable = currentBlock.available(); - if (blockAvailable > len) { - currentBlock.readFully(buffer, 0, len); - return; - } - // else read big amount in chunks - int remaining = len; - int writePos = 0; - int currentOffset = offset; - while (remaining > 0) { - boolean blockIsExpiring = remaining >= blockAvailable; - int reqSize; - if (blockIsExpiring) { - reqSize = blockAvailable; - } else { - reqSize = remaining; - } - currentBlock.readFully(buffer, writePos, reqSize); - remaining-=reqSize; - writePos+=reqSize; - currentOffset += reqSize; - if (blockIsExpiring) { - if (currentOffset == _size) { - if (remaining > 0) { - throw new IllegalStateException("reached end of document stream unexpectedly"); - } - currentBlock = null; - break; - } - currentBlock = getDataInputBlock(currentOffset); - blockAvailable = currentBlock.available(); - } - } + ODocumentInputStream.readFullyInternal(buffer, 0, buffer.length, offset, _size, this::getDataInputBlock); } /** diff --git a/src/scratchpad/src/org/apache/poi/hpbf/model/HPBFPart.java b/src/scratchpad/src/org/apache/poi/hpbf/model/HPBFPart.java index 2cbc6bcd0..49e2ac43a 100644 --- a/src/scratchpad/src/org/apache/poi/hpbf/model/HPBFPart.java +++ b/src/scratchpad/src/org/apache/poi/hpbf/model/HPBFPart.java @@ -64,6 +64,9 @@ public abstract class HPBFPart { public void writeOut(DirectoryNode baseDir) throws IOException { String[] path = getPath(); + if (path == null) { + return; + } // Ensure that all parent directories exist DirectoryNode dir = baseDir; diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java index 63f30bd45..0b2d322b6 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java @@ -301,44 +301,46 @@ public final class HSLFFreeformShape extends HSLFAutoShape implements FreeformSh while (vertIter.hasNext() && segIter.hasNext()) { byte[] segElem = segIter.next(); PathInfo pi = getPathInfo(segElem); - switch (pi) { - case escape: { - // handleEscapeInfo(path, segElem, vertIter); - break; - } - case moveTo: { - fillPoint(vertIter.next(), xyPoints); - double x = xyPoints[0]; - double y = xyPoints[1]; - path.moveTo(x,y); - break; - } - case curveTo: { - fillPoint(vertIter.next(), xyPoints); - double x1 = xyPoints[0]; - double y1 = xyPoints[1]; - fillPoint(vertIter.next(), xyPoints); - double x2 = xyPoints[0]; - double y2 = xyPoints[1]; - fillPoint(vertIter.next(), xyPoints); - double x3 = xyPoints[0]; - double y3 = xyPoints[1]; - path.curveTo(x1,y1,x2,y2,x3,y3); - break; - } - case lineTo: - if (vertIter.hasNext()) { + if (pi != null) { + switch (pi) { + case escape: { + // handleEscapeInfo(path, segElem, vertIter); + break; + } + case moveTo: { fillPoint(vertIter.next(), xyPoints); double x = xyPoints[0]; double y = xyPoints[1]; - path.lineTo(x,y); + path.moveTo(x, y); + break; } - break; - case close: - path.closePath(); - break; - default: - break; + case curveTo: { + fillPoint(vertIter.next(), xyPoints); + double x1 = xyPoints[0]; + double y1 = xyPoints[1]; + fillPoint(vertIter.next(), xyPoints); + double x2 = xyPoints[0]; + double y2 = xyPoints[1]; + fillPoint(vertIter.next(), xyPoints); + double x3 = xyPoints[0]; + double y3 = xyPoints[1]; + path.curveTo(x1, y1, x2, y2, x3, y3); + break; + } + case lineTo: + if (vertIter.hasNext()) { + fillPoint(vertIter.next(), xyPoints); + double x = xyPoints[0]; + double y = xyPoints[1]; + path.lineTo(x, y); + } + break; + case close: + path.closePath(); + break; + default: + break; + } } } diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFObjectShape.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFObjectShape.java index ffe2c51b0..8845df677 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFObjectShape.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFObjectShape.java @@ -212,7 +212,10 @@ public final class HSLFObjectShape extends HSLFPictureShape implements ObjectSha } public void setFullName(final String fullName) { - getExEmbed(true).setClipboardName(fullName); + final ExEmbed ex = getExEmbed(true); + if (ex != null) { + ex.setClipboardName(fullName); + } } @Override @@ -222,7 +225,10 @@ public final class HSLFObjectShape extends HSLFPictureShape implements ObjectSha } public void setProgId(final String progId) { - getExEmbed(true).setProgId(progId); + final ExEmbed ex = getExEmbed(true); + if (ex != null) { + ex.setProgId(progId); + } } public OutputStream updateObjectData(final Application application, final ObjectMetaData metaData) throws IOException { @@ -246,16 +252,18 @@ public final class HSLFObjectShape extends HSLFPictureShape implements ObjectSha poifs.getRoot().setStorageClsid(md.getClassID()); - int oid = getObjectID(); if (oid == 0) { // assign new embedding oid = ppt.addEmbed(poifs); setObjectID(oid); } else { - ByteArrayOutputStream bos = new ByteArrayOutputStream(this.size()+1000); - poifs.writeFilesystem(bos); - getObjectData().setData(bos.toByteArray()); + final HSLFObjectData od = getObjectData(); + if (od != null) { + ByteArrayOutputStream bos = new ByteArrayOutputStream(this.size()+1000); + poifs.writeFilesystem(bos); + od.setData(bos.toByteArray()); + } } setProgId(md.getProgId()); diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/HeaderStories.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/HeaderStories.java index 16ae1c40d..b15757ae0 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/HeaderStories.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/HeaderStories.java @@ -208,15 +208,17 @@ public final class HeaderStories { // First page header is optional, only return // if it's set if(pageNumber == 1) { - if(getFirstHeader().length() > 0) { - return getFirstHeader(); + final String fh = getFirstHeader(); + if(fh != null && !fh.isEmpty()) { + return fh; } } // Even page header is optional, only return // if it's set if(pageNumber % 2 == 0) { - if(getEvenHeader().length() > 0) { - return getEvenHeader(); + final String eh = getEvenHeader(); + if(eh != null && !eh.isEmpty()) { + return eh; } } // Odd is the default @@ -274,15 +276,17 @@ public final class HeaderStories { // First page footer is optional, only return // if it's set if(pageNumber == 1) { - if(getFirstFooter().length() > 0) { - return getFirstFooter(); + final String ff = getFirstFooter(); + if(ff != null && !ff.isEmpty()) { + return ff; } } // Even page footer is optional, only return // if it's set if(pageNumber % 2 == 0) { - if(getEvenFooter().length() > 0) { - return getEvenFooter(); + final String ef = getEvenFooter(); + if(ef != null && !ef.isEmpty()) { + return ef; } } // Odd is the default