From 65812fc154da7468ffc31360a993f907d820b8d1 Mon Sep 17 00:00:00 2001 From: Armin Date: Sat, 16 Sep 2017 20:42:57 +0200 Subject: [PATCH] #26083 Invalid JSON request body caused endless loop --- .../rest/action/RestActions.java | 9 ++++++ .../rest/action/RestActionsTests.java | 32 ++++++++++++++++--- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/rest/action/RestActions.java b/core/src/main/java/org/elasticsearch/rest/action/RestActions.java index 61e3ded6456b6..759cd4a773dd9 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/RestActions.java +++ b/core/src/main/java/org/elasticsearch/rest/action/RestActions.java @@ -243,6 +243,15 @@ public RestResponse buildResponse(NodesResponse response, XContentBuilder builde private static QueryBuilder parseTopLevelQueryBuilder(XContentParser parser) { try { QueryBuilder queryBuilder = null; + XContentParser.Token first = parser.nextToken(); + if (first == null) { + return null; + } else if (first != XContentParser.Token.START_OBJECT) { + throw new ParsingException( + parser.getTokenLocation(), "Expected [" + XContentParser.Token.START_OBJECT + + "] but found [" + first + "]", parser.getTokenLocation() + ); + } for (XContentParser.Token token = parser.nextToken(); token != XContentParser.Token.END_OBJECT; token = parser.nextToken()) { if (token == XContentParser.Token.FIELD_NAME) { String fieldName = parser.currentName(); diff --git a/core/src/test/java/org/elasticsearch/rest/action/RestActionsTests.java b/core/src/test/java/org/elasticsearch/rest/action/RestActionsTests.java index 7272243e3cf93..401cc79b02092 100644 --- a/core/src/test/java/org/elasticsearch/rest/action/RestActionsTests.java +++ b/core/src/test/java/org/elasticsearch/rest/action/RestActionsTests.java @@ -19,6 +19,8 @@ package org.elasticsearch.rest.action; +import com.fasterxml.jackson.core.io.JsonEOFException; +import java.util.Arrays; import org.elasticsearch.common.ParsingException; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.NamedXContentRegistry; @@ -59,10 +61,32 @@ public void testParseTopLevelBuilder() throws IOException { } public void testParseTopLevelBuilderEmptyObject() throws IOException { - String requestBody = "{}"; - try (XContentParser parser = createParser(JsonXContent.jsonXContent, requestBody)) { - QueryBuilder query = RestActions.getQueryContent(parser); - assertNull(query); + for (String requestBody : Arrays.asList("{}", "")) { + try (XContentParser parser = createParser(JsonXContent.jsonXContent, requestBody)) { + QueryBuilder query = RestActions.getQueryContent(parser); + assertNull(query); + } + } + } + + public void testParseTopLevelBuilderMalformedJson() throws IOException { + for (String requestBody : Arrays.asList("\"\"", "\"someString\"", "\"{\"")) { + try (XContentParser parser = createParser(JsonXContent.jsonXContent, requestBody)) { + ParsingException exception = + expectThrows(ParsingException.class, () -> RestActions.getQueryContent(parser)); + assertEquals("Expected [START_OBJECT] but found [VALUE_STRING]", exception.getMessage()); + } + } + } + + public void testParseTopLevelBuilderIncompleteJson() throws IOException { + for (String requestBody : Arrays.asList("{", "{ \"query\" :")) { + try (XContentParser parser = createParser(JsonXContent.jsonXContent, requestBody)) { + ParsingException exception = + expectThrows(ParsingException.class, () -> RestActions.getQueryContent(parser)); + assertEquals("Failed to parse", exception.getMessage()); + assertEquals(JsonEOFException.class, exception.getRootCause().getClass()); + } } }