Skip to content

Commit 0d97cd6

Browse files
author
dilanbhalla
committed
Merge branch 'main' of https://github.com/microsoft/codeql into auto/sync-main-pr
2 parents 1e24627 + 02c027d commit 0d97cd6

File tree

27 files changed

+1209
-337
lines changed

27 files changed

+1209
-337
lines changed

csharp/ql/lib/semmle/code/csharp/hashcons/HashCons.qll

Lines changed: 743 additions & 0 deletions
Large diffs are not rendered by default.

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

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -527,13 +527,25 @@ module API {
527527
pred = MkNamespaceOfTypeNameNode(typeName) and
528528
succ = getForwardStartNode(typeName)
529529
)
530-
// or
531-
// TODO: Handle getAMember when the predecessor is a MkUsingNode?
530+
or
531+
pred = MkRoot() and
532+
exists(DataFlow::AutomaticVariableNode automatic |
533+
automatic.getName() = name and
534+
succ = getForwardStartNode(automatic)
535+
)
536+
or
537+
exists(MemberExprReadAccess read |
538+
read.getMemberName().toLowerCase() = name and
539+
pred = getForwardEndNode(getALocalSourceStrict(getNodeFromExpr(read.getQualifier()))) and
540+
succ = getForwardStartNode(getNodeFromExpr(read))
541+
)
532542
}
533543

