mirror of
https://github.com/apache/poi.git
synced 2026-02-27 20:40:08 +08:00
Avoid some NullPointerException and ClassCastExceptions found when fuzzing Apache POI
This mostly only makes thrown runtime-exceptions a bit more consistent and improves information in exceptions. git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1906360 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
22807e03dd
commit
1ff1e84e4a
@ -122,11 +122,13 @@ public class XmlVisioDocument extends POIXMLDocument {
|
||||
* @return pages ordered by page number
|
||||
*/
|
||||
public Collection<XDGFPage> getPages() {
|
||||
if (_pages == null) {
|
||||
throw new IllegalStateException("No page-information available");
|
||||
}
|
||||
return _pages.getPageList();
|
||||
}
|
||||
|
||||
public XDGFStyleSheet getStyleById(long id) {
|
||||
return _document.getStyleById(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -117,7 +117,8 @@ public class ExObjList extends RecordContainer {
|
||||
for (Record child : _children) {
|
||||
if (child instanceof ExHyperlink) {
|
||||
ExHyperlink rec = (ExHyperlink) child;
|
||||
if (rec.getExHyperlinkAtom().getNumber() == id) {
|
||||
if (rec.getExHyperlinkAtom() != null &&
|
||||
rec.getExHyperlinkAtom().getNumber() == id) {
|
||||
return rec;
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,7 +63,11 @@ public final class HSLFShapeFactory {
|
||||
|
||||
public static HSLFGroupShape createShapeGroup(EscherContainerRecord spContainer, ShapeContainer<HSLFShape,HSLFTextParagraph> parent){
|
||||
boolean isTable = false;
|
||||
EscherContainerRecord ecr = (EscherContainerRecord)spContainer.getChild(0);
|
||||
EscherRecord child = spContainer.getChild(0);
|
||||
if (!(child instanceof EscherContainerRecord)) {
|
||||
throw new RecordFormatException("Did not have a EscherContainerRecord: " + child);
|
||||
}
|
||||
EscherContainerRecord ecr = (EscherContainerRecord) child;
|
||||
EscherRecord opt = HSLFShape.getEscherChild(ecr, EscherRecordTypes.USER_DEFINED);
|
||||
|
||||
if (opt != null) {
|
||||
|
||||
@ -172,6 +172,9 @@ public abstract class HSLFSheet implements HSLFShapeContainer, Sheet<HSLFShape,H
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(r instanceof EscherContainerRecord)) {
|
||||
throw new IllegalArgumentException("Did not have a EscherContainerRecord: " + r);
|
||||
}
|
||||
EscherContainerRecord sp = (EscherContainerRecord)r;
|
||||
HSLFShape sh = HSLFShapeFactory.createShape(sp, null);
|
||||
sh.setSheet(this);
|
||||
|
||||
@ -120,11 +120,17 @@ public class HSLFSlideShowEncrypted implements Closeable {
|
||||
recordMap.put(encOffset, r);
|
||||
}
|
||||
|
||||
if (!(r instanceof DocumentEncryptionAtom)) {
|
||||
throw new EncryptedPowerPointFileException("Did not have a DocumentEncryptionAtom: " + r);
|
||||
}
|
||||
this.dea = (DocumentEncryptionAtom)r;
|
||||
|
||||
String pass = Biff8EncryptionKey.getCurrentUserPassword();
|
||||
EncryptionInfo ei = getEncryptionInfo();
|
||||
try {
|
||||
if (ei == null || ei.getDecryptor() == null) {
|
||||
throw new IllegalStateException("Invalid encryption-info: " + ei);
|
||||
}
|
||||
if(!ei.getDecryptor().verifyPassword(pass != null ? pass : Decryptor.DEFAULT_PASSWORD)) {
|
||||
throw new EncryptedPowerPointFileException("PowerPoint file is encrypted. The correct password needs to be set via Biff8EncryptionKey.setCurrentUserPassword()");
|
||||
}
|
||||
|
||||
@ -310,10 +310,11 @@ public final class HSLFSlideShowImpl extends POIDocument implements Closeable {
|
||||
|
||||
private void initRecordOffsets(byte[] docstream, int usrOffset, NavigableMap<Integer, Record> recordMap, Map<Integer, Integer> offset2id) {
|
||||
while (usrOffset != 0) {
|
||||
UserEditAtom usr = (UserEditAtom) Record.buildRecordAtOffset(docstream, usrOffset);
|
||||
if (usr == null) {
|
||||
throw new CorruptPowerPointFileException("Powerpoint document contains no user edit atom");
|
||||
Record builtRecord = Record.buildRecordAtOffset(docstream, usrOffset);
|
||||
if (!(builtRecord instanceof UserEditAtom)) {
|
||||
throw new CorruptPowerPointFileException("Did not have a user edit atom: " + builtRecord);
|
||||
}
|
||||
UserEditAtom usr = (UserEditAtom) builtRecord;
|
||||
|
||||
recordMap.put(usrOffset, usr);
|
||||
|
||||
@ -500,6 +501,9 @@ public final class HSLFSlideShowImpl extends POIDocument implements Closeable {
|
||||
// records share an offset.
|
||||
Map<Integer, List<EscherBSERecord>> unmatchedRecords = new HashMap<>();
|
||||
for (EscherRecord child : blipStore) {
|
||||
if (!(child instanceof EscherBSERecord)) {
|
||||
throw new CorruptPowerPointFileException("Did not have a EscherBSERecord: " + child);
|
||||
}
|
||||
EscherBSERecord record = (EscherBSERecord) child;
|
||||
unmatchedRecords.computeIfAbsent(record.getOffset(), k -> new ArrayList<>()).add(record);
|
||||
}
|
||||
@ -984,7 +988,13 @@ public final class HSLFSlideShowImpl extends POIDocument implements Closeable {
|
||||
private EscherContainerRecord getBlipStore() {
|
||||
Document documentRecord = null;
|
||||
for (Record record : _records) {
|
||||
if (record == null) {
|
||||
throw new CorruptPowerPointFileException("Did not have a valid record: " + record);
|
||||
}
|
||||
if (record.getRecordType() == RecordTypes.Document.typeID) {
|
||||
if (!(record instanceof Document)) {
|
||||
throw new CorruptPowerPointFileException("Did not have a Document: " + record);
|
||||
}
|
||||
documentRecord = (Document) record;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ public final class StyleSheet {
|
||||
/**
|
||||
* General information about a stylesheet
|
||||
*/
|
||||
private Stshif _stshif;
|
||||
private final Stshif _stshif;
|
||||
|
||||
StyleDescription[] _styleDescriptions;
|
||||
|
||||
@ -205,6 +205,10 @@ public final class StyleSheet {
|
||||
@Deprecated
|
||||
private void createPap(int istd) {
|
||||
StyleDescription sd = _styleDescriptions[istd];
|
||||
if (sd == null) {
|
||||
throw new IllegalStateException("Cannot create Pap, empty styleDescription, had : " + _styleDescriptions.length + " descriptions");
|
||||
}
|
||||
|
||||
ParagraphProperties pap = sd.getPAP();
|
||||
byte[] papx = sd.getPAPX();
|
||||
int baseIndex = sd.getBaseStyle();
|
||||
@ -212,7 +216,11 @@ public final class StyleSheet {
|
||||
ParagraphProperties parentPAP = new ParagraphProperties();
|
||||
if (baseIndex != NIL_STYLE) {
|
||||
|
||||
parentPAP = _styleDescriptions[baseIndex].getPAP();
|
||||
StyleDescription styleDescription = _styleDescriptions[baseIndex];
|
||||
if (styleDescription == null) {
|
||||
throw new IllegalStateException("Cannot create Pap, empty styleDescription, had : " + _styleDescriptions.length + " descriptions");
|
||||
}
|
||||
parentPAP = styleDescription.getPAP();
|
||||
if (parentPAP == null) {
|
||||
if (baseIndex == istd) {
|
||||
// Oh dear, style claims that it is its own parent
|
||||
@ -220,7 +228,7 @@ public final class StyleSheet {
|
||||
}
|
||||
// Create the parent style
|
||||
createPap(baseIndex);
|
||||
parentPAP = _styleDescriptions[baseIndex].getPAP();
|
||||
parentPAP = styleDescription.getPAP();
|
||||
}
|
||||
|
||||
}
|
||||
@ -247,6 +255,10 @@ public final class StyleSheet {
|
||||
@Deprecated
|
||||
private void createChp(int istd) {
|
||||
StyleDescription sd = _styleDescriptions[istd];
|
||||
if (sd == null) {
|
||||
throw new IllegalStateException("Cannot create Chp, empty styleDescription, had : " + _styleDescriptions.length + " descriptions");
|
||||
}
|
||||
|
||||
CharacterProperties chp = sd.getCHP();
|
||||
byte[] chpx = sd.getCHPX();
|
||||
int baseIndex = sd.getBaseStyle();
|
||||
@ -263,10 +275,15 @@ public final class StyleSheet {
|
||||
if (chp == null && chpx != null) {
|
||||
CharacterProperties parentCHP = new CharacterProperties();
|
||||
if (baseIndex != NIL_STYLE) {
|
||||
parentCHP = _styleDescriptions[baseIndex].getCHP();
|
||||
StyleDescription styleDescription = _styleDescriptions[baseIndex];
|
||||
if (styleDescription == null) {
|
||||
throw new IllegalStateException("Cannot create Chp, empty styleDescription, had : " + _styleDescriptions.length + " descriptions");
|
||||
}
|
||||
|
||||
parentCHP = styleDescription.getCHP();
|
||||
if (parentCHP == null) {
|
||||
createChp(baseIndex);
|
||||
parentCHP = _styleDescriptions[baseIndex].getCHP();
|
||||
parentCHP = styleDescription.getCHP();
|
||||
}
|
||||
if (parentCHP == null) {
|
||||
parentCHP = new CharacterProperties();
|
||||
|
||||
@ -285,6 +285,9 @@ public final class TableSprmUncompressor extends SprmUncompressor {
|
||||
|
||||
for (int c = itcFirst; c < itcLim; c++) {
|
||||
TableCellDescriptor tableCellDescriptor = newTAP.getRgtc()[c];
|
||||
if (tableCellDescriptor == null) {
|
||||
throw new IllegalStateException("Cannot unCompress TAP, empty table cell descriptor, had : " + newTAP.getRgtc().length + " Rgtc");
|
||||
}
|
||||
|
||||
if ((grfbrc & 0x01) != 0) {
|
||||
tableCellDescriptor.setFtsCellPaddingTop(ftsWidth);
|
||||
|
||||
@ -111,8 +111,13 @@ public final class EscherBSERecord extends EscherRecord {
|
||||
|
||||
int bytesRead = 0;
|
||||
if (bytesRemaining > 0) {
|
||||
EscherRecord record = recordFactory.createRecord(data, pos + 36);
|
||||
if (!(record instanceof EscherBlipRecord)) {
|
||||
throw new IllegalArgumentException("Did not have a EscherBlipRecord: " + record);
|
||||
}
|
||||
|
||||
// Some older escher formats skip this last record
|
||||
field_12_blipRecord = (EscherBlipRecord) recordFactory.createRecord( data, pos + 36 );
|
||||
field_12_blipRecord = (EscherBlipRecord) record;
|
||||
bytesRead = field_12_blipRecord.fillFields( data, pos + 36, recordFactory );
|
||||
}
|
||||
pos += 36 + bytesRead;
|
||||
|
||||
@ -44,6 +44,7 @@ import org.apache.poi.hssf.record.RecordInputStream;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
||||
import org.apache.poi.poifs.filesystem.DocumentNode;
|
||||
import org.apache.poi.poifs.filesystem.Entry;
|
||||
import org.apache.poi.poifs.filesystem.FileMagic;
|
||||
import org.apache.poi.poifs.filesystem.NotOLE2FileException;
|
||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||
@ -149,14 +150,18 @@ public class OldExcelExtractor implements POITextExtractor {
|
||||
private void open(DirectoryNode directory) throws IOException {
|
||||
DocumentNode book;
|
||||
try {
|
||||
book = (DocumentNode)directory.getEntry(OLD_WORKBOOK_DIR_ENTRY_NAME);
|
||||
Entry entry = directory.getEntry(OLD_WORKBOOK_DIR_ENTRY_NAME);
|
||||
if (!(entry instanceof DocumentNode)) {
|
||||
throw new IllegalArgumentException("Did not have an Excel 5/95 Book stream: " + entry);
|
||||
}
|
||||
book = (DocumentNode) entry;
|
||||
} catch (FileNotFoundException | IllegalArgumentException e) {
|
||||
// some files have "Workbook" instead
|
||||
book = (DocumentNode)directory.getEntry(WORKBOOK_DIR_ENTRY_NAMES.get(0));
|
||||
}
|
||||
|
||||
if (book == null) {
|
||||
throw new IOException("No Excel 5/95 Book stream found");
|
||||
Entry entry = directory.getEntry(WORKBOOK_DIR_ENTRY_NAMES.get(0));
|
||||
if (!(entry instanceof DocumentNode)) {
|
||||
throw new IllegalArgumentException("Did not have an Excel 5/95 Book stream: " + entry);
|
||||
}
|
||||
book = (DocumentNode) entry;
|
||||
}
|
||||
|
||||
ris = new RecordInputStream(directory.createDocumentInputStream(book));
|
||||
|
||||
@ -830,7 +830,11 @@ public final class InternalWorkbook {
|
||||
|
||||
xfptr += index;
|
||||
|
||||
return ( ExtendedFormatRecord ) records.get(xfptr);
|
||||
Record record = records.get(xfptr);
|
||||
if (!(record instanceof ExtendedFormatRecord)) {
|
||||
throw new IllegalStateException("Did not have a ExtendedFormatRecord: " + record);
|
||||
}
|
||||
return (ExtendedFormatRecord) record;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -125,7 +125,11 @@ public final class CFRecordsAggregate extends RecordAggregate implements Generic
|
||||
|
||||
CFRuleBase[] rules = new CFRuleBase[nRules];
|
||||
for (int i = 0; i < rules.length; i++) {
|
||||
rules[i] = (CFRuleBase) rs.getNext();
|
||||
Record record = rs.getNext();
|
||||
if (!(record instanceof CFRuleBase)) {
|
||||
throw new IllegalArgumentException("Did not have a CFRuleBase: " + record);
|
||||
}
|
||||
rules[i] = (CFRuleBase) record;
|
||||
}
|
||||
|
||||
return new CFRecordsAggregate(header, rules);
|
||||
|
||||
@ -32,6 +32,7 @@ import org.apache.poi.ddf.EscherContainerRecord;
|
||||
import org.apache.poi.ddf.EscherDgRecord;
|
||||
import org.apache.poi.ddf.EscherOptRecord;
|
||||
import org.apache.poi.ddf.EscherProperty;
|
||||
import org.apache.poi.ddf.EscherRecord;
|
||||
import org.apache.poi.ddf.EscherSpRecord;
|
||||
import org.apache.poi.ddf.EscherSpgrRecord;
|
||||
import org.apache.poi.hssf.model.DrawingManager2;
|
||||
@ -80,9 +81,24 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing<HSSFShap
|
||||
HSSFPatriarch(HSSFSheet sheet, EscherAggregate boundAggregate) {
|
||||
_sheet = sheet;
|
||||
_boundAggregate = boundAggregate;
|
||||
|
||||
if (_boundAggregate == null || _boundAggregate.getEscherContainer() == null) {
|
||||
throw new IllegalArgumentException("Could not read mainSpgrContainer from " + _boundAggregate);
|
||||
}
|
||||
|
||||
_mainSpgrContainer = _boundAggregate.getEscherContainer().getChildContainers().get(0);
|
||||
EscherContainerRecord spContainer = (EscherContainerRecord) _boundAggregate.getEscherContainer()
|
||||
.getChildContainers().get(0).getChild(0);
|
||||
|
||||
if (_mainSpgrContainer == null) {
|
||||
throw new IllegalArgumentException("Could not read mainSpgrContainer from " + _boundAggregate);
|
||||
}
|
||||
|
||||
EscherRecord child = _mainSpgrContainer.getChild(0);
|
||||
|
||||
if (!(child instanceof EscherContainerRecord)) {
|
||||
throw new IllegalArgumentException("Did not have a EscherContainerRecord: " + child);
|
||||
}
|
||||
|
||||
EscherContainerRecord spContainer = (EscherContainerRecord) child;
|
||||
_spgrRecord = spContainer.getChildById(EscherSpgrRecord.RECORD_ID);
|
||||
buildShapeTree();
|
||||
}
|
||||
@ -171,10 +187,10 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing<HSSFShap
|
||||
/**
|
||||
* Creates a simple shape. This includes such shapes as lines, rectangles,
|
||||
* and ovals.
|
||||
*
|
||||
* Note: Microsoft Excel seems to sometimes disallow
|
||||
* higher y1 than y2 or higher x1 than x2 in the anchor, you might need to
|
||||
* reverse them and draw shapes vertically or horizontally flipped!
|
||||
*
|
||||
* Note: Microsoft Excel seems to sometimes disallow
|
||||
* higher y1 than y2 or higher x1 than x2 in the anchor, you might need to
|
||||
* reverse them and draw shapes vertically or horizontally flipped!
|
||||
*
|
||||
* @param anchor the client anchor describes how this group is attached
|
||||
* to the sheet.
|
||||
@ -234,14 +250,14 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing<HSSFShap
|
||||
ftCmo.setReserved2(0);
|
||||
ftCmo.setReserved3(0);
|
||||
obj.addSubRecord(ftCmo);
|
||||
|
||||
// FtCf (pictFormat)
|
||||
|
||||
// FtCf (pictFormat)
|
||||
FtCfSubRecord ftCf = new FtCfSubRecord();
|
||||
HSSFPictureData pictData = getSheet().getWorkbook().getAllPictures().get(pictureIndex-1);
|
||||
switch (pictData.getFormat()) {
|
||||
case Workbook.PICTURE_TYPE_WMF:
|
||||
case Workbook.PICTURE_TYPE_EMF:
|
||||
// this needs patch #49658 to be applied to actually work
|
||||
// this needs patch #49658 to be applied to actually work
|
||||
ftCf.setFlags(FtCfSubRecord.METAFILE_BIT);
|
||||
break;
|
||||
case Workbook.PICTURE_TYPE_DIB:
|
||||
@ -258,12 +274,12 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing<HSSFShap
|
||||
FtPioGrbitSubRecord ftPioGrbit = new FtPioGrbitSubRecord();
|
||||
ftPioGrbit.setFlagByBit(FtPioGrbitSubRecord.AUTO_PICT_BIT, true);
|
||||
obj.addSubRecord(ftPioGrbit);
|
||||
|
||||
|
||||
EmbeddedObjectRefSubRecord ftPictFmla = new EmbeddedObjectRefSubRecord();
|
||||
ftPictFmla.setUnknownFormulaData(new byte[]{2, 0, 0, 0, 0});
|
||||
ftPictFmla.setOleClassname("Paket");
|
||||
ftPictFmla.setStorageId(storageId);
|
||||
|
||||
|
||||
obj.addSubRecord(ftPictFmla);
|
||||
obj.addSubRecord(new EndSubRecord());
|
||||
|
||||
@ -278,22 +294,22 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing<HSSFShap
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new IllegalStateException("trying to add ole shape without actually adding data first - use HSSFWorkbook.addOlePackage first", e);
|
||||
}
|
||||
|
||||
|
||||
// create picture shape, which need to be minimal modified for oleshapes
|
||||
HSSFPicture shape = new HSSFPicture(null, (HSSFClientAnchor)anchor);
|
||||
shape.setPictureIndex(pictureIndex);
|
||||
EscherContainerRecord spContainer = shape.getEscherContainer();
|
||||
EscherSpRecord spRecord = spContainer.getChildById(EscherSpRecord.RECORD_ID);
|
||||
spRecord.setFlags(spRecord.getFlags() | EscherSpRecord.FLAG_OLESHAPE);
|
||||
|
||||
HSSFObjectData oleShape = new HSSFObjectData(spContainer, obj, oleRoot);
|
||||
|
||||
HSSFObjectData oleShape = new HSSFObjectData(spContainer, obj, oleRoot);
|
||||
addShape(oleShape);
|
||||
onCreate(oleShape);
|
||||
|
||||
|
||||
|
||||
|
||||
return oleShape;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a polygon
|
||||
*
|
||||
|
||||
@ -69,12 +69,22 @@ public class HSSFShapeFactory {
|
||||
|
||||
for (EscherRecord record : container) {
|
||||
switch (EscherRecordTypes.forTypeID(record.getRecordId())) {
|
||||
case CLIENT_DATA:
|
||||
objRecord = (ObjRecord) shapeToObj.get(record);
|
||||
case CLIENT_DATA: {
|
||||
Record subRecord = shapeToObj.get(record);
|
||||
if (!(subRecord instanceof ObjRecord)) {
|
||||
throw new RecordFormatException("Did not have a ObjRecord: " + subRecord);
|
||||
}
|
||||
objRecord = (ObjRecord) subRecord;
|
||||
break;
|
||||
case CLIENT_TEXTBOX:
|
||||
txtRecord = (TextObjectRecord) shapeToObj.get(record);
|
||||
}
|
||||
case CLIENT_TEXTBOX: {
|
||||
Record subRecord = shapeToObj.get(record);
|
||||
if (!(subRecord instanceof TextObjectRecord)) {
|
||||
throw new RecordFormatException("Did not have a TextObjRecord: " + subRecord);
|
||||
}
|
||||
txtRecord = (TextObjectRecord) subRecord;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -140,7 +140,13 @@ public final class PropertyTable implements BATManaged {
|
||||
*/
|
||||
public RootProperty getRoot() {
|
||||
// it's always the first element in the List
|
||||
return ( RootProperty ) _properties.get(0);
|
||||
Property property = _properties.get(0);
|
||||
if (property instanceof RootProperty) {
|
||||
return (RootProperty) property;
|
||||
} else {
|
||||
throw new IllegalStateException("Invalid format, cannot convert property " +
|
||||
property + " to RootProperty");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user