Skip to content

Commit 2366890

Browse files
authored
Handle duplicate extensible directives properly in the Razor parser (#27695)
1 parent 9f72904 commit 2366890

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

src/Razor/Microsoft.AspNetCore.Razor.Language/src/Legacy/CSharpCodeParser.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -959,10 +959,18 @@ private void EnsureDirectiveIsAtStartOfLine()
959959
}
960960
}
961961

962-
protected void MapDirectives(Action<SyntaxListBuilder<RazorSyntaxNode>, CSharpTransitionSyntax> handler, params string[] directives)
962+
// Internal for testing.
963+
internal void MapDirectives(Action<SyntaxListBuilder<RazorSyntaxNode>, CSharpTransitionSyntax> handler, params string[] directives)
963964
{
964965
foreach (var directive in directives)
965966
{
967+
if (_directiveParserMap.ContainsKey(directive))
968+
{
969+
// It is possible for the list to contain duplicates in cases when the project is misconfigured.
970+
// In those cases, we shouldn't register multiple handlers per keyword.
971+
continue;
972+
}
973+
966974
_directiveParserMap.Add(directive, (builder, transition) =>
967975
{
968976
handler(builder, transition);

src/Razor/Microsoft.AspNetCore.Razor.Language/test/Legacy/CSharpCodeParserTest.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) .NET Foundation. All rights reserved.
1+
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

44
using System;
@@ -211,5 +211,19 @@ public void TagHelperPrefixDirective_DuplicatesCauseError()
211211
var diagnostic = Assert.Single(chunkGenerator.Diagnostics);
212212
Assert.Equal(expectedDiagnostic, diagnostic);
213213
}
214+
215+
[Fact]
216+
public void MapDirectives_HandlesDuplicates()
217+
{
218+
// Arrange
219+
var source = TestRazorSourceDocument.Create();
220+
var options = RazorParserOptions.CreateDefault();
221+
var context = new ParserContext(source, options);
222+
var parser = new CSharpCodeParser(context);
223+
224+
// Act & Assert (Does not throw)
225+
parser.MapDirectives((b, t) => { }, "test");
226+
parser.MapDirectives((b, t) => { }, "test");
227+
}
214228
}
215229
}

0 commit comments

Comments
 (0)