Skip to content

Commit 99c50ee

Browse files
authored
Set processor's copy_from should deep copy non-primitive mutable types (#69349) (#69871)
1 parent 939cbe5 commit 99c50ee

File tree

3 files changed

+65
-2
lines changed

3 files changed

+65
-2
lines changed

modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/SetProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public IngestDocument execute(IngestDocument document) {
7373
if (overrideEnabled || document.hasField(field) == false || document.getFieldValue(field, Object.class) == null) {
7474
if (copyFrom != null) {
7575
Object fieldValue = document.getFieldValue(copyFrom, Object.class, ignoreEmptyValue);
76-
document.setFieldValue(field, fieldValue, ignoreEmptyValue);
76+
document.setFieldValue(field, IngestDocument.deepCopy(fieldValue), ignoreEmptyValue);
7777
} else {
7878
document.setFieldValue(field, value, ignoreEmptyValue);
7979
}

modules/ingest-common/src/test/java/org/elasticsearch/ingest/common/SetProcessorTests.java

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,13 @@
1717
import org.elasticsearch.test.ESTestCase;
1818
import org.hamcrest.Matchers;
1919

20+
import java.util.ArrayList;
21+
import java.util.Date;
2022
import java.util.HashMap;
23+
import java.util.HashSet;
24+
import java.util.List;
2125
import java.util.Map;
26+
import java.util.Set;
2227

2328
import static org.hamcrest.Matchers.equalTo;
2429

@@ -144,6 +149,64 @@ public void testCopyFromOtherField() throws Exception {
144149
assertThat(ingestDocument.getFieldValue(fieldName, Object.class), equalTo(fieldValue));
145150
}
146151

152+
public void testCopyFromDeepCopiesNonPrimitiveMutableTypes() throws Exception {
153+
final String originalField = "originalField";
154+
final String targetField = "targetField";
155+
Processor processor = createSetProcessor(targetField, null, originalField, true, false);
156+
157+
// map types
158+
Map<String, Object> document = new HashMap<>();
159+
Map<String, Object> originalMap = new HashMap<>();
160+
originalMap.put("foo", "bar");
161+
document.put(originalField, originalMap);
162+
IngestDocument ingestDocument = RandomDocumentPicks.randomIngestDocument(random(), document);
163+
IngestDocument output = processor.execute(ingestDocument);
164+
originalMap.put("foo", "not-bar");
165+
Map<?, ?> outputMap = output.getFieldValue(targetField, Map.class);
166+
assertThat(outputMap.get("foo"), equalTo("bar"));
167+
168+
// set types
169+
document = new HashMap<>();
170+
Set<String> originalSet = randomUnique(() -> randomAlphaOfLength(5), 5);
171+
Set<String> preservedSet = new HashSet<>(originalSet);
172+
document.put(originalField, originalSet);
173+
ingestDocument = RandomDocumentPicks.randomIngestDocument(random(), document);
174+
processor.execute(ingestDocument);
175+
originalSet.add(randomValueOtherThanMany(originalSet::contains, () -> randomAlphaOfLength(5)));
176+
assertThat(ingestDocument.getFieldValue(targetField, Object.class), equalTo(preservedSet));
177+
178+
// list types
179+
document = new HashMap<>();
180+
List<String> originalList = randomList(1, 5, () -> randomAlphaOfLength(5));
181+
List<String> preservedList = new ArrayList<>(originalList);
182+
document.put(originalField, originalList);
183+
ingestDocument = RandomDocumentPicks.randomIngestDocument(random(), document);
184+
processor.execute(ingestDocument);
185+
originalList.add(randomValueOtherThanMany(originalList::contains, () -> randomAlphaOfLength(5)));
186+
assertThat(ingestDocument.getFieldValue(targetField, Object.class), equalTo(preservedList));
187+
188+
// byte[] types
189+
document = new HashMap<>();
190+
byte[] originalBytes = randomByteArrayOfLength(10);
191+
byte[] preservedBytes = new byte[originalBytes.length];
192+
System.arraycopy(originalBytes, 0, preservedBytes, 0, originalBytes.length);
193+
document.put(originalField, originalBytes);
194+
ingestDocument = RandomDocumentPicks.randomIngestDocument(random(), document);
195+
processor.execute(ingestDocument);
196+
originalBytes[0] = originalBytes[0] == 0 ? (byte) 1 : (byte) 0;
197+
assertThat(ingestDocument.getFieldValue(targetField, Object.class), equalTo(preservedBytes));
198+
199+
// Date types
200+
document = new HashMap<>();
201+
Date originalDate = new Date();
202+
Date preservedDate = new Date(originalDate.getTime());
203+
document.put(originalField, originalDate);
204+
ingestDocument = RandomDocumentPicks.randomIngestDocument(random(), document);
205+
processor.execute(ingestDocument);
206+
originalDate.setTime(originalDate.getTime() + 1);
207+
assertThat(ingestDocument.getFieldValue(targetField, Object.class), equalTo(preservedDate));
208+
}
209+
147210
private static Processor createSetProcessor(String fieldName, Object fieldValue, String copyFrom, boolean overrideEnabled,
148211
boolean ignoreEmptyValue) {
149212
return new SetProcessor(randomAlphaOfLength(10), null, new TestTemplateService.MockTemplateScript.Factory(fieldName),

server/src/main/java/org/elasticsearch/ingest/IngestDocument.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -716,7 +716,7 @@ public static <K, V> Map<K, V> deepCopyMap(Map<K, V> source) {
716716
return (Map<K, V>) deepCopy(source);
717717
}
718718

719-
private static Object deepCopy(Object value) {
719+
public static Object deepCopy(Object value) {
720720
if (value instanceof Map) {
721721
Map<?, ?> mapValue = (Map<?, ?>) value;
722722
Map<Object, Object> copy = new HashMap<>(mapValue.size());

0 commit comments

Comments
 (0)