@@ -541,6 +541,7 @@ class ParameterExt extends TParameterExt {
541
541
542
542
private module DataFlowIntegrationInput implements Impl:: DataFlowIntegrationInputSig {
543
543
private import codeql.ruby.controlflow.internal.Guards as Guards
544
+ private import codeql.util.Boolean
544
545
545
546
class Parameter = ParameterExt ;
546
547
@@ -560,6 +561,79 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
560
561
predicate hasCfgNode ( SsaInput:: BasicBlock bb , int i ) { this = bb .getNode ( i ) }
561
562
}
562
563
564
+ abstract class LogicalOperationGuard extends Guard {
565
+ abstract Guard getOperand ( int i ) ;
566
+
567
+ abstract predicate lift ( string id , int i , boolean operandBranch , boolean branch ) ;
568
+ }
569
+
570
+ private class NotGuard extends LogicalOperationGuard ,
571
+ Cfg:: CfgNodes:: ExprNodes:: UnaryOperationCfgNode
572
+ {
573
+ NotGuard ( ) { this .getExpr ( ) instanceof NotExpr }
574
+
575
+ override Guard getOperand ( int i ) { i = 0 and result = this .getOperand ( ) }
576
+
577
+ override predicate lift ( string id , int i , boolean operandBranch , boolean branch ) {
578
+ operandBranch instanceof Boolean and
579
+ id = operandBranch .toString ( ) and
580
+ i = 0 and
581
+ branch = operandBranch .booleanNot ( )
582
+ }
583
+ }
584
+
585
+ private class StmtSequenceGuard extends LogicalOperationGuard ,
586
+ Cfg:: CfgNodes:: ExprNodes:: StmtSequenceCfgNode
587
+ {
588
+ override Guard getOperand ( int i ) { i = 0 and result = this .getLastStmt ( ) }
589
+
590
+ override predicate lift ( string id , int i , boolean operandBranch , boolean branch ) {
591
+ operandBranch instanceof Boolean and
592
+ id = operandBranch .toString ( ) and
593
+ i = 0 and
594
+ branch = operandBranch
595
+ }
596
+ }
597
+
598
+ abstract private class BinaryLogicalOperationGuard extends LogicalOperationGuard ,
599
+ Cfg:: CfgNodes:: ExprNodes:: BinaryOperationCfgNode
600
+ {
601
+ final override Guard getOperand ( int i ) {
602
+ i = 0 and result = this .getLeftOperand ( )
603
+ or
604
+ i = 1 and result = this .getRightOperand ( )
605
+ }
606
+
607
+ abstract predicate lift ( Boolean branchLeft , Boolean branchRight , boolean branch ) ;
608
+
609
+ final override predicate lift ( string id , int i , boolean operandBranch , boolean branch ) {
610
+ exists ( Boolean branchLeft , Boolean branchRight |
611
+ this .lift ( branchLeft , branchRight , branch ) and
612
+ id = branchLeft + "," + branchRight
613
+ |
614
+ i = 0 and operandBranch = branchLeft
615
+ or
616
+ i = 1 and operandBranch = branchRight
617
+ )
618
+ }
619
+ }
620
+
621
+ private class AndGuard extends BinaryLogicalOperationGuard {
622
+ AndGuard ( ) { this .getExpr ( ) instanceof LogicalAndExpr }
623
+
624
+ override predicate lift ( Boolean branchLeft , Boolean branchRight , boolean branch ) {
625
+ branch = branchLeft .booleanOr ( branchRight ) // yes, should not be `booleanAnd`
626
+ }
627
+ }
628
+
629
+ private class OrGuard extends BinaryLogicalOperationGuard {
630
+ OrGuard ( ) { this .getExpr ( ) instanceof LogicalOrExpr }
631
+
632
+ override predicate lift ( Boolean branchLeft , Boolean branchRight , boolean branch ) {
633
+ branch = branchLeft .booleanAnd ( branchRight ) // yes, should not be `booleanOr`
634
+ }
635
+ }
636
+
563
637
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
564
638
predicate guardControlsBlock ( Guard guard , SsaInput:: BasicBlock bb , boolean branch ) {
565
639
Guards:: guardControlsBlock ( guard , bb , branch )
0 commit comments