From 6952f7b5606504666ccac3edb68f43d04d3ebd44 Mon Sep 17 00:00:00 2001 From: olcbean Date: Tue, 26 Sep 2017 18:49:20 +0200 Subject: [PATCH] Validate top-level keys for create index request (#23755) (#23869) This commit ensures create index requests do not ignore unknown keys passed to the request. closes #23755 --- .../indices/create/CreateIndexRequest.java | 12 ++---- .../CreateIndexRequestBuilderTests.java | 15 ++++++-- .../create/CreateIndexRequestTests.java | 24 ++++++++++++ .../compound-word-tokenfilter.asciidoc | 38 ++++++++++--------- .../test/store_smb/15_index_creation.yml | 5 ++- .../cluster.allocation_explain/10_basic.yml | 2 +- 6 files changed, 63 insertions(+), 33 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java b/core/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java index eb0ede3c3f3..2d320b094b2 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java +++ b/core/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java @@ -374,38 +374,32 @@ public class CreateIndexRequest extends AcknowledgedRequest */ @SuppressWarnings("unchecked") public CreateIndexRequest source(Map source) { - boolean found = false; for (Map.Entry entry : source.entrySet()) { String name = entry.getKey(); if (name.equals("settings")) { - found = true; settings((Map) entry.getValue()); } else if (name.equals("mappings")) { - found = true; Map mappings = (Map) entry.getValue(); for (Map.Entry entry1 : mappings.entrySet()) { mapping(entry1.getKey(), (Map) entry1.getValue()); } } else if (name.equals("aliases")) { - found = true; aliases((Map) entry.getValue()); } else { // maybe custom? IndexMetaData.Custom proto = IndexMetaData.lookupPrototype(name); if (proto != null) { - found = true; try { customs.put(name, proto.fromMap((Map) entry.getValue())); } catch (IOException e) { throw new ElasticsearchParseException("failed to parse custom metadata for [{}]", name); } + } else { + // found a key which is neither custom defined nor one of the supported ones + throw new ElasticsearchParseException("unknown key [{}] for create index", name); } } } - if (!found) { - // the top level are settings, use them - settings(source); - } return this; } diff --git a/core/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequestBuilderTests.java b/core/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequestBuilderTests.java index db273faf7f2..2dd8a8343c5 100644 --- a/core/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequestBuilderTests.java +++ b/core/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequestBuilderTests.java @@ -19,6 +19,7 @@ package org.elasticsearch.action.admin.indices.create; +import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; @@ -31,6 +32,7 @@ import org.junit.Before; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.HashMap; +import java.util.Locale; import java.util.Map; public class CreateIndexRequestBuilderTests extends ESTestCase { @@ -58,16 +60,23 @@ public class CreateIndexRequestBuilderTests extends ESTestCase { */ public void testSetSource() throws IOException { CreateIndexRequestBuilder builder = new CreateIndexRequestBuilder(this.testClient, CreateIndexAction.INSTANCE); - builder.setSource("{\""+KEY+"\" : \""+VALUE+"\"}", XContentType.JSON); + + ElasticsearchParseException e = expectThrows(ElasticsearchParseException.class, + () -> {builder.setSource("{\""+KEY+"\" : \""+VALUE+"\"}", XContentType.JSON);}); + assertEquals(String.format(Locale.ROOT, "unknown key [%s] for create index", KEY), e.getMessage()); + + builder.setSource("{\"settings\" : {\""+KEY+"\" : \""+VALUE+"\"}}", XContentType.JSON); assertEquals(VALUE, builder.request().settings().get(KEY)); - XContentBuilder xContent = XContentFactory.jsonBuilder().startObject().field(KEY, VALUE).endObject(); + XContentBuilder xContent = XContentFactory.jsonBuilder().startObject() + .startObject("settings").field(KEY, VALUE).endObject().endObject(); xContent.close(); builder.setSource(xContent); assertEquals(VALUE, builder.request().settings().get(KEY)); ByteArrayOutputStream docOut = new ByteArrayOutputStream(); - XContentBuilder doc = XContentFactory.jsonBuilder(docOut).startObject().field(KEY, VALUE).endObject(); + XContentBuilder doc = XContentFactory.jsonBuilder(docOut).startObject() + .startObject("settings").field(KEY, VALUE).endObject().endObject(); doc.close(); builder.setSource(docOut.toByteArray(), XContentType.JSON); assertEquals(VALUE, builder.request().settings().get(KEY)); diff --git a/core/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequestTests.java b/core/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequestTests.java index 74a87497181..4acdfd636bf 100644 --- a/core/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequestTests.java +++ b/core/src/test/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequestTests.java @@ -19,6 +19,7 @@ package org.elasticsearch.action.admin.indices.create; +import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.common.io.stream.BytesStreamOutput; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.xcontent.XContentType; @@ -45,4 +46,27 @@ public class CreateIndexRequestTests extends ESTestCase { } } } + + public void testTopLevelKeys() throws IOException { + String createIndex = + "{\n" + + " \"FOO_SHOULD_BE_ILLEGAL_HERE\": {\n" + + " \"BAR_IS_THE_SAME\": 42\n" + + " },\n" + + " \"mappings\": {\n" + + " \"test\": {\n" + + " \"properties\": {\n" + + " \"field1\": {\n" + + " \"type\": \"text\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + "}"; + + CreateIndexRequest request = new CreateIndexRequest(); + ElasticsearchParseException e = expectThrows(ElasticsearchParseException.class, + () -> {request.source(createIndex, XContentType.JSON);}); + assertEquals("unknown key [FOO_SHOULD_BE_ILLEGAL_HERE] for create index", e.getMessage()); + } } diff --git a/docs/reference/analysis/tokenfilters/compound-word-tokenfilter.asciidoc b/docs/reference/analysis/tokenfilters/compound-word-tokenfilter.asciidoc index e790ed4c4b5..d200c0b988b 100644 --- a/docs/reference/analysis/tokenfilters/compound-word-tokenfilter.asciidoc +++ b/docs/reference/analysis/tokenfilters/compound-word-tokenfilter.asciidoc @@ -86,25 +86,27 @@ Here is an example: -------------------------------------------------- PUT /compound_word_example { - "index": { - "analysis": { - "analyzer": { - "my_analyzer": { - "type": "custom", - "tokenizer": "standard", - "filter": ["dictionary_decompounder", "hyphenation_decompounder"] - } - }, - "filter": { - "dictionary_decompounder": { - "type": "dictionary_decompounder", - "word_list": ["one", "two", "three"] + "settings": { + "index": { + "analysis": { + "analyzer": { + "my_analyzer": { + "type": "custom", + "tokenizer": "standard", + "filter": ["dictionary_decompounder", "hyphenation_decompounder"] + } }, - "hyphenation_decompounder": { - "type" : "hyphenation_decompounder", - "word_list_path": "analysis/example_word_list.txt", - "hyphenation_patterns_path": "analysis/hyphenation_patterns.xml", - "max_subword_size": 22 + "filter": { + "dictionary_decompounder": { + "type": "dictionary_decompounder", + "word_list": ["one", "two", "three"] + }, + "hyphenation_decompounder": { + "type" : "hyphenation_decompounder", + "word_list_path": "analysis/example_word_list.txt", + "hyphenation_patterns_path": "analysis/hyphenation_patterns.xml", + "max_subword_size": 22 + } } } } diff --git a/plugins/store-smb/src/test/resources/rest-api-spec/test/store_smb/15_index_creation.yml b/plugins/store-smb/src/test/resources/rest-api-spec/test/store_smb/15_index_creation.yml index d036176e320..53b036b6682 100644 --- a/plugins/store-smb/src/test/resources/rest-api-spec/test/store_smb/15_index_creation.yml +++ b/plugins/store-smb/src/test/resources/rest-api-spec/test/store_smb/15_index_creation.yml @@ -3,8 +3,9 @@ indices.create: index: smb-test body: - index: - store.type: smb_mmap_fs + settings: + index: + store.type: smb_mmap_fs - do: index: diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.allocation_explain/10_basic.yml b/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.allocation_explain/10_basic.yml index 63724be1331..e88093c5c11 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.allocation_explain/10_basic.yml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.allocation_explain/10_basic.yml @@ -47,7 +47,7 @@ - do: indices.create: index: test - body: { "index.number_of_shards": 1, "index.number_of_replicas": 9 } + body: { "settings": { "index.number_of_shards": 1, "index.number_of_replicas": 9 } } - do: cluster.state: