diff options
author | Dominik Stadler <centic@apache.org> | 2020-11-01 09:22:09 +0000 |
---|---|---|
committer | Dominik Stadler <centic@apache.org> | 2020-11-01 09:22:09 +0000 |
commit | d835bdef42a46f6b70baaf558e0a716914c2a2cb (patch) | |
tree | a0e5a1431acc98297c5f58515c0a9606eeeb5fce /src/java | |
parent | 232d734941d4a082841e42b9451f2ed1b540bf04 (diff) | |
download | poi-d835bdef42a46f6b70baaf558e0a716914c2a2cb.tar.gz poi-d835bdef42a46f6b70baaf558e0a716914c2a2cb.zip |
Fix file-handle-leaks when re-writing documents or slideshows
When replacing a directory, we should close the previous one
Close some resources in tests
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1883038 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java')
3 files changed, 34 insertions, 15 deletions
diff --git a/src/java/org/apache/poi/POIDocument.java b/src/java/org/apache/poi/POIDocument.java index 06a76a952b..55517ffe76 100644 --- a/src/java/org/apache/poi/POIDocument.java +++ b/src/java/org/apache/poi/POIDocument.java @@ -463,7 +463,21 @@ public abstract class POIDocument implements Closeable { * @param newDirectory the new directory */ @Internal - protected void replaceDirectory(DirectoryNode newDirectory) { + protected void replaceDirectory(DirectoryNode newDirectory) throws IOException { + if ( + // do not close if it is actually the same directory or + newDirectory == directory || + + // also for different directories, but same FileSystem + (newDirectory != null && directory != null && newDirectory.getFileSystem() == directory.getFileSystem())) { + return; + } + + // close any previous opened DataSource + if (directory != null && directory.getFileSystem() != null) { + directory.getFileSystem().close(); + } + directory = newDirectory; } diff --git a/src/java/org/apache/poi/poifs/nio/ByteArrayBackedDataSource.java b/src/java/org/apache/poi/poifs/nio/ByteArrayBackedDataSource.java index 72758c2d97..15c4f6ff07 100644 --- a/src/java/org/apache/poi/poifs/nio/ByteArrayBackedDataSource.java +++ b/src/java/org/apache/poi/poifs/nio/ByteArrayBackedDataSource.java @@ -32,15 +32,16 @@ public class ByteArrayBackedDataSource extends DataSource { private byte[] buffer; private long size; - + public ByteArrayBackedDataSource(byte[] data, int size) { // NOSONAR this.buffer = data; this.size = size; } + public ByteArrayBackedDataSource(byte[] data) { this(data, data.length); } - + @Override public ByteBuffer read(int length, long position) { if(position >= size) { @@ -49,28 +50,28 @@ public class ByteArrayBackedDataSource extends DataSource { position + " in stream of length " + size ); } - + int toRead = (int)Math.min(length, size - position); return ByteBuffer.wrap(buffer, (int)position, toRead); } - + @Override public void write(ByteBuffer src, long position) { // Extend if needed - long endPosition = position + src.capacity(); + long endPosition = position + src.capacity(); if(endPosition > buffer.length) { extend(endPosition); } - + // Now copy src.get(buffer, (int)position, src.capacity()); - + // Update size if needed if(endPosition > size) { size = endPosition; } } - + private void extend(long length) { // Consider extending by a bit more than requested long difference = length - buffer.length; @@ -86,17 +87,17 @@ public class ByteArrayBackedDataSource extends DataSource { System.arraycopy(buffer, 0, nb, 0, (int)size); buffer = nb; } - + @Override public void copyTo(OutputStream stream) throws IOException { stream.write(buffer, 0, (int)size); } - + @Override public long size() { return size; } - + @Override public void close() { buffer = null; diff --git a/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java b/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java index 2d4af278c1..ce73077910 100644 --- a/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java +++ b/src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java @@ -43,7 +43,7 @@ public class FileBackedDataSource extends DataSource { private final boolean writable; // remember file base, which needs to be closed too - private RandomAccessFile srcFile; + private final RandomAccessFile srcFile; // Buffers which map to a file-portion are not closed automatically when the Channel is closed // therefore we need to keep the list of mapped buffers and do some ugly reflection to try to @@ -63,11 +63,15 @@ public class FileBackedDataSource extends DataSource { } public FileBackedDataSource(RandomAccessFile srcFile, boolean readOnly) { - this(srcFile.getChannel(), readOnly); - this.srcFile = srcFile; + this(srcFile, srcFile.getChannel(), readOnly); } public FileBackedDataSource(FileChannel channel, boolean readOnly) { + this(null, channel, readOnly); + } + + private FileBackedDataSource(RandomAccessFile srcFile, FileChannel channel, boolean readOnly) { + this.srcFile = srcFile; this.channel = channel; this.writable = !readOnly; } |