Skip to content

Consider non-ASCII characters in HTML case regex #10866

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ public static TheoryData HtmlConversionData
{ "ALLCAPS", "allcaps" },
{ "One1Two2Three3", "one1-two2-three3" },
{ "ONE1TWO2THREE3", "one1two2three3" },
{ "First_Second_ThirdHi", "first_second_third-hi" }
{ "First_Second_ThirdHi", "first_second_third-hi" },
{ "TestÄa", "test-äa" },
{ "KůňŽluťoučký", "kůň-žluťoučký" },
};
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public static class HtmlConventions
// Each match is then prefixed by a "-" via the ToHtmlCase method.
private static readonly Regex HtmlCaseRegex =
new Regex(
"(?<!^)((?<=[a-zA-Z0-9])[A-Z][a-z])|((?<=[a-z])[A-Z])",
@"(?<!^)((?<=[\p{Ll}\p{Lu}0-9])\p{Lu}\p{Ll})|((?<=\p{Ll})\p{Lu})",
RegexOptions.None,
TimeSpan.FromMilliseconds(500));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,43 @@ public override void Process(TagHelperContext context, TagHelperOutput output)
await VerifyRazorPageMatchesBaselineAsync(compilation, "Views_Home_Index");
}

[Fact, WorkItem("https://github.com/dotnet/razor/issues/10844")]
public async Task CustomTagHelper_Unicode()
{
// Arrange
var project = CreateTestProject(new()
{
["Views/Home/Index.cshtml"] = """
@addTagHelper *, TestProject

<test-äh>1</test-äh>
<testäh>2</testäh>
""",
}, new()
{
["TestÄhTagHelper.cs"] = """
using Microsoft.AspNetCore.Razor.TagHelpers;

public class TestÄhTagHelper : TagHelper
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.TagName = "a";
}
}
""",
});
var compilation = await project.GetCompilationAsync();
var driver = await GetDriverAsync(project);

// Act
var result = RunGenerator(compilation!, ref driver, out compilation);

// Assert
result.VerifyOutputsMatchBaseline();
await VerifyRazorPageMatchesBaselineAsync(compilation, "Views_Home_Index");
}

[Theory]
[InlineData("Index")]
[InlineData("CustomEncoder")]
Expand Down Expand Up @@ -900,6 +937,50 @@ public string Invoke(string text, int number, bool flag)
await VerifyRazorPageMatchesBaselineAsync(compilation, "Views_Home_Index");
}

[Fact, WorkItem("https://github.com/dotnet/razor/issues/10844")]
public async Task ViewComponent_Unicode()
{
// Arrange
var project = CreateTestProject(new()
{
["Views/Home/Index.cshtml"] = """
@addTagHelper *, TestProject
<vc:testäh text="1" />
<vc:test-äh text="2" />
<vc:testabc text="3" />
<vc:test-abc text="4" />
""",
}, new()
{
["TestViewComponent.cs"] = """
public class TestAbcViewComponent
{
public string Invoke(string text)
{
return GetType().Name + text;
}
}

public class TestÄhViewComponent
{
public string Invoke(string text)
{
return GetType().Name + text;
}
}
""",
});
var compilation = await project.GetCompilationAsync();
var driver = await GetDriverAsync(project);

// Act
var result = RunGenerator(compilation!, ref driver, out compilation);

// Assert
result.VerifyOutputsMatchBaseline();
await VerifyRazorPageMatchesBaselineAsync(compilation, "Views_Home_Index");
}

[Fact]
public async Task ViewComponentTagHelpers()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

