diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/PageDirective.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/PageDirective.cs index 48db33bc17..014587d2c1 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/PageDirective.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor.Extensions/PageDirective.cs @@ -67,10 +67,15 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions private static string TrimQuotes(string content) { - Debug.Assert(content.StartsWith("\"", StringComparison.Ordinal)); - Debug.Assert(content.EndsWith("\"", StringComparison.Ordinal)); + if (content.Length >= 2 && + content.StartsWith("\"", StringComparison.Ordinal) && + content.EndsWith("\"", StringComparison.Ordinal)) + { + return content.Substring(1, content.Length - 2); + } - return content.Substring(1, content.Length - 2); + // The extensible directive system handed us invalid content. There's already an error logged. + return null; } private class Visitor : RazorIRNodeWalker diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/IntegrationTests/CodeGenerationIntegrationTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/IntegrationTests/CodeGenerationIntegrationTest.cs index a195666fad..b434d7591f 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/IntegrationTests/CodeGenerationIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/IntegrationTests/CodeGenerationIntegrationTest.cs @@ -24,7 +24,22 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.IntegrationTests private static readonly RazorSourceDocument DefaultImports = MvcRazorTemplateEngine.GetDefaultImports(); #region Runtime - + + [Fact] + public void MalformedPageDirective_Runtime() + { + // Arrange + var engine = CreateRuntimeEngine(); + var document = CreateCodeDocument(); + + // Act + engine.Process(document); + + // Assert + AssertIRMatchesBaseline(document.GetIRDocument()); + AssertCSharpDocumentMatchesBaseline(document.GetCSharpDocument()); + } + [Fact] public void Basic_Runtime() { @@ -192,6 +207,22 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.IntegrationTests #endregion #region DesignTime + + [Fact] + public void MalformedPageDirective_DesignTime() + { + // Arrange + var engine = CreateDesignTimeEngine(); + var document = CreateCodeDocument(); + + // Act + engine.Process(document); + + // Assert + AssertIRMatchesBaseline(document.GetIRDocument()); + AssertCSharpDocumentMatchesBaseline(document.GetCSharpDocument()); + } + [Fact] public void Basic_DesignTime() { diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/PageDirectiveTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/PageDirectiveTest.cs index 580651bdc2..f94bbf8559 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/PageDirectiveTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/PageDirectiveTest.cs @@ -9,6 +9,25 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions { public class PageDirectiveTest { + [Fact] + public void TryGetPageDirective_CanHandleMalformedPageDirectives() + { + // Arrange + var content = "@page \""; + var sourceDocument = RazorSourceDocument.Create(content, "file"); + var codeDocument = RazorCodeDocument.Create(sourceDocument); + var engine = CreateEngine(); + var irDocument = CreateIRDocument(engine, codeDocument); + + // Act + var result = PageDirective.TryGetPageDirective(irDocument, out var pageDirective); + + // Assert + Assert.True(result); + Assert.Null(pageDirective.RouteTemplate); + Assert.Null(pageDirective.PageName); + } + [Fact] public void TryGetPageDirective_ReturnsFalse_IfPageDoesNotHaveDirective() { diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml new file mode 100644 index 0000000000..9b4f9d5559 --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml @@ -0,0 +1,4 @@ +@page "foo + +
We are awesome.
\ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.codegen.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.codegen.cs new file mode 100644 index 0000000000..26ffa461cd --- /dev/null +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Extensions.Test/TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective_DesignTime.codegen.cs @@ -0,0 +1,41 @@ +namespace AspNetCore +{ + #line hidden + using TModel = global::System.Object; + using System; + using System.Threading.Tasks; + using System.Linq; + using System.Collections.Generic; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + public class TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective_cshtml : global::Microsoft.AspNetCore.Mvc.RazorPages.Page + { + #pragma warning disable 219 + private void __RazorDirectiveTokenHelpers__() { + ((System.Action)(() => { +global::System.Object __typeHelper = "foo; + } + ))(); + } + #pragma warning restore 219 + private static System.Object __o = null; + #pragma warning disable 1998 + public async override global::System.Threading.Tasks.Task ExecuteAsync() + { + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper+ RazorIRToken - (36:3,3 [15] MalformedPageDirective.cshtml) - Html - We are awesome. + RazorIRToken - (51:3,18 [4] MalformedPageDirective.cshtml) - Html -
+ InjectDirective - + InjectDirective - + InjectDirective - + InjectDirective - + InjectDirective - + CSharpStatement - + RazorIRToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionaryWe are awesome.
"); + EndContext(); + } + #pragma warning restore 1998 + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IUrlHelper Url { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json { get; private set; } + [global::Microsoft.AspNetCore.Mvc.Razor.Internal.RazorInjectAttribute] + public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper+ RazorIRToken - (36:3,3 [15] MalformedPageDirective.cshtml) - Html - We are awesome. + RazorIRToken - (51:3,18 [4] MalformedPageDirective.cshtml) - Html -
+ CSharpStatement - + RazorIRToken - - CSharp - EndContext(); + InjectDirective - + InjectDirective - + InjectDirective - + InjectDirective - + InjectDirective - + CSharpStatement - + RazorIRToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary