From cd54d41a7280916079f6d889cfe18085253cc5fc Mon Sep 17 00:00:00 2001 From: Ioannis Kakavas Date: Fri, 21 Dec 2018 09:04:34 +0200 Subject: [PATCH] Handle Null in FetchSourceContext#fetchSource (#36839) This change ensures that when null is passed as the value to one of UpdateRequest#fetchSource @Nullable parameters, it is not wrapped in a String array. That would in turn cause a NPE when attempting to serialize FetchSourceContext as its constructor checks explicitly for Null and not for arrays of Null objects. In master, the problematic behavior was corrected as part of #29293 --- .../action/update/UpdateRequest.java | 4 ++- .../org/elasticsearch/update/UpdateIT.java | 28 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/org/elasticsearch/action/update/UpdateRequest.java b/server/src/main/java/org/elasticsearch/action/update/UpdateRequest.java index 7b16e096cb504..c95ab817430ab 100644 --- a/server/src/main/java/org/elasticsearch/action/update/UpdateRequest.java +++ b/server/src/main/java/org/elasticsearch/action/update/UpdateRequest.java @@ -410,7 +410,9 @@ public UpdateRequest fields(String... fields) { */ public UpdateRequest fetchSource(@Nullable String include, @Nullable String exclude) { FetchSourceContext context = this.fetchSourceContext == null ? FetchSourceContext.FETCH_SOURCE : this.fetchSourceContext; - this.fetchSourceContext = new FetchSourceContext(context.fetchSource(), new String[] {include}, new String[]{exclude}); + String[] includes = include == null ? Strings.EMPTY_ARRAY : new String[]{include}; + String[] excludes = exclude == null ? Strings.EMPTY_ARRAY : new String[]{exclude}; + this.fetchSourceContext = new FetchSourceContext(context.fetchSource(), includes, excludes); return this; } diff --git a/server/src/test/java/org/elasticsearch/update/UpdateIT.java b/server/src/test/java/org/elasticsearch/update/UpdateIT.java index 78324123d4504..a05a7539ea59a 100644 --- a/server/src/test/java/org/elasticsearch/update/UpdateIT.java +++ b/server/src/test/java/org/elasticsearch/update/UpdateIT.java @@ -379,6 +379,34 @@ public void testUpdate() throws Exception { assertThat(updateResponse.getGetResult().sourceAsMap().size(), equalTo(1)); assertThat(updateResponse.getGetResult().sourceAsMap().get("field1"), equalTo(2)); + // check updates with null excludes + client().prepareIndex("test", "type1", "1").setSource("field1", 1, "field2", 2).execute().actionGet(); + updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1") + .setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, FIELD_INC_SCRIPT, Collections.singletonMap("field", "field1"))) + .setFetchSource("field1", null) + .get(); + assertThat(updateResponse.getIndex(), equalTo("test")); + assertThat(updateResponse.getGetResult(), notNullValue()); + assertThat(updateResponse.getGetResult().getIndex(), equalTo("test")); + assertThat(updateResponse.getGetResult().sourceRef(), notNullValue()); + assertThat(updateResponse.getGetResult().field("field1"), nullValue()); + assertThat(updateResponse.getGetResult().sourceAsMap().size(), equalTo(1)); + assertThat(updateResponse.getGetResult().sourceAsMap().get("field1"), equalTo(2)); + + // check updates with null includes + client().prepareIndex("test", "type1", "1").setSource("field1", 1, "field2", 2).execute().actionGet(); + updateResponse = client().prepareUpdate(indexOrAlias(), "type1", "1") + .setScript(new Script(ScriptType.INLINE, UPDATE_SCRIPTS, FIELD_INC_SCRIPT, Collections.singletonMap("field", "field1"))) + .setFetchSource(null, "field1") + .get(); + assertThat(updateResponse.getIndex(), equalTo("test")); + assertThat(updateResponse.getGetResult(), notNullValue()); + assertThat(updateResponse.getGetResult().getIndex(), equalTo("test")); + assertThat(updateResponse.getGetResult().sourceRef(), notNullValue()); + assertThat(updateResponse.getGetResult().field("field2"), nullValue()); + assertThat(updateResponse.getGetResult().sourceAsMap().size(), equalTo(1)); + assertThat(updateResponse.getGetResult().sourceAsMap().get("field2"), equalTo(2)); + // check updates without script // add new field client().prepareIndex("test", "type1", "1").setSource("field", 1).execute().actionGet();