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:
parent
16a8d5245f
commit
742d929b56
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
- do:
|
||||
mget:
|
||||
body:
|
||||
index: test_2
|
||||
docs:
|
||||
- { _index: test_1, _type: test, _id: 1}
|
||||
|
||||
|
|
Loading…
Reference in New Issue