Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 29 additions & 101 deletions ql/lib/codeql/bicep/ast/Calls.qll
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ private import Idents
private import Misc
private import internal.Arguments
private import internal.CallExpression
private import internal.Parameter
private import internal.Parameters
private import internal.ParameterDeclaration
private import internal.UserDefinedFunction

/**
* Represents a callable expression in the AST, such as a function or method call.
* Provides access to the identifier and name of the call expression.
*/
abstract class Callable extends Expr {
/**
* Gets the identifier of the call expression.
Expand All @@ -17,121 +17,49 @@ abstract class Callable extends Expr {

/**
* Gets the name of the call expression.
*
* @return The name as a string.
*/
string getName() { result = this.getIdentifier().getName() }

/**
* Checks if the call expression has a specific name.
*
* @param name The name to check against.
* @return True if the call expression has the given name.
*/
predicate hasName(string name) { this.getName() = name }
}

/**
* A CallExpression expression in the AST.
*/
class CallExpression extends Callable instanceof CallExpressionImpl {
override Idents getIdentifier() {
result = CallExpressionImpl.super.getIdentifier()
}

Expr getArgument(int index) {
result = this.getDeclaredArguments().getArgument(index)
}

Expr getArguments() {
result = this.getDeclaredArguments().getArguments()
}

Arguments getDeclaredArguments() {
result = CallExpressionImpl.super.getArguments()
}
}


/**
* A Arguments unknown AST node.
*/
class Arguments extends AstNode instanceof ArgumentsImpl {

Expr getArgument(int index) {
result = ArgumentsImpl.super.getArgument(index)
}

Expr getArguments() {
result = ArgumentsImpl.super.getArguments()
}
}

/**
* A Parameter unknown AST node.
* Represents a call expression node in the AST.
* Provides access to the identifier, arguments, and declared arguments.
*/
class Parameter extends AstNode instanceof ParameterImpl {

Idents getName() {
result = ParameterImpl.super.getName()
}

Type getType() {
result = ParameterImpl.super.getType()
}
}

