diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index 8b0697483f..9d8ec90dab 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -53,6 +53,7 @@ import org.apache.poi.ddf.EscherBlipRecord; import org.apache.poi.ddf.EscherMetafileBlip; import org.apache.poi.ddf.EscherRecord; import org.apache.poi.hpsf.ClassID; +import org.apache.poi.hpsf.ClassIDPredefined; import org.apache.poi.hpsf.DocumentSummaryInformation; import org.apache.poi.hpsf.SummaryInformation; import org.apache.poi.hssf.OldExcelFormatException; @@ -2007,9 +2008,9 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss protected static Map getOleMap() { Map olemap = new HashMap<>(); - olemap.put("PowerPoint Document", ClassID.PPT_SHOW); + olemap.put("PowerPoint Document", ClassIDPredefined.POWERPOINT_V8.getClassID()); for (String str : WORKBOOK_DIR_ENTRY_NAMES) { - olemap.put(str, ClassID.XLS_WORKBOOK); + olemap.put(str, ClassIDPredefined.EXCEL_V7_WORKBOOK.getClassID()); } // ... to be continued return olemap; @@ -2056,16 +2057,12 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss String storageStr = "MBD"+ HexDump.toHex(++storageId); if (!getDirectory().hasEntry(storageStr)) { oleDir = getDirectory().createDirectory(storageStr); - oleDir.setStorageClsid(ClassID.OLE10_PACKAGE); + oleDir.setStorageClsid(ClassIDPredefined.OLE_V1_PACKAGE.getClassID()); } } while (oleDir == null); - // the following data was taken from an example libre office document - // beside this "\u0001Ole" record there were several other records, e.g. CompObj, - // OlePresXXX, but it seems, that they aren't neccessary - byte oleBytes[] = { 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - oleDir.createDocument("\u0001Ole", new ByteArrayInputStream(oleBytes)); - + Ole10Native.createOleMarkerEntry(oleDir); + Ole10Native oleNative = new Ole10Native(label, fileName, command, oleData); ByteArrayOutputStream bos = new ByteArrayOutputStream(); oleNative.writeOut(bos); diff --git a/src/java/org/apache/poi/poifs/filesystem/Ole10Native.java b/src/java/org/apache/poi/poifs/filesystem/Ole10Native.java index 7c1b9bec16..2e6cfcd55e 100644 --- a/src/java/org/apache/poi/poifs/filesystem/Ole10Native.java +++ b/src/java/org/apache/poi/poifs/filesystem/Ole10Native.java @@ -17,6 +17,7 @@ package org.apache.poi.poifs.filesystem; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -30,8 +31,6 @@ import org.apache.poi.util.StringUtil; /** * Represents an Ole10Native record which is wrapped around certain binary * files being embedded in OLE2 documents. - * - * @author Rainer Schwarze */ public class Ole10Native { @@ -41,6 +40,15 @@ public class Ole10Native { //arbitrarily selected; may need to increase private static final int MAX_RECORD_LENGTH = 100_000_000; + /** + * Default content of the \u0001Ole entry + */ + private static final byte[] OLE_MARKER_BYTES = + { 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + private static final String OLE_MARKER_NAME = "\u0001Ole"; + + + // (the fields as they appear in the raw record:) private int totalSize; // 4 bytes, total size of record not including this field private short flags1 = 2; // 2 bytes, unknown, mostly [02 00] @@ -205,6 +213,27 @@ public class Ole10Native { ofs += dataSize; } + /** + * Add the \1OLE marker entry, which is not the Ole10Native entry. + * Beside this "\u0001Ole" record there were several other records, e.g. CompObj, + * OlePresXXX, but it seems, that they aren't necessary + */ + public static void createOleMarkerEntry(final DirectoryEntry parent) throws IOException { + if (!parent.hasEntry(OLE_MARKER_NAME)) { + parent.createDocument(OLE_MARKER_NAME, new ByteArrayInputStream(OLE_MARKER_BYTES)); + } + } + + /** + * Add the \1OLE marker entry, which is not the Ole10Native entry. + * Beside this "\u0001Ole" record there were several other records, e.g. CompObj, + * OlePresXXX, but it seems, that they aren't necessary + */ + public static void createOleMarkerEntry(final POIFSFileSystem poifs) throws IOException { + createOleMarkerEntry(poifs.getRoot()); + } + + /* * Helper - determine length of zero terminated string (ASCIIZ). */ diff --git a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java index 495c298157..315b09b213 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java +++ b/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java @@ -18,7 +18,6 @@ package org.apache.poi.hslf.usermodel; import java.awt.Dimension; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.File; @@ -38,40 +37,16 @@ import org.apache.poi.ddf.EscherBSERecord; import org.apache.poi.ddf.EscherContainerRecord; import org.apache.poi.ddf.EscherOptRecord; import org.apache.poi.hpsf.ClassID; +import org.apache.poi.hpsf.ClassIDPredefined; import org.apache.poi.hslf.exceptions.CorruptPowerPointFileException; import org.apache.poi.hslf.exceptions.HSLFException; import org.apache.poi.hslf.model.HeadersFooters; import org.apache.poi.hslf.model.MovieShape; -import org.apache.poi.hslf.record.Document; -import org.apache.poi.hslf.record.DocumentAtom; -import org.apache.poi.hslf.record.ExAviMovie; -import org.apache.poi.hslf.record.ExControl; -import org.apache.poi.hslf.record.ExEmbed; -import org.apache.poi.hslf.record.ExEmbedAtom; -import org.apache.poi.hslf.record.ExMCIMovie; -import org.apache.poi.hslf.record.ExObjList; -import org.apache.poi.hslf.record.ExObjListAtom; -import org.apache.poi.hslf.record.ExOleObjAtom; -import org.apache.poi.hslf.record.ExOleObjStg; -import org.apache.poi.hslf.record.ExVideoContainer; -import org.apache.poi.hslf.record.FontCollection; -import org.apache.poi.hslf.record.HeadersFootersContainer; -import org.apache.poi.hslf.record.MainMaster; -import org.apache.poi.hslf.record.Notes; -import org.apache.poi.hslf.record.PersistPtrHolder; -import org.apache.poi.hslf.record.PositionDependentRecord; -import org.apache.poi.hslf.record.PositionDependentRecordContainer; -import org.apache.poi.hslf.record.Record; -import org.apache.poi.hslf.record.RecordContainer; -import org.apache.poi.hslf.record.RecordTypes; -import org.apache.poi.hslf.record.Slide; -import org.apache.poi.hslf.record.SlideListWithText; +import org.apache.poi.hslf.record.*; import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet; -import org.apache.poi.hslf.record.SlidePersistAtom; -import org.apache.poi.hslf.record.TxMasterStyleAtom; -import org.apache.poi.hslf.record.UserEditAtom; import org.apache.poi.poifs.filesystem.DirectoryNode; import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; +import org.apache.poi.poifs.filesystem.Ole10Native; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.sl.usermodel.MasterSheet; import org.apache.poi.sl.usermodel.PictureData.PictureType; @@ -96,12 +71,12 @@ public final class HSLFSlideShow implements SlideShow loadSavePhase = new ThreadLocal<>(); - + // What we're based on private final HSLFSlideShowImpl _hslfSlideShow; @@ -134,7 +109,7 @@ public final class HSLFSlideShow implements SlideShow(); - Integer[] allIDs = mostRecentByBytes.keySet().toArray(new Integer[mostRecentByBytes.size()]); + Integer[] allIDs = mostRecentByBytes.keySet().toArray(new Integer[mostRecentByBytes.size()]); Arrays.sort(allIDs); for (int i = 0; i < allIDs.length; i++) { _sheetIdToCoreRecordsLookup.put(allIDs[i], i); @@ -239,22 +214,22 @@ public final class HSLFSlideShow implements SlideShow me : mostRecentByBytes.entrySet()) { mostRecentByBytesRev.put(me.getValue(), me.getKey()); } - + // Now convert the byte offsets back into record offsets for (Record record : _hslfSlideShow.getRecords()) { if (!(record instanceof PositionDependentRecord)) { continue; } - + PositionDependentRecord pdr = (PositionDependentRecord) record; int recordAt = pdr.getLastOnDiskOffset(); Integer thisID = mostRecentByBytesRev.get(recordAt); - + if (thisID == null) { continue; } - + // Bingo. Now, where do we store it? int storeAt = _sheetIdToCoreRecordsLookup.get(thisID); @@ -342,7 +317,7 @@ public final class HSLFSlideShow implements SlideShow slideIdToNotes = new HashMap<>(); @@ -364,7 +339,7 @@ public final class HSLFSlideShow implements SlideShow slideIdToNotes) { SlideListWithText notesSLWT = _documentRecord.getNotesSlideListWithText(); if (notesSLWT == null) { return; } - + // Match up the records and the SlideAtomSets int idx = -1; for (SlideAtomsSet notesSet : notesSLWT.getSlideAtomsSets()) { @@ -408,13 +383,13 @@ public final class HSLFSlideShow implements SlideShow getSlideMasters() { return _masters; } - + /** * Returns an array of all the normal Title Masters found in the slideshow */ @@ -629,13 +604,13 @@ public final class HSLFSlideShow implements SlideShow lst = new ArrayList<>(); for (SlideAtomsSet s : sas) { lst.add(s.getSlidePersistAtom()); lst.addAll(Arrays.asList(s.getSlideRecords())); } - + Record[] r = lst.toArray(new Record[lst.size()]); slwt.setChildRecord(r); } @@ -667,12 +642,12 @@ public final class HSLFSlideShow implements SlideShow getOleMap() { Map olemap = new HashMap<>(); - olemap.put(POWERPOINT_DOCUMENT, ClassID.PPT_SHOW); - olemap.put("Workbook", ClassID.EXCEL97); // as per BIFF8 spec - olemap.put("WORKBOOK", ClassID.EXCEL97); // Typically from third party programs - olemap.put("BOOK", ClassID.EXCEL97); // Typically odd Crystal Reports exports + olemap.put(POWERPOINT_DOCUMENT, ClassIDPredefined.POWERPOINT_V8.getClassID()); + // as per BIFF8 spec + olemap.put("Workbook", ClassIDPredefined.EXCEL_V8.getClassID()); + // Typically from third party programs + olemap.put("WORKBOOK", ClassIDPredefined.EXCEL_V8.getClassID()); + // Typically odd Crystal Reports exports + olemap.put("BOOK", ClassIDPredefined.EXCEL_V8.getClassID()); // ... to be continued return olemap; } @@ -1117,7 +1087,7 @@ public final class HSLFSlideShow implements SlideShow it = dir.getEntries(); entry = it.next(); assertEquals(true, entry.isDocumentEntry()); - assertEquals("\u0001Ole10Native", entry.getName()); + assertEquals(Ole10Native.OLE10_NATIVE, entry.getName()); entry = it.next(); assertEquals(true, entry.isDocumentEntry());