Skip to content

Commit 6fc00ad

Browse files
authored
Fix template alias parsing livelock (#112217) (#112245)
* Fix template alias parsing livelock This commit fixes an issue with templates parsing alias definitions that can cause the ES thread to hang indefinitely. Due to the malformed alias definition, the parsing gets into a loop which never exits. In this commit a null check in both the component template and alias parsing code is added, which prevents the looping.
1 parent 7b3d73c commit 6fc00ad

File tree

4 files changed

+31
-1
lines changed

4 files changed

+31
-1
lines changed

docs/changelog/112217.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 112217
2+
summary: Fix template alias parsing livelock
3+
area: Indices APIs
4+
type: bug
5+
issues: []

server/src/main/java/org/elasticsearch/cluster/metadata/AliasMetadata.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,8 @@ public static AliasMetadata fromXContent(XContentParser parser) throws IOExcepti
396396
} else if ("is_hidden".equals(currentFieldName)) {
397397
builder.isHidden(parser.booleanValue());
398398
}
399+
} else if (token == null) {
400+
throw new IllegalArgumentException("unexpected null token while parsing alias");
399401
}
400402
}
401403
return builder.build();

server/src/main/java/org/elasticsearch/cluster/metadata/Template.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,11 @@ public class Template implements SimpleDiffable<Template>, ToXContentObject {
7070
}, MAPPINGS, ObjectParser.ValueType.VALUE_OBJECT_ARRAY);
7171
PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), (p, c) -> {
7272
Map<String, AliasMetadata> aliasMap = new HashMap<>();
73-
while ((p.nextToken()) != XContentParser.Token.END_OBJECT) {
73+
XContentParser.Token token;
74+
while ((token = p.nextToken()) != XContentParser.Token.END_OBJECT) {
75+
if (token == null) {
76+
break;
77+
}
7478
AliasMetadata alias = AliasMetadata.Builder.fromXContent(p);
7579
aliasMap.put(alias.alias(), alias);
7680
}

server/src/test/java/org/elasticsearch/cluster/metadata/ComponentTemplateTests.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.elasticsearch.xcontent.XContentBuilder;
2525
import org.elasticsearch.xcontent.XContentFactory;
2626
import org.elasticsearch.xcontent.XContentParser;
27+
import org.elasticsearch.xcontent.XContentParserConfiguration;
2728
import org.elasticsearch.xcontent.XContentType;
2829

2930
import java.io.IOException;
@@ -307,4 +308,22 @@ public void testXContentSerializationWithRolloverAndEffectiveRetention() throws
307308
assertThat(serialized, not(containsString("effective_retention")));
308309
}
309310
}
311+
312+
public void testHangingParsing() throws IOException {
313+
String cutDown = """
314+
{
315+
"template": {
316+
"aliases": {
317+
"foo": "bar"
318+
},
319+
"food": "eggplant"
320+
},
321+
"potato": true
322+
}
323+
""";
324+
325+
try (XContentParser parser = XContentType.JSON.xContent().createParser(XContentParserConfiguration.EMPTY, cutDown)) {
326+
expectThrows(Exception.class, () -> ComponentTemplate.parse(parser));
327+
}
328+
}
310329
}

0 commit comments

Comments
 (0)