use of org.apache.poi.hslf.record.PersistPtrHolder 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.record.PersistPtrHolder in project poi by apache.
the class HSLFSlideShowEncrypted method removeEncryptionRecord.
protected static Record[] removeEncryptionRecord(Record[] records) {
int deaSlideId = -1;
int deaOffset = -1;
PersistPtrHolder ptr = null;
UserEditAtom uea = null;
List<Record> recordList = new ArrayList<Record>();
for (Record r : records) {
if (r instanceof DocumentEncryptionAtom) {
deaOffset = ((DocumentEncryptionAtom) r).getLastOnDiskOffset();
continue;
} else if (r instanceof UserEditAtom) {
uea = (UserEditAtom) r;
deaSlideId = uea.getEncryptSessionPersistIdRef();
uea.setEncryptSessionPersistIdRef(-1);
} else if (r instanceof PersistPtrHolder) {
ptr = (PersistPtrHolder) r;
}
recordList.add(r);
}
if (ptr == null || uea == null) {
throw new EncryptedDocumentException("UserEditAtom or PersistPtrholder not found.");
}
if (deaSlideId == -1 && deaOffset == -1) {
return records;
}
TreeMap<Integer, Integer> tm = new TreeMap<Integer, Integer>(ptr.getSlideLocationsLookup());
ptr.clear();
int maxSlideId = -1;
for (Map.Entry<Integer, Integer> me : tm.entrySet()) {
if (me.getKey() == deaSlideId || me.getValue() == deaOffset) {
continue;
}
ptr.addSlideLookup(me.getKey(), me.getValue());
maxSlideId = Math.max(me.getKey(), maxSlideId);
}
uea.setMaxPersistWritten(maxSlideId);
records = recordList.toArray(new Record[recordList.size()]);
return records;
}
use of org.apache.poi.hslf.record.PersistPtrHolder in project poi by apache.
the class HSLFSlideShowEncrypted method encryptRecord.
protected OutputStream encryptRecord(OutputStream plainStream, int persistId, Record record) {
boolean isPlain = (dea == null || record instanceof UserEditAtom || record instanceof PersistPtrHolder || record instanceof DocumentEncryptionAtom);
try {
if (isPlain) {
if (cyos != null) {
// write cached data to stream
cyos.flush();
}
return plainStream;
}
encryptInit();
if (cyos == null) {
enc.setChunkSize(-1);
cyos = enc.getDataStream(plainStream, 0);
}
cyos.initCipherForBlock(persistId, false);
} catch (Exception e) {
throw new EncryptedPowerPointFileException(e);
}
return cyos;
}
use of org.apache.poi.hslf.record.PersistPtrHolder in project poi by apache.
the class HSLFSlideShowEncrypted method addEncryptionRecord.
protected static Record[] addEncryptionRecord(Record[] records, DocumentEncryptionAtom dea) {
assert (dea != null);
int ueaIdx = -1, ptrIdx = -1, deaIdx = -1, idx = -1;
for (Record r : records) {
idx++;
if (r instanceof UserEditAtom) {
ueaIdx = idx;
} else if (r instanceof PersistPtrHolder) {
ptrIdx = idx;
} else if (r instanceof DocumentEncryptionAtom) {
deaIdx = idx;
}
}
assert (ueaIdx != -1 && ptrIdx != -1 && ptrIdx < ueaIdx);
if (deaIdx != -1) {
DocumentEncryptionAtom deaOld = (DocumentEncryptionAtom) records[deaIdx];
dea.setLastOnDiskOffset(deaOld.getLastOnDiskOffset());
records[deaIdx] = dea;
return records;
} else {
PersistPtrHolder ptr = (PersistPtrHolder) records[ptrIdx];
UserEditAtom uea = ((UserEditAtom) records[ueaIdx]);
dea.setLastOnDiskOffset(ptr.getLastOnDiskOffset() - 1);
int nextSlideId = uea.getMaxPersistWritten() + 1;
ptr.addSlideLookup(nextSlideId, ptr.getLastOnDiskOffset() - 1);
uea.setEncryptSessionPersistIdRef(nextSlideId);
uea.setMaxPersistWritten(nextSlideId);
Record[] newRecords = new Record[records.length + 1];
if (ptrIdx > 0) {
System.arraycopy(records, 0, newRecords, 0, ptrIdx);
}
if (ptrIdx < records.length - 1) {
System.arraycopy(records, ptrIdx, newRecords, ptrIdx + 1, records.length - ptrIdx);
}
newRecords[ptrIdx] = dea;
return newRecords;
}
}
use of org.apache.poi.hslf.record.PersistPtrHolder in project poi by apache.
the class HSLFSlideShowEncrypted method normalizeRecords.
/**
* remove duplicated UserEditAtoms and merge PersistPtrHolder.
* Before this method is called, make sure that the offsets are correct,
* i.e. call {@link HSLFSlideShowImpl#updateAndWriteDependantRecords(OutputStream, Map)}
*/
protected static Record[] normalizeRecords(Record[] records) {
// http://msdn.microsoft.com/en-us/library/office/gg615594(v=office.14).aspx
// repeated slideIds can be overwritten, i.e. ignored
UserEditAtom uea = null;
PersistPtrHolder pph = null;
TreeMap<Integer, Integer> slideLocations = new TreeMap<Integer, Integer>();
TreeMap<Integer, Record> recordMap = new TreeMap<Integer, Record>();
List<Integer> obsoleteOffsets = new ArrayList<Integer>();
int duplicatedCount = 0;
for (Record r : records) {
assert (r instanceof PositionDependentRecord);
PositionDependentRecord pdr = (PositionDependentRecord) r;
if (pdr instanceof UserEditAtom) {
uea = (UserEditAtom) pdr;
continue;
}
if (pdr instanceof PersistPtrHolder) {
if (pph != null) {
duplicatedCount++;
}
pph = (PersistPtrHolder) pdr;
for (Map.Entry<Integer, Integer> me : pph.getSlideLocationsLookup().entrySet()) {
Integer oldOffset = slideLocations.put(me.getKey(), me.getValue());
if (oldOffset != null) {
obsoleteOffsets.add(oldOffset);
}
}
continue;
}
recordMap.put(pdr.getLastOnDiskOffset(), r);
}
if (uea == null || pph == null || uea.getPersistPointersOffset() != pph.getLastOnDiskOffset()) {
throw new EncryptedDocumentException("UserEditAtom and PersistPtrHolder must exist and their offset need to match.");
}
recordMap.put(pph.getLastOnDiskOffset(), pph);
recordMap.put(uea.getLastOnDiskOffset(), uea);
if (duplicatedCount == 0 && obsoleteOffsets.isEmpty()) {
return records;
}
uea.setLastUserEditAtomOffset(0);
pph.clear();
for (Map.Entry<Integer, Integer> me : slideLocations.entrySet()) {
pph.addSlideLookup(me.getKey(), me.getValue());
}
for (Integer oldOffset : obsoleteOffsets) {
recordMap.remove(oldOffset);
}
return recordMap.values().toArray(new Record[recordMap.size()]);
}
Aggregations