diff --git a/ql/src/codeql_ruby/ast/Pattern.qll b/ql/src/codeql_ruby/ast/Pattern.qll index d23ddb0de52..e5cbd87bac9 100644 --- a/ql/src/codeql_ruby/ast/Pattern.qll +++ b/ql/src/codeql_ruby/ast/Pattern.qll @@ -14,6 +14,21 @@ class Pattern extends AstNode { Variable getAVariable() { result = range.getAVariable() } } +/** + * A "left-hand-side" expression. + * ```rb + * var = 1 + * var += 1 + * E = 1 + * foo.bar = 1 + * foo[0] = 1 + * rescue E => var + * ``` + */ +class LhsExpr extends Pattern, Expr { + override LhsExpr::Range range; +} + /** A simple variable pattern. */ class VariablePattern extends Pattern { override VariablePattern::Range range; diff --git a/ql/src/codeql_ruby/ast/internal/Expr.qll b/ql/src/codeql_ruby/ast/internal/Expr.qll index c395511e43f..ab295e94f33 100644 --- a/ql/src/codeql_ruby/ast/internal/Expr.qll +++ b/ql/src/codeql_ruby/ast/internal/Expr.qll @@ -310,7 +310,7 @@ module RescueClause { class Range extends Expr::Range, @rescue { final override Generated::Rescue generated; - final Expr getException(int n) { result = generated.getExceptions().getChild(n) } + final LhsExpr getException(int n) { result = generated.getExceptions().getChild(n) } final Expr getVariableExpr() { result = generated.getVariable() } diff --git a/ql/src/codeql_ruby/ast/internal/Operation.qll b/ql/src/codeql_ruby/ast/internal/Operation.qll index 124bd18e03e..0a0715961f3 100644 --- a/ql/src/codeql_ruby/ast/internal/Operation.qll +++ b/ql/src/codeql_ruby/ast/internal/Operation.qll @@ -246,7 +246,7 @@ module AssignOperation { final override string getOperator() { result = generated.getOperator() } - final override Expr getLhs() { result = generated.getLeft() } + final override LhsExpr getLhs() { result = generated.getLeft() } final override Expr getRhs() { result = generated.getRight() } } diff --git a/ql/src/codeql_ruby/ast/internal/Pattern.qll b/ql/src/codeql_ruby/ast/internal/Pattern.qll index e18788255cb..205439881d2 100644 --- a/ql/src/codeql_ruby/ast/internal/Pattern.qll +++ b/ql/src/codeql_ruby/ast/internal/Pattern.qll @@ -1,6 +1,7 @@ private import codeql_ruby.AST private import TreeSitter private import codeql_ruby.ast.internal.AST +private import codeql_ruby.ast.internal.Expr private import codeql_ruby.ast.internal.Variable private import codeql_ruby.ast.internal.Method private import codeql.Locations @@ -58,8 +59,12 @@ module Pattern { } } +module LhsExpr { + abstract class Range extends Pattern::Range, Expr::Range { } +} + module VariablePattern { - class Range extends Pattern::Range, @token_identifier { + class Range extends LhsExpr::Range, @token_identifier { override Generated::Identifier generated; string getVariableName() { result = generated.getValue() }