diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index ddd7e1f5b84..e60ab1c2f0c 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -70,6 +70,9 @@ Bug fixes * LUCENE-8754: Fix ConcurrentModificationException in SegmentInfo if attributes are accessed in MergePolicy while the merge is running (Simon Willnauer) +* LUCENE-8765: Fixed validation of the number of added points in KD trees. + (Zhao Yang via Adrien Grand) + Improvements * LUCENE-8673: Use radix partitioning when merging dimensional points instead diff --git a/lucene/core/src/java/org/apache/lucene/util/bkd/BKDWriter.java b/lucene/core/src/java/org/apache/lucene/util/bkd/BKDWriter.java index 307372821f2..3fa3eb63199 100644 --- a/lucene/core/src/java/org/apache/lucene/util/bkd/BKDWriter.java +++ b/lucene/core/src/java/org/apache/lucene/util/bkd/BKDWriter.java @@ -553,8 +553,8 @@ public class BKDWriter implements Closeable { docsSeen.set(docID); leafCount++; - if (valueCount > totalPointCount) { - throw new IllegalStateException("totalPointCount=" + totalPointCount + " was passed when we were created, but we just hit " + pointCount + " values"); + if (valueCount + leafCount > totalPointCount) { + throw new IllegalStateException("totalPointCount=" + totalPointCount + " was passed when we were created, but we just hit " + pointCount + leafCount + " values"); } if (leafCount == maxPointsInLeafNode) { diff --git a/lucene/core/src/test/org/apache/lucene/util/bkd/TestBKD.java b/lucene/core/src/test/org/apache/lucene/util/bkd/TestBKD.java index b651b539ecf..282add97bb3 100644 --- a/lucene/core/src/test/org/apache/lucene/util/bkd/TestBKD.java +++ b/lucene/core/src/test/org/apache/lucene/util/bkd/TestBKD.java @@ -24,6 +24,7 @@ import java.util.Arrays; import java.util.BitSet; import java.util.List; +import org.apache.lucene.codecs.MutablePointValues; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.index.MergeState; import org.apache.lucene.index.PointValues.IntersectVisitor; @@ -1245,4 +1246,94 @@ public class TestBKD extends LuceneTestCase { pointsIn.close(); dir.close(); } + + public void testTotalPointCountValidation() throws IOException { + Directory dir = newDirectory(); + final int numValues = 10; + final int numPointsAdded = 50; // exceeds totalPointCount + final int numBytesPerDim = TestUtil.nextInt(random(), 1, 4); + final byte[] pointValue = new byte[numBytesPerDim]; + random().nextBytes(pointValue); + + MutablePointValues reader = new MutablePointValues() { + + @Override + public void intersect(IntersectVisitor visitor) throws IOException { + for(int i=0;i { + try (IndexOutput out = dir.createOutput("bkd", IOContext.DEFAULT)) { + w.writeField(out, "test_field_name", reader); + } finally { + w.close(); + dir.close(); + } + }); + } }