Skip to content

Commit 31fbb6f

Browse files
committed
PS: Prevent bad magic by calling a HOP to compute the transitive closure.
1 parent 2d045ea commit 31fbb6f

File tree

2 files changed

+24
-17
lines changed

2 files changed

+24
-17
lines changed

powershell/ql/lib/semmle/code/powershell/ast/internal/Raw/Ast.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ private import Scope
55
class Ast extends @ast {
66
final string toString() { none() }
77

8+
pragma[nomagic]
89
final Ast getParent() { result.getAChild() = this }
910

1011
Ast getChild(ChildIndex i) { none() }
1112

13+
pragma[nomagic]
1214
final Ast getAChild() { result = this.getChild(_) }
1315

1416
Location getLocation() { none() }

powershell/ql/lib/semmle/code/powershell/ast/internal/Synthesis.qll

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -772,28 +772,33 @@ private module IteratorAccessSynth {
772772
// TODO: We could join on something other than the string if we wanted (i.e., the raw parameter).
773773
v.getPropertyName().toLowerCase() = result and
774774
result =
775-
pb.getScriptBlock()
776-
.getParamBlock()
777-
.getAPipelineByPropertyNameParameter()
778-
.getLowerCaseName()
775+
pb.getScriptBlock().getParamBlock().getAPipelineByPropertyNameParameter().getLowerCaseName()
779776
}
780777

778+
private Raw::Ast getParent(Raw::Ast a) { a.getParent() = result }
779+
780+
private predicate isVarAccess(Raw::VarAccess va) { any() }
781+
782+
private predicate isProcessBlock(Raw::ProcessBlock pb) { any() }
783+
784+
private Raw::ProcessBlock getProcessBlock(Raw::VarAccess va) =
785+
doublyBoundedFastTC(getParent/1, isVarAccess/1, isProcessBlock/1)(va, result)
786+
781787
private class IteratorAccessSynth extends Synthesis {
782788
final override predicate isRelevant(Raw::Ast a) {
783-
exists(Raw::ProcessBlock pb, Raw::VarAccess va |
784-
va = a and
785-
pb = va.getParent+()
786-
|
789+
exists(Raw::VarAccess va | va = a |
787790
va.getUserPath() = "_"
788791
or
789-
va.getUserPath().toLowerCase() =
790-
pb.getScriptBlock().getParamBlock().getPipelineParameter().getLowerCaseName()
791-
or
792-
va.getUserPath().toLowerCase() =
793-
pb.getScriptBlock()
794-
.getParamBlock()
795-
.getAPipelineByPropertyNameParameter()
796-
.getLowerCaseName()
792+
exists(Raw::ProcessBlock pb | pb = getProcessBlock(va) |
793+
va.getUserPath().toLowerCase() =
794+
pb.getScriptBlock().getParamBlock().getPipelineParameter().getLowerCaseName()
795+
or
796+
va.getUserPath().toLowerCase() =
797+
pb.getScriptBlock()
798+
.getParamBlock()
799+
.getAPipelineByPropertyNameParameter()
800+
.getLowerCaseName()
801+
)
797802
)
798803
}
799804

@@ -811,7 +816,7 @@ private module IteratorAccessSynth {
811816

812817
private PipelineOrPipelineByPropertyNameIteratorVariable varAccess(Raw::VarAccess va) {
813818
exists(Raw::ProcessBlock pb |
814-
pb = va.getParent+() and
819+
pb = getProcessBlock(va) and
815820
result = TVariableSynth(pb, _) and
816821
va.getUserPath().toLowerCase() = getAPipelineIteratorName(pb, result)
817822
)

0 commit comments

Comments
 (0)