@@ -7,12 +7,16 @@ private import codeql.ruby.controlflow.CfgNodes
7
7
private import codeql.ruby.dataflow.SSA
8
8
private import codeql.ruby.ast.internal.Constant
9
9
private import codeql.ruby.InclusionTests
10
+ private import codeql.ruby.ast.internal.Literal
10
11
11
12
private predicate stringConstCompare ( CfgNodes:: AstCfgNode guard , CfgNode testedNode , boolean branch ) {
12
13
exists ( CfgNodes:: ExprNodes:: ComparisonOperationCfgNode c |
13
14
c = guard and
14
15
exists ( CfgNodes:: ExprNodes:: StringLiteralCfgNode strLitNode |
15
- c .getExpr ( ) instanceof EqExpr and branch = true
16
+ // Only consider strings without any interpolations
17
+ not exists ( StringInterpolationComponent comp | comp = strLitNode .getExpr ( ) .getComponent ( _) ) and
18
+ c .getExpr ( ) instanceof EqExpr and
19
+ branch = true
16
20
or
17
21
c .getExpr ( ) instanceof CaseEqExpr and branch = true
18
22
or
@@ -26,24 +30,43 @@ private predicate stringConstCompare(CfgNodes::AstCfgNode guard, CfgNode testedN
26
30
or
27
31
stringConstCaseCompare ( guard , testedNode , branch )
28
32
or
29
- stringConstCompareOr ( guard , testedNode , branch )
33
+ exists ( Ssa:: Definition def , CfgNodes:: ExprNodes:: BinaryOperationCfgNode g |
34
+ g = guard and
35
+ stringConstCompareOr ( guard , def , branch ) and
36
+ stringConstCompare ( g .getLeftOperand ( ) , testedNode , _)
37
+ )
30
38
or
31
39
stringConstCompareAnd ( guard , testedNode , branch )
32
40
}
33
41
42
+ /**
43
+ * Holds if `guard` is an `or` expression whose operands are string comparison guards that test the same SSA variable.
44
+ * `testedNode` is an arbitrary node that is tested by one of the guards.
45
+ * For example:
46
+ *
47
+ * ```rb
48
+ * x == "foo" or x == "bar"
49
+ * ```
50
+ */
34
51
private predicate stringConstCompareOr (
35
- CfgNodes:: ExprNodes:: BinaryOperationCfgNode guard , CfgNode testedNode , boolean branch
52
+ CfgNodes:: ExprNodes:: BinaryOperationCfgNode guard , Ssa :: Definition def , boolean branch
36
53
) {
37
54
guard .getExpr ( ) instanceof LogicalOrExpr and
38
55
branch = true and
39
- exists ( Ssa:: Definition def |
40
- forall ( CfgNode innerGuard | innerGuard = guard .getAnOperand ( ) |
41
- stringConstCompare ( innerGuard , def .getARead ( ) , branch )
42
- ) and
43
- testedNode = any ( CfgNode node | stringConstCompare ( guard .getAnOperand ( ) , node , _) )
56
+ forall ( CfgNode innerGuard | innerGuard = guard .getAnOperand ( ) |
57
+ stringConstCompare ( innerGuard , def .getARead ( ) , branch )
44
58
)
45
59
}
46
60
61
+ /**
62
+ * Holds if guard is an `and` expression containing a string comparison guard in either operand.
63
+ * For example:
64
+ *
65
+ * ```rb
66
+ * x == "foo" and other_condition()
67
+ * other_condition() and x == "foo"
68
+ * ```
69
+ */
47
70
private predicate stringConstCompareAnd (
48
71
CfgNodes:: ExprNodes:: BinaryOperationCfgNode guard , CfgNode testedNode , boolean branch
49
72
) {
0 commit comments