Enable page directive to handle malformed text.

- Made a targeted fix to PageDirective that stops it from crashing Visual Studio when its malformed.
- Added unit test to validate PageDirective didn't throw when attempting to determine if something was a page.
- Added an integration test to validate malformed page tags can make their way through the entire Razor pipeline and don't destroy the rest of the content.

#1247
This commit is contained in:
N. Taylor Mullen 2017-04-20 13:44:14 -07:00
parent 715aa9bcae
commit c25aadf599
8 changed files with 229 additions and 4 deletions

View File

@ -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

View File

@ -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()
{

View File

@ -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()
{

View File

@ -0,0 +1,4 @@
@page "foo
<h1>About Us</h1>
<p>We are awesome.</p>

View File

@ -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<TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective_cshtml> Html { get; private set; }
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective_cshtml> ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective_cshtml>)PageContext?.ViewData;
public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective_cshtml Model => ViewData.Model;
}
}

View File

@ -0,0 +1,56 @@
Document -
Checksum -
NamespaceDeclaration - - AspNetCore
UsingStatement - - TModel = global::System.Object
UsingStatement - (1:0,1 [12] ) - System
UsingStatement - - System.Threading.Tasks
UsingStatement - (16:1,1 [17] ) - System.Linq
UsingStatement - (36:2,1 [32] ) - System.Collections.Generic
UsingStatement - (71:3,1 [30] ) - Microsoft.AspNetCore.Mvc
UsingStatement - (104:4,1 [40] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingStatement - (147:5,1 [43] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective_cshtml - global::Microsoft.AspNetCore.Mvc.RazorPages.Page -
DirectiveTokenHelper -
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning disable 219
CSharpStatement -
RazorIRToken - - CSharp - private void __RazorDirectiveTokenHelpers__() {
DirectiveToken - (200:6,8 [62] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel>
DirectiveToken - (263:6,71 [4] ) - Html
DirectiveToken - (277:7,8 [54] ) - global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper
DirectiveToken - (332:7,63 [4] ) - Json
DirectiveToken - (346:8,8 [53] ) - global::Microsoft.AspNetCore.Mvc.IViewComponentHelper
DirectiveToken - (400:8,62 [9] ) - Component
DirectiveToken - (419:9,8 [43] ) - global::Microsoft.AspNetCore.Mvc.IUrlHelper
DirectiveToken - (463:9,52 [3] ) - Url
DirectiveToken - (476:10,8 [70] ) - global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider
DirectiveToken - (547:10,79 [23] ) - ModelExpressionProvider
DirectiveToken - (586:11,14 [96] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (698:12,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (801:13,14 [87] ) - Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor
DirectiveToken - (6:0,6 [4] MalformedPageDirective.cshtml) - "foo
CSharpStatement -
RazorIRToken - - CSharp - }
CSharpStatement -
RazorIRToken - - CSharp - #pragma warning restore 219
CSharpStatement -
RazorIRToken - - CSharp - private static System.Object __o = null;
RazorMethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync
HtmlContent - (12:1,0 [43] MalformedPageDirective.cshtml)
RazorIRToken - (12:1,0 [2] MalformedPageDirective.cshtml) - Html - \n
RazorIRToken - (14:2,0 [4] MalformedPageDirective.cshtml) - Html - <h1>
RazorIRToken - (18:2,4 [8] MalformedPageDirective.cshtml) - Html - About Us
RazorIRToken - (26:2,12 [5] MalformedPageDirective.cshtml) - Html - </h1>
RazorIRToken - (31:2,17 [2] MalformedPageDirective.cshtml) - Html - \n
RazorIRToken - (33:3,0 [3] MalformedPageDirective.cshtml) - Html - <p>
RazorIRToken - (36:3,3 [15] MalformedPageDirective.cshtml) - Html - We are awesome.
RazorIRToken - (51:3,18 [4] MalformedPageDirective.cshtml) - Html - </p>
InjectDirective -
InjectDirective -
InjectDirective -
InjectDirective -
InjectDirective -
CSharpStatement -
RazorIRToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective_cshtml> ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective_cshtml>)PageContext?.ViewData;
CSharpStatement -
RazorIRToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective_cshtml Model => ViewData.Model;

View File

@ -0,0 +1,35 @@
#pragma checksum "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/MalformedPageDirective.cshtml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "5a9ff8440150c6746e4a8ba63bc633ea84930405"
namespace AspNetCore
{
#line hidden
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 1998
public async override global::System.Threading.Tasks.Task ExecuteAsync()
{
BeginContext(12, 43, true);
WriteLiteral("\r\n<h1>About Us</h1>\r\n<p>We are awesome.</p>");
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<TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective_cshtml> Html { get; private set; }
public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective_cshtml> ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective_cshtml>)PageContext?.ViewData;
public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective_cshtml Model => ViewData.Model;
}
}

View File

@ -0,0 +1,34 @@
Document -
Checksum -
NamespaceDeclaration - - AspNetCore
UsingStatement - (1:0,1 [14] ) - System
UsingStatement - - System.Threading.Tasks
UsingStatement - (16:1,1 [19] ) - System.Linq
UsingStatement - (36:2,1 [34] ) - System.Collections.Generic
UsingStatement - (71:3,1 [32] ) - Microsoft.AspNetCore.Mvc
UsingStatement - (104:4,1 [42] ) - Microsoft.AspNetCore.Mvc.Rendering
UsingStatement - (147:5,1 [45] ) - Microsoft.AspNetCore.Mvc.ViewFeatures
ClassDeclaration - - public - TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective_cshtml - global::Microsoft.AspNetCore.Mvc.RazorPages.Page -
RazorMethodDeclaration - - public - async, override - global::System.Threading.Tasks.Task - ExecuteAsync
CSharpStatement -
RazorIRToken - - CSharp - BeginContext(12, 43, true);
HtmlContent - (12:1,0 [43] MalformedPageDirective.cshtml)
RazorIRToken - (12:1,0 [2] MalformedPageDirective.cshtml) - Html - \n
RazorIRToken - (14:2,0 [4] MalformedPageDirective.cshtml) - Html - <h1>
RazorIRToken - (18:2,4 [8] MalformedPageDirective.cshtml) - Html - About Us
RazorIRToken - (26:2,12 [5] MalformedPageDirective.cshtml) - Html - </h1>
RazorIRToken - (31:2,17 [2] MalformedPageDirective.cshtml) - Html - \n
RazorIRToken - (33:3,0 [3] MalformedPageDirective.cshtml) - Html - <p>
RazorIRToken - (36:3,3 [15] MalformedPageDirective.cshtml) - Html - We are awesome.
RazorIRToken - (51:3,18 [4] MalformedPageDirective.cshtml) - Html - </p>
CSharpStatement -
RazorIRToken - - CSharp - EndContext();
InjectDirective -
InjectDirective -
InjectDirective -
InjectDirective -
InjectDirective -
CSharpStatement -
RazorIRToken - - CSharp - public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective_cshtml> ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective_cshtml>)PageContext?.ViewData;
CSharpStatement -
RazorIRToken - - CSharp - public TestFiles_IntegrationTests_CodeGenerationIntegrationTest_MalformedPageDirective_cshtml Model => ViewData.Model;