@@ -550,100 +550,45 @@ abstract class ReturnNode extends Node {
550
550
abstract ReturnKind getKind ( ) ;
551
551
}
552
552
553
- private module ReturnNodes {
554
- /** An AST element that may produce return values when evaluated. */
555
- abstract private class ReturnContainer extends Ast {
556
- /**
557
- * Gets a direct node that will may be returned when evaluating this node.
558
- */
559
- CfgNode getANode ( ) { none ( ) }
560
-
561
- /** Gets a child that may produce more nodes that may be returned. */
562
- abstract ReturnContainer getAChild ( ) ;
563
-
564
- /**
565
- * Gets a (possibly transitive) node that may be returned when evaluating
566
- * this node.
567
- */
568
- final CfgNode getAReturnedNode ( ) {
569
- result = this .getANode ( )
553
+ private module EscapeContainer {
554
+ private import semmle.code.powershell.internal.AstEscape:: Private
555
+
556
+ private module ReturnContainerInterpreter implements InterpretAstInputSig {
557
+ class T = CfgNodes:: AstCfgNode ;
558
+
559
+ T interpret ( Ast a ) {
560
+ result .( CfgNodes:: ExprCfgNode ) .getExpr ( ) = a
570
561
or
571
- result = this . getAChild ( ) . getAReturnedNode ( )
562
+ result . ( CfgNodes :: StmtCfgNode ) . getStmt ( ) = a . ( Cmd )
572
563
}
564
+ }
573
565
566
+ class EscapeContainer extends AstEscape< ReturnContainerInterpreter > :: Element {
574
567
/** Holds if `n` may be returned multiples times. */
575
568
predicate mayBeMultiReturned ( CfgNode n ) {
576
569
n = this .getANode ( ) and
577
570
n .getASuccessor + ( ) = n
578
571
or
579
- this .getAChild ( ) .mayBeMultiReturned ( n )
572
+ this .getAChild ( ) .( EscapeContainer ) . mayBeMultiReturned ( n )
580
573
}
581
574
}
575
+ }
582
576
583
- class ScriptBlockReturnContainer extends ReturnContainer , ScriptBlock {
584
- final override ReturnContainer getAChild ( ) { result = this .getEndBlock ( ) }
585
- }
586
-
587
- class NamedBlockReturnContainer extends ReturnContainer , NamedBlock {
588
- final override ReturnContainer getAChild ( ) { result = this .getAStmt ( ) }
589
- }
590
-
591
- class CmdExprReturnContainer extends ReturnContainer , CmdExpr {
592
- final override CfgNodes:: ExprCfgNode getANode ( ) { result .getExpr ( ) = this .getExpr ( ) }
593
-
594
- final override ReturnContainer getAChild ( ) { none ( ) }
595
- }
596
-
597
- class LoopStmtReturnContainer extends ReturnContainer , LoopStmt {
598
- final override ReturnContainer getAChild ( ) { result = this .getBody ( ) }
599
- }
600
-
601
- class StmtBlockReturnConainer extends ReturnContainer , StmtBlock {
602
- final override ReturnContainer getAChild ( ) { result = this .getAStmt ( ) }
603
- }
604
-
605
- class TryStmtReturnContainer extends ReturnContainer , TryStmt {
606
- final override ReturnContainer getAChild ( ) {
607
- result = this .getBody ( ) or result = this .getACatchClause ( ) or result = this .getFinally ( )
608
- }
609
- }
610
-
611
- class ReturnStmtReturnContainer extends ReturnContainer , ReturnStmt {
612
- final override ReturnContainer getAChild ( ) { result = this .getPipeline ( ) }
613
- }
614
-
615
- class CatchClausReturnContainer extends ReturnContainer , CatchClause {
616
- final override ReturnContainer getAChild ( ) { result = this .getBody ( ) }
617
- }
618
-
619
- class SwitchStmtReturnContainer extends ReturnContainer , SwitchStmt {
620
- final override ReturnContainer getAChild ( ) { result = this .getACase ( ) }
621
- }
622
-
623
- class CmdBaseReturnContainer extends ReturnContainer , CmdExpr {
624
- final override CfgNodes:: ExprCfgNode getANode ( ) { result .getExpr ( ) = this .getExpr ( ) }
625
-
626
- final override ReturnContainer getAChild ( ) { none ( ) }
627
- }
628
-
629
- class CmdReturnContainer extends ReturnContainer , Cmd {
630
- final override CfgNodes:: StmtCfgNode getANode ( ) { result .getStmt ( ) = this }
631
-
632
- final override ReturnContainer getAChild ( ) { none ( ) }
633
- }
577
+ private module ReturnNodes {
578
+ private import EscapeContainer
634
579
635
- private predicate isReturnedImpl ( CfgNodes:: AstCfgNode n , ReturnContainer container ) {
580
+ private predicate isReturnedImpl ( CfgNodes:: AstCfgNode n , EscapeContainer container ) {
636
581
container = n .getScope ( ) and
637
- n = container .getAReturnedNode ( )
582
+ n = container .getAnEscapingElement ( )
638
583
}
639
584
640
585
/**
641
586
* Holds if `n` may be returned, and there are possibly
642
587
* more than one return value from the function.
643
588
*/
644
589
predicate isMultiReturned ( CfgNodes:: AstCfgNode n ) {
645
- exists ( ReturnContainer container | isReturnedImpl ( n , container ) |
646
- strictcount ( container .getAReturnedNode ( ) ) > 1
590
+ exists ( EscapeContainer container | isReturnedImpl ( n , container ) |
591
+ strictcount ( container .getAnEscapingElement ( ) ) > 1
647
592
or
648
593
container .mayBeMultiReturned ( n )
649
594
)
0 commit comments