Skip to content

Commit 2ba2099

Browse files
committed
Ruby: Disjunctive barrier guards for free
1 parent c568a8d commit 2ba2099

File tree

4 files changed

+25
-29
lines changed

4 files changed

+25
-29
lines changed

Diff for: ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll

-24
Original file line numberDiff line numberDiff line change
@@ -31,30 +31,6 @@ private predicate stringConstCompare(CfgNodes::AstCfgNode guard, CfgNode testedN
3131
)
3232
or
3333
stringConstCaseCompare(guard, testedNode, branch)
34-
or
35-
exists(CfgNodes::ExprNodes::BinaryOperationCfgNode g |
36-
g = guard and
37-
stringConstCompareOr(guard, branch) and
38-
stringConstCompare(g.getLeftOperand(), testedNode, _)
39-
)
40-
}
41-
42-
/**
43-
* Holds if `guard` is an `or` expression whose operands are string comparison guards.
44-
* For example:
45-
*
46-
* ```rb
47-
* x == "foo" or x == "bar"
48-
* ```
49-
*/
50-
private predicate stringConstCompareOr(
51-
CfgNodes::ExprNodes::BinaryOperationCfgNode guard, boolean branch
52-
) {
53-
guard.getExpr() instanceof LogicalOrExpr and
54-
branch = true and
55-
forall(CfgNode innerGuard | innerGuard = guard.getAnOperand() |
56-
stringConstCompare(innerGuard, any(Ssa::Definition def).getARead(), branch)
57-
)
5834
}
5935

