diff options
author | Simeon Andreev | 2020-11-02 09:24:04 +0000 |
---|---|---|
committer | Andrey Loskutov | 2020-11-05 22:52:37 +0000 |
commit | 34fd68381b995c120c725b6aa4ee37a41016bf22 (patch) | |
tree | 0e40cf3598b0f2eeac0b70d50b3fb64cb2ccb986 | |
parent | 014c422d5667c8e19d23e2a16b5fb1bf143a58a1 (diff) | |
download | eclipse.jdt.core-34fd68381b995c120c725b6aa4ee37a41016bf22.tar.gz eclipse.jdt.core-34fd68381b995c120c725b6aa4ee37a41016bf22.tar.xz eclipse.jdt.core-34fd68381b995c120c725b6aa4ee37a41016bf22.zip |
Bug 566262 - AIOOBE in DiskIndex.readChunkI20201105-1800
During JDT indexing of a project its possible that the project is
deleted in parallel, deleting also index files for that project. With
bad ordering, the indexing can save a "stale" index file after the
project is deleted. Re-creating the project and deleting it again (e.g.
during tests) can result in DiskIndex throwing an
ArrayIndexOutOfBoundsException (AIOOBE).
In particular, the AIOOBE is caused by reading a bad value (-1) for
DiskIndex.bufferEnd, due to the deleted index file. As a result
DiskIndex.readStreamBuffer() will return without resetting
DiskIndex.bufferIndex to 0, when the end of DiskIndex.streamBuffer is
reached. DiskIndex.readChunk() will then increment
DiskIndex.bufferIndex() past the length of the buffer, accessing an
invalid index with the next operation and so throwing an exception.
This change ensures an IOException is thrown in case DiskIndex.bufferEnd
has a bad value and the input stream of DiskIndex has no more available
data to read. An IOException is already handled by JDT, unlike an
AIOOBE.
Change-Id: I1c95d87faf1bf01348c602fb721be1b85b8a7306
Signed-off-by: Simeon Andreev <simeon.danailov.andreev@gmail.com>
-rw-r--r-- | org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java index d5e7eb6367..d5ba2b9841 100644 --- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java +++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/index/DiskIndex.java @@ -19,6 +19,7 @@ import java.util.regex.Pattern; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.core.search.*; import org.eclipse.jdt.internal.core.util.*; +import org.eclipse.osgi.util.NLS; import org.eclipse.jdt.internal.compiler.util.HashtableOfIntValues; import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable; @@ -753,6 +754,10 @@ private void readChunk(String[] docNames, InputStream stream, int index, int siz for (int i = 1; i < size; i++) { if (stream != null && this.bufferIndex + 2 >= this.bufferEnd) readStreamBuffer(stream); + // bug 566262: check if the index file was deleted in parallel, if so throw an IOException instead of risking to run into index OOB exceptions + if (this.bufferEnd == -1 && stream.available() == 0) { + throw new IOException(NLS.bind("Stream was closed for index location \"{0}\"", this.indexLocation)); //$NON-NLS-1$ + } int start = this.streamBuffer[this.bufferIndex++] & 0xFF; int end = this.streamBuffer[this.bufferIndex++] & 0xFF; String next = new String(readStreamChars(stream)); |