Skip to content

Commit a6b2563

Browse files
committed
PS: Add return and out nodes.
1 parent 54521ad commit a6b2563

File tree

1 file changed

+90
-2
lines changed

1 file changed

+90
-2
lines changed

powershell/ql/lib/semmle/code/powershell/dataflow/internal/DataFlowPrivate.qll

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,89 @@ abstract class ReturnNode extends Node {
489489
}
490490

491491
private module ReturnNodes {
492-
// TODO
492+
/** An AST element that may produce return values when evaluated. */
493+
abstract private class ReturnContainer extends Ast {
494+
/**
495+
* Gets a direct node that will may be returned when evaluating this node.
496+
*/
497+
Node getANode() { none() }
498+
499+
/** Gets a child that may produce more nodes that may be returned. */
500+
abstract ReturnContainer getAChild();
501+
502+
/**
503+
* Gets a (possibly transitive) node that may be returned when evaluating
504+
* this node.
505+
*/
506+
final Node getAReturnedNode() {
507+
result = this.getANode()
508+
or
509+
result = this.getAChild().getAReturnedNode()
510+
}
511+
}
512+
513+
class ScriptBlockReturnContainer extends ReturnContainer, ScriptBlock {
514+
final override ReturnContainer getAChild() { result = this.getEndBlock() }
515+
}
516+
517+
class NamedBlockReturnContainer extends ReturnContainer, NamedBlock {
518+
final override ReturnContainer getAChild() { result = this.getAStmt() }
519+
}
520+
521+
class CmdExprReturnContainer extends ReturnContainer, CmdExpr {
522+
final override ExprNode getANode() { result.getExprNode().getExpr() = this.getExpr() }
523+
524+
final override ReturnContainer getAChild() { none() }
525+
}
526+
527+
class LoopStmtReturnContainer extends ReturnContainer, LoopStmt {
528+
final override ReturnContainer getAChild() { result = this.getBody() }
529+
}
530+
531+
class StmtBlockReturnConainer extends ReturnContainer, StmtBlock {
532+
final override ReturnContainer getAChild() { result = this.getAStmt() }
533+
}
534+
535+
class TryStmtReturnContainer extends ReturnContainer, TryStmt {
536+
final override ReturnContainer getAChild() {
537+
result = this.getBody() or result = this.getACatchClause() or result = this.getFinally()
538+
}
539+
}
540+
541+
class ReturnStmtReturnContainer extends ReturnContainer, ReturnStmt {
542+
final override ReturnContainer getAChild() { result = this.getPipeline() }
543+
}
544+
545+
class CatchClausReturnContainer extends ReturnContainer, CatchClause {
546+
final override ReturnContainer getAChild() { result = this.getBody() }
547+
}
548+
549+
class SwitchStmtReturnContainer extends ReturnContainer, SwitchStmt {
550+
final override ReturnContainer getAChild() { result = this.getACase() }
551+
}
552+
553+
class CmdBaseReturnContainer extends ReturnContainer, CmdExpr {
554+
final override ExprNode getANode() { result.getExprNode().getExpr() = this.getExpr() }
555+
556+
final override ReturnContainer getAChild() { none() }
557+
}
558+
559+
class CmdReturnContainer extends ReturnContainer, Cmd {
560+
final override StmtNode getANode() { result.getStmtNode().getStmt() = this }
561+
562+
final override ReturnContainer getAChild() { none() }
563+
}
564+
565+
class NormalReturnNode extends ReturnNode instanceof NodeImpl {
566+
NormalReturnNode() {
567+
exists(ReturnContainer container |
568+
container = this.getEnclosingCallable().asCfgScope() and
569+
this = container.getAReturnedNode()
570+
)
571+
}
572+
573+
final override NormalReturnKind getKind() { any() }
574+
}
493575
}
494576

495577
import ReturnNodes
@@ -501,7 +583,13 @@ abstract class OutNode extends Node {
501583
}
502584

503585
private module OutNodes {
504-
// TODO
586+
/** A data-flow node that reads a value returned directly by a callable */
587+
class CallOutNode extends OutNode instanceof CallNode {
588+
override DataFlowCall getCall(ReturnKind kind) {
589+
result.asCall() = super.getCallNode() and
590+
kind instanceof NormalReturnKind
591+
}
592+
}
505593
}
506594

507595
import OutNodes

0 commit comments

Comments
 (0)