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:
parent
40a5e940c1
commit
70db618688
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user