Skip to content

Commit e020ae7

Browse files
authored
Merge pull request #10158 from michaelnebel/csharp/narrowcollectiontypes
C#: Narrow collection like types in model generation.
2 parents 623531a + f4835e3 commit e020ae7

File tree

12 files changed

+934
-294
lines changed

12 files changed

+934
-294
lines changed

csharp/ql/lib/semmle/code/csharp/frameworks/generated/dotnet/NegativeRuntime.qll

Lines changed: 7 additions & 146 deletions
Large diffs are not rendered by default.

csharp/ql/lib/semmle/code/csharp/frameworks/generated/dotnet/Runtime.qll

Lines changed: 304 additions & 9 deletions
Large diffs are not rendered by default.

csharp/ql/src/utils/model-generator/internal/CaptureModels.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ string captureSource(TargetApi api) {
234234
config.hasFlow(source, sink) and
235235
ExternalFlow::sourceNode(source, kind) and
236236
api = sink.getEnclosingCallable() and
237+
isRelevantSourceKind(kind) and
237238
result = asSourceModel(api, returnNodeAsOutput(sink), kind)
238239
)
239240
}

csharp/ql/src/utils/model-generator/internal/CaptureModelsSpecific.qll

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,31 @@ predicate asPartialModel = DataFlowPrivate::Csv::asPartialModel/1;
5858

5959
predicate asPartialNegativeModel = DataFlowPrivate::Csv::asPartialNegativeModel/1;
6060

61+
/**
62+
* Holds if `t` is a type that is generally used for bulk data in collection types.
63+
* Eg. char[] is roughly equivalent to string and thus a highly
64+
* relevant type for model generation.
65+
*/
66+
private predicate isPrimitiveTypeUsedForBulkData(CS::Type t) {
67+
t instanceof CS::ByteType or
68+
t instanceof CS::CharType
69+
}
70+
71+
/**
72+
* Holds if the collection type `ct` is irrelevant for model generation.
73+
* Collection types where the type of the elements are
74+
* (1) unknown - are considered relevant.
75+
* (2) known - at least one the child types should be relevant (a non-simple type
76+
* or a type used for bulk data)
77+
*/
78+
private predicate irrelevantCollectionType(CS::Type ct) {
79+
Collections::isCollectionType(ct) and
80+
forex(CS::Type child | child = ct.getAChild() |
81+
child instanceof CS::SimpleType and
82+
not isPrimitiveTypeUsedForBulkData(child)
83+
)
84+
}
85+
6186
/**
6287
* Holds for type `t` for fields that are relevant as an intermediate
6388
* read or write step in the data flow analysis.
@@ -66,7 +91,8 @@ predicate asPartialNegativeModel = DataFlowPrivate::Csv::asPartialNegativeModel/
6691
*/
6792
predicate isRelevantType(CS::Type t) {
6893
not t instanceof CS::SimpleType and
69-
not t instanceof CS::Enum
94+
not t instanceof CS::Enum and
95+
not irrelevantCollectionType(t)
7096
}
7197

7298
/**
@@ -167,3 +193,9 @@ string asInputArgument(DataFlow::Node source) {
167193
*/
168194
bindingset[kind]
169195
predicate isRelevantSinkKind(string kind) { any() }
196+
197+
/**
198+
* Holds if `kind` is a relevant source kind for creating source models.
199+
*/
200+
bindingset[kind]
201+
predicate isRelevantSourceKind(string kind) { not kind = "file" }

csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected

Lines changed: 323 additions & 127 deletions
Large diffs are not rendered by default.

csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected

Lines changed: 204 additions & 11 deletions
Large diffs are not rendered by default.

csharp/ql/test/utils/model-generator/CaptureNegativeSummaryModels.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
| NoSummaries;BaseClass;M1;(System.String);generated |
22
| NoSummaries;BaseClass;M2;(System.String);generated |
3+
| NoSummaries;CollectionFlow;ReturnSimpleTypeArray;(System.Int32[]);generated |
4+
| NoSummaries;CollectionFlow;ReturnSimpleTypeDictionary;(System.Collections.Generic.Dictionary<System.Int32,System.Int32>);generated |
5+
| NoSummaries;CollectionFlow;ReturnSimpleTypeList;(System.Collections.Generic.List<System.Int32>);generated |
36
| NoSummaries;EquatableBound;Equals;(System.Object);generated |
47
| NoSummaries;EquatableUnBound<>;Equals;(T);generated |
58
| NoSummaries;SimpleTypes;M1;(System.Boolean);generated |

