]> source.dussan.org Git - poi.git/commitdiff
#61941 - Move Ole marker generation to Ole10Native
authorAndreas Beeker <kiwiwings@apache.org>
Sun, 31 Dec 2017 00:22:43 +0000 (00:22 +0000)
committerAndreas Beeker <kiwiwings@apache.org>
Sun, 31 Dec 2017 00:22:43 +0000 (00:22 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1819706 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
src/java/org/apache/poi/poifs/filesystem/Ole10Native.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShow.java
src/testcases/org/apache/poi/poifs/filesystem/TestFileSystemBugs.java

index 8b0697483f607eb4dec0cca54d55b34bc57e56df..9d8ec90dab1d82962f0d8dca63cd879fa8a9c10e 100644 (file)
@@ -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<String,ClassID> getOleMap() {
        Map<String,ClassID> 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);
index 7c1b9bec166a017e133d3d6b9c14dcf19524035c..2e6cfcd55e530d0843be6509173a32d2e7ca5f02 100644 (file)
@@ -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).
      */
index 495c29815751624d380a059cc12016b343fd337b..315b09b2139b485ff8911bd91c3331e8ff009040 100644 (file)
@@ -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<HSLFShape,HSLFTextParagrap
 
        /** Powerpoint document entry/stream name */
     public static final String POWERPOINT_DOCUMENT = "PowerPoint Document";
-    
+
     enum LoadSavePhase {
         INIT, LOADED
        }
     private static final ThreadLocal<LoadSavePhase> loadSavePhase = new ThreadLocal<>();
-    
+
     // What we're based on
        private final HSLFSlideShowImpl _hslfSlideShow;
 
@@ -134,7 +109,7 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
         */
        public HSLFSlideShow(HSLFSlideShowImpl hslfSlideShow) {
            loadSavePhase.set(LoadSavePhase.INIT);
-           
+
            // Get useful things from our base slideshow
            _hslfSlideShow = hslfSlideShow;
 
@@ -150,7 +125,7 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
 
                // Build up the model level Slides and Notes
                buildSlidesAndNotes();
-               
+
                loadSavePhase.set(LoadSavePhase.LOADED);
        }
 
@@ -191,7 +166,7 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
     protected static LoadSavePhase getLoadSavePhase() {
         return loadSavePhase.get();
     }
-    
+
        /**
         * Use the PersistPtrHolder entries to figure out what is the "most recent"
         * version of all the core records (Document, Notes, Slide etc), and save a
@@ -229,7 +204,7 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
                // We'll also want to be able to turn the slide IDs into a position
                // in this array
                _sheetIdToCoreRecordsLookup = new HashMap<>();
-               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<HSLFShape,HSLFTextParagrap
                for (Map.Entry<Integer,Integer> 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<HSLFShape,HSLFTextParagrap
                // SlideAtom/NotesAtom to match them with the StyleAtomSet
 
                findMasterSlides();
-               
+
                // Having sorted out the masters, that leaves the notes and slides
         Map<Integer,Integer> slideIdToNotes = new HashMap<>();
 
@@ -364,7 +339,7 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
         if (masterSLWT == null) {
             return;
         }
-        
+
         for (SlideAtomsSet sas : masterSLWT.getSlideAtomsSets()) {
             Record r = getCoreRecordForSAS(sas);
             int sheetNo = sas.getSlidePersistAtom().getSlideIdentifier();
@@ -379,14 +354,14 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
             }
         }
        }
-       
+
        private void findNotesSlides(Map<Integer,Integer> 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<HSLFShape,HSLFTextParagrap
                 logger.log(POILogger.ERROR, loggerLoc+", but that was actually a " + r);
                 continue;
             }
-            
+
             Notes notesRecord = (Notes) r;
 
             // Record the match between slide id and these notes
             int slideId = spa.getSlideIdentifier();
             slideIdToNotes.put(slideId, idx);
-            
+
             HSLFNotes hn = new HSLFNotes(notesRecord);
             hn.setSlideShow(this);
             _notes.add(hn);
@@ -443,7 +418,7 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
                         + ", but that was actually a " + r);
                 continue;
             }
-            
+
             Slide slide = (Slide)r;
 
             // Do we have a notes for this?
@@ -467,7 +442,7 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
             _slides.add(hs);
         }
        }
-       
+
        @Override
        public void write(OutputStream out) throws IOException {
            // check for text paragraph modifications
@@ -491,10 +466,10 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
                    }
                }
            }
-           
+
                _hslfSlideShow.write(out);
        }
-       
+
        private void writeDirtyParagraphs(HSLFShapeContainer container) {
         for (HSLFShape sh : container.getShapes()) {
             if (sh instanceof HSLFShapeContainer) {
@@ -542,7 +517,7 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
        public List<HSLFSlideMaster> 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<HSLFShape,HSLFTextParagrap
                Collections.swap(_slides, oldSlideNumber - 1, newSlideNumber - 1);
                _slides.get(newSlideNumber - 1).setSlideNumber(newSlideNumber);
                _slides.get(oldSlideNumber - 1).setSlideNumber(oldSlideNumber);
-               
+
                ArrayList<Record> 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<HSLFShape,HSLFTextParagrap
                HSLFSlide removedSlide = _slides.remove(index);
                _notes.remove(removedSlide.getNotes());
                sa.remove(index);
-               
+
                int i=0;
                for (HSLFSlide s : _slides) {
             s.setSlideNumber(i++);
         }
-               
+
                for (SlideAtomsSet s : sa) {
             records.add(s.getSlidePersistAtom());
             records.addAll(Arrays.asList(s.getSlideRecords()));
@@ -774,7 +749,7 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
                int psrId = addPersistentObject(slideRecord);
                sp.setRefID(psrId);
                slideRecord.setSheetId(psrId);
-               
+
                slide.setMasterSheet(_masters.get(0));
                // All done and added
                return slide;
@@ -783,15 +758,15 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
        @Override
        public HSLFPictureData addPicture(byte[] data, PictureType format) throws IOException {
                if (format == null || format.nativeId == -1) {
-                       throw new IllegalArgumentException("Unsupported picture format: " + format); 
+                       throw new IllegalArgumentException("Unsupported picture format: " + format);
                }
-               
+
                HSLFPictureData pd = findPictureData(data);
                if (pd != null) {
                        // identical picture was already added to the SlideShow
                        return pd;
                }
-               
+
                EscherContainerRecord bstore;
 
                EscherContainerRecord dggContainer = _documentRecord.getPPDrawingGroup().getDggContainer();
@@ -880,10 +855,10 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
         }
                return addPicture(data, format);
        }
-       
+
     /**
      * check if a picture with this picture data already exists in this presentation
-     * 
+     *
      * @param pictureData The picture data to find in the SlideShow
      * @return {@code null} if picture data is not found in this slideshow
      * @since 3.15 beta 3
@@ -979,7 +954,7 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
 
                int objectId = addToObjListAtom(mci);
                exVideo.getExMediaAtom().setObjectId(objectId);
-               
+
                return objectId;
        }
 
@@ -998,12 +973,12 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
                ctrl.setProgId(progId);
                ctrl.setMenuName(name);
                ctrl.setClipboardName(name);
-               
+
                ExOleObjAtom oleObj = ctrl.getExOleObjAtom();
                oleObj.setDrawAspect(ExOleObjAtom.DRAW_ASPECT_VISIBLE);
                oleObj.setType(ExOleObjAtom.TYPE_CONTROL);
                oleObj.setSubType(ExOleObjAtom.SUBTYPE_DEFAULT);
-               
+
                int objectId = addToObjListAtom(ctrl);
                oleObj.setObjID(objectId);
                return objectId;
@@ -1016,7 +991,7 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
         */
        public int addEmbed(POIFSFileSystem poiData) {
         DirectoryNode root = poiData.getRoot();
-        
+
         // prepare embedded data
         if (new ClassID().equals(root.getStorageClsid())) {
                // need to set class id
@@ -1029,12 +1004,12 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
                        }
                }
                if (classID == null) {
-                       throw new IllegalArgumentException("Unsupported embedded document");                    
+                       throw new IllegalArgumentException("Unsupported embedded document");
                }
