Update TagHelperMatchingConventions to disallow opt-out prefix.
- Prior to this change the `TagHelper` parsing would strip the opt-out character (`!`) from tag names that got passed to the TagHelper matching services. At design time this proved to be a problem because they have their own understanding of the HTML document and only pass us full tag names (names that include `!`). This changes the matching conventions to immediately return false if a tag name is seen to contain the `TagHelper` opt-out. - Added two `DefaultTagHelperFactService` tests to verify that tag names with opt-out prefixes are denied `TagHelperDescriptor`s. #1186
This commit is contained in:
parent
0228fd2770
commit
af3cf497a6
|
|
@ -12,6 +12,8 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
{
|
{
|
||||||
public const string ElementCatchAllName = "*";
|
public const string ElementCatchAllName = "*";
|
||||||
|
|
||||||
|
public const char ElementOptOutCharacter = '!';
|
||||||
|
|
||||||
public static bool SatisfiesRule(
|
public static bool SatisfiesRule(
|
||||||
string tagNameWithoutPrefix,
|
string tagNameWithoutPrefix,
|
||||||
string parentTagName,
|
string parentTagName,
|
||||||
|
|
@ -66,6 +68,17 @@ namespace Microsoft.AspNetCore.Razor.Evolution
|
||||||
throw new ArgumentNullException(nameof(rule));
|
throw new ArgumentNullException(nameof(rule));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(tagNameWithoutPrefix))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tagNameWithoutPrefix[0] == ElementOptOutCharacter)
|
||||||
|
{
|
||||||
|
// TagHelpers can never satisfy tag names that are prefixed with the opt-out character.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (rule.TagName != ElementCatchAllName &&
|
if (rule.TagName != ElementCatchAllName &&
|
||||||
rule.TagName != null &&
|
rule.TagName != null &&
|
||||||
!string.Equals(tagNameWithoutPrefix, rule.TagName, StringComparison.OrdinalIgnoreCase))
|
!string.Equals(tagNameWithoutPrefix, rule.TagName, StringComparison.OrdinalIgnoreCase))
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ using Microsoft.AspNetCore.Razor.Evolution.Legacy;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.Composition;
|
using System.ComponentModel.Composition;
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Microsoft.VisualStudio.LanguageServices.Razor
|
namespace Microsoft.VisualStudio.LanguageServices.Razor
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,26 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor
|
||||||
// Purposefully not thoroughly testing DefaultTagHelperFactsService.GetTagHelperBinding because it's a pass through
|
// Purposefully not thoroughly testing DefaultTagHelperFactsService.GetTagHelperBinding because it's a pass through
|
||||||
// into TagHelperDescriptorProvider.GetTagHelperBinding.
|
// into TagHelperDescriptorProvider.GetTagHelperBinding.
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetTagHelperBinding_DoesNotAllowOptOutCharacterPrefix()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var documentDescriptors = new[]
|
||||||
|
{
|
||||||
|
ITagHelperDescriptorBuilder.Create("TestType", "TestAssembly")
|
||||||
|
.TagMatchingRule(rule => rule.RequireTagName("*"))
|
||||||
|
.Build()
|
||||||
|
};
|
||||||
|
var documentContext = TagHelperDocumentContext.Create(string.Empty, documentDescriptors);
|
||||||
|
var service = new DefaultTagHelperFactsService();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var binding = service.GetTagHelperBinding(documentContext, "!a", Enumerable.Empty<KeyValuePair<string, string>>(), parentTag: null);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Null(binding);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void GetTagHelperBinding_WorksAsExpected()
|
public void GetTagHelperBinding_WorksAsExpected()
|
||||||
{
|
{
|
||||||
|
|
@ -133,6 +153,26 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor
|
||||||
Assert.Equal(expectedAttributeDescriptors, descriptors, BoundAttributeDescriptorComparer.CaseSensitive);
|
Assert.Equal(expectedAttributeDescriptors, descriptors, BoundAttributeDescriptorComparer.CaseSensitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetTagHelpersGivenTag_DoesNotAllowOptOutCharacterPrefix()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var documentDescriptors = new[]
|
||||||
|
{
|
||||||
|
ITagHelperDescriptorBuilder.Create("TestType", "TestAssembly")
|
||||||
|
.TagMatchingRule(rule => rule.RequireTagName("*"))
|
||||||
|
.Build()
|
||||||
|
};
|
||||||
|
var documentContext = TagHelperDocumentContext.Create(string.Empty, documentDescriptors);
|
||||||
|
var service = new DefaultTagHelperFactsService();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var descriptors = service.GetTagHelpersGivenTag(documentContext, "!strong", parentTag: null);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Empty(descriptors);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void GetTagHelpersGivenTag_RequiresTagName()
|
public void GetTagHelpersGivenTag_RequiresTagName()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue