public void MethodContainsControlStructureInElseStatement_DiagnosticIsReported()
        {
            const string Code = @"
            class SomeClass
            {
                public void SomeMethod()
                {
                    if (new Random().Next(1) == 1)
                    {
                        System.Console.WriteLine(string.Empty);
                    }
                    else
                    {
                        for (int i = 0; i < 10; i++)
                        {
                            System.Console.WriteLine();
                        }
                    }
                }
            }";

            var expected = new DiagnosticResult
            {
                Id = "DaVinciOC1",
                Message = "\'SomeMethod\' contains more than 1 level of indentation.",
                Severity = DiagnosticSeverity.Info,
                Locations = new[] { new DiagnosticResultLocation("Test0.cs", 4, 29) }
            };

            VerifyCSharpDiagnostic(Code, expected);
        }
        public void DiagnosticForMethod()
        {
            var source = @"
using System.Threading;
class T
{
    void M(CancellationToken t, int i)
    {
    }
}";
            var expected = new DiagnosticResult
            {
                Id = RoslynDiagnosticIds.CancellationTokenMustBeLastRuleId,
                Message = string.Format(RoslynDiagnosticsResources.CancellationTokenMustBeLastMessage, "T.M(System.Threading.CancellationToken, int)"),
                Severity = DiagnosticSeverity.Warning,
                Locations = new[]
                {
                    new DiagnosticResultLocation("Test0.cs", 5, 10)
                }
            };

            VerifyCSharp(source, expected);

            var fixedSource = @"
using System.Threading;
class T
{
    void M(int i, CancellationToken t)
    {
    }
}";
            VerifyCSharpFix(source, fixedSource);
        }
        public void MethodContainsIfWithElse_OneDiagnosticReported()
        {
            const string Code = @"
            class SomeClass
            {
                private int firstField;

                private int secondField;

                public void Do()
                {
                    if (true)
                    {
                        System.Console.WriteLine();
                    }
                    else
                    {
                        System.Console.WriteLine();
                    }
                }
            }";

            var expected = new DiagnosticResult
            {
                Id = "DaVinciOC2",
                Message = "The else keyword should be avoided.",
                Severity = DiagnosticSeverity.Info,
                Locations = new[] { new DiagnosticResultLocation("Test0.cs", 14, 21) }
            };
            VerifyCSharpDiagnostic(Code, expected);
        }
        public void NestedExpressionContains2Dots_DiagnosticIsReported()
        {
            const string code = @"
               class Board {
                public String boardRepresentation() {
                    StringBuilder buf = new StringBuilder();

                    for (Location loc : squares()) {
                        buf.append(loc.current.substring(0, 1));
                    }

                    return buf.toString();
                }
             }";

            var expected = new DiagnosticResult
            {
                Id = "DaVinciOC5",
                Message = "\'loc.current.substring(0, 1)\' contains more than 1 dot per line.",
                Severity = DiagnosticSeverity.Info,
                Locations = new[] { new DiagnosticResultLocation("Test0.cs", 7, 36) }
            };

            VerifyCSharpDiagnostic(code, expected);
        }
        public void ClassContainsListAndField_ReportDiagnostic()
        {
            const string Code = @"
            class SomeClass
            {
                private int someField;

                private System.Collections.Generic.List<int> list;

                public SomeClass()
                {
                    this.someField = 1;
                    this.list = new System.Collections.Generic.List<int>();
                }
            }";

            var expected = new DiagnosticResult
            {
                Id = "DaVinciOC4",
                Message = "Consider wrapping the collection into a separate class.",
                Severity = DiagnosticSeverity.Info,
                Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 62) }
            };

            VerifyCSharpDiagnostic(Code, expected);
        }
        public void ClassContainsTwoListsAndAnotherField_ReportDiagnostic()
        {
            const string Code = @"
            class SomeClass
            {
                private System.Collections.Generic.List<int> firstList;
                private System.Collections.Generic.List<int> secondList;
                private int intField;

                public SomeClass(int val)
                {
                    this.firstList = new System.Collections.Generic.List<int>();
                    this.secondList = new System.Collections.Generic.List<int>();
                    this.intField = val;
                }
            }";

            var firstExpected = new DiagnosticResult
            {
                Id = "DaVinciOC4",
                Message = "Consider wrapping the collection into a separate class.",
                Severity = DiagnosticSeverity.Info,
                Locations = new[] { new DiagnosticResultLocation("Test0.cs", 4, 62)}
            };

            var secondExpected = new DiagnosticResult
            {
                Id = "DaVinciOC4",
                Message = "Consider wrapping the collection into a separate class.",
                Severity = DiagnosticSeverity.Info,
                Locations = new[] { new DiagnosticResultLocation("Test0.cs", 5, 62) }
            };

            VerifyCSharpDiagnostic(Code, firstExpected, secondExpected);
        }
        public void TestExpressionBodiedProperties()
        {
            var test = @"
namespace ConsoleApplication1
{
    class TypeName
    {
        private IAuthenticationManager AuthenticationManager => this.HttpContext.GetOwinContext().Authentication;
    }
}";
            var expected = new DiagnosticResult
            {
                Id = "SA1623D",
                Message = $"property documentation: no documentation.",
                Severity = DiagnosticSeverity.Warning,
                Locations =
                    new[] { new DiagnosticResultLocation("Test0.cs", 6, 40) }
            };

            new DocumentationPropertyCodeFixVerifier().VerifyCSharpDiagnostic(test, expected);

            var fixtest = @"
namespace ConsoleApplication1
{
    class TypeName
    {
        /// <summary>
        /// Gets the authentication manager.
        /// </summary>
        private IAuthenticationManager AuthenticationManager => this.HttpContext.GetOwinContext().Authentication;
    }
}";
            new DocumentationPropertyCodeFixVerifier().VerifyCSharpFix(test, fixtest);
        }
        public void TestThatFirstPropertyHasCorrectSpacingBefore()
        {
            var test = @"
namespace Test
{
    public class TestClass
    {
        private readonly int _someVariable;
    }
}";
            var expected = new DiagnosticResult
            {
                Id = "SA1600D",
                Message = $"members must be correctly documented.",
                Severity = DiagnosticSeverity.Warning,
                Locations =
                    new[] { new DiagnosticResultLocation("Test0.cs", 6, 30) }
            };

            new DocumentationMemberCodeFixVerifier().VerifyCSharpDiagnostic(test, expected);

            var fixtest = @"
namespace Test
{
    public class TestClass
    {
        /// <summary>
        /// the some variable.
        /// </summary>
        private readonly int _someVariable;
    }
}";
            new DocumentationMemberCodeFixVerifier().VerifyCSharpFix(test, fixtest);
        }
        public void TestUnspecifiedSetPropertyHasCorrectComment()
        {
            var test = @"
namespace ConsoleApplication1
{
    class TypeName
    {
        public string VogonConstructorFleet { get; }
    }
}";
            var expected = new DiagnosticResult
            {
                Id = "SA1623D",
                Message = $"property documentation: no documentation.",
                Severity = DiagnosticSeverity.Warning,
                Locations =
                    new[] { new DiagnosticResultLocation("Test0.cs", 6, 23) }
            };

            new DocumentationPropertyCodeFixVerifier().VerifyCSharpDiagnostic(test, expected);

            var fixtest = @"
namespace ConsoleApplication1
{
    class TypeName
    {
        /// <summary>
        /// Gets the vogon constructor fleet.
        /// </summary>
        public string VogonConstructorFleet { get; }
    }
}";
            new DocumentationPropertyCodeFixVerifier().VerifyCSharpFix(test, fixtest);
        }
        public void TestThatMethodContainingParametersHaveParametersDetected()
        {
            var test = @"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class TypeName
    {
        /// <summary>
        /// build the vogon constructor fleet.       
        /// </summary>
        /// <param name=""parameterOne"">parameter one</param>
        public void BuildVogonConstructorFleet(string parameterOne, int parameterItemTwo)
        {
        }
    }
}";
            var expected = new DiagnosticResult
            {
                Id = "SA1612D",
                Message = $"method documentation: missing 'parameterItemTwo'.",
                Severity = DiagnosticSeverity.Warning,
                Locations =
                    new[] { new DiagnosticResultLocation("Test0.cs", 17, 21) }
            };

            new DocumentationMethodCodeFixVerifier().VerifyCSharpDiagnostic(test, expected);
        }
        public void MethodTakesMultiplePrimitiveAsParameter_MultipleDiagnosticReported()
        {
            const string Code = @"
                class SomeClass
                {
                    public void DoSomething(int parameter1, uint parameter2)
                    {
                    }
                }";

            var expected1 = new DiagnosticResult
            {
                Id = "DaVinciOC3",
                Message = "'parameter1' should be wrapped as it's a primitive.",
                Severity = DiagnosticSeverity.Info,
                Locations = new[] { new DiagnosticResultLocation("Test0.cs", 4, 49) }
            };

            var expected2 = new DiagnosticResult
            {
                Id = "DaVinciOC3",
                Message = "'parameter2' should be wrapped as it's a primitive.",
                Severity = DiagnosticSeverity.Info,
                Locations = new[] { new DiagnosticResultLocation("Test0.cs", 4, 66) }
            };

            VerifyCSharpDiagnostic(Code, expected1, expected2);
        }
        public void ConstructorParameterDocumentationAddSingleParameterTest()
        {
            var test = @"
using System;
namespace ConsoleApplication1
{
    public class TypeName
    {
        /// <summary>
        /// a description has been provided.
        /// line 2 of the description.
        /// </summary>
        /// <param name=""parameterOne"">there is some documentation</param>
        /// <param name=""parameterTwo""></param>
        public TypeName(
            string parameterOne,
            int parameterItemTwo,
            string parameterThree)
        {
        }
    }
}";
            var expected = new DiagnosticResult
            {
                Id = "SA1642D",
                Message = $"constructors must be correctly documented.",
                Severity = DiagnosticSeverity.Warning,
                Locations =
                    new[] { new DiagnosticResultLocation("Test0.cs", 13, 16) }
            };

            new DocumentationConstructorCodeFixVerifier().VerifyCSharpDiagnostic(test, expected);

            var fixtest = @"
using System;
namespace ConsoleApplication1
{
    public class TypeName
    {
        /// <summary>
        /// Initializes a new instance of the <see cref=""TypeName""/> class.
        /// a description has been provided.
        /// line 2 of the description.
        /// </summary>
        /// <param name=""parameterOne"">there is some documentation</param>
        /// <param name=""parameterItemTwo"">the parameter item two.</param>
        /// <param name=""parameterThree"">the parameter three.</param>
        public TypeName(
            string parameterOne,
            int parameterItemTwo,
            string parameterThree)
        {
        }
    }
}";
            new DocumentationConstructorCodeFixVerifier().VerifyCSharpFix(test, fixtest);
        }
        public void TestMethodBuildsCorrectMethodSummaryAfterFix()
        {
            var test = @"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class TypeName
    {
        public void BuildVogonConstructorFleet()
        {
        }
    }
}";
            var expected = new DiagnosticResult
            {
                Id = "SA1612D",
                Message = $"method documentation: no documentation.",
                Severity = DiagnosticSeverity.Warning,
                Locations =
                    new[] { new DiagnosticResultLocation("Test0.cs", 13, 21) }
            };

            new DocumentationMethodCodeFixVerifier().VerifyCSharpDiagnostic(test, expected);

            var fixtest = @"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class TypeName
    {
        /// <summary>
        /// build the vogon constructor fleet.
        /// </summary>
        public void BuildVogonConstructorFleet()
        {
        }
    }
}";
            new DocumentationMethodCodeFixVerifier().VerifyCSharpFix(test, fixtest);
        }
        public void VerifyMissingQuickFixReplacesDocumentation()
        {
            var test = @"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class TypeName
    {
        public string TestProperty { get; set; }
    }
}";
            var expected = new DiagnosticResult
            {
                Id = "SA1623D",
                Message = $"property documentation: no documentation.",
                Severity = DiagnosticSeverity.Warning,
                Locations =
                    new[] { new DiagnosticResultLocation("Test0.cs", 13, 23) }
            };

            this.VerifyCSharpDiagnostic(test, expected);

            var fixtest = @"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class TypeName
    {
        /// <summary>
        /// Gets or sets the test property.
        /// </summary>
        public string TestProperty { get; set; }
    }
}";
            this.VerifyCSharpFix(test, fixtest);
        }
        public void TestThatReturnValuesAreNotReplaced()
        {
            var test = @"
namespace ConsoleApplication1
{
    class TypeName
    {
        /// <summary>
        /// build the vogon constructor fleet.       
        /// </summary>
        /// <returns>the result of the application</returns>
        public static int Main<T>(string[] arguments)
        {
        }
    }
}";
            var expected = new DiagnosticResult
            {
                Id = "SA1612D",
                Message = $"method documentation: missing 'arguments'.",
                Severity = DiagnosticSeverity.Warning,
                Locations =
                    new[] { new DiagnosticResultLocation("Test0.cs", 10, 27) }
            };

            new DocumentationMethodCodeFixVerifier().VerifyCSharpDiagnostic(test, expected);

            var fixtest = @"
namespace ConsoleApplication1
{
    class TypeName
    {
        /// <summary>
        /// build the vogon constructor fleet.
        /// </summary>
        /// <param name=""arguments"">the arguments.</param>
        /// <returns>the result of the application</returns>
        /// <typeparam name=""T"">a type of {T}.</typeparam>
        public static int Main<T>(string[] arguments)
        {
        }
    }
}";
            new DocumentationMethodCodeFixVerifier().VerifyCSharpFix(test, fixtest);
        }
        public void TestMethod2()
        {
            var test = @"
            using System;
            using System.Collections.Generic;
            using System.Linq;
            using System.Text;
            using System.Threading.Tasks;
            using System.Diagnostics;

            namespace ConsoleApplication1
            {
            class TypeName
            {
            }
            }";
            var expected = new DiagnosticResult
            {
                Id = "ConfigureAwaitAnalyzer",
                Message = String.Format("Type name '{0}' contains lowercase letters", "TypeName"),
                Severity = DiagnosticSeverity.Warning,
                Locations =
                    new[] {
                            new DiagnosticResultLocation("Test0.cs", 11, 15)
                        }
            };

            this.VerifyCSharpDiagnostic(test, expected);

            var fixtest = @"
            using System;
            using System.Collections.Generic;
            using System.Linq;
            using System.Text;
            using System.Threading.Tasks;
            using System.Diagnostics;

            namespace ConsoleApplication1
            {
            class TYPENAME
            {
            }
            }";
            this.VerifyCSharpFix(test, fixtest);
        }
        public void TestStaticMainMethodWithASingleParameter()
        {
            var test = @"
namespace ConsoleApplication1
{
    class TypeName
    {
        /// <summary>
        /// build the vogon constructor fleet.       
        /// </summary>
        /// <param name=""args""></param>
        public static void Main(string[] args)
        {
        }
    }
}";
            var expected = new DiagnosticResult
            {
                Id = "SA1612D",
                Message = $"method documentation: missing 'args'.",
                Severity = DiagnosticSeverity.Warning,
                Locations =
                    new[] { new DiagnosticResultLocation("Test0.cs", 10, 28) }
            };

            new DocumentationMethodCodeFixVerifier().VerifyCSharpDiagnostic(test, expected);

            var fixtest = @"
namespace ConsoleApplication1
{
    class TypeName
    {
        /// <summary>
        /// build the vogon constructor fleet.
        /// </summary>
        /// <param name=""args"">the args.</param>
        public static void Main(string[] args)
        {
        }
    }
}";
            new DocumentationMethodCodeFixVerifier().VerifyCSharpFix(test, fixtest);
        }
        public async void AllowMembersOrderingForMoreThanOneMemberShouldTiggerDiagnostic(string typeDeclaration)
        {
            var test = @"
            " + typeDeclaration + @" Foo
            {
                int bar() { return 0; }
                void car() { }
            }";

            var expected = new DiagnosticResult
            {
                Id = DiagnosticId.AllowMembersOrdering.ToDiagnosticId(),
                Message = AllowMembersOrderingAnalyzer.MessageFormat,
                Severity = DiagnosticSeverity.Hidden,
                Locations = new[] { new DiagnosticResultLocation("Test0.cs", 2, 14 + typeDeclaration.Length) }
            };

            await VerifyCSharpDiagnosticAsync(test, expected);
        }
        public void TestNamedMethodWithStringReturnValue()
        {
            var test = @"
namespace ConsoleApplication1
{
    class TypeName
    {
        /// <summary>
        /// build the vogon constructor fleet.
        /// </summary>
        public int PerformAFunction()
        {
        }
    }
}";
            var expected = new DiagnosticResult
            {
                Id = "SA1612D",
                Message = $"method documentation: missing return value documentation.",
                Severity = DiagnosticSeverity.Warning,
                Locations =
                    new[] { new DiagnosticResultLocation("Test0.cs", 9, 20) }
            };

            new DocumentationMethodCodeFixVerifier().VerifyCSharpDiagnostic(test, expected);

            var fixtest = @"
namespace ConsoleApplication1
{
    class TypeName
    {
        /// <summary>
        /// build the vogon constructor fleet.
        /// </summary>
        /// <returns>an int containing the perform a function.</returns>
        public int PerformAFunction()
        {
        }
    }
}";
            new DocumentationMethodCodeFixVerifier().VerifyCSharpFix(test, fixtest);
        }
        public void ClassHasThreeFields_OneDiagnosticReportedShowingThreeFields()
        {
            const string Code = @"
            class SomeClass
            {
                private int firstField;
                private int secondField;
                private int thirdField;
            }";

            var expected = new DiagnosticResult
            {
                Id = "DaVinciOC8",
                Message = "\'SomeClass\' contains more than 2 fields (3).",
                Severity = DiagnosticSeverity.Info,
                Locations = new[] { new DiagnosticResultLocation("Test0.cs", 2, 19) }
            };

            VerifyCSharpDiagnostic(Code, expected);
        }
        public void ClassContainsOneProperty_OneDiagnosticReported()
        {
            const string Code = @"
            class SomeClass
            {
                public int SomeProperty { get; set; }
            }";

            var expected = new DiagnosticResult
            {
                Id = "DaVinciOC9",
                Message = "\'SomeProperty\' is a property and should be avoided.",
                Severity = DiagnosticSeverity.Info,
                Locations =
                    new[] {
                            new DiagnosticResultLocation("Test0.cs", 4, 28)
                        }
            };

            VerifyCSharpDiagnostic(Code, expected);
        }
        public void TestThatExistingTypeParametersAreNotOverridden()
        {
            var test = @"
using System;
namespace ConsoleApplication1
{
    /// <typeparam name=""TTypePayload"">existing documentation must not change</typeparam>
    public class ThisIsALongTypeName<TTypePayload, TOther>
    {
        private int Test { get; set; }
    }
}";
            var expected = new DiagnosticResult
            {
                Id = "SA1606D",
                Message = $"class documentation: no documentation.",
                Severity = DiagnosticSeverity.Warning,
                Locations =
                    new[] { new DiagnosticResultLocation("Test0.cs", 6, 18) }
            };

            new DocumentationClassFixVerifier().VerifyCSharpDiagnostic(test, expected);

            var fixtest = @"
using System;
namespace ConsoleApplication1
{
    /// <summary>
    /// this is a long type name.
    /// </summary>
    /// <typeparam name=""TTypePayload"">existing documentation must not change</typeparam>
    /// <typeparam name=""TOther"">a type of other.</typeparam>
    public class ThisIsALongTypeName<TTypePayload, TOther>
    {
        private int Test { get; set; }
    }
}";
            new DocumentationClassFixVerifier().VerifyCSharpFix(test, fixtest);
        }
