Core: Check if from + size don't cause overflow and fail with a better error.

Closes #7778
This commit is contained in:
Martijn van Groningen 2014-09-18 12:25:48 +02:00
parent dbe4e6e674
commit afcbffbfc1
3 changed files with 29 additions and 0 deletions

View File

@ -63,6 +63,7 @@ import org.elasticsearch.search.fetch.script.ScriptFieldsContext;
import org.elasticsearch.search.fetch.source.FetchSourceContext;
import org.elasticsearch.search.highlight.SearchContextHighlight;
import org.elasticsearch.search.lookup.SearchLookup;
import org.elasticsearch.search.query.QueryPhaseExecutionException;
import org.elasticsearch.search.query.QuerySearchResult;
import org.elasticsearch.search.rescore.RescoreSearchContext;
import org.elasticsearch.search.scan.ScanContext;
@ -213,6 +214,15 @@ public class DefaultSearchContext extends SearchContext {
* Should be called before executing the main query and after all other parameters have been set.
*/
public void preProcess() {
if (!(from() == -1 && size() == -1)) {
// from and size have been set.
int numHits = from() + size();
if (numHits < 0) {
String msg = "Result window is too large, from + size must be less than or equal to: [" + Integer.MAX_VALUE + "] but was [" + (((long) from()) + ((long) size())) + "]";
throw new QueryPhaseExecutionException(this, msg);
}
}
if (query() == null) {
parsedQuery(ParsedQuery.parsedMatchAllQuery());
}

View File

@ -30,4 +30,8 @@ public class QueryPhaseExecutionException extends SearchContextException {
public QueryPhaseExecutionException(SearchContext context, String msg, Throwable cause) {
super(context, "Query Failed [" + msg + "]", cause);
}
public QueryPhaseExecutionException(SearchContext context, String msg) {
super(context, msg);
}
}

View File

@ -21,6 +21,7 @@ package org.elasticsearch.search.simple;
import org.elasticsearch.ElasticsearchIllegalArgumentException;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchPhaseExecutionException;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.xcontent.XContentFactory;
@ -39,6 +40,7 @@ import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.*;
import static org.hamcrest.Matchers.containsString;
public class SimpleSearchTests extends ElasticsearchIntegrationTest {
@ -244,4 +246,17 @@ public class SimpleSearchTests extends ElasticsearchIntegrationTest {
assertHitCount(searchResponse, max);
assertFalse(searchResponse.isTerminatedEarly());
}
@Test
public void testInsaneFrom() throws Exception {
createIndex("idx");
indexRandom(true, client().prepareIndex("idx", "type").setSource("{}"));
try {
client().prepareSearch("idx").setFrom(Integer.MAX_VALUE).get();
fail();
} catch (SearchPhaseExecutionException e) {
assertThat(e.getMessage(), containsString("Result window is too large, from + size must be less than or equal to:"));
}
}
}