Be stricter parsing ids for ids query

Adds a check to make sure that all ids in the query are either strings
or numbers. This is to prevent the case where a user accidentally
specifies:

"ids": [["1", "2"]]

(note the double array)

With this change, an exception will be thrown since the second "[" is
not a string or number, it is a Token.START_ARRAY.

Fixes #7686
This commit is contained in:
Lee Hinman 2014-10-01 10:23:47 +02:00
parent 50923a764c
commit 9c8beb8220
2 changed files with 30 additions and 5 deletions

View File

@ -70,11 +70,17 @@ public class IdsQueryParser implements QueryParser {
if ("values".equals(currentFieldName)) { if ("values".equals(currentFieldName)) {
idsProvided = true; idsProvided = true;
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) { while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
BytesRef value = parser.utf8BytesOrNull(); if ((token == XContentParser.Token.VALUE_STRING) ||
if (value == null) { (token == XContentParser.Token.VALUE_NUMBER)) {
throw new QueryParsingException(parseContext.index(), "No value specified for term filter"); BytesRef value = parser.utf8BytesOrNull();
if (value == null) {
throw new QueryParsingException(parseContext.index(), "No value specified for term filter");
}
ids.add(value);
} else {
throw new QueryParsingException(parseContext.index(),
"Illegal value for id, expecting a string or number, got: " + token);
} }
ids.add(value);
} }
} else if ("types".equals(currentFieldName) || "type".equals(currentFieldName)) { } else if ("types".equals(currentFieldName) || "type".equals(currentFieldName)) {
types = new ArrayList<>(); types = new ArrayList<>();
@ -125,4 +131,3 @@ public class IdsQueryParser implements QueryParser {
return query; return query;
} }
} }

View File

@ -2700,4 +2700,24 @@ public class SimpleQueryTests extends ElasticsearchIntegrationTest {
} }
} }
@Test // see #7686.
public void testIdsQueryWithInvalidValues() throws Exception {
createIndex("test");
indexRandom(true, false, client().prepareIndex("test", "type", "1").setSource("body", "foo"));
try {
client().prepareSearch("test")
.setTypes("type")
.setQuery("{\n" +
" \"ids\": {\n" +
" \"values\": [[\"1\"]]\n" +
" }\n" +
"}")
.get();
fail("query is invalid and should have produced a parse exception");
} catch (Exception e) {
assertThat("query could not be parsed due to bad format: " + e.getMessage(),
e.getMessage().contains("Illegal value for id, expecting a string or number, got: START_ARRAY"),
equalTo(true));
}
}
} }