diff --git a/ql/src/codeql_ruby/ast/Expr.qll b/ql/src/codeql_ruby/ast/Expr.qll index 29ea9e12cdb..a46d4f33627 100644 --- a/ql/src/codeql_ruby/ast/Expr.qll +++ b/ql/src/codeql_ruby/ast/Expr.qll @@ -110,6 +110,12 @@ class StringLiteral extends Literal, @string__ { class SymbolLiteral extends Literal { final override SymbolLiteral::Range range; + SymbolLiteral() { + not any(UndefStmt u).getAMethodName() = this and + not any(AliasStmt a).getNewName() = this and + not any(AliasStmt a).getOldName() = this + } + final override string getAPrimaryQlClass() { result = "SymbolLiteral" } } diff --git a/ql/src/codeql_ruby/ast/internal/Expr.qll b/ql/src/codeql_ruby/ast/internal/Expr.qll index 6a2f278b5f8..68bc63e180d 100644 --- a/ql/src/codeql_ruby/ast/internal/Expr.qll +++ b/ql/src/codeql_ruby/ast/internal/Expr.qll @@ -173,27 +173,33 @@ module SymbolLiteral { } module MethodName { - class Range extends Literal::Range, @underscore_method_name { - final override Generated::UnderscoreMethodName generated; + private class TokenTypes = + @setter or @token_class_variable or @token_constant or @token_global_variable or + @token_identifier or @token_instance_variable or @token_operator; + abstract class Range extends Literal::Range, @underscore_method_name { Range() { exists(Generated::Undef u | u.getChild(_) = generated) or exists(Generated::Alias a | a.getName() = generated or a.getAlias() = generated) } + } + + private class TokenMethodName extends MethodName::Range, TokenTypes { + final override Generated::UnderscoreMethodName generated; final override string getValueText() { - result = generated.(Generated::Token).getValue() or - result = generated.(SymbolLiteral).getValueText() or + result = generated.(Generated::Token).getValue() + or result = generated.(Generated::Setter).getName().getValue() + "=" } - - final override string toString() { - result = getValueText() - or - not exists(getValueText()) and result = generated.(SymbolLiteral).toString() - } } + + private class SimpleSymbolMethodName extends MethodName::Range, SymbolLiteral::SimpleSymbolRange, + @token_simple_symbol { } + + private class DelimitedSymbolMethodName extends MethodName::Range, + SymbolLiteral::DelimitedSymbolRange, @delimited_symbol { } } module StmtSequence { diff --git a/ql/src/codeql_ruby/ast/internal/Statement.qll b/ql/src/codeql_ruby/ast/internal/Statement.qll index 35b11030591..7c0aee758bd 100644 --- a/ql/src/codeql_ruby/ast/internal/Statement.qll +++ b/ql/src/codeql_ruby/ast/internal/Statement.qll @@ -39,9 +39,9 @@ module AliasStmt { class Range extends Stmt::Range, @alias { final override Generated::Alias generated; - final MethodName getNewName() { result = generated.getAlias() } + final MethodName getNewName() { result = generated.getName() } - final MethodName getOldName() { result = generated.getName() } + final MethodName getOldName() { result = generated.getAlias() } final override string toString() { result = "alias ..." } } diff --git a/ql/test/library-tests/ast/misc/misc.expected b/ql/test/library-tests/ast/misc/misc.expected index 300de9c39cb..3f2c98f43fd 100644 --- a/ql/test/library-tests/ast/misc/misc.expected +++ b/ql/test/library-tests/ast/misc/misc.expected @@ -1,32 +1,21 @@ undef -| misc.rb:3:1:3:30 | undef ... | 0 | misc.rb:3:7:3:9 | foo | MethodName | -| misc.rb:3:1:3:30 | undef ... | 1 | misc.rb:3:12:3:15 | :foo | MethodName | -| misc.rb:3:1:3:30 | undef ... | 1 | misc.rb:3:12:3:15 | :foo | SymbolLiteral | -| misc.rb:3:1:3:30 | undef ... | 1 | misc.rb:3:12:3:15 | foo | MethodName | -| misc.rb:3:1:3:30 | undef ... | 1 | misc.rb:3:12:3:15 | foo | SymbolLiteral | -| misc.rb:3:1:3:30 | undef ... | 2 | misc.rb:3:18:3:21 | foo= | MethodName | -| misc.rb:3:1:3:30 | undef ... | 3 | misc.rb:3:24:3:25 | [] | MethodName | -| misc.rb:3:1:3:30 | undef ... | 4 | misc.rb:3:28:3:30 | []= | MethodName | -| misc.rb:4:1:4:19 | undef ... | 0 | misc.rb:4:7:4:19 | :"foo_#{...}" | MethodName | -| misc.rb:4:1:4:19 | undef ... | 0 | misc.rb:4:7:4:19 | :"foo_#{...}" | SymbolLiteral | -| misc.rb:5:1:5:35 | undef ... | 0 | misc.rb:5:7:5:9 | nil | MethodName | -| misc.rb:5:1:5:35 | undef ... | 1 | misc.rb:5:12:5:15 | true | MethodName | -| misc.rb:5:1:5:35 | undef ... | 2 | misc.rb:5:18:5:22 | false | MethodName | -| misc.rb:5:1:5:35 | undef ... | 3 | misc.rb:5:25:5:29 | super | MethodName | -| misc.rb:5:1:5:35 | undef ... | 4 | misc.rb:5:32:5:35 | self | MethodName | +| misc.rb:3:1:3:30 | undef ... | 0 | misc.rb:3:7:3:9 | foo | foo | MethodName | +| misc.rb:3:1:3:30 | undef ... | 1 | misc.rb:3:12:3:15 | :foo | foo | MethodName | +| misc.rb:3:1:3:30 | undef ... | 2 | misc.rb:3:18:3:21 | foo= | foo= | MethodName | +| misc.rb:3:1:3:30 | undef ... | 3 | misc.rb:3:24:3:25 | [] | [] | MethodName | +| misc.rb:3:1:3:30 | undef ... | 4 | misc.rb:3:28:3:30 | []= | []= | MethodName | +| misc.rb:4:1:4:19 | undef ... | 0 | misc.rb:4:7:4:19 | :"foo_#{...}" | (none) | MethodName | +| misc.rb:5:1:5:35 | undef ... | 0 | misc.rb:5:7:5:9 | nil | nil | MethodName | +| misc.rb:5:1:5:35 | undef ... | 1 | misc.rb:5:12:5:15 | true | true | MethodName | +| misc.rb:5:1:5:35 | undef ... | 2 | misc.rb:5:18:5:22 | false | false | MethodName | +| misc.rb:5:1:5:35 | undef ... | 3 | misc.rb:5:25:5:29 | super | super | MethodName | +| misc.rb:5:1:5:35 | undef ... | 4 | misc.rb:5:32:5:35 | self | self | MethodName | alias -| misc.rb:7:1:7:14 | alias ... | new | misc.rb:7:11:7:14 | :bar | MethodName | -| misc.rb:7:1:7:14 | alias ... | new | misc.rb:7:11:7:14 | :bar | SymbolLiteral | -| misc.rb:7:1:7:14 | alias ... | new | misc.rb:7:11:7:14 | bar | MethodName | -| misc.rb:7:1:7:14 | alias ... | new | misc.rb:7:11:7:14 | bar | SymbolLiteral | -| misc.rb:7:1:7:14 | alias ... | old | misc.rb:7:7:7:9 | foo | MethodName | -| misc.rb:8:1:8:14 | alias ... | new | misc.rb:8:12:8:14 | []= | MethodName | -| misc.rb:8:1:8:14 | alias ... | old | misc.rb:8:7:8:10 | foo= | MethodName | -| misc.rb:9:1:9:16 | alias ... | new | misc.rb:9:13:9:16 | self | MethodName | -| misc.rb:9:1:9:16 | alias ... | old | misc.rb:9:7:9:11 | super | MethodName | -| misc.rb:10:1:10:24 | alias ... | new | misc.rb:10:19:10:24 | :foo | MethodName | -| misc.rb:10:1:10:24 | alias ... | new | misc.rb:10:19:10:24 | :foo | SymbolLiteral | -| misc.rb:10:1:10:24 | alias ... | new | misc.rb:10:19:10:24 | foo | MethodName | -| misc.rb:10:1:10:24 | alias ... | new | misc.rb:10:19:10:24 | foo | SymbolLiteral | -| misc.rb:10:1:10:24 | alias ... | old | misc.rb:10:7:10:17 | :"\\n#{...}" | MethodName | -| misc.rb:10:1:10:24 | alias ... | old | misc.rb:10:7:10:17 | :"\\n#{...}" | SymbolLiteral | +| misc.rb:7:1:7:14 | alias ... | new | misc.rb:7:7:7:9 | new | new | MethodName | +| misc.rb:7:1:7:14 | alias ... | old | misc.rb:7:11:7:14 | :old | old | MethodName | +| misc.rb:8:1:8:14 | alias ... | new | misc.rb:8:7:8:10 | foo= | foo= | MethodName | +| misc.rb:8:1:8:14 | alias ... | old | misc.rb:8:12:8:14 | []= | []= | MethodName | +| misc.rb:9:1:9:16 | alias ... | new | misc.rb:9:7:9:11 | super | super | MethodName | +| misc.rb:9:1:9:16 | alias ... | old | misc.rb:9:13:9:16 | self | self | MethodName | +| misc.rb:10:1:10:24 | alias ... | new | misc.rb:10:7:10:17 | :"\\n#{...}" | (none) | MethodName | +| misc.rb:10:1:10:24 | alias ... | old | misc.rb:10:19:10:24 | :foo | foo | MethodName | diff --git a/ql/test/library-tests/ast/misc/misc.ql b/ql/test/library-tests/ast/misc/misc.ql index 835c30189b3..788a8593cdd 100644 --- a/ql/test/library-tests/ast/misc/misc.ql +++ b/ql/test/library-tests/ast/misc/misc.ql @@ -1,12 +1,20 @@ import ruby -query predicate undef(UndefStmt u, int i, MethodName m, string pClass) { - pClass = m.getAPrimaryQlClass() and - u.getMethodName(i) = m +private string getValueText(MethodName m) { + result = m.getValueText() + or + not exists(m.getValueText()) and result = "(none)" } -query predicate alias(AliasStmt a, string prop, MethodName m, string pClass) { +query predicate undef(UndefStmt u, int i, MethodName m, string name, string pClass) { pClass = m.getAPrimaryQlClass() and + u.getMethodName(i) = m and + name = getValueText(m) +} + +query predicate alias(AliasStmt a, string prop, MethodName m, string name, string pClass) { + pClass = m.getAPrimaryQlClass() and + name = getValueText(m) and ( a.getOldName() = m and prop = "old" or diff --git a/ql/test/library-tests/ast/misc/misc.rb b/ql/test/library-tests/ast/misc/misc.rb index 7d1fa31817b..6f7fabec245 100644 --- a/ql/test/library-tests/ast/misc/misc.rb +++ b/ql/test/library-tests/ast/misc/misc.rb @@ -4,7 +4,7 @@ undef foo, :foo, foo=, [], []= undef :"foo_#{bar}" undef nil, true, false, super, self -alias foo :bar +alias new :old alias foo= []= alias super self alias :"\n#{bar}" :"foo"