From 8a587ead8972a7d68e1e3cab93e0b154913fe113 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Mon, 10 Aug 2015 21:56:33 -0700 Subject: [PATCH] Mappings: Validate parsed document does not have trailing garbage that is invalid json See #2315 --- .../elasticsearch/index/mapper/DocumentParser.java | 8 ++++++++ .../mapper/source/DefaultSourceMappingTests.java | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java b/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java index 6aa66f20d6f..9e60ef5caa8 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java @@ -25,6 +25,7 @@ import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexOptions; import org.apache.lucene.index.IndexableField; import org.apache.lucene.util.CloseableThreadLocal; +import org.elasticsearch.Version; import org.elasticsearch.common.Strings; import org.elasticsearch.common.joda.FormatDateTimeFormatter; import org.elasticsearch.common.settings.Settings; @@ -127,6 +128,13 @@ class DocumentParser implements Closeable { parser.nextToken(); } + // try to parse the next token, this should be null if the object is ended properly + // but will throw a JSON exception if the extra tokens is not valid JSON (this will be handled by the catch) + if (Version.indexCreated(indexSettings).onOrAfter(Version.V_2_0_0_beta1)) { + token = parser.nextToken(); + assert token == null; // double check, in tests, that we didn't end parsing early + } + for (MetadataFieldMapper metadataMapper : mapping.metadataMappers) { metadataMapper.postParse(context); } diff --git a/core/src/test/java/org/elasticsearch/index/mapper/source/DefaultSourceMappingTests.java b/core/src/test/java/org/elasticsearch/index/mapper/source/DefaultSourceMappingTests.java index 6e055f7403d..f6a4c30c863 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/source/DefaultSourceMappingTests.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/source/DefaultSourceMappingTests.java @@ -309,4 +309,18 @@ public class DefaultSourceMappingTests extends ESSingleNodeTestCase { .endObject().endObject().string(); assertFalse(parser.parse(mapping).sourceMapper().isComplete()); } + + public void testSourceObjectContainsExtraTokens() throws Exception { + String mapping = XContentFactory.jsonBuilder().startObject().startObject("type").endObject().endObject().string(); + DocumentMapper documentMapper = createIndex("test").mapperService().documentMapperParser().parse(mapping); + + try { + documentMapper.parse("test", "type", "1", new BytesArray("{}}")); // extra end object (invalid JSON) + fail("Expected parse exception"); + } catch (MapperParsingException e) { + assertNotNull(e.getRootCause()); + String message = e.getRootCause().getMessage(); + assertTrue(message, message.contains("Unexpected close marker '}'")); + } + } }