Example #23
0
        public async Task IfRegexIdentifierFoundAndRegexTextIsIncorrectCreatesDiagnostic()
        {
            const string source = @"
    using System;
    using System.Text.RegularExpressions;

    namespace ConsoleApplication1
    {
        class TypeName
        {
            public async Task Foo()
            {
                System.Text.RegularExpressions.Regex.Match("""", ""["");
            }
        }
    }";

            var message = "";
            try
            {
#pragma warning disable CC0010
                System.Text.RegularExpressions.Regex.Match("", "[");
#pragma warning restore CC0010
            }
            catch (ArgumentException e)
            {
                message = e.Message;
            }

            var expected = new DiagnosticResult
            {
                Id = DiagnosticId.Regex.ToDiagnosticId(),
                Message = message,
                Severity = DiagnosticSeverity.Error,
                Locations = new[] { new DiagnosticResultLocation("Test0.cs", 11, 64) }
            };

            await VerifyCSharpDiagnosticAsync(source, expected);
        }
        public void TestThatReturnTypeDocumentationContainsCorrectReturnDocumentation()
        {
            var test = @"
namespace ConsoleApplication1
{
    class TypeName
    {
        public ITestAnInterfaceTypeReturnValue Observe(string vogonConstructorFleet)
        {
        }
    }
}";
            var expected = new DiagnosticResult
                               {
                                   Id = "SA1612D",
                                   Message = $"method documentation: no documentation.",
                                   Severity = DiagnosticSeverity.Warning,
                                   Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 48) }
                               };

            new DocumentationMethodCodeFixVerifier().VerifyCSharpDiagnostic(test, expected);

            var fixtest = @"
namespace ConsoleApplication1
{
    class TypeName
    {
        /// <summary>
        /// observe the vogon constructor fleet.
        /// </summary>
        /// <param name=""vogonConstructorFleet"">the vogon constructor fleet.</param>
        /// <returns>the test an interface type return value.</returns>
        public ITestAnInterfaceTypeReturnValue Observe(string vogonConstructorFleet)
        {
        }
    }
}";
            new DocumentationMethodCodeFixVerifier().VerifyCSharpFix(test, fixtest);
        }
        public async Task IfVirtualMethodWithThisFoundInConstructorCreatesDiagnostic() {
            const string test = @"
public class Person
{{
	public Person(string foo) 
	{{
		this.DoFoo(foo);
	}}

	public virtual void DoFoo(string foo) 
	{{ 
	}}
}}";
            var expected = new DiagnosticResult {
                Id = DiagnosticId.VirtualMethodOnConstructor.ToDiagnosticId(),
                Message = VirtualMethodOnConstructorAnalyzer.Message,
                Severity = DiagnosticSeverity.Warning,
                Locations = new[] { new DiagnosticResultLocation("Test0.cs", 6, 3) }
            };

            await VerifyCSharpDiagnosticAsync(test, expected);
        }
        public void TestThatSingleWordMethodDocumentationIncludesFirstParameter()
        {
            var test = @"
namespace ConsoleApplication1
{
    class TypeName
    {
        public void Observe(string vogonConstructorFleet)
        {
        }
    }
}";
            var expected = new DiagnosticResult
                               {
                                   Id = "SA1612D",
                                   Message = $"method documentation: no documentation.",
                                   Severity = DiagnosticSeverity.Warning,
                                   Locations =
                                       new[] { new DiagnosticResultLocation("Test0.cs", 6, 21) }
                               };

            new DocumentationMethodCodeFixVerifier().VerifyCSharpDiagnostic(test, expected);

            var fixtest = @"
namespace ConsoleApplication1
{
    class TypeName
    {
        /// <summary>
        /// observe the vogon constructor fleet.
        /// </summary>
        /// <param name=""vogonConstructorFleet"">the vogon constructor fleet.</param>
        public void Observe(string vogonConstructorFleet)
        {
        }
    }
}";
            new DocumentationMethodCodeFixVerifier().VerifyCSharpFix(test, fixtest);
        }
        public void DiagnosticForMethod()
        {
            var source = @"
using System.Threading;
class T
{
    void M(CancellationToken t, int i)
    {
    }
}";
            var expected = new DiagnosticResult
            {
                Id = CancellationTokenParametersMustComeLastAnalyzer.RuleId,
                Message = string.Format(MicrosoftApiDesignGuidelinesAnalyzersResources.CancellationTokenParametersMustComeLastMessage, "T.M(System.Threading.CancellationToken, int)"),
                Severity = DiagnosticSeverity.Warning,
                Locations = new[]
                {
                    new DiagnosticResultLocation("Test0.cs", 5, 10)
                }
            };

            VerifyCSharp(source, expected);
        }
        public void TestThatGeneratedCodeDoesNotTrigger()
        {
            var test = @"
//
// <auto-generated />
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class TypeName
    {
        public string VogonConstructorFleet { get; set; }
    }
}";
            var expected = new DiagnosticResult[] { };
            new DocumentationPropertyCodeFixVerifier().VerifyCSharpDiagnostic(test, expected);
        }
        public void TestPropertyWithoutCorrectText()
        {
            var test = @"
namespace ConsoleApplication1
{
    class TypeName
    {
        /// <summary>
        /// Gets or sets the test.
        /// </summary>
        public string SomeProperty { get; private set; }
    }
}";
            var expected = new DiagnosticResult
            {
                Id = "SA1623D",
                Message = $"property documentation: does not start with 'Gets the'.",
                Severity = DiagnosticSeverity.Warning,
                Locations =
                    new[] { new DiagnosticResultLocation("Test0.cs", 9, 23) }
            };

            new DocumentationPropertyCodeFixVerifier().VerifyCSharpDiagnostic(test, expected);

            var fixtest = @"
namespace ConsoleApplication1
{
    class TypeName
    {
        /// <summary>
        /// Gets the test.
        /// </summary>
        public string SomeProperty { get; private set; }
    }
}";
            new DocumentationPropertyCodeFixVerifier().VerifyCSharpFix(test, fixtest);
        }
        public void TestThatPropertyFixDoesNotEraseExistingCommentText()
        {
            var test = @"
namespace ConsoleApplication1
{
    class TypeName
    {
        /// <summary>
        /// returns an interresting property value.
        /// </summary>
        public string SomeProperty { get; set; }
    }
}";
            var expected = new DiagnosticResult
            {
                Id = "SA1623D",
                Message = $"property documentation: does not start with 'Gets or sets the'.",
                Severity = DiagnosticSeverity.Warning,
                Locations =
                    new[] { new DiagnosticResultLocation("Test0.cs", 9, 23) }
            };

            new DocumentationPropertyCodeFixVerifier().VerifyCSharpDiagnostic(test, expected);

            var fixtest = @"
namespace ConsoleApplication1
{
    class TypeName
    {
        /// <summary>
        /// Gets or sets the interresting property value.
        /// </summary>
        public string SomeProperty { get; set; }
    }
}";
            new DocumentationPropertyCodeFixVerifier().VerifyCSharpFix(test, fixtest);
        }
        public async Task WeakCipherModeECB()
        {
            const string cSharpTest = @"
using System;
using System.IO;
using System.Security.Cryptography;
using static System.Security.Cryptography.CipherMode;
using System.Text;

class WeakCipherMode
{
    public static string EncryptECB(string decryptedString)
    {
        DESCryptoServiceProvider desProvider = new DESCryptoServiceProvider();
        desProvider.Mode = ECB;
        desProvider.Padding = PaddingMode.PKCS7;
        desProvider.Key = Encoding.ASCII.GetBytes(""d66cf8"");
        using (MemoryStream stream = new MemoryStream())
        {
            using (CryptoStream cs = new CryptoStream(stream, desProvider.CreateEncryptor(), CryptoStreamMode.Write))
            {
                byte[] data = Encoding.Default.GetBytes(decryptedString);
                cs.Write(data, 0, data.Length);
                return Convert.ToBase64String(stream.ToArray());
            }
        }
    }
}
";

            const string visualBasicTest = @"
Imports System
Imports System.IO
Imports System.Security.Cryptography
Imports System.Security.Cryptography.CipherMode
Imports System.Text

Class WeakCipherMode
    Public Shared Function EncryptECB(decryptedString As String) As String
        Dim desProvider As New DESCryptoServiceProvider()
        desProvider.Mode = ECB
        desProvider.Padding = PaddingMode.PKCS7
        desProvider.Key = Encoding.ASCII.GetBytes(""d66cf8"")

        Using stream As New MemoryStream()
            Using cs As New CryptoStream(stream, desProvider.CreateEncryptor(), CryptoStreamMode.Write)
                Dim data As Byte() = Encoding.[Default].GetBytes(decryptedString)
                cs.Write(data, 0, data.Length)
                Return Convert.ToBase64String(stream.ToArray())
            End Using
        End Using
    End Function
End Class
";

            var expected = new DiagnosticResult
            {
                Id       = "SCS0012",
                Severity = DiagnosticSeverity.Warning,
            };

            await VerifyCSharpDiagnostic(cSharpTest, expected).ConfigureAwait(false);
            await VerifyVisualBasicDiagnostic(visualBasicTest, expected).ConfigureAwait(false);
        }
 private static DiagnosticResult CreateResult(params object[] formatMessageArgs)
 {
     return(DiagnosticResult.Create(DisposeLocallyAnalyzer.BS3001, formatMessageArgs));
 }
Example #33
0
        public async Task TransferMemoryStream()
        {
            var cSharpTest = @"
#pragma warning disable 8019
    using System;
    using System.IO;
    using System.Text;
    using System.Data.SqlClient;
#pragma warning restore 8019

class SqlTransferTesting
{
    public void Run(string input)
    {
        var query = """";
        var bytes = Encoding.ASCII.GetBytes(input);
        using(var stream = new MemoryStream())
        {
            stream.Write(bytes, 0, bytes.Length);
            StreamReader reader = new StreamReader( stream );
            query = reader.ReadToEnd();
        }
        new SqlCommand(query);
    }
}
";

            var visualBasicTest = @"
#Disable Warning BC50001
    Imports System
    Imports System.IO
    Imports System.Text
    Imports System.Data.SqlClient
#Enable Warning BC50001

Friend Class SqlTransferTesting
    Public Sub Run(ByVal input As String)
        Dim query = """"
        Dim bytes = Encoding.ASCII.GetBytes(input)

        Using stream = New MemoryStream()
            stream.Write(bytes, 0, bytes.Length)
            Dim reader As StreamReader = New StreamReader(stream)
            query = reader.ReadToEnd()
        End Using

        Dim a = New SqlCommand(query)
    End Sub
End Class
";

            var expected = new DiagnosticResult
            {
                Id       = "SCS0026",
                Severity = DiagnosticSeverity.Warning,
            };

            var testConfig = @"
TaintEntryPoints:
  AAA:
    ClassName: SqlTransferTesting
";

            var optionsWithProjectConfig = ConfigurationTest.CreateAnalyzersOptionsWithConfig(testConfig);

            await VerifyCSharpDiagnostic(cSharpTest, expected, optionsWithProjectConfig).ConfigureAwait(false);
            await VerifyVisualBasicDiagnostic(visualBasicTest, expected, optionsWithProjectConfig).ConfigureAwait(false);
        }
Example #34
0
        public async Task MergePostConditions(string cs, string className, string name, string outParam, string taintFromArguments, bool warn)
        {
            var cSharpTest = $@"
using System.Data.SqlClient;

class Test
{{
    public string Foo(string a, string b)
    {{
        return null;
    }}

    public void Run(string a, string b)
    {{
#pragma warning disable CS0219
        Test o = null;
#pragma warning restore CS0219
        {cs}
        new SqlCommand(query);
    }}
}}
";

            var visualBasicTest = $@"
Imports System.Data.SqlClient

Class Test
    Public Function Foo(ByVal a As String, ByVal b As String) As String
        Return Nothing
    End Function

    Public Sub Run(ByVal a As String, ByVal b As String)
        Dim o As Test = Nothing
        {cs.CSharpReplaceToVBasic()}
        Dim temp = New SqlCommand(query)
    End Sub
End Class
";

            var expected = new DiagnosticResult
            {
                Id       = "SCS0026",
                Severity = DiagnosticSeverity.Warning,
            };

            var testConfig = $@"
TaintEntryPoints:
  AAA:
    ClassName: Test

Behavior:
  BBB:
    ClassName: {className}
    Name: {name}
    Method:
      If:
        Condition: {{1: {{Value: """"}}}}
        Then:
          {outParam}:
            Taint: LocalUrl
      {outParam}:
        {taintFromArguments}
";

            var optionsWithProjectConfig = ConfigurationTest.CreateAnalyzersOptionsWithConfig(testConfig);

            if (warn)
            {
                await VerifyCSharpDiagnostic(cSharpTest, expected, optionsWithProjectConfig).ConfigureAwait(false);
                await VerifyVisualBasicDiagnostic(visualBasicTest, expected, optionsWithProjectConfig).ConfigureAwait(false);
            }
            else
            {
                await VerifyCSharpDiagnostic(cSharpTest, null, optionsWithProjectConfig).ConfigureAwait(false);
                await VerifyVisualBasicDiagnostic(visualBasicTest, null, optionsWithProjectConfig).ConfigureAwait(false);
            }
        }
Example #35
0
        public void Guid_NonDeterministicMethod_AllGuidCases()
        {
            var test = @"
    using System;
    using System.Threading.Tasks;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.DurableTask;

    namespace VSSample
    {
        public static class HelloSequence
        {
            [FunctionName(""GuidAnalyzerTestCases"")]
            public static async Task Run(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
            {
                DirectCall();
            }

        public static string DirectCall()
        {
            " + allTests;


            var expectedDiagnostics = new DiagnosticResult[3];

            expectedDiagnostics[0] = new DiagnosticResult
            {
                Id        = MethodInvocationAnalyzer.DiagnosticId,
                Message   = string.Format(Resources.MethodAnalyzerMessageFormat, "DirectCall()"),
                Severity  = Severity,
                Locations =
                    new[] {
                    new DiagnosticResultLocation("Test0.cs", 15, 17)
                }
            };

            expectedDiagnostics[1] = new DiagnosticResult
            {
                Id        = DiagnosticId,
                Message   = string.Format(Resources.DeterministicAnalyzerMessageFormat, "Guid.NewGuid"),
                Severity  = Severity,
                Locations =
                    new[] {
                    new DiagnosticResultLocation("Test0.cs", 23, 13)
                }
            };

            expectedDiagnostics[2] = new DiagnosticResult
            {
                Id        = DiagnosticId,
                Message   = string.Format(Resources.DeterministicAnalyzerMessageFormat, "System.Guid.NewGuid"),
                Severity  = Severity,
                Locations =
                    new[] {
                    new DiagnosticResultLocation("Test0.cs", 24, 13)
                }
            };

            VerifyCSharpDiagnostic(test, expectedDiagnostics);
        }
Example #36
0
        public override Task <DiagnosticResult> Examine(SharedState history)
        {
            var jdkPath = history.GetEnvironmentVariable("JAVA_HOME") ?? Environment.GetEnvironmentVariable("JAVA_HOME");

            string androidSdkPath = null;

            try
            {
                // Set the logger to override the default one that is set in this library
                // So we can catch output from failed path lookups that are otherwise swallowed
                var _ = new AndroidSdkInfo((traceLevel, msg) =>
                {
                    if (Util.Verbose || traceLevel == System.Diagnostics.TraceLevel.Error)
                    {
                        Util.LogAlways(msg);
                    }
                }, androidSdkPath, null, jdkPath);
            }
            catch (Exception ex)
            {
                Util.Exception(ex);
            }

            if (string.IsNullOrEmpty(androidSdkPath))
            {
                androidSdkPath = FindBestSdkLocation();
            }

            var missingPackages = new List <IAndroidComponent>();

            var installer = new AndroidSDKInstaller(new Helper(), AndroidManifestType.GoogleV2);

            installer.Discover(new List <string> {
                androidSdkPath
            });

            var sdkInstance = installer.FindInstance(androidSdkPath);

            if (string.IsNullOrEmpty(sdkInstance?.Path))
            {
                return(Task.FromResult(
                           new DiagnosticResult(
                               Status.Error,
                               this,
                               "Failed to find Android SDK.",
                               new Suggestion("Install the Android SDK",
                                              "For more information see: [underline]https://aka.ms/dotnet-androidsdk-help[/]"))));
            }

            history.SetEnvironmentVariable("ANDROID_SDK_ROOT", sdkInstance.Path);
            history.SetEnvironmentVariable("ANDROID_HOME", sdkInstance.Path);

            var installed = sdkInstance?.Components?.AllInstalled(true);

            foreach (var package in RequiredPackages)
            {
                var v = !string.IsNullOrWhiteSpace(package.Version) ? new AndroidRevision(package.Version) : null;

                var installedPkg = FindInstalledPackage(installed, package)
                                   ?? FindInstalledPackage(installed, package.Alternatives?.ToArray());

                if (installedPkg == null)
                {
                    var pkgToInstall = sdkInstance?.Components?.AllNotInstalled()?
                                       .FirstOrDefault(p => p.Path.Equals(package.Path.Trim(), StringComparison.OrdinalIgnoreCase) &&
                                                       p.Revision >= (v ?? p.Revision));

                    ReportStatus($"{package.Path} ({package.Version}) missing.", Status.Error);

                    if (pkgToInstall != null)
                    {
                        missingPackages.Add(pkgToInstall);
                    }
                }
                else
                {
                    if (!package.Path.Equals(installedPkg.Path) || v != (installedPkg.Revision ?? installedPkg.InstalledRevision))
                    {
                        ReportStatus($"{installedPkg.Path} ({installedPkg.InstalledRevision ?? installedPkg.Revision})", Status.Ok);
                    }
                    else
                    {
                        ReportStatus($"{package.Path} ({package.Version})", Status.Ok);
                    }
                }
            }

            if (!missingPackages.Any())
            {
                return(Task.FromResult(DiagnosticResult.Ok(this)));
            }


            var installationSet = installer.GetInstallationSet(sdkInstance, missingPackages);

            var desc =
                @$ "Your Android SDK has missing or outdated packages.
You can use the Android SDK Manager to install / update them.
For more information see: [underline]https://aka.ms/dotnet-androidsdk-help[/]";
        public void WhenFixingMayAddExtraUnnededReturn()
        {
            var test = @"
using System;
using System.Web.Http;

namespace Test
{
    public class FooBar: ApiController
    {
        public void ViolatingMethod(int a)
        {
            if(a > 0)
            {
                return;
            } 
            else 
            {
                return;
            }
        }
    }
}";

            var expected = new DiagnosticResult
            {
                Id      = "AnalyzerWebApiNoVoidReturn",
                Message = String.Format(
                    AnalyzerWebApiNoVoidReturnAnalyzer.MessageFormat,
                    "FooBar",
                    "ViolatingMethod"),
                Severity  = DiagnosticSeverity.Error,
                Locations =
                    new[] {
                    new DiagnosticResultLocation("Test0.cs", 9, 21)
                }
            };

            VerifyCSharpDiagnostic(test, expected);

            var fixtest = @"
using System;
using System.Web.Http;

namespace Test
{
    public class FooBar: ApiController
    {
        public int ViolatingMethod(int a)
        {
            if(a > 0)
            {
                return new Random().Next();
            } 
            else 
            {
                return new Random().Next();
            }

            return new Random().Next();
        }
    }
}";

            VerifyCSharpFix(test, fixtest, allowNewCompilerDiagnostics: true);
        }
Example #38
0
 private static Task VerifyCSharpFixAsync(string source, DiagnosticResult expected, string fixedSource, CancellationToken cancellationToken)
 => VerifyCSharpFixAsync(source, new[] { expected }, fixedSource, cancellationToken);
        private async Task <int> ExecuteAsync(string output)
        {
            // Don't use IStandardStreams for writing output in this command as we
            // cannot trust any component on the ICommandContext is working correctly.
            Console.WriteLine($"Running diagnostics...{Environment.NewLine}");

            if (_diagnostics.Count == 0)
            {
                Console.WriteLine("No diagnostics to run.");
                return(0);
            }

            int numFailed  = 0;
            int numSkipped = 0;

            string currentDir = Directory.GetCurrentDirectory();
            string outputDir;

            if (string.IsNullOrWhiteSpace(output))
            {
                outputDir = currentDir;
            }
            else
            {
                if (!Directory.Exists(output))
                {
                    Directory.CreateDirectory(output);
                }

                outputDir = Path.GetFullPath(Path.Combine(currentDir, output));
            }

            string logFilePath = Path.Combine(outputDir, "gcm-diagnose.log");
            var    extraLogs   = new List <string>();

            using var fullLog = new StreamWriter(logFilePath, append: false, Encoding.UTF8);
            fullLog.WriteLine("Diagnose log at {0:s}Z", DateTime.UtcNow);
            fullLog.WriteLine();
            fullLog.WriteLine($"Executable: {_context.ApplicationPath}");
            fullLog.WriteLine(
                TryGetAssemblyVersion(out string version)
                    ? $"Version: {version}"
                    : "Version: [!] Failed to get version information [!]"
                );
            fullLog.WriteLine();

            foreach (IDiagnostic diagnostic in _diagnostics)
            {
                fullLog.WriteLine("------------");
                fullLog.WriteLine($"Diagnostic: {diagnostic.Name}");

                if (!diagnostic.CanRun())
                {
                    fullLog.WriteLine("Skipped: True");
                    fullLog.WriteLine();

                    Console.Write(" ");
                    ConsoleEx.WriteColor("[SKIP]", ConsoleColor.Gray);
                    Console.WriteLine(" {0}", diagnostic.Name);

                    numSkipped++;
                    continue;
                }

                string inProgressMsg = $"  >>>>  {diagnostic.Name}";
                Console.Write(inProgressMsg);

                fullLog.WriteLine("Skipped: False");
                DiagnosticResult result = await diagnostic.RunAsync();

                fullLog.WriteLine("Success: {0}", result.IsSuccess);

                if (result.Exception is null)
                {
                    fullLog.WriteLine("Exception: None");
                }
                else
                {
                    fullLog.WriteLine("Exception:");
                    fullLog.WriteLine(result.Exception.ToString());
                }

                fullLog.WriteLine("Log:");
                fullLog.WriteLine(result.DiagnosticLog);

                Console.Write(new string('\b', inProgressMsg.Length - 1));
                ConsoleEx.WriteColor(
                    result.IsSuccess ? "[ OK ]" : "[FAIL]",
                    result.IsSuccess ? ConsoleColor.DarkGreen : ConsoleColor.Red
                    );
                Console.WriteLine(" {0}", diagnostic.Name);

                if (!result.IsSuccess)
                {
                    numFailed++;

                    if (result.Exception is not null)
                    {
                        Console.WriteLine();
                        ConsoleEx.WriteLineIndent("[!] Encountered an exception [!]");
                        ConsoleEx.WriteLineIndent(result.Exception.ToString());
                    }

                    Console.WriteLine();
                    ConsoleEx.WriteLineIndent("[*] Diagnostic test log [*]");
                    ConsoleEx.WriteLineIndent(result.DiagnosticLog);

                    Console.WriteLine();
                }

                foreach (string filePath in result.AdditionalFiles)
                {
                    string fileName = Path.GetFileName(filePath);
                    string destPath = Path.Combine(outputDir, fileName);
                    try
                    {
                        File.Copy(filePath, destPath, overwrite: true);
                    }
                    catch
                    {
                        ConsoleEx.WriteLineIndent($"Failed to copy additional file '{filePath}'");
                    }

                    extraLogs.Add(destPath);
                }

                fullLog.Flush();
            }

            Console.WriteLine();
            string summary = $"Diagnostic summary: {_diagnostics.Count - numFailed} passed, {numSkipped} skipped, {numFailed} failed.";

            Console.WriteLine(summary);
            Console.WriteLine("Log files:");
            Console.WriteLine($"  {logFilePath}");
            foreach (string log in extraLogs)
            {
                Console.WriteLine($"  {log}");
            }
            Console.WriteLine();
            Console.WriteLine("Caution: Log files may include sensitive information - redact before sharing.");
            Console.WriteLine();

            if (numFailed > 0)
            {
                Console.WriteLine("Diagnostics indicate a possible problem with your installation.");
                Console.WriteLine($"Please open an issue at {Constants.HelpUrls.GcmNewIssue} and include log files.");
                Console.WriteLine();
            }

            fullLog.Close();
            return(numFailed);
        }
 /// <inheritdoc cref="CodeRefactoringVerifier{TCodeRefactoring, TTest, TVerifier}.VerifyRefactoringAsync(string, DiagnosticResult, string)"/>
 public static async Task VerifyRefactoringAsync(string source, DiagnosticResult expected, string fixedSource)
 {
     await VerifyRefactoringAsync(source, new[] { expected }, fixedSource);
 }
Example #41
0
        private void AssertSingleDiagnostic(string file, int line, int column)
        {
            DiagnosticResult result = CreateDiagnosticResult(line, column);

            VerifyCSharpDiagnostic(file, result);
        }
 protected Task TestKeywordStatementAsync(string statement, DiagnosticResult expected, string fixedStatement, string returnType = "void", bool asyncMethod = false, LanguageVersion?languageVersion = default)
 {
     return(this.TestKeywordStatementAsync(statement, new[] { expected }, fixedStatement, returnType, asyncMethod, languageVersion));
 }
Example #43
0
        public async Task TestPropertyWithMultipleInlineCommentsAsync()
        {
            var testCode = @"
public class Foo
{
    /// <summary>
    /// Gets the test property.
    /// </summary>
    public int Prop
    {
        /* c1 */ get /* c2 */ { /* c3 */ return 1; /* c4 */ } /* c5 */
        /* c6 */
        protected
        /* c7 */ internal
        /* c8 */ set /* c9 */
        {
            /* c10 */
        } /* c11 */
    }
}";

            var fixedTestCodeSingle = @"
public class Foo
{
    /// <summary>
    /// Gets the test property.
    /// </summary>
    public int Prop
    {
        /* c1 */ get /* c2 */ { /* c3 */ return 1; /* c4 */ } /* c5 */
        /* c6 */ protected /* c7 */ internal /* c8 */ set /* c9 */ { /* c10 */ } /* c11 */
    }
}";

            var fixedTestCodeMultiple = @"
public class Foo
{
    /// <summary>
    /// Gets the test property.
    /// </summary>
    public int Prop
    {
        /* c1 */ get /* c2 */
        { /* c3 */
            return 1; /* c4 */
        } /* c5 */

        /* c6 */ protected /* c7 */ internal /* c8 */ set /* c9 */
        { /* c10 */
        } /* c11 */
    }
}";

            DiagnosticResult expected = this.CSharpDiagnostic().WithLocation(9, 18);

            await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);

            await this.VerifyCSharpDiagnosticAsync(fixedTestCodeSingle, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);

            await this.VerifyCSharpDiagnosticAsync(fixedTestCodeMultiple, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);

            await this.VerifyCSharpFixAsync(testCode, fixedTestCodeSingle, codeFixIndex : 0).ConfigureAwait(false);

            await this.VerifyCSharpFixAsync(testCode, fixedTestCodeMultiple, codeFixIndex : 1).ConfigureAwait(false);
        }
Example #44
0
 private static Task VerifyCSharpDiagnosticAsync(string source, DiagnosticResult expected, CancellationToken cancellationToken)
 => VerifyCSharpDiagnosticAsync(source, TestSettings, new[] { expected }, cancellationToken);
Example #45
0
        public override async Task ReportsDiagnostic_ForNestedReEntrantCall()
        {
            var source = @"Imports NSubstitute

Namespace MyNamespace
    Interface IFoo
        Function Bar() As Integer
    End Interface

    Interface IBar
        Function Foo() As Integer
    End Interface

    Public Class FooTests
        Public Sub Test()
            Dim substitute = NSubstitute.Substitute.[For](Of IFoo)()
            SubstituteExtensions.Returns(Of Integer)(substitute.Bar(), ReturnThis(), OtherReturn())
        End Sub

        Private Function ReturnThis() As Integer
            Return OtherReturn()
        End Function

        Private Function OtherReturn() As Integer
            Dim substitute = NSubstitute.Substitute.[For](Of IBar)()
            SubstituteExtensions.Returns(Of Integer)(substitute.Foo(), NestedReturnThis())
            Return 1
        End Function

        Private Function NestedReturnThis() As Integer
            Return OtherNestedReturnThis()
        End Function

        Private Function OtherNestedReturnThis() As Integer
            Dim [sub] = Substitute.[For](Of IBar)()
            SubstituteExtensions.Returns(Of Integer)([sub].Foo(), 1)
            Return 1
        End Function
    End Class
End Namespace
";

            var firstArgumentDiagnostic = new DiagnosticResult
            {
                Id       = DiagnosticIdentifiers.ReEntrantSubstituteCall,
                Severity = DiagnosticSeverity.Warning,
                Message  =
                    "Returns() is set with a method that itself calls Returns. This can cause problems with NSubstitute. Consider replacing with a lambda: Returns(Function(x) ReturnThis()).",
                Locations = new[]
                {
                    new DiagnosticResultLocation(15, 72)
                }
            };

            var secondArgumentDiagnostic = new DiagnosticResult
            {
                Id       = DiagnosticIdentifiers.ReEntrantSubstituteCall,
                Severity = DiagnosticSeverity.Warning,
                Message  =
                    "Returns() is set with a method that itself calls Returns. This can cause problems with NSubstitute. Consider replacing with a lambda: Returns(Function(x) OtherReturn()).",
                Locations = new[]
                {
                    new DiagnosticResultLocation(15, 86)
                }
            };

            var nestedArgumentDiagnostic = new DiagnosticResult
            {
                Id       = DiagnosticIdentifiers.ReEntrantSubstituteCall,
                Severity = DiagnosticSeverity.Warning,
                Message  =
                    "Returns() is set with a method that itself calls Returns. This can cause problems with NSubstitute. Consider replacing with a lambda: Returns(Function(x) NestedReturnThis()).",
                Locations = new[]
                {
                    new DiagnosticResultLocation(24, 72)
                }
            };

            await VerifyDiagnostic(source, firstArgumentDiagnostic, secondArgumentDiagnostic, nestedArgumentDiagnostic);
        }
        public async Task DiagnosticsAndCodeFixes_WhenModelStateIsInNestedBlock()
        {
            // Arrange
            var expectedDiagnostic = new DiagnosticResult
            {
                Id        = "MVC1001",
                Message   = "Actions on types annotated with ApiControllerAttribute do not require explicit ModelState validity check.",
                Severity  = DiagnosticSeverity.Warning,
                Locations = new[] { new DiagnosticResultLocation("Test.cs", 15, 13) }
            };

            var test =
                @"
using Microsoft.AspNetCore.Mvc;

[ApiController]
public class PetController : ControllerBase
{
    public IActionResult GetPetId()
    {
        if (User == null)
        {
            return Unauthorized();
        }
        else
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            Debug.Assert(ModelState.Count == 0);
        }

        return Ok();
    }
}";
            var expectedFix =
                @"
using Microsoft.AspNetCore.Mvc;

[ApiController]
public class PetController : ControllerBase
{
    public IActionResult GetPetId()
    {
        if (User == null)
        {
            return Unauthorized();
        }
        else
        {
            Debug.Assert(ModelState.Count == 0);
        }

        return Ok();
    }
}";

            var project = CreateProject(test);

            // Act & Assert
            var actualDiagnostics = await GetDiagnosticAsync(project);

            Assert.DiagnosticsEqual(new[] { expectedDiagnostic }, actualDiagnostics);
            var actualFix = await ApplyCodeFixAsync(project, actualDiagnostics);

            Assert.Equal(expectedFix, actualFix, ignoreLineEndingDifferences: true);
        }
Example #47
0
        public async Task VariableConcatenationPropertyReadonlyContructorBackingField(string initializer, string accessor)
        {
            var cSharpTest = $@"
using System.Data.SqlClient;
#pragma warning disable 8019
    using System;
#pragma warning restore 8019

namespace sample
{{
    class MyFoo
    {{
        private readonly string StringConst = {initializer};
        public string stringConst
        {{
            get {{ return StringConst; }}
        }}

        public MyFoo(string x)
        {{
            StringConst = x;
        }}

        void Foo()
        {{
            var s          = ""select * from Products"";
            var sqlCommand = new SqlCommand(s + {accessor});
        }}
    }}
}}
";

            initializer = initializer.Replace("new ", "New ").Replace("'", "\"");
            accessor    = accessor.Replace("this.", "Me.");
            var visualBasicTest = $@"
Imports System.Data.SqlClient
#Disable Warning BC50001
    Imports System
#Enable Warning BC50001

Namespace sample
    Class MyFoo
        Private ReadOnly StringConstField As String = {initializer}
        Public ReadOnly Property stringConst() As String
            Get
                Return StringConstField
            End Get
        End Property
        Public Sub New(ByVal x as String)
            StringConstField = x
        End Sub
        Private Sub Foo()
            Dim s As String = ""select * from Products""

            Dim com As New SqlCommand(s + {accessor})
        End Sub
    End Class
End Namespace
";

            var expected = new DiagnosticResult
            {
                Id       = "SCS0026",
                Severity = DiagnosticSeverity.Warning,
            };

            await VerifyCSharpDiagnostic(cSharpTest, expected).ConfigureAwait(false);
            await VerifyVisualBasicDiagnostic(visualBasicTest, expected).ConfigureAwait(false);
        }
Example #48
0
        public async Task CSharp_NoDiagnosticCases_NestedOperationAnalyzerRegistration()
        {
            var source = @"
using System;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;

[DiagnosticAnalyzer(LanguageNames.CSharp)]
class MyAnalyzer : DiagnosticAnalyzer
{
    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics
    {
        get
        {
            throw new NotImplementedException();
        }
    }

    public override void Initialize(AnalysisContext context)
    {
        context.RegisterCompilationStartAction(compilationContext =>
        {
            compilationContext.RegisterOperationBlockStartAction(operationBlockContext =>
            {
                AnalyzeOperationBlockStart(operationBlockContext);
            });
        });

        context.RegisterCompilationStartAction(compilationContext =>
        {
            compilationContext.RegisterOperationAction(AnalyzeOperation, OperationKind.Invocation);
        });

        context.RegisterCompilationStartAction(compilationContext =>
        {
            compilationContext.RegisterOperationBlockAction(AnalyzeOperationBlock);
        });
    }

    private static void AnalyzeOperation(OperationAnalysisContext context)
    {
    }

    private static void AnalyzeOperationBlock(OperationBlockAnalysisContext context)
    {
    }

    private static void AnalyzeOperationBlockStart(OperationBlockStartAnalysisContext context)
    {
        context.RegisterOperationAction(AnalyzeOperation, OperationKind.Invocation);
    }
}";

            await new VerifyCS.Test
            {
                ReferenceAssemblies = ReferenceAssemblies.Default,
                TestState           =
                {
                    Sources             = { source },
                    ExpectedDiagnostics =
                    {
                        // Test0.cs(3,26): error CS0234: The type or namespace name 'Immutable' does not exist in the namespace 'System.Collections' (are you missing an assembly reference?)
                        DiagnosticResult.CompilerError("CS0234").WithSpan(3,  26,  3,                           35).WithArguments("Immutable", "System.Collections"),
                        // Test0.cs(4,17): error CS0234: The type or namespace name 'CodeAnalysis' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)
                        DiagnosticResult.CompilerError("CS0234").WithSpan(4,  17,  4,                        29).WithArguments("CodeAnalysis", "Microsoft"),
                        // Test0.cs(5,17): error CS0234: The type or namespace name 'CodeAnalysis' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?)
                        DiagnosticResult.CompilerError("CS0234").WithSpan(5,  17,  5,                        29).WithArguments("CodeAnalysis", "Microsoft"),
                        // Test0.cs(7,2): error CS0246: The type or namespace name 'DiagnosticAnalyzer' could not be found (are you missing a using directive or an assembly reference?)
                        DiagnosticResult.CompilerError("CS0246").WithSpan(7,   2,  7,                 20).WithArguments("DiagnosticAnalyzer"),
                        // Test0.cs(7,2): error CS0246: The type or namespace name 'DiagnosticAnalyzerAttribute' could not be found (are you missing a using directive or an assembly reference?)
                        DiagnosticResult.CompilerError("CS0246").WithSpan(7,   2,  7,        20).WithArguments("DiagnosticAnalyzerAttribute"),
                        // Test0.cs(7,21): error CS0103: The name 'LanguageNames' does not exist in the current context
                        DiagnosticResult.CompilerError("CS0103").WithSpan(7,  21,  7,                      34).WithArguments("LanguageNames"),
                        // Test0.cs(8,20): error CS0246: The type or namespace name 'DiagnosticAnalyzer' could not be found (are you missing a using directive or an assembly reference?)
                        DiagnosticResult.CompilerError("CS0246").WithSpan(8,  20,  8,                 38).WithArguments("DiagnosticAnalyzer"),
                        // Test0.cs(10,21): error CS0246: The type or namespace name 'ImmutableArray<>' could not be found (are you missing a using directive or an assembly reference?)
                        DiagnosticResult.CompilerError("CS0246").WithSpan(10, 21, 10,                   57).WithArguments("ImmutableArray<>"),
                        // Test0.cs(10,36): error CS0246: The type or namespace name 'DiagnosticDescriptor' could not be found (are you missing a using directive or an assembly reference?)
                        DiagnosticResult.CompilerError("CS0246").WithSpan(10, 36, 10,               56).WithArguments("DiagnosticDescriptor"),
                        // Test0.cs(10,58): error CS0115: 'MyAnalyzer.SupportedDiagnostics': no suitable method found to override
                        DiagnosticResult.CompilerError("CS0115").WithSpan(10, 58, 10,    78).WithArguments("MyAnalyzer.SupportedDiagnostics"),
                        // Test0.cs(18,37): error CS0246: The type or namespace name 'AnalysisContext' could not be found (are you missing a using directive or an assembly reference?)
                        DiagnosticResult.CompilerError("CS0246").WithSpan(18, 37, 18,                    52).WithArguments("AnalysisContext"),
                        // Test0.cs(39,42): error CS0246: The type or namespace name 'OperationAnalysisContext' could not be found (are you missing a using directive or an assembly reference?)
                        DiagnosticResult.CompilerError("CS0246").WithSpan(39, 42, 39,           66).WithArguments("OperationAnalysisContext"),
                        // Test0.cs(43,47): error CS0246: The type or namespace name 'OperationBlockAnalysisContext' could not be found (are you missing a using directive or an assembly reference?)
                        DiagnosticResult.CompilerError("CS0246").WithSpan(43, 47, 43,      76).WithArguments("OperationBlockAnalysisContext"),
                        // Test0.cs(47,52): error CS0246: The type or namespace name 'OperationBlockStartAnalysisContext' could not be found (are you missing a using directive or an assembly reference?)
                        DiagnosticResult.CompilerError("CS0246").WithSpan(47, 52, 47, 86).WithArguments("OperationBlockStartAnalysisContext"),
                        // Test0.cs(49,59): error CS0103: The name 'OperationKind' does not exist in the current context
                        DiagnosticResult.CompilerError("CS0103").WithSpan(49, 59, 49,                      72).WithArguments("OperationKind"),
                    },
                },
            }.RunAsync();
        }
Example #49
0
 private Task TestCommaInStatementOrDeclAsync(string originalStatement, DiagnosticResult expected, string fixedStatement)
 {
     return(this.TestCommaInStatementOrDeclAsync(originalStatement, new[] { expected }, fixedStatement));
 }
Example #50
0
        public async Task VisualBasic_NoDiagnosticCases_NestedOperationAnalyzerRegistration()
        {
            var source = @"
Imports System
Imports System.Collections.Immutable
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Diagnostics

<DiagnosticAnalyzer(LanguageNames.VisualBasic)> _
MustInherit Class MyAnalyzer
	Inherits DiagnosticAnalyzer
	Public Overrides ReadOnly Property SupportedDiagnostics() As ImmutableArray(Of DiagnosticDescriptor)
		Get
			Throw New NotImplementedException()
		End Get
	End Property

	Public Overrides Sub Initialize(context As AnalysisContext)
		context.RegisterCompilationStartAction(Function(compilationContext) 
                                                    compilationContext.RegisterOperationBlockStartAction(Function(operationBlockContext) 
		                                                                                                    AnalyzeOperationBlockStart(operationBlockContext)
                                                                                                         End Function)
                                               End Function)

		context.RegisterCompilationStartAction(Function(compilationContext) 
		                                         compilationContext.RegisterOperationAction(AddressOf AnalyzeOperation, OperationKind.Invocation)
                                               End Function)

		context.RegisterCompilationStartAction(Function(compilationContext) 
		                                            compilationContext.RegisterOperationBlockAction(AddressOf AnalyzeOperationBlock)
                                               End Function)
	End Sub

	Private Shared Sub AnalyzeOperation(context As OperationAnalysisContext)
	End Sub

	Private Shared Sub AnalyzeOperationBlock(context As OperationBlockAnalysisContext)
	End Sub

	Private Shared Sub AnalyzeOperationBlockStart(context As OperationBlockStartAnalysisContext)
		context.RegisterOperationAction(AddressOf AnalyzeOperation, OperationKind.Invocation)
	End Sub
End Class
";

            await new VerifyVB.Test
            {
                ReferenceAssemblies = ReferenceAssemblies.Default,
                TestState           =
                {
                    Sources             = { source },
                    ExpectedDiagnostics =
                    {
                        // Test0.vb(7) : error BC30002: Type 'DiagnosticAnalyzer' is not defined.
                        DiagnosticResult.CompilerError("BC30002").WithSpan(7,   2,  7,                 20).WithArguments("DiagnosticAnalyzer"),
                        // Test0.vb(7) : error BC30451: 'LanguageNames' is not declared. It may be inaccessible due to its protection level.
                        DiagnosticResult.CompilerError("BC30451").WithSpan(7,  21,  7,                      34).WithArguments("LanguageNames"),
                        // Test0.vb(9) : error BC30002: Type 'DiagnosticAnalyzer' is not defined.
                        DiagnosticResult.CompilerError("BC30002").WithSpan(9,  11,  9,                 29).WithArguments("DiagnosticAnalyzer"),
                        // Test0.vb(10) : error BC30284: property 'SupportedDiagnostics' cannot be declared 'Overrides' because it does not override a property in a base class.
                        DiagnosticResult.CompilerError("BC30284").WithSpan(10, 37, 10,                            57).WithArguments("property","SupportedDiagnostics"),
                        // Test0.vb(10) : error BC30002: Type 'ImmutableArray' is not defined.
                        DiagnosticResult.CompilerError("BC30002").WithSpan(10, 63, 10,                    102).WithArguments("ImmutableArray"),
                        // Test0.vb(10) : error BC30002: Type 'DiagnosticDescriptor' is not defined.
                        DiagnosticResult.CompilerError("BC30002").WithSpan(10, 81, 10,              101).WithArguments("DiagnosticDescriptor"),
                        // Test0.vb(16) : error BC30284: sub 'Initialize' cannot be declared 'Overrides' because it does not override a sub in a base class.
                        DiagnosticResult.CompilerError("BC30284").WithSpan(16, 23, 16,                                 33).WithArguments("sub","Initialize"),
                        // Test0.vb(16) : error BC30002: Type 'AnalysisContext' is not defined.
                        DiagnosticResult.CompilerError("BC30002").WithSpan(16, 45, 16,                    60).WithArguments("AnalysisContext"),
                        // Test0.vb(32) : error BC30002: Type 'OperationAnalysisContext' is not defined.
                        DiagnosticResult.CompilerError("BC30002").WithSpan(32, 49, 32,           73).WithArguments("OperationAnalysisContext"),
                        // Test0.vb(35) : error BC30002: Type 'OperationBlockAnalysisContext' is not defined.
                        DiagnosticResult.CompilerError("BC30002").WithSpan(35, 54, 35,      83).WithArguments("OperationBlockAnalysisContext"),
                        // Test0.vb(38) : error BC30002: Type 'OperationBlockStartAnalysisContext' is not defined.
                        DiagnosticResult.CompilerError("BC30002").WithSpan(38, 59, 38, 93).WithArguments("OperationBlockStartAnalysisContext"),
                        // Test0.vb(39) : error BC30451: 'OperationKind' is not declared. It may be inaccessible due to its protection level.
                        DiagnosticResult.CompilerError("BC30451").WithSpan(39, 63, 39, 76).WithArguments("OperationKind")
                    },
                }
            }.RunAsync();
        }
Example #51
0
        public void TestMethod2()
        {
            var test = @"
                        using System;

                        namespace ConsoleApplication1
                        {
                            public class Test 
                            {
                                public static void M()
                                {
                                    F(new Derived1());
                                }

                                static void F(Derived d)
                                {
                                }
                            }

                            

                            public class Base
                            {
                                public static T Create<T>() where T : Base, new()
                                {
                                    return new T();
                                }
                            }
                            public class Derived : Base
                            {   
                            }
                            public class Derived1 : Derived
                            {   
                            }
                        }";

            var fixedText = @"
                        using System;

                        namespace ConsoleApplication1
                        {
                            public class Test 
                            {
                                public static void M()
                                {
                                    F(Base.Create<Derived1>());
                                }

                                static void F(Derived d)
                                {
                                }
                            }

                            

                            public class Base
                            {
                                public static T Create<T>() where T : Base, new()
                                {
                                    return new T();
                                }
                            }
                            public class Derived : Base
                            {   
                            }
                            public class Derived1 : Derived
                            {   
                            }
                        }";

            var expected = new DiagnosticResult
            {
                Id        = FactoryAnalyzer.DiagnosticId,
                Message   = $"This class should be created by factory method Create of class Base",
                Severity  = DiagnosticSeverity.Error,
                Locations = new[] { new DiagnosticResultLocation("Test0.cs", 10, 39) }
            };

            VerifyCSharpDiagnostic(test, expected);

            VerifyCSharpFix(test, fixedText);
        }
Example #52
0
        public async Task Sanitizer(string payload, string warningId)
        {
            var cSharpTest = $@"
#pragma warning disable 8019
    using System.Data.SqlClient;
    using System.Web.Mvc;
    using System.DirectoryServices;
    using Microsoft.Security.Application;
    using System.Web;
    using System.IO;
#pragma warning restore 8019

namespace sample
{{
    class MyController : Controller
    {{
#pragma warning disable CS0414
        private HttpServerUtility _HttpServerUtility = null;
#pragma warning restore CS0414

        public void Run(string input, char[] inputChars)
        {{
            {payload}
        }}
    }}
}}
";

            payload = payload.CSharpReplaceToVBasic();

            var visualBasicTest = $@"
#Disable Warning BC50001
    Imports System.Data.SqlClient
    Imports System.Web.Mvc
    Imports System.DirectoryServices
    Imports Microsoft.Security.Application
    Imports System.Web
    Imports System.IO
#Enable Warning BC50001

Namespace sample
    Public Class MyController
        Inherits Controller

        Private _HttpServerUtility As HttpServerUtility = Nothing

        Public Sub Run(input As System.String, ByVal inputChars As System.Char())
            {payload}
        End Sub
    End Class
End Namespace
";

            var expected = new DiagnosticResult
            {
                Id       = warningId,
                Severity = DiagnosticSeverity.Warning,
            };

            await VerifyCSharpDiagnostic(cSharpTest, expected).ConfigureAwait(false);
            await VerifyVisualBasicDiagnostic(visualBasicTest, expected).ConfigureAwait(false);
        }
Example #53
0
        public async Task TaintArgumentsTransfer(string cs, bool warn)
        {
            var cSharpTest = $@"
using System.Data.SqlClient;

class StaticTest
{{
    public static void Foo2(string a, string b)
    {{
    }}

    public static string Get()
    {{
        return null;
    }}
}}

class Test
{{
    public string Foo(string a, string b)
    {{
        return null;
    }}

    public void Foo2(string a, string b) {{ }}

    public string Foo3(string a, out string b)
    {{
        b = null;
        return null;
    }}

    public string Foo4(string a, ref string b)
    {{
        return null;
    }}

    public void Run(string a, string b)
    {{
#pragma warning disable CS0219
        Test o = null;
#pragma warning restore CS0219
        {cs}
        new SqlCommand(query);
    }}
}}
";

            var visualBasicTest = $@"
Imports System.Data.SqlClient

Class StaticTest
    Public Shared Sub Foo2(ByVal a As String, ByVal b As String)
    End Sub

    Public Shared Function [Get]() As String
        Return Nothing
    End Function
End Class

Class Test
    Public Function Foo(ByVal a As String, ByVal b As String) As String
        Return Nothing
    End Function

    Public Sub Foo2(ByVal a As String, ByVal b As String)
    End Sub

    Public Function Foo3(ByVal a As String, <System.Runtime.InteropServices.Out> ByRef b As String) As String
        b = Nothing
        Return Nothing
    End Function

    Public Function Foo4(ByVal a As String, ByRef b As String) As String
        Return Nothing
    End Function

    Public Sub Run(ByVal a As String, ByVal b As String)
        Dim o As Test = Nothing
        {cs.CSharpReplaceToVBasic()}
        Dim temp = New SqlCommand(query)
    End Sub
End Class
";

            var expected = new DiagnosticResult
            {
                Id       = "SCS0026",
                Severity = DiagnosticSeverity.Warning,
            };

            var testConfig = @"
TaintEntryPoints:
  AAA:
    ClassName: Test
";

            var optionsWithProjectConfig = ConfigurationTest.CreateAnalyzersOptionsWithConfig(testConfig);

            if (warn)
            {
                await VerifyCSharpDiagnostic(cSharpTest, expected, optionsWithProjectConfig).ConfigureAwait(false);
                await VerifyVisualBasicDiagnostic(visualBasicTest, expected, optionsWithProjectConfig).ConfigureAwait(false);
            }
            else
            {
                await VerifyCSharpDiagnostic(cSharpTest, null, optionsWithProjectConfig).ConfigureAwait(false);
                await VerifyVisualBasicDiagnostic(visualBasicTest, null, optionsWithProjectConfig).ConfigureAwait(false);
            }
        }
        public async Task ToStringSanitizer(string intputType, string sinkType, string sink, bool warn)
        {
            var cSharpTest = $@"
namespace sample
{{
    public enum MyEnum
    {{
        Value = 1
    }}

    public class Sink
    {{
        public static void Redirect({sinkType} x)
        {{
        }}
    }}

    public class My
    {{
        public void Run({intputType} input)
        {{
            {sinkType} value = default({sinkType});
            {sink};
            Sink.Redirect(value);
        }}
    }}
}}
";

            var visualBasicTest = $@"
Namespace sample
    Public Enum MyEnum
        Value = 1
    End Enum

    Public Class Sink
        Public Shared Sub Redirect(ByVal x As {sinkType})
        End Sub
    End Class

    Public Class My
        Public Sub Run(ByVal input As {intputType})
            Dim value As {sinkType}
            {sink.CSharpReplaceToVBasic()}
            Sink.Redirect(value)
        End Sub
    End Class
End Namespace
";

            var testConfig = @"
TaintEntryPoints:
  sample.My:
    Method:
      Name: Run

Sinks:
  - Type: sample.Sink
    TaintTypes:
      - SCS0027
    Methods:
    - Name: Redirect
      Arguments:
        - x
";

            var optionsWithProjectConfig = ConfigurationTest.CreateAnalyzersOptionsWithConfig(testConfig);

            if (warn)
            {
                var expected = new DiagnosticResult
                {
                    Id       = "SCS0027",
                    Severity = DiagnosticSeverity.Warning,
                };

                await VerifyCSharpDiagnostic(cSharpTest, expected, optionsWithProjectConfig).ConfigureAwait(false);
                await VerifyVisualBasicDiagnostic(visualBasicTest, expected, optionsWithProjectConfig).ConfigureAwait(false);
            }
            else
            {
                await VerifyCSharpDiagnostic(cSharpTest, null, optionsWithProjectConfig).ConfigureAwait(false);
                await VerifyVisualBasicDiagnostic(visualBasicTest, null, optionsWithProjectConfig).ConfigureAwait(false);
            }
        }
Example #55
0
        /// <summary>
        /// Checks each of the actual Diagnostics found and compares them with the corresponding DiagnosticResult in the array of expected results.
        /// Diagnostics are considered equal only if the DiagnosticResultLocation, Id, Severity, and Message of the DiagnosticResult match the actual diagnostic.
        /// </summary>
        /// <param name="actualResults">The Diagnostics found by the compiler after running the analyzer on the source code</param>
        /// <param name="analyzer">The analyzer that was being run on the sources</param>
        /// <param name="expectedResults">Diagnostic Results that should have appeared in the code</param>
        private static void VerifyDiagnosticResults(IEnumerable <Diagnostic> actualResults, DiagnosticAnalyzer analyzer, params DiagnosticResult[] expectedResults)
        {
            int expectedCount = expectedResults.Length;
            int actualCount   = actualResults.Count();

            if (expectedCount != actualCount)
            {
                string diagnosticsOutput = actualResults.Any() ? FormatDiagnostics(analyzer, actualResults.ToArray()) : "    NONE.";

                Assert.True(false,
                            string.Format("Mismatch between number of diagnostics returned, expected \"{0}\" actual \"{1}\"\r\n\r\nDiagnostics:\r\n{2}\r\n", expectedCount, actualCount, diagnosticsOutput));
            }

            for (int i = 0; i < expectedResults.Length; i++)
            {
                Diagnostic       actual   = actualResults.ElementAt(i);
                DiagnosticResult expected = expectedResults[i];

                if (expected.HasLocation)
                {
                    if (actual.Location != Location.None)
                    {
                        Assert.True(false,
                                    string.Format("Expected:\nA project diagnostic with No location\nActual:\n{0}",
                                                  FormatDiagnostics(analyzer, actual)));
                    }
                }
                else
                {
                    VerifyDiagnosticLocation(analyzer, actual, actual.Location, expected.Spans[0]);
                    Location[] additionalLocations = actual.AdditionalLocations.ToArray();

                    if (additionalLocations.Length != expected.Spans.Length - 1)
                    {
                        Assert.True(false,
                                    string.Format("Expected {0} additional locations but got {1} for Diagnostic:\r\n    {2}\r\n",
                                                  expected.Spans.Length - 1, additionalLocations.Length,
                                                  FormatDiagnostics(analyzer, actual)));
                    }

                    for (int j = 0; j < additionalLocations.Length; ++j)
                    {
                        VerifyDiagnosticLocation(analyzer, actual, additionalLocations[j], expected.Spans[j + 1]);
                    }
                }

                if (actual.Id != expected.Id)
                {
                    Assert.True(false,
                                string.Format("Expected diagnostic id to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n    {2}\r\n",
                                              expected.Id, actual.Id, FormatDiagnostics(analyzer, actual)));
                }

                if (actual.Severity != expected.Severity)
                {
                    Assert.True(false,
                                string.Format("Expected diagnostic severity to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n    {2}\r\n",
                                              expected.Severity, actual.Severity, FormatDiagnostics(analyzer, actual)));
                }

                if (actual.GetMessage() != expected.Message)
                {
                    Assert.True(false,
                                string.Format("Expected diagnostic message to be \"{0}\" was \"{1}\"\r\n\r\nDiagnostic:\r\n    {2}\r\n",
                                              expected.Message, actual.GetMessage(), FormatDiagnostics(analyzer, actual)));
                }
            }
        }
        public async Task Validator(string usingNamespace, string validate, string sink, bool warn)
        {
            var cSharpTest = $@"
{usingNamespace}

namespace sample
{{
    public class Model
    {{
        public string x {{ get; set; }}
    }}

    public class MyController : Controller
    {{
        public object Run(string input, Uri inputUri, Model inputModel)
        {{
#pragma warning disable CS0219
            Uri uri = null;
#pragma warning restore CS0219
            if ({validate})
                return {sink};
            else
                return null;
        }}
    }}
}}
";

            var vb = validate.CSharpReplaceToVBasic().Replace("!", "Not ");

            var visualBasicTest = $@"
{usingNamespace.CSharpReplaceToVBasic()}

Namespace sample
    Public Class Model
        Public Property x As String
    End Class

    Public Class MyController
        Inherits Controller

        Public Function Run(ByVal input As String, ByVal inputUri as Uri, ByVal inputModel As Model) As Object
#Disable Warning BC42024
            Dim uri As Uri = Nothing
#Enable Warning BC42024
            If {vb} Then
                Return {sink}
            Else
                Return Nothing
            End If
        End Function
    End Class
End Namespace
";

            if (warn)
            {
                var expected = new DiagnosticResult
                {
                    Id       = "SCS0027",
                    Severity = DiagnosticSeverity.Warning,
                };

                await VerifyCSharpDiagnostic(cSharpTest, expected).ConfigureAwait(false);
                await VerifyVisualBasicDiagnostic(visualBasicTest, expected).ConfigureAwait(false);
            }
            else
            {
                await VerifyCSharpDiagnostic(cSharpTest).ConfigureAwait(false);
                await VerifyVisualBasicDiagnostic(visualBasicTest).ConfigureAwait(false);
            }
        }
Example #57
0
        public async Task IgnoreGeneratedCode()
        {
            var code1          = @"
#nullable enable$$

class Example
{
  string? value;
}
";
            var generatedCode1 = @"// <auto-generated/>

#nullable enable

class Example2
{
  string? value;
}
";
            var generatedCode2 = @"// <auto-generated/>

#nullable disable

class Example3
{
  string value;
}
";
            var generatedCode3 = @"// <auto-generated/>

#nullable restore

class Example4
{
  string {|#0:value|};
}
";

            var fixedCode1 = @"

class Example
{
  string? value;
}
";

            await new VerifyCS.Test
            {
                TestState =
                {
                    Sources =
                    {
                        code1,
                        generatedCode1,
                        generatedCode2,
                        generatedCode3,
                    },
                },
                FixedState =
                {
                    Sources             =
                    {
                        fixedCode1,
                        generatedCode1,
                        generatedCode2,
                        generatedCode3,
                    },
                    ExpectedDiagnostics =
                    {
                        // /0/Test3.cs(7,10): error CS8618: Non-nullable field 'value' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.
                        DiagnosticResult.CompilerError("CS8618").WithLocation(0),
                    },
                },
                SolutionTransforms = { s_enableNullableInFixedSolution },
            }.RunAsync();
        }
 public static Task VerifyCodeFixAsync(string source, DiagnosticResult expected, string fixedSource)
 => VerifyCodeFixAsync(source, new[] { expected }, fixedSource);
 private Task TestKeywordDeclarationAsync(string statement, DiagnosticResult expected, string fixedStatement)
 {
     return(this.TestKeywordDeclarationAsync(statement, new[] { expected }, fixedStatement));
 }
        public async Task WeakCipherModeCBC()
        {
            const string cSharpTest = @"
using System;
using System.IO;
using System.Security.Cryptography;

class WeakCipherMode
{
    public static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
    {
        // Check arguments.
        if (plainText == null || plainText.Length <= 0)
            throw new ArgumentNullException(""plainText"");
        if (Key == null || Key.Length <= 0)
            throw new ArgumentNullException(""Key"");

        if (IV == null || IV.Length <= 0)
            throw new ArgumentNullException(""IV"");
        byte[] encrypted;
        // Create an AesCryptoServiceProvider object
        // with the specified key and IV.
        using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
        {
            aesAlg.Key = Key;
            aesAlg.IV = IV;
            aesAlg.Mode = CipherMode.CBC;
            aesAlg.Padding = PaddingMode.PKCS7;
            // Create a decryptor to perform the stream transform.
            ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

            // Create the streams used for encryption.
            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {

                        //Write all data to the stream.
                        swEncrypt.Write(plainText);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
        }

        return encrypted;
    }
}";

            const string visualBasicTest = @"
Imports System
Imports System.IO
Imports System.Security.Cryptography

Class WeakCipherMode
    Public Shared Function EncryptStringToBytes_Aes(plainText As String, Key As Byte(), IV As Byte()) As Byte()
        ' Check arguments.
        If plainText Is Nothing OrElse plainText.Length <= 0 Then
            Throw New ArgumentNullException(""plainText"")
        End If
        If Key Is Nothing OrElse Key.Length <= 0 Then
            Throw New ArgumentNullException(""Key"")
        End If
        If IV Is Nothing OrElse IV.Length <= 0 Then
            Throw New ArgumentNullException(""IV"")
        End If
        Dim encrypted As Byte()
        ' Create an AesCryptoServiceProvider object
        ' with the specified key and IV.
        Using aesAlg As New AesCryptoServiceProvider()
            aesAlg.Key = Key
            aesAlg.IV = IV
            aesAlg.Mode = CipherMode.CBC
            aesAlg.Padding = PaddingMode.PKCS7
            ' Create a decrytor to perform the stream transform.
            Dim encryptor As ICryptoTransform = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV)
            ' Create the streams used for encryption.
            Using msEncrypt As New MemoryStream()
                Using csEncrypt As New CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)
                    Using swEncrypt As New StreamWriter(csEncrypt)
                        'Write all data to the stream.
                        swEncrypt.Write(plainText)
                    End Using
                    encrypted = msEncrypt.ToArray()
                End Using
            End Using
        End Using
        Return encrypted
    End Function
End Class
";

            var expected = new DiagnosticResult
            {
                Id       = "SCS0011",
                Severity = DiagnosticSeverity.Warning,
            };

            await VerifyCSharpDiagnostic(cSharpTest, expected).ConfigureAwait(false);
            await VerifyVisualBasicDiagnostic(visualBasicTest, expected).ConfigureAwait(false);
        }