From 62200cf060f9321e6514339bbfd986fc5e120f9c Mon Sep 17 00:00:00 2001 From: Paul Ming Date: Wed, 15 Apr 2020 17:10:56 -0700 Subject: [PATCH] Handle local functions in DoNotCallDangerousMethodsInDeserialization --- ...otCallDangerousMethodsInDeserialization.cs | 4 ++ ...lDangerousMethodsInDeserializationTests.cs | 53 +++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DoNotCallDangerousMethodsInDeserialization.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DoNotCallDangerousMethodsInDeserialization.cs index 6976ae3441..d5b1b6f55f 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DoNotCallDangerousMethodsInDeserialization.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/DoNotCallDangerousMethodsInDeserialization.cs @@ -180,8 +180,12 @@ public sealed override void Initialize(AnalysisContext context) calledMethods.TryAdd(calledSymbol, true); + // calledSymbol.ContainingSymbol.Kind == SymbolKind.Method => local function + // For the purposes of this rule, we'll treat invocations inside the local function as part of + // the containing method's set of invocations. if (!calledSymbol.IsInSource() || calledSymbol.ContainingType.TypeKind == TypeKind.Interface || + calledSymbol.ContainingSymbol.Kind == SymbolKind.Method || calledSymbol.IsAbstract || possibleDelegateSymbol.TypeKind == TypeKind.Delegate) { diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DoNotCallDangerousMethodsInDeserializationTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DoNotCallDangerousMethodsInDeserializationTests.cs index 969bf5fc69..1048f20c94 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DoNotCallDangerousMethodsInDeserializationTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Security/DoNotCallDangerousMethodsInDeserializationTests.cs @@ -2499,6 +2499,59 @@ private void TestMethod() }"); } + [Fact] + public async Task TestLocalFunctionDiagnostic() + { + await VerifyCS.VerifyAnalyzerAsync(@" +using System; +using System.IO; +using System.Runtime.Serialization; + +[Serializable()] +public class TestClass +{ + private string member; + + [OnDeserializing()] + internal void OnDeserializingMethod(StreamingContext context) + { + byte[] bytes = new byte[] {0x20, 0x20, 0x20}; + ALocalFunction(); + + void ALocalFunction() + { + File.WriteAllBytes(""C:\\"", bytes); + } + } +}", + GetCSharpResultAt(12, 19, "TestClass", "OnDeserializingMethod", "WriteAllBytes")); + } + + [Fact] + public async Task TestLocalFunctionNoDiagnostic() + { + await VerifyCS.VerifyAnalyzerAsync(@" +using System; +using System.Runtime.Serialization; + +[Serializable()] +public class TestClass +{ + private string member; + + [OnDeserializing()] + internal void OnDeserializingMethod(StreamingContext context) + { + ALocalFunction(); + + void ALocalFunction() + { + object o = new Object(); + } + } +}"); + } + private static DiagnosticResult GetCSharpResultAt(int line, int column, params string[] arguments) => VerifyCS.Diagnostic() .WithLocation(line, column)