You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ro...@apache.org on 2026/10/22 13:41:25 UTC
(lucene) branch branch_10x updated: Throw proper CorruptIndexException in stored fields reader (#16891)
This is an automated email from the ASF dual-hosted git repository.
romseygeek pushed a commit to branch branch_10x
in repository https://gitbox.apache.org/repos/asf/lucene.git
The following commit(s) were added to refs/heads/branch_10x by this push:
new f8964e2bdbe Throw proper CorruptIndexException in stored fields reader (#16891)
f8964e2bdbe is described below
commit f8964e2bdbe3e2fcd5873f795cce6d7bc0e84624
Author: Alan Woodward <ro...@apache.org>
AuthorDate: Thu Oct 22 14:37:52 2026 +0100
Throw proper CorruptIndexException in stored fields reader (#16891)
Lucene90StoredFieldsReader would throw an AssertionError when it hit
corrupt data, which in most client applications will cause a JVM
shutdown. Replace this with a CorruptIndexException which can be
handled more gracefully, and will identify which file contains the
error.
---
.../Lucene90CompressingStoredFieldsReader.java | 18 ++++++++------
.../TestCompressingStoredFieldsFormat.java | 29 ++++++++++++++++++++++
2 files changed, 40 insertions(+), 7 deletions(-)
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene90/compressing/Lucene90CompressingStoredFieldsReader.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene90/compressing/Lucene90CompressingStoredFieldsReader.java
index af20a351b4b..f1a4dd4aab6 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/lucene90/compressing/Lucene90CompressingStoredFieldsReader.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene90/compressing/Lucene90CompressingStoredFieldsReader.java
@@ -286,7 +286,8 @@ public final class Lucene90CompressingStoredFieldsReader extends StoredFieldsRea
return original == this && mergeFieldsStream != fieldsStream ? mergeFieldsStream : null;
}
- private static void readField(DataInput in, StoredFieldVisitor visitor, FieldInfo info, int bits)
+ static void readField(
+ DataInput in, StoredFieldVisitor visitor, FieldInfo info, int bits, DataInput source)
throws IOException {
switch (bits & TYPE_MASK) {
case BYTE_ARR:
@@ -309,11 +310,11 @@ public final class Lucene90CompressingStoredFieldsReader extends StoredFieldsRea
visitor.doubleField(info, readZDouble(in));
break;
default:
- throw new AssertionError("Unknown type flag: " + Integer.toHexString(bits));
+ throw new CorruptIndexException("Unknown type flag: " + Integer.toHexString(bits), source);
}
}
- private static void skipField(DataInput in, int bits) throws IOException {
+ static void skipField(DataInput in, int bits, DataInput source) throws IOException {
switch (bits & TYPE_MASK) {
case BYTE_ARR:
case STRING:
@@ -333,7 +334,7 @@ public final class Lucene90CompressingStoredFieldsReader extends StoredFieldsRea
readZDouble(in);
break;
default:
- throw new AssertionError("Unknown type flag: " + Integer.toHexString(bits));
+ throw new CorruptIndexException("Unknown type flag: " + Integer.toHexString(bits), source);
}
}
@@ -699,20 +700,23 @@ public final class Lucene90CompressingStoredFieldsReader extends StoredFieldsRea
final long infoAndBits = doc.in.readVLong();
final int fieldNumber = (int) (infoAndBits >>> TYPE_BITS);
final FieldInfo fieldInfo = fieldInfos.fieldInfo(fieldNumber);
+ if (fieldInfo == null) {
+ throw new CorruptIndexException(
+ "Unknown field number: " + fieldNumber + ", docID=" + docID, fieldsStream);
+ }
final int bits = (int) (infoAndBits & TYPE_MASK);
- assert bits <= NUMERIC_DOUBLE : "bits=" + Integer.toHexString(bits);
switch (visitor.needsField(fieldInfo)) {
case YES:
- readField(doc.in, visitor, fieldInfo, bits);
+ readField(doc.in, visitor, fieldInfo, bits, fieldsStream);
break;
case NO:
if (fieldIDX
== doc.numStoredFields - 1) { // don't skipField on last field value; treat like STOP
return;
}
- skipField(doc.in, bits);
+ skipField(doc.in, bits, fieldsStream);
break;
case STOP:
return;
diff --git a/lucene/core/src/test/org/apache/lucene/codecs/lucene90/compressing/TestCompressingStoredFieldsFormat.java b/lucene/core/src/test/org/apache/lucene/codecs/lucene90/compressing/TestCompressingStoredFieldsFormat.java
index 9c6140801a9..6a3f8dfc3f3 100644
--- a/lucene/core/src/test/org/apache/lucene/codecs/lucene90/compressing/TestCompressingStoredFieldsFormat.java
+++ b/lucene/core/src/test/org/apache/lucene/codecs/lucene90/compressing/TestCompressingStoredFieldsFormat.java
@@ -17,11 +17,15 @@
package org.apache.lucene.codecs.lucene90.compressing;
import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.List;
import java.util.Random;
import org.apache.lucene.codecs.Codec;
import org.apache.lucene.document.Document;
+import org.apache.lucene.document.DocumentStoredFieldVisitor;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.index.CodecReader;
+import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
@@ -29,7 +33,10 @@ import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.NoMergePolicy;
import org.apache.lucene.store.ByteArrayDataInput;
import org.apache.lucene.store.ByteArrayDataOutput;
+import org.apache.lucene.store.ByteBuffersDataInput;
+import org.apache.lucene.store.ByteBuffersIndexInput;
import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.IndexInput;
import org.apache.lucene.tests.analysis.MockAnalyzer;
import org.apache.lucene.tests.codecs.compressing.CompressingCodec;
import org.apache.lucene.tests.index.BaseStoredFieldsFormatTestCase;
@@ -49,6 +56,28 @@ public class TestCompressingStoredFieldsFormat extends BaseStoredFieldsFormatTes
}
}
+ public void testUnknownTypeFlagIsCorruptIndex() throws Exception {
+ IndexInput source =
+ new ByteBuffersIndexInput(
+ new ByteBuffersDataInput(List.of(ByteBuffer.allocate(1))), "test.fdt");
+ ByteArrayDataInput in = new ByteArrayDataInput(new byte[8]);
+ for (int bits : new int[] {6, 7}) {
+ CorruptIndexException readException =
+ expectThrows(
+ CorruptIndexException.class,
+ () ->
+ Lucene90CompressingStoredFieldsReader.readField(
+ in, new DocumentStoredFieldVisitor(), null, bits, source));
+ assertTrue(readException.getMessage().contains("test.fdt"));
+
+ CorruptIndexException skipException =
+ expectThrows(
+ CorruptIndexException.class,
+ () -> Lucene90CompressingStoredFieldsReader.skipField(in, bits, source));
+ assertTrue(skipException.getMessage().contains("test.fdt"));
+ }
+ }
+
public void testZFloat() throws Exception {
byte[] buffer = new byte[5]; // we never need more than 5 bytes
ByteArrayDataOutput out = new ByteArrayDataOutput(buffer);