-               
+
                root.setStorageClsid(classID);
         }
-        
+
                ExEmbed exEmbed = new ExEmbed();
         // remove unneccessary infos, so we don't need to specify the type
         // of the ole object multiple times
@@ -1055,26 +1030,18 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
 
         ExOleObjStg exOleObjStg = new ExOleObjStg();
         try {
-               final String OLESTREAM_NAME = "\u0001Ole";
-               if (!root.hasEntry(OLESTREAM_NAME)) {
-                   // 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 };
-                   poiData.createDocument(new ByteArrayInputStream(oleBytes), OLESTREAM_NAME);
-               }        
-
+            Ole10Native.createOleMarkerEntry(poiData);
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                poiData.writeFilesystem(bos);
                exOleObjStg.setData(bos.toByteArray());
         } catch (IOException e) {
                throw new HSLFException(e);
         }
-        
+
         int psrId = addPersistentObject(exOleObjStg);
         exOleObjStg.setPersistId(psrId);
         eeAtom.setObjStgDataRef(psrId);
-        
+
                int objectId = addToObjListAtom(exEmbed);
                eeAtom.setObjID(objectId);
                return objectId;
@@ -1088,16 +1055,19 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
                objAtom.setObjectIDSeed(objectId);
 
                lst.addChildAfter(exObj, objAtom);
-               
+
                return objectId;
        }
 
     protected static Map<String,ClassID> getOleMap() {
        Map<String,ClassID> 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<HSLFShape,HSLFTextParagrap
         } catch (IOException e) {
             throw new HSLFException(e);
         }
-               
+
                PersistPtrHolder ptr = (PersistPtrHolder)interestingRecords.get(RecordTypes.PersistPtrIncrementalBlock);
                UserEditAtom usr = (UserEditAtom)interestingRecords.get(RecordTypes.UserEditAtom);
 
@@ -1158,7 +1128,7 @@ public final class HSLFSlideShow implements SlideShow<HSLFShape,HSLFTextParagrap
     public HSLFSlideShowImpl getSlideShowImpl() {
         return _hslfSlideShow;
     }
-    
+
     @Override
     public void close() throws IOException {
         _hslfSlideShow.close();
index 6b859d9380189abebe75801e082a82097b4031d4..ebf7fb1d09abe96d66ed008baf8a12459c5106c4 100644 (file)
@@ -104,7 +104,7 @@ public final class TestFileSystemBugs extends TestCase {
             Iterator<Entry> 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());