From 70db6186880a6aa51e875ca2c43e4b563107b28a Mon Sep 17 00:00:00 2001 From: Tim Allison Date: Thu, 1 Nov 2018 20:31:42 +0000 Subject: [PATCH] bug 62624 -- further cleanup git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1845511 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/poifs/macros/VBAMacroReader.java | 56 +++++++++---------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java b/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java index 8ba36e7a9..8254b86d8 100644 --- a/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java +++ b/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java @@ -70,6 +70,8 @@ import org.apache.poi.util.StringUtil; public class VBAMacroReader implements Closeable { private static final POILogger LOGGER = POILogFactory.getLogger(VBAMacroReader.class); + //arbitrary limit on size of strings to read, etc. + private static final int MAX_STRING_LENGTH = 20000; protected static final String VBA_PROJECT_OOXML = "vbaProject.bin"; protected static final String VBA_PROJECT_POIFS = "VBA"; @@ -352,6 +354,7 @@ public class VBAMacroReader implements Closeable { DocumentNode document = (DocumentNode)entry; try(DocumentInputStream dis = new DocumentInputStream(document)) { readProjectProperties(dis, moduleNameMap, modules); + return; } } else if (entry instanceof DirectoryNode) { findProjectProperties((DirectoryNode)entry, moduleNameMap, modules); @@ -365,6 +368,7 @@ public class VBAMacroReader implements Closeable { DocumentNode document = (DocumentNode)entry; try(DocumentInputStream dis = new DocumentInputStream(document)) { readNameMapRecords(dis, moduleNameMap, modules.charset); + return; } } else if (entry.isDirectoryEntry()) { findModuleNameMap((DirectoryNode)entry, moduleNameMap, modules); @@ -634,47 +638,53 @@ public class VBAMacroReader implements Closeable { return new ASCIIUnicodeStringPair(ascii, unicode); } - private static void readNameMapRecords(InputStream is, + protected void readNameMapRecords(InputStream is, Map moduleNames, Charset charset) throws IOException { //see 2.3.3 PROJECTwm Stream: Module Name Information //multibytecharstring String mbcs = null; String unicode = null; - //arbitrary sanity thresholds + //arbitrary sanity threshold final int maxNameRecords = 10000; - final int maxNameLength = 20000; int records = 0; while (++records < maxNameRecords) { try { - mbcs = readMBCS(is, charset, maxNameLength); + int b = IOUtils.readByte(is); + //check for two 0x00 that mark end of record + if (b == 0) { + b = IOUtils.readByte(is); + if (b == 0) { + return; + } + } + mbcs = readMBCS(b, is, charset, MAX_STRING_LENGTH); } catch (EOFException e) { return; } - if (mbcs == null) { - return; - } + try { - unicode = readUnicode(is, maxNameLength); + unicode = readUnicode(is, MAX_STRING_LENGTH); } catch (EOFException e) { return; } - if (unicode != null) { + if (mbcs.trim().length() > 0 && unicode.trim().length() > 0) { moduleNames.put(mbcs, unicode); } + } if (records >= maxNameRecords) { LOGGER.log(POILogger.WARN, "Hit max name records to read ("+maxNameRecords+"). Stopped early."); } } - private static String readUnicode(InputStream is, int maxNameLength) throws IOException { + private static String readUnicode(InputStream is, int maxLength) throws IOException { //reads null-terminated unicode string ByteArrayOutputStream bos = new ByteArrayOutputStream(); int b0 = IOUtils.readByte(is); int b1 = IOUtils.readByte(is); int read = 2; - while ((b0 + b1) != 0 && read < maxNameLength) { + while ((b0 + b1) != 0 && read < maxLength) { bos.write(b0); bos.write(b1); @@ -682,33 +692,21 @@ public class VBAMacroReader implements Closeable { b1 = IOUtils.readByte(is); read += 2; } - if (read >= maxNameLength) { + if (read >= maxLength) { LOGGER.log(POILogger.WARN, "stopped reading unicode name after "+read+" bytes"); } return new String (bos.toByteArray(), StandardCharsets.UTF_16LE); } - //returns a string if any bytes are read or null if two 0x00 are read - private static String readMBCS(InputStream is, Charset charset, int maxLength) throws IOException { + private static String readMBCS(int firstByte, InputStream is, Charset charset, int maxLength) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); int len = 0; - int b = IOUtils.readByte(is); + int b = firstByte; while (b > 0 && len < maxLength) { ++len; bos.write(b); b = IOUtils.readByte(is); } - //if b was 0 and the above while loop - //was never entered, check for a second 0, - //which would be the sign that you're at the end - //of the list - if (len == 0) { - b = IOUtils.readByte(is); - if (b != 0) { - LOGGER.log(POILogger.WARN, "expected two 0x00 at end of module name map"); - } - return null; - } return new String(bos.toByteArray(), charset); } @@ -722,7 +720,7 @@ public class VBAMacroReader implements Closeable { * @throws IOException If reading from the stream fails */ private static String readString(InputStream stream, int length, Charset charset) throws IOException { - byte[] buffer = IOUtils.safelyAllocate(length, 20000); + byte[] buffer = IOUtils.safelyAllocate(length, MAX_STRING_LENGTH); int bytesRead = IOUtils.readFully(stream, buffer); if (bytesRead != length) { throw new IOException("Tried to read: "+length + @@ -787,10 +785,10 @@ public class VBAMacroReader implements Closeable { } private String readUnicodeString(RLEDecompressingInputStream in, int unicodeNameRecordLength) throws IOException { - byte[] buffer = IOUtils.safelyAllocate(unicodeNameRecordLength, 20000); + byte[] buffer = IOUtils.safelyAllocate(unicodeNameRecordLength, MAX_STRING_LENGTH); int bytesRead = IOUtils.readFully(in, buffer); if (bytesRead != unicodeNameRecordLength) { - + throw new EOFException(); } return new String(buffer, StringUtil.UTF16LE); }