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 {
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<String, String> 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);
}