Skip to content

Commit dc8cd62

Browse files
committed
Ruby: Fix join orders following DB stats removal
1 parent 750f1ae commit dc8cd62

File tree

10 files changed

+155
-103
lines changed

10 files changed

+155
-103
lines changed

ruby/ql/lib/codeql/ruby/ast/internal/Literal.qll

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,12 @@ private import codeql.ruby.ast.internal.Scope
99
private import codeql.ruby.controlflow.CfgNodes
1010
private import codeql.util.Numbers
1111

12+
bindingset[t]
13+
pragma[inline_late]
14+
private string getTokenValue(Ruby::Token t) { result = t.getValue() }
15+
1216
int parseInteger(Ruby::Integer i) {
13-
exists(string s | s = i.getValue().toLowerCase().replaceAll("_", "") |
17+
exists(string s | s = getTokenValue(i).toLowerCase().replaceAll("_", "") |
1418
s.charAt(0) != "0" and
1519
result = s.toInt()
1620
or
@@ -38,7 +42,7 @@ class IntegerLiteralReal extends IntegerLiteralImpl, TIntegerLiteralReal {
3842

3943
final override int getValue() { result = parseInteger(g) }
4044

41-
final override string toString() { result = g.getValue() }
45+
final override string toString() { result = getTokenValue(g) }
4246
}
4347

4448
class IntegerLiteralSynth extends IntegerLiteralImpl, TIntegerLiteralSynth {
@@ -52,7 +56,7 @@ class IntegerLiteralSynth extends IntegerLiteralImpl, TIntegerLiteralSynth {
5256
}
5357

5458
// TODO: implement properly
55-
float parseFloat(Ruby::Float f) { result = f.getValue().toFloat() }
59+
float parseFloat(Ruby::Float f) { result = getTokenValue(f).toFloat() }
5660

5761
class FloatLiteralImpl extends Expr, TFloatLiteral {
5862
private Ruby::Float g;
@@ -61,7 +65,7 @@ class FloatLiteralImpl extends Expr, TFloatLiteral {
6165

6266
final float getValue() { result = parseFloat(g) }
6367

64-
final override string toString() { result = g.getValue() }
68+
final override string toString() { result = getTokenValue(g) }
6569
}
6670

6771
predicate isRationalValue(Ruby::Rational r, int numerator, int denominator) {
@@ -71,8 +75,8 @@ predicate isRationalValue(Ruby::Rational r, int numerator, int denominator) {
7175
exists(Ruby::Float f, string regex, string before, string after |
7276
f = r.getChild() and
7377
regex = "([^.]*)\\.(.*)" and
74-
before = f.getValue().regexpCapture(regex, 1) and
75-
after = f.getValue().regexpCapture(regex, 2) and
78+
before = getTokenValue(f).regexpCapture(regex, 1) and
79+
after = getTokenValue(f).regexpCapture(regex, 2) and
7680
numerator = before.toInt() * denominator + after.toInt() and
7781
denominator = 10.pow(after.length())
7882
)
@@ -87,14 +91,14 @@ class RationalLiteralImpl extends Expr, TRationalLiteral {
8791
isRationalValue(g, numerator, denominator)
8892
}
8993

90-
final override string toString() { result = g.getChild().(Ruby::Token).getValue() + "r" }
94+
final override string toString() { result = getTokenValue(g.getChild()) + "r" }
9195
}
9296

9397
float getComplexValue(Ruby::Complex c) {
9498
exists(int n, int d | isRationalValue(c.getChild(), n, d) and result = n.(float) / d.(float))
9599
or
96100
exists(string s |
97-
s = c.getChild().(Ruby::Token).getValue() and
101+
s = getTokenValue(c.getChild()) and
98102
result = s.prefix(s.length()).toFloat()
99103
)
100104
}
@@ -109,8 +113,8 @@ class ComplexLiteralImpl extends Expr, TComplexLiteral {
109113
}
110114

111115
final override string toString() {
112-
result = g.getChild().(Ruby::Token).getValue() + "i" or
113-
result = g.getChild().(Ruby::Rational).getChild().(Ruby::Token).getValue() + "ri"
116+
result = getTokenValue(g.getChild()) + "i" or
117+
result = getTokenValue(g.getChild().(Ruby::Rational).getChild()) + "ri"
114118
}
115119
}
116120

@@ -137,7 +141,7 @@ class TrueLiteral extends BooleanLiteralImpl, TTrueLiteral {
137141

138142
TrueLiteral() { this = TTrueLiteral(g) }
139143

140-
final override string toString() { result = g.getValue() }
144+
final override string toString() { result = getTokenValue(g) }
141145

142146
final override boolean getValue() { result = true }
143147
}
@@ -147,7 +151,7 @@ class FalseLiteral extends BooleanLiteralImpl, TFalseLiteral {
147151

148152
FalseLiteral() { this = TFalseLiteral(g) }
149153

150-
final override string toString() { result = g.getValue() }
154+
final override string toString() { result = getTokenValue(g) }
151155

152156
final override boolean getValue() { result = false }
153157
}
@@ -290,9 +294,9 @@ class RangeLiteralSynth extends RangeLiteralImpl, TRangeLiteralSynth {
290294
}
291295

292296
private string getMethodName(MethodName::Token t) {
293-
result = t.(Ruby::Token).getValue()
297+
result = getTokenValue(t)
294298
or
295-
result = t.(Ruby::Setter).getName().getValue() + "="
299+
result = getTokenValue(t.(Ruby::Setter).getName()) + "="
296300
}
297301

298302
class TokenMethodName extends Expr, TTokenMethodName {
@@ -339,9 +343,9 @@ class StringTextComponentStringOrHeredocContent extends StringTextComponentImpl,
339343

340344
final override string getValue() { result = this.getUnescapedText() }
341345

342-
final override string getRawTextImpl() { result = g.getValue() }
346+
final override string getRawTextImpl() { result = getTokenValue(g) }
343347

344-
final private string getUnescapedText() { result = unescapeTextComponent(g.getValue()) }
348+
final private string getUnescapedText() { result = unescapeTextComponent(getTokenValue(g)) }
345349
}
346350

347351
private class StringTextComponentSimpleSymbol extends StringTextComponentImpl,
@@ -352,7 +356,7 @@ private class StringTextComponentSimpleSymbol extends StringTextComponentImpl,
352356
StringTextComponentSimpleSymbol() { this = TStringTextComponentNonRegexpSimpleSymbol(g) }
353357

354358
// Tree-sitter gives us value text including the colon, which we skip.
355-
private string getSimpleSymbolValue() { result = g.getValue().suffix(1) }
359+
private string getSimpleSymbolValue() { result = getTokenValue(g).suffix(1) }
356360

357361
final override string getValue() { result = this.getSimpleSymbolValue() }
358362

@@ -366,9 +370,9 @@ private class StringTextComponentHashKeySymbol extends StringTextComponentImpl,
366370

367371
StringTextComponentHashKeySymbol() { this = TStringTextComponentNonRegexpHashKeySymbol(g) }
368372

369-
final override string getValue() { result = g.getValue() }
373+
final override string getValue() { result = getTokenValue(g) }
370374

371-
final override string getRawTextImpl() { result = g.getValue() }
375+
final override string getRawTextImpl() { result = getTokenValue(g) }
372376
}
373377

374378
bindingset[escaped]
@@ -438,9 +442,9 @@ class StringEscapeSequenceComponentImpl extends StringComponentImpl,
438442

439443
final override string getValue() { result = this.getUnescapedText() }
440444

441-
final string getRawTextImpl() { result = g.getValue() }
445+
final string getRawTextImpl() { result = getTokenValue(g) }
442446

443-
final private string getUnescapedText() { result = unescapeEscapeSequence(g.getValue()) }
447+
final private string getUnescapedText() { result = unescapeEscapeSequence(getTokenValue(g)) }
444448

445449
final override string toString() { result = this.getRawTextImpl() }
446450
}
@@ -473,10 +477,10 @@ class RegExpTextComponentImpl extends RegExpComponentImpl, TStringTextComponentR
473477
// Exclude components that are children of a free-spacing regex.
474478
// We do this because `ParseRegExp.qll` cannot handle free-spacing regexes.
475479
not this.getParent().(RegExpLiteral).hasFreeSpacingFlag() and
476-
result = g.getValue()
480+
result = getTokenValue(g)
477481
}
478482

479-
final override string toString() { result = g.getValue() }
483+
final override string toString() { result = getTokenValue(g) }
480484
}
481485

482486
class RegExpEscapeSequenceComponentImpl extends RegExpComponentImpl,
@@ -490,10 +494,10 @@ class RegExpEscapeSequenceComponentImpl extends RegExpComponentImpl,
490494
// Exclude components that are children of a free-spacing regex.
491495
// We do this because `ParseRegExp.qll` cannot handle free-spacing regexes.
492496
not this.getParent().(RegExpLiteral).hasFreeSpacingFlag() and
493-
result = g.getValue()
497+
result = getTokenValue(g)
494498
}
495499

