bug 62624 -- further cleanup

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1845511 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Tim Allison 2018-11-01 20:31:42 +00:00
parent 40a5e940c1
commit 70db618688

View File

@ -70,6 +70,8 @@ import org.apache.poi.util.StringUtil;
public class VBAMacroReader implements Closeable { public class VBAMacroReader implements Closeable {
private static final POILogger LOGGER = POILogFactory.getLogger(VBAMacroReader.class); 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_OOXML = "vbaProject.bin";
protected static final String VBA_PROJECT_POIFS = "VBA"; protected static final String VBA_PROJECT_POIFS = "VBA";
@ -352,6 +354,7 @@ public class VBAMacroReader implements Closeable {
DocumentNode document = (DocumentNode)entry; DocumentNode document = (DocumentNode)entry;
try(DocumentInputStream dis = new DocumentInputStream(document)) { try(DocumentInputStream dis = new DocumentInputStream(document)) {
readProjectProperties(dis, moduleNameMap, modules); readProjectProperties(dis, moduleNameMap, modules);
return;
} }
} else if (entry instanceof DirectoryNode) { } else if (entry instanceof DirectoryNode) {
findProjectProperties((DirectoryNode)entry, moduleNameMap, modules); findProjectProperties((DirectoryNode)entry, moduleNameMap, modules);
@ -365,6 +368,7 @@ public class VBAMacroReader implements Closeable {
DocumentNode document = (DocumentNode)entry; DocumentNode document = (DocumentNode)entry;
try(DocumentInputStream dis = new DocumentInputStream(document)) { try(DocumentInputStream dis = new DocumentInputStream(document)) {
readNameMapRecords(dis, moduleNameMap, modules.charset); readNameMapRecords(dis, moduleNameMap, modules.charset);
return;
} }
} else if (entry.isDirectoryEntry()) { } else if (entry.isDirectoryEntry()) {
findModuleNameMap((DirectoryNode)entry, moduleNameMap, modules); findModuleNameMap((DirectoryNode)entry, moduleNameMap, modules);
@ -634,47 +638,53 @@ public class VBAMacroReader implements Closeable {
return new ASCIIUnicodeStringPair(ascii, unicode); return new ASCIIUnicodeStringPair(ascii, unicode);
} }
private static void readNameMapRecords(InputStream is, protected void readNameMapRecords(InputStream is,
Map<String, String> moduleNames, Charset charset) throws IOException { Map<String, String> moduleNames, Charset charset) throws IOException {
//see 2.3.3 PROJECTwm Stream: Module Name Information //see 2.3.3 PROJECTwm Stream: Module Name Information
//multibytecharstring //multibytecharstring
String mbcs = null; String mbcs = null;
String unicode = null; String unicode = null;
//arbitrary sanity thresholds //arbitrary sanity threshold
final int maxNameRecords = 10000; final int maxNameRecords = 10000;
final int maxNameLength = 20000;
int records = 0; int records = 0;
while (++records < maxNameRecords) { while (++records < maxNameRecords) {
try { 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) { } catch (EOFException e) {
return; return;
} }
if (mbcs == null) {
return;
}
try { try {
unicode = readUnicode(is, maxNameLength); unicode = readUnicode(is, MAX_STRING_LENGTH);
} catch (EOFException e) { } catch (EOFException e) {
return; return;
} }
if (unicode != null) { if (mbcs.trim().length() > 0 && unicode.trim().length() > 0) {
moduleNames.put(mbcs, unicode); moduleNames.put(mbcs, unicode);
} }
} }
if (records >= maxNameRecords) { if (records >= maxNameRecords) {
LOGGER.log(POILogger.WARN, "Hit max name records to read ("+maxNameRecords+"). Stopped early."); 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 //reads null-terminated unicode string
ByteArrayOutputStream bos = new ByteArrayOutputStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream();
int b0 = IOUtils.readByte(is); int b0 = IOUtils.readByte(is);
int b1 = IOUtils.readByte(is); int b1 = IOUtils.readByte(is);
int read = 2; int read = 2;
while ((b0 + b1) != 0 && read < maxNameLength) { while ((b0 + b1) != 0 && read < maxLength) {
bos.write(b0); bos.write(b0);
bos.write(b1); bos.write(b1);
@ -682,33 +692,21 @@ public class VBAMacroReader implements Closeable {
b1 = IOUtils.readByte(is); b1 = IOUtils.readByte(is);
read += 2; read += 2;
} }
if (read >= maxNameLength) { if (read >= maxLength) {
LOGGER.log(POILogger.WARN, "stopped reading unicode name after "+read+" bytes"); LOGGER.log(POILogger.WARN, "stopped reading unicode name after "+read+" bytes");
} }
return new String (bos.toByteArray(), StandardCharsets.UTF_16LE); 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(int firstByte, InputStream is, Charset charset, int maxLength) throws IOException {
private static String readMBCS(InputStream is, Charset charset, int maxLength) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream(); ByteArrayOutputStream bos = new ByteArrayOutputStream();
int len = 0; int len = 0;
int b = IOUtils.readByte(is); int b = firstByte;
while (b > 0 && len < maxLength) { while (b > 0 && len < maxLength) {
++len; ++len;
bos.write(b); bos.write(b);
b = IOUtils.readByte(is); 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); return new String(bos.toByteArray(), charset);
} }
@ -722,7 +720,7 @@ public class VBAMacroReader implements Closeable {
* @throws IOException If reading from the stream fails * @throws IOException If reading from the stream fails
*/ */
private static String readString(InputStream stream, int length, Charset charset) throws IOException { 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); int bytesRead = IOUtils.readFully(stream, buffer);
if (bytesRead != length) { if (bytesRead != length) {
throw new IOException("Tried to read: "+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 { 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); int bytesRead = IOUtils.readFully(in, buffer);
if (bytesRead != unicodeNameRecordLength) { if (bytesRead != unicodeNameRecordLength) {
throw new EOFException();
} }
return new String(buffer, StringUtil.UTF16LE); return new String(buffer, StringUtil.UTF16LE);
} }