Skip to content

Commit ea2f155

Browse files
committed
PS: Add two new kinds of nodes: A node that represents implicit unwrapping and a new node to hold the final return value of a function.
1 parent 706eff2 commit ea2f155

File tree

1 file changed

+59
-1
lines changed

1 file changed

+59
-1
lines changed

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

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,10 @@ private module Cached {
130130
)
131131
or
132132
n = any(CfgNodes::ExprNodes::IndexCfgNode index).getBase()
133-
}
133+
} or
134+
TPreReturnNodeImpl(CfgNodes::AstCfgNode n, Boolean isArray) { isReturned(n) } or
135+
TImplicitWrapNode(CfgNodes::AstCfgNode n, Boolean shouldWrap) { isReturned(n) } or
136+
TReturnNodeImpl(CfgScope scope)
134137

135138
cached
136139
Location getLocation(NodeImpl n) { result = n.getLocationImpl() }
@@ -742,6 +745,61 @@ private module PostUpdateNodes {
742745

743746
private import PostUpdateNodes
744747

748+
/**
749+
* A node that performs implicit array unwrapping when an expression
750+
* (or statement) is being returned from a function.
751+
*/
752+
private class ImplicitWrapNode extends TImplicitWrapNode, NodeImpl {
753+
private CfgNodes::AstCfgNode n;
754+
private boolean shouldWrap;
755+
756+
ImplicitWrapNode() { this = TImplicitWrapNode(n, shouldWrap) }
757+
758+
CfgNodes::AstCfgNode getReturnedNode() { result = n }
759+
760+
predicate shouldWrap() { shouldWrap = true }
761+
762+
override CfgScope getCfgScope() { result = n.getScope() }
763+
764+
override Location getLocationImpl() { result = n.getLocation() }
765+
766+
override string toStringImpl() { result = "implicit unwrapping of " + n.toString() }
767+
}
768+
769+
/**
770+
* A node that represents the return value before any array-unwrapping
771+
* has been performed.
772+
*/
773+
private class PreReturNodeImpl extends TPreReturnNodeImpl, NodeImpl {
774+
private CfgNodes::AstCfgNode n;
775+
private boolean isArray;
776+
777+
PreReturNodeImpl() { this = TPreReturnNodeImpl(n, isArray) }
778+
779+
CfgNodes::AstCfgNode getReturnedNode() { result = n }
780+
781+
override CfgScope getCfgScope() { result = n.getScope() }
782+
783+
override Location getLocationImpl() { result = n.getLocation() }
784+
785+
override string toStringImpl() { result = "pre-return value for " + n.toString() }
786+
787+
override predicate nodeIsHidden() { any() }
788+
}
789+
790+
/** The node that represents the return value of a function. */
791+
private class ReturnNodeImpl extends TReturnNodeImpl, NodeImpl {
792+
CfgScope scope;
793+
794+
ReturnNodeImpl() { this = TReturnNodeImpl(scope) }
795+
796+
override CfgScope getCfgScope() { result = scope }
797+
798+
override Location getLocationImpl() { result = scope.getLocation() }
799+
800+
override string toStringImpl() { result = "return value for " + scope.toString() }
801+
}
802+
745803
/** A node that performs a type cast. */
746804
class CastNode extends Node {
747805
CastNode() { none() }

0 commit comments

Comments
 (0)