Skip to content

Commit 3bd0c33

Browse files
author
Christoph Büscher
committed
Fix potential NPE in FuzzyTermsEnum (#53231)
Under certain circumstances SpanMultiTermQueryWrapper uses SpanBooleanQueryRewriteWithMaxClause as its rewrite method, which in turn tries to get a TermsEnum from the wrapped MultiTermQuery currently using a `null` AttributeSource. While queries TermsQuery or subclasses of AutomatonQuery ignore this argument, FuzzyQuery uses it to create a FuzzyTermsEnum which triggers an NPE when the AttributeSource is not provided. This PR fixes this by supplying an empty AttributeSource instead of a `null` value. Closes #52894
1 parent 8e3c1cb commit 3bd0c33

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

server/src/main/java/org/elasticsearch/common/lucene/search/SpanBooleanQueryRewriteWithMaxClause.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.apache.lucene.search.spans.SpanOrQuery;
3434
import org.apache.lucene.search.spans.SpanQuery;
3535
import org.apache.lucene.search.spans.SpanTermQuery;
36+
import org.apache.lucene.util.AttributeSource;
3637
import org.apache.lucene.util.BytesRef;
3738

3839
import java.io.IOException;
@@ -92,11 +93,12 @@ private Collection<SpanQuery> collectTerms(IndexReader reader, MultiTermQuery qu
9293
continue;
9394
}
9495

95-
final TermsEnum termsEnum = getTermsEnum(query, terms, null);
96+
final TermsEnum termsEnum = getTermsEnum(query, terms, new AttributeSource());
9697
assert termsEnum != null;
9798

98-
if (termsEnum == TermsEnum.EMPTY)
99+
if (termsEnum == TermsEnum.EMPTY) {
99100
continue;
101+
}
100102

101103
BytesRef bytes;
102104
while ((bytes = termsEnum.next()) != null) {

server/src/test/java/org/elasticsearch/search/query/SearchQueryIT.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@
1919

2020
package org.elasticsearch.search.query;
2121

22+
import org.apache.lucene.index.IndexReader;
23+
import org.apache.lucene.search.MultiTermQuery;
2224
import org.apache.lucene.search.join.ScoreMode;
25+
import org.apache.lucene.util.AttributeSource;
2326
import org.apache.lucene.util.English;
2427
import org.elasticsearch.action.index.IndexRequestBuilder;
2528
import org.elasticsearch.action.search.SearchPhaseExecutionException;
@@ -28,6 +31,7 @@
2831
import org.elasticsearch.bootstrap.JavaVersion;
2932
import org.elasticsearch.common.Strings;
3033
import org.elasticsearch.common.document.DocumentField;
34+
import org.elasticsearch.common.lucene.search.SpanBooleanQueryRewriteWithMaxClause;
3135
import org.elasticsearch.common.settings.Settings;
3236
import org.elasticsearch.common.time.DateFormatter;
3337
import org.elasticsearch.common.xcontent.XContentBuilder;
@@ -1892,4 +1896,20 @@ public void testFieldAliasesForMetaFields() throws Exception {
18921896
}
18931897

18941898
}
1899+
1900+
/**
1901+
* Test correct handling {@link SpanBooleanQueryRewriteWithMaxClause#rewrite(IndexReader, MultiTermQuery)}. That rewrite method is e.g.
1902+
* set for fuzzy queries with "constant_score" rewrite nested inside a `span_multi` query and would cause NPEs due to an unset
1903+
* {@link AttributeSource}.
1904+
*/
1905+
public void testIssueFuzzyInsideSpanMulti() {
1906+
createIndex("test");
1907+
client().prepareIndex("test", "_doc", "1").setSource("field", "foobarbaz").get();
1908+
ensureGreen();
1909+
refresh();
1910+
1911+
BoolQueryBuilder query = boolQuery().filter(spanMultiTermQueryBuilder(fuzzyQuery("field", "foobarbiz").rewrite("constant_score")));
1912+
SearchResponse response = client().prepareSearch("test").setQuery(query).get();
1913+
assertHitCount(response, 1);
1914+
}
18951915
}

0 commit comments

Comments
 (0)