bug 62624 -- fix loop identified as dodgy by FindBugs; add a other sanity checks.
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1845299 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
9229cab9bc
commit
c257dd71f9
@ -631,14 +631,19 @@ public class VBAMacroReader implements Closeable {
|
|||||||
return new ASCIIUnicodeStringPair(ascii, unicode);
|
return new ASCIIUnicodeStringPair(ascii, unicode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void readNameMapRecords(InputStream is, Map<String, String> moduleNames, Charset charset) throws IOException {
|
private static void readNameMapRecords(InputStream is,
|
||||||
|
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;
|
||||||
do {
|
//arbitrary sanity thresholds
|
||||||
|
final int maxNameRecords = 10000;
|
||||||
|
final int maxNameLength = 20000;
|
||||||
|
int records = 0;
|
||||||
|
while (++records < maxNameRecords) {
|
||||||
try {
|
try {
|
||||||
mbcs = readMBCS(is, charset);
|
mbcs = readMBCS(is, charset, maxNameLength);
|
||||||
} catch (EOFException e) {
|
} catch (EOFException e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -646,53 +651,56 @@ public class VBAMacroReader implements Closeable {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
unicode = readUnicode(is);
|
unicode = readUnicode(is, maxNameLength);
|
||||||
} catch (EOFException e) {
|
} catch (EOFException e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mbcs != null && unicode != null) {
|
if (unicode != null) {
|
||||||
moduleNames.put(mbcs, unicode);
|
moduleNames.put(mbcs, unicode);
|
||||||
}
|
}
|
||||||
} while (mbcs != null && unicode != null);
|
}
|
||||||
|
if (records >= maxNameRecords) {
|
||||||
|
LOGGER.log(POILogger.WARN, "Hit max name records to read ("+maxNameRecords+"). Stopped early.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String readUnicode(InputStream is) throws IOException {
|
private static String readUnicode(InputStream is, int maxNameLength) throws IOException {
|
||||||
//reads null-terminated unicode string
|
//reads null-terminated unicode string
|
||||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
int b0 = is.read();
|
int b0 = IOUtils.readByte(is);
|
||||||
int b1 = is.read();
|
int b1 = IOUtils.readByte(is);
|
||||||
|
|
||||||
while ((b0 + b1) != 0) {
|
int read = 2;
|
||||||
if (b0 == -1 || b1 == -1) {
|
while ((b0 + b1) != 0 && read < maxNameLength) {
|
||||||
throw new EOFException();
|
|
||||||
}
|
|
||||||
|
|
||||||
bos.write(b0);
|
bos.write(b0);
|
||||||
bos.write(b1);
|
bos.write(b1);
|
||||||
b0 = is.read();
|
b0 = IOUtils.readByte(is);
|
||||||
b1 = is.read();
|
b1 = IOUtils.readByte(is);
|
||||||
|
read += 2;
|
||||||
|
}
|
||||||
|
if (read >= maxNameLength) {
|
||||||
|
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
|
//returns a string if any bytes are read or null if two 0x00 are read
|
||||||
private static String readMBCS(InputStream is, Charset charset) 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 = is.read();
|
int b = IOUtils.readByte(is);
|
||||||
while (b != 0) {
|
while (b > 0 && len < maxLength) {
|
||||||
++len;
|
++len;
|
||||||
if (b == -1) {
|
|
||||||
throw new EOFException();
|
|
||||||
}
|
|
||||||
bos.write(b);
|
bos.write(b);
|
||||||
b = is.read();
|
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) {
|
if (len == 0) {
|
||||||
b = is.read();
|
b = IOUtils.readByte(is);
|
||||||
if (b == -1) {
|
|
||||||
throw new EOFException();
|
|
||||||
}
|
|
||||||
if (b != 0) {
|
if (b != 0) {
|
||||||
LOGGER.log(POILogger.WARN, "expected two 0x00 at end of module name map");
|
LOGGER.log(POILogger.WARN, "expected two 0x00 at end of module name map");
|
||||||
}
|
}
|
||||||
|
@ -548,6 +548,22 @@ public final class IOUtils {
|
|||||||
return new byte[(int)length];
|
return new byte[(int)length];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple utility function to check that you haven't hit EOF
|
||||||
|
* when reading a byte.
|
||||||
|
*
|
||||||
|
* @param is inputstream to read
|
||||||
|
* @return byte read, unless
|
||||||
|
* @throws IOException on IOException or EOF if -1 is read
|
||||||
|
*/
|
||||||
|
public static int readByte(InputStream is) throws IOException {
|
||||||
|
int b = is.read();
|
||||||
|
if (b == -1) {
|
||||||
|
throw new EOFException();
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
private static void throwRFE(long length, int maxLength) {
|
private static void throwRFE(long length, int maxLength) {
|
||||||
throw new RecordFormatException("Tried to allocate an array of length "+length +
|
throw new RecordFormatException("Tried to allocate an array of length "+length +
|
||||||
", but "+ maxLength+" is the maximum for this record type.\n" +
|
", but "+ maxLength+" is the maximum for this record type.\n" +
|
||||||
|
Loading…
Reference in New Issue
Block a user