mirror of
https://github.com/github/codeql.git
synced 2026-05-25 00:27:09 +02:00
PS: Delete the old AST.
This commit is contained in:
@@ -1,26 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class ArrayExpr extends @array_expression, Expr {
|
||||
override SourceLocation getLocation() { array_expression_location(this, result) }
|
||||
|
||||
StmtBlock getStmtBlock() { array_expression(this, result) }
|
||||
|
||||
/**
|
||||
* Gets the i'th element of this `ArrayExpr`, if this can be determined statically.
|
||||
*
|
||||
* See `getStmtBlock` when the array elements are not known statically.
|
||||
*/
|
||||
Expr getElement(int i) {
|
||||
result =
|
||||
unique( | | this.getStmtBlock().getAStmt()).(CmdExpr).getExpr().(ArrayLiteral).getElement(i)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an element of this `ArrayExpr`, if this can be determined statically.
|
||||
*
|
||||
* See `getStmtBlock` when the array elements are not known statically.
|
||||
*/
|
||||
Expr getAnElement() { result = this.getElement(_) }
|
||||
|
||||
override string toString() { result = "@(...)" }
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class ArrayLiteral extends @array_literal, Expr {
|
||||
override SourceLocation getLocation() { array_literal_location(this, result) }
|
||||
|
||||
Expr getElement(int index) { array_literal_element(this, index, result) }
|
||||
|
||||
Expr getAnElement() { array_literal_element(this, _, result) }
|
||||
|
||||
override string toString() { result = "...,..." }
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class AssignStmt extends @assignment_statement, PipelineBase {
|
||||
override SourceLocation getLocation() { assignment_statement_location(this, result) }
|
||||
|
||||
int getKind() { assignment_statement(this, result, _, _) }
|
||||
|
||||
Expr getLeftHandSide() { assignment_statement(this, _, result, _) }
|
||||
|
||||
Stmt getRightHandSide() { assignment_statement(this, _, _, result) }
|
||||
|
||||
override string toString() { result = "...=..." }
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import powershell
|
||||
private import semmle.code.powershell.controlflow.internal.Scope
|
||||
|
||||
class Ast extends @ast {
|
||||
string toString() { none() }
|
||||
|
||||
Ast getParent() { parent(this, result) }
|
||||
|
||||
Location getLocation() { none() }
|
||||
|
||||
Scope getEnclosingScope() { result = scopeOf(this) }
|
||||
|
||||
final Function getEnclosingFunction() { this.getEnclosingScope() = result.getBody() }
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class Attribute extends @attribute, AttributeBase {
|
||||
override string toString() { result = this.getName() }
|
||||
|
||||
override SourceLocation getLocation() { attribute_location(this, result) }
|
||||
|
||||
string getName() { attribute(this, result, _, _) }
|
||||
|
||||
int getNumNamedArguments() { attribute(this, _, result, _) }
|
||||
|
||||
int getNumPositionalArguments() { attribute(this, _, _, result) }
|
||||
|
||||
NamedAttributeArgument getNamedArgument(int i) { attribute_named_argument(this, i, result) }
|
||||
|
||||
NamedAttributeArgument getANamedArgument() { result = this.getNamedArgument(_) }
|
||||
|
||||
int getNumberOfArguments() { result = count(this.getAPositionalArgument()) }
|
||||
|
||||
Expr getPositionalArgument(int i) { attribute_positional_argument(this, i, result) }
|
||||
|
||||
Expr getAPositionalArgument() { result = this.getPositionalArgument(_) }
|
||||
|
||||
int getNumberOfPositionalArguments() { result = count(this.getAPositionalArgument()) }
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class AttributeBase extends @attribute_base, Ast { }
|
||||
@@ -1,13 +0,0 @@
|
||||
import powershell
|
||||
|
||||
/** The base class for constant expressions. */
|
||||
class BaseConstExpr extends @base_constant_expression, Expr {
|
||||
/** Gets the type of this constant expression. */
|
||||
string getType() { none() }
|
||||
|
||||
/** Gets a string literal of this constant expression. */
|
||||
StringLiteral getValue() { none() }
|
||||
|
||||
/** Gets a string literal representing this constant expression. */
|
||||
final override string toString() { result = this.getValue().toString() }
|
||||
}
|
||||
@@ -1,319 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class BinaryExpr extends @binary_expression, Expr {
|
||||
override SourceLocation getLocation() { binary_expression_location(this, result) }
|
||||
|
||||
int getKind() { binary_expression(this, result, _, _) }
|
||||
|
||||
/** Gets an operand of this binary expression. */
|
||||
Expr getAnOperand() {
|
||||
result = this.getLeft()
|
||||
or
|
||||
result = this.getRight()
|
||||
}
|
||||
|
||||
/** Holds if this binary expression has the operands `e1` and `e2`. */
|
||||
predicate hasOperands(Expr e1, Expr e2) {
|
||||
e1 = this.getLeft() and
|
||||
e2 = this.getRight()
|
||||
or
|
||||
e1 = this.getRight() and
|
||||
e2 = this.getLeft()
|
||||
}
|
||||
|
||||
Expr getLeft() { binary_expression(this, _, result, _) }
|
||||
|
||||
Expr getRight() { binary_expression(this, _, _, result) }
|
||||
}
|
||||
|
||||
abstract private class AbstractArithmeticExpr extends BinaryExpr { }
|
||||
|
||||
final class ArithmeticExpr = AbstractArithmeticExpr;
|
||||
|
||||
class AddExpr extends AbstractArithmeticExpr {
|
||||
AddExpr() { this.getKind() = 40 }
|
||||
|
||||
final override string toString() { result = "...+..." }
|
||||
}
|
||||
|
||||
class SubExpr extends AbstractArithmeticExpr {
|
||||
SubExpr() { this.getKind() = 41 }
|
||||
|
||||
final override string toString() { result = "...-..." }
|
||||
}
|
||||
|
||||
class MulExpr extends AbstractArithmeticExpr {
|
||||
MulExpr() { this.getKind() = 37 }
|
||||
|
||||
final override string toString() { result = "...*..." }
|
||||
}
|
||||
|
||||
class DivExpr extends AbstractArithmeticExpr {
|
||||
DivExpr() { this.getKind() = 38 }
|
||||
|
||||
final override string toString() { result = ".../..." }
|
||||
}
|
||||
|
||||
class RemExpr extends AbstractArithmeticExpr {
|
||||
RemExpr() { this.getKind() = 39 }
|
||||
|
||||
final override string toString() { result = "...%..." }
|
||||
}
|
||||
|
||||
abstract private class AbstractBitwiseExpr extends BinaryExpr { }
|
||||
|
||||
final class BitwiseExpr = AbstractBitwiseExpr;
|
||||
|
||||
class BitwiseAndExpr extends AbstractBitwiseExpr {
|
||||
BitwiseAndExpr() { this.getKind() = 56 }
|
||||
|
||||
final override string toString() { result = "...&..." }
|
||||
}
|
||||
|
||||
class BitwiseOrExpr extends AbstractBitwiseExpr {
|
||||
BitwiseOrExpr() { this.getKind() = 57 }
|
||||
|
||||
final override string toString() { result = "...|..." }
|
||||
}
|
||||
|
||||
class BitwiseXorExpr extends AbstractBitwiseExpr {
|
||||
BitwiseXorExpr() { this.getKind() = 58 }
|
||||
|
||||
final override string toString() { result = "...^..." }
|
||||
}
|
||||
|
||||
class ShiftLeftExpr extends AbstractBitwiseExpr {
|
||||
ShiftLeftExpr() { this.getKind() = 97 }
|
||||
|
||||
final override string toString() { result = "...<<..." }
|
||||
}
|
||||
|
||||
class ShiftRightExpr extends AbstractBitwiseExpr {
|
||||
ShiftRightExpr() { this.getKind() = 98 }
|
||||
|
||||
final override string toString() { result = "...>>..." }
|
||||
}
|
||||
|
||||
abstract private class AbstractComparisonExpr extends BinaryExpr { }
|
||||
|
||||
final class ComparisonExpr = AbstractComparisonExpr;
|
||||
|
||||
abstract private class AbstractCaseInsensitiveComparisonExpr extends AbstractComparisonExpr { }
|
||||
|
||||
final class CaseInsensitiveComparisonExpr = AbstractCaseInsensitiveComparisonExpr;
|
||||
|
||||
abstract private class AbstractCaseSensitiveComparisonExpr extends AbstractComparisonExpr { }
|
||||
|
||||
final class CaseSensitiveComparisonExpr = AbstractCaseSensitiveComparisonExpr;
|
||||
|
||||
class EqExpr extends AbstractCaseInsensitiveComparisonExpr {
|
||||
EqExpr() { this.getKind() = 60 }
|
||||
|
||||
final override string toString() { result = "... -eq ..." }
|
||||
}
|
||||
|
||||
class NeExpr extends AbstractCaseInsensitiveComparisonExpr {
|
||||
NeExpr() { this.getKind() = 61 }
|
||||
|
||||
final override string toString() { result = "... -ne ..." }
|
||||
}
|
||||
|
||||
class CEqExpr extends AbstractCaseSensitiveComparisonExpr {
|
||||
CEqExpr() { this.getKind() = 76 }
|
||||
|
||||
final override string toString() { result = "... -ceq ..." }
|
||||
}
|
||||
|
||||
class CNeExpr extends AbstractCaseSensitiveComparisonExpr {
|
||||
CNeExpr() { this.getKind() = 77 }
|
||||
|
||||
final override string toString() { result = "... -cne ..." }
|
||||
}
|
||||
|
||||
abstract private class AbstractRelationalExpr extends AbstractComparisonExpr { }
|
||||
|
||||
final class RelationalExpr = AbstractRelationalExpr;
|
||||
|
||||
abstract private class AbstractCaseInsensitiveRelationalExpr extends AbstractRelationalExpr { }
|
||||
|
||||
final class CaseInsensitiveRelationalExpr = AbstractCaseInsensitiveRelationalExpr;
|
||||
|
||||
abstract private class AbstractCaseSensitiveRelationalExpr extends AbstractRelationalExpr { }
|
||||
|
||||
final class CaseSensitiveRelationalExpr = AbstractCaseSensitiveRelationalExpr;
|
||||
|
||||
class GeExpr extends AbstractCaseInsensitiveRelationalExpr {
|
||||
GeExpr() { this.getKind() = 62 }
|
||||
|
||||
final override string toString() { result = "... -ge ..." }
|
||||
}
|
||||
|
||||
class GtExpr extends AbstractCaseInsensitiveRelationalExpr {
|
||||
GtExpr() { this.getKind() = 63 }
|
||||
|
||||
final override string toString() { result = "... -gt ..." }
|
||||
}
|
||||
|
||||
class LtExpr extends AbstractCaseInsensitiveRelationalExpr {
|
||||
LtExpr() { this.getKind() = 64 }
|
||||
|
||||
final override string toString() { result = "... -lt ..." }
|
||||
}
|
||||
|
||||
class LeExpr extends AbstractCaseInsensitiveRelationalExpr {
|
||||
LeExpr() { this.getKind() = 65 }
|
||||
|
||||
final override string toString() { result = "... -le ..." }
|
||||
}
|
||||
|
||||
class CGeExpr extends AbstractCaseSensitiveRelationalExpr {
|
||||
CGeExpr() { this.getKind() = 78 }
|
||||
|
||||
final override string toString() { result = "... -cge ..." }
|
||||
}
|
||||
|
||||
class CGtExpr extends AbstractCaseSensitiveRelationalExpr {
|
||||
CGtExpr() { this.getKind() = 79 }
|
||||
|
||||
final override string toString() { result = "... -cgt ..." }
|
||||
}
|
||||
|
||||
class CLtExpr extends AbstractCaseSensitiveRelationalExpr {
|
||||
CLtExpr() { this.getKind() = 80 }
|
||||
|
||||
final override string toString() { result = "... -clt ..." }
|
||||
}
|
||||
|
||||
class CLeExpr extends AbstractCaseSensitiveRelationalExpr {
|
||||
CLeExpr() { this.getKind() = 81 }
|
||||
|
||||
final override string toString() { result = "... -cle ..." }
|
||||
}
|
||||
|
||||
class LikeExpr extends AbstractCaseInsensitiveComparisonExpr {
|
||||
LikeExpr() { this.getKind() = 66 }
|
||||
|
||||
final override string toString() { result = "... -like ..." }
|
||||
}
|
||||
|
||||
class NotLikeExpr extends AbstractCaseInsensitiveComparisonExpr {
|
||||
NotLikeExpr() { this.getKind() = 67 }
|
||||
|
||||
final override string toString() { result = "... -notlike ..." }
|
||||
}
|
||||
|
||||
class MatchExpr extends AbstractCaseInsensitiveComparisonExpr {
|
||||
MatchExpr() { this.getKind() = 68 }
|
||||
|
||||
final override string toString() { result = "... -match ..." }
|
||||
}
|
||||
|
||||
class NotMatchExpr extends AbstractCaseInsensitiveComparisonExpr {
|
||||
NotMatchExpr() { this.getKind() = 69 }
|
||||
|
||||
final override string toString() { result = "... -notmatch ..." }
|
||||
}
|
||||
|
||||
class ReplaceExpr extends AbstractCaseInsensitiveComparisonExpr {
|
||||
ReplaceExpr() { this.getKind() = 70 }
|
||||
|
||||
final override string toString() { result = "... -replace ..." }
|
||||
}
|
||||
|
||||
abstract class AbstractTypeExpr extends BinaryExpr { }
|
||||
|
||||
final class TypeExpr = AbstractTypeExpr;
|
||||
|
||||
abstract class AbstractTypeComparisonExpr extends AbstractTypeExpr { }
|
||||
|
||||
final class TypeComparisonExpr = AbstractTypeComparisonExpr;
|
||||
|
||||
class IsExpr extends AbstractTypeComparisonExpr {
|
||||
IsExpr() { this.getKind() = 92 }
|
||||
|
||||
final override string toString() { result = "... -is ..." }
|
||||
}
|
||||
|
||||
class IsNotExpr extends AbstractTypeComparisonExpr {
|
||||
IsNotExpr() { this.getKind() = 93 }
|
||||
|
||||
final override string toString() { result = "... -isnot ..." }
|
||||
}
|
||||
|
||||
class AsExpr extends AbstractTypeExpr {
|
||||
AsExpr() { this.getKind() = 94 }
|
||||
|
||||
final override string toString() { result = "... -as ..." }
|
||||
}
|
||||
|
||||
abstract private class AbstractContainmentExpr extends BinaryExpr { }
|
||||
|
||||
final class ContainmentExpr = AbstractContainmentExpr;
|
||||
|
||||
abstract private class AbstractCaseInsensitiveContainmentExpr extends AbstractContainmentExpr { }
|
||||
|
||||
final class CaseInsensitiveContainmentExpr = AbstractCaseInsensitiveContainmentExpr;
|
||||
|
||||
class ContainsExpr extends AbstractCaseInsensitiveContainmentExpr {
|
||||
ContainsExpr() { this.getKind() = 71 }
|
||||
|
||||
final override string toString() { result = "... -contains ..." }
|
||||
}
|
||||
|
||||
class NotContainsExpr extends AbstractCaseInsensitiveContainmentExpr {
|
||||
NotContainsExpr() { this.getKind() = 72 }
|
||||
|
||||
final override string toString() { result = "... -notcontains ..." }
|
||||
}
|
||||
|
||||
class InExpr extends AbstractCaseInsensitiveContainmentExpr {
|
||||
InExpr() { this.getKind() = 73 }
|
||||
|
||||
final override string toString() { result = "... -in ..." }
|
||||
}
|
||||
|
||||
class NotInExpr extends AbstractCaseInsensitiveContainmentExpr {
|
||||
NotInExpr() { this.getKind() = 74 }
|
||||
|
||||
final override string toString() { result = "... -notin ..." }
|
||||
}
|
||||
|
||||
abstract private class AbstractLogicalBinaryExpr extends BinaryExpr { }
|
||||
|
||||
final class LogicalBinaryExpr = AbstractLogicalBinaryExpr;
|
||||
|
||||
class LogicalAndExpr extends AbstractLogicalBinaryExpr {
|
||||
LogicalAndExpr() { this.getKind() = 53 }
|
||||
|
||||
final override string toString() { result = "... -and ..." }
|
||||
}
|
||||
|
||||
class LogicalOrExpr extends AbstractLogicalBinaryExpr {
|
||||
LogicalOrExpr() { this.getKind() = 54 }
|
||||
|
||||
final override string toString() { result = "... -or ..." }
|
||||
}
|
||||
|
||||
class LogicalXorExpr extends AbstractLogicalBinaryExpr {
|
||||
LogicalXorExpr() { this.getKind() = 55 }
|
||||
|
||||
final override string toString() { result = "... -xor ..." }
|
||||
}
|
||||
|
||||
class JoinExpr extends BinaryExpr {
|
||||
JoinExpr() { this.getKind() = 59 }
|
||||
|
||||
final override string toString() { result = "... -join ..." }
|
||||
}
|
||||
|
||||
class SequenceExpr extends BinaryExpr {
|
||||
SequenceExpr() { this.getKind() = 33 }
|
||||
|
||||
final override string toString() { result = "[..]" }
|
||||
}
|
||||
|
||||
class FormatExpr extends BinaryExpr {
|
||||
FormatExpr() { this.getKind() = 50 }
|
||||
|
||||
final override string toString() { result = "... -f ..." }
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class BreakStmt extends GotoStmt, @break_statement {
|
||||
override SourceLocation getLocation() { break_statement_location(this, result) }
|
||||
|
||||
override string toString() { result = "break" }
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
import powershell
|
||||
private import semmle.code.powershell.dataflow.internal.DataFlowImplCommon
|
||||
private import semmle.code.powershell.dataflow.internal.DataFlowDispatch
|
||||
private import semmle.code.powershell.controlflow.CfgNodes
|
||||
|
||||
abstract private class AbstractCall extends Ast {
|
||||
abstract Expr getCommand();
|
||||
|
||||
abstract string getName();
|
||||
|
||||
/** Gets the i'th argument to this call. */
|
||||
abstract Expr getArgument(int i);
|
||||
|
||||
/** Gets the i'th positional argument to this call. */
|
||||
abstract Expr getPositionalArgument(int i);
|
||||
|
||||
/** Holds if an argument with name `name` is provided to this call. */
|
||||
final predicate hasNamedArgument(string name) { exists(this.getNamedArgument(name)) }
|
||||
|
||||
/** Gets the argument to this call with the name `name`. */
|
||||
abstract Expr getNamedArgument(string name);
|
||||
|
||||
/** Gets any argument to this call. */
|
||||
final Expr getAnArgument() { result = this.getArgument(_) }
|
||||
|
||||
/** Gets the qualifier of this call, if any. */
|
||||
Expr getQualifier() { none() }
|
||||
|
||||
/** Gets a possible runtime target of this call. */
|
||||
abstract Function getATarget();
|
||||
}
|
||||
|
||||
/** A call to a command. For example, `Write-Host "Hello, world!"`. */
|
||||
class CmdCall extends AbstractCall instanceof Cmd {
|
||||
final override Expr getCommand() { result = Cmd.super.getCommand() }
|
||||
|
||||
final override Expr getPositionalArgument(int i) { result = Cmd.super.getPositionalArgument(i) }
|
||||
|
||||
final override string getName() { result = Cmd.super.getCommandName() }
|
||||
|
||||
final override Expr getArgument(int i) { result = Cmd.super.getArgument(i) }
|
||||
|
||||
final override Expr getNamedArgument(string name) { result = Cmd.super.getNamedArgument(name) }
|
||||
|
||||
final override Function getATarget() {
|
||||
exists(DataFlowCall call | call.asCall().(StmtNodes::CmdCfgNode).getStmt() = this |
|
||||
result.getBody() = viableCallableLambda(call, _).asCfgScope()
|
||||
or
|
||||
result.getBody() = getTarget(call)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** A call to a method on an object. For example, `$obj.ToString()`. */
|
||||
class MethodCall extends AbstractCall instanceof InvokeMemberExpr {
|
||||
final override Expr getCommand() { result = super.getMember() }
|
||||
|
||||
final override Expr getPositionalArgument(int i) {
|
||||
result = InvokeMemberExpr.super.getArgument(i)
|
||||
}
|
||||
|
||||
final override Expr getArgument(int i) { result = this.getPositionalArgument(i) }
|
||||
|
||||
final override Expr getQualifier() { result = InvokeMemberExpr.super.getQualifier() }
|
||||
|
||||
final override Expr getNamedArgument(string name) { none() }
|
||||
|
||||
final override Function getATarget() {
|
||||
exists(DataFlowCall call | call.asCall().(ExprNodes::InvokeMemberCfgNode).getExpr() = this |
|
||||
result.getBody() = viableCallableLambda(call, _).asCfgScope()
|
||||
or
|
||||
result.getBody() = getTarget(call)
|
||||
)
|
||||
}
|
||||
|
||||
final override string getName() { result = InvokeMemberExpr.super.getName() }
|
||||
}
|
||||
|
||||
final class Call = AbstractCall;
|
||||
@@ -1,39 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class CatchClause extends @catch_clause, Ast {
|
||||
override SourceLocation getLocation() { catch_clause_location(this, result) }
|
||||
|
||||
override string toString() { result = "catch {...}" }
|
||||
|
||||
StmtBlock getBody() { catch_clause(this, result, _) }
|
||||
|
||||
TypeConstraint getCatchType(int i) { catch_clause_catch_type(this, i, result) }
|
||||
|
||||
int getNumberOfCatchTypes() { result = count(this.getACatchType()) }
|
||||
|
||||
TypeConstraint getACatchType() { result = this.getCatchType(_) }
|
||||
|
||||
predicate isCatchAll() { not exists(this.getACatchType()) }
|
||||
|
||||
TryStmt getTryStmt() { result.getACatchClause() = this }
|
||||
|
||||
predicate isLast() {
|
||||
exists(TryStmt ts, int last |
|
||||
ts = this.getTryStmt() and
|
||||
last = max(int i | exists(ts.getCatchClause(i))) and
|
||||
this = ts.getCatchClause(last)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class GeneralCatchClause extends CatchClause {
|
||||
GeneralCatchClause() { this.isCatchAll() }
|
||||
|
||||
override string toString() { result = "catch {...}" }
|
||||
}
|
||||
|
||||
class SpecificCatchClause extends CatchClause {
|
||||
SpecificCatchClause() { not this.isCatchAll() }
|
||||
|
||||
override string toString() { result = "catch[...] {...}" }
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class Chainable extends @chainable, PipelineBase { }
|
||||
@@ -1,114 +0,0 @@
|
||||
import powershell
|
||||
|
||||
private predicate parseCommandName(Cmd cmd, string namespace, string name) {
|
||||
exists(string qualified | command(cmd, qualified, _, _, _) |
|
||||
namespace = qualified.regexpCapture("([^\\\\]+)\\\\([^\\\\]+)", 1) and
|
||||
name = qualified.regexpCapture("([^\\\\]+)\\\\([^\\\\]+)", 2)
|
||||
or
|
||||
// Not a qualified name
|
||||
not exists(qualified.indexOf("\\")) and
|
||||
namespace = "" and
|
||||
name = qualified
|
||||
)
|
||||
}
|
||||
|
||||
/** A call to a command. */
|
||||
class Cmd extends @command, CmdBase {
|
||||
override string toString() {
|
||||
exists(string name | name = this.getQualifiedCommandName() |
|
||||
if name = "" then result = "call" else result = "call to " + name
|
||||
)
|
||||
or
|
||||
not exists(this.getQualifiedCommandName()) and
|
||||
result = "call"
|
||||
}
|
||||
|
||||
override SourceLocation getLocation() { command_location(this, result) }
|
||||
|
||||
/** Gets the name of the command without any qualifiers. */
|
||||
string getCommandName() { parseCommandName(this, _, result) }
|
||||
|
||||
/** Holds if the command is qualified. */
|
||||
predicate isQualified() { parseCommandName(this, any(string s | s != ""), _) }
|
||||
|
||||
/** Gets the namespace qualifier of this command, if any. */
|
||||
string getNamespaceQualifier() {
|
||||
result != "" and
|
||||
parseCommandName(this, result, _)
|
||||
or
|
||||
// Implicit import because it's in a module manifest
|
||||
parseCommandName(this, "", _) and
|
||||
exists(ModuleManifest manifest |
|
||||
manifest.getACmdLetToExport() = this.getCommandName() and
|
||||
result = manifest.getModuleName()
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the (possibly qualified) name of this command. */
|
||||
string getQualifiedCommandName() { command(this, result, _, _, _) }
|
||||
|
||||
int getKind() { command(this, _, result, _, _) }
|
||||
|
||||
int getNumElements() { command(this, _, _, result, _) }
|
||||
|
||||
int getNumRedirection() { command(this, _, _, _, result) }
|
||||
|
||||
CmdElement getElement(int i) { command_command_element(this, i, result) }
|
||||
|
||||
/** Gets the expression that determines the command to invoke. */
|
||||
Expr getCommand() { result = this.getElement(0) }
|
||||
|
||||
/** Gets the name of this command, if this is statically known. */
|
||||
StringConstExpr getCmdName() { result = this.getElement(0) }
|
||||
|
||||
/** Gets any argument to this command. */
|
||||
Expr getAnArgument() { result = this.getArgument(_) }
|
||||
|
||||
/**
|
||||
* Gets the `i`th argument to this command.
|
||||
*
|
||||
* The argument may be named or positional.
|
||||
*/
|
||||
Expr getArgument(int i) {
|
||||
result =
|
||||
rank[i + 1](CmdElement e, int j |
|
||||
e = this.getElement(j) and
|
||||
not e instanceof CmdParameter and
|
||||
j > 0 // 0'th element is the command name itself
|
||||
|
|
||||
e order by j
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the `i`th positional argument to this command. */
|
||||
Expr getPositionalArgument(int i) {
|
||||
result =
|
||||
rank[i + 1](Argument e, int j |
|
||||
e = this.getArgument(j) and
|
||||
e instanceof PositionalArgument
|
||||
|
|
||||
e order by j
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if this call has an argument named `name`. */
|
||||
predicate hasNamedArgument(string name) { exists(this.getNamedArgument(name)) }
|
||||
|
||||
/** Gets the named argument with the given name. */
|
||||
Expr getNamedArgument(string name) {
|
||||
exists(int i, CmdParameter p |
|
||||
this.getElement(i) = p and
|
||||
p.getName() = name and
|
||||
result = p.getArgument()
|
||||
)
|
||||
}
|
||||
|
||||
Redirection getRedirection(int i) { command_redirection(this, i, result) }
|
||||
|
||||
Redirection getARedirection() { result = this.getRedirection(_) }
|
||||
}
|
||||
|
||||
/** A call to operator `&`. */
|
||||
class CallOperator extends Cmd {
|
||||
CallOperator() { this.getKind() = 28 }
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class CmdBase extends @command_base, Chainable { }
|
||||
@@ -1,3 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class CmdElement extends @command_element, Ast { }
|
||||
@@ -1,15 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class CmdExpr extends @command_expression, CmdBase {
|
||||
override SourceLocation getLocation() { command_expression_location(this, result) }
|
||||
|
||||
Expr getExpr() { command_expression(this, result, _) }
|
||||
|
||||
int getNumRedirections() { command_expression(this, _, result) }
|
||||
|
||||
Redirection getRedirection(int i) { command_expression_redirection(this, i, result) }
|
||||
|
||||
Redirection getARedirection() { result = this.getRedirection(_) }
|
||||
|
||||
override string toString() { result = this.getExpr().toString() }
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class CmdParameter extends @command_parameter, CmdElement {
|
||||
override SourceLocation getLocation() { command_parameter_location(this, result) }
|
||||
|
||||
string getName() { command_parameter(this, result) }
|
||||
|
||||
Expr getArgument() {
|
||||
// When an argumnt is of the form -Name:$var
|
||||
command_parameter_argument(this, result)
|
||||
or
|
||||
// When an argument is of the form -Name $var
|
||||
exists(int i, Cmd cmd |
|
||||
cmd = this.getCmd() and
|
||||
cmd.getElement(i) = this and
|
||||
result = cmd.getElement(i + 1)
|
||||
)
|
||||
}
|
||||
|
||||
Cmd getCmd() { result.getElement(_) = this }
|
||||
|
||||
override string toString() { command_parameter(this, result) }
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class Comment extends @comment_entity {
|
||||
Location getLocation() { comment_entity_location(this, result) }
|
||||
|
||||
StringLiteral getCommentContents() { comment_entity(this, result) }
|
||||
|
||||
string toString() { result = this.getCommentContents().toString() }
|
||||
}
|
||||
|
||||
class SingleLineComment extends Comment {
|
||||
SingleLineComment() { this.getCommentContents().getNumContinuations() = 1 }
|
||||
}
|
||||
|
||||
class MultiLineComment extends Comment {
|
||||
MultiLineComment() { this.getCommentContents().getNumContinuations() > 1 }
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class Configuration extends @configuration_definition, Stmt {
|
||||
override SourceLocation getLocation() { configuration_definition_location(this, result) }
|
||||
|
||||
override string toString() { result = "Configuration" }
|
||||
|
||||
Expr getName() { configuration_definition(this, _, _, result) }
|
||||
|
||||
ScriptBlockExpr getBody() { configuration_definition(this, result, _, _) }
|
||||
|
||||
predicate isMeta() { configuration_definition(this, _, 1, _) }
|
||||
|
||||
predicate isResource() { configuration_definition(this, _, 0, _) }
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class ConstExpr extends @constant_expression, BaseConstExpr {
|
||||
override SourceLocation getLocation() { constant_expression_location(this, result) }
|
||||
|
||||
override string getType() { constant_expression(this, result) }
|
||||
|
||||
override StringLiteral getValue() { constant_expression_value(this, result) }
|
||||
}
|
||||
|
||||
private newtype TConstantValue =
|
||||
TConstInteger(int value) {
|
||||
exists(ConstExpr ce | ce.getType() = "Int32" and ce.getValue().getValue().toInt() = value)
|
||||
or
|
||||
value = [0 .. 10] // needed for `trackKnownValue` in `DataFlowPrivate`
|
||||
} or
|
||||
TConstDouble(float double) {
|
||||
exists(ConstExpr ce | ce.getType() = "Double" and ce.getValue().getValue().toFloat() = double)
|
||||
} or
|
||||
TConstString(string value) { exists(StringLiteral sl | sl.getValue() = value) } or
|
||||
TConstBoolean(boolean value) {
|
||||
exists(VarAccess va |
|
||||
value = true and
|
||||
va.getUserPath() = "true"
|
||||
or
|
||||
value = false and
|
||||
va.getUserPath() = "false"
|
||||
)
|
||||
} or
|
||||
TNull()
|
||||
|
||||
/** A constant value. */
|
||||
class ConstantValue extends TConstantValue {
|
||||
/** Gets a string representation of this value. */
|
||||
final string toString() { result = this.getValue() }
|
||||
|
||||
/** Gets the value of this consant. */
|
||||
string getValue() { none() }
|
||||
|
||||
/** Gets the integer value of this constant, if any. */
|
||||
int asInt() { none() }
|
||||
|
||||
/** Gets the floating point value of this constant, if any. */
|
||||
float asDouble() { none() }
|
||||
|
||||
/** Gets the string value of this constant, if any. */
|
||||
string asString() { none() }
|
||||
|
||||
/** Gets the boolean value of this constant, if any. */
|
||||
boolean asBoolean() { none() }
|
||||
|
||||
/** Holds if this constant represents the null value. */
|
||||
predicate isNull() { none() }
|
||||
|
||||
/** Gets a (unique) serialized version of this value. */
|
||||
string serialize() { none() }
|
||||
|
||||
/** Gets an exprssion that has this value. */
|
||||
Expr getAnExpr() { none() }
|
||||
}
|
||||
|
||||
/** A constant integer value */
|
||||
class ConstInteger extends ConstantValue, TConstInteger {
|
||||
final override int asInt() { this = TConstInteger(result) }
|
||||
|
||||
final override string getValue() { result = this.asInt().toString() }
|
||||
|
||||
final override string serialize() { result = this.getValue() }
|
||||
|
||||
final override ConstExpr getAnExpr() { result.getValue().getValue() = this.getValue() }
|
||||
}
|
||||
|
||||
/** A constant floating point value. */
|
||||
class ConstDouble extends ConstantValue, TConstDouble {
|
||||
final override float asDouble() { this = TConstDouble(result) }
|
||||
|
||||
final override string getValue() { result = this.asDouble().toString() }
|
||||
|
||||
final override string serialize() {
|
||||
exists(string res | res = this.asDouble().toString() |
|
||||
if exists(res.indexOf(".")) then result = res else result = res + ".0"
|
||||
)
|
||||
}
|
||||
|
||||
final override ConstExpr getAnExpr() { result.getValue().getValue() = this.getValue() }
|
||||
}
|
||||
|
||||
/** A constant string value. */
|
||||
class ConstString extends ConstantValue, TConstString {
|
||||
final override string asString() { this = TConstString(result) }
|
||||
|
||||
final override string getValue() { result = this.asString() }
|
||||
|
||||
final override string serialize() {
|
||||
result = "\"" + this.asString().replaceAll("\"", "\\\"") + "\""
|
||||
}
|
||||
|
||||
final override BaseConstExpr getAnExpr() { result.getValue().getValue() = this.getValue() }
|
||||
}
|
||||
|
||||
/** A constant boolean value. */
|
||||
class ConstBoolean extends ConstantValue, TConstBoolean {
|
||||
final override boolean asBoolean() { this = TConstBoolean(result) }
|
||||
|
||||
final override string getValue() { result = this.asBoolean().toString() }
|
||||
|
||||
final override string serialize() { result = this.getValue() }
|
||||
|
||||
final override VarAccess getAnExpr() {
|
||||
this.asBoolean() = true and
|
||||
result.getUserPath() = "true"
|
||||
or
|
||||
this.asBoolean() = false and
|
||||
result.getUserPath() = "false"
|
||||
}
|
||||
}
|
||||
|
||||
/** The constant null value. */
|
||||
class NullConst extends ConstantValue, TNull {
|
||||
final override predicate isNull() { any() }
|
||||
|
||||
final override string getValue() { result = "null" }
|
||||
|
||||
final override string serialize() { result = this.getValue() }
|
||||
|
||||
final override VarAccess getAnExpr() { result.getUserPath() = "null" }
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class ContinueStmt extends GotoStmt, @continue_statement {
|
||||
override SourceLocation getLocation() { continue_statement_location(this, result) }
|
||||
|
||||
override string toString() { result = "continue" }
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class ConvertExpr extends @convert_expression, Expr {
|
||||
override string toString() { result = "[...]..." }
|
||||
|
||||
override SourceLocation getLocation() { convert_expression_location(this, result) }
|
||||
|
||||
Expr getBase() { convert_expression(this, _, result, _, _) }
|
||||
|
||||
TypeConstraint getType() { convert_expression(this, _, _, result, _) }
|
||||
|
||||
AttributeBase getAttribute() { convert_expression(this, result, _, _, _) }
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class DataStmt extends @data_statement, Stmt {
|
||||
override SourceLocation getLocation() { data_statement_location(this, result) }
|
||||
|
||||
override string toString() { result = "data {...}" }
|
||||
|
||||
string getVariableName() { data_statement_variable(this, result) }
|
||||
|
||||
Expr getCmdAllowed(int i) { data_statement_commands_allowed(this, i, result) }
|
||||
|
||||
Expr getACmdAllowed() { result = this.getCmdAllowed(_) }
|
||||
|
||||
StmtBlock getBody() { data_statement(this, result) }
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class DoUntilStmt extends @do_until_statement, LoopStmt {
|
||||
override SourceLocation getLocation() { do_until_statement_location(this, result) }
|
||||
|
||||
override string toString() { result = "DoUntil" }
|
||||
|
||||
PipelineBase getCondition() { do_until_statement_condition(this, result) }
|
||||
|
||||
final override StmtBlock getBody() { do_until_statement(this, result) }
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class DoWhileStmt extends @do_while_statement, LoopStmt {
|
||||
override SourceLocation getLocation() { do_while_statement_location(this, result) }
|
||||
|
||||
override string toString() { result = "DoWhile" }
|
||||
|
||||
PipelineBase getCondition() { do_while_statement_condition(this, result) }
|
||||
|
||||
final override StmtBlock getBody() { do_while_statement(this, result) }
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class DynamicStmt extends @dynamic_keyword_statement, Stmt {
|
||||
override SourceLocation getLocation() { dynamic_keyword_statement_location(this, result) }
|
||||
|
||||
override string toString() { result = "&..." }
|
||||
|
||||
CmdElement getCmd(int i) { dynamic_keyword_statement_command_elements(this, i, result) }
|
||||
|
||||
CmdElement getACmd() { result = this.getCmd(_) }
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class ErrorExpr extends @error_expression, Expr {
|
||||
final override SourceLocation getLocation() { error_expression_location(this, result) }
|
||||
|
||||
final override string toString() { result = "error" }
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class ErrorStmt extends @error_statement, PipelineBase {
|
||||
final override SourceLocation getLocation() { error_statement_location(this, result) }
|
||||
|
||||
final override string toString() { result = "error" }
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class ExitStmt extends @exit_statement, Stmt {
|
||||
override SourceLocation getLocation() { exit_statement_location(this, result) }
|
||||
|
||||
override string toString() { if this.hasPipeline() then result = "exit ..." else result = "exit" }
|
||||
|
||||
/** ..., if any. */
|
||||
PipelineBase getPipeline() { exit_statement_pipeline(this, result) }
|
||||
|
||||
predicate hasPipeline() { exists(this.getPipeline()) }
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class ExpandableStringExpr extends @expandable_string_expression, Expr {
|
||||
override SourceLocation getLocation() { expandable_string_expression_location(this, result) }
|
||||
|
||||
override string toString() { result = this.getUnexpandedValue().toString() }
|
||||
|
||||
StringLiteral getUnexpandedValue() { expandable_string_expression(this, result, _, _) }
|
||||
|
||||
int getNumExprs() { result = count(this.getAnExpr()) }
|
||||
|
||||
Expr getExpr(int i) { expandable_string_expression_nested_expression(this, i, result) }
|
||||
|
||||
Expr getAnExpr() { result = this.getExpr(_) }
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import powershell
|
||||
|
||||
/**
|
||||
* An expression.
|
||||
*
|
||||
* This is the topmost class in the hierachy of all expression in PowerShell.
|
||||
*/
|
||||
class Expr extends @expression, CmdElement {
|
||||
/** Gets the constant value of this expression, if this is known. */
|
||||
final ConstantValue getValue() { result.getAnExpr() = this }
|
||||
}
|
||||
@@ -1,224 +0,0 @@
|
||||
/**
|
||||
* Provides classes representing filesystem files and folders.
|
||||
* Based on csharp/ql/lib/semmle/code/csharp/File.qll
|
||||
*/
|
||||
|
||||
/** A file or folder. */
|
||||
class Container extends @container {
|
||||
/**
|
||||
* Gets the absolute, canonical path of this container, using forward slashes
|
||||
* as path separator.
|
||||
*
|
||||
* The path starts with a _root prefix_ followed by zero or more _path
|
||||
* segments_ separated by forward slashes.
|
||||
*
|
||||
* The root prefix is of one of the following forms:
|
||||
*
|
||||
* 1. A single forward slash `/` (Unix-style)
|
||||
* 2. An upper-case drive letter followed by a colon and a forward slash,
|
||||
* such as `C:/` (Windows-style)
|
||||
* 3. Two forward slashes, a computer name, and then another forward slash,
|
||||
* such as `//FileServer/` (UNC-style)
|
||||
*
|
||||
* Path segments are never empty (that is, absolute paths never contain two
|
||||
* contiguous slashes, except as part of a UNC-style root prefix). Also, path
|
||||
* segments never contain forward slashes, and no path segment is of the
|
||||
* form `.` (one dot) or `..` (two dots).
|
||||
*
|
||||
* Note that an absolute path never ends with a forward slash, except if it is
|
||||
* a bare root prefix, that is, the path has no path segments. A container
|
||||
* whose absolute path has no segments is always a `Folder`, not a `File`.
|
||||
*/
|
||||
string getAbsolutePath() { none() }
|
||||
|
||||
/**
|
||||
* Gets a URL representing the location of this container.
|
||||
*
|
||||
* For more information see [Providing URLs](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/#providing-urls).
|
||||
*/
|
||||
string getURL() { none() }
|
||||
|
||||
/**
|
||||
* Gets the relative path of this file or folder from the root folder of the
|
||||
* analyzed source location. The relative path of the root folder itself is
|
||||
* the empty string.
|
||||
*
|
||||
* This has no result if the container is outside the source root, that is,
|
||||
* if the root folder is not a reflexive, transitive parent of this container.
|
||||
*/
|
||||
string getRelativePath() {
|
||||
exists(string absPath, string pref |
|
||||
absPath = this.getAbsolutePath() and sourceLocationPrefix(pref)
|
||||
|
|
||||
absPath = pref and result = ""
|
||||
or
|
||||
absPath = pref.regexpReplaceAll("/$", "") + "/" + result and
|
||||
not result.matches("/%")
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the base name of this container including extension, that is, the last
|
||||
* segment of its absolute path, or the empty string if it has no segments.
|
||||
*
|
||||
* Here are some examples of absolute paths and the corresponding base names
|
||||
* (surrounded with quotes to avoid ambiguity):
|
||||
*
|
||||
* <table border="1">
|
||||
* <tr><th>Absolute path</th><th>Base name</th></tr>
|
||||
* <tr><td>"/tmp/tst.sql"</td><td>"tst.sql"</td></tr>
|
||||
* <tr><td>"C:/Program Files (x86)"</td><td>"Program Files (x86)"</td></tr>
|
||||
* <tr><td>"/"</td><td>""</td></tr>
|
||||
* <tr><td>"C:/"</td><td>""</td></tr>
|
||||
* <tr><td>"D:/"</td><td>""</td></tr>
|
||||
* <tr><td>"//FileServer/"</td><td>""</td></tr>
|
||||
* </table>
|
||||
*/
|
||||
string getBaseName() {
|
||||
result = this.getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the extension of this container, that is, the suffix of its base name
|
||||
* after the last dot character, if any.
|
||||
*
|
||||
* In particular,
|
||||
*
|
||||
* - if the name does not include a dot, there is no extension, so this
|
||||
* predicate has no result;
|
||||
* - if the name ends in a dot, the extension is the empty string;
|
||||
* - if the name contains multiple dots, the extension follows the last dot.
|
||||
*
|
||||
* Here are some examples of absolute paths and the corresponding extensions
|
||||
* (surrounded with quotes to avoid ambiguity):
|
||||
*
|
||||
* <table border="1">
|
||||
* <tr><th>Absolute path</th><th>Extension</th></tr>
|
||||
* <tr><td>"/tmp/tst.cs"</td><td>"cs"</td></tr>
|
||||
* <tr><td>"/tmp/.classpath"</td><td>"classpath"</td></tr>
|
||||
* <tr><td>"/bin/bash"</td><td>not defined</td></tr>
|
||||
* <tr><td>"/tmp/tst2."</td><td>""</td></tr>
|
||||
* <tr><td>"/tmp/x.tar.gz"</td><td>"gz"</td></tr>
|
||||
* </table>
|
||||
*/
|
||||
string getExtension() {
|
||||
result = this.getAbsolutePath().regexpCapture(".*/([^/]*?)(\\.([^.]*))?", 3)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the stem of this container, that is, the prefix of its base name up to
|
||||
* (but not including) the last dot character if there is one, or the entire
|
||||
* base name if there is not.
|
||||
*
|
||||
* Here are some examples of absolute paths and the corresponding stems
|
||||
* (surrounded with quotes to avoid ambiguity):
|
||||
*
|
||||
* <table border="1">
|
||||
* <tr><th>Absolute path</th><th>Stem</th></tr>
|
||||
* <tr><td>"/tmp/tst.cs"</td><td>"tst"</td></tr>
|
||||
* <tr><td>"/tmp/.classpath"</td><td>""</td></tr>
|
||||
* <tr><td>"/bin/bash"</td><td>"bash"</td></tr>
|
||||
* <tr><td>"/tmp/tst2."</td><td>"tst2"</td></tr>
|
||||
* <tr><td>"/tmp/x.tar.gz"</td><td>"x.tar"</td></tr>
|
||||
* </table>
|
||||
*/
|
||||
string getStem() {
|
||||
result = this.getAbsolutePath().regexpCapture(".*/([^/]*?)(?:\\.([^.]*))?", 1)
|
||||
}
|
||||
|
||||
/** Gets the parent container of this file or folder, if any. */
|
||||
Container getParentContainer() { containerparent(result, this) }
|
||||
|
||||
/** Gets a file or sub-folder in this container. */
|
||||
Container getAChildContainer() { this = result.getParentContainer() }
|
||||
|
||||
/** Gets a file in this container. */
|
||||
File getAFile() { result = this.getAChildContainer() }
|
||||
|
||||
/** Gets the file in this container that has the given `baseName`, if any. */
|
||||
File getFile(string baseName) {
|
||||
result = this.getAFile() and
|
||||
result.getBaseName() = baseName
|
||||
}
|
||||
|
||||
/** Gets a sub-folder in this container. */
|
||||
Folder getAFolder() { result = this.getAChildContainer() }
|
||||
|
||||
/** Gets the sub-folder in this container that has the given `baseName`, if any. */
|
||||
Folder getFolder(string baseName) {
|
||||
result = this.getAFolder() and
|
||||
result.getBaseName() = baseName
|
||||
}
|
||||
|
||||
/** Gets the file or sub-folder in this container that has the given `name`, if any. */
|
||||
Container getChildContainer(string name) {
|
||||
result = this.getAChildContainer() and
|
||||
result.getBaseName() = name
|
||||
}
|
||||
|
||||
/** Gets the file in this container that has the given `stem` and `extension`, if any. */
|
||||
File getFile(string stem, string extension) {
|
||||
result = this.getAChildContainer() and
|
||||
result.getStem() = stem and
|
||||
result.getExtension() = extension
|
||||
}
|
||||
|
||||
/** Gets a sub-folder contained in this container. */
|
||||
Folder getASubFolder() { result = this.getAChildContainer() }
|
||||
|
||||
/**
|
||||
* Gets a textual representation of the path of this container.
|
||||
*
|
||||
* This is the absolute path of the container.
|
||||
*/
|
||||
string toString() { result = this.getAbsolutePath() }
|
||||
}
|
||||
|
||||
/** A folder. */
|
||||
class Folder extends Container, @folder {
|
||||
override string getAbsolutePath() { folders(this, result) }
|
||||
|
||||
override string getURL() { result = "folder://" + this.getAbsolutePath() }
|
||||
}
|
||||
|
||||
/** A file. */
|
||||
class File extends Container, @file {
|
||||
override string getAbsolutePath() { files(this, result) }
|
||||
|
||||
/** Gets the number of lines in this file. */
|
||||
int getNumberOfLines() { numlines(this, result, _, _) }
|
||||
|
||||
/** Gets the number of lines containing code in this file. */
|
||||
int getNumberOfLinesOfCode() { numlines(this, _, result, _) }
|
||||
|
||||
/** Gets the number of lines containing comments in this file. */
|
||||
int getNumberOfLinesOfComments() { numlines(this, _, _, result) }
|
||||
|
||||
override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" }
|
||||
|
||||
/** Holds if this file is a QL test stub file. */
|
||||
pragma[noinline]
|
||||
private predicate isStub() {
|
||||
// this.extractedQlTest() and
|
||||
this.getAbsolutePath().matches("%resources/stubs/%")
|
||||
}
|
||||
|
||||
/** Holds if this file contains source code. */
|
||||
predicate fromSource() {
|
||||
this.getExtension() = "cs" and
|
||||
not this.isStub()
|
||||
}
|
||||
|
||||
/** Holds if this file is a library. */
|
||||
predicate fromLibrary() {
|
||||
not this.getBaseName() = "" and
|
||||
not this.fromSource()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A source file.
|
||||
*/
|
||||
class SourceFile extends File {
|
||||
SourceFile() { this.fromSource() }
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class FileRedirection extends @file_redirection, Redirection {
|
||||
override string toString() { result = "FileRedirection" }
|
||||
|
||||
override Location getLocation() { file_redirection_location(this, result) }
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class ForEachStmt extends @foreach_statement, LoopStmt {
|
||||
override SourceLocation getLocation() { foreach_statement_location(this, result) }
|
||||
|
||||
override string toString() { result = "forach(... in ...)" }
|
||||
|
||||
final override StmtBlock getBody() { foreach_statement(this, _, _, result, _) }
|
||||
|
||||
VarAccess getVarAccess() { foreach_statement(this, result, _, _, _) }
|
||||
|
||||
Variable getVariable() {
|
||||
exists(VarAccess va |
|
||||
va = this.getVarAccess() and
|
||||
foreach_statement(this, va, _, _, _) and
|
||||
result = va.getVariable()
|
||||
)
|
||||
}
|
||||
|
||||
PipelineBase getIterableExpr() { foreach_statement(this, _, result, _, _) }
|
||||
|
||||
predicate isParallel() { foreach_statement(this, _, _, _, 1) }
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class ForStmt extends @for_statement, LoopStmt {
|
||||
override SourceLocation getLocation() { for_statement_location(this, result) }
|
||||
|
||||
override string toString() { result = "for(...;...;...)" }
|
||||
|
||||
PipelineBase getInitializer() { for_statement_initializer(this, result) }
|
||||
|
||||
PipelineBase getCondition() { for_statement_condition(this, result) }
|
||||
|
||||
PipelineBase getIterator() { for_statement_iterator(this, result) }
|
||||
|
||||
final override StmtBlock getBody() { for_statement(this, result) }
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
import powershell
|
||||
import semmle.code.powershell.controlflow.BasicBlocks
|
||||
|
||||
abstract private class AbstractFunction extends Ast {
|
||||
/** Gets the name of this function. */
|
||||
abstract string getName();
|
||||
|
||||
/** Holds if this function has name `name`. */
|
||||
final predicate hasName(string name) { this.getName() = name }
|
||||
|
||||
/** Gets the body of this function. */
|
||||
abstract ScriptBlock getBody();
|
||||
|
||||
/**
|
||||
* Gets the i'th function parameter, if any.
|
||||
*
|
||||
* Note that this predicate only returns _function_ parameters.
|
||||
* To also get _block_ parameters use the `getParameter` predicate.
|
||||
*/
|
||||
abstract Parameter getFunctionParameter(int i);
|
||||
|
||||
/** Gets the declaring type of this function, if any. */
|
||||
abstract Type getDeclaringType();
|
||||
|
||||
/**
|
||||
* Gets any function parameter of this function.
|
||||
*
|
||||
* Note that this only gets _function_ paramters. To get any parameter
|
||||
* use the `getAParameter` predicate.
|
||||
*/
|
||||
final Parameter getAFunctionParameter() { result = this.getFunctionParameter(_) }
|
||||
|
||||
/** Gets the number of function parameters. */
|
||||
final int getNumberOfFunctionParameters() { result = count(this.getAFunctionParameter()) }
|
||||
|
||||
/**
|
||||
* Gets the number of parameters (both function and block).
|
||||
* Note: This excludes the `this` parameter.
|
||||
*/
|
||||
final int getNumberOfParameters() { result = count(this.getAParameter()) }
|
||||
|
||||
/**
|
||||
* Gets the i'th parameter of this function, if any.
|
||||
*
|
||||
* This does not include the `this` parameter.
|
||||
*
|
||||
* The implicit underscore parameter (if any) is included at index `-1`.
|
||||
*/
|
||||
final Parameter getParameter(int i) {
|
||||
result.getFunction() = this and
|
||||
result.getIndex() = i
|
||||
}
|
||||
|
||||
final Parameter getParameterExcludingPiplines(int i) {
|
||||
result = this.getFunctionParameter(i)
|
||||
or
|
||||
result = this.getBody().getParamBlock().getParameterExcludingPiplines(i)
|
||||
}
|
||||
|
||||
final Parameter getThisParameter() {
|
||||
result.isThis() and
|
||||
result.getFunction() = this
|
||||
}
|
||||
|
||||
/** Gets any parameter of this function. */
|
||||
final Parameter getAParameter() { result = this.getParameter(_) }
|
||||
|
||||
/** Gets the entry point of this function in the control-flow graph. */
|
||||
EntryBasicBlock getEntryBasicBlock() { result.getScope() = this.getBody() }
|
||||
}
|
||||
|
||||
final class Function = AbstractFunction;
|
||||
|
||||
/**
|
||||
* A function definition.
|
||||
*/
|
||||
private class FunctionBase extends @function_definition, Stmt, AbstractFunction {
|
||||
override string toString() { result = this.getName() }
|
||||
|
||||
override SourceLocation getLocation() { function_definition_location(this, result) }
|
||||
|
||||
override string getName() { function_definition(this, _, result, _, _) }
|
||||
|
||||
override ScriptBlock getBody() { function_definition(this, result, _, _, _) }
|
||||
|
||||
predicate isFilter() { function_definition(this, _, _, true, _) }
|
||||
|
||||
predicate isWorkflow() { function_definition(this, _, _, _, true) }
|
||||
|
||||
override Parameter getFunctionParameter(int i) { result.isFunctionParameter(this, i) }
|
||||
|
||||
override Type getDeclaringType() { none() }
|
||||
}
|
||||
|
||||
private predicate isMethod(Member m, ScriptBlock body) {
|
||||
function_member(m, body, _, _, _, _, _, _, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* A method definition. That is, a function defined inside a class definition.
|
||||
*/
|
||||
class Method extends FunctionBase {
|
||||
Method() { isMethod(_, super.getBody()) }
|
||||
|
||||
/** Gets the member corresponding to this function definition. */
|
||||
Member getMember() { isMethod(result, super.getBody()) }
|
||||
|
||||
/** Holds if this method is a constructor. */
|
||||
predicate isConstructor() { function_member(this.getMember(), _, true, _, _, _, _, _, _) }
|
||||
|
||||
final override Type getDeclaringType() { result = this.getMember().getDeclaringType() }
|
||||
}
|
||||
|
||||
/** A constructor definition. */
|
||||
class Constructor extends Method {
|
||||
Constructor() { this.isConstructor() }
|
||||
}
|
||||
|
||||
class TopLevel extends AbstractFunction instanceof TopLevelScriptBlock {
|
||||
final override string getName() { result = "toplevel" }
|
||||
|
||||
final override ScriptBlock getBody() { result = this }
|
||||
|
||||
final override Parameter getFunctionParameter(int i) { none() }
|
||||
|
||||
final override Type getDeclaringType() { none() }
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
import powershell
|
||||
|
||||
/** A `break` or `continue` statement. */
|
||||
class GotoStmt extends @labelled_statement, Stmt {
|
||||
|
||||
/** ..., if any. */
|
||||
Expr getLabel() { statement_label(this, result) }
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class HashTableExpr extends @hash_table, Expr {
|
||||
final override Location getLocation() { hash_table_location(this, result) }
|
||||
|
||||
final override string toString() { result = "${...}" }
|
||||
|
||||
Stmt getElement(Expr key) { hash_table_key_value_pairs(this, _, key, result) } // TODO: Change @ast to @expr in db scheme
|
||||
|
||||
Stmt getElementFromConstant(string key) {
|
||||
result = this.getElement(any(StringConstExpr sc | sc.getValue().getValue() = key))
|
||||
}
|
||||
|
||||
predicate hasKey(Expr key) { exists(this.getElement(key)) }
|
||||
|
||||
Stmt getAnElement() { result = this.getElement(_) }
|
||||
|
||||
predicate hasEntry(int index, Expr key, Stmt value) {
|
||||
hash_table_key_value_pairs(this, index, key, value)
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class IfStmt extends @if_statement, Stmt {
|
||||
override SourceLocation getLocation() { if_statement_location(this, result) }
|
||||
|
||||
override string toString() {
|
||||
if this.hasElse() then result = "if (...) {...} else {...}" else result = "if (...) {...}"
|
||||
}
|
||||
|
||||
PipelineBase getCondition(int i) { if_statement_clause(this, i, result, _) }
|
||||
|
||||
PipelineBase getACondition() { result = this.getCondition(_) }
|
||||
|
||||
StmtBlock getThen(int i) { if_statement_clause(this, i, _, result) }
|
||||
|
||||
int getNumberOfConditions() { result = count(this.getACondition()) }
|
||||
|
||||
StmtBlock getAThen() { result = this.getThen(_) }
|
||||
|
||||
/** ..., if any. */
|
||||
StmtBlock getElse() { if_statement_else(this, result) }
|
||||
|
||||
predicate hasElse() { exists(this.getElse()) }
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
import powershell
|
||||
private import internal.ExplicitWrite::Private
|
||||
|
||||
class IndexExpr extends @index_expression, Expr {
|
||||
override string toString() { result = "...[...]" }
|
||||
|
||||
override SourceLocation getLocation() { index_expression_location(this, result) }
|
||||
|
||||
Expr getIndex() { index_expression(this, result, _, _) } // TODO: Change @ast to @expr in the dbscheme
|
||||
|
||||
Expr getBase() { index_expression(this, _, result, _) } // TODO: Change @ast to @expr in the dbscheme
|
||||
|
||||
predicate isNullConditional() { index_expression(this, _, _, true) }
|
||||
}
|
||||
|
||||
private predicate isImplicitIndexWrite(Expr e) { none() }
|
||||
|
||||
/** An index expression that is being written to. */
|
||||
class IndexExprWrite extends IndexExpr {
|
||||
IndexExprWrite() { isExplicitWrite(this, _) or isImplicitIndexWrite(this) }
|
||||
|
||||
predicate isExplicit(AssignStmt assign) { isExplicitWrite(this, assign) }
|
||||
|
||||
predicate isImplicit() { isImplicitIndexWrite(this) }
|
||||
}
|
||||
|
||||
/** An index expression that is being read from. */
|
||||
class IndexExprRead extends IndexExpr {
|
||||
IndexExprRead() { not this instanceof IndexExprWrite }
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class InvokeMemberExpr extends @invoke_member_expression, MemberExprBase {
|
||||
override SourceLocation getLocation() { invoke_member_expression_location(this, result) }
|
||||
|
||||
Expr getQualifier() { invoke_member_expression(this, result, _) }
|
||||
|
||||
string getName() { result = this.getMember().(StringConstExpr).getValue().getValue() }
|
||||
|
||||
CmdElement getMember() { invoke_member_expression(this, _, result) }
|
||||
|
||||
string getMemberName() { result = this.getMember().(StringConstExpr).getValue().getValue() }
|
||||
|
||||
Expr getArgument(int i) { invoke_member_expression_argument(this, i, result) }
|
||||
|
||||
Expr getAnArgument() { invoke_member_expression_argument(this, _, result) }
|
||||
|
||||
override string toString() { result = "call to " + this.getName() }
|
||||
|
||||
override predicate isStatic() { this.getQualifier() instanceof TypeNameExpr }
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to a constructor. For example:
|
||||
*
|
||||
* ```powershell
|
||||
* [System.IO.FileInfo]::new("C:\\file.txt")
|
||||
* ```
|
||||
*/
|
||||
class ConstructorCall extends InvokeMemberExpr {
|
||||
TypeNameExpr typename;
|
||||
|
||||
ConstructorCall() {
|
||||
this.isStatic() and typename = this.getQualifier() and this.getName() = "new"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type being constructed by this constructor call.
|
||||
*
|
||||
* Note that the type may not exist in the database.
|
||||
*
|
||||
* Use `getConstructedTypeName` to get the name of the type (which will
|
||||
* always exist in the database).
|
||||
*/
|
||||
Type getConstructedType() { result = typename.getType() }
|
||||
|
||||
/** Gets the name of the type being constructed by this constructor call. */
|
||||
string getConstructedTypeName() { result = typename.getName() }
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class LabeledStmt extends @labeled_statement, Stmt {
|
||||
string getLabel() { label(this, result) }
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/**
|
||||
* Provides the `Location` class to give a location for each
|
||||
* program element.
|
||||
*
|
||||
* A `SourceLocation` provides a section of text in a source file
|
||||
* containing the program element.
|
||||
*
|
||||
* Based on csharp/ql/lib/semmle/code/csharp/Location.qll
|
||||
*/
|
||||
|
||||
import File
|
||||
|
||||
/**
|
||||
* A location of a program element.
|
||||
*/
|
||||
class Location extends @location {
|
||||
/** Gets the file of the location. */
|
||||
File getFile() { none() }
|
||||
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
none()
|
||||
}
|
||||
|
||||
/** Gets a textual representation of this location. */
|
||||
string toString() { none() }
|
||||
|
||||
/** Gets the 1-based line number (inclusive) where this location starts. */
|
||||
int getStartLine() { this.hasLocationInfo(_, result, _, _, _) }
|
||||
|
||||
/** Gets the 1-based line number (inclusive) where this location ends. */
|
||||
int getEndLine() { this.hasLocationInfo(_, _, _, result, _) }
|
||||
|
||||
/** Gets the 1-based column number (inclusive) where this location starts. */
|
||||
int getStartColumn() { this.hasLocationInfo(_, _, result, _, _) }
|
||||
|
||||
/** Gets the 1-based column number (inclusive) where this location ends. */
|
||||
int getEndColumn() { this.hasLocationInfo(_, _, _, _, result) }
|
||||
}
|
||||
|
||||
/** An empty location. */
|
||||
class EmptyLocation extends Location {
|
||||
EmptyLocation() { this.hasLocationInfo("", 0, 0, 0, 0) }
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class LoopStmt extends @loop_statement, LabeledStmt {
|
||||
StmtBlock getBody() { none() }
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class Member extends @member, Ast {
|
||||
Type getDeclaringType() { result.getAMember() = this }
|
||||
|
||||
string getName() { none() }
|
||||
|
||||
override string toString() { result = this.getName() }
|
||||
|
||||
predicate isHidden() { none() }
|
||||
|
||||
predicate isPrivate() { none() }
|
||||
|
||||
predicate isPublic() { none() }
|
||||
|
||||
predicate isStatic() { none() }
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class MemberExpr extends @member_expression, MemberExprBase {
|
||||
final override Location getLocation() { member_expression_location(this, result) }
|
||||
|
||||
Expr getQualifier() { member_expression(this, result, _, _, _) }
|
||||
|
||||
CmdElement getMember() { member_expression(this, _, result, _, _) }
|
||||
|
||||
/** Gets the name of the member being looked up, if any. */
|
||||
string getMemberName() { result = this.getMember().(StringConstExpr).getValue().getValue() }
|
||||
|
||||
predicate isNullConditional() { member_expression(this, _, _, true, _) }
|
||||
|
||||
override predicate isStatic() { member_expression(this, _, _, _, true) }
|
||||
|
||||
final override string toString() { result = this.getMember().toString() }
|
||||
}
|
||||
|
||||
/** A `MemberExpr` that is being written to. */
|
||||
class MemberExprWriteAccess extends MemberExpr {
|
||||
MemberExprWriteAccess() { this = any(AssignStmt assign).getLeftHandSide() }
|
||||
}
|
||||
|
||||
/** A `MemberExpr` that is being read from. */
|
||||
class MemberExprReadAccess extends MemberExpr {
|
||||
MemberExprReadAccess() { not this instanceof MemberExprWriteAccess }
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class MemberExprBase extends @member_expression_base, Expr {
|
||||
predicate isStatic() { none() }
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class MergingRedirection extends @merging_redirection, Redirection {
|
||||
override string toString() { result = "MergingRedirection" }
|
||||
|
||||
override Location getLocation() { merging_redirection_location(this, result) }
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class ModuleManifestFile extends File {
|
||||
ModuleManifestFile() { this.getExtension() = "psd1" }
|
||||
}
|
||||
|
||||
private Expr getEntry(HashTableExpr ht, string key) {
|
||||
result = ht.getElementFromConstant(key).(CmdExpr).getExpr() and
|
||||
not result instanceof ArrayLiteral
|
||||
}
|
||||
|
||||
private Expr getAnEntry(HashTableExpr ht, string key) {
|
||||
exists(Expr e | e = ht.getElementFromConstant(key).(CmdExpr).getExpr() |
|
||||
not e instanceof ArrayLiteral and result = e
|
||||
or
|
||||
result = e.(ArrayLiteral).getAnElement()
|
||||
)
|
||||
}
|
||||
|
||||
class ModuleManifest extends HashTableExpr {
|
||||
string moduleVersion;
|
||||
|
||||
ModuleManifest() {
|
||||
// The hash table is in a .psd1 file
|
||||
this.getLocation().getFile() instanceof ModuleManifestFile and
|
||||
// It's at the top level of the file
|
||||
this.getParent().(CmdExpr).getParent().(NamedBlock).getParent() instanceof TopLevel and
|
||||
// It has a `ModuleVersion` entry. The only required field is ModuleVersion.
|
||||
// https://learn.microsoft.com/en-us/powershell/scripting/developer/module/how-to-write-a-powershell-module-manifest?view=powershell-7.4#to-create-and-use-a-module-manifest
|
||||
moduleVersion = getEntry(this, "ModuleVersion").getValue().asString()
|
||||
}
|
||||
|
||||
string getModuleVersion() { result = moduleVersion }
|
||||
|
||||
string getModuleName() {
|
||||
result + ".psd1" = this.getLocation().getFile().getBaseName()
|
||||
}
|
||||
|
||||
string getAFunctionToExport() {
|
||||
result = getAnEntry(this, "FunctionsToExport").getValue().asString()
|
||||
}
|
||||
|
||||
string getACmdLetToExport() { result = getAnEntry(this, "CmdletsToExport").getValue().asString() }
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class ModuleSpecification extends @module_specification {
|
||||
string toString() { result = this.getName() }
|
||||
|
||||
string getName() { module_specification(this, result, _, _, _, _) }
|
||||
|
||||
string getGuid() { module_specification(this, _, result, _, _, _) }
|
||||
|
||||
string getMaxVersion() { module_specification(this, _, _, result, _, _) }
|
||||
|
||||
string getRequiredVersion() { module_specification(this, _, _, _, result, _) }
|
||||
|
||||
string getVersion() { module_specification(this, _, _, _, _, result) }
|
||||
|
||||
Location getLocation() { result instanceof EmptyLocation }
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class NamedAttributeArgument extends @named_attribute_argument, Ast {
|
||||
final override string toString() { result = this.getName() }
|
||||
|
||||
final override SourceLocation getLocation() { named_attribute_argument_location(this, result) }
|
||||
|
||||
string getName() { named_attribute_argument(this, result, _) }
|
||||
|
||||
predicate hasName(string s) { this.getName() = s }
|
||||
|
||||
Expr getValue() { named_attribute_argument(this, _, result) }
|
||||
}
|
||||
|
||||
class ValueFromPipelineAttribute extends NamedAttributeArgument {
|
||||
ValueFromPipelineAttribute() { this.getName() = "ValueFromPipeline" }
|
||||
}
|
||||
|
||||
class ValueFromPipelineByPropertyName extends NamedAttributeArgument {
|
||||
ValueFromPipelineByPropertyName() { this.getName() = "ValueFromPipelineByPropertyName" }
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class NamedBlock extends @named_block, Ast {
|
||||
override string toString() { result = "{...}" }
|
||||
|
||||
override SourceLocation getLocation() { named_block_location(this, result) }
|
||||
|
||||
int getNumStatements() { named_block(this, result, _) }
|
||||
|
||||
int getNumTraps() { named_block(this, _, result) }
|
||||
|
||||
Stmt getStmt(int i) { named_block_statement(this, i, result) }
|
||||
|
||||
Stmt getAStmt() { result = this.getStmt(_) }
|
||||
|
||||
TrapStmt getTrap(int i) { named_block_trap(this, i, result) }
|
||||
|
||||
TrapStmt getATrap() { result = this.getTrap(_) }
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
import powershell
|
||||
|
||||
abstract private class AbstractObjectCreation extends Call {
|
||||
/**
|
||||
* The type of the object being constructed.
|
||||
* Note that the type may not exist in the database.
|
||||
*
|
||||
* Use `getConstructedTypeName` to get the name of the type (which will
|
||||
* always exist in the database).
|
||||
*/
|
||||
abstract Type getConstructedType();
|
||||
|
||||
/** The name of the type of the object being constructed. */
|
||||
abstract string getConstructedTypeName();
|
||||
}
|
||||
|
||||
/**
|
||||
* An object creation from a call to a constructor. For example:
|
||||
* ```powershell
|
||||
* [System.IO.FileInfo]::new("C:\\file.txt")
|
||||
* ```
|
||||
*/
|
||||
class NewObjectCreation extends AbstractObjectCreation instanceof ConstructorCall {
|
||||
final override Type getConstructedType() { result = ConstructorCall.super.getConstructedType() }
|
||||
|
||||
final override string getConstructedTypeName() {
|
||||
result = ConstructorCall.super.getConstructedTypeName()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An object creation from a call to `New-Object`. For example:
|
||||
* ```powershell
|
||||
* New-Object -TypeName System.IO.FileInfo -ArgumentList "C:\\file.txt"
|
||||
* ```
|
||||
*/
|
||||
class DotNetObjectCreation extends AbstractObjectCreation instanceof Cmd {
|
||||
DotNetObjectCreation() { this.getCommandName() = "New-Object" }
|
||||
|
||||
final override Type getConstructedType() { none() }
|
||||
|
||||
final override string getConstructedTypeName() {
|
||||
// Either it's the named argument `TypeName`
|
||||
result = Cmd.super.getNamedArgument("TypeName").(StringConstExpr).getValue().getValue()
|
||||
or
|
||||
// Or it's the first positional argument if that's the named argument
|
||||
not Cmd.super.hasNamedArgument("TypeName") and
|
||||
exists(StringConstExpr arg | arg = Cmd.super.getPositionalArgument(0) |
|
||||
result = arg.getValue().getValue() and
|
||||
not arg = Cmd.super.getNamedArgument(["ArgumentList", "Property"])
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
final class ObjectCreation = AbstractObjectCreation;
|
||||
@@ -1,21 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class ParamBlock extends @param_block, Ast {
|
||||
override string toString() { result = "param(...)" }
|
||||
|
||||
override SourceLocation getLocation() { param_block_location(this, result) }
|
||||
|
||||
int getNumAttributes() { param_block(this, result, _) }
|
||||
|
||||
int getNumParameters() { param_block(this, _, result) }
|
||||
|
||||
Attribute getAttribute(int i) { param_block_attribute(this, i, result) }
|
||||
|
||||
Attribute getAnAttribute() { result = this.getAttribute(_) }
|
||||
|
||||
Parameter getParameter(int i) { result.hasParameterBlock(this, i) }
|
||||
|
||||
Parameter getParameterExcludingPiplines(int i) { result.hasParameterBlockExcludingPipelines(this, i) }
|
||||
|
||||
Parameter getAParameter() { result = this.getParameter(_) }
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class ParenExpr extends @paren_expression, Expr {
|
||||
PipelineBase getBase() { paren_expression(this, result) }
|
||||
|
||||
override SourceLocation getLocation() { paren_expression_location(this, result) }
|
||||
|
||||
override string toString() { result = "(...)" }
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class Pipeline extends @pipeline, Chainable {
|
||||
override string toString() {
|
||||
if this.getNumberOfComponents() = 1
|
||||
then result = this.getComponent(0).toString()
|
||||
else result = "...|..."
|
||||
}
|
||||
|
||||
override SourceLocation getLocation() { pipeline_location(this, result) }
|
||||
|
||||
int getNumberOfComponents() { result = count(this.getAComponent()) }
|
||||
|
||||
CmdBase getComponent(int i) { pipeline_component(this, i, result) }
|
||||
|
||||
CmdBase getAComponent() { result = this.getComponent(_) }
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class PipelineBase extends @pipeline_base, Stmt { }
|
||||
@@ -1,11 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class PipelineChain extends @pipeline_chain, Chainable {
|
||||
final override SourceLocation getLocation() { pipeline_chain_location(this, result) }
|
||||
|
||||
predicate isBackground() { pipeline_chain(this, true, _, _, _) }
|
||||
|
||||
Chainable getLeft() { pipeline_chain(this, _, _, result, _) }
|
||||
|
||||
Pipeline getRight() { pipeline_chain(this, _, _, _, result) }
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class PropertyMember extends @property_member, Member {
|
||||
override string getName() { property_member(this, _, _, _, _, result, _) }
|
||||
|
||||
override SourceLocation getLocation() { property_member_location(this, result) }
|
||||
|
||||
override string toString() { result = this.getName() }
|
||||
|
||||
override predicate isHidden() { property_member(this, true, _, _, _, _, _) }
|
||||
|
||||
override predicate isPrivate() { property_member(this, _, true, _, _, _, _) }
|
||||
|
||||
override predicate isPublic() { property_member(this, _, _, true, _, _, _) }
|
||||
|
||||
override predicate isStatic() { property_member(this, _, _, _, true, _, _) }
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class Redirection extends @redirection, Ast { }
|
||||
@@ -1,13 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class ReturnStmt extends @return_statement, Stmt {
|
||||
override SourceLocation getLocation() { return_statement_location(this, result) }
|
||||
|
||||
override string toString() {
|
||||
if this.hasPipeline() then result = "return ..." else result = "return"
|
||||
}
|
||||
|
||||
PipelineBase getPipeline() { return_statement_pipeline(this, result) }
|
||||
|
||||
predicate hasPipeline() { exists(this.getPipeline()) }
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
import powershell
|
||||
private import semmle.code.powershell.controlflow.internal.Scope
|
||||
|
||||
class ScriptBlock extends @script_block, Ast {
|
||||
predicate isTopLevel() { not exists(this.getParent()) }
|
||||
|
||||
override string toString() {
|
||||
if this.isTopLevel()
|
||||
then result = this.getLocation().getFile().getBaseName()
|
||||
else result = "{...}"
|
||||
}
|
||||
|
||||
override Location getLocation() { script_block_location(this, result) }
|
||||
|
||||
int getNumUsings() { script_block(this, result, _, _, _, _) }
|
||||
|
||||
int getNumRequiredModules() { script_block(this, _, result, _, _, _) }
|
||||
|
||||
int getNumRequiredAssemblies() { script_block(this, _, _, result, _, _) }
|
||||
|
||||
int getNumRequiredPsEditions() { script_block(this, _, _, _, result, _) }
|
||||
|
||||
int getNumRequiredPsSnapIns() { script_block(this, _, _, _, _, result) }
|
||||
|
||||
Stmt getUsing(int i) { script_block_using(this, i, result) }
|
||||
|
||||
Stmt getAUsing() { result = this.getUsing(_) }
|
||||
|
||||
ParamBlock getParamBlock() { script_block_param_block(this, result) }
|
||||
|
||||
NamedBlock getBeginBlock() { script_block_begin_block(this, result) }
|
||||
|
||||
NamedBlock getCleanBlock() { script_block_clean_block(this, result) }
|
||||
|
||||
NamedBlock getDynamicParamBlock() { script_block_dynamic_param_block(this, result) }
|
||||
|
||||
NamedBlock getEndBlock() { script_block_end_block(this, result) }
|
||||
|
||||
NamedBlock getProcessBlock() { script_block_process_block(this, result) }
|
||||
|
||||
string getRequiredApplicationId() { script_block_required_application_id(this, result) }
|
||||
|
||||
boolean getRequiresElevation() { script_block_requires_elevation(this, result) }
|
||||
|
||||
string getRequiredPsVersion() { script_block_required_ps_version(this, result) }
|
||||
|
||||
ModuleSpecification getModuleSpecification(int i) {
|
||||
script_block_required_module(this, i, result)
|
||||
}
|
||||
|
||||
ModuleSpecification getAModuleSpecification() { result = this.getModuleSpecification(_) }
|
||||
|
||||
final override Scope getEnclosingScope() { result = this }
|
||||
|
||||
/**
|
||||
* Gets the `i`'th paramter in this scope.
|
||||
*
|
||||
* This may be both function paramters and parameter block parameters.
|
||||
*/
|
||||
Parameter getParameter(int i) {
|
||||
exists(Function func |
|
||||
func.getBody() = this and
|
||||
result = func.getParameter(i)
|
||||
)
|
||||
or
|
||||
this.isTopLevel() and
|
||||
result = this.getParamBlock().getParameter(i)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a paramter in this scope.
|
||||
*
|
||||
* This may be both function parameters and parameter block parameters.
|
||||
*/
|
||||
Parameter getAParameter() { result = this.getParameter(_) }
|
||||
|
||||
Parameter getThisParameter() {
|
||||
exists(Function func |
|
||||
func.getBody() = this and
|
||||
result = func.getThisParameter()
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the number of function parameters. */
|
||||
final int getNumberOfParameters() { result = count(this.getAParameter()) }
|
||||
|
||||
final Parameter getParameterExcludingPiplines(int i) {
|
||||
result = this.getParamBlock().getParameterExcludingPiplines(i)
|
||||
}
|
||||
}
|
||||
|
||||
/** A `process` block. */
|
||||
class ProcessBlock extends NamedBlock {
|
||||
ScriptBlock scriptBlock;
|
||||
|
||||
ProcessBlock() { scriptBlock.getProcessBlock() = this }
|
||||
|
||||
ScriptBlock getScriptBlock() { result = scriptBlock }
|
||||
|
||||
PipelineParameter getPipelineParameter() {
|
||||
result = scriptBlock.getEnclosingFunction().getAParameter()
|
||||
}
|
||||
|
||||
PipelineByPropertyNameParameter getAPipelineByPropertyNameParameter() {
|
||||
result = scriptBlock.getEnclosingFunction().getAParameter()
|
||||
}
|
||||
}
|
||||
|
||||
class TopLevelScriptBlock extends ScriptBlock {
|
||||
TopLevelScriptBlock() { this.isTopLevel() }
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class ScriptBlockExpr extends @script_block_expression, Expr {
|
||||
override SourceLocation getLocation() { script_block_expression_location(this, result) }
|
||||
|
||||
override string toString() { result = "{...}" }
|
||||
|
||||
ScriptBlock getBody() { script_block_expression(this, result) }
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import powershell
|
||||
|
||||
/**
|
||||
* A location in source code, comprising of a source file and a segment of text
|
||||
* within the file.
|
||||
*/
|
||||
class SourceLocation extends Location, @location_default {
|
||||
override File getFile() { locations_default(this, result, _, _, _, _) }
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
exists(File f | locations_default(this, f, startline, startcolumn, endline, endcolumn) |
|
||||
filepath = f.getAbsolutePath()
|
||||
)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
|
||||
this.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
|
|
||||
result = filepath + ":" + startline + ":" + startcolumn + ":" + endline + ":" + endcolumn
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import powershell
|
||||
|
||||
abstract private class AbstractSplitExpr extends Expr {
|
||||
abstract Expr getExpr();
|
||||
|
||||
/** ..., if any. */
|
||||
Expr getSeparator() { none() }
|
||||
}
|
||||
|
||||
final class SplitExpr = AbstractSplitExpr;
|
||||
|
||||
class UnarySplitExpr extends AbstractSplitExpr, UnaryExpr {
|
||||
UnarySplitExpr() { this.getKind() = 75 }
|
||||
|
||||
final override string toString() { result = "-split ..." }
|
||||
|
||||
final override Expr getExpr() { result = this.getOperand() }
|
||||
}
|
||||
|
||||
class BinarySplitExpr extends AbstractSplitExpr, BinaryExpr {
|
||||
BinarySplitExpr() { this.getKind() = 75 }
|
||||
|
||||
final override string toString() { result = "... -split ..." }
|
||||
|
||||
final override Expr getExpr() { result = this.getLeft() }
|
||||
|
||||
final override Expr getSeparator() { result = this.getRight() }
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class Stmt extends @statement, Ast { }
|
||||
@@ -1,32 +0,0 @@
|
||||
import powershell
|
||||
private import semmle.code.powershell.internal.AstEscape::Private
|
||||
|
||||
private module ReturnContainerInterpreter implements InterpretAstInputSig {
|
||||
class T = Ast;
|
||||
|
||||
pragma[inline]
|
||||
T interpret(Ast a) { result = a }
|
||||
}
|
||||
|
||||
class StmtBlock extends @statement_block, Ast {
|
||||
override SourceLocation getLocation() { statement_block_location(this, result) }
|
||||
|
||||
int getNumberOfStmts() { statement_block(this, result, _) }
|
||||
|
||||
int getNumTraps() { statement_block(this, _, result) }
|
||||
|
||||
Stmt getStmt(int index) { statement_block_statement(this, index, result) }
|
||||
|
||||
Stmt getAStmt() { result = this.getStmt(_) }
|
||||
|
||||
TrapStmt getTrapStmt(int index) { statement_block_trap(this, index, result) }
|
||||
|
||||
TrapStmt getATrapStmt() { result = this.getTrapStmt(_) }
|
||||
|
||||
override string toString() { result = "{...}" }
|
||||
|
||||
/** Gets an element that may escape this `StmtBlock`. */
|
||||
Ast getAnElement() {
|
||||
result = this.(AstEscape<ReturnContainerInterpreter>::Element).getAnEscapingElement()
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
import powershell
|
||||
|
||||
/** A string constant. */
|
||||
class StringConstExpr extends @string_constant_expression, BaseConstExpr {
|
||||
override StringLiteral getValue() { string_constant_expression(this, result) }
|
||||
|
||||
override string getType() { result = "String" }
|
||||
|
||||
override SourceLocation getLocation() { string_constant_expression_location(this, result) }
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class StringLiteral extends @string_literal {
|
||||
int getNumContinuations() { result = strictcount(int i | exists(this.getContinuation(i))) }
|
||||
|
||||
string getContinuation(int index) { string_literal_line(this, index, result) }
|
||||
|
||||
/** Get the full string literal with all its parts concatenated */
|
||||
string toString() { result = this.getValue() }
|
||||
|
||||
string getValue() {
|
||||
result = concat(int i | i = [0 .. this.getNumContinuations()] | this.getContinuation(i), "\n")
|
||||
}
|
||||
|
||||
SourceLocation getLocation() { string_literal_location(this, result) }
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
import powershell
|
||||
|
||||
// TODO: Should we remove this from the dbscheme?
|
||||
class ExpandableSubExpr extends @sub_expression, Expr {
|
||||
final override Location getLocation() { sub_expression_location(this, result) }
|
||||
|
||||
StmtBlock getExpr() { sub_expression(this, result) }
|
||||
|
||||
final override string toString() { result = "$(...)" }
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class SwitchStmt extends LabeledStmt, @switch_statement {
|
||||
final override Location getLocation() { switch_statement_location(this, result) }
|
||||
|
||||
PipelineBase getCondition() { switch_statement(this, result, _) }
|
||||
|
||||
StmtBlock getDefault() { switch_statement_default(this, result) }
|
||||
|
||||
StmtBlock getCase(int i, Expr e) { switch_statement_clauses(this, i, e, result) }
|
||||
|
||||
StmtBlock getCase(int i) { result = this.getCase(i, _) }
|
||||
|
||||
StmtBlock getACase() { result = this.getCase(_) }
|
||||
|
||||
StmtBlock getCaseForExpr(Expr e) { result = this.getCase(_, e) }
|
||||
|
||||
Expr getPattern(int i) { exists(this.getCase(i, result)) }
|
||||
|
||||
Expr getAPattern() { result = this.getPattern(_) }
|
||||
|
||||
int getNumberOfCases() { result = count(this.getACase()) }
|
||||
|
||||
final override string toString() { result = "switch(...) {...}" }
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class ConditionalExpr extends @ternary_expression, Expr {
|
||||
override string toString() { result = "...?...:..." }
|
||||
|
||||
override SourceLocation getLocation() { ternary_expression_location(this, result) }
|
||||
|
||||
Expr getCondition() { ternary_expression(this, result, _, _) }
|
||||
|
||||
Expr getIfFalse() { ternary_expression(this, _, result, _) }
|
||||
|
||||
Expr getIfTrue() { ternary_expression(this, _, _, result) }
|
||||
|
||||
Expr getBranch(boolean value) {
|
||||
value = true and
|
||||
result = this.getIfTrue()
|
||||
or
|
||||
value = false and
|
||||
result = this.getIfFalse()
|
||||
}
|
||||
|
||||
Expr getABranch() { result = this.getBranch(_) }
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class ThrowStmt extends @throw_statement, Stmt {
|
||||
override SourceLocation getLocation() { throw_statement_location(this, result) }
|
||||
|
||||
override string toString() {
|
||||
if this.hasPipeline() then result = "throw ..." else result = "throw"
|
||||
}
|
||||
|
||||
PipelineBase getPipeline() { throw_statement_pipeline(this, result) }
|
||||
|
||||
predicate hasPipeline() { exists(this.getPipeline()) }
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class TrapStmt extends @trap_statement, Stmt {
|
||||
override SourceLocation getLocation() { trap_statement_location(this, result) }
|
||||
|
||||
override string toString() { result = "TrapStatement at: " + this.getLocation().toString() }
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class TryStmt extends @try_statement, Stmt {
|
||||
override SourceLocation getLocation() { try_statement_location(this, result) }
|
||||
|
||||
override string toString() { result = "try {...}" }
|
||||
|
||||
CatchClause getCatchClause(int i) { try_statement_catch_clause(this, i, result) }
|
||||
|
||||
CatchClause getACatchClause() { result = this.getCatchClause(_) }
|
||||
|
||||
/** ..., if any. */
|
||||
StmtBlock getFinally() { try_statement_finally(this, result) }
|
||||
|
||||
StmtBlock getBody() { try_statement(this, result) }
|
||||
|
||||
predicate hasFinally() { exists(this.getFinally()) }
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class Type extends @type_definition, Stmt {
|
||||
override SourceLocation getLocation() { type_definition_location(this, result) }
|
||||
|
||||
override string toString() { result = this.getName() }
|
||||
|
||||
string getName() { type_definition(this, result, _, _, _, _) }
|
||||
|
||||
Member getMember(int i) { type_definition_members(this, i, result) }
|
||||
|
||||
Member getAMember() { result = this.getMember(_) }
|
||||
|
||||
Method getMethod(string name) {
|
||||
result.getMember() = this.getAMember() and
|
||||
result.hasName(name)
|
||||
}
|
||||
|
||||
Constructor getAConstructor() {
|
||||
result = this.getAMethod() and
|
||||
result.getName() = this.getName()
|
||||
}
|
||||
|
||||
Method getAMethod() { result = this.getMethod(_) }
|
||||
|
||||
TypeConstraint getBaseType(int i) { type_definition_base_type(this, i, result) }
|
||||
|
||||
TypeConstraint getABaseType() { result = this.getBaseType(_) }
|
||||
|
||||
Type getASubtype() { result.getABaseType().getName() = this.getName() }
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class TypeConstraint extends @type_constraint, AttributeBase {
|
||||
override SourceLocation getLocation() { type_constraint_location(this, result) }
|
||||
|
||||
/** Gets the assembly name. */
|
||||
string getName() { type_constraint(this, result, _) }
|
||||
|
||||
/** Gets the full name of this type constraint including namespaces. */
|
||||
string getFullName() { type_constraint(this, _, result) }
|
||||
|
||||
override string toString() { result = this.getName() }
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class TypeNameExpr extends @type_expression, Expr {
|
||||
string getName() { type_expression(this, result, _) }
|
||||
|
||||
string getFullyQualifiedName() { type_expression(this, _, result) }
|
||||
|
||||
override string toString() { result = this.getName() }
|
||||
|
||||
override SourceLocation getLocation() { type_expression_location(this, result) }
|
||||
|
||||
/** Gets the type referred to by this `TypeNameExpr`. */
|
||||
Type getType() { result.getName() = this.getName() }
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class UnaryExpr extends @unary_expression, Expr {
|
||||
override SourceLocation getLocation() { unary_expression_location(this, result) }
|
||||
|
||||
int getKind() { unary_expression(this, _, result, _) }
|
||||
|
||||
Expr getOperand() { unary_expression(this, result, _, _) }
|
||||
}
|
||||
|
||||
class NotExpr extends UnaryExpr {
|
||||
NotExpr() { this.getKind() = [36, 51] }
|
||||
|
||||
predicate isExclamationMark() { this.getKind() = 36 }
|
||||
|
||||
predicate isNot() { this.getKind() = 51 }
|
||||
|
||||
final override string toString() {
|
||||
this.isExclamationMark() and result = "!..."
|
||||
or
|
||||
this.isNot() and result = "-not ..."
|
||||
}
|
||||
}
|
||||
|
||||
abstract private class AbstractUnaryArithmeticExpr extends UnaryExpr { }
|
||||
|
||||
final class UnaryArithmeticExpr = AbstractUnaryArithmeticExpr;
|
||||
|
||||
abstract private class AbstractPostfixExpr extends AbstractUnaryArithmeticExpr, UnaryExpr { }
|
||||
|
||||
abstract private class AbstractPrefixExpr extends AbstractUnaryArithmeticExpr, UnaryExpr { }
|
||||
|
||||
abstract private class AbstractIncrExpr extends AbstractUnaryArithmeticExpr, UnaryExpr { }
|
||||
|
||||
abstract private class AbstractDecrExpr extends AbstractUnaryArithmeticExpr, UnaryExpr { }
|
||||
|
||||
final class PostfixExpr = AbstractPostfixExpr;
|
||||
|
||||
final class PrefixExpr = AbstractPrefixExpr;
|
||||
|
||||
final class IncrExpr = AbstractIncrExpr;
|
||||
|
||||
final class DecrExpr = AbstractDecrExpr;
|
||||
|
||||
class PostfixIncrExpr extends AbstractPostfixExpr, AbstractIncrExpr {
|
||||
PostfixIncrExpr() { this.getKind() = 95 }
|
||||
|
||||
final override string toString() { result = "...++" }
|
||||
}
|
||||
|
||||
class PostfixDecrExpr extends AbstractPostfixExpr, AbstractIncrExpr {
|
||||
PostfixDecrExpr() { this.getKind() = 96 }
|
||||
|
||||
final override string toString() { result = "...--" }
|
||||
}
|
||||
|
||||
class PrefixDecrExpr extends AbstractPostfixExpr, AbstractIncrExpr {
|
||||
PrefixDecrExpr() { this.getKind() = 31 }
|
||||
|
||||
final override string toString() { result = "--..." }
|
||||
}
|
||||
|
||||
class PrefixIncrExpr extends AbstractPostfixExpr, AbstractIncrExpr {
|
||||
PrefixIncrExpr() { this.getKind() = 32 }
|
||||
|
||||
final override string toString() { result = "++..." }
|
||||
}
|
||||
|
||||
class NegateExpr extends AbstractUnaryArithmeticExpr {
|
||||
NegateExpr() { this.getKind() = 41 }
|
||||
|
||||
final override string toString() { result = "-..." }
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class UsingExpr extends @using_expression, Expr {
|
||||
override string toString() { result = "$using..." }
|
||||
|
||||
override SourceLocation getLocation() { using_expression_location(this, result) }
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class UsingStmt extends @using_statement, Stmt {
|
||||
override SourceLocation getLocation() { using_statement_location(this, result) }
|
||||
|
||||
override string toString() { result = "using ..." }
|
||||
|
||||
string getName() {
|
||||
exists(StringConstExpr const |
|
||||
using_statement_name(this, const) and // TODO: Change dbscheme
|
||||
result = const.getValue().getValue()
|
||||
)
|
||||
}
|
||||
|
||||
string getAlias() {
|
||||
exists(StringConstExpr const |
|
||||
using_statement_alias(this, const) and // TODO: Change dbscheme
|
||||
result = const.getValue().getValue()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,406 +0,0 @@
|
||||
private import powershell
|
||||
private import semmle.code.powershell.controlflow.internal.Scope
|
||||
private import internal.Parameter::Private as Internal
|
||||
|
||||
private predicate isFunctionParameterImpl(Internal::Parameter p, Function f, int i) {
|
||||
function_definition_parameter(f, i, p)
|
||||
}
|
||||
|
||||
private predicate hasParameterBlockImpl(Internal::Parameter p, ParamBlock block, int i) {
|
||||
param_block_parameter(block, i, p)
|
||||
}
|
||||
|
||||
private predicate hasParameterBlockExcludingPipelinesImpl(
|
||||
Internal::Parameter p, ParamBlock block, int i
|
||||
) {
|
||||
p =
|
||||
rank[i + 1](Internal::Parameter cand, int j |
|
||||
hasParameterBlockImpl(cand, block, j) and
|
||||
not cand.getAnAttribute().(Attribute).getANamedArgument() instanceof
|
||||
ValueFromPipelineAttribute and
|
||||
not cand.getAnAttribute().(Attribute).getANamedArgument() instanceof
|
||||
ValueFromPipelineByPropertyName
|
||||
|
|
||||
cand order by j
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the enclosing scope of `p`.
|
||||
*
|
||||
* For a function parameter, this is the function body. For a parameter from a
|
||||
* parameter block, this is the enclosing scope of the parameter block.
|
||||
*
|
||||
* In both of the above cases, the enclosing scope is the function body.
|
||||
*/
|
||||
private Scope getEnclosingScopeImpl(Internal::Parameter p) {
|
||||
exists(Function f |
|
||||
isFunctionParameterImpl(p, f, _) and
|
||||
result = f.getBody()
|
||||
)
|
||||
or
|
||||
exists(ParamBlock b |
|
||||
hasParameterBlockImpl(p, b, _) and
|
||||
result = b.getEnclosingScope()
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[scope]
|
||||
pragma[inline_late]
|
||||
private predicate isParameterImpl(string name, Scope scope) {
|
||||
exists(Internal::Parameter p | p.getName() = name and getEnclosingScopeImpl(p) = scope)
|
||||
or
|
||||
name = "_"
|
||||
}
|
||||
|
||||
private predicate isThisParameter(Scope scope, Type t) {
|
||||
t = scope.getEnclosingFunction().getDeclaringType()
|
||||
}
|
||||
|
||||
private newtype TParameterImpl =
|
||||
TInternalParameter(Internal::Parameter p) or
|
||||
TUnderscore(Scope scope) {
|
||||
exists(VarAccess va | va.getUserPath() = ["_", "PSItem"] and scope = va.getEnclosingScope())
|
||||
} or
|
||||
TThisParameter(Scope scope) { isThisParameter(scope, _) }
|
||||
|
||||
private class ParameterImpl extends TParameterImpl {
|
||||
abstract Location getLocation();
|
||||
|
||||
string toString() { result = this.getName() }
|
||||
|
||||
abstract string getName();
|
||||
|
||||
abstract Scope getEnclosingScope();
|
||||
|
||||
predicate hasParameterBlock(ParamBlock block, int i) { none() }
|
||||
|
||||
predicate hasParameterBlockExcludingPipelines(ParamBlock block, int i) { none() }
|
||||
|
||||
predicate isFunctionParameter(Function f, int i) { none() }
|
||||
|
||||
Expr getDefaultValue() { none() }
|
||||
|
||||
abstract Attribute getAnAttribute();
|
||||
|
||||
VarAccess getAnAccess() {
|
||||
// TODO: This won't join order nicely.
|
||||
result.getUserPath() = this.getName() and
|
||||
result.getEnclosingScope() = this.getEnclosingScope()
|
||||
}
|
||||
|
||||
abstract predicate isPipeline();
|
||||
|
||||
abstract predicate isPipelineByPropertyName();
|
||||
|
||||
/**
|
||||
* Gets the static type of this parameter.
|
||||
* The type of this parameter at runtime may be a subtype of this static
|
||||
* type.
|
||||
*/
|
||||
abstract string getStaticType();
|
||||
}
|
||||
|
||||
private class InternalParameter extends ParameterImpl, TInternalParameter {
|
||||
Internal::Parameter p;
|
||||
|
||||
InternalParameter() { this = TInternalParameter(p) }
|
||||
|
||||
override Location getLocation() { result = p.getLocation() }
|
||||
|
||||
override string getName() { result = p.getName() }
|
||||
|
||||
final override Scope getEnclosingScope() { result = getEnclosingScopeImpl(p) }
|
||||
|
||||
override predicate hasParameterBlock(ParamBlock block, int i) {
|
||||
hasParameterBlockImpl(p, block, i)
|
||||
}
|
||||
|
||||
override predicate hasParameterBlockExcludingPipelines(ParamBlock block, int i) {
|
||||
hasParameterBlockExcludingPipelinesImpl(p, block, i)
|
||||
}
|
||||
|
||||
override predicate isFunctionParameter(Function f, int i) { isFunctionParameterImpl(p, f, i) }
|
||||
|
||||
override Expr getDefaultValue() { result = p.getDefaultValue() }
|
||||
|
||||
override Attribute getAnAttribute() { result = p.getAnAttribute() }
|
||||
|
||||
override predicate isPipeline() {
|
||||
this.getAnAttribute().getANamedArgument() instanceof ValueFromPipelineAttribute
|
||||
}
|
||||
|
||||
override predicate isPipelineByPropertyName() {
|
||||
this.getAnAttribute().getANamedArgument() instanceof ValueFromPipelineByPropertyName
|
||||
}
|
||||
|
||||
final override string getStaticType() { result = p.getStaticType() }
|
||||
}
|
||||
|
||||
/**
|
||||
* The variable that represents an element in the pipeline.
|
||||
*
|
||||
* This is either the variable `$_` or the variable `$PSItem`.
|
||||
*/
|
||||
private class Underscore extends ParameterImpl, TUnderscore {
|
||||
Scope scope;
|
||||
|
||||
Underscore() { this = TUnderscore(scope) }
|
||||
|
||||
override Location getLocation() {
|
||||
// The location is the first access (ordered by location) to the variable in the scope
|
||||
exists(VarAccess va |
|
||||
va =
|
||||
min(VarAccess cand, Location location |
|
||||
cand = this.getAnAccess() and location = cand.getLocation()
|
||||
|
|
||||
cand order by location.getStartLine(), location.getStartColumn()
|
||||
) and
|
||||
result = va.getLocation()
|
||||
)
|
||||
}
|
||||
|
||||
override string getName() { result = "_" }
|
||||
|
||||
final override Scope getEnclosingScope() { result = scope }
|
||||
|
||||
final override Attribute getAnAttribute() { none() }
|
||||
|
||||
final override predicate isPipeline() { any() }
|
||||
|
||||
final override predicate isPipelineByPropertyName() { none() }
|
||||
|
||||
final override predicate isFunctionParameter(Function f, int i) { f.getBody() = scope and i = -1 }
|
||||
|
||||
final override string getStaticType() { none() }
|
||||
}
|
||||
|
||||
private class ThisParameter extends ParameterImpl, TThisParameter {
|
||||
Scope scope;
|
||||
|
||||
ThisParameter() { this = TThisParameter(scope) }
|
||||
|
||||
override Location getLocation() { result = scope.getLocation() }
|
||||
|
||||
override string getName() { result = "this" }
|
||||
|
||||
final override Scope getEnclosingScope() { result = scope }
|
||||
|
||||
final override Attribute getAnAttribute() { none() }
|
||||
|
||||
final override predicate isPipeline() { none() }
|
||||
|
||||
final override predicate isPipelineByPropertyName() { none() }
|
||||
|
||||
final override string getStaticType() {
|
||||
exists(Type t |
|
||||
isThisParameter(scope, t) and
|
||||
result = t.getName()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private predicate isPipelineIteratorVariable(ParameterImpl p, ProcessBlock pb) {
|
||||
p.isPipeline() and
|
||||
pb.getEnclosingScope() = p.getEnclosingScope()
|
||||
}
|
||||
|
||||
private predicate isPipelineByPropertyNameIteratorVariable(ParameterImpl p, ProcessBlock pb) {
|
||||
p.isPipelineByPropertyName() and
|
||||
pb.getEnclosingScope() = p.getEnclosingScope()
|
||||
}
|
||||
|
||||
private newtype TVariable =
|
||||
TLocalVariable(string name, Scope scope) {
|
||||
not isParameterImpl(name, scope) and
|
||||
not name = "this" and // This is modeled as a parameter
|
||||
exists(VarAccess va | va.getUserPath() = name and scope = va.getEnclosingScope())
|
||||
} or
|
||||
TParameter(ParameterImpl p) or
|
||||
TPipelineIteratorVariable(ProcessBlock pb) { isPipelineIteratorVariable(_, pb) } or
|
||||
TPipelineByPropertyNameIteratorVariable(ParameterImpl p) {
|
||||
isPipelineByPropertyNameIteratorVariable(p, _)
|
||||
}
|
||||
|
||||
private class AbstractVariable extends TVariable {
|
||||
abstract Location getLocation();
|
||||
|
||||
string toString() { result = this.getName() }
|
||||
|
||||
abstract string getName();
|
||||
|
||||
final predicate hasName(string s) { this.getName() = s }
|
||||
|
||||
abstract Scope getDeclaringScope();
|
||||
|
||||
VarAccess getAnAccess() {
|
||||
exists(string s |
|
||||
s = concat(this.getAQlClass(), ", ") and
|
||||
// TODO: This won't join order nicely.
|
||||
result.getUserPath() = this.getName() and
|
||||
result.getEnclosingScope() = this.getDeclaringScope()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
final class Variable = AbstractVariable;
|
||||
|
||||
abstract class AbstractLocalScopeVariable extends AbstractVariable { }
|
||||
|
||||
final class LocalScopeVariable = AbstractLocalScopeVariable;
|
||||
|
||||
class LocalVariable extends AbstractLocalScopeVariable, TLocalVariable {
|
||||
string name;
|
||||
Scope scope;
|
||||
|
||||
LocalVariable() { this = TLocalVariable(name, scope) }
|
||||
|
||||
override Location getLocation() {
|
||||
// The location is the first access (ordered by location) to the variable in the scope
|
||||
exists(VarAccess va |
|
||||
va =
|
||||
min(VarAccess cand, Location location |
|
||||
cand = this.getAnAccess() and location = cand.getLocation()
|
||||
|
|
||||
cand order by location.getStartLine(), location.getStartColumn()
|
||||
) and
|
||||
result = va.getLocation()
|
||||
)
|
||||
}
|
||||
|
||||
override string getName() { result = name }
|
||||
|
||||
final override Scope getDeclaringScope() { result = scope }
|
||||
}
|
||||
|
||||
/**
|
||||
* A variable of the form `$Env:HOME`.
|
||||
*/
|
||||
class EnvVariable extends Variable {
|
||||
string var;
|
||||
|
||||
EnvVariable() { this.getName() = ["env:", "Env:"] + var }
|
||||
|
||||
/**
|
||||
* Gets the part of the variable name that represens which environment
|
||||
* variable.
|
||||
*/
|
||||
string getEnvironmentVariable() { result = var }
|
||||
}
|
||||
|
||||
class Parameter extends AbstractLocalScopeVariable, TParameter {
|
||||
ParameterImpl p;
|
||||
|
||||
Parameter() { this = TParameter(p) }
|
||||
|
||||
override Location getLocation() { result = p.getLocation() }
|
||||
|
||||
override string getName() { result = p.getName() }
|
||||
|
||||
final predicate hasName(string name) { name = p.getName() }
|
||||
|
||||
final override Scope getDeclaringScope() { result = p.getEnclosingScope() }
|
||||
|
||||
predicate hasParameterBlock(ParamBlock block, int i) { p.hasParameterBlock(block, i) }
|
||||
|
||||
predicate hasParameterBlockExcludingPipelines(ParamBlock block, int i) {
|
||||
p.hasParameterBlockExcludingPipelines(block, i)
|
||||
}
|
||||
|
||||
predicate isFunctionParameter(Function f, int i) { p.isFunctionParameter(f, i) }
|
||||
|
||||
Expr getDefaultValue() { result = p.getDefaultValue() }
|
||||
|
||||
predicate hasDefaultValue() { exists(this.getDefaultValue()) }
|
||||
|
||||
/** Holds if this is the `this` parameter. */
|
||||
predicate isThis() { p instanceof ThisParameter }
|
||||
|
||||
/**
|
||||
* Gets the index of this parameter, if any.
|
||||
*
|
||||
* The parameter may be in a parameter block or a function parameter.
|
||||
*/
|
||||
int getIndex() { result = this.getFunctionIndex() or result = this.getBlockIndex() }
|
||||
|
||||
int getIndexExcludingPipelines() {
|
||||
result = this.getFunctionIndex() or result = this.getBlockIndexExcludingPipelines()
|
||||
}
|
||||
|
||||
/** Gets the index of this parameter in the parameter block, if any. */
|
||||
int getBlockIndex() { this.hasParameterBlock(_, result) }
|
||||
|
||||
int getBlockIndexExcludingPipelines() { this.hasParameterBlockExcludingPipelines(_, result) }
|
||||
|
||||
/** Gets the index of this parameter in the function, if any. */
|
||||
int getFunctionIndex() { this.isFunctionParameter(_, result) }
|
||||
|
||||
Function getFunction() { result.getBody() = this.getDeclaringScope() }
|
||||
|
||||
Attribute getAnAttribute() { result = p.getAnAttribute() }
|
||||
|
||||
predicate isPipeline() { p.isPipeline() }
|
||||
|
||||
predicate isPipelineByPropertyName() { p.isPipelineByPropertyName() }
|
||||
|
||||
string getStaticType() { result = p.getStaticType() }
|
||||
}
|
||||
|
||||
class PipelineParameter extends Parameter {
|
||||
PipelineParameter() { this.isPipeline() }
|
||||
|
||||
PipelineIteratorVariable getIteratorVariable() {
|
||||
result.getProcessBlock().getEnclosingScope() = p.getEnclosingScope()
|
||||
}
|
||||
}
|
||||
|
||||
class PipelineByPropertyNameParameter extends Parameter {
|
||||
PipelineByPropertyNameParameter() { this.isPipelineByPropertyName() }
|
||||
|
||||
PipelineByPropertyNameIteratorVariable getIteratorVariable() { result.getParameter() = this }
|
||||
}
|
||||
|
||||
/**
|
||||
* The variable that represents the value of a pipeline during a process block.
|
||||
*
|
||||
* That is, it is _not_ the `ValueFromPipeline` variable, but the value that is obtained by reading
|
||||
* from the pipeline.
|
||||
*/
|
||||
class PipelineIteratorVariable extends AbstractLocalScopeVariable, TPipelineIteratorVariable {
|
||||
private ProcessBlock pb;
|
||||
|
||||
PipelineIteratorVariable() { this = TPipelineIteratorVariable(pb) }
|
||||
|
||||
override Location getLocation() { result = pb.getLocation() }
|
||||
|
||||
override string getName() { result = "pipeline iterator for " + pb.toString() }
|
||||
|
||||
final override Scope getDeclaringScope() { result = pb.getEnclosingScope() }
|
||||
|
||||
ProcessBlock getProcessBlock() { result = pb }
|
||||
}
|
||||
|
||||
/**
|
||||
* The variable that represents the value of a pipeline that picks out a
|
||||
* property specific property during a process block.
|
||||
*
|
||||
* That is, it is _not_ the `PipelineByPropertyName` variable, but the value that is obtained by reading
|
||||
* from the pipeline.
|
||||
*/
|
||||
class PipelineByPropertyNameIteratorVariable extends AbstractLocalScopeVariable,
|
||||
TPipelineByPropertyNameIteratorVariable
|
||||
{
|
||||
private ParameterImpl p;
|
||||
|
||||
PipelineByPropertyNameIteratorVariable() { this = TPipelineByPropertyNameIteratorVariable(p) }
|
||||
|
||||
override Location getLocation() { result = p.getLocation() }
|
||||
|
||||
override string getName() { result = "pipeline iterator for " + p.toString() }
|
||||
|
||||
final override Scope getDeclaringScope() { result = p.getEnclosingScope() }
|
||||
|
||||
Parameter getParameter() { result = TParameter(p) }
|
||||
|
||||
ProcessBlock getProcessBlock() { isPipelineByPropertyNameIteratorVariable(p, result) }
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
import powershell
|
||||
private import internal.ExplicitWrite::Private
|
||||
|
||||
private predicate isParameterName(@variable_expression ve) { parameter(_, ve, _, _) }
|
||||
|
||||
class VarAccess extends @variable_expression, Expr {
|
||||
VarAccess() { not isParameterName(this) }
|
||||
|
||||
override string toString() { result = this.getUserPath() }
|
||||
|
||||
override SourceLocation getLocation() { variable_expression_location(this, result) }
|
||||
|
||||
string getUserPath() { variable_expression(this, result, _, _, _, _, _, _, _, _, _, _) }
|
||||
|
||||
string getDriveName() { variable_expression(this, _, result, _, _, _, _, _, _, _, _, _) }
|
||||
|
||||
boolean isConstant() { variable_expression(this, _, _, result, _, _, _, _, _, _, _, _) }
|
||||
|
||||
boolean isGlobal() { variable_expression(this, _, _, _, result, _, _, _, _, _, _, _) }
|
||||
|
||||
boolean isLocal() { variable_expression(this, _, _, _, _, result, _, _, _, _, _, _) }
|
||||
|
||||
boolean isPrivate() { variable_expression(this, _, _, _, _, _, result, _, _, _, _, _) }
|
||||
|
||||
boolean isScript() { variable_expression(this, _, _, _, _, _, _, result, _, _, _, _) }
|
||||
|
||||
boolean isUnqualified() { variable_expression(this, _, _, _, _, _, _, _, result, _, _, _) }
|
||||
|
||||
boolean isUnscoped() { variable_expression(this, _, _, _, _, _, _, _, _, result, _, _) }
|
||||
|
||||
boolean isVariable() { variable_expression(this, _, _, _, _, _, _, _, _, _, result, _) }
|
||||
|
||||
boolean isDriveQualified() { variable_expression(this, _, _, _, _, _, _, _, _, _, _, result) }
|
||||
|
||||
Variable getVariable() { result.getAnAccess() = this }
|
||||
}
|
||||
|
||||
private predicate isImplicitVariableWriteAccess(Expr e) { none() }
|
||||
|
||||
class VarReadAccess extends VarAccess {
|
||||
VarReadAccess() { not this instanceof VarWriteAccess }
|
||||
}
|
||||
|
||||
class VarWriteAccess extends VarAccess {
|
||||
VarWriteAccess() { isExplicitWrite(this, _) or isImplicitVariableWriteAccess(this) }
|
||||
|
||||
predicate isExplicit(AssignStmt assign) { isExplicitWrite(this, assign) }
|
||||
|
||||
predicate isImplicit() { isImplicitVariableWriteAccess(this) }
|
||||
}
|
||||
|
||||
/** An access to an environment variable such as `$Env:PATH` */
|
||||
class EnvVarAccess extends VarAccess {
|
||||
EnvVarAccess() { super.getVariable() instanceof EnvVariable }
|
||||
|
||||
override EnvVariable getVariable() { result = super.getVariable() }
|
||||
|
||||
string getEnvironmentVariable() { result = this.getVariable().getEnvironmentVariable() }
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import powershell
|
||||
|
||||
class WhileStmt extends @while_statement, LoopStmt {
|
||||
override SourceLocation getLocation() { while_statement_location(this, result) }
|
||||
|
||||
override string toString() { result = "while(...) {...}" }
|
||||
|
||||
PipelineBase getCondition() { while_statement_condition(this, result) }
|
||||
|
||||
final override StmtBlock getBody() { while_statement(this, result) }
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
private import powershell
|
||||
private import ControlFlowGraphImpl
|
||||
|
||||
/** Gets the enclosing scope of `n`. */
|
||||
Scope scopeOf(Ast n) {
|
||||
exists(Ast m | m = n.getParent() |
|
||||
m = result
|
||||
or
|
||||
not m instanceof Scope and result = scopeOf(m)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A variable scope. This is either a top-level (file), a module, a class,
|
||||
* or a callable.
|
||||
*/
|
||||
class Scope extends Ast, ScriptBlock {
|
||||
/** Gets the outer scope, if any. */
|
||||
Scope getOuterScope() { result = scopeOf(this) }
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
module Private {
|
||||
import Parameter::Private
|
||||
import ExplicitWrite::Private
|
||||
import Argument::Private
|
||||
import Operation::Private
|
||||
}
|
||||
|
||||
module Public {
|
||||
import Parameter::Public
|
||||
import ExplicitWrite::Public
|
||||
import Argument::Public
|
||||
import Operation::Public
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
import powershell
|
||||
|
||||
module Private {
|
||||
abstract private class AbstractOperation extends Expr {
|
||||
abstract Expr getAnOperand();
|
||||
|
||||
abstract int getKind();
|
||||
}
|
||||
|
||||
class BinaryOperation extends BinaryExpr, AbstractOperation {
|
||||
final override Expr getAnOperand() { result = BinaryExpr.super.getAnOperand() }
|
||||
|
||||
final override int getKind() { result = BinaryExpr.super.getKind() }
|
||||
}
|
||||
|
||||
class UnaryOperation extends UnaryExpr, AbstractOperation {
|
||||
final override Expr getAnOperand() { result = UnaryExpr.super.getOperand() }
|
||||
|
||||
final override int getKind() { result = UnaryExpr.super.getKind() }
|
||||
}
|
||||
|
||||
final class Operation = AbstractOperation;
|
||||
}
|
||||
|
||||
module Public {
|
||||
class Operation = Private::Operation;
|
||||
|
||||
class BinaryOperation = Private::BinaryOperation;
|
||||
|
||||
class UnaryOperation = Private::UnaryOperation;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import powershell
|
||||
|
||||
module Private {
|
||||
class Parameter extends @parameter, Ast {
|
||||
override string toString() { result = this.getName().toString() }
|
||||
|
||||
string getName() {
|
||||
exists(@variable_expression ve |
|
||||
parameter(this, ve, _, _) and
|
||||
variable_expression(ve, result, _, _, _, _, _, _, _, _, _, _)
|
||||
)
|
||||
}
|
||||
|
||||
string getStaticType() { parameter(this, _, result, _) }
|
||||
|
||||
int getNumAttributes() { parameter(this, _, _, result) }
|
||||
|
||||
AttributeBase getAttribute(int i) { parameter_attribute(this, i, result) }
|
||||
|
||||
AttributeBase getAnAttribute() { result = this.getAttribute(_) }
|
||||
|
||||
Expr getDefaultValue() { parameter_default_value(this, result) }
|
||||
|
||||
override SourceLocation getLocation() { parameter_location(this, result) }
|
||||
}
|
||||
}
|
||||
|
||||
module Public { }
|
||||
Reference in New Issue
Block a user