You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by gs...@apache.org on 2022/11/25 19:38:46 UTC

[lucene] branch main updated: Fix NPE in BinaryRangeFieldRangeQuery when field does not exist or is of wrong type (#11950)

This is an automated email from the ASF dual-hosted git repository.

gsmiller pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/lucene.git


The following commit(s) were added to refs/heads/main by this push:
     new 2e83c3b40f4 Fix NPE in BinaryRangeFieldRangeQuery when field does not exist or is of wrong type (#11950)
2e83c3b40f4 is described below

commit 2e83c3b40f43e7dd1d71f23693272dc1a6345f6a
Author: Greg Miller <gs...@gmail.com>
AuthorDate: Fri Nov 25 11:38:41 2022 -0800

    Fix NPE in BinaryRangeFieldRangeQuery when field does not exist or is of wrong type (#11950)
---
 lucene/CHANGES.txt                                 |  3 +++
 .../lucene/document/BinaryRangeDocValues.java      |  1 +
 .../document/BinaryRangeFieldRangeQuery.java       | 11 ++++++---
 .../search/TestRangeFieldsDocValuesQuery.java      | 28 ++++++++++++++++++++++
 4 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index b3d5f23e448..a47de99039f 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -160,6 +160,9 @@ Bug Fixes
 
 * GITHUB#11954: Remove QueryTimeout#isTimeoutEnabled method and move check to caller. (Shubham Chaudhary)
 
+* GITHUB#11950: Fix NPE in BinaryRangeFieldRangeQuery variants when the queried field doesn't exist
+  in a segment or is of the wrong type. (Greg Miller)
+
 Optimizations
 ---------------------
 * GITHUB#11738: Optimize MultiTermQueryConstantScoreWrapper when a term is present that matches all
diff --git a/lucene/core/src/java/org/apache/lucene/document/BinaryRangeDocValues.java b/lucene/core/src/java/org/apache/lucene/document/BinaryRangeDocValues.java
index e057e1de46c..cfa871429bc 100644
--- a/lucene/core/src/java/org/apache/lucene/document/BinaryRangeDocValues.java
+++ b/lucene/core/src/java/org/apache/lucene/document/BinaryRangeDocValues.java
@@ -29,6 +29,7 @@ class BinaryRangeDocValues extends BinaryDocValues {
   private int docID = -1;
 
   BinaryRangeDocValues(BinaryDocValues in, int numDims, int numBytesPerDimension) {
+    assert in != null;
     this.in = in;
     this.numBytesPerDimension = numBytesPerDimension;
     this.numDims = numDims;
diff --git a/lucene/core/src/java/org/apache/lucene/document/BinaryRangeFieldRangeQuery.java b/lucene/core/src/java/org/apache/lucene/document/BinaryRangeFieldRangeQuery.java
index b8ebf578594..621c55f65b0 100644
--- a/lucene/core/src/java/org/apache/lucene/document/BinaryRangeFieldRangeQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/document/BinaryRangeFieldRangeQuery.java
@@ -20,7 +20,6 @@ package org.apache.lucene.document;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Objects;
-import org.apache.lucene.index.BinaryDocValues;
 import org.apache.lucene.index.DocValues;
 import org.apache.lucene.index.LeafReader;
 import org.apache.lucene.index.LeafReaderContext;
@@ -91,9 +90,15 @@ abstract class BinaryRangeFieldRangeQuery extends Query {
   }
 
   private BinaryRangeDocValues getValues(LeafReader reader, String field) throws IOException {
-    BinaryDocValues binaryDocValues = reader.getBinaryDocValues(field);
+    if (reader.getFieldInfos().fieldInfo(field) == null) {
+      // Returning null when the field doesn't exist in the segment allows us to return a null
+      // Scorer, which is
+      // just a bit more efficient:
+      return null;
+    }
 
-    return new BinaryRangeDocValues(binaryDocValues, numDims, numBytesPerDimension);
+    return new BinaryRangeDocValues(
+        DocValues.getBinary(reader, field), numDims, numBytesPerDimension);
   }
 
   @Override
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestRangeFieldsDocValuesQuery.java b/lucene/core/src/test/org/apache/lucene/search/TestRangeFieldsDocValuesQuery.java
index 4c2ff0be01e..27ebeb2cff6 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestRangeFieldsDocValuesQuery.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestRangeFieldsDocValuesQuery.java
@@ -20,9 +20,11 @@ package org.apache.lucene.search;
 import java.io.IOException;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.DoubleRangeDocValuesField;
+import org.apache.lucene.document.Field.Store;
 import org.apache.lucene.document.FloatRangeDocValuesField;
 import org.apache.lucene.document.IntRangeDocValuesField;
 import org.apache.lucene.document.LongRangeDocValuesField;
+import org.apache.lucene.document.StringField;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.tests.index.RandomIndexWriter;
@@ -226,4 +228,30 @@ public class TestRangeFieldsDocValuesQuery extends LuceneTestCase {
     Query q4 = LongRangeDocValuesField.newSlowIntersectsQuery("foo", longMin, longMax);
     assertEquals("foo:[[101, 124, 137] TO [138, 145, 156]]", q4.toString());
   }
+
+  public void testNoData() throws IOException {
+    Directory dir = newDirectory();
+    RandomIndexWriter iw = new RandomIndexWriter(random(), dir);
+    Document doc = new Document();
+    doc.add(new StringField("foo", "abc", Store.NO));
+    iw.addDocument(doc);
+
+    final IndexReader reader = iw.getReader();
+    final IndexSearcher searcher = newSearcher(reader);
+    iw.close();
+
+    // test on field that doesn't exist
+    Query q1 =
+        LongRangeDocValuesField.newSlowIntersectsQuery("bar", new long[] {20}, new long[] {27});
+    TopDocs r = searcher.search(q1, 10);
+    assertEquals(0, r.totalHits.value);
+
+    // test on field of wrong type
+    Query q2 =
+        LongRangeDocValuesField.newSlowIntersectsQuery("foo", new long[] {20}, new long[] {27});
+    expectThrows(IllegalStateException.class, () -> searcher.search(q2, 10));
+
+    reader.close();
+    dir.close();
+  }
 }