496-
final override string toString() { result = g.getValue() }
500+
final override string toString() { result = getTokenValue(g) }
497501
}
498502

499503
class RegExpInterpolationComponentImpl extends RegExpComponentImpl,
@@ -564,7 +568,7 @@ abstract class StringlikeLiteralImpl extends Expr, TStringlikeLiteral {
564568
concat(StringComponent c, int i, string s |
565569
c = this.getComponentImpl(i) and
566570
(
567-
s = toGenerated(c).(Ruby::Token).getValue()
571+
s = getTokenValue(toGenerated(c))
568572
or
569573
not toGenerated(c) instanceof Ruby::Token and
570574
s = "#{...}"
@@ -635,7 +639,7 @@ class SimpleSymbolLiteralReal extends SimpleSymbolLiteralImpl, TSimpleSymbolLite
635639

636640
final override StringComponent getComponentImpl(int n) { n = 0 and toGenerated(result) = g }
637641

638-
final override string toString() { result = g.getValue() }
642+
final override string toString() { result = getTokenValue(g) }
639643
}
640644

641645
class SimpleSymbolLiteralSynth extends SimpleSymbolLiteralImpl, TSimpleSymbolLiteralSynth,
@@ -677,7 +681,7 @@ private class HashKeySymbolLiteral extends SymbolLiteralImpl, THashKeySymbolLite
677681

678682
final override StringComponent getComponentImpl(int n) { n = 0 and toGenerated(result) = g }
679683

680-
final override string toString() { result = ":" + g.getValue() }
684+
final override string toString() { result = ":" + getTokenValue(g) }
681685
}
682686

683687
class RegExpLiteralImpl extends StringlikeLiteralImpl, TRegExpLiteral {
@@ -701,9 +705,9 @@ class CharacterLiteralImpl extends Expr, TCharacterLiteral {
701705

702706
CharacterLiteralImpl() { this = TCharacterLiteral(g) }
703707

704-
final string getValue() { result = g.getValue() }
708+
final string getValue() { result = getTokenValue(g) }
705709

706-
final override string toString() { result = g.getValue() }
710+
final override string toString() { result = getTokenValue(g) }
707711
}
708712

709713
class HereDocImpl extends StringlikeLiteralImpl, THereDoc {
@@ -715,5 +719,5 @@ class HereDocImpl extends StringlikeLiteralImpl, THereDoc {
715719
toGenerated(result) = getHereDocBody(g).getChild(n)
716720
}
717721

718-
final override string toString() { result = g.getValue() }
722+
final override string toString() { result = getTokenValue(g) }
719723
}

ruby/ql/lib/codeql/ruby/ast/internal/Module.qll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ private TMethodOrExpr lookupMethodOrConst(Module m, string name) {
639639
// For now, we restrict the scope of top-level declarations to their file.
640640
// This may remove some plausible targets, but also removes a lot of
641641
// implausible targets
642-
if getNode(result).getEnclosingModule() instanceof Toplevel
643-
then getNode(result).getFile() = m.getADeclaration().getFile()
644-
else any()
642+
forall(File file | file = getNode(result).getEnclosingModule().(Toplevel).getFile() |
643+
file = m.getADeclaration().getFile()
644+
)
645645
}

ruby/ql/lib/codeql/ruby/ast/internal/Scope.qll

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,11 @@ cached
149149
private module Cached {
150150
/** Gets the enclosing scope of a node */
151151
cached
152-
Scope::Range scopeOf(Ruby::AstNode n) {
152+
Scope::Range scopeOfImpl(Ruby::AstNode n) {
153153
exists(Ruby::AstNode p | p = parentOf(n) |
154154
p = result
155155
or
156-
not p instanceof Scope::Range and result = scopeOf(p)
156+
not p instanceof Scope::Range and result = scopeOfImpl(p)
157157
)
158158
}
159159

@@ -163,16 +163,22 @@ private module Cached {
163163
* and synthesized scopes into account.
164164
*/
165165
cached
166-
Scope scopeOfInclSynth(AstNode n) {
166+
Scope scopeOfInclSynthImpl(AstNode n) {
167167
exists(AstNode p | p = parentOfInclSynth(n) |
168168
p = result
169169
or
170-
not p instanceof Scope and result = scopeOfInclSynth(p)
170+
not p instanceof Scope and result = scopeOfInclSynthImpl(p)
171171
)
172172
}
173173
}
174174

175-
import Cached
175+
bindingset[n]
176+
pragma[inline_late]
177+
Scope::Range scopeOf(Ruby::AstNode n) { result = Cached::scopeOfImpl(n) }
178+
179+
bindingset[n]
180+
pragma[inline_late]
181+
Scope scopeOfInclSynth(AstNode n) { result = Cached::scopeOfInclSynthImpl(n) }
176182

177183
abstract class ScopeImpl extends AstNode, TScopeType {
178184
final Scope getOuterScopeImpl() { result = scopeOfInclSynth(this) }

ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -687,26 +687,30 @@ pragma[nomagic]
687687
private CfgScope getTargetInstance(DataFlowCall call, string method) {
688688
exists(boolean exact |
689689
result = lookupInstanceMethodCall(call, method, exact) and
690-
(
691-
if result.(Method).isPrivate()
692-
then
693-
call.asCall().getReceiver().getExpr() instanceof SelfVariableAccess and
694-
// For now, we restrict the scope of top-level declarations to their file.
695-
// This may remove some plausible targets, but also removes a lot of
696-
// implausible targets
697-
(
698-
isToplevelMethodInFile(result, call.asCall().getFile()) or
699-
not isToplevelMethodInFile(result, _)
700-
)
701-
else any()
702-
) and
703-
if result.(Method).isProtected()
704-
then
705-
result = lookupMethod(call.asCall().getExpr().getEnclosingModule().getModule(), method, exact)
706-
else any()
690+
(if result.(Method).isPrivate() then result = privateFilter(call) else any()) and
691+
if result.(Method).isProtected() then result = protectedFilter(call, method, exact) else any()
707692
)
708693
}
709694

695+
bindingset[call, result]
696+
pragma[inline_late]
697+
private CfgScope privateFilter(DataFlowCall call) {
698+
call.asCall().getReceiver().getExpr() instanceof SelfVariableAccess and
699+
// For now, we restrict the scope of top-level declarations to their file.
700+
// This may remove some plausible targets, but also removes a lot of
701+
// implausible targets
702+
(
703+
isToplevelMethodInFile(result, call.asCall().getFile()) or
704+
not isToplevelMethodInFile(result, _)
705+
)
706+
}
707+
708+
bindingset[call, method, exact, result]
709+
pragma[inline_late]
710+
private CfgScope protectedFilter(DataFlowCall call, string method, boolean exact) {
711+
result = lookupMethod(call.asCall().getExpr().getEnclosingModule().getModule(), method, exact)
712+
}
713+
710714
private module TrackBlockInput implements CallGraphConstruction::Simple::InputSig {
711715
class State = Block;
712716

0 commit comments

Comments
 (0)