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:
N. Taylor Mullen 2017-04-06 15:50:59 -07:00
parent 0228fd2770
commit af3cf497a6
3 changed files with 55 additions and 3 deletions

View File

@ -12,6 +12,8 @@ namespace Microsoft.AspNetCore.Razor.Evolution
{
public const string ElementCatchAllName = "*";
public const char ElementOptOutCharacter = '!';
public static bool SatisfiesRule(
string tagNameWithoutPrefix,
string parentTagName,
@ -66,6 +68,17 @@ namespace Microsoft.AspNetCore.Razor.Evolution
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 &&
rule.TagName != null &&
!string.Equals(tagNameWithoutPrefix, rule.TagName, StringComparison.OrdinalIgnoreCase))

View File

@ -6,7 +6,6 @@ using Microsoft.AspNetCore.Razor.Evolution.Legacy;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
namespace Microsoft.VisualStudio.LanguageServices.Razor
{
@ -48,8 +47,8 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor
}
public override IEnumerable<BoundAttributeDescriptor> GetBoundTagHelperAttributes(
TagHelperDocumentContext documentContext,
string attributeName,
TagHelperDocumentContext documentContext,
string attributeName,
TagHelperBinding binding)
{
if (documentContext == null)

View File

@ -13,6 +13,26 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor
// Purposefully not thoroughly testing DefaultTagHelperFactsService.GetTagHelperBinding because it's a pass through
// 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]
public void GetTagHelperBinding_WorksAsExpected()
{
@ -133,6 +153,26 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor
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]
public void GetTagHelpersGivenTag_RequiresTagName()
{