Skip to content

Commit 40e020d

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

3 files changed

Lines changed: 30 additions & 6 deletions

File tree

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

Lines changed: 26 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,17 @@ module AssignableDefinitions {
735742
/** Gets the assignable (field or property) being initialized. */
736743
Assignable getAssignable() { result = fieldOrProp }
737744
}
745+
746+
/**
747+
* A definition by a compound assignment operation, for example `x += y`.
748+
*/
749+
class AssignOperationDefinition extends AssignableDefinition, TAssignOperationDefinition {
750+
AssignOperation ao;
751+
752+
AssignOperationDefinition() { this = TAssignOperationDefinition(ao) }
753+
754+
override Expr getSource() { result = ao }
755+
756+
override string toString() { result = ao.toString() }
757+
}
738758
}

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/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)