/**
* A Parameters unknown AST node.
*/
class Parameters extends AstNode instanceof ParametersImpl {
Parameter getParameter(int index) {
result = ParametersImpl.super.getParameter(index)
}
}
class CallExpression extends Expr instanceof CallExpressionImpl {
/** Gets the identifier of the call expression. */
Idents getIdentifier() { result = CallExpressionImpl.super.getIdentifier() }

/** Gets the name of the call expression. */
string getName() { result = this.getIdentifier().getName() }

/**
* A ParameterDeclaration unknown AST node.
*/
class ParameterDeclaration extends AstNode instanceof ParameterDeclarationImpl {
Identifier getName() {
result = ParameterDeclarationImpl.super.getName()
}
/** Gets the argument at the specified index. */
Expr getArgument(int index) { result = this.getDeclaredArguments().getArgument(index) }

Type getType() {
result = ParameterDeclarationImpl.super.getType()
}
/** Gets all arguments of the call expression. */
Expr getArguments() { result = this.getDeclaredArguments().getArguments() }

Expr getDefaultValue() {
result = ParameterDeclarationImpl.super.getDefaultValue()
}
/** Gets the declared arguments node. */
Arguments getDeclaredArguments() { result = CallExpressionImpl.super.getArguments() }
}

/**
* A UserDefinedFunction unknown AST node.
* Represents the arguments node in the AST.
* Provides access to individual and all arguments.
*/
class UserDefinedFunction extends AstNode instanceof UserDefinedFunctionImpl {
Identifier getIdentifier() {
result = UserDefinedFunctionImpl.super.getName()
}

string getName() {
result = this.getIdentifier().getName()
}

Type getReturnType() {
result = UserDefinedFunctionImpl.super.getReturnType()
}

Parameters getDeclaredParameters() {
result = UserDefinedFunctionImpl.super.getParameters()
}

Parameter getParameters() {
result = this.getDeclaredParameters().getParameter(_)
}

Parameter getParameter(int index) {
result = this.getDeclaredParameters().getParameter(index)
}
class Arguments extends AstNode instanceof ArgumentsImpl {
/** Gets the argument at the specified index. */
Expr getArgument(int index) { result = ArgumentsImpl.super.getArgument(index) }

Expr getBody() {
result = UserDefinedFunctionImpl.super.getBody()
}
/** Gets all arguments. */
Expr getArguments() { result = ArgumentsImpl.super.getArguments() }
}
5 changes: 0 additions & 5 deletions ql/lib/codeql/bicep/ast/Misc.qll
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ private import internal.MetadataDeclaration
private import internal.ModuleDeclaration
private import internal.NegatedType
private import internal.ObjectProperty
private import internal.OutputDeclaration
private import internal.ParameterizedType
private import internal.ParenthesizedType
private import internal.PrimitiveType
Expand Down Expand Up @@ -102,10 +101,6 @@ class ModuleDeclaration extends AstNode instanceof ModuleDeclarationImpl { }
*/
class NegatedType extends AstNode instanceof NegatedTypeImpl { }

/**
* A OutputDeclaration unknown AST node.
*/
class OutputDeclaration extends AstNode instanceof OutputDeclarationImpl { }

/**
* A ParameterizedType unknown AST node.
Expand Down
94 changes: 94 additions & 0 deletions ql/lib/codeql/bicep/ast/Stmts.qll
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
*/

private import AstNodes
private import Idents
private import Expr
private import Misc
private import internal.AstNodes
private import internal.TreeSitter
private import internal.Stmts
Expand All @@ -14,6 +17,11 @@ private import internal.ImportWithStatement
private import internal.Infrastructure
private import internal.Statement
private import internal.UsingStatement
private import internal.Parameter
private import internal.Parameters
private import internal.ParameterDeclaration
private import internal.OutputDeclaration
private import internal.UserDefinedFunction
// CFG
private import codeql.bicep.CFG
private import codeql.bicep.controlflow.internal.ControlFlowGraphImpl as CfgImpl
Expand Down Expand Up @@ -57,6 +65,92 @@ class Infrastructure extends AstNode instanceof InfrastructureImpl {
Stmts getStatement(int index) { result = InfrastructureImpl.super.getStatement(index) }
}

/**
* Represents a parameter declaration node in the AST.
* Provides access to the identifier, name, type, and default value of the parameter.
*/
class ParameterDeclaration extends AstNode instanceof ParameterDeclarationImpl {
/** Gets the identifier of the parameter declaration. */
Identifier getIdentifier() { result = ParameterDeclarationImpl.super.getName() }

/** Gets the name of the parameter declaration. */
string getName() { result = this.getIdentifier().getName() }

/** Gets the type of the parameter declaration. */
Type getType() { result = ParameterDeclarationImpl.super.getType() }

/** Gets the default value of the parameter declaration, if any. */
Expr getDefaultValue() { result = ParameterDeclarationImpl.super.getDefaultValue() }
}


/**
* Represents an output declaration node in the AST.
* Provides access to the identifier, name, type, and value of the output.
*/
class OutputDeclaration extends AstNode instanceof OutputDeclarationImpl {
/** Gets the identifier of the output declaration. */
Identifier getIdentifier() { result = OutputDeclarationImpl.super.getIdentifier() }

/** Gets the name of the output declaration. */
string getName() { result = this.getIdentifier().getName() }

/** Gets the type of the output declaration. */
Type getType() { result = OutputDeclarationImpl.super.getType() }

/** Gets the value of the output declaration. */
Expr getValue() { result = OutputDeclarationImpl.super.getValue() }
}

/**
* Represents a user-defined function node in the AST.
* Provides access to the identifier, name, return type, parameters, and body of the function.
*/
class UserDefinedFunction extends AstNode instanceof UserDefinedFunctionImpl {
/** Gets the identifier of the user-defined function. */
Identifier getIdentifier() { result = UserDefinedFunctionImpl.super.getName() }

/** Gets the name of the user-defined function. */
string getName() { result = this.getIdentifier().getName() }

/** Gets the return type of the user-defined function. */
Type getReturnType() { result = UserDefinedFunctionImpl.super.getReturnType() }

/** Gets the declared parameters of the user-defined function. */
Parameters getDeclaredParameters() { result = UserDefinedFunctionImpl.super.getParameters() }

/** Gets all parameters of the user-defined function. */
Parameter getParameters() { result = this.getDeclaredParameters().getParameter(_) }

/** Gets the parameter at the specified index. */
Parameter getParameter(int index) { result = this.getDeclaredParameters().getParameter(index) }

/** Gets the body of the user-defined function. */
Expr getBody() { result = UserDefinedFunctionImpl.super.getBody() }
}

/**
* Represents a parameter node in the AST.
* Provides access to the parameter's name and type.
*/
class Parameter extends AstNode instanceof ParameterImpl {
/** Gets the name of the parameter. */
Idents getName() { result = ParameterImpl.super.getName() }

/** Gets the type of the parameter. */
Type getType() { result = ParameterImpl.super.getType() }
}

/**
* Represents a parameters node in the AST.
* Provides access to individual parameters by index.
*/
class Parameters extends AstNode instanceof ParametersImpl {
/** Gets the parameter at the specified index. */
Parameter getParameter(int index) { result = ParametersImpl.super.getParameter(index) }
}


/**
* A ImportWithStatement statement
*/
Expand Down
12 changes: 12 additions & 0 deletions ql/lib/codeql/bicep/ast/internal/OutputDeclaration.qll
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
private import AstNodes
private import TreeSitter
private import codeql.bicep.ast.AstNodes
private import Idents
private import Expr
private import Type

/**
* A OutputDeclaration AST Node.
Expand All @@ -19,6 +22,15 @@ class OutputDeclarationImpl extends TOutputDeclaration, AstNode {

override string toString() { result = ast.toString() }

IdentsImpl getIdentifier() {
toTreeSitter(result) = ast.getChild(0)
}

TypeImpl getType() {
toTreeSitter(result) = ast.getChild(1)
}

ExprImpl getValue() {
toTreeSitter(result) = ast.getChild(2)
}
}
62 changes: 62 additions & 0 deletions ql/lib/codeql/bicep/controlflow/internal/ControlFlowGraphImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,23 @@ private module CfgImpl = Make<Location, Implementation>;

import CfgImpl

class InfrastructureScopeTree extends StandardTree, PreOrderTree, PostOrderTree, Scope::InfrastructureScope {
override AstNode getChildNode(int i) { result = super.getStatement(i) }
}

class StmtsTree extends StandardPostOrderTree instanceof Stmts {
override AstNode getChildNode(int i) {
//
i = 0 and result = super.getAChild()
}
}

class ExprTree extends StandardPostOrderTree instanceof Expr {
override AstNode getChildNode(int i) {
i = 0 and result = super.getAChild()
}
}

/**
* A literal value in a Bicep program.
*/
Expand All @@ -87,3 +104,48 @@ class StringLiteralTree extends LeafTree instanceof StringLiteral { }
* A StringContent literal value in a Bicep program.
*/
class StringContentLiteralTree extends LeafTree instanceof StringContentLiteral { }

/**
* ParameterDeclarationTree represents a parameter declaration in a Bicep program.
*/
class ParameterDeclarationTree extends PreOrderTree instanceof ParameterDeclaration {
final override predicate propagatesAbnormal(AstNode child) { child = super.getIdentifier() }

override predicate succ(AstNode pred, AstNode succ, Completion c) {
// Start with the identifier
pred = this and first(super.getIdentifier(), succ) and completionIsSimple(c)
or
last(super.getIdentifier(), pred, c) and first(super.getDefaultValue(), succ) and completionIsNormal(c)
}

override predicate last(AstNode node, Completion c) {
node = super.getDefaultValue() and completionIsNormal(c)
}
}

class UserDefinedFunctionTree extends StandardPostOrderTree instanceof UserDefinedFunction {
override AstNode getChildNode(int i) {
i = 0 and result = super.getIdentifier()
or
i = 1 and result = super.getParameters()
or
i = 2 and result = super.getReturnType()
or
i = 3 and result = super.getBody()
}
}

class OutputDeclarationTree extends PreOrderTree instanceof OutputDeclaration {
final override predicate propagatesAbnormal(AstNode child) { child = super.getIdentifier() }

override predicate succ(AstNode pred, AstNode succ, Completion c) {
// Start with the identifier
pred = this and first(super.getIdentifier(), succ) and completionIsSimple(c)
or
last(super.getIdentifier(), pred, c) and first(super.getValue(), succ) and completionIsNormal(c)
}

override predicate last(AstNode node, Completion c) {
node = super.getValue() and completionIsNormal(c)
}
}
Loading