csharp/ql/test/utils/model-generator/CaptureSummaryModels.expected

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,13 @@
1313
| Summaries;CollectionFlow;false;AssignFieldToArray;(System.Object[]);;Argument[this];Argument[0].Element;taint;generated |
1414
| Summaries;CollectionFlow;false;AssignToArray;(System.Object,System.Object[]);;Argument[0];Argument[1].Element;taint;generated |
1515
| Summaries;CollectionFlow;false;ReturnArrayElement;(System.Object[]);;Argument[0].Element;ReturnValue;taint;generated |
16+
| Summaries;CollectionFlow;false;ReturnBulkTypeList;(System.Collections.Generic.List<System.Byte>);;Argument[0].Element;ReturnValue;taint;generated |
17+
| Summaries;CollectionFlow;false;ReturnComplexTypeArray;(System.String[]);;Argument[0].Element;ReturnValue;taint;generated |
18+
| Summaries;CollectionFlow;false;ReturnComplexTypeDictionary;(System.Collections.Generic.Dictionary<System.Int32,System.String>);;Argument[0].Element;ReturnValue;taint;generated |
1619
| Summaries;CollectionFlow;false;ReturnFieldInAList;();;Argument[this];ReturnValue;taint;generated |
1720
| Summaries;CollectionFlow;false;ReturnListElement;(System.Collections.Generic.List<System.Object>);;Argument[0].Element;ReturnValue;taint;generated |
21+
| Summaries;CollectionFlow;false;ReturnUntypedArray;(System.Array);;Argument[0].Element;ReturnValue;taint;generated |
22+
| Summaries;CollectionFlow;false;ReturnUntypedList;(System.Collections.IList);;Argument[0].Element;ReturnValue;taint;generated |
1823
| Summaries;DerivedClass1Flow;false;ReturnParam1;(System.String,System.String);;Argument[1];ReturnValue;taint;generated |
1924
| Summaries;DerivedClass2Flow;false;ReturnParam0;(System.String,System.Int32);;Argument[0];ReturnValue;taint;generated |
2025
| Summaries;DerivedClass2Flow;false;ReturnParam;(System.Object);;Argument[0];ReturnValue;taint;generated |

csharp/ql/test/utils/model-generator/NoSummaries.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23

34
namespace NoSummaries;
45

@@ -110,4 +111,24 @@ public virtual string M1(string s)
110111

111112
// Negative summary.
112113
public abstract string M2(string s);
114+
}
115+
116+
// No methods in this class will have generated flow as
117+
// the simple types used in the collection are not bulk data types.
118+
public class CollectionFlow
119+
{
120+
public int[] ReturnSimpleTypeArray(int[] a)
121+
{
122+
return a;
123+
}
124+
125+
public List<int> ReturnSimpleTypeList(List<int> a)
126+
{
127+
return a;
128+
}
129+
130+
public Dictionary<int, int> ReturnSimpleTypeDictionary(Dictionary<int, int> a)
131+
{
132+
return a;
133+
}
113134
}

csharp/ql/test/utils/model-generator/Summaries.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Linq;
3+
using System.Collections;
34
using System.Collections.Generic;
45

56
namespace Summaries;
@@ -85,6 +86,31 @@ public List<string> ReturnFieldInAList()
8586
{
8687
return new List<string> { tainted };
8788
}
89+
90+
public string[] ReturnComplexTypeArray(string[] a)
91+
{
92+
return a;
93+
}
94+
95+
public List<byte> ReturnBulkTypeList(List<byte> a)
96+
{
97+
return a;
98+
}
99+
100+
public Dictionary<int, string> ReturnComplexTypeDictionary(Dictionary<int, string> a)
101+
{
102+
return a;
103+
}
104+
105+
public Array ReturnUntypedArray(Array a)
106+
{
107+
return a;
108+
}
109+
110+
public IList ReturnUntypedList(IList a)
111+
{
112+
return a;
113+
}
88114
}
89115

90116
public class IEnumerableFlow

0 commit comments

Comments
 (0)