From 195c8ec9036905a23f74a21faa24ade9e43fabe9 Mon Sep 17 00:00:00 2001 From: Alexander Reelsen Date: Mon, 13 Jul 2015 09:59:03 +0200 Subject: [PATCH] Term Query: Be more strict during parsing The term query parser was too lenient during parsing and allowed to specify more than one field, even though this expected to filter only for a single field. This commit returns an exception if a query has been specified more than once. Closes #12184 --- .../index/query/TermQueryParser.java | 6 +++++ .../query/SimpleIndexQueryParserTests.java | 22 +++++++++++++++++++ .../term-filter-broken-multi-terms-2.json | 10 +++++++++ .../query/term-filter-broken-multi-terms.json | 10 +++++++++ 4 files changed, 48 insertions(+) create mode 100644 core/src/test/java/org/elasticsearch/index/query/term-filter-broken-multi-terms-2.json create mode 100644 core/src/test/java/org/elasticsearch/index/query/term-filter-broken-multi-terms.json diff --git a/core/src/main/java/org/elasticsearch/index/query/TermQueryParser.java b/core/src/main/java/org/elasticsearch/index/query/TermQueryParser.java index 318017757ef..be74053bc71 100644 --- a/core/src/main/java/org/elasticsearch/index/query/TermQueryParser.java +++ b/core/src/main/java/org/elasticsearch/index/query/TermQueryParser.java @@ -63,6 +63,9 @@ public class TermQueryParser implements QueryParser { // skip } else if (token == XContentParser.Token.START_OBJECT) { // also support a format of "term" : {"field_name" : { ... }} + if (fieldName != null) { + throw new QueryParsingException(parseContext, "[term] query does not support different field names, use [bool] query instead"); + } fieldName = currentFieldName; while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) { if (token == XContentParser.Token.FIELD_NAME) { @@ -87,6 +90,9 @@ public class TermQueryParser implements QueryParser { } else if ("boost".equals(currentFieldName)) { boost = parser.floatValue(); } else { + if (fieldName != null) { + throw new QueryParsingException(parseContext, "[term] query does not support different field names, use [bool] query instead"); + } fieldName = currentFieldName; value = parser.objectBytes(); } diff --git a/core/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java b/core/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java index db30948c4c1..e8c73dfd0a9 100644 --- a/core/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java +++ b/core/src/test/java/org/elasticsearch/index/query/SimpleIndexQueryParserTests.java @@ -1204,6 +1204,28 @@ public class SimpleIndexQueryParserTests extends ElasticsearchSingleNodeTest { assertEquals(expected, parsedQuery.query()); } + @Test + public void testTermQueryParserShouldOnlyAllowSingleTerm() throws Exception { + String query = copyToStringFromClasspath("/org/elasticsearch/index/query/term-filter-broken-multi-terms.json"); + assertQueryParsingFailureDueToMultipleTermsInTermFilter(query); + } + + @Test + public void testTermQueryParserShouldOnlyAllowSingleTermInAlternateFormat() throws Exception { + String query = copyToStringFromClasspath("/org/elasticsearch/index/query/term-filter-broken-multi-terms-2.json"); + assertQueryParsingFailureDueToMultipleTermsInTermFilter(query); + } + + private void assertQueryParsingFailureDueToMultipleTermsInTermFilter(String query) throws IOException { + IndexQueryParserService queryParser = queryParser(); + try { + queryParser.parse(query); + fail("Expected Query Parsing Exception but did not happen"); + } catch (QueryParsingException e) { + assertThat(e.getMessage(), containsString("[term] query does not support different field names, use [bool] query instead")); + } + } + @Test public void testTermsFilterQueryBuilder() throws Exception { IndexQueryParserService queryParser = queryParser(); diff --git a/core/src/test/java/org/elasticsearch/index/query/term-filter-broken-multi-terms-2.json b/core/src/test/java/org/elasticsearch/index/query/term-filter-broken-multi-terms-2.json new file mode 100644 index 00000000000..b71de530533 --- /dev/null +++ b/core/src/test/java/org/elasticsearch/index/query/term-filter-broken-multi-terms-2.json @@ -0,0 +1,10 @@ +{ + "filtered": { + "filter": { + "term": { + "name.first": { "value": "shay" }, + "name.last": { "value": "banon" } + } + } + } +} \ No newline at end of file diff --git a/core/src/test/java/org/elasticsearch/index/query/term-filter-broken-multi-terms.json b/core/src/test/java/org/elasticsearch/index/query/term-filter-broken-multi-terms.json new file mode 100644 index 00000000000..aabd6e48376 --- /dev/null +++ b/core/src/test/java/org/elasticsearch/index/query/term-filter-broken-multi-terms.json @@ -0,0 +1,10 @@ +{ + "filtered":{ + "query":{ + "term":{ + "name.first": "shay", + "name.last" : "banon" + } + } + } +} \ No newline at end of file