Skip to content

Commit 33c02fe

Browse files
authored
Merge pull request #355 from hvitved/csharp/guards-logic
Approved by calumgrant
2 parents 62a5aef + 2d25a04 commit 33c02fe

File tree

23 files changed

+820
-295
lines changed

23 files changed

+820
-295
lines changed

csharp/ql/src/Performance/UseTryGetValue.ql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
import csharp
1313
import semmle.code.csharp.commons.StructuralComparison
14-
import semmle.code.csharp.controlflow.Guards
14+
import semmle.code.csharp.controlflow.Guards as G
1515

1616
class SameElement extends StructuralComparisonConfiguration
1717
{
@@ -22,7 +22,7 @@ class SameElement extends StructuralComparisonConfiguration
2222
exists(MethodCall mc, IndexerRead access |
2323
mc.getTarget().hasName("ContainsKey")
2424
and
25-
access.getQualifier().(GuardedExpr).isGuardedBy(mc, mc.getQualifier(), _)
25+
access.getQualifier().(G::GuardedExpr).isGuardedBy(mc, mc.getQualifier(), _)
2626
and
2727
e1 = mc.getArgument(0)
2828
and

csharp/ql/src/Security Features/CWE-022/ZipSlip.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ import semmle.code.csharp.security.dataflow.ZipSlip::ZipSlip
1616

1717
from TaintTrackingConfiguration zipTaintTracking, DataFlow::Node source, DataFlow::Node sink
1818
where zipTaintTracking.hasFlow(source, sink)
19-
select sink, "Unsanitized zip archive $@, which may contain '..', is used in a file system operation.", source, "item path"
19+
select sink, "Unsanitized zip archive $@, which may contain '..', is used in a file system operation.", source, "item path"

csharp/ql/src/Security Features/CWE-022/ZipSlipBad.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ public static void WriteToDirectory(ZipArchiveEntry entry,
99
string destFileName = Path.Combine(destDirectory, entry.FullName);
1010
entry.ExtractToFile(destFileName);
1111
}
12-
}
12+
}

csharp/ql/src/Stubs/Stubs.qll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
/**
1+
/**
22
* Generates C# stubs for use in test code.
33
*
44
* Extend the abstract class `GeneratedDeclaration` with the declarations that should be generated.
55
* This will generate stubs for all the required dependencies as well.
6-
*
6+
*
77
* Use
88
* ```
99
* select generatedCode()
@@ -104,7 +104,7 @@ private abstract class GeneratedType extends ValueOrRefType, GeneratedElement {
104104
result = this.stubComment() +
105105
this.stubAttributes() +
106106
this.stubAbstractModifier() +
107-
this.stubStaticModifier() +
107+
this.stubStaticModifier() +
108108
this.stubAccessibilityModifier() +
109109
this.stubKeyword() + " " +
110110
this.getUndecoratedName() +

csharp/ql/src/semmle/code/csharp/commons/Assertions.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ class ForwarderAssertMethod extends AssertMethod {
144144
override ExceptionClass getExceptionClass() {
145145
result = this.getUnderlyingAssertMethod().getExceptionClass()
146146
}
147-
147+
148148
/** Gets the underlying assertion method that is being forwarded to. */
149149
AssertMethod getUnderlyingAssertMethod() { result = a.getAssertMethod() }
150150
}

csharp/ql/src/semmle/code/csharp/commons/StructuralComparison.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ abstract class StructuralComparisonConfiguration extends string {
152152
*/
153153
module Internal {
154154
// Import all uses of the internal library to make sure caching works
155-
private import semmle.code.csharp.controlflow.Guards
155+
private import semmle.code.csharp.controlflow.Guards as G
156156

157157
/**
158158
* A configuration for performing structural comparisons of program elements

csharp/ql/src/semmle/code/csharp/controlflow/BasicBlocks.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,7 @@ class ConditionBlock extends BasicBlock {
524524
//
525525
// In the former case, `x` and `y` control `A`, in the latter case
526526
// only `x & y` controls `A` if we do not take sub conditions into account.
527+
deprecated
527528
predicate controlsSubCond(BasicBlock controlled, boolean testIsTrue, Expr cond, boolean condIsTrue) {
528529
impliesSub(getLastNode().getElement(), cond, testIsTrue, condIsTrue) and
529530
controls(controlled, any(BooleanSuccessor s | s.getValue() = testIsTrue))
@@ -542,6 +543,7 @@ class ConditionBlock extends BasicBlock {
542543
* Holds if `e2` is a sub expression of (Boolean) expression `e1`, and
543544
* if `e1` has value `b1` then `e2` must have value `b2`.
544545
*/
546+
deprecated
545547
private predicate impliesSub(Expr e1, Expr e2, boolean b1, boolean b2) {
546548
if e1 instanceof LogicalNotExpr then (
547549
impliesSub(e1.(LogicalNotExpr).getOperand(), e2, b1.booleanNot(), b2)

csharp/ql/src/semmle/code/csharp/controlflow/Completion.qll

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,12 +430,20 @@ private predicate mustHaveMatchingCompletion(ControlFlowElement cfe) {
430430
cfe instanceof SpecificCatchClause
431431
}
432432

433+
/**
434+
* Holds if `cfe` is the element inside foreach statement `fs` that has the emptiness
435+
* completion.
436+
*/
437+
predicate foreachEmptiness(ForeachStmt fs, ControlFlowElement cfe) {
438+
cfe = fs // use `foreach` statement itself to represent the emptiness test
439+
}
440+
433441
/**
434442
* Holds if a normal completion of `cfe` must be an emptiness completion. Thats is,
435443
* whether `cfe` determines whether to execute the body of a `foreach` statement.
436444
*/
437445
private predicate mustHaveEmptinessCompletion(ControlFlowElement cfe) {
438-
cfe instanceof ForeachStmt // use `foreach` statement itself to represent the emptiness test
446+
foreachEmptiness(_, cfe)
439447
}
440448

441449
/**

csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2593,6 +2593,15 @@ module ControlFlow {
25932593
this = TPhiPreSsaDef(_, result)
25942594
}
25952595

2596+
LocalScopeVariableRead getARead() {
2597+
firstReadSameVar(this, result)
2598+
or
2599+
exists(LocalScopeVariableRead read |
2600+
firstReadSameVar(this, read) |
2601+
adjacentReadPairSameVar+(read, result)
2602+
)
2603+
}
2604+
25962605
Location getLocation() {
25972606
exists(AssignableDefinition def |
25982607
this = TExplicitPreSsaDef(_, _, def, _) |
@@ -2720,21 +2729,29 @@ module ControlFlow {
27202729
ssaRefRank(bb2, i2, v, _) = 1
27212730
}
27222731

2723-
predicate firstReadSameVar(Definition def, LocalScopeVariableRead read) {
2724-
exists(SimpleLocalScopeVariable v, PreBasicBlock b1, int i1, PreBasicBlock b2, int i2 |
2725-
adjacentVarRefs(v, b1, i1, b2, i2) and
2726-
defAt(b1, i1, def, v) and
2727-
readAt(b2, i2, read, v)
2728-
)
2729-
}
2732+
private cached module PreSsaCached {
2733+
cached
2734+
predicate firstReadSameVar(Definition def, LocalScopeVariableRead read) {
2735+
exists(SimpleLocalScopeVariable v, PreBasicBlock b1, int i1, PreBasicBlock b2, int i2 |
2736+
adjacentVarRefs(v, b1, i1, b2, i2) and
2737+
defAt(b1, i1, def, v) and
2738+
readAt(b2, i2, read, v)
2739+
)
2740+
}
27302741

2731-
predicate adjacentReadPairSameVar(LocalScopeVariableRead read1, LocalScopeVariableRead read2) {
2732-
exists(SimpleLocalScopeVariable v, PreBasicBlock bb1, int i1, PreBasicBlock bb2, int i2 |
2733-
adjacentVarRefs(v, bb1, i1, bb2, i2) and
2734-
readAt(bb1, i1, read1, v) and
2735-
readAt(bb2, i2, read2, v)
2736-
)
2742+
cached
2743+
predicate adjacentReadPairSameVar(LocalScopeVariableRead read1, LocalScopeVariableRead read2) {
2744+
exists(SimpleLocalScopeVariable v, PreBasicBlock bb1, int i1, PreBasicBlock bb2, int i2 |
2745+
adjacentVarRefs(v, bb1, i1, bb2, i2) and
2746+
readAt(bb1, i1, read1, v) and
2747+
readAt(bb2, i2, read2, v)
2748+
)
2749+
}
2750+
2751+
cached
2752+
predicate forceCachingInSameStage() { any() }
27372753
}
2754+
import PreSsaCached
27382755
}
27392756

27402757
/**
@@ -3327,11 +3344,7 @@ module ControlFlow {
33273344
* Holds if condition `cb` is a read of the SSA variable in this split.
33283345
*/
33293346
private predicate defCondition(ConditionBlock cb) {
3330-
exists(LocalScopeVariableRead read1, LocalScopeVariableRead read2 |
3331-
firstReadSameVar(def, read1) |
3332-
adjacentReadPairSameVar*(read1, read2) and
3333-
read2 = cb.getLastElement()
3334-
)
3347+
cb.getLastElement() = def.getARead()
33353348
}
33363349

33373350
/**
@@ -3827,6 +3840,7 @@ module ControlFlow {
38273840
cached
38283841
newtype TPreSsaDef =
38293842
TExplicitPreSsaDef(PreBasicBlocks::PreBasicBlock bb, int i, AssignableDefinition def, LocalScopeVariable v) {
3843+
PreSsa::forceCachingInSameStage() and
38303844
PreSsa::assignableDefAt(bb, i, def, v)
38313845
}
38323846
or

0 commit comments

Comments
 (0)