Skip to content

Commit a16b51a

Browse files
authored
Merge pull request #122 from microsoft/powershell-flow-through-conversions
PS: Flow through conversions
2 parents 91d3f11 + 0e298a8 commit a16b51a

File tree

8 files changed

+70
-8
lines changed

8 files changed

+70
-8
lines changed

powershell/ql/lib/semmle/code/powershell/ConvertExpr.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ class ConvertExpr extends @convert_expression, Expr {
55

66
override SourceLocation getLocation() { convert_expression_location(this, result) }
77

8-
Expr getExpr() { convert_expression(this, _, result, _, _) }
8+
Expr getBase() { convert_expression(this, _, result, _, _) }
99

1010
TypeConstraint getType() { convert_expression(this, _, _, result, _) }
1111

powershell/ql/lib/semmle/code/powershell/ParenExpression.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import powershell
22

33
class ParenExpr extends @paren_expression, Expr {
4-
PipelineBase getExpr() { paren_expression(this, result) }
4+
PipelineBase getBase() { paren_expression(this, result) }
55

66
override SourceLocation getLocation() { paren_expression_location(this, result) }
77

powershell/ql/lib/semmle/code/powershell/controlflow/CfgNodes.qll

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,36 @@ module ExprNodes {
485485
)
486486
}
487487
}
488+
489+
class ConvertExprChildMapping extends ExprChildMapping, ConvertExpr {
490+
override predicate relevantChild(Ast n) { n = this.getBase() }
491+
}
492+
493+
class ConvertCfgNode extends ExprCfgNode {
494+
override string getAPrimaryQlClass() { result = "ConvertCfgNode" }
495+
496+
override ConvertExprChildMapping e;
497+
498+
override ConvertExpr getExpr() { result = e }
499+
500+
final ExprCfgNode getBase() { e.hasCfgChild(e.getBase(), this, result) }
501+
502+
TypeConstraint getType() { result = e.getType() }
503+
}
504+
505+
class ParenExprChildMapping extends ExprChildMapping, ParenExpr {
506+
override predicate relevantChild(Ast n) { n = this.getBase() }
507+
}
508+
509+
class ParenCfgNode extends ExprCfgNode {
510+
override string getAPrimaryQlClass() { result = "ParenExprCfgNode" }
511+
512+
override ParenExprChildMapping e;
513+
514+
override ParenExpr getExpr() { result = e }
515+
516+
final StmtCfgNode getBase() { e.hasCfgChild(e.getBase(), this, result) }
517+
}
488518
}
489519

