diff --git a/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java b/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java index 90727c24a..d0aa4660c 100644 --- a/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java +++ b/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java @@ -29,6 +29,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.PushbackInputStream; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; import java.util.zip.ZipEntry; @@ -268,6 +269,7 @@ public class VBAMacroReader implements Closeable { private static final int MODULE_NAME = 0x0019; private static final int MODULE_NAME_UNICODE = 0x0047; private static final int MODULE_DOC_STRING = 0x001c; + private static final int STREAMNAME_RESERVED = 0x0032; /** * Reads VBA Project modules from a VBA Project directory located at @@ -287,6 +289,7 @@ public class VBAMacroReader implements Closeable { // process DIR RLEDecompressingInputStream in = new RLEDecompressingInputStream(dis); String streamName = null; + String streamNameUnicode = null; int recordId = 0; try { while (true) { @@ -306,6 +309,14 @@ public class VBAMacroReader implements Closeable { break; case STREAMNAME: streamName = readString(in, recordLength, modules.charset); + int reserved = in.readShort(); + if (reserved != STREAMNAME_RESERVED) { + throw new IOException("Expected x0032 after stream name before Unicode stream name, but found: "+ + Integer.toHexString(reserved)); + } + int unicodeNameRecordLength = in.readInt(); + streamNameUnicode = readUnicodeString(in, unicodeNameRecordLength); + //do something with this at some point break; case MODULEOFFSET: readModule(in, streamName, modules); @@ -334,4 +345,10 @@ public class VBAMacroReader implements Closeable { } } } + + private String readUnicodeString(RLEDecompressingInputStream in, int unicodeNameRecordLength) throws IOException { + byte[] buffer = new byte[unicodeNameRecordLength]; + IOUtils.readFully(in, buffer); + return new String(buffer, Charset.forName("UTF-16LE")); + } } diff --git a/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java b/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java index 0e634b5c5..f622c5486 100644 --- a/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java +++ b/src/testcases/org/apache/poi/poifs/macros/TestVBAMacroReader.java @@ -244,22 +244,15 @@ public class TestVBAMacroReader { assertContains(content, testMacroNoSub); } - @Ignore + @Test public void bug59830() throws IOException { - // This file is intentionally omitted from the test-data directory - // unless we can extract the vbaProject.bin from this Word 97-2003 file - // so that it's less likely to be opened and executed on a Windows computer. - // The file is attached to bug 59830. - // The Macro Virus only affects Windows computers, as it makes a - // subprocess call to powershell.exe with an encoded payload - // The document contains macros that execute on workbook open if macros - // are enabled - File doc = POIDataSamples.getDocumentInstance().getFile("macro_virus.doc.do_not_open"); - VBAMacroReader reader = new VBAMacroReader(doc); - Map macros = reader.readMacros(); - assertNotNull(macros); - reader.close(); + //test file is "609751.xls" in govdocs1 + File f = POIDataSamples.getSpreadSheetInstance().getFile("59830.xls"); + VBAMacroReader r = new VBAMacroReader(f); + Map macros = r.readMacros(); + assertNotNull(macros.get("Module20")); + assertContains(macros.get("Module20"), "here start of superscripting"); } // This test is written as expected-to-fail and should be rewritten diff --git a/test-data/spreadsheet/59830.xls b/test-data/spreadsheet/59830.xls new file mode 100644 index 000000000..592d9ba69 Binary files /dev/null and b/test-data/spreadsheet/59830.xls differ