<a>1</a>
<testäh>2</testäh>
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#pragma checksum "Views/Home/Index.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "8e99753af767ba2c899acc05fc5cc8e6e0213f23"
// <auto-generated/>
#pragma warning disable 1591
[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCoreGeneratedDocument.Views_Home_Index), @"mvc.1.0.view", @"/Views/Home/Index.cshtml")]
namespace AspNetCoreGeneratedDocument
{
#line default
using global::System;
using global::System.Collections.Generic;
using global::System.Linq;
using global::System.Threading.Tasks;
using global::Microsoft.AspNetCore.Mvc;
using global::Microsoft.AspNetCore.Mvc.Rendering;
using global::Microsoft.AspNetCore.Mvc.ViewFeatures;
#line default
#line hidden
[global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("Identifier", "/Views/Home/Index.cshtml")]
[global::System.Runtime.CompilerServices.CreateNewOnMetadataUpdateAttribute]
#nullable restore
internal sealed class Views_Home_Index : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
#nullable disable
{
#line hidden
#pragma warning disable 0649
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
#pragma warning restore 0649
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
#pragma warning disable 0169
private string __tagHelperStringValueBuffer;
#pragma warning restore 0169
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
{
get
{
if (__backed__tagHelperScopeManager == null)
{
__backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
}
return __backed__tagHelperScopeManager;
}
}
private global::TestÄhTagHelper __TestÄhTagHelper;
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
WriteLiteral("\r\n");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("test-äh", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.StartTagAndEndTag, "test", async() => {
WriteLiteral("1");
}
);
__TestÄhTagHelper = CreateTagHelper<global::TestÄhTagHelper>();
__tagHelperExecutionContext.Add(__TestÄhTagHelper);
await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
if (!__tagHelperExecutionContext.Output.IsContentModified)
{
await __tagHelperExecutionContext.SetOutputContentAsync();
}
Write(__tagHelperExecutionContext.Output);
__tagHelperExecutionContext = __tagHelperScopeManager.End();
WriteLiteral("\r\n<testäh>2</testäh>");
}
#pragma warning restore 1998
#nullable restore
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } = default!;
#nullable disable
#nullable restore
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } = default!;
#nullable disable
#nullable restore
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } = default!;
#nullable disable
#nullable restore
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } = default!;
#nullable disable
#nullable restore
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<dynamic> Html { get; private set; } = default!;
#nullable disable
}
}
#pragma warning restore 1591
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<vc:testäh text="1" />
Test&#xC4;hViewComponent2
<vc:testabc text="3" />
TestAbcViewComponent4
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
#pragma checksum "Views/Home/Index.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "b6ceddade7ebaedd811e26957835c26a123a6a4c"
// <auto-generated/>
#pragma warning disable 1591
[assembly: global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemAttribute(typeof(AspNetCoreGeneratedDocument.Views_Home_Index), @"mvc.1.0.view", @"/Views/Home/Index.cshtml")]
namespace AspNetCoreGeneratedDocument
{
#line default
using global::System;
using global::System.Collections.Generic;
using global::System.Linq;
using global::System.Threading.Tasks;
using global::Microsoft.AspNetCore.Mvc;
using global::Microsoft.AspNetCore.Mvc.Rendering;
using global::Microsoft.AspNetCore.Mvc.ViewFeatures;
#line default
#line hidden
[global::Microsoft.AspNetCore.Razor.Hosting.RazorCompiledItemMetadataAttribute("Identifier", "/Views/Home/Index.cshtml")]
[global::System.Runtime.CompilerServices.CreateNewOnMetadataUpdateAttribute]
#nullable restore
internal sealed class Views_Home_Index : global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>
#nullable disable
{
#line hidden
#pragma warning disable 0649
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperExecutionContext __tagHelperExecutionContext;
#pragma warning restore 0649
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner __tagHelperRunner = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperRunner();
#pragma warning disable 0169
private string __tagHelperStringValueBuffer;
#pragma warning restore 0169
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __backed__tagHelperScopeManager = null;
private global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager __tagHelperScopeManager
{
get
{
if (__backed__tagHelperScopeManager == null)
{
__backed__tagHelperScopeManager = new global::Microsoft.AspNetCore.Razor.Runtime.TagHelpers.TagHelperScopeManager(StartTagHelperWritingScope, EndTagHelperWritingScope);
}
return __backed__tagHelperScopeManager;
}
}
private global::AspNetCoreGeneratedDocument.Views_Home_Index.__Generated__TestÄhViewComponentTagHelper __TestÄhViewComponentTagHelper;
private global::AspNetCoreGeneratedDocument.Views_Home_Index.__Generated__TestAbcViewComponentTagHelper __TestAbcViewComponentTagHelper;
#pragma warning disable 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
WriteLiteral("<vc:testäh text=\"1\" />\r\n");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("vc:test-äh", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
}
);
__TestÄhViewComponentTagHelper = CreateTagHelper<global::AspNetCoreGeneratedDocument.Views_Home_Index.__Generated__TestÄhViewComponentTagHelper>();
__tagHelperExecutionContext.Add(__TestÄhViewComponentTagHelper);
BeginWriteTagHelperAttribute();
WriteLiteral("2");
__tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
__TestÄhViewComponentTagHelper.text = __tagHelperStringValueBuffer;
__tagHelperExecutionContext.AddTagHelperAttribute("text", __TestÄhViewComponentTagHelper.text, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
if (!__tagHelperExecutionContext.Output.IsContentModified)
{
await __tagHelperExecutionContext.SetOutputContentAsync();
}
Write(__tagHelperExecutionContext.Output);
__tagHelperExecutionContext = __tagHelperScopeManager.End();
WriteLiteral("\r\n<vc:testabc text=\"3\" />\r\n");
__tagHelperExecutionContext = __tagHelperScopeManager.Begin("vc:test-abc", global::Microsoft.AspNetCore.Razor.TagHelpers.TagMode.SelfClosing, "test", async() => {
}
);
__TestAbcViewComponentTagHelper = CreateTagHelper<global::AspNetCoreGeneratedDocument.Views_Home_Index.__Generated__TestAbcViewComponentTagHelper>();
__tagHelperExecutionContext.Add(__TestAbcViewComponentTagHelper);
BeginWriteTagHelperAttribute();
WriteLiteral("4");
__tagHelperStringValueBuffer = EndWriteTagHelperAttribute();
__TestAbcViewComponentTagHelper.text = __tagHelperStringValueBuffer;
__tagHelperExecutionContext.AddTagHelperAttribute("text", __TestAbcViewComponentTagHelper.text, global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
if (!__tagHelperExecutionContext.Output.IsContentModified)
{
await __tagHelperExecutionContext.SetOutputContentAsync();
}
Write(__tagHelperExecutionContext.Output);
__tagHelperExecutionContext = __tagHelperScopeManager.End();
}
#pragma warning restore 1998
#nullable restore
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } = default!;
#nullable disable
#nullable restore
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } = default!;
#nullable disable
#nullable restore
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } = default!;
#nullable disable
#nullable restore
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } = default!;
#nullable disable
#nullable restore
[global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<dynamic> Html { get; private set; } = default!;
#nullable disable
[Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute("vc:test-äh")]
public class __Generated__TestÄhViewComponentTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper
{
private readonly global::Microsoft.AspNetCore.Mvc.IViewComponentHelper __helper = null;
public __Generated__TestÄhViewComponentTagHelper(global::Microsoft.AspNetCore.Mvc.IViewComponentHelper helper)
{
__helper = helper;
}
[Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute, global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { get; set; }
public System.String text { get; set; }
public override async global::System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext __context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput __output)
{
(__helper as global::Microsoft.AspNetCore.Mvc.ViewFeatures.IViewContextAware)?.Contextualize(ViewContext);
var __helperContent = await __helper.InvokeAsync("TestÄh", ProcessInvokeAsyncArgs(__context));
__output.TagName = null;
__output.Content.SetHtmlContent(__helperContent);
}
private Dictionary<string, object> ProcessInvokeAsyncArgs(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext __context)
{
Dictionary<string, object> args = new Dictionary<string, object>();
if (__context.AllAttributes.ContainsName("text"))
{
args[nameof(text)] = text;
}
return args;
}
}
[Microsoft.AspNetCore.Razor.TagHelpers.HtmlTargetElementAttribute("vc:test-abc")]
public class __Generated__TestAbcViewComponentTagHelper : Microsoft.AspNetCore.Razor.TagHelpers.TagHelper
{
private readonly global::Microsoft.AspNetCore.Mvc.IViewComponentHelper __helper = null;
public __Generated__TestAbcViewComponentTagHelper(global::Microsoft.AspNetCore.Mvc.IViewComponentHelper helper)
{
__helper = helper;
}
[Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeNotBoundAttribute, global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewContextAttribute]
public global::Microsoft.AspNetCore.Mvc.Rendering.ViewContext ViewContext { get; set; }
public System.String text { get; set; }
public override async global::System.Threading.Tasks.Task ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext __context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput __output)
{
(__helper as global::Microsoft.AspNetCore.Mvc.ViewFeatures.IViewContextAware)?.Contextualize(ViewContext);
var __helperContent = await __helper.InvokeAsync("TestAbc", ProcessInvokeAsyncArgs(__context));
__output.TagName = null;
__output.Content.SetHtmlContent(__helperContent);
}
private Dictionary<string, object> ProcessInvokeAsyncArgs(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext __context)
{
Dictionary<string, object> args = new Dictionary<string, object>();
if (__context.AllAttributes.ContainsName("text"))
{
args[nameof(text)] = text;
}
return args;
}
}
}
}
#pragma warning restore 1591
Loading