diff --git a/powershell/ql/lib/semmle/code/powershell/ArrayExpression.qll b/powershell/ql/lib/semmle/code/powershell/ArrayExpression.qll index b1841c94094..a8d8ba6735d 100644 --- a/powershell/ql/lib/semmle/code/powershell/ArrayExpression.qll +++ b/powershell/ql/lib/semmle/code/powershell/ArrayExpression.qll @@ -3,7 +3,7 @@ import powershell class ArrayExpr extends @array_expression, Expr { override SourceLocation getLocation() { array_expression_location(this, result) } - StmtBlock getStatementBlock() { array_expression(this, result) } + StmtBlock getStmtBlock() { array_expression(this, result) } - override string toString() { result = "ArrayExpression at: " + this.getLocation().toString() } + override string toString() { result = "@(...)" } } diff --git a/powershell/ql/lib/semmle/code/powershell/Attribute.qll b/powershell/ql/lib/semmle/code/powershell/Attribute.qll index 88c8b466e0f..72a061c09f2 100644 --- a/powershell/ql/lib/semmle/code/powershell/Attribute.qll +++ b/powershell/ql/lib/semmle/code/powershell/Attribute.qll @@ -15,7 +15,11 @@ class Attribute extends @attribute, AttributeBase { 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()) } } diff --git a/powershell/ql/lib/semmle/code/powershell/CatchClause.qll b/powershell/ql/lib/semmle/code/powershell/CatchClause.qll index bf5ca9d8722..1156cf1f2a0 100644 --- a/powershell/ql/lib/semmle/code/powershell/CatchClause.qll +++ b/powershell/ql/lib/semmle/code/powershell/CatchClause.qll @@ -14,4 +14,24 @@ class CatchClause extends @catch_clause, Ast { predicate isCatchAll() { catch_clause(this, _, true) } // TODO: Should be equivalent to 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[...] {...}" } } diff --git a/powershell/ql/lib/semmle/code/powershell/Command.qll b/powershell/ql/lib/semmle/code/powershell/Command.qll index 29f17624493..73c2df41a7a 100644 --- a/powershell/ql/lib/semmle/code/powershell/Command.qll +++ b/powershell/ql/lib/semmle/code/powershell/Command.qll @@ -15,9 +15,28 @@ class Cmd extends @command, CmdBase { CmdElement getElement(int i) { command_command_element(this, i, result) } - Redirection getRedirection(int i) { command_redirection(this, i, result) } + StringConstExpr getCmdName() { result = this.getElement(0) } - CmdElement getAnElement() { result = this.getElement(_) } + 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 + ) + } + + 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(_) } } diff --git a/powershell/ql/lib/semmle/code/powershell/CommandParameter.qll b/powershell/ql/lib/semmle/code/powershell/CommandParameter.qll index 9e2faa21064..e1bb400b87b 100644 --- a/powershell/ql/lib/semmle/code/powershell/CommandParameter.qll +++ b/powershell/ql/lib/semmle/code/powershell/CommandParameter.qll @@ -5,7 +5,19 @@ class CmdParameter extends @command_parameter, CmdElement { string getName() { command_parameter(this, result) } - Expr getArgument() { command_parameter_argument(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) } } diff --git a/powershell/ql/lib/semmle/code/powershell/IfStmt.qll b/powershell/ql/lib/semmle/code/powershell/IfStmt.qll index 019a811fa6d..f53bd76760c 100644 --- a/powershell/ql/lib/semmle/code/powershell/IfStmt.qll +++ b/powershell/ql/lib/semmle/code/powershell/IfStmt.qll @@ -13,6 +13,10 @@ class IfStmt extends @if_statement, Stmt { StmtBlock getThen(int i) { if_statement_clause(this, i, _, result) } // TODO: Change @ast to @statement_block in dbscheme + int getNumberOfConditions() { result = count(this.getACondition()) } + + StmtBlock getAThen() { result = this.getThen(_) } + /** ..., if any. */ StmtBlock getElse() { if_statement_else(this, result) } // TODO: Change @ast to @stmt_block in dbscheme diff --git a/powershell/ql/lib/semmle/code/powershell/InvokeMemberExpression.qll b/powershell/ql/lib/semmle/code/powershell/InvokeMemberExpression.qll index 90e04f0c5d1..1ff04f78e3a 100644 --- a/powershell/ql/lib/semmle/code/powershell/InvokeMemberExpression.qll +++ b/powershell/ql/lib/semmle/code/powershell/InvokeMemberExpression.qll @@ -1,9 +1,9 @@ import powershell -class InvokeMemberExpression extends @invoke_member_expression, MemberExprBase { +class InvokeMemberExpr extends @invoke_member_expression, MemberExprBase { override SourceLocation getLocation() { invoke_member_expression_location(this, result) } - Expr getExpression() { invoke_member_expression(this, result, _) } + Expr getBase() { invoke_member_expression(this, result, _) } CmdElement getMember() { invoke_member_expression(this, _, result) } @@ -11,5 +11,5 @@ class InvokeMemberExpression extends @invoke_member_expression, MemberExprBase { Expr getAnArgument() { invoke_member_expression_argument(this, _, result) } - override string toString() { result = "ArrayExpression at: " + this.getLocation().toString() } + override string toString() { result = "call to " + this.getMember() } } diff --git a/powershell/ql/lib/semmle/code/powershell/NamedAttributeArgument.qll b/powershell/ql/lib/semmle/code/powershell/NamedAttributeArgument.qll index ef6a667d213..150ff9992de 100644 --- a/powershell/ql/lib/semmle/code/powershell/NamedAttributeArgument.qll +++ b/powershell/ql/lib/semmle/code/powershell/NamedAttributeArgument.qll @@ -1,9 +1,9 @@ import powershell -class NamedAttributeArgument extends @named_attribute_argument { - string toString() { result = this.getValue().toString() } +class NamedAttributeArgument extends @named_attribute_argument, Ast { + final override string toString() { result = this.getValue().toString() } - SourceLocation getLocation() { named_attribute_argument_location(this, result) } + final override SourceLocation getLocation() { named_attribute_argument_location(this, result) } string getName() { named_attribute_argument(this, result, _) } diff --git a/powershell/ql/lib/semmle/code/powershell/StringConstantExpression.qll b/powershell/ql/lib/semmle/code/powershell/StringConstantExpression.qll index 788b2def636..2ca13df15b6 100644 --- a/powershell/ql/lib/semmle/code/powershell/StringConstantExpression.qll +++ b/powershell/ql/lib/semmle/code/powershell/StringConstantExpression.qll @@ -1,10 +1,10 @@ import powershell -class StringConstExpression extends @string_constant_expression, BaseConstExpr { +class StringConstExpr extends @string_constant_expression, BaseConstExpr { StringLiteral getValue() { string_constant_expression(this, result) } /** Get the full string literal with all its parts concatenated */ - override string toString() { result = getValue().toString() } + override string toString() { result = this.getValue().toString() } override SourceLocation getLocation() { string_constant_expression_location(this, result) } } diff --git a/powershell/ql/lib/semmle/code/powershell/StringLiteral.qll b/powershell/ql/lib/semmle/code/powershell/StringLiteral.qll index 4eb9a9d77a4..77ece5d7d1c 100644 --- a/powershell/ql/lib/semmle/code/powershell/StringLiteral.qll +++ b/powershell/ql/lib/semmle/code/powershell/StringLiteral.qll @@ -7,7 +7,11 @@ class StringLiteral extends @string_literal { /** Get the full string literal with all its parts concatenated */ string toString() { - result = concat(int i | i = [0 .. getNumContinuations()] | getContinuation(i), "\n") + result = this.getValue() + } + + string getValue() { + result = concat(int i | i = [0 .. this.getNumContinuations()] | this.getContinuation(i), "\n") } SourceLocation getLocation() { string_literal_location(this, result) } diff --git a/powershell/ql/lib/semmle/code/powershell/TryStmt.qll b/powershell/ql/lib/semmle/code/powershell/TryStmt.qll index 5c2b4f33b9e..cce994e0f99 100644 --- a/powershell/ql/lib/semmle/code/powershell/TryStmt.qll +++ b/powershell/ql/lib/semmle/code/powershell/TryStmt.qll @@ -14,4 +14,5 @@ class TryStmt extends @try_statement, Stmt { StmtBlock getBody() { try_statement(this, result) } // TODO: Change @ast to @stmt_block in dbscheme + predicate hasFinally() { exists(this.getFinally()) } }