diff --git a/ql/src/codeql_ruby/ast/Expr.qll b/ql/src/codeql_ruby/ast/Expr.qll index e48f091dfd1..29ea9e12cdb 100644 --- a/ql/src/codeql_ruby/ast/Expr.qll +++ b/ql/src/codeql_ruby/ast/Expr.qll @@ -113,6 +113,21 @@ class SymbolLiteral extends Literal { final override string getAPrimaryQlClass() { result = "SymbolLiteral" } } +/** + * A method name literal. For example: + * ```rb + * - method_name # a normal name + * - + # an operator + * - :method_name # a symbol + * - :"eval_#{name}" # a complex symbol + * ``` + */ +class MethodName extends Literal { + final override MethodName::Range range; + + final override string getAPrimaryQlClass() { result = "MethodName" } +} + /** A sequence of expressions. */ class StmtSequence extends Expr { override StmtSequence::Range range; diff --git a/ql/src/codeql_ruby/ast/Statement.qll b/ql/src/codeql_ruby/ast/Statement.qll index e7af8a952a0..8e52135a3ba 100644 --- a/ql/src/codeql_ruby/ast/Statement.qll +++ b/ql/src/codeql_ruby/ast/Statement.qll @@ -59,6 +59,46 @@ class EndBlock extends StmtSequence, @end_block { final override string getAPrimaryQlClass() { result = "EndBlock" } } +/** + * An `undef` statement. For example: + * ```rb + * - undef method_name + * - undef &&, :method_name + * - undef :"method_#{ name }" + * ``` + */ +class UndefStmt extends Stmt, @undef { + final override UndefStmt::Range range; + + /** Gets the `n`th method name to undefine. */ + final MethodName getMethodName(int n) { result = range.getMethodName(n) } + + /** Gets a method name to undefine. */ + final MethodName getAMethodName() { result = getMethodName(_) } + + final override string getAPrimaryQlClass() { result = "UndefStmt" } +} + +/** + * An `alias` statement. For example: + * ```rb + * - alias alias_name method_name + * - undef foo :method_name + * - undef bar :"method_#{ name }" + * ``` + */ +class AliasStmt extends Stmt, @alias { + final override AliasStmt::Range range; + + /** Gets the new method name. */ + final MethodName getNewName() { result = range.getNewName() } + + /** Gets the original method name. */ + final MethodName getOldName() { result = range.getOldName() } + + final override string getAPrimaryQlClass() { result = "AliasStmt" } +} + /** * A statement that may return a value: `return`, `break` and `next`. * diff --git a/ql/src/codeql_ruby/ast/internal/AST.qll b/ql/src/codeql_ruby/ast/internal/AST.qll index 618aea0313a..d0a4bc556a3 100644 --- a/ql/src/codeql_ruby/ast/internal/AST.qll +++ b/ql/src/codeql_ruby/ast/internal/AST.qll @@ -31,8 +31,6 @@ module AstNode { or this = any(Generated::RestAssignment ra).getChild() or - this instanceof Generated::Alias - or this instanceof Generated::SymbolArray or this instanceof Generated::Interpolation @@ -55,10 +53,6 @@ module AstNode { or this instanceof Generated::Character or - this = any(Generated::Alias a).getName() - or - this = any(Generated::Alias a).getAlias() - or this instanceof Generated::HeredocBody or this instanceof Generated::HeredocBeginning @@ -72,10 +66,6 @@ module AstNode { this instanceof Generated::RescueModifier or this instanceof Generated::Subshell - or - this instanceof Generated::Undef - or - this = any(Generated::Undef u).getChild(_) } override string toString() { result = "AstNode" } diff --git a/ql/src/codeql_ruby/ast/internal/Expr.qll b/ql/src/codeql_ruby/ast/internal/Expr.qll index 9a7dfe22758..6a2f278b5f8 100644 --- a/ql/src/codeql_ruby/ast/internal/Expr.qll +++ b/ql/src/codeql_ruby/ast/internal/Expr.qll @@ -172,6 +172,30 @@ module SymbolLiteral { } } +module MethodName { + class Range extends Literal::Range, @underscore_method_name { + final override Generated::UnderscoreMethodName generated; + + Range() { + exists(Generated::Undef u | u.getChild(_) = generated) + or + exists(Generated::Alias a | a.getName() = generated or a.getAlias() = generated) + } + + final override string getValueText() { + result = generated.(Generated::Token).getValue() or + result = generated.(SymbolLiteral).getValueText() or + result = generated.(Generated::Setter).getName().getValue() + "=" + } + + final override string toString() { + result = getValueText() + or + not exists(getValueText()) and result = generated.(SymbolLiteral).toString() + } + } +} + module StmtSequence { abstract class Range extends Expr::Range { abstract Stmt getStmt(int n); diff --git a/ql/src/codeql_ruby/ast/internal/Method.qll b/ql/src/codeql_ruby/ast/internal/Method.qll index ae3462af950..4d0bd75cb08 100644 --- a/ql/src/codeql_ruby/ast/internal/Method.qll +++ b/ql/src/codeql_ruby/ast/internal/Method.qll @@ -17,7 +17,6 @@ module Method { string getName() { result = generated.getName().(Generated::Token).getValue() or - result = generated.getName().(SymbolLiteral).getValueText() or result = generated.getName().(Generated::Setter).getName().getValue() + "=" } diff --git a/ql/src/codeql_ruby/ast/internal/Statement.qll b/ql/src/codeql_ruby/ast/internal/Statement.qll index 5d94ddc0684..35b11030591 100644 --- a/ql/src/codeql_ruby/ast/internal/Statement.qll +++ b/ql/src/codeql_ruby/ast/internal/Statement.qll @@ -25,6 +25,28 @@ module EndBlock { } } +module UndefStmt { + class Range extends Stmt::Range, @undef { + final override Generated::Undef generated; + + final MethodName getMethodName(int n) { result = generated.getChild(n) } + + final override string toString() { result = "undef ..." } + } +} + +module AliasStmt { + class Range extends Stmt::Range, @alias { + final override Generated::Alias generated; + + final MethodName getNewName() { result = generated.getAlias() } + + final MethodName getOldName() { result = generated.getName() } + + final override string toString() { result = "alias ..." } + } +} + module ReturningStmt { abstract class Range extends Stmt::Range { abstract Generated::ArgumentList getArgumentList(); diff --git a/ql/test/library-tests/controlflow/graph/Cfg.expected b/ql/test/library-tests/controlflow/graph/Cfg.expected index 98762e036bd..aa36014772f 100644 --- a/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -566,12 +566,12 @@ case.rb: cfg.rb: # 1| bar -#-----| -> Alias +#-----| -> alias ... # 1| bar #-----| -> bar -# 3| Alias +# 3| alias ... #-----| -> foo # 3| foo @@ -1793,7 +1793,7 @@ cfg.rb: #-----| -> ! ... # 165| ... = ... -#-----| -> Undef +#-----| -> undef ... # 165| x #-----| -> ... = ... @@ -1804,7 +1804,7 @@ cfg.rb: # 165| 42 #-----| -> - ... -# 167| Undef +# 167| undef ... #-----| -> two_parameters # 167| two_parameters