Skip to content

Commit

Permalink
Fix potential NPE in FuzzyTermsEnum (#53231)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Christoph Büscher authored Mar 9, 2020
1 parent 1c8ab01 commit 649a228
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
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;
Expand Down Expand Up @@ -92,11 +93,12 @@ private Collection<SpanQuery> collectTerms(IndexReader reader, MultiTermQuery qu
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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -28,6 +31,7 @@
import org.elasticsearch.action.search.ShardSearchFailure;
import org.elasticsearch.bootstrap.JavaVersion;
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.unit.Fuzziness;
Expand Down Expand Up @@ -1758,4 +1762,20 @@ public void testFieldAliasesForMetaFields() throws Exception {
}

}

/**
* 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").setId("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);
}
}

0 comments on commit 649a228

Please sign in to comment.