Search in sources :

Example 1 with UserEditAtom

use of org.apache.poi.hslf.record.UserEditAtom 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");
            }
        }
    }
}
Also used : PersistPtrHolder(org.apache.poi.hslf.record.PersistPtrHolder) CorruptPowerPointFileException(org.apache.poi.hslf.exceptions.CorruptPowerPointFileException) UserEditAtom(org.apache.poi.hslf.record.UserEditAtom) HashMap(java.util.HashMap) Map(java.util.Map) NavigableMap(java.util.NavigableMap) TreeMap(java.util.TreeMap)

Example 2 with UserEditAtom

use of org.apache.poi.hslf.record.UserEditAtom 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;
}
Also used : EncryptedDocumentException(org.apache.poi.EncryptedDocumentException) PersistPtrHolder(org.apache.poi.hslf.record.PersistPtrHolder) ArrayList(java.util.ArrayList) TreeMap(java.util.TreeMap) DocumentEncryptionAtom(org.apache.poi.hslf.record.DocumentEncryptionAtom) Record(org.apache.poi.hslf.record.Record) PositionDependentRecord(org.apache.poi.hslf.record.PositionDependentRecord) UserEditAtom(org.apache.poi.hslf.record.UserEditAtom) Map(java.util.Map) NavigableMap(java.util.NavigableMap) TreeMap(java.util.TreeMap)

Example 3 with UserEditAtom

use of org.apache.poi.hslf.record.UserEditAtom 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;
}
Also used : DocumentEncryptionAtom(org.apache.poi.hslf.record.DocumentEncryptionAtom) PersistPtrHolder(org.apache.poi.hslf.record.PersistPtrHolder) UserEditAtom(org.apache.poi.hslf.record.UserEditAtom) EncryptedPowerPointFileException(org.apache.poi.hslf.exceptions.EncryptedPowerPointFileException) EncryptedPowerPointFileException(org.apache.poi.hslf.exceptions.EncryptedPowerPointFileException) GeneralSecurityException(java.security.GeneralSecurityException) IOException(java.io.IOException) CorruptPowerPointFileException(org.apache.poi.hslf.exceptions.CorruptPowerPointFileException) EncryptedDocumentException(org.apache.poi.EncryptedDocumentException)

Example 4 with UserEditAtom

use of org.apache.poi.hslf.record.UserEditAtom 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;
    }
}
Also used : DocumentEncryptionAtom(org.apache.poi.hslf.record.DocumentEncryptionAtom) PersistPtrHolder(org.apache.poi.hslf.record.PersistPtrHolder) Record(org.apache.poi.hslf.record.Record) PositionDependentRecord(org.apache.poi.hslf.record.PositionDependentRecord) UserEditAtom(org.apache.poi.hslf.record.UserEditAtom)

Example 5 with UserEditAtom

use of org.apache.poi.hslf.record.UserEditAtom 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()]);
}
Also used : EncryptedDocumentException(org.apache.poi.EncryptedDocumentException) PersistPtrHolder(org.apache.poi.hslf.record.PersistPtrHolder) ArrayList(java.util.ArrayList) TreeMap(java.util.TreeMap) PositionDependentRecord(org.apache.poi.hslf.record.PositionDependentRecord) Record(org.apache.poi.hslf.record.Record) PositionDependentRecord(org.apache.poi.hslf.record.PositionDependentRecord) UserEditAtom(org.apache.poi.hslf.record.UserEditAtom) Map(java.util.Map) NavigableMap(java.util.NavigableMap) TreeMap(java.util.TreeMap)

Aggregations

UserEditAtom (org.apache.poi.hslf.record.UserEditAtom)10 PersistPtrHolder (org.apache.poi.hslf.record.PersistPtrHolder)8 Record (org.apache.poi.hslf.record.Record)8 PositionDependentRecord (org.apache.poi.hslf.record.PositionDependentRecord)5 Map (java.util.Map)4 NavigableMap (java.util.NavigableMap)4 TreeMap (java.util.TreeMap)4 HashMap (java.util.HashMap)3 EncryptedDocumentException (org.apache.poi.EncryptedDocumentException)3 DocumentEncryptionAtom (org.apache.poi.hslf.record.DocumentEncryptionAtom)3 Test (org.junit.Test)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 ArrayList (java.util.ArrayList)2 CorruptPowerPointFileException (org.apache.poi.hslf.exceptions.CorruptPowerPointFileException)2 CurrentUserAtom (org.apache.poi.hslf.record.CurrentUserAtom)2 HSLFSlideShowImpl (org.apache.poi.hslf.usermodel.HSLFSlideShowImpl)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 IOException (java.io.IOException)1 GeneralSecurityException (java.security.GeneralSecurityException)1 EncryptedPowerPointFileException (org.apache.poi.hslf.exceptions.EncryptedPowerPointFileException)1