534544
cached
535545
predicate methodEdge(Node pred, string name, Node succ) {
536-
exists(DataFlow::CallNode call | succ = MkMethodAccessNode(call) and name = call.getName() |
546+
exists(DataFlow::CallNode call |
547+
succ = MkMethodAccessNode(call) and name = call.getName().toLowerCase()
548+
|
537549
pred = getForwardEndNode(getALocalSourceStrict(call.getQualifier()))
538550
)
539551
}

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ newtype ChildIndex =
3232
// hasMemberInType(_, _, i, _)
3333
} or
3434
ThisVar() or
35-
PipelineParamVar() or
36-
PipelineByPropertyNameVar(Raw::PipelineByPropertyNameParameter p) or
3735
PipelineIteratorVar() or
3836
PipelineByPropertyNameIteratorVar(Raw::PipelineByPropertyNameParameter p) or
3937
RealVar(string name) { name = variableNameInScope(_, _) } or
@@ -85,9 +83,6 @@ string stringOfChildIndex(ChildIndex i) {
8583
i = ThisVar() and
8684
result = "ThisVar"
8785
or
88-
i = PipelineParamVar() and
89-
result = "PipelineParamVar"
90-
or
9186
i = PipelineIteratorVar() and
9287
result = "PipelineIteratorVar"
9388
or

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

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,23 +34,49 @@ class Parameter extends Variable instanceof ParameterImpl {
3434

3535
class ThisParameter extends Parameter instanceof ThisParameterImpl { }
3636

37-
class PipelineParameter extends Parameter {
38-
PipelineParameter() { any(Synthesis s).isPipelineParameter(this) }
37+
/** The pipeline parameter of a function. */
38+
class PipelineParameter extends Parameter instanceof PipelineParameterImpl {
39+
ScriptBlock getScriptBlock() { result = super.getScriptBlock() }
3940
}
4041

41-
class PipelineByPropertyNameParameter extends Parameter {
42-
PipelineByPropertyNameParameter() {
43-
exists(NamedAttributeArgument namedAttribute |
44-
this.getAnAttribute().(Attribute).getANamedArgument() = namedAttribute and
45-
namedAttribute.getName().toLowerCase() = "valuefrompipelinebypropertyname"
46-
|
47-
namedAttribute.getValue().getValue().asBoolean() = true
48-
or
49-
not exists(namedAttribute.getValue().getValue().asBoolean())
50-
)
51-
}
42+
/**
43+
* The iterator variable associated with a pipeline parameter.
44+
*
45+
* This is the variable that is bound to the current element in the pipeline.
46+
*/
47+
class PipelineIteratorVariable extends Variable instanceof PipelineIteratorVariableImpl {
48+
ProcessBlock getProcessBlock() { result = super.getProcessBlock() }
49+
}
50+
51+
/**
52+
* A pipeline-by-property-name parameter of a function.
53+
*/
54+
class PipelineByPropertyNameParameter extends Parameter instanceof PipelineByPropertyNameParameterImpl
55+
{
56+
ScriptBlock getScriptBlock() { result = super.getScriptBlock() }
5257

53-
string getPropertyName() { result = this.getName() }
58+
string getPropertyName() { result = super.getName() }
5459

60+
/**
61+
* Gets the iterator variable that is used to iterate over the elements in the pipeline.
62+
*/
5563
PipelineByPropertyNameIteratorVariable getIteratorVariable() { result.getParameter() = this }
5664
}
65+
66+
/**
67+
* The iterator variable associated with a pipeline-by-property-name parameter.
68+
*
69+
* This is the variable that is bound to the current element in the pipeline.
70+
*/
71+
class PipelineByPropertyNameIteratorVariable extends Variable instanceof PipelineByPropertyNameIteratorVariableImpl
72+
{
73+
ProcessBlock getProcessBlock() { result = super.getProcessBlock() }
74+
75+
string getPropertyName() { result = super.getPropertyName() }
76+
77+
/**
78+
* Gets the pipeline-by-property-name parameter that this variable
79+
* iterates over.
80+
*/
81+
PipelineByPropertyNameParameter getParameter() { result = super.getParameter() }
82+
}

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,7 @@ class ScriptBlock extends Ast, TScriptBlock {
8888
)
8989
}
9090

91-
Parameter getParameter(int i) {
92-
synthChild(getRawAst(this), funParam(i), result)
93-
or
94-
any(Synthesis s).pipelineParameterHasIndex(this, i) and
95-
synthChild(getRawAst(this), PipelineParamVar(), result)
96-
}
91+
Parameter getParameter(int i) { synthChild(getRawAst(this), funParam(i), result) }
9792

9893
Parameter getThisParameter() { synthChild(getRawAst(this), ThisVar(), result) }
9994

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

Lines changed: 65 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ private import AutomaticVariable
2323
newtype VarKind =
2424
ThisVarKind() or
2525
ParamVarRealKind() or
26-
ParamVarPipelineKind() or
2726
PipelineIteratorKind() or
2827
PipelineByPropertyNameIteratorKind(string name) {
2928
exists(Raw::ProcessBlock pb |
@@ -78,9 +77,7 @@ class Synthesis extends TSynthesis {
7877

7978
predicate parameterStaticType(Parameter p, string type) { none() }
8079

81-
predicate isPipelineParameter(Parameter p) { none() }
82-
83-
predicate pipelineParameterHasIndex(ScriptBlock s, int i) { none() }
80+
predicate pipelineParameterHasIndex(Raw::ScriptBlock s, int i) { none() }
8481

8582
predicate functionName(FunctionBase f, string name) { none() }
8683

@@ -167,33 +164,28 @@ private module SetVariableAssignment {
167164
}
168165
}
169166

167+
/** Gets the pipeline parameter associated with `s`. */
168+
TVariable getPipelineParameter(Raw::ScriptBlock s) {
169+
exists(ChildIndex i |
170+
any(ParameterSynth::ParameterSynth ps).isPipelineParameterChild(s, _, i, _, _) and
171+
result = TVariableSynth(s, i)
172+
)
173+
}
174+
170175
/**
171176
* Syntesize parameters from parameter blocks and function definitions
172177
* so that they have a uniform API.
173178
*/
174179
private module ParameterSynth {
175-
private class ParameterSynth extends Synthesis {
180+
class ParameterSynth extends Synthesis {
176181
final override predicate isRelevant(Raw::Ast a) { a = any(Scope::Range r).getAParameter() }
177182

178-
private predicate parameter(
179-
Raw::Ast parent, ChildIndex i, Raw::Parameter p, Child child, boolean isPipelineParameter
180-
) {
183+
private predicate parameter(Raw::Ast parent, ChildIndex i, Raw::Parameter p, Child child) {
181184
exists(Scope::Range r, int index |
182185
p = r.getParameter(index) and
183186
parent = r and
184187
i = funParam(index) and
185-
child = SynthChild(VarSynthKind(ParamVarRealKind())) and
186-
if p instanceof Raw::PipelineParameter
187-
then isPipelineParameter = true
188-
else isPipelineParameter = false
189-
)
190-
}
191-
192-
final override predicate isPipelineParameter(Parameter p) {
193-
exists(Raw::Ast parent, ChildIndex i |
194-
parent = getRawAst(p.getFunction().getBody()) and
195-
this.isPipelineParameterChild(parent, _, i) and
196-
p = TVariableSynth(parent, i)
188+
child = SynthChild(VarSynthKind(ParamVarRealKind()))
197189
)
198190
}
199191

@@ -205,47 +197,49 @@ private module ParameterSynth {
205197
}
206198

207199
final override predicate variableSynthName(VariableSynth v, string name) {
208-
exists(Raw::Ast parent, int i, Raw::Parameter p |
209-
this.parameter(parent, FunParam(i), p, _, false) and
210-
v = TVariableSynth(parent, FunParam(i)) and
211-
name = p.getName()
212-
)
213-
or
214-
exists(Raw::Ast parent |
215-
this.child(parent, PipelineParamVar(), _) and
216-
v = TVariableSynth(parent, PipelineParamVar()) and
200+
exists(Raw::Ast parent, ChildIndex i | v = TVariableSynth(parent, i) |
201+
exists(Raw::Parameter p |
202+
this.parameter(parent, i, p, _) and
203+
name = p.getName()
204+
)
205+
or
206+
this.isPipelineParameterChild(parent, _, i, _, true) and
217207
name = "[synth] pipeline"
218208
)
219209
}
220210

221-
private predicate isPipelineParameterChild(Raw::Ast parent, int index, ChildIndex i) {
222-
exists(Scope::Range r | parent = r and i = PipelineParamVar() |
223-
r.getParameter(index) instanceof Raw::PipelineParameter
211+
predicate isPipelineParameterChild(
212+
Raw::Ast parent, int index, ChildIndex i, Child child, boolean synthesized
213+
) {
214+
exists(Scope::Range r |
215+
parent = r and
216+
i = funParam(index) and
217+
child = SynthChild(VarSynthKind(ParamVarRealKind()))
218+
|
219+
r.getParameter(index) instanceof Raw::PipelineParameter and
220+
synthesized = false
224221
or
225222
not r.getAParameter() instanceof Raw::PipelineParameter and
226-
index = synthPipelineParameterChildIndex(r)
223+
index = synthPipelineParameterChildIndex(r) and
224+
synthesized = true
227225
)
228226
}
229227

230-
final override predicate pipelineParameterHasIndex(ScriptBlock s, int i) {
231-
exists(Raw::ScriptBlock scriptBlock |
232-
s = TScriptBlock(scriptBlock) and
233-
this.isPipelineParameterChild(scriptBlock, i, _)
234-
)
228+
final override predicate pipelineParameterHasIndex(Raw::ScriptBlock s, int i) {
229+
this.isPipelineParameterChild(s, i, _, _, _)
235230
}
236231

237232
final override predicate child(Raw::Ast parent, ChildIndex i, Child child) {
238233
// Synthesize parameters
239-
this.parameter(parent, i, _, child, false)
234+
this.parameter(parent, i, _, child)
240235
or
241-
// Synthesize pipeline parameter
242-
child = SynthChild(VarSynthKind(ParamVarPipelineKind())) and
243-
this.isPipelineParameterChild(parent, _, i)
236+
// Synthesize implicit pipeline parameter, if necessary
237+
this.isPipelineParameterChild(parent, _, i, child, true)
244238
or
245239
// Synthesize default values
246240
exists(Raw::Parameter q |
247241
parent = q and
248-
this.parameter(_, _, q, _, _)
242+
this.parameter(_, _, q, _)
249243
|
250244
i = paramDefaultVal() and
251245
child = childRef(getResultAst(q.getDefaultValue()))
@@ -258,30 +252,30 @@ private module ParameterSynth {
258252
}
259253

260254
final override Parameter getResultAstImpl(Raw::Ast r) {
261-
exists(Raw::Ast parent, int i |
262-
this.parameter(parent, FunParam(i), r, _, false) and
263-
result = TVariableSynth(parent, FunParam(i))
264-
)
265-
or
266-
exists(Scope::Range scope, int i, ChildIndex index |
267-
scope.getParameter(i) = r and
268-
this.isPipelineParameterChild(scope, i, index) and
269-
result = TVariableSynth(scope, index)
255+
exists(Raw::Ast parent, ChildIndex i |
256+
this.parameter(parent, i, r, _) and
257+
result = TVariableSynth(parent, i)
270258
)
271259
}
272260

273261
final override Location getLocation(Ast n) {
274-
exists(Raw::Ast parent, Raw::Parameter p, int i |
275-
this.parameter(parent, _, p, _, _) and
276-
n = TVariableSynth(parent, FunParam(i)) and
277-
result = p.getLocation()
262+
exists(Raw::Ast parent, ChildIndex i | n = TVariableSynth(parent, i) |
263+
exists(Raw::Parameter p |
264+
this.parameter(parent, i, p, _) and
265+
result = p.getLocation()
266+
)
267+
or
268+
this.isPipelineParameterChild(parent, _, i, _, true) and
269+
result = parent.getLocation()
278270
)
279271
}
280272

281273
final override predicate parameterStaticType(Parameter n, string type) {
282-
exists(Raw::Ast parent, int i, Raw::Parameter p |
283-
this.parameter(parent, FunParam(i), p, _, false) and
284-
n = TVariableSynth(parent, FunParam(i)) and
274+
exists(Raw::Ast parent, Raw::Parameter p, ChildIndex i |
275+
// No need to consider the synthesized pipeline parameter as it never
276+
// has a static type.
277+
this.parameter(parent, i, p, _) and
278+
n = TVariableSynth(parent, i) and
285279
type = p.getStaticType()
286280
)
287281
}
@@ -440,6 +434,11 @@ private module FunctionSynth {
440434
n = TFunctionSynth(fundefStmt, _) and
441435
result = fundefStmt.getLocation()
442436
)
437+
or
438+
exists(Raw::TopLevelScriptBlock topLevelScriptBlock |
439+
n = TTopLevelFunction(topLevelScriptBlock) and
440+
result = topLevelScriptBlock.getLocation()
441+
)
443442
}
444443
}
445444
}
@@ -857,8 +856,10 @@ private module IteratorAccessSynth {
857856
result = cmdExpr.getLocation()
858857
)
859858
or
860-
exists(Raw::Ast parent |
861-
n = TVariableSynth(parent, _) and
859+
exists(Raw::Ast parent, ChildIndex i |
860+
i instanceof PipelineIteratorVar or i instanceof PipelineByPropertyNameIteratorVar
861+
|
862+
n = TVariableSynth(parent, i) and
862863
result = parent.getLocation()
863864
)
864865
}
@@ -870,12 +871,12 @@ private module PipelineAccess {
870871
final override predicate child(Raw::Ast parent, ChildIndex i, Child child) {
871872
exists(Raw::ProcessBlock pb | parent = pb |
872873
i = processBlockPipelineVarReadAccess() and
873-
exists(PipelineVariable pipelineVar |
874-
pipelineVar = TVariableSynth(pb.getScriptBlock(), PipelineParamVar()) and
874+
exists(PipelineParameter pipelineVar |
875+
pipelineVar = getPipelineParameter(pb.getScriptBlock()) and
875876
child = SynthChild(VarAccessSynthKind(pipelineVar))
876877
)
877878
or
878-
exists(PipelineByPropertyNameVariable pipelineVar, Raw::PipelineByPropertyNameParameter p |
879+
exists(PipelineByPropertyNameParameter pipelineVar, Raw::PipelineByPropertyNameParameter p |
879880
i = processBlockPipelineByPropertyNameVarReadAccess(p.getName()) and
880881
getResultAst(p) = pipelineVar and
881882
child = SynthChild(VarAccessSynthKind(pipelineVar))

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ class TypeNameExpr extends Expr, TTypeNameExpr {
2525
override string toString() { result = this.getName() }
2626

2727
predicate isQualified() { this.getNamespace() != "" }
28+
29+
predicate hasQualifiedName(string namespace, string typename) {
30+
this.isQualified() and
31+
this.parseName(namespace, typename)
32+
}
2833
}
2934

3035
class QualifiedTypeNameExpr extends TypeNameExpr {

0 commit comments

Comments
 (0)