BUG 59830 -- incorrect reading of unicode stream name

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1765468 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Tim Allison 2016-10-18 15:47:38 +00:00
parent db79501e9f
commit c878e39b55
3 changed files with 24 additions and 14 deletions

View File

@ -29,6 +29,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.PushbackInputStream; import java.io.PushbackInputStream;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.zip.ZipEntry; 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 = 0x0019;
private static final int MODULE_NAME_UNICODE = 0x0047; private static final int MODULE_NAME_UNICODE = 0x0047;
private static final int MODULE_DOC_STRING = 0x001c; 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 * Reads VBA Project modules from a VBA Project directory located at
@ -287,6 +289,7 @@ public class VBAMacroReader implements Closeable {
// process DIR // process DIR
RLEDecompressingInputStream in = new RLEDecompressingInputStream(dis); RLEDecompressingInputStream in = new RLEDecompressingInputStream(dis);
String streamName = null; String streamName = null;
String streamNameUnicode = null;
int recordId = 0; int recordId = 0;
try { try {
while (true) { while (true) {
@ -306,6 +309,14 @@ public class VBAMacroReader implements Closeable {
break; break;
case STREAMNAME: case STREAMNAME:
streamName = readString(in, recordLength, modules.charset); 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; break;
case MODULEOFFSET: case MODULEOFFSET:
readModule(in, streamName, modules); 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"));
}
} }

View File

@ -244,22 +244,15 @@ public class TestVBAMacroReader {
assertContains(content, testMacroNoSub); assertContains(content, testMacroNoSub);
} }
@Ignore
@Test @Test
public void bug59830() throws IOException { public void bug59830() throws IOException {
// This file is intentionally omitted from the test-data directory //test file is "609751.xls" in govdocs1
// unless we can extract the vbaProject.bin from this Word 97-2003 file File f = POIDataSamples.getSpreadSheetInstance().getFile("59830.xls");
// so that it's less likely to be opened and executed on a Windows computer. VBAMacroReader r = new VBAMacroReader(f);
// The file is attached to bug 59830. Map<String, String> macros = r.readMacros();
// The Macro Virus only affects Windows computers, as it makes a assertNotNull(macros.get("Module20"));
// subprocess call to powershell.exe with an encoded payload assertContains(macros.get("Module20"), "here start of superscripting");
// 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<String, String> macros = reader.readMacros();
assertNotNull(macros);
reader.close();
} }
// This test is written as expected-to-fail and should be rewritten // This test is written as expected-to-fail and should be rewritten

Binary file not shown.