Validate top-level keys when parsing mget requests

Today, when parsing mget requests, we silently ignore keys in the top
level that do not match "docs" or "ids". This commit addresses this
situation by throwing an exception if any other key occurs here, and
providing the names of valid keys.

Relates #23746
This commit is contained in:
Jason Tedor 2017-03-28 08:27:31 -04:00 committed by GitHub
parent 16a8d5245f
commit 742d929b56
3 changed files with 89 additions and 1 deletions

View File

@ -44,6 +44,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
public class MultiGetRequest extends ActionRequest implements Iterable<MultiGetRequest.Item>, CompositeIndicesRequest, RealtimeRequest {
@ -319,6 +320,14 @@ public class MultiGetRequest extends ActionRequest implements Iterable<MultiGetR
boolean allowExplicitIndex) throws IOException {
XContentParser.Token token;
String currentFieldName = null;
if ((token = parser.nextToken()) != XContentParser.Token.START_OBJECT) {
final String message = String.format(
Locale.ROOT,
"unexpected token [%s], expected [%s]",
token,
XContentParser.Token.START_OBJECT);
throw new ParsingException(parser.getTokenLocation(), message);
}
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
if (token == XContentParser.Token.FIELD_NAME) {
currentFieldName = parser.currentName();
@ -327,7 +336,22 @@ public class MultiGetRequest extends ActionRequest implements Iterable<MultiGetR
parseDocuments(parser, this.items, defaultIndex, defaultType, defaultFields, defaultFetchSource, defaultRouting, allowExplicitIndex);
} else if ("ids".equals(currentFieldName)) {
parseIds(parser, this.items, defaultIndex, defaultType, defaultFields, defaultFetchSource, defaultRouting);
} else {
final String message = String.format(
Locale.ROOT,
"unknown key [%s] for a %s, expected [docs] or [ids]",
currentFieldName,
token);
throw new ParsingException(parser.getTokenLocation(), message);
}
} else {
final String message = String.format(
Locale.ROOT,
"unexpected token [%s], expected [%s] or [%s]",
token,
XContentParser.Token.FIELD_NAME,
XContentParser.Token.START_ARRAY);
throw new ParsingException(parser.getTokenLocation(), message);
}
}
return this;

View File

@ -19,13 +19,78 @@
package org.elasticsearch.action.get;
import org.elasticsearch.common.ParsingException;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
import static org.hamcrest.Matchers.containsString;
public class MultiGetRequestTests extends ESTestCase {
public void testAddWithInvalidKey() throws IOException {
final XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
{
builder.startArray("doc");
{
builder.startObject();
{
builder.field("_type", "type");
builder.field("_id", "1");
}
builder.endObject();
}
builder.endArray();
}
builder.endObject();
final XContentParser parser = createParser(builder);
final MultiGetRequest mgr = new MultiGetRequest();
final ParsingException e = expectThrows(
ParsingException.class,
() -> {
final String defaultIndex = randomAsciiOfLength(5);
final String defaultType = randomAsciiOfLength(3);
final FetchSourceContext fetchSource = FetchSourceContext.FETCH_SOURCE;
mgr.add(defaultIndex, defaultType, null, fetchSource, null, parser, true);
});
assertThat(
e.toString(),
containsString("unknown key [doc] for a START_ARRAY, expected [docs] or [ids]"));
}
public void testUnexpectedField() throws IOException {
final XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
{
builder.startObject("docs");
{
builder.field("_type", "type");
builder.field("_id", "1");
}
builder.endObject();
}
builder.endObject();
final XContentParser parser = createParser(builder);
final MultiGetRequest mgr = new MultiGetRequest();
final ParsingException e = expectThrows(
ParsingException.class,
() -> {
final String defaultIndex = randomAsciiOfLength(5);
final String defaultType = randomAsciiOfLength(3);
final FetchSourceContext fetchSource = FetchSourceContext.FETCH_SOURCE;
mgr.add(defaultIndex, defaultType, null, fetchSource, null, parser, true);
});
assertThat(
e.toString(),
containsString(
"unexpected token [START_OBJECT], expected [FIELD_NAME] or [START_ARRAY]"));
}
public void testAddWithInvalidSourceValueIsRejected() throws Exception {
String sourceValue = randomFrom("on", "off", "0", "1");
XContentParser parser = createParser(XContentFactory.jsonBuilder()

View File

@ -21,7 +21,6 @@
- do:
mget:
body:
index: test_2
docs:
- { _index: test_1, _type: test, _id: 1}