Skip to content

Commit 329d05f

Browse files
committed
Fix UOE on search requests that match a sparse role query (elastic#43668)
Search requests executed through the SecurityIndexSearcherWrapper throw an UnsupportedOperationException if they match a sparse role query. When low level cancellation is activated (which is the default since elastic#42857), the context index searcher creates a weight that doesn't handle #scorer. This change fixes this bug and adds a test to ensure that we check this case.
1 parent cd4f81e commit 329d05f

File tree

2 files changed

+11
-4
lines changed

2 files changed

+11
-4
lines changed

server/src/main/java/org/elasticsearch/search/internal/ContextIndexSearcher.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,14 @@ public Explanation explain(LeafReaderContext context, int doc) throws IOExceptio
152152
}
153153

154154
@Override
155-
public Scorer scorer(LeafReaderContext context) throws IOException {
155+
public boolean isCacheable(LeafReaderContext ctx) {
156156
throw new UnsupportedOperationException();
157157
}
158158

159159
@Override
160-
public boolean isCacheable(LeafReaderContext ctx) {
161-
throw new UnsupportedOperationException();
160+
public Scorer scorer(LeafReaderContext context) throws IOException {
161+
// in case the wrapped searcher (in) uses the scorer directly
162+
return weight.scorer(context);
162163
}
163164

164165
@Override

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/accesscontrol/SecurityIndexSearcherWrapperUnitTests.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import org.elasticsearch.index.Index;
4444
import org.elasticsearch.index.IndexSettings;
4545
import org.elasticsearch.index.cache.bitset.BitsetFilterCache;
46+
import org.elasticsearch.index.engine.Engine;
4647
import org.elasticsearch.index.mapper.FieldNamesFieldMapper;
4748
import org.elasticsearch.index.mapper.MapperService;
4849
import org.elasticsearch.index.mapper.SeqNoFieldMapper;
@@ -52,6 +53,7 @@
5253
import org.elasticsearch.license.XPackLicenseState;
5354
import org.elasticsearch.script.ScriptService;
5455
import org.elasticsearch.search.aggregations.LeafBucketCollector;
56+
import org.elasticsearch.search.internal.ContextIndexSearcher;
5557
import org.elasticsearch.test.ESTestCase;
5658
import org.elasticsearch.test.IndexSettingsModule;
5759
import org.elasticsearch.xpack.core.security.authz.accesscontrol.DocumentSubsetReader.DocumentSubsetDirectoryReader;
@@ -537,7 +539,11 @@ public void onRemoval(ShardId shardId, Accountable accountable) {
537539
}
538540

539541
DocumentSubsetDirectoryReader filteredReader = DocumentSubsetReader.wrap(reader, cache, roleQuery);
540-
IndexSearcher searcher = new SecurityIndexSearcherWrapper.IndexSearcherWrapper(filteredReader);
542+
IndexSearcher wrapSearcher = new SecurityIndexSearcherWrapper.IndexSearcherWrapper(filteredReader);
543+
Engine.Searcher engineSearcher = new Engine.Searcher("test", wrapSearcher, () -> {});
544+
ContextIndexSearcher searcher = new ContextIndexSearcher(engineSearcher,
545+
wrapSearcher.getQueryCache(), wrapSearcher.getQueryCachingPolicy());
546+
searcher.setCheckCancelled(() -> {});
541547

542548
// Searching a non-existing term will trigger a null scorer
543549
assertEquals(0, searcher.count(new TermQuery(new Term("non_existing_field", "non_existing_value"))));

0 commit comments

Comments
 (0)