From 5958cb4840e28c7f11d471309ce1b5775553b316 Mon Sep 17 00:00:00 2001 From: Tim Allison Date: Wed, 19 Oct 2016 18:44:46 +0000 Subject: [PATCH] BUG-59302 --add minimal support for VBAMacro extraction to HSLF; credit to Andreas Beeker for this patch. Problems are mine. git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1765696 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/poifs/macros/VBAMacroReader.java | 9 +- .../poi/hslf/record/DocInfoListContainer.java | 84 +++++++++++++ .../apache/poi/hslf/record/ExOleObjStg.java | 9 ++ .../apache/poi/hslf/record/RecordTypes.java | 6 +- .../apache/poi/hslf/record/VBAInfoAtom.java | 118 ++++++++++++++++++ .../poi/hslf/record/VBAInfoContainer.java | 87 +++++++++++++ .../apache/poi/hslf/usermodel/TestBugs.java | 58 +++++++++ .../poi/poifs/macros/TestVBAMacroReader.java | 6 +- test-data/slideshow/59302.ppt | Bin 0 -> 87552 bytes 9 files changed, 371 insertions(+), 6 deletions(-) create mode 100644 src/scratchpad/src/org/apache/poi/hslf/record/DocInfoListContainer.java create mode 100644 src/scratchpad/src/org/apache/poi/hslf/record/VBAInfoAtom.java create mode 100644 src/scratchpad/src/org/apache/poi/hslf/record/VBAInfoContainer.java create mode 100644 test-data/slideshow/59302.ppt diff --git a/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java b/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java index dee87e122..83eb7295c 100644 --- a/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java +++ b/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java @@ -46,8 +46,15 @@ import org.apache.poi.util.IOUtils; import org.apache.poi.util.RLEDecompressingInputStream; /** - * Finds all VBA Macros in an office file (OLE2/POIFS and OOXML/OPC), + *

Finds all VBA Macros in an office file (OLE2/POIFS and OOXML/OPC), * and returns them. + *

+ *

+ * NOTE: This does not read macros from .ppt files. + * See org.apache.poi.hslf.usermodel.TestBugs.getMacrosFromHSLF() in the scratchpad + * module for an example of how to do this. Patches that make macro + * extraction from .ppt more elegant are welcomed! + *

* * @since 3.15-beta2 */ diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/DocInfoListContainer.java b/src/scratchpad/src/org/apache/poi/hslf/record/DocInfoListContainer.java new file mode 100644 index 000000000..eed1de23f --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/record/DocInfoListContainer.java @@ -0,0 +1,84 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hslf.record; + +import java.io.IOException; +import java.io.OutputStream; + +import org.apache.poi.util.LittleEndian; + +/** + * A container record that specifies information about the document and document display settings. + */ +public final class DocInfoListContainer extends RecordContainer { + private byte[] _header; + private static long _type = RecordTypes.List.typeID; + + // Links to our more interesting children + + /** + * Set things up, and find our more interesting children + */ + protected DocInfoListContainer(byte[] source, int start, int len) { + // Grab the header + _header = new byte[8]; + System.arraycopy(source,start,_header,0,8); + + // Find our children + _children = Record.findChildRecords(source,start+8,len-8); + findInterestingChildren(); + } + + /** + * Go through our child records, picking out the ones that are + * interesting, and saving those for use by the easy helper + * methods. + */ + private void findInterestingChildren() { + + } + + /** + * Create a new DocInfoListContainer, with blank fields - not yet supported + */ + private DocInfoListContainer() { + _header = new byte[8]; + _children = new Record[0]; + + // Setup our header block + _header[0] = 0x0f; // We are a container record + LittleEndian.putShort(_header, 2, (short)_type); + + // Setup our child records + findInterestingChildren(); + } + + /** + * We are of type 0x7D0 + */ + public long getRecordType() { return _type; } + + /** + * Write the contents of the record back, so it can be written + * to disk + */ + public void writeOut(OutputStream out) throws IOException { + writeOut(_header[0],_header[1],_type,_children,out); + } + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjStg.java b/src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjStg.java index 7a875c5e5..e705d24db 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjStg.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/ExOleObjStg.java @@ -143,6 +143,15 @@ public class ExOleObjStg extends RecordAtom implements PositionDependentRecord, return RecordTypes.ExOleObjStg.typeID; } + /** + * Gets the record instance from the header + * + * @return record instance + */ + public int getRecordInstance() { + return (LittleEndian.getUShort(_header, 0) >>> 4); + } + /** * Write the contents of the record back, so it can be written * to disk. diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java b/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java index c20ca12b2..6e3932606 100644 --- a/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java +++ b/src/scratchpad/src/org/apache/poi/hslf/record/RecordTypes.java @@ -47,8 +47,8 @@ public enum RecordTypes { ViewInfo(1020,null), ViewInfoAtom(1021,null), SlideViewInfoAtom(1022,null), - VBAInfo(1023,null), - VBAInfoAtom(1024,null), + VBAInfo(1023,VBAInfoContainer.class), + VBAInfoAtom(1024,VBAInfoAtom.class), SSDocInfoAtom(1025,null), Summary(1026,null), DocRoutingSlip(1030,null), @@ -63,7 +63,7 @@ public enum RecordTypes { NamedShowSlides(1042,null), SheetProperties(1044,null), RoundTripCustomTableStyles12Atom(1064,null), - List(2000,null), + List(2000,DocInfoListContainer.class), FontCollection(2005,FontCollection.class), BookmarkCollection(2019,null), SoundCollection(2020,SoundCollection.class), diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/VBAInfoAtom.java b/src/scratchpad/src/org/apache/poi/hslf/record/VBAInfoAtom.java new file mode 100644 index 000000000..d847c3853 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/record/VBAInfoAtom.java @@ -0,0 +1,118 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hslf.record; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import org.apache.poi.util.LittleEndian; + +/** + * An atom record that specifies a reference to the VBA project storage. + */ +public final class VBAInfoAtom extends RecordAtom { + private static final long _type = RecordTypes.VBAInfoAtom.typeID; + + /** + * Record header. + */ + private byte[] _header; + + /** + * Record data. + */ + private long persistIdRef; + private boolean hasMacros; + private long version; + + /** + * Constructs an empty atom - not yet supported + */ + private VBAInfoAtom() { + _header = new byte[8]; + // TODO: fix me + LittleEndian.putUInt(_header, 0, _type); + persistIdRef = 0; + hasMacros = true; + version = 2; + } + + /** + * Constructs the vba atom record from its source data. + * + * @param source the source data as a byte array. + * @param start the start offset into the byte array. + * @param len the length of the slice in the byte array. + */ + public VBAInfoAtom(byte[] source, int start, int len) { + // Get the header. + _header = new byte[8]; + System.arraycopy(source,start,_header,0,8); + + // Get the record data. + persistIdRef = LittleEndian.getUInt(source, start+8); + hasMacros = (LittleEndian.getUInt(source, start+12) == 1); + version = LittleEndian.getUInt(source, start+16); + } + /** + * Gets the record type. + * @return the record type. + */ + public long getRecordType() { return _type; } + + /** + * Write the contents of the record back, so it can be written + * to disk + * + * @param out the output stream to write to. + * @throws java.io.IOException if an error occurs. + */ + public void writeOut(OutputStream out) throws IOException { + out.write(_header); + LittleEndian.putUInt(persistIdRef, out); + LittleEndian.putUInt(hasMacros ? 1 : 0, out); + LittleEndian.putUInt(version, out); + } + + public long getPersistIdRef() { + return persistIdRef; + } + + public void setPersistIdRef(long persistIdRef) { + this.persistIdRef = persistIdRef; + } + + public boolean isHasMacros() { + return hasMacros; + } + + public void setHasMacros(boolean hasMacros) { + this.hasMacros = hasMacros; + } + + public long getVersion() { + return version; + } + + public void setVersion(long version) { + this.version = version; + } + + +} diff --git a/src/scratchpad/src/org/apache/poi/hslf/record/VBAInfoContainer.java b/src/scratchpad/src/org/apache/poi/hslf/record/VBAInfoContainer.java new file mode 100644 index 000000000..03577653e --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hslf/record/VBAInfoContainer.java @@ -0,0 +1,87 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hslf.record; + +import java.io.IOException; +import java.io.OutputStream; + +import org.apache.poi.util.LittleEndian; + +/** + * A container record that specifies VBA information for the document. + */ +public final class VBAInfoContainer extends RecordContainer { + private byte[] _header; + private static long _type = RecordTypes.VBAInfo.typeID; + + // Links to our more interesting children + + /** + * Set things up, and find our more interesting children + */ + protected VBAInfoContainer(byte[] source, int start, int len) { + // Grab the header + _header = new byte[8]; + System.arraycopy(source, start, _header, 0, 8); + + // Find our children + _children = Record.findChildRecords(source, start + 8, len - 8); + + findInterestingChildren(); + } + + /** + * Go through our child records, picking out the ones that are + * interesting, and saving those for use by the easy helper + * methods. + */ + private void findInterestingChildren() { + + } + + /** + * Create a new VBAInfoContainer, with blank fields - not yet supported + */ + private VBAInfoContainer() { + _header = new byte[8]; + _children = new Record[0]; + + // Setup our header block + _header[0] = 0x0f; // We are a container record + LittleEndian.putShort(_header, 2, (short) _type); + + // Setup our child records + findInterestingChildren(); + } + + /** + * We are of type 0x3FF + */ + public long getRecordType() { + return _type; + } + + /** + * Write the contents of the record back, so it can be written + * to disk + */ + public void writeOut(OutputStream out) throws IOException { + writeOut(_header[0], _header[1], _type, _children, out); + } + +} diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java index 08ffabc0b..e9a8236f6 100644 --- a/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java +++ b/src/scratchpad/testcases/org/apache/poi/hslf/usermodel/TestBugs.java @@ -17,6 +17,7 @@ package org.apache.poi.hslf.usermodel; +import static org.apache.poi.POITestCase.assertContains; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -30,7 +31,9 @@ import java.awt.geom.Path2D; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.text.AttributedCharacterIterator; @@ -43,6 +46,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.apache.poi.POIDataSamples; import org.apache.poi.ddf.AbstractEscherOptRecord; import org.apache.poi.ddf.EscherArrayProperty; import org.apache.poi.ddf.EscherColorRef; @@ -51,12 +55,18 @@ import org.apache.poi.hslf.HSLFTestDataSamples; import org.apache.poi.hslf.exceptions.OldPowerPointFormatException; import org.apache.poi.hslf.extractor.PowerPointExtractor; import org.apache.poi.hslf.model.HeadersFooters; +import org.apache.poi.hslf.record.DocInfoListContainer; import org.apache.poi.hslf.record.Document; import org.apache.poi.hslf.record.Record; +import org.apache.poi.hslf.record.RecordTypes; import org.apache.poi.hslf.record.SlideListWithText; import org.apache.poi.hslf.record.SlideListWithText.SlideAtomsSet; import org.apache.poi.hslf.record.TextHeaderAtom; +import org.apache.poi.hslf.record.VBAInfoAtom; +import org.apache.poi.hslf.record.VBAInfoContainer; import org.apache.poi.hssf.usermodel.DummyGraphics2d; +import org.apache.poi.poifs.filesystem.NPOIFSFileSystem; +import org.apache.poi.poifs.macros.VBAMacroReader; import org.apache.poi.sl.draw.DrawFactory; import org.apache.poi.sl.draw.DrawPaint; import org.apache.poi.sl.draw.DrawTextParagraph; @@ -72,6 +82,7 @@ import org.apache.poi.sl.usermodel.TextBox; import org.apache.poi.sl.usermodel.TextParagraph; import org.apache.poi.sl.usermodel.TextParagraph.TextAlign; import org.apache.poi.sl.usermodel.TextRun; +import org.apache.poi.util.IOUtils; import org.apache.poi.util.LittleEndian; import org.apache.poi.util.StringUtil; import org.apache.poi.util.Units; @@ -948,4 +959,51 @@ public final class TestBugs { ppt2.close(); } + + @Test + public void bug59302() throws IOException { + //add extraction from PPT + Map macros = getMacrosFromHSLF("59302.ppt"); + assertNotNull("couldn't find macros", macros); + assertNotNull("couldn't find second module", macros.get("Module2")); + assertContains(macros.get("Module2"), "newMacro in Module2"); + + assertNotNull("couldn't find first module", macros.get("Module1")); + assertContains(macros.get("Module1"), "Italicize"); + + macros = getMacrosFromHSLF("SimpleMacro.ppt"); + assertNotNull(macros.get("Module1")); + assertContains(macros.get("Module1"), "This is a macro slideshow"); + } + + //It isn't pretty, but it works... + private Map getMacrosFromHSLF(String fileName) throws IOException { + InputStream is = null; + NPOIFSFileSystem npoifs = null; + try { + is = new FileInputStream(POIDataSamples.getSlideShowInstance().getFile(fileName)); + npoifs = new NPOIFSFileSystem(is); + //TODO: should we run the VBAMacroReader on this npoifs? + //TBD: We know that ppt typically don't store macros in the regular place, + //but _can_ they? + + HSLFSlideShow ppt = new HSLFSlideShow(npoifs); + + //get macro persist id + DocInfoListContainer list = (DocInfoListContainer)ppt.getDocumentRecord().findFirstOfType(RecordTypes.List.typeID); + VBAInfoContainer vbaInfo = (VBAInfoContainer)list.findFirstOfType(RecordTypes.VBAInfo.typeID); + VBAInfoAtom vbaAtom = (VBAInfoAtom)vbaInfo.findFirstOfType(RecordTypes.VBAInfoAtom.typeID); + long persistId = vbaAtom.getPersistIdRef(); + for (HSLFObjectData objData : ppt.getEmbeddedObjects()) { + if (objData.getExOleObjStg().getPersistId() == persistId) { + return new VBAMacroReader(objData.getData()).readMacros(); + } + } + + } finally { + IOUtils.closeQuietly(npoifs); + IOUtils.closeQuietly(is); + } + return null; + } } diff --git a/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java b/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java index df90c8f44..6ac37eacb 100644 --- a/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java +++ b/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java @@ -87,7 +87,8 @@ public class TestVBAMacroReader { public void XSSFfromStream() throws Exception { fromStream(POIDataSamples.getSpreadSheetInstance(), "SimpleMacro.xlsm"); } - @Ignore("bug 59302: Found 0 macros") + @Ignore("bug 59302: Found 0 macros; See org.apache.poi.hslf.usermodel.TestBugs.getMacrosFromHSLF()" + + "for an example of how to get macros out of ppt. TODO: make integration across file formats more elegant") @Test public void HSLFfromStream() throws Exception { fromStream(POIDataSamples.getSlideShowInstance(), "SimpleMacro.ppt"); @@ -123,7 +124,8 @@ public class TestVBAMacroReader { public void XSSFfromFile() throws Exception { fromFile(POIDataSamples.getSpreadSheetInstance(), "SimpleMacro.xlsm"); } - @Ignore("bug 59302: Found 0 macros") + @Ignore("bug 59302: Found 0 macros; See org.apache.poi.hslf.usermodel.TestBugs.getMacrosFromHSLF()" + + "for an example of how to get macros out of ppt. TODO: make integration across file formats more elegant") @Test public void HSLFfromFile() throws Exception { fromFile(POIDataSamples.getSlideShowInstance(), "SimpleMacro.ppt"); diff --git a/test-data/slideshow/59302.ppt b/test-data/slideshow/59302.ppt new file mode 100644 index 0000000000000000000000000000000000000000..bd53fe44d16c3657cb5d7d82d5fb48b0ae78b45a GIT binary patch literal 87552 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 literal 0 HcmV?d00001