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
This commit is contained in:
Christoph Büscher 2020-03-09 12:16:09 +01:00
parent 28cb4a167d
commit 2fd954a3b7
2 changed files with 24 additions and 2 deletions

View File

@ -33,6 +33,7 @@ import org.apache.lucene.search.spans.SpanMultiTermQueryWrapper;
import org.apache.lucene.search.spans.SpanOrQuery;
import org.apache.lucene.search.spans.SpanQuery;
import org.apache.lucene.search.spans.SpanTermQuery;
import org.apache.lucene.util.AttributeSource;
import org.apache.lucene.util.BytesRef;
import java.io.IOException;
@ -92,11 +93,12 @@ public class SpanBooleanQueryRewriteWithMaxClause extends SpanMultiTermQueryWrap
continue;
}
final TermsEnum termsEnum = getTermsEnum(query, terms, null);
final TermsEnum termsEnum = getTermsEnum(query, terms, new AttributeSource());
assert termsEnum != null;
if (termsEnum == TermsEnum.EMPTY)
if (termsEnum == TermsEnum.EMPTY) {
continue;
}
BytesRef bytes;
while ((bytes = termsEnum.next()) != null) {

View File

@ -19,7 +19,10 @@
package org.elasticsearch.search.query;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.MultiTermQuery;
import org.apache.lucene.search.join.ScoreMode;
import org.apache.lucene.util.AttributeSource;
import org.apache.lucene.util.English;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchPhaseExecutionException;
@ -28,6 +31,7 @@ import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.bootstrap.JavaVersion;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.document.DocumentField;
import org.elasticsearch.common.lucene.search.SpanBooleanQueryRewriteWithMaxClause;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.time.DateFormatter;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -1892,4 +1896,20 @@ public class SearchQueryIT extends ESIntegTestCase {
}
}
/**
* Test correct handling {@link SpanBooleanQueryRewriteWithMaxClause#rewrite(IndexReader, MultiTermQuery)}. That rewrite method is e.g.
* set for fuzzy queries with "constant_score" rewrite nested inside a `span_multi` query and would cause NPEs due to an unset
* {@link AttributeSource}.
*/
public void testIssueFuzzyInsideSpanMulti() {
createIndex("test");
client().prepareIndex("test", "_doc", "1").setSource("field", "foobarbaz").get();
ensureGreen();
refresh();
BoolQueryBuilder query = boolQuery().filter(spanMultiTermQueryBuilder(fuzzyQuery("field", "foobarbiz").rewrite("constant_score")));
SearchResponse response = client().prepareSearch("test").setQuery(query).get();
assertHitCount(response, 1);
}
}