diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 6cc5fccac46..9e282f8f673 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -526,6 +526,9 @@ Bug fixes * LUCENE-2634: isCurrent on an NRT reader was failing to return false if the writer had just committed (Nikolay Zamosenchuk via Mike McCandless) +* LUCENE-2650: Added extra safety to MMapIndexInput clones to prevent accessing + an unmapped buffer if the input is closed (Mike McCandless, Uwe Schindler, Robert Muir) + New features * LUCENE-2128: Parallelized fetching document frequencies during weight diff --git a/lucene/src/java/org/apache/lucene/store/MMapDirectory.java b/lucene/src/java/org/apache/lucene/store/MMapDirectory.java index 58be3678ccb..596ffd539b0 100644 --- a/lucene/src/java/org/apache/lucene/store/MMapDirectory.java +++ b/lucene/src/java/org/apache/lucene/store/MMapDirectory.java @@ -259,6 +259,8 @@ public class MMapDirectory extends FSDirectory { @Override public Object clone() { + if (buffer == null) + throw new AlreadyClosedException("MMapIndexInput already closed"); MMapIndexInput clone = (MMapIndexInput)super.clone(); clone.isClone = true; clone.buffer = buffer.duplicate(); @@ -267,9 +269,9 @@ public class MMapDirectory extends FSDirectory { @Override public void close() throws IOException { - if (isClone || buffer == null) return; // unmap the buffer (if enabled) and at least unset it for GC try { + if (isClone || buffer == null) return; cleanMapping(buffer); } finally { buffer = null; @@ -382,6 +384,8 @@ public class MMapDirectory extends FSDirectory { @Override public Object clone() { + if (buffers == null) + throw new AlreadyClosedException("MultiMMapIndexInput already closed"); MultiMMapIndexInput clone = (MultiMMapIndexInput)super.clone(); clone.isClone = true; clone.buffers = new ByteBuffer[buffers.length]; @@ -403,8 +407,8 @@ public class MMapDirectory extends FSDirectory { @Override public void close() throws IOException { - if (isClone || buffers == null) return; try { + if (isClone || buffers == null) return; for (int bufNr = 0; bufNr < buffers.length; bufNr++) { // unmap the buffer (if enabled) and at least unset it for GC try {