490520
module StmtNodes {

powershell/ql/lib/semmle/code/powershell/controlflow/internal/ControlFlowGraphImpl.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ module Trees {
589589
class ScriptBlockExprTree extends LeafTree instanceof ScriptBlockExpr { }
590590

591591
class ConvertExprTree extends StandardPostOrderTree instanceof ConvertExpr {
592-
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
592+
override AstNode getChildNode(int i) { i = 0 and result = super.getBase() }
593593
}
594594

595595
class IndexExprTree extends StandardPostOrderTree instanceof IndexExpr {
@@ -601,7 +601,7 @@ module Trees {
601601
}
602602

603603
class ParenExprTree extends StandardPostOrderTree instanceof ParenExpr {
604-
override AstNode getChildNode(int i) { i = 0 and result = super.getExpr() }
604+
override AstNode getChildNode(int i) { i = 0 and result = super.getBase() }
605605
}
606606

607607
class TypeNameExprTree extends LeafTree instanceof TypeNameExpr { }

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ module LocalFlow {
102102
or
103103
nodeFrom.asExpr() = nodeTo.asStmt().(CfgNodes::StmtNodes::CmdExprCfgNode).getExpr()
104104
or
105+
nodeFrom.asExpr() = nodeTo.asExpr().(CfgNodes::ExprNodes::ConvertCfgNode).getBase()
106+
or
107+
nodeFrom.asStmt() = nodeTo.asExpr().(CfgNodes::ExprNodes::ParenCfgNode).getBase()
108+
or
105109
exists(
106110
CfgNodes::ExprNodes::ArrayExprCfgNode arrayExpr, EscapeContainer::EscapeContainer container
107111
|

powershell/ql/lib/semmle/code/powershell/internal/ExplicitWrite.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ module Private {
1010
predicate isExplicitWrite(Expr e, AssignStmt assign) {
1111
e = assign.getLeftHandSide()
1212
or
13-
e = any(ConvertExpr convert | isExplicitWrite(convert, assign)).getExpr()
13+
e = any(ConvertExpr convert | isExplicitWrite(convert, assign)).getBase()
1414
or
1515
e = any(ArrayLiteral array | isExplicitWrite(array, assign)).getAnElement()
1616
}

powershell/ql/test/library-tests/dataflow/local/test.expected

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,37 @@
33
| test.ps1:1:7:1:13 | Source | test.ps1:1:1:1:13 | ...=... |
44
| test.ps1:2:1:2:9 | Sink | test.ps1:2:1:2:9 | pre-return value for Sink |
55
| test.ps1:2:1:2:9 | Sink | test.ps1:2:1:2:9 | pre-return value for Sink |
6-
| test.ps1:2:1:2:9 | implicit unwrapping of Sink | test.ps1:1:1:8:9 | return value for test.ps1 |
6+
| test.ps1:2:1:2:9 | implicit unwrapping of Sink | test.ps1:1:1:14:8 | return value for test.ps1 |
77
| test.ps1:2:1:2:9 | pre-return value for Sink | test.ps1:2:1:2:9 | implicit unwrapping of Sink |
88
| test.ps1:4:1:4:3 | b | test.ps1:5:4:5:6 | b |
99
| test.ps1:4:6:4:13 | GetBool | test.ps1:4:1:4:3 | b |
1010
| test.ps1:4:6:4:13 | GetBool | test.ps1:4:1:4:13 | ...=... |
11+
| test.ps1:5:4:5:6 | b | test.ps1:10:14:10:16 | b |
1112
| test.ps1:6:5:6:8 | a2 | test.ps1:8:6:8:9 | a2 |
1213
| test.ps1:6:11:6:17 | Source | test.ps1:6:5:6:8 | a2 |
1314
| test.ps1:6:11:6:17 | Source | test.ps1:6:5:6:17 | ...=... |
1415
| test.ps1:8:1:8:9 | Sink | test.ps1:8:1:8:9 | pre-return value for Sink |
1516
| test.ps1:8:1:8:9 | Sink | test.ps1:8:1:8:9 | pre-return value for Sink |
16-
| test.ps1:8:1:8:9 | implicit unwrapping of Sink | test.ps1:1:1:8:9 | return value for test.ps1 |
17+
| test.ps1:8:1:8:9 | implicit unwrapping of Sink | test.ps1:1:1:14:8 | return value for test.ps1 |
1718
| test.ps1:8:1:8:9 | pre-return value for Sink | test.ps1:8:1:8:9 | implicit unwrapping of Sink |
19+
| test.ps1:10:1:10:3 | c | test.ps1:11:6:11:8 | c |
20+
| test.ps1:10:6:10:16 | [...]... | test.ps1:10:1:10:3 | c |
21+
| test.ps1:10:6:10:16 | [...]... | test.ps1:10:1:10:16 | ...=... |
22+
| test.ps1:10:6:10:16 | [...]... | test.ps1:10:6:10:16 | [...]... |
23+
| test.ps1:10:14:10:16 | b | test.ps1:10:6:10:16 | [...]... |
24+
| test.ps1:11:1:11:8 | Sink | test.ps1:11:1:11:8 | pre-return value for Sink |
25+
| test.ps1:11:1:11:8 | Sink | test.ps1:11:1:11:8 | pre-return value for Sink |
26+
| test.ps1:11:1:11:8 | implicit unwrapping of Sink | test.ps1:1:1:14:8 | return value for test.ps1 |
27+
| test.ps1:11:1:11:8 | pre-return value for Sink | test.ps1:11:1:11:8 | implicit unwrapping of Sink |
28+
| test.ps1:11:6:11:8 | [post] c | test.ps1:13:7:13:9 | c |
29+
| test.ps1:11:6:11:8 | c | test.ps1:13:7:13:9 | c |
30+
| test.ps1:13:1:13:3 | d | test.ps1:14:6:14:8 | d |
31+
| test.ps1:13:6:13:10 | (...) | test.ps1:13:1:13:3 | d |
32+
| test.ps1:13:6:13:10 | (...) | test.ps1:13:1:13:10 | ...=... |
33+
| test.ps1:13:6:13:10 | (...) | test.ps1:13:6:13:10 | (...) |
34+
| test.ps1:13:7:13:9 | c | test.ps1:13:6:13:10 | (...) |
35+
| test.ps1:13:7:13:9 | c | test.ps1:13:7:13:9 | c |
36+
| test.ps1:14:1:14:8 | Sink | test.ps1:14:1:14:8 | pre-return value for Sink |
37+
| test.ps1:14:1:14:8 | Sink | test.ps1:14:1:14:8 | pre-return value for Sink |
38+
| test.ps1:14:1:14:8 | implicit unwrapping of Sink | test.ps1:1:1:14:8 | return value for test.ps1 |
39+
| test.ps1:14:1:14:8 | pre-return value for Sink | test.ps1:14:1:14:8 | implicit unwrapping of Sink |

powershell/ql/test/library-tests/dataflow/local/test.ps1

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,10 @@ $b = GetBool
55
if($b) {
66
$a2 = Source
77
}
8-
Sink $a2
8+
Sink $a2
9+
10+
$c = [string]$b
11+
Sink $c
12+
13+
$d = ($c)
14+
Sink $d

0 commit comments

Comments
 (0)