From 60df3450f4373d4561bf51c1b83a76be1e102a1b Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Thu, 14 Apr 2016 14:45:29 -0700 Subject: [PATCH] Mappings: Fix array parsing to remove its context when finished parsing Handling of the current path when parsing a document is very sensitive. This fixes a subtle bug in array parsing, where the path that was added by parsing an array would not be cleared. It also adds a hard state check at the end of parsing to ensure we ended with a clean path. --- .../index/mapper/DocumentParser.java | 5 +++++ .../index/mapper/DocumentParserTests.java | 18 ++++++++++++++++++ 2 files changed, 23 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 70219516147..750d77604a4 100644 --- a/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java +++ b/core/src/main/java/org/elasticsearch/index/mapper/DocumentParser.java @@ -97,6 +97,10 @@ final class DocumentParser implements Closeable { parser.close(); } } + String remainingPath = context.path().pathAsText(""); + if (remainingPath.isEmpty() == false) { + throw new IllegalStateException("found leftover path elements: " + remainingPath); + } reverseOrder(context); @@ -553,6 +557,7 @@ final class DocumentParser implements Closeable { context.addDynamicMapper(mapper); context.path().add(arrayFieldName); parseObjectOrField(context, mapper); + context.path().remove(); } else { parseNonDynamicArray(context, parentMapper, lastFieldName, arrayFieldName); } diff --git a/core/src/test/java/org/elasticsearch/index/mapper/DocumentParserTests.java b/core/src/test/java/org/elasticsearch/index/mapper/DocumentParserTests.java index e4d1e306af3..7a30df9a46d 100644 --- a/core/src/test/java/org/elasticsearch/index/mapper/DocumentParserTests.java +++ b/core/src/test/java/org/elasticsearch/index/mapper/DocumentParserTests.java @@ -178,4 +178,22 @@ public class DocumentParserTests extends ESSingleNodeTestCase { assertTrue(barMapper instanceof ObjectMapper); assertNotNull(((ObjectMapper)barMapper).getMapper("baz")); } + + public void testDynamicArrayWithTemplate() throws Exception { + DocumentMapperParser mapperParser = createIndex("test").mapperService().documentMapperParser(); + String mapping = XContentFactory.jsonBuilder().startObject().startObject("type") + .startArray("dynamic_templates").startObject().startObject("georule") + .field("match", "foo*") + .startObject("mapping").field("type", "geo_point").endObject() + .endObject().endObject().endArray().endObject().endObject().string(); + DocumentMapper mapper = mapperParser.parse("type", new CompressedXContent(mapping)); + + BytesReference bytes = XContentFactory.jsonBuilder() + .startObject().startArray("foo") + .startArray().value(0).value(0).endArray() + .startArray().value(1).value(1).endArray() + .endArray().endObject().bytes(); + ParsedDocument doc = mapper.parse("test", "type", "1", bytes); + assertEquals(2, doc.rootDoc().getFields("foo").length); + } }