From a4f3b86865b8a43ac6e7c772ead2ded9701f7b1e Mon Sep 17 00:00:00 2001 From: Pranav K Date: Tue, 24 Mar 2015 16:43:15 -0700 Subject: [PATCH] Prevent RazorErrorExtensions.ToDiagnostics from throwing when it encounters SourceLocation.Undefined \ negative error lengths --- .../Precompilation/RazorErrorExtensions.cs | 21 +++--- .../RazorErrorExtensionsTest.cs | 66 +++++++++++++++++++ 2 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 test/Microsoft.AspNet.Mvc.Razor.Test/Precompilation/RazorErrorExtensionsTest.cs diff --git a/src/Microsoft.AspNet.Mvc.Razor/Precompilation/RazorErrorExtensions.cs b/src/Microsoft.AspNet.Mvc.Razor/Precompilation/RazorErrorExtensions.cs index 7495f1e201..0f8c94da8f 100644 --- a/src/Microsoft.AspNet.Mvc.Razor/Precompilation/RazorErrorExtensions.cs +++ b/src/Microsoft.AspNet.Mvc.Razor/Precompilation/RazorErrorExtensions.cs @@ -1,7 +1,9 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using Microsoft.AspNet.Razor.Parser.SyntaxTree; +using Microsoft.AspNet.Razor.Text; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Text; using Microsoft.Framework.Internal; @@ -20,15 +22,18 @@ namespace Microsoft.AspNet.Mvc.Razor.Precompilation defaultSeverity: DiagnosticSeverity.Error, isEnabledByDefault: true); - var textSpan = new TextSpan(error.Location.AbsoluteIndex, error.Length); - var linePositionStart = new LinePosition(error.Location.LineIndex, error.Location.CharacterIndex); - var linePositionEnd = new LinePosition(error.Location.LineIndex, - error.Location.CharacterIndex + error.Length); + var location = error.Location; + if (location == SourceLocation.Undefined) + { + location = SourceLocation.Zero; + } + var length = Math.Max(0, error.Length); + + var textSpan = new TextSpan(location.AbsoluteIndex, length); + var linePositionStart = new LinePosition(location.LineIndex, location.CharacterIndex); + var linePositionEnd = new LinePosition(location.LineIndex, location.CharacterIndex + length); var linePositionSpan = new LinePositionSpan(linePositionStart, linePositionEnd); - - var location = Location.Create(filePath, textSpan, linePositionSpan); - - return Diagnostic.Create(descriptor, location); + return Diagnostic.Create(descriptor, Location.Create(filePath, textSpan, linePositionSpan)); } } } \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/Precompilation/RazorErrorExtensionsTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/Precompilation/RazorErrorExtensionsTest.cs new file mode 100644 index 0000000000..ed0f61f051 --- /dev/null +++ b/test/Microsoft.AspNet.Mvc.Razor.Test/Precompilation/RazorErrorExtensionsTest.cs @@ -0,0 +1,66 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNet.Razor.Parser.SyntaxTree; +using Microsoft.AspNet.Razor.Text; +using Xunit; + +namespace Microsoft.AspNet.Mvc.Razor.Precompilation +{ + public class RazorErrorExtensionsTest + { + public static TheoryData ToDiagnostic_SucceedsWhenRazorErrorLocationIsZeroOrUndefinedData + { + get + { + return new TheoryData + { + { SourceLocation.Undefined, -1 }, + { SourceLocation.Undefined, 0 }, + { SourceLocation.Zero, -1 }, + { SourceLocation.Zero, 0 }, + }; + } + } + + [Theory] + [MemberData(nameof(ToDiagnostic_SucceedsWhenRazorErrorLocationIsZeroOrUndefinedData))] + public void ToDiagnostic_SucceedsWhenRazorErrorLocationIsZeroOrUndefined( + SourceLocation location, + int length) + { + // Arrange + var error = new RazorError("some message", location, length); + + // Act + var diagnostics = error.ToDiagnostics("/some-path"); + + // Assert + var span = diagnostics.Location.GetMappedLineSpan(); + Assert.Equal("/some-path", span.Path); + Assert.Equal(0, span.StartLinePosition.Line); + Assert.Equal(0, span.StartLinePosition.Character); + Assert.Equal(0, span.EndLinePosition.Line); + Assert.Equal(0, span.EndLinePosition.Character); + } + + [Fact] + public void ToDiagnostic_ConvertsRazorErrorLocation_ToSourceLineMappings() + { + // Arrange + var sourceLocation = new SourceLocation(absoluteIndex: 30, lineIndex: 10, characterIndex: 1); + var error = new RazorError("some message", sourceLocation, length: 5); + + // Act + var diagnostics = error.ToDiagnostics("/some-path"); + + // Assert + var span = diagnostics.Location.GetMappedLineSpan(); + Assert.Equal("/some-path", span.Path); + Assert.Equal(10, span.StartLinePosition.Line); + Assert.Equal(1, span.StartLinePosition.Character); + Assert.Equal(10, span.EndLinePosition.Line); + Assert.Equal(6, span.EndLinePosition.Character); + } + } +} \ No newline at end of file