mirror of https://github.com/apache/poi.git
bug 52949,59830: move module storage and decompressing into a standalone function
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1751990 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
c220067619
commit
ab9ecf9373
|
@ -128,6 +128,12 @@ public class VBAMacroReader implements Closeable {
|
||||||
protected static class Module {
|
protected static class Module {
|
||||||
Integer offset;
|
Integer offset;
|
||||||
byte[] buf;
|
byte[] buf;
|
||||||
|
void read(InputStream in) throws IOException {
|
||||||
|
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
|
IOUtils.copy(in, out);
|
||||||
|
out.close();
|
||||||
|
buf = out.toByteArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
protected static class ModuleMap extends HashMap<String, Module> {
|
protected static class ModuleMap extends HashMap<String, Module> {
|
||||||
Charset charset = Charset.forName("Cp1252"); // default charset
|
Charset charset = Charset.forName("Cp1252"); // default charset
|
||||||
|
@ -173,7 +179,7 @@ public class VBAMacroReader implements Closeable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* reads module from input stream and adds it to the modules map for decompression later
|
* reads module from DIR node in input stream and adds it to the modules map for decompression later
|
||||||
* on the second pass through this function, the module will be decompressed
|
* on the second pass through this function, the module will be decompressed
|
||||||
*
|
*
|
||||||
* Side-effects: adds a new module to the module map or sets the buf field on the module
|
* Side-effects: adds a new module to the module map or sets the buf field on the module
|
||||||
|
@ -187,24 +193,43 @@ public class VBAMacroReader implements Closeable {
|
||||||
private static void readModule(RLEDecompressingInputStream in, String streamName, ModuleMap modules) throws IOException {
|
private static void readModule(RLEDecompressingInputStream in, String streamName, ModuleMap modules) throws IOException {
|
||||||
int moduleOffset = in.readInt();
|
int moduleOffset = in.readInt();
|
||||||
Module module = modules.get(streamName);
|
Module module = modules.get(streamName);
|
||||||
// First time we've seen the module. Add it to the ModuleMap and decompress it later
|
|
||||||
if (module == null) {
|
if (module == null) {
|
||||||
|
// First time we've seen the module. Add it to the ModuleMap and decompress it later
|
||||||
module = new Module();
|
module = new Module();
|
||||||
module.offset = moduleOffset;
|
module.offset = moduleOffset;
|
||||||
modules.put(streamName, module);
|
modules.put(streamName, module);
|
||||||
}
|
// Would adding module.read(in) here be correct?
|
||||||
|
} else {
|
||||||
// Decompress a previously found module and store the decompressed result into module.buf
|
// Decompress a previously found module and store the decompressed result into module.buf
|
||||||
else {
|
InputStream stream = new RLEDecompressingInputStream(
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
new ByteArrayInputStream(module.buf, moduleOffset, module.buf.length - moduleOffset)
|
||||||
RLEDecompressingInputStream stream = new RLEDecompressingInputStream(new ByteArrayInputStream(
|
);
|
||||||
module.buf, moduleOffset, module.buf.length - moduleOffset));
|
module.read(stream);
|
||||||
IOUtils.copy(stream, out);
|
|
||||||
stream.close();
|
stream.close();
|
||||||
out.close();
|
|
||||||
module.buf = out.toByteArray();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void readModule(DocumentInputStream dis, String name, ModuleMap modules) throws IOException {
|
||||||
|
Module module = modules.get(name);
|
||||||
|
// TODO Refactor this to fetch dir then do the rest
|
||||||
|
if (module == null) {
|
||||||
|
// no DIR stream with offsets yet, so store the compressed bytes for later
|
||||||
|
module = new Module();
|
||||||
|
modules.put(name, module);
|
||||||
|
module.read(dis);
|
||||||
|
} else {
|
||||||
|
// we know the offset already, so decompress immediately on-the-fly
|
||||||
|
long skippedBytes = dis.skip(module.offset);
|
||||||
|
if (skippedBytes != module.offset) {
|
||||||
|
throw new IOException("tried to skip " + module.offset + " bytes, but actually skipped " + skippedBytes + " bytes");
|
||||||
|
}
|
||||||
|
InputStream stream = new RLEDecompressingInputStream(dis);
|
||||||
|
module.read(stream);
|
||||||
|
stream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Skips <tt>n</tt> bytes in an input stream, throwing IOException if the
|
* Skips <tt>n</tt> bytes in an input stream, throwing IOException if the
|
||||||
* number of bytes skipped is different than requested.
|
* number of bytes skipped is different than requested.
|
||||||
|
@ -294,27 +319,7 @@ public class VBAMacroReader implements Closeable {
|
||||||
} 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
|
||||||
Module module = modules.get(name);
|
readModule(dis, name, modules);
|
||||||
final InputStream in;
|
|
||||||
// TODO Refactor this to fetch dir then do the rest
|
|
||||||
if (module == null) {
|
|
||||||
// no DIR stream with offsets yet, so store the compressed bytes for later
|
|
||||||
module = new Module();
|
|
||||||
modules.put(name, module);
|
|
||||||
in = dis;
|
|
||||||
} else {
|
|
||||||
// we know the offset already, so decompress immediately on-the-fly
|
|
||||||
long skippedBytes = dis.skip(module.offset);
|
|
||||||
if (skippedBytes != module.offset) {
|
|
||||||
throw new IOException("tried to skip " + module.offset + " bytes, but actually skipped " + skippedBytes + " bytes");
|
|
||||||
}
|
|
||||||
in = new RLEDecompressingInputStream(dis);
|
|
||||||
}
|
|
||||||
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
||||||
IOUtils.copy(in, out);
|
|
||||||
in.close();
|
|
||||||
out.close();
|
|
||||||
module.buf = out.toByteArray();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
|
Loading…
Reference in New Issue