Skip to content

Commit 56e1420

Browse files
authored
Merge pull request #2944 from dotpaul/tests
PropertySetAnalysis: Handling assignments to flow captures when tracking properties
2 parents 82894b3 + 51dd600 commit 56e1420

3 files changed

Lines changed: 118 additions & 13 deletions

File tree

src/Microsoft.NetCore.Analyzers/UnitTests/Security/DoNotUseInsecureDeserializerBinaryFormatterWithoutBinderTests.cs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,5 +1196,58 @@ public BookRecord DeserializeBookRecord(byte[] bytes)
11961196
}
11971197
}", GetEditorConfigAdditionalFile(editorConfigText), expected);
11981198
}
1199+
1200+
[Fact]
1201+
public void Deserialize_SharedBinderInstance_NoDiagnostic()
1202+
{
1203+
VerifyCSharpWithMyBinderDefined(@"
1204+
using System;
1205+
using System.IO;
1206+
using System.Runtime.Serialization;
1207+
using System.Runtime.Serialization.Formatters.Binary;
1208+
using System.Runtime.Remoting.Messaging;
1209+
1210+
namespace Blah
1211+
{
1212+
public class Program
1213+
{
1214+
public static SerializationBinder B { get; set; }
1215+
1216+
private object DoDeserialization(Stream stream)
1217+
{
1218+
BinaryFormatter f = new BinaryFormatter();
1219+
f.Binder = B ?? throw new Exception(""Expected a non-null SerializationBinder"");
1220+
return f.Deserialize(stream);
1221+
}
1222+
}
1223+
}");
1224+
}
1225+
1226+
[Fact]
1227+
public void Deserialize_SharedBinderInstanceIntermediate_NoDiagnostic()
1228+
{
1229+
VerifyCSharpWithMyBinderDefined(@"
1230+
using System;
1231+
using System.IO;
1232+
using System.Runtime.Serialization;
1233+
using System.Runtime.Serialization.Formatters.Binary;
1234+
using System.Runtime.Remoting.Messaging;
1235+
1236+
namespace Blah
1237+
{
1238+
public class Program
1239+
{
1240+
public static SerializationBinder B { get; set; }
1241+
1242+
private object DoDeserialization(Stream stream)
1243+
{
1244+
BinaryFormatter f = new BinaryFormatter();
1245+
SerializationBinder b = B ?? throw new Exception(""Expected a non-null SerializationBinder"");
1246+
f.Binder = b;
1247+
return f.Deserialize(stream);
1248+
}
1249+
}
1250+
}");
1251+
}
11991252
}
12001253
}

src/Microsoft.NetCore.Analyzers/UnitTests/Security/UseXmlReaderForSchemaReadTests.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,30 @@ public void TestMethod(XmlReader reader, ValidationEventHandler validationEventH
6666
}");
6767
}
6868

