mirror of
https://github.com/github/codeql.git
synced 2026-05-02 12:15:17 +02:00
Merge branch 'main' into rails/render_locals_shared
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
## 0.5.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.5.0
|
||||
|
||||
### Major Analysis Improvements
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Ruby 3.2: anonymous rest and keyword rest arguments can now be passed as arguments, instead of just used in method parameters.
|
||||
3
ruby/ql/lib/change-notes/released/0.5.1.md
Normal file
3
ruby/ql/lib/change-notes/released/0.5.1.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.5.1
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.5.0
|
||||
lastReleaseVersion: 0.5.1
|
||||
|
||||
@@ -181,7 +181,10 @@ class HashSplatParameter extends NamedParameter, THashSplatParameter {
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "HashSplatParameter" }
|
||||
|
||||
final override LocalVariable getVariable() { result = TLocalVariableReal(_, _, g.getName()) }
|
||||
final override LocalVariable getVariable() {
|
||||
result = TLocalVariableReal(_, _, g.getName()) or
|
||||
result = TLocalVariableSynth(this, 0)
|
||||
}
|
||||
|
||||
final override string toString() {
|
||||
result = "**" + this.getName()
|
||||
@@ -307,7 +310,10 @@ class SplatParameter extends NamedParameter, TSplatParameter {
|
||||
|
||||
final override string getAPrimaryQlClass() { result = "SplatParameter" }
|
||||
|
||||
final override LocalVariable getVariable() { result = TLocalVariableReal(_, _, g.getName()) }
|
||||
final override LocalVariable getVariable() {
|
||||
result = TLocalVariableReal(_, _, g.getName()) or
|
||||
result = TLocalVariableSynth(this, 0)
|
||||
}
|
||||
|
||||
final override string toString() {
|
||||
result = "*" + this.getName()
|
||||
|
||||
@@ -36,7 +36,7 @@ class LocalVariable extends Variable, TLocalVariable {
|
||||
/** Gets the access where this local variable is first introduced. */
|
||||
VariableAccess getDefiningAccess() {
|
||||
result = this.(LocalVariableReal).getDefiningAccessImpl() or
|
||||
synthChild(any(BlockParameter p | this = p.getVariable()), 0, result)
|
||||
synthChild(any(NamedParameter p | this = p.getVariable()), 0, result)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,7 +120,7 @@ class VariableAccess extends Expr instanceof VariableAccessImpl {
|
||||
or
|
||||
this = any(HashPattern p).getValue(_)
|
||||
or
|
||||
synthChild(any(BlockParameter p), 0, this)
|
||||
synthChild(any(NamedParameter p), 0, this)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,10 @@ class SplatExprReal extends UnaryOperationImpl, TSplatExprReal {
|
||||
|
||||
final override string getOperatorImpl() { result = "*" }
|
||||
|
||||
final override Expr getOperandImpl() { toGenerated(result) = g.getChild() }
|
||||
final override Expr getOperandImpl() {
|
||||
toGenerated(result) = g.getChild() or
|
||||
synthChild(this, 0, result)
|
||||
}
|
||||
}
|
||||
|
||||
class SplatExprSynth extends UnaryOperationImpl, TSplatExprSynth {
|
||||
@@ -56,7 +59,10 @@ class HashSplatExprImpl extends UnaryOperationImpl, THashSplatExpr {
|
||||
|
||||
HashSplatExprImpl() { this = THashSplatExpr(g) }
|
||||
|
||||
final override Expr getOperandImpl() { toGenerated(result) = g.getChild() }
|
||||
final override Expr getOperandImpl() {
|
||||
toGenerated(result) = g.getChild() or
|
||||
synthChild(this, 0, result)
|
||||
}
|
||||
|
||||
final override string getOperatorImpl() { result = "**" }
|
||||
}
|
||||
|
||||
@@ -1317,46 +1317,62 @@ private module ImplicitHashValueSynthesis {
|
||||
|
||||
/**
|
||||
* ```rb
|
||||
* def foo(&)
|
||||
* bar(&)
|
||||
* def foo(*, **, &)
|
||||
* bar(*, **, &)
|
||||
* end
|
||||
* ```
|
||||
* desugars to,
|
||||
* ```rb
|
||||
* def foo(&__synth_0)
|
||||
* bar(&__synth_0)
|
||||
* def foo(*__synth_0, **__synth_1, &__synth_2)
|
||||
* bar(*__synth_0, **__synth_1, &__synth_2)
|
||||
* end
|
||||
* ```
|
||||
*/
|
||||
private module AnonymousBlockParameterSynth {
|
||||
private BlockParameter anonymousBlockParameter() {
|
||||
private module AnonymousParameterSynth {
|
||||
private class AnonymousParameter = TBlockParameter or THashSplatParameter or TSplatParameter;
|
||||
|
||||
private class AnonymousArgument = TBlockArgument or THashSplatExpr or TSplatExpr;
|
||||
|
||||
private AnonymousParameter anonymousParameter() {
|
||||
exists(Ruby::BlockParameter p | not exists(p.getName()) and toGenerated(result) = p)
|
||||
or
|
||||
exists(Ruby::SplatParameter p | not exists(p.getName()) and toGenerated(result) = p)
|
||||
or
|
||||
exists(Ruby::HashSplatParameter p | not exists(p.getName()) and toGenerated(result) = p)
|
||||
}
|
||||
|
||||
private BlockArgument anonymousBlockArgument() {
|
||||
private AnonymousArgument anonymousArgument() {
|
||||
exists(Ruby::BlockArgument p | not exists(p.getChild()) and toGenerated(result) = p)
|
||||
or
|
||||
exists(Ruby::SplatArgument p | not exists(p.getChild()) and toGenerated(result) = p)
|
||||
or
|
||||
exists(Ruby::HashSplatArgument p | not exists(p.getChild()) and toGenerated(result) = p)
|
||||
}
|
||||
|
||||
private class AnonymousBlockParameterSynthesis extends Synthesis {
|
||||
private class AnonymousParameterSynthesis extends Synthesis {
|
||||
final override predicate child(AstNode parent, int i, Child child) {
|
||||
i = 0 and
|
||||
parent = anonymousBlockParameter() and
|
||||
parent = anonymousParameter() and
|
||||
child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(parent, 0)))
|
||||
}
|
||||
|
||||
final override predicate localVariable(AstNode n, int i) {
|
||||
n = anonymousBlockParameter() and i = 0
|
||||
}
|
||||
final override predicate localVariable(AstNode n, int i) { n = anonymousParameter() and i = 0 }
|
||||
}
|
||||
|
||||
private class AnonymousBlockArgumentSynthesis extends Synthesis {
|
||||
private class AnonymousArgumentSynthesis extends Synthesis {
|
||||
final override predicate child(AstNode parent, int i, Child child) {
|
||||
i = 0 and
|
||||
parent = anonymousBlockArgument() and
|
||||
exists(BlockParameter param |
|
||||
param = anonymousBlockParameter() and
|
||||
parent = anonymousArgument() and
|
||||
exists(AnonymousParameter param |
|
||||
param = anonymousParameter() and
|
||||
scopeOf(toGenerated(parent)).getEnclosingMethod() = scopeOf(toGenerated(param)) and
|
||||
child = SynthChild(LocalVariableAccessSynthKind(TLocalVariableSynth(param, 0)))
|
||||
|
|
||||
param instanceof TBlockParameter and parent instanceof TBlockArgument
|
||||
or
|
||||
param instanceof TSplatParameter and parent instanceof TSplatExpr
|
||||
or
|
||||
param instanceof THashSplatParameter and parent instanceof THashSplatExpr
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -875,10 +875,10 @@ module Ruby {
|
||||
final override string getAPrimaryQlClass() { result = "HashSplatArgument" }
|
||||
|
||||
/** Gets the child of this node. */
|
||||
final UnderscoreArg getChild() { ruby_hash_splat_argument_def(this, result) }
|
||||
final UnderscoreArg getChild() { ruby_hash_splat_argument_child(this, result) }
|
||||
|
||||
/** Gets a field or child node of this node. */
|
||||
final override AstNode getAFieldOrChild() { ruby_hash_splat_argument_def(this, result) }
|
||||
final override AstNode getAFieldOrChild() { ruby_hash_splat_argument_child(this, result) }
|
||||
}
|
||||
|
||||
/** A class representing `hash_splat_nil` tokens. */
|
||||
@@ -1572,10 +1572,10 @@ module Ruby {
|
||||
final override string getAPrimaryQlClass() { result = "SplatArgument" }
|
||||
|
||||
/** Gets the child of this node. */
|
||||
final UnderscoreArg getChild() { ruby_splat_argument_def(this, result) }
|
||||
final UnderscoreArg getChild() { ruby_splat_argument_child(this, result) }
|
||||
|
||||
/** Gets a field or child node of this node. */
|
||||
final override AstNode getAFieldOrChild() { ruby_splat_argument_def(this, result) }
|
||||
final override AstNode getAFieldOrChild() { ruby_splat_argument_child(this, result) }
|
||||
}
|
||||
|
||||
/** A class representing `splat_parameter` nodes. */
|
||||
|
||||
@@ -139,7 +139,7 @@ abstract class SummarizedCallable extends LibraryCallable, Impl::Public::Summari
|
||||
DataFlow::ParameterNode getParameter(string s) {
|
||||
exists(ParameterPosition pos |
|
||||
DataFlowImplCommon::parameterNode(result, TLibraryCallable(this), pos) and
|
||||
s = getParameterPositionCsv(pos)
|
||||
s = getParameterPosition(pos)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,11 @@ module Public {
|
||||
)
|
||||
or
|
||||
exists(ReturnKind rk | this = TReturnSummaryComponent(rk) and result = "return (" + rk + ")")
|
||||
or
|
||||
exists(SummaryComponent::SyntheticGlobal sg |
|
||||
this = TSyntheticGlobalSummaryComponent(sg) and
|
||||
result = "synthetic global (" + sg + ")"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,24 +164,24 @@ module Public {
|
||||
SummaryComponentStack return(ReturnKind rk) { result = singleton(SummaryComponent::return(rk)) }
|
||||
}
|
||||
|
||||
private predicate noComponentSpecificCsv(SummaryComponent sc) {
|
||||
not exists(getComponentSpecificCsv(sc))
|
||||
private predicate noComponentSpecific(SummaryComponent sc) {
|
||||
not exists(getComponentSpecific(sc))
|
||||
}
|
||||
|
||||
/** Gets a textual representation of this component used for flow summaries. */
|
||||
private string getComponentCsv(SummaryComponent sc) {
|
||||
result = getComponentSpecificCsv(sc)
|
||||
private string getComponent(SummaryComponent sc) {
|
||||
result = getComponentSpecific(sc)
|
||||
or
|
||||
noComponentSpecificCsv(sc) and
|
||||
noComponentSpecific(sc) and
|
||||
(
|
||||
exists(ArgumentPosition pos |
|
||||
sc = TParameterSummaryComponent(pos) and
|
||||
result = "Parameter[" + getArgumentPositionCsv(pos) + "]"
|
||||
result = "Parameter[" + getArgumentPosition(pos) + "]"
|
||||
)
|
||||
or
|
||||
exists(ParameterPosition pos |
|
||||
sc = TArgumentSummaryComponent(pos) and
|
||||
result = "Argument[" + getParameterPositionCsv(pos) + "]"
|
||||
result = "Argument[" + getParameterPosition(pos) + "]"
|
||||
)
|
||||
or
|
||||
sc = TReturnSummaryComponent(getReturnValueKind()) and result = "ReturnValue"
|
||||
@@ -184,16 +189,16 @@ module Public {
|
||||
}
|
||||
|
||||
/** Gets a textual representation of this stack used for flow summaries. */
|
||||
string getComponentStackCsv(SummaryComponentStack stack) {
|
||||
string getComponentStack(SummaryComponentStack stack) {
|
||||
exists(SummaryComponent head, SummaryComponentStack tail |
|
||||
head = stack.head() and
|
||||
tail = stack.tail() and
|
||||
result = getComponentStackCsv(tail) + "." + getComponentCsv(head)
|
||||
result = getComponentStack(tail) + "." + getComponent(head)
|
||||
)
|
||||
or
|
||||
exists(SummaryComponent c |
|
||||
stack = TSingletonSummaryComponentStack(c) and
|
||||
result = getComponentCsv(c)
|
||||
result = getComponent(c)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1217,8 +1222,8 @@ module Private {
|
||||
c.relevantSummary(input, output, preservesValue) and
|
||||
csv =
|
||||
c.getCallableCsv() // Callable information
|
||||
+ getComponentStackCsv(input) + ";" // input
|
||||
+ getComponentStackCsv(output) + ";" // output
|
||||
+ getComponentStack(input) + ";" // input
|
||||
+ getComponentStack(output) + ";" // output
|
||||
+ renderKind(preservesValue) + ";" // kind
|
||||
+ renderProvenance(c) // provenance
|
||||
)
|
||||
|
||||
@@ -139,10 +139,10 @@ SummaryComponent interpretComponentSpecific(AccessPathToken c) {
|
||||
}
|
||||
|
||||
/** Gets the textual representation of a summary component in the format used for flow summaries. */
|
||||
string getComponentSpecificCsv(SummaryComponent sc) { none() }
|
||||
string getComponentSpecific(SummaryComponent sc) { none() }
|
||||
|
||||
/** Gets the textual representation of a parameter position in the format used for flow summaries. */
|
||||
string getParameterPositionCsv(ParameterPosition pos) {
|
||||
string getParameterPosition(ParameterPosition pos) {
|
||||
exists(int i |
|
||||
pos.isPositional(i) and
|
||||
result = i.toString()
|
||||
@@ -172,7 +172,7 @@ string getParameterPositionCsv(ParameterPosition pos) {
|
||||
}
|
||||
|
||||
/** Gets the textual representation of an argument position in the format used for flow summaries. */
|
||||
string getArgumentPositionCsv(ArgumentPosition pos) {
|
||||
string getArgumentPosition(ArgumentPosition pos) {
|
||||
pos.isSelf() and result = "self"
|
||||
or
|
||||
pos.isBlock() and result = "block"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/ruby-all
|
||||
version: 0.5.1-dev
|
||||
version: 0.5.2-dev
|
||||
groups: ruby
|
||||
extractor: ruby
|
||||
dbscheme: ruby.dbscheme
|
||||
|
||||
@@ -661,9 +661,13 @@ ruby_hash_pattern_def(
|
||||
unique int id: @ruby_hash_pattern
|
||||
);
|
||||
|
||||
ruby_hash_splat_argument_child(
|
||||
unique int ruby_hash_splat_argument: @ruby_hash_splat_argument ref,
|
||||
unique int child: @ruby_underscore_arg ref
|
||||
);
|
||||
|
||||
ruby_hash_splat_argument_def(
|
||||
unique int id: @ruby_hash_splat_argument,
|
||||
int child: @ruby_underscore_arg ref
|
||||
unique int id: @ruby_hash_splat_argument
|
||||
);
|
||||
|
||||
ruby_hash_splat_parameter_name(
|
||||
@@ -1112,9 +1116,13 @@ ruby_singleton_method_def(
|
||||
int object: @ruby_singleton_method_object_type ref
|
||||
);
|
||||
|
||||
ruby_splat_argument_child(
|
||||
unique int ruby_splat_argument: @ruby_splat_argument ref,
|
||||
unique int child: @ruby_underscore_arg ref
|
||||
);
|
||||
|
||||
ruby_splat_argument_def(
|
||||
unique int id: @ruby_splat_argument,
|
||||
int child: @ruby_underscore_arg ref
|
||||
unique int id: @ruby_splat_argument
|
||||
);
|
||||
|
||||
ruby_splat_parameter_name(
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,6 @@
|
||||
description: Update grammar
|
||||
compatibility: full
|
||||
ruby_splat_argument_def.rel: reorder ruby_splat_argument_def.rel ( int id, int child) id
|
||||
ruby_splat_argument_child.rel: reorder ruby_splat_argument_def.rel ( int id, int child) id child
|
||||
ruby_hash_splat_argument_def.rel: reorder ruby_hash_splat_argument_def.rel ( int id, int child) id
|
||||
ruby_hash_splat_argument_child.rel: reorder ruby_hash_splat_argument_def.rel ( int id, int child) id child
|
||||
Reference in New Issue
Block a user