Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 697b0ba

Browse files
committed
C#: Address review comments
1 parent 1ba9e29 commit 697b0ba

4 files changed

Lines changed: 75 additions & 9 deletions

File tree

csharp/ql/src/semmle/code/csharp/dataflow/FlowSummary.qll

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,11 @@ module SummaryOutput {
138138
}
139139

140140
/**
141-
* Gets an output specification that specifies the output `output` of calling
142-
* `target` as the output. `output` is limited to (this) parameters and
143-
* ordinary returns.
141+
* Gets an output specification that specifies the `output` of `target` as the
142+
* output. That is, data will flow into one callable and out of another callable
143+
* (`target`).
144+
*
145+
* `output` is limited to (this) parameters and ordinary returns.
144146
*/
145147
SummaryOutput jump(SummarizableCallable target, SummaryOutput output) {
146148
result = TJumpSummaryOutput(target, toReturnKind(output))

csharp/ql/src/semmle/code/csharp/frameworks/EntityFramework.qll

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,41 @@ module EntityFramework {
7373
/** The class `Microsoft.EntityFrameworkCore.DbSet<>` or `System.Data.Entity.DbSet<>`. */
7474
class DbSet extends EFClass, UnboundGenericClass {
7575
DbSet() { this.getName() = "DbSet<>" }
76+
77+
/** Gets a method that adds or updates entities in a DB set. */
78+
SummarizableMethod getAnAddOrUpdateMethod(boolean range) {
79+
exists(string name | result = this.getAMethod(name) |
80+
name in ["Add", "AddAsync", "Attach", "Update"] and
81+
range = false
82+
or
83+
name in ["AddRange", "AddRangeAsync", "AttachRange", "UpdateRange"] and
84+
range = true
85+
)
86+
}
87+
}
88+
89+
/** A flow summary for EntityFramework. */
90+
abstract class EFSummarizedCallable extends SummarizedCallable { }
91+
92+
private class DbSetAddOrUpdate extends EFSummarizedCallable {
93+
private boolean range;
94+
95+
DbSetAddOrUpdate() { this = any(DbSet c).getAnAddOrUpdateMethod(range) }
96+
97+
override predicate propagatesFlow(
98+
SummaryInput input, ContentList inputContents, SummaryOutput output,
99+
ContentList outputContents, boolean preservesValue
100+
) {
101+
input = SummaryInput::parameter(0) and
102+
(
103+
if range = true
104+
then inputContents = ContentList::element()
105+
else inputContents = ContentList::empty()
106+
) and
107+
output = SummaryOutput::thisParameter() and
108+
outputContents = ContentList::element() and
109+
preservesValue = true
110+
}
76111
}
77112

78113
/** The class `Microsoft.EntityFrameworkCore.DbQuery<>` or `System.Data.Entity.DbQuery<>`. */
@@ -118,9 +153,6 @@ module EntityFramework {
118153
}
119154
}
120155

121-
/** A flow summary for EntityFramework. */
122-
abstract class EFSummarizedCallable extends SummarizedCallable { }
123-
124156
/** The struct `Microsoft.EntityFrameworkCore.RawSqlString`. */
125157
private class RawSqlStringStruct extends Struct {
126158
RawSqlStringStruct() { this.getQualifiedName() = "Microsoft.EntityFrameworkCore.RawSqlString" }
@@ -359,7 +391,9 @@ module EntityFramework {
359391
* to a column in the underlying DB.
360392
*/
361393
pragma[noinline]
362-
predicate mappedPath(Property dbSet, PropertyContent head, ContentList tail, Property last) {
394+
predicate pathFromDbSetToDbProperty(
395+
Property dbSet, PropertyContent head, ContentList tail, Property last
396+
) {
363397
this.requiresContentList(head, _, tail, _, last) and
364398
head.getProperty() = dbSet and
365399
dbSet = this.getADbSetProperty(_)
@@ -383,12 +417,12 @@ module EntityFramework {
383417
preservesValue = true and
384418
exists(PropertyContent sourceHead, ContentList sourceTail |
385419
input = SummaryInput::thisParameter() and
386-
c.mappedPath(_, sourceHead, sourceTail, mapped) and
420+
c.pathFromDbSetToDbProperty(_, sourceHead, sourceTail, mapped) and
387421
inputContents = ContentList::cons(sourceHead, sourceTail)
388422
) and
389423
exists(Property dbSetProp |
390424
output = SummaryOutput::jump(dbSetProp.getGetter(), SummaryOutput::return()) and
391-
c.mappedPath(dbSetProp, _, outputContents, mapped)
425+
c.pathFromDbSetToDbProperty(dbSetProp, _, outputContents, mapped)
392426
)
393427
)
394428
}

csharp/ql/test/library-tests/frameworks/EntityFramework/FlowSummaries.expected

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@
6868
| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Persons, [], Id] -> jump to get_Persons (return) [[], Id] | true |
6969
| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Persons, [], Name] -> jump to get_PersonAddresses (return) [[], Person, Name] | true |
7070
| Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync() | this parameter [Persons, [], Name] -> jump to get_Persons (return) [[], Name] | true |
71+
| Microsoft.EntityFrameworkCore.DbSet<>.Add(T) | parameter 0 -> this parameter [[]] | true |
72+
| Microsoft.EntityFrameworkCore.DbSet<>.AddAsync(T) | parameter 0 -> this parameter [[]] | true |
73+
| Microsoft.EntityFrameworkCore.DbSet<>.AddRange(IEnumerable<T>) | parameter 0 [[]] -> this parameter [[]] | true |
74+
| Microsoft.EntityFrameworkCore.DbSet<>.AddRangeAsync(IEnumerable<T>) | parameter 0 [[]] -> this parameter [[]] | true |
75+
| Microsoft.EntityFrameworkCore.DbSet<>.Attach(T) | parameter 0 -> this parameter [[]] | true |
76+
| Microsoft.EntityFrameworkCore.DbSet<>.AttachRange(IEnumerable<T>) | parameter 0 [[]] -> this parameter [[]] | true |
77+
| Microsoft.EntityFrameworkCore.DbSet<>.Update(T) | parameter 0 -> this parameter [[]] | true |
78+
| Microsoft.EntityFrameworkCore.DbSet<>.UpdateRange(IEnumerable<T>) | parameter 0 [[]] -> this parameter [[]] | true |
7179
| Microsoft.EntityFrameworkCore.RawSqlString.RawSqlString(string) | parameter 0 -> return | false |
7280
| Microsoft.EntityFrameworkCore.RawSqlString.implicit conversion(string) | parameter 0 -> return | false |
7381
| System.Data.Entity.DbContext.SaveChanges() | this parameter [Addresses, [], Id] -> jump to get_Addresses (return) [[], Id] | true |
@@ -140,3 +148,11 @@
140148
| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Persons, [], Id] -> jump to get_Persons (return) [[], Id] | true |
141149
| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Persons, [], Name] -> jump to get_PersonAddresses (return) [[], Person, Name] | true |
142150
| System.Data.Entity.DbContext.SaveChangesAsync() | this parameter [Persons, [], Name] -> jump to get_Persons (return) [[], Name] | true |
151+
| System.Data.Entity.DbSet<>.Add(T) | parameter 0 -> this parameter [[]] | true |
152+
| System.Data.Entity.DbSet<>.AddAsync(T) | parameter 0 -> this parameter [[]] | true |
153+
| System.Data.Entity.DbSet<>.AddRange(IEnumerable<T>) | parameter 0 [[]] -> this parameter [[]] | true |
154+
| System.Data.Entity.DbSet<>.AddRangeAsync(IEnumerable<T>) | parameter 0 [[]] -> this parameter [[]] | true |
155+
| System.Data.Entity.DbSet<>.Attach(T) | parameter 0 -> this parameter [[]] | true |
156+
| System.Data.Entity.DbSet<>.AttachRange(IEnumerable<T>) | parameter 0 [[]] -> this parameter [[]] | true |
157+
| System.Data.Entity.DbSet<>.Update(T) | parameter 0 -> this parameter [[]] | true |
158+
| System.Data.Entity.DbSet<>.UpdateRange(IEnumerable<T>) | parameter 0 [[]] -> this parameter [[]] | true |

csharp/ql/test/resources/stubs/EntityFramework.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ public class DbSet
1313
public class DbSet<T> : IEnumerable<T>
1414
{
1515
public void Add(T t) { }
16+
public System.Threading.Tasks.Task<int> AddAsync(T t) => null;
17+
public void AddRange(IEnumerable<T> t) { }
18+
public System.Threading.Tasks.Task<int> AddRangeAsync(IEnumerable<T> t) => null;
19+
public void Attach(T t) { }
20+
public void AttachRange(IEnumerable<T> t) { }
21+
public void Update(T t) { }
22+
public void UpdateRange(IEnumerable<T> t) { }
1623
IEnumerator<T> IEnumerable<T>.GetEnumerator() => null;
1724
IEnumerator IEnumerable.GetEnumerator() => null;
1825
}
@@ -55,6 +62,13 @@ namespace Microsoft.EntityFrameworkCore
5562
public class DbSet<T> : IEnumerable<T>
5663
{
5764
public void Add(T t) { }
65+
public System.Threading.Tasks.Task<int> AddAsync(T t) => null;
66+
public void AddRange(IEnumerable<T> t) { }
67+
public System.Threading.Tasks.Task<int> AddRangeAsync(IEnumerable<T> t) => null;
68+
public void Attach(T t) { }
69+
public void AttachRange(IEnumerable<T> t) { }
70+
public void Update(T t) { }
71+
public void UpdateRange(IEnumerable<T> t) { }
5872
IEnumerator<T> IEnumerable<T>.GetEnumerator() => null;
5973
IEnumerator IEnumerable.GetEnumerator() => null;
6074
}

0 commit comments

Comments
 (0)