Browse Source

Fix bug in the Settings#processSetting method

The Settings#processSetting method is intended to take a setting map and add a
setting to it, adjusting the keys as it goes in case of "conflicts" where the
new setting implies an object where there is currently a string, or vice
versa. processSetting was failing in two cases: adding a setting two levels
under a string, and adding a setting two levels under a string and four levels
under a map. This commit fixes the bug and adds test coverage for the
previously faulty edge cases.

* fix issue #43791 about settings
* add unit test in testProcessSetting()
kkewwei 6 years ago
parent
commit
de34d72b41

+ 2 - 2
server/src/main/java/org/elasticsearch/common/settings/Settings.java

@@ -144,13 +144,13 @@ public final class Settings implements ToXContentFragment {
             if (existingValue == null) {
                 Map<String, Object> newMap = new HashMap<>(2);
                 processSetting(newMap, "", rest, value);
-                map.put(key, newMap);
+                map.put(prefix + key, newMap);
             } else {
                 if (existingValue instanceof Map) {
                     @SuppressWarnings("unchecked")
                     Map<String, Object> innerMap = (Map<String, Object>) existingValue;
                     processSetting(innerMap, "", rest, value);
-                    map.put(key, innerMap);
+                    map.put(prefix + key, innerMap);
                 } else {
                     // It supposed to be a map, but we already have a value stored, which is not a map
                     // fall back to "." notation

+ 24 - 0
server/src/test/java/org/elasticsearch/common/settings/SettingsTests.java

@@ -705,4 +705,28 @@ public class SettingsTests extends ESTestCase {
         assertThat(actual, equalTo(expected));
     }
 
+    public void testProcessSetting() throws IOException {
+        Settings test = Settings.builder()
+            .put("ant", "value1")
+            .put("ant.bee.cat", "value2")
+            .put("bee.cat", "value3")
+            .build();
+        XContentBuilder builder = XContentBuilder.builder(XContentType.JSON.xContent());
+        builder.startObject();
+        test.toXContent(builder, new ToXContent.MapParams(Collections.emptyMap()));
+        builder.endObject();
+        assertEquals("{\"ant.bee\":{\"cat\":\"value2\"},\"ant\":\"value1\",\"bee\":{\"cat\":\"value3\"}}", Strings.toString(builder));
+
+        test = Settings.builder()
+            .put("ant", "value1")
+            .put("ant.bee.cat", "value2")
+            .put("ant.bee.cat.dog.ewe", "value3")
+            .build();
+        builder = XContentBuilder.builder(XContentType.JSON.xContent());
+        builder.startObject();
+        test.toXContent(builder, new ToXContent.MapParams(Collections.emptyMap()));
+        builder.endObject();
+        assertEquals("{\"ant.bee\":{\"cat.dog\":{\"ewe\":\"value3\"},\"cat\":\"value2\"},\"ant\":\"value1\"}", Strings.toString(builder));
+    }
+
 }