69+
[Fact]
70+
public void XmlSchemaReadDocSample1_Solution()
71+
{
72+
VerifyCSharp(@"
73+
using System.IO;
74+
using System.Xml;
75+
using System.Xml.Schema;
76+
77+
class TestClass
78+
{
79+
public XmlSchema Test
80+
{
81+
get
82+
{
83+
var src = """";
84+
TextReader tr = new StreamReader(src);
85+
XmlReader reader = XmlReader.Create(tr, new XmlReaderSettings() { XmlResolver = null });
86+
XmlSchema schema = XmlSchema.Read(reader , null);
87+
return schema;
88+
}
89+
}
90+
}");
91+
}
92+
6993
protected override DiagnosticAnalyzer GetBasicDiagnosticAnalyzer()
7094
{
7195
return new UseXmlReaderForSchemaRead();

src/Utilities/FlowAnalysis/FlowAnalysis/Analysis/PropertySetAnalysis/PropertySetAnalysis.PropertySetDataFlowOperationVisitor.cs

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -241,19 +241,9 @@ protected override PropertySetAbstractValue VisitAssignmentOperation(IAssignment
241241
AnalysisEntity targetAnalysisEntity = null;
242242
if (operation.Target.Kind == OperationKind.FlowCaptureReference)
243243
{
244-
PointsToAbstractValue lValuePointsToAbstractValue = this.GetPointsToAbstractValue(operation.Target);
245-
if (lValuePointsToAbstractValue.LValueCapturedOperations.Count == 1)
244+
if (this.TryUnwrapFlowCaptureReference(operation.Target, out IOperation lValueOperation, OperationKind.PropertyReference, OperationKind.FieldReference))
246245
{
247-
IOperation lValueOperation = lValuePointsToAbstractValue.LValueCapturedOperations.First();
248-
if (lValueOperation.Kind == OperationKind.FieldReference
249-
|| lValueOperation.Kind == OperationKind.PropertyReference)
250-
{
251-
this.AnalysisEntityFactory.TryCreate(lValueOperation, out targetAnalysisEntity);
252-
}
253-
}
254-
else
255-
{
256-
Debug.Fail("Can LValues FlowCaptureReferences have more than one operation?");
246+
this.AnalysisEntityFactory.TryCreate(lValueOperation, out targetAnalysisEntity);
257247
}
258248
}
259249
else
@@ -295,7 +285,14 @@ protected override PropertySetAbstractValue VisitAssignmentOperation(IAssignment
295285
}
296286
}
297287

298-
if (operation.Target is IPropertyReferenceOperation propertyReferenceOperation
288+
IPropertyReferenceOperation propertyReferenceOperation = operation.Target as IPropertyReferenceOperation;
289+
if (propertyReferenceOperation == null && operation.Target.Kind == OperationKind.FlowCaptureReference)
290+
{
291+
this.TryUnwrapFlowCaptureReference(operation.Target, out IOperation lValue, OperationKind.PropertyReference);
292+
propertyReferenceOperation = lValue as IPropertyReferenceOperation;
293+
}
294+
295+
if (propertyReferenceOperation != null
299296
&& propertyReferenceOperation.Instance != null
300297
&& this.TrackedTypeSymbols.Any(s => propertyReferenceOperation.Instance.Type.GetBaseTypesAndThis().Contains(s))
301298
&& this.DataFlowAnalysisContext.PropertyMappers.TryGetPropertyMapper(
@@ -698,6 +695,37 @@ private void MergeInterproceduralResults(IOperation originalOperation)
698695
this._visitedLambdas.Add(lambdaOperation);
699696
}
700697
}
698+
699+
/// <summary>
700+
/// Attempts to find the underlying IOperation that a flow capture reference refers to.
701+
/// </summary>
702+
/// <param name="flowCaptureReferenceOperation">Operation that may be a flow capture reference to look at.</param>
703+
/// <param name="unwrappedOperation">The found underlying operation, if any.</param>
704+
/// <param name="kinds">Kinds of operations to look for.</param>
705+
/// <returns>True if found, false otherwise.</returns>
706+
private bool TryUnwrapFlowCaptureReference(IOperation flowCaptureReferenceOperation, out IOperation unwrappedOperation, params OperationKind[] kinds)
707+
{
708+
unwrappedOperation = null;
709+
if (flowCaptureReferenceOperation != null && flowCaptureReferenceOperation.Kind == OperationKind.FlowCaptureReference)
710+
{
711+
PointsToAbstractValue lValuePointsToAbstractValue = this.GetPointsToAbstractValue(flowCaptureReferenceOperation);
712+
if (lValuePointsToAbstractValue.LValueCapturedOperations.Count == 1)
713+
{
714+
IOperation lValueOperation = lValuePointsToAbstractValue.LValueCapturedOperations.First();
715+
if (kinds == null || kinds.Contains(lValueOperation.Kind))
716+
{
717+
unwrappedOperation = lValueOperation;
718+
return true;
719+
}
720+
}
721+
else
722+
{
723+
Debug.Fail("Can LValues FlowCaptureReferences have more than one operation?");
724+
}
725+
}
726+
727+
return false;
728+
}
701729
}
702730
}
703731
}

0 commit comments

Comments
 (0)