Skip to content

Commit 36d0c12

Browse files
Thomas CallahanThomas Callahan
Thomas Callahan
authored and
Thomas Callahan
committed
Ensures watch definitions are valid json
Currently, watches may be submitted and accepted by the cluster that do not consist of valid JSON. This is because in certain cases, WatchParser.java will not consume enough tokens from XContentParser to be able to encounter an underlying JSON parse error. This patch fixes this behavior and adds a test. Closes elastic#29746
1 parent 75665a2 commit 36d0c12

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/watch/WatchParser.java

+14
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
package org.elasticsearch.xpack.watcher.watch;
77

8+
import com.fasterxml.jackson.core.JsonParseException;
89
import org.elasticsearch.ElasticsearchParseException;
910
import org.elasticsearch.common.Nullable;
1011
import org.elasticsearch.common.bytes.BytesReference;
@@ -174,6 +175,19 @@ public Watch parse(String id, boolean includeStatus, WatcherXContentParser parse
174175
throw new ElasticsearchParseException("could not parse watch [{}]. unexpected field [{}]", id, currentFieldName);
175176
}
176177
}
178+
179+
try {
180+
/* Make sure we are at the end of the available input data -- certain types of JSON errors will not manifest
181+
until we try to consume additional tokens.
182+
*/
183+
if (parser.nextToken() != null) {
184+
throw new ElasticsearchParseException("Received non-null token beyond end of watch definition!");
185+
}
186+
} catch (JsonParseException|ElasticsearchParseException e) {
187+
throw new ElasticsearchParseException("could not parse watch [{}]. unexpected data beyond [line: {}, column: {}]",
188+
e, id, parser.getTokenLocation().lineNumber, parser.getTokenLocation().columnNumber);
189+
}
190+
177191
if (trigger == null) {
178192
throw new ElasticsearchParseException("could not parse watch [{}]. missing required field [{}]", id,
179193
WatchField.TRIGGER.getPreferredName());

x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/watch/WatchTests.java

+34
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.elasticsearch.action.support.WriteRequest;
1212
import org.elasticsearch.client.Client;
1313
import org.elasticsearch.common.ParseField;
14+
import org.elasticsearch.common.bytes.BytesArray;
1415
import org.elasticsearch.common.bytes.BytesReference;
1516
import org.elasticsearch.common.logging.Loggers;
1617
import org.elasticsearch.common.settings.Settings;
@@ -19,6 +20,7 @@
1920
import org.elasticsearch.common.xcontent.XContentBuilder;
2021
import org.elasticsearch.common.xcontent.XContentParser;
2122
import org.elasticsearch.common.xcontent.XContentType;
23+
import org.elasticsearch.common.xcontent.json.JsonXContent;
2224
import org.elasticsearch.index.query.MatchAllQueryBuilder;
2325
import org.elasticsearch.index.query.QueryBuilder;
2426
import org.elasticsearch.index.query.ScriptQueryBuilder;
@@ -296,6 +298,38 @@ public void testParserBadActions() throws Exception {
296298
}
297299
}
298300

301+
public void testParserConsumesEntireDefinition() throws Exception {
302+
WatchParser wp = createWatchparser();
303+
String watchDef="{\n" +
304+
" \"trigger\": {\n" +
305+
" \"schedule\": {\n" +
306+
" \"interval\": \"10s\"\n" +
307+
" }\n" +
308+
" },\n" +
309+
" \"input\": {\n" +
310+
" \"simple\": {}\n" +
311+
" }},\n" + /* NOTICE EXTRA CLOSING CURLY BRACE */
312+
" \"condition\": {\n" +
313+
" \"script\": {\n" +
314+
" \"inline\": \"return false\"\n" +
315+
" }\n" +
316+
" },\n" +
317+
" \"actions\": {\n" +
318+
" \"logging\": {\n" +
319+
" \"logging\": {\n" +
320+
" \"text\": \"{{ctx.payload}}\"\n" +
321+
" }\n" +
322+
" }\n" +
323+
" }\n" +
324+
"}";
325+
try {
326+
wp.parseWithSecrets("failure", false, new BytesArray(watchDef), new DateTime(), XContentType.JSON, true);
327+
fail("This watch should fail to parse as there is an extra closing curly brace in the middle of the watch");
328+
} catch (ElasticsearchParseException pe) {
329+
assertThat(pe.getMessage().contains("unexpected data beyond"), is(true));
330+
}
331+
}
332+
299333
public void testParserDefaults() throws Exception {
300334
Schedule schedule = randomSchedule();
301335
ScheduleRegistry scheduleRegistry = registry(schedule);

0 commit comments

Comments
 (0)