use of org.apache.poi.hslf.exceptions.CorruptPowerPointFileException in project poi by apache.
the class HSLFSlideShowEncrypted method decryptPicture.
protected void decryptPicture(byte[] pictstream, int offset) {
if (dea == null) {
return;
}
decryptInit();
try {
// decrypt header and read length to be decrypted
decryptPicBytes(pictstream, offset, 8);
int recInst = fieldRecInst.getValue(LittleEndian.getUShort(pictstream, offset));
int recType = LittleEndian.getUShort(pictstream, offset + 2);
int rlen = (int) LittleEndian.getUInt(pictstream, offset + 4);
offset += 8;
int endOffset = offset + rlen;
if (recType == 0xF007) {
// File BLIP Store Entry (FBSE)
for (int part : BLIB_STORE_ENTRY_PARTS) {
decryptPicBytes(pictstream, offset, part);
}
offset += 36;
int cbName = LittleEndian.getUShort(pictstream, offset - 3);
if (cbName > 0) {
// read nameData
decryptPicBytes(pictstream, offset, cbName);
offset += cbName;
}
if (offset == endOffset) {
// no embedded blip
return;
}
// fall through, read embedded blip now
// update header data
decryptPicBytes(pictstream, offset, 8);
recInst = fieldRecInst.getValue(LittleEndian.getUShort(pictstream, offset));
recType = LittleEndian.getUShort(pictstream, offset + 2);
// rlen = (int)LittleEndian.getUInt(pictstream, offset+4);
offset += 8;
}
int rgbUidCnt = (recInst == 0x217 || recInst == 0x3D5 || recInst == 0x46B || recInst == 0x543 || recInst == 0x6E1 || recInst == 0x6E3 || recInst == 0x6E5 || recInst == 0x7A9) ? 2 : 1;
// rgbUid 1/2
for (int i = 0; i < rgbUidCnt; i++) {
decryptPicBytes(pictstream, offset, 16);
offset += 16;
}
int nextBytes;
if (recType == 0xF01A || recType == 0XF01B || recType == 0XF01C) {
// metafileHeader
nextBytes = 34;
} else {
// tag
nextBytes = 1;
}
decryptPicBytes(pictstream, offset, nextBytes);
offset += nextBytes;
int blipLen = endOffset - offset;
decryptPicBytes(pictstream, offset, blipLen);
} catch (Exception e) {
throw new CorruptPowerPointFileException(e);
}
}
use of org.apache.poi.hslf.exceptions.CorruptPowerPointFileException in project poi by apache.
the class HSLFSlideShowImpl method initRecordOffsets.
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);
recordMap.put(usrOffset, usr);
int psrOffset = usr.getPersistPointersOffset();
PersistPtrHolder ptr = (PersistPtrHolder) Record.buildRecordAtOffset(docstream, psrOffset);
recordMap.put(psrOffset, ptr);
for (Map.Entry<Integer, Integer> entry : ptr.getSlideLocationsLookup().entrySet()) {
Integer offset = entry.getValue();
Integer id = entry.getKey();
// reserve a slot for the record
recordMap.put(offset, null);
offset2id.put(offset, id);
}
usrOffset = usr.getLastUserEditAtomOffset();
// if the next user edit atom offset is already known, we would go into an endless loop
if (usrOffset > 0 && recordMap.containsKey(usrOffset)) {
// a user edit atom is usually located 36 byte before the smallest known record offset
usrOffset = recordMap.firstKey() - 36;
// check that we really are located on a user edit atom
int ver_inst = LittleEndian.getUShort(docstream, usrOffset);
int type = LittleEndian.getUShort(docstream, usrOffset + 2);
int len = LittleEndian.getInt(docstream, usrOffset + 4);
if (ver_inst == 0 && type == 4085 && (len == 0x1C || len == 0x20)) {
logger.log(POILogger.WARN, "Repairing invalid user edit atom");
usr.setLastUserEditAtomOffset(usrOffset);
} else {
throw new CorruptPowerPointFileException("Powerpoint document contains invalid user edit atom");
}
}
}
}
use of org.apache.poi.hslf.exceptions.CorruptPowerPointFileException in project poi by apache.
the class HSLFSlideShowImpl method addPicture.
/**
* Add a new picture to this presentation.
*
* @return offset of this picture in the Pictures stream
*/
public int addPicture(HSLFPictureData img) {
// Process any existing pictures if we haven't yet
if (_pictures == null) {
try {
readPictures();
} catch (IOException e) {
throw new CorruptPowerPointFileException(e.getMessage());
}
}
// Add the new picture in
int offset = 0;
if (_pictures.size() > 0) {
HSLFPictureData prev = _pictures.get(_pictures.size() - 1);
offset = prev.getOffset() + prev.getRawData().length + 8;
}
img.setOffset(offset);
img.setIndex(_pictures.size() + 1);
_pictures.add(img);
return offset;
}
use of org.apache.poi.hslf.exceptions.CorruptPowerPointFileException in project poi by apache.
the class HSLFSlideShowImpl method readPictures.
/**
* Find and read in pictures contained in this presentation.
* This is lazily called as and when we want to touch pictures.
*/
private void readPictures() throws IOException {
_pictures = new ArrayList<HSLFPictureData>();
// if the presentation doesn't contain pictures - will use a null set instead
if (!getDirectory().hasEntry("Pictures")) {
return;
}
DocumentEntry entry = (DocumentEntry) getDirectory().getEntry("Pictures");
DocumentInputStream is = getDirectory().createDocumentInputStream(entry);
byte[] pictstream = IOUtils.toByteArray(is, entry.getSize());
is.close();
HSLFSlideShowEncrypted decryptData = new HSLFSlideShowEncrypted(getDocumentEncryptionAtom());
try {
int pos = 0;
// An empty picture record (length 0) will take up 8 bytes
while (pos <= (pictstream.length - 8)) {
int offset = pos;
decryptData.decryptPicture(pictstream, offset);
// Image signature
int signature = LittleEndian.getUShort(pictstream, pos);
pos += LittleEndianConsts.SHORT_SIZE;
// Image type + 0xF018
int type = LittleEndian.getUShort(pictstream, pos);
pos += LittleEndianConsts.SHORT_SIZE;
// Image size (excluding the 8 byte header)
int imgsize = LittleEndian.getInt(pictstream, pos);
pos += LittleEndianConsts.INT_SIZE;
// should terminate if the type isn't 0xf007 or 0xf018->0xf117
if (!((type == 0xf007) || (type >= 0xf018 && type <= 0xf117))) {
break;
}
// time, so we won't get stuck)
if (imgsize < 0) {
throw new CorruptPowerPointFileException("The file contains a picture, at position " + _pictures.size() + ", which has a negatively sized data length, so we can't trust any of the picture data");
}
// If they type (including the bonus 0xF018) is 0, skip it
PictureType pt = PictureType.forNativeID(type - 0xF018);
if (pt == null) {
logger.log(POILogger.ERROR, "Problem reading picture: Invalid image type 0, on picture with length " + imgsize + ".\nYou document will probably become corrupted if you save it!");
logger.log(POILogger.ERROR, "" + pos);
} else {
//that are not used in any slide -- BUG-60305
if (pos + imgsize > pictstream.length) {
logger.log(POILogger.WARN, "\"Pictures\" stream may have ended early. In some circumstances, this is not a problem; " + "in others, this could indicate a corrupt file");
break;
}
// Build the PictureData object from the data
try {
HSLFPictureData pict = HSLFPictureData.create(pt);
pict.setSignature(signature);
// Copy the data, ready to pass to PictureData
byte[] imgdata = new byte[imgsize];
System.arraycopy(pictstream, pos, imgdata, 0, imgdata.length);
pict.setRawData(imgdata);
pict.setOffset(offset);
pict.setIndex(_pictures.size());
_pictures.add(pict);
} catch (IllegalArgumentException e) {
logger.log(POILogger.ERROR, "Problem reading picture: " + e + "\nYou document will probably become corrupted if you save it!");
}
}
pos += imgsize;
}
} finally {
decryptData.close();
}
}
Aggregations