Fix aspnet/Mvc#6296 sanitize class and namespace
The new @namespace directive isn't sanitizing class and namespace names when generating them. This means that a file-system-legal character like '-' will show up in a class name, and that's not good. Note that the old code paths (document classifiers) already had tests for this and did it properly. It was only missing from @namespace.
This commit is contained in:
parent
e391ac7a3c
commit
2a88d6efcf
|
|
@ -4,9 +4,9 @@
|
|||
using System.Globalization;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Internal
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
||||
{
|
||||
public static class ClassName
|
||||
internal static class ClassName
|
||||
{
|
||||
public static string GetClassNameFromPath(string path)
|
||||
{
|
||||
|
|
@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Internal
|
|||
category == UnicodeCategory.Format; // Cf
|
||||
}
|
||||
|
||||
private static string SanitizeClassName(string inputName)
|
||||
public static string SanitizeClassName(string inputName)
|
||||
{
|
||||
if (!IsIdentifierStart(inputName[0]) && IsIdentifierPart(inputName[0]))
|
||||
{
|
||||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.Extensions.Internal;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Mvc.Razor.Extensions.Internal;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
||||
|
||||
|
|
|
|||
|
|
@ -63,13 +63,14 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
{
|
||||
// Beautify the class name since we're using a hierarchy for namespaces.
|
||||
var @class = visitor.FirstClass;
|
||||
var prefix = Path.GetFileNameWithoutExtension(codeDocument.Source.FileName);
|
||||
if (@class != null && irDocument.DocumentKind == RazorPageDocumentClassifierPass.RazorPageDocumentKind)
|
||||
{
|
||||
@class.Name = Path.GetFileNameWithoutExtension(codeDocument.Source.FileName) + "_Page";
|
||||
@class.Name = ClassName.SanitizeClassName(prefix + "_Page");
|
||||
}
|
||||
else if (@class != null && irDocument.DocumentKind == MvcViewDocumentClassifierPass.MvcViewDocumentKind)
|
||||
{
|
||||
@class.Name = Path.GetFileNameWithoutExtension(codeDocument.Source.FileName) + "_View";
|
||||
@class.Name = ClassName.SanitizeClassName(prefix + "_View");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -125,7 +126,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
for (var i = 0; i < segments.Length - 1; i++)
|
||||
{
|
||||
builder.Append('.');
|
||||
builder.Append(segments[i]);
|
||||
builder.Append(ClassName.SanitizeClassName(segments[i]));
|
||||
}
|
||||
|
||||
@namespace = builder.ToString();
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
using System;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Internal
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
||||
{
|
||||
public static class RazorCodeDocumentExtensions
|
||||
internal static class RazorCodeDocumentExtensions
|
||||
{
|
||||
private const string RelativePathKey = "relative-path";
|
||||
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Mvc.Razor.Extensions.Internal;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.Extensions.Internal;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.Extensions.Internal;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
||||
using Xunit;
|
||||
|
|
|
|||
|
|
@ -196,6 +196,44 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
Assert.Equal("AddUser_Page", @class.Name);
|
||||
}
|
||||
|
||||
// Handles cases where invalid characters appears in filenames. Note that we don't sanitize the part of
|
||||
// the namespace that you put in an import, just the file-based-suffix. Garbage in, garbage out.
|
||||
[Fact]
|
||||
public void Pass_SetsNamespaceAndClassName_SanitizesClassAndNamespace()
|
||||
{
|
||||
// Arrange
|
||||
var document = new DocumentIRNode();
|
||||
var builder = RazorIRBuilder.Create(document);
|
||||
|
||||
builder.Push(new DirectiveIRNode()
|
||||
{
|
||||
Descriptor = NamespaceDirective.Directive,
|
||||
Source = new SourceSpan("/Account/_ViewImports.cshtml", 0, 0, 0, 0),
|
||||
});
|
||||
builder.Add(new DirectiveTokenIRNode() { Content = "WebApplication.Account" });
|
||||
builder.Pop();
|
||||
|
||||
var @namespace = new NamespaceDeclarationIRNode() { Content = "default" };
|
||||
builder.Push(@namespace);
|
||||
|
||||
var @class = new ClassDeclarationIRNode() { Name = "default" };
|
||||
builder.Add(@class);
|
||||
|
||||
document.DocumentKind = RazorPageDocumentClassifierPass.RazorPageDocumentKind;
|
||||
|
||||
var codeDocument = RazorCodeDocument.Create(RazorSourceDocument.Create("ignored", "/Account/Manage-Info/Add+User.cshtml"));
|
||||
|
||||
var pass = new NamespaceDirective.Pass();
|
||||
pass.Engine = RazorEngine.CreateEmpty(b => { });
|
||||
|
||||
// Act
|
||||
pass.Execute(codeDocument, document);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("WebApplication.Account.Manage_Info", @namespace.Content);
|
||||
Assert.Equal("Add_User_Page", @class.Name);
|
||||
}
|
||||
|
||||
// This is the case where the source file sets the namespace.
|
||||
[Fact]
|
||||
public void Pass_SetsNamespaceAndClassName_ComputedFromSource_ForView()
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.Extensions.Internal;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
||||
using Xunit;
|
||||
|
|
|
|||
Loading…
Reference in New Issue