Skip to content

Commit c94de85

Browse files
committed
C#: Add another group of assignable definitions (corresponding to compound assignment operations) and update taint flow for +.
1 parent ad73248 commit c94de85

File tree

5 files changed

+29
-8
lines changed

5 files changed

+29
-8
lines changed

csharp/ql/lib/semmle/code/csharp/Assignable.qll

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ class AssignableRead extends AssignableAccess {
7878
this.isRefArgument()
7979
or
8080
this = any(AssignableDefinitions::AddressOfDefinition def).getTargetAccess()
81+
or
82+
this = any(AssignableDefinitions::AssignOperationDefinition def).getTargetAccess()
8183
) and
8284
not nameOfChild(_, this)
8385
}
@@ -271,6 +273,8 @@ module AssignableInternal {
271273
def = TAddressOfDefinition(result)
272274
or
273275
def = TPatternDefinition(result)
276+
or
277+
def = TAssignOperationDefinition(result)
274278
}
275279

276280
/** A local variable declaration at the top-level of a pattern. */
@@ -286,7 +290,10 @@ module AssignableInternal {
286290
private module Cached {
287291
cached
288292
newtype TAssignableDefinition =
289-
TAssignmentDefinition(Assignment a) { not a.getLValue() instanceof TupleExpr } or
293+
TAssignmentDefinition(Assignment a) {
294+
not a.getLValue() instanceof TupleExpr and
295+
not a instanceof AssignOperation
296+
} or
290297
TTupleAssignmentDefinition(AssignExpr ae, Expr leaf) { tupleAssignmentDefinition(ae, leaf) } or
291298
TOutRefDefinition(AssignableAccess aa) {
292299
aa.isOutArgument()
@@ -309,7 +316,8 @@ module AssignableInternal {
309316
)
310317
} or
311318
TAddressOfDefinition(AddressOfExpr aoe) or
312-
TPatternDefinition(TopLevelPatternDecl tlpd)
319+
TPatternDefinition(TopLevelPatternDecl tlpd) or
320+
TAssignOperationDefinition(AssignOperation ao)
313321

314322
/**
315323
* Gets the source expression assigned in tuple definition `def`, if any.
@@ -355,6 +363,8 @@ module AssignableInternal {
355363
def = TMutationDefinition(any(MutatorOperation mo | mo.getOperand() = result))
356364
or
357365
def = TAddressOfDefinition(any(AddressOfExpr aoe | aoe.getOperand() = result))
366+
or
367+
def = TAssignOperationDefinition(any(AssignOperation ao | ao.getLeftOperand() = result))
358368
}
359369

360370
/**
@@ -509,10 +519,7 @@ module AssignableDefinitions {
509519
/** Gets the underlying assignment. */
510520
Assignment getAssignment() { result = a }
511521

512-
override Expr getSource() {
513-
result = a.getRValue() and
514-
not a instanceof AssignOperation
515-
}
522+
override Expr getSource() { result = a.getRValue() }
516523

517524
override string toString() { result = a.toString() }
518525
}
@@ -735,4 +742,14 @@ module AssignableDefinitions {
735742
/** Gets the assignable (field or property) being initialized. */
736743
Assignable getAssignable() { result = fieldOrProp }
737744
}
745+
746+
class AssignOperationDefinition extends AssignableDefinition, TAssignOperationDefinition {
747+
AssignOperation ao;
748+
749+
AssignOperationDefinition() { this = TAssignOperationDefinition(ao) }
750+
751+
override Expr getSource() { result = ao }
752+
753+
override string toString() { result = ao.toString() }
754+
}
738755
}

csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImpl.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,7 @@ module Expressions {
486486
result = qe.getChild(i)
487487
)
488488
or
489+
// TODO: This can be fixed if the extracted indexes are fixed.
489490
e =
490491
any(Assignment a |
491492
// The left-hand side of an assignment is evaluated before the right-hand side

csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3050,7 +3050,7 @@ predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preserves
30503050
or
30513051
exists(AddEventExpr aee |
30523052
nodeFrom.asExpr() = aee.getRValue() and
3053-
nodeTo.asExpr().(EventRead).getTarget() = aee.getTarget() and
3053+
nodeTo.asExpr().(EventRead).getTarget() = aee.getTargetEvent() and
30543054
preservesValue = false
30553055
)
30563056
or

csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ private module CallGraph {
336336
or
337337
pred = succ.(DelegateCreation).getArgument()
338338
or
339-
exists(AddEventExpr ae | succ.(EventAccess).getTarget() = ae.getTarget() |
339+
exists(AddEventExpr ae | succ.(EventAccess).getTarget() = ae.getTargetEvent() |
340340
pred = ae.getRValue()
341341
)
342342
}

csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ private class LocalTaintExprStepConfiguration extends ControlFlowReachabilityCon
6060
e1 = e2.(AddExpr).getAnOperand() and
6161
scope = e2
6262
or
63+
e1 = e2.(AssignAddExpr).getAnOperand() and
64+
scope = e2
65+
or
6366
// A comparison expression where taint can flow from one of the
6467
// operands if the other operand is a constant value.
6568
exists(ComparisonTest ct, Expr other |

0 commit comments

Comments
 (0)