bug 59830: attach context to any IOException (likely a result of reaching EOF on input stream)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1751986 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
518253650a
commit
76dde0aed5
@ -40,6 +40,7 @@ import org.apache.poi.poifs.filesystem.DocumentNode;
|
|||||||
import org.apache.poi.poifs.filesystem.Entry;
|
import org.apache.poi.poifs.filesystem.Entry;
|
||||||
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
|
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
|
||||||
import org.apache.poi.poifs.filesystem.OfficeXmlFileException;
|
import org.apache.poi.poifs.filesystem.OfficeXmlFileException;
|
||||||
|
import org.apache.poi.util.HexDump;
|
||||||
import org.apache.poi.util.IOUtils;
|
import org.apache.poi.util.IOUtils;
|
||||||
import org.apache.poi.util.RLEDecompressingInputStream;
|
import org.apache.poi.util.RLEDecompressingInputStream;
|
||||||
|
|
||||||
@ -179,13 +180,31 @@ public class VBAMacroReader implements Closeable {
|
|||||||
private static void trySkip(InputStream in, long n) throws IOException {
|
private static void trySkip(InputStream in, long n) throws IOException {
|
||||||
long skippedBytes = in.skip(n);
|
long skippedBytes = in.skip(n);
|
||||||
if (skippedBytes != n) {
|
if (skippedBytes != n) {
|
||||||
|
if (skippedBytes < 0) {
|
||||||
throw new IOException(
|
throw new IOException(
|
||||||
"Skipped only " + skippedBytes + " while trying to skip " + n + " bytes. " +
|
"Tried skipping " + n + " bytes, but no bytes were skipped. "
|
||||||
" This should never happen.");
|
+ "The end of the stream has been reached or the stream is closed.");
|
||||||
|
} else {
|
||||||
|
throw new IOException(
|
||||||
|
"Tried skipping " + n + " bytes, but only " + skippedBytes + " bytes were skipped. "
|
||||||
|
+ "This should never happen.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Constants from MS-OVBA: https://msdn.microsoft.com/en-us/library/office/cc313094(v=office.12).aspx
|
||||||
|
private static final int EOF = -1;
|
||||||
|
private static final int VERSION_INDEPENDENT_TERMINATOR = 0x0010;
|
||||||
|
private static final int VERSION_DEPENDENT_TERMINATOR = 0x002B;
|
||||||
|
private static final int PROJECTVERSION = 0x0009;
|
||||||
|
private static final int PROJECTCODEPAGE = 0x0003;
|
||||||
|
private static final int STREAMNAME = 0x001A;
|
||||||
|
private static final int MODULEOFFSET = 0x0031;
|
||||||
|
private static final int MODULETYPE_PROCEDURAL = 0x0021;
|
||||||
|
private static final int MODULETYPE_DOCUMENT_CLASS_OR_DESIGNER = 0x0022;
|
||||||
|
private static final int PROJECTLCID = 0x0002;
|
||||||
|
|
||||||
|
/**
|
||||||
* Reads VBA Project modules from a VBA Project directory located at
|
* Reads VBA Project modules from a VBA Project directory located at
|
||||||
* <tt>macroDir</tt> into <tt>modules</tt>.
|
* <tt>macroDir</tt> into <tt>modules</tt>.
|
||||||
*
|
*
|
||||||
@ -203,24 +222,27 @@ public class VBAMacroReader implements Closeable {
|
|||||||
// process DIR
|
// process DIR
|
||||||
RLEDecompressingInputStream in = new RLEDecompressingInputStream(dis);
|
RLEDecompressingInputStream in = new RLEDecompressingInputStream(dis);
|
||||||
String streamName = null;
|
String streamName = null;
|
||||||
|
int recordId = 0;
|
||||||
|
try {
|
||||||
while (true) {
|
while (true) {
|
||||||
int id = in.readShort();
|
recordId = in.readShort();
|
||||||
if (id == -1 || id == 0x0010) {
|
if (EOF == recordId
|
||||||
break; // EOF or TERMINATOR
|
|| VERSION_INDEPENDENT_TERMINATOR == recordId) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
int len = in.readInt();
|
int recordLength = in.readInt();
|
||||||
switch (id) {
|
switch (recordId) {
|
||||||
case 0x0009: // PROJECTVERSION
|
case PROJECTVERSION:
|
||||||
trySkip(in, 6);
|
trySkip(in, 6);
|
||||||
break;
|
break;
|
||||||
case 0x0003: // PROJECTCODEPAGE
|
case PROJECTCODEPAGE:
|
||||||
int codepage = in.readShort();
|
int codepage = in.readShort();
|
||||||
modules.charset = Charset.forName("Cp" + codepage);
|
modules.charset = Charset.forName("Cp" + codepage);
|
||||||
break;
|
break;
|
||||||
case 0x001A: // STREAMNAME
|
case STREAMNAME:
|
||||||
streamName = readString(in, len, modules.charset);
|
streamName = readString(in, recordLength, modules.charset);
|
||||||
break;
|
break;
|
||||||
case 0x0031: // MODULEOFFSET
|
case MODULEOFFSET:
|
||||||
int moduleOffset = in.readInt();
|
int moduleOffset = in.readInt();
|
||||||
Module module = modules.get(streamName);
|
Module module = modules.get(streamName);
|
||||||
if (module != null) {
|
if (module != null) {
|
||||||
@ -238,15 +260,18 @@ public class VBAMacroReader implements Closeable {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
try {
|
trySkip(in, recordLength);
|
||||||
trySkip(in, len);
|
|
||||||
} catch (final IOException e) {
|
|
||||||
throw new IOException("Error occurred while reading section id " + id, e);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (final IOException e) {
|
||||||
|
throw new IOException(
|
||||||
|
"Error occurred while reading macros at section id "
|
||||||
|
+ recordId + " (" + HexDump.shortToHex(recordId) + ")", e);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
in.close();
|
in.close();
|
||||||
|
}
|
||||||
} else if (!startsWithIgnoreCase(name, "__SRP")
|
} else if (!startsWithIgnoreCase(name, "__SRP")
|
||||||
&& !startsWithIgnoreCase(name, "_VBA_PROJECT")) {
|
&& !startsWithIgnoreCase(name, "_VBA_PROJECT")) {
|
||||||
// process module, skip __SRP and _VBA_PROJECT since these do not contain macros
|
// process module, skip __SRP and _VBA_PROJECT since these do not contain macros
|
||||||
|
Loading…
Reference in New Issue
Block a user