diff --git a/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java b/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java index 104195599..42fe76c42 100644 --- a/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java +++ b/src/java/org/apache/poi/poifs/macros/VBAMacroReader.java @@ -171,6 +171,39 @@ public class VBAMacroReader implements Closeable { int count = stream.read(buffer); return new String(buffer, 0, count, charset); } + + /** + * reads module from input stream and adds it to the modules map for decompression later + * 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 + * to the decompressed stream contents (the VBA code for one module) + * + * @param in the run-length encoded input stream to read from + * @param streamName the stream name of the module + * @param modules a map to store the modules + * @throws IOException + */ + private static void readModule(RLEDecompressingInputStream in, String streamName, ModuleMap modules) throws IOException { + int moduleOffset = in.readInt(); + Module module = modules.get(streamName); + // First time we've seen the module. Add it to the ModuleMap and decompress it later + if (module == null) { + module = new Module(); + module.offset = moduleOffset; + modules.put(streamName, module); + } + // Decompress a previously found module and store the decompressed result into module.buf + else { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + RLEDecompressingInputStream stream = new RLEDecompressingInputStream(new ByteArrayInputStream( + module.buf, moduleOffset, module.buf.length - moduleOffset)); + IOUtils.copy(stream, out); + stream.close(); + out.close(); + module.buf = out.toByteArray(); + } + } /** * Skips n bytes in an input stream, throwing IOException if the @@ -243,21 +276,7 @@ public class VBAMacroReader implements Closeable { streamName = readString(in, recordLength, modules.charset); break; case MODULEOFFSET: - int moduleOffset = in.readInt(); - Module module = modules.get(streamName); - if (module != null) { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - RLEDecompressingInputStream stream = new RLEDecompressingInputStream(new ByteArrayInputStream( - module.buf, moduleOffset, module.buf.length - moduleOffset)); - IOUtils.copy(stream, out); - stream.close(); - out.close(); - module.buf = out.toByteArray(); - } else { - module = new Module(); - module.offset = moduleOffset; - modules.put(streamName, module); - } + readModule(in, streamName, modules); break; default: trySkip(in, recordLength);