6036
/**

Diff for: ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll

+24
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,30 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
560560
predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { this = bb.getNode(i) }
561561
}
562562

563+
class AndGuard extends Guard instanceof Cfg::CfgNodes::ExprNodes::BinaryOperationCfgNode {
564+
AndGuard() { this.getExpr() instanceof LogicalAndExpr }
565+
566+
Guard getLeftOperand() {
567+
result = Cfg::CfgNodes::ExprNodes::BinaryOperationCfgNode.super.getLeftOperand()
568+
}
569+
570+
Guard getRightOperand() {
571+
result = Cfg::CfgNodes::ExprNodes::BinaryOperationCfgNode.super.getRightOperand()
572+
}
573+
}
574+
575+
class OrGuard extends Guard, Cfg::CfgNodes::ExprNodes::BinaryOperationCfgNode {
576+
OrGuard() { this.getExpr() instanceof LogicalOrExpr }
577+
578+
Guard getLeftOperand() {
579+
result = Cfg::CfgNodes::ExprNodes::BinaryOperationCfgNode.super.getLeftOperand()
580+
}
581+
582+
Guard getRightOperand() {
583+
result = Cfg::CfgNodes::ExprNodes::BinaryOperationCfgNode.super.getRightOperand()
584+
}
585+
}
586+
563587
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
564588
predicate guardControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
565589
Guards::guardControlsBlock(guard, bb, branch)

Diff for: ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-flow.expected

-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ edges
1010
| barrier_flow.rb:82:5:82:5 | x | barrier_flow.rb:93:14:93:14 | x | provenance | |
1111
| barrier_flow.rb:82:5:82:5 | x | barrier_flow.rb:99:14:99:14 | x | provenance | |
1212
| barrier_flow.rb:82:5:82:5 | x | barrier_flow.rb:103:14:103:14 | x | provenance | |
13-
| barrier_flow.rb:82:5:82:5 | x | barrier_flow.rb:105:14:105:14 | x | provenance | |
1413
| barrier_flow.rb:82:9:82:18 | call to source | barrier_flow.rb:82:5:82:5 | x | provenance | |
1514
| barrier_flow.rb:110:5:110:5 | x | barrier_flow.rb:115:14:115:14 | x | provenance | |
1615
| barrier_flow.rb:110:5:110:5 | x | barrier_flow.rb:119:14:119:14 | x | provenance | |
@@ -33,7 +32,6 @@ nodes
3332
| barrier_flow.rb:93:14:93:14 | x | semmle.label | x |
3433
| barrier_flow.rb:99:14:99:14 | x | semmle.label | x |
3534
| barrier_flow.rb:103:14:103:14 | x | semmle.label | x |
36-
| barrier_flow.rb:105:14:105:14 | x | semmle.label | x |
3735
| barrier_flow.rb:110:5:110:5 | x | semmle.label | x |
3836
| barrier_flow.rb:110:9:110:18 | call to source | semmle.label | call to source |
3937
| barrier_flow.rb:115:14:115:14 | x | semmle.label | x |
@@ -42,7 +40,6 @@ nodes
4240
| barrier_flow.rb:131:14:131:14 | x | semmle.label | x |
4341
subpaths
4442
testFailures
45-
| barrier_flow.rb:105:14:105:14 | x | Unexpected result: hasValueFlow=10 |
4643
#select
4744
| barrier_flow.rb:4:10:4:10 | x | barrier_flow.rb:2:9:2:17 | call to source | barrier_flow.rb:4:10:4:10 | x | $@ | barrier_flow.rb:2:9:2:17 | call to source | call to source |
4845
| barrier_flow.rb:11:14:11:14 | x | barrier_flow.rb:8:9:8:17 | call to source | barrier_flow.rb:11:14:11:14 | x | $@ | barrier_flow.rb:8:9:8:17 | call to source | call to source |
@@ -51,7 +48,6 @@ testFailures
5148
| barrier_flow.rb:93:14:93:14 | x | barrier_flow.rb:82:9:82:18 | call to source | barrier_flow.rb:93:14:93:14 | x | $@ | barrier_flow.rb:82:9:82:18 | call to source | call to source |
5249
| barrier_flow.rb:99:14:99:14 | x | barrier_flow.rb:82:9:82:18 | call to source | barrier_flow.rb:99:14:99:14 | x | $@ | barrier_flow.rb:82:9:82:18 | call to source | call to source |
5350
| barrier_flow.rb:103:14:103:14 | x | barrier_flow.rb:82:9:82:18 | call to source | barrier_flow.rb:103:14:103:14 | x | $@ | barrier_flow.rb:82:9:82:18 | call to source | call to source |
54-
| barrier_flow.rb:105:14:105:14 | x | barrier_flow.rb:82:9:82:18 | call to source | barrier_flow.rb:105:14:105:14 | x | $@ | barrier_flow.rb:82:9:82:18 | call to source | call to source |
5551
| barrier_flow.rb:115:14:115:14 | x | barrier_flow.rb:110:9:110:18 | call to source | barrier_flow.rb:115:14:115:14 | x | $@ | barrier_flow.rb:110:9:110:18 | call to source | call to source |
5652
| barrier_flow.rb:119:14:119:14 | x | barrier_flow.rb:110:9:110:18 | call to source | barrier_flow.rb:119:14:119:14 | x | $@ | barrier_flow.rb:110:9:110:18 | call to source | call to source |
5753
| barrier_flow.rb:125:14:125:14 | x | barrier_flow.rb:110:9:110:18 | call to source | barrier_flow.rb:125:14:125:14 | x | $@ | barrier_flow.rb:110:9:110:18 | call to source | call to source |

Diff for: ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
testFailures
2-
| barrier_flow.rb:105:16:105:26 | # $ guarded | Missing result:guarded= |
32
failures
43
newStyleBarrierGuards
54
| barrier-guards.rb:3:16:4:19 | [input] SSA phi read(foo) |
@@ -54,6 +53,7 @@ newStyleBarrierGuards
5453
| barrier_flow.rb:91:14:91:14 | x |
5554
| barrier_flow.rb:96:24:96:24 | x |
5655
| barrier_flow.rb:97:14:97:14 | x |
56+
| barrier_flow.rb:105:14:105:14 | x |
5757
| barrier_flow.rb:112:8:112:19 | [input] SSA phi read(x) |
5858
| barrier_flow.rb:112:24:112:35 | [input] SSA phi read(x) |
5959
| barrier_flow.rb:113:14:113:14 | x |

0 commit comments

Comments
 (0)