aboutsummaryrefslogtreecommitdiffstats
path: root/src/java
diff options
context:
space:
mode:
authorDominik Stadler <centic@apache.org>2020-11-01 09:22:09 +0000
committerDominik Stadler <centic@apache.org>2020-11-01 09:22:09 +0000
commitd835bdef42a46f6b70baaf558e0a716914c2a2cb (patch)
treea0e5a1431acc98297c5f58515c0a9606eeeb5fce /src/java
parent232d734941d4a082841e42b9451f2ed1b540bf04 (diff)
downloadpoi-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')
-rw-r--r--src/java/org/apache/poi/POIDocument.java16
-rw-r--r--src/java/org/apache/poi/poifs/nio/ByteArrayBackedDataSource.java23
-rw-r--r--src/java/org/apache/poi/poifs/nio/FileBackedDataSource.java10
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;
}