Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a213982

Browse files
authoredAug 22, 2024··
Merge pull request #17222 from hvitved/ruby/hash-splat-param-arg-matching
Ruby: Rework (hash) splat argument/parameter matching
2 parents 09aca6b + cb1b1da commit a213982

File tree

13 files changed

+1040
-1993
lines changed

13 files changed

+1040
-1993
lines changed
 

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

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,11 @@ private module Cached {
563563
THashSplatArgumentPosition() or
564564
TSynthHashSplatArgumentPosition() or
565565
TSplatArgumentPosition(int pos) { exists(Call c | c.getArgument(pos) instanceof SplatExpr) } or
566-
TSynthSplatArgumentPosition() or
566+
TSynthSplatArgumentPosition(int actualSplatPos) {
567+
actualSplatPos = -1 // represents no actual splat
568+
or
569+
exists(Call c | c.getArgument(actualSplatPos) instanceof SplatExpr)
570+
} or
567571
TAnyArgumentPosition() or
568572
TAnyKeywordArgumentPosition()
569573

@@ -590,11 +594,15 @@ private module Cached {
590594
THashSplatParameterPosition() or
591595
TSynthHashSplatParameterPosition() or
592596
TSplatParameterPosition(int pos) {
593-
pos = 0
597+
pos = 0 // needed for flow summaries
594598
or
595599
exists(Parameter p | p.getPosition() = pos and p instanceof SplatParameter)
596600
} or
597-
TSynthSplatParameterPosition() or
601+
TSynthSplatParameterPosition(int actualSplatPos) {
602+
actualSplatPos = -1 // represents no actual splat
603+
or
604+
exists(Callable c | c.getParameter(actualSplatPos) instanceof SplatParameter)
605+
} or
598606
TAnyParameterPosition() or
599607
TAnyKeywordParameterPosition()
600608
}
@@ -1383,8 +1391,14 @@ class ParameterPosition extends TParameterPosition {
13831391
/** Holds if this position represents a splat parameter at position `n`. */
13841392
predicate isSplat(int n) { this = TSplatParameterPosition(n) }
13851393

1386-
/** Holds if this position represents a synthetic splat parameter. */
1387-
predicate isSynthSplat() { this = TSynthSplatParameterPosition() }
1394+
/**
1395+
* Holds if this position represents a synthetic splat parameter.
1396+
*
1397+
* `actualSplatPos` indicates the position of the (unique) actual splat
1398+
* parameter belonging to the same method, with `-1` representing no actual
1399+
* splat parameter.
1400+
*/
1401+
predicate isSynthSplat(int actualSplatPos) { this = TSynthSplatParameterPosition(actualSplatPos) }
13881402

13891403
/**
13901404
* Holds if this position represents any parameter, except `self` parameters. This
@@ -1419,7 +1433,11 @@ class ParameterPosition extends TParameterPosition {
14191433
or
14201434
exists(int pos | this.isSplat(pos) and result = "* (position " + pos + ")")
14211435
or
1422-
this.isSynthSplat() and result = "synthetic *"
1436+
exists(int actualSplatPos, string suffix |
1437+
this.isSynthSplat(actualSplatPos) and
1438+
result = "synthetic *" + suffix and
1439+
if actualSplatPos = -1 then suffix = "" else suffix = " (actual at " + actualSplatPos + ")"
1440+
)
14231441
}
14241442
}
14251443

@@ -1458,8 +1476,14 @@ class ArgumentPosition extends TArgumentPosition {
14581476
/** Holds if this position represents a splat argument at position `n`. */
14591477
predicate isSplat(int n) { this = TSplatArgumentPosition(n) }
14601478

1461-
/** Holds if this position represents a synthetic splat argument. */
1462-
predicate isSynthSplat() { this = TSynthSplatArgumentPosition() }
1479+
/**
1480+
* Holds if this position represents a synthetic splat argument.
1481+
*
1482+
* `actualSplatPos` indicates the position of the (unique) actual splat
1483+
* argument belonging to the same call, with `-1` representing no actual
1484+
* splat argument.
1485+
*/
1486+
predicate isSynthSplat(int actualSplatPos) { this = TSynthSplatArgumentPosition(actualSplatPos) }
14631487

14641488
/** Gets a textual representation of this position. */
14651489
string toString() {
@@ -1483,7 +1507,11 @@ class ArgumentPosition extends TArgumentPosition {
14831507
or
14841508
exists(int pos | this.isSplat(pos) and result = "* (position " + pos + ")")
14851509
or
1486-
this.isSynthSplat() and result = "synthetic *"
1510+
exists(int actualSplatPos, string suffix |
1511+
this.isSynthSplat(actualSplatPos) and
1512+
result = "synthetic *" + suffix and
1513+
if actualSplatPos = -1 then suffix = "" else suffix = " (actual at " + actualSplatPos + ")"
1514+
)
14871515
}
14881516
}
14891517

@@ -1517,19 +1545,29 @@ predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) {
15171545
exists(string name | ppos.isKeyword(name) and apos.isKeyword(name))
15181546
or
15191547
(ppos.isHashSplat() or ppos.isSynthHashSplat()) and
1520-
(apos.isHashSplat() or apos.isSynthHashSplat())
1548+
(apos.isHashSplat() or apos.isSynthHashSplat()) and
1549+
// prevent synthetic hash-splat parameters from matching synthetic hash-splat
1550+
// arguments when direct keyword matching is possible
1551+
not (ppos.isSynthHashSplat() and apos.isSynthHashSplat())
15211552
or
15221553
exists(int pos |
15231554
(
15241555
ppos.isSplat(pos)
15251556
or
1526-
ppos.isSynthSplat() and pos = 0
1557+
ppos.isSynthSplat(_) and
1558+
pos = 0
15271559
) and
15281560
(
15291561
apos.isSplat(pos)
15301562
or
1531-
apos.isSynthSplat() and pos = 0
1563+
apos.isSynthSplat(_) and pos = 0
15321564
)
1565+
) and
1566+
// prevent synthetic splat parameters from matching synthetic splat arguments
1567+
// when direct positional matching is possible
1568+
not exists(int actualSplatPos |
1569+
ppos.isSynthSplat(actualSplatPos) and
1570+
apos.isSynthSplat(actualSplatPos)
15331571
)
15341572
or
15351573
ppos.isAny() and argumentPositionIsNotSelf(apos)

‎ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll

Lines changed: 42 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,9 @@ private class Argument extends CfgNodes::ExprCfgNode {
195195
not this.getExpr().(Pair).getKey().getConstantValue().isSymbol(_) and
196196
not this.getExpr() instanceof HashSplatExpr and
197197
not this.getExpr() instanceof SplatExpr and
198-
arg.isPositional(i)
198+
arg.isPositional(i) and
199+
// There are no splat arguments before the positional argument
200+
not splatArgumentAt(call, any(int j | j < i))
199201
)
200202
or
201203
exists(CfgNodes::ExprNodes::PairCfgNode p |
@@ -217,7 +219,9 @@ private class Argument extends CfgNodes::ExprCfgNode {
217219
exists(int pos |
218220
this = call.getArgument(pos) and
219221
this.getExpr() instanceof SplatExpr and
220-
arg.isSplat(pos)
222+
arg.isSplat(pos) and
223+
// There are no earlier splat arguments
224+
not splatArgumentAt(call, any(int j | j < pos))
221225
)
222226
or
223227
this = call.getAnArgument() and
@@ -432,7 +436,7 @@ private predicate splatParameterAt(Callable c, int pos) {
432436
}
433437

434438
private predicate splatArgumentAt(CfgNodes::ExprNodes::CallCfgNode c, int pos) {
435-
exists(Argument arg, ArgumentPosition apos | arg.isArgumentOf(c, apos) and apos.isSplat(pos))
439+
c.getArgument(pos).getExpr() instanceof SplatExpr
436440
}
437441

438442
/** A collection of cached types and predicates to be evaluated in the same stage. */
@@ -661,8 +665,8 @@ private module Cached {
661665
name = [input, output].regexpFind("(?<=(^|\\.)Field\\[)[^\\]]+(?=\\])", _, _).trim()
662666
)
663667
} or
664-
TSplatContent(int i, Boolean shifted) { i in [0 .. 10] } or
665-
THashSplatContent(ConstantValue::ConstantSymbolValue cv) or
668+
deprecated TSplatContent(int i, Boolean shifted) { i in [0 .. 10] } or
669+
deprecated THashSplatContent(ConstantValue::ConstantSymbolValue cv) or
666670
TCapturedVariableContent(VariableCapture::CapturedVariable v) or
667671
// Only used by type-tracking
668672
TAttributeName(string name) { name = any(SetterMethodCall c).getTargetName() }
@@ -686,29 +690,16 @@ private module Cached {
686690
TUnknownElementContentApprox() or
687691
TKnownIntegerElementContentApprox() or
688692
TKnownElementContentApprox(string approx) { approx = approxKnownElementIndex(_) } or
689-
TSplatContentApprox(Boolean shifted) or
690-
THashSplatContentApprox(string approx) { approx = approxKnownElementIndex(_) } or
691693
TNonElementContentApprox(Content c) { not c instanceof Content::ElementContent } or
692694
TCapturedVariableContentApprox(VariableCapture::CapturedVariable v)
693695

694696
cached
695697
newtype TDataFlowType =
696698
TLambdaDataFlowType(Callable c) { c = any(LambdaSelfReferenceNode n).getCallable() } or
697-
// In order to reduce the set of cons-candidates, we annotate all implicit (hash) splat
698-
// creations with the name of the method that they are passed into. This includes
699-
// array/hash literals as well (where the name is simply `[]`), because of how they
700-
// are modeled (see `Array.qll` and `Hash.qll`).
701-
TSynthHashSplatArgumentType(string methodName) {
702-
methodName = any(SynthHashSplatArgumentNode n).getMethodName()
703-
} or
704-
TSynthSplatArgumentType(string methodName) {
705-
methodName = any(SynthSplatArgumentNode n).getMethodName()
706-
} or
707699
TUnknownDataFlowType()
708700
}
709701

710-
class TElementContent =
711-
TKnownElementContent or TUnknownElementContent or TSplatContent or THashSplatContent;
702+
class TElementContent = TKnownElementContent or TUnknownElementContent;
712703

713704
import Cached
714705

@@ -933,7 +924,12 @@ private module ParameterNodes {
933924

934925
override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
935926
exists(Callable callable | callable = c.asCfgScope() |
936-
exists(int i | pos.isPositional(i) and callable.getParameter(i) = parameter |
927+
exists(int i |
928+
pos.isPositional(i) and
929+
callable.getParameter(i) = parameter and
930+
// There are no splat parameters before the positional parameter
931+
not splatParameterAt(callable, any(int m | m < i))
932+
|
937933
parameter instanceof SimpleParameter
938934
or
939935
parameter instanceof OptionalParameter
@@ -952,7 +948,9 @@ private module ParameterNodes {
952948
parameter = callable.getParameter(n).(SplatParameter) and
953949
pos.isSplat(n) and
954950
// There are no positional parameters after the splat
955-
not exists(SimpleParameter p, int m | m > n | p = callable.getParameter(m))
951+
not exists(SimpleParameter p, int m | m > n | p = callable.getParameter(m)) and
952+
// There are no earlier splat parameters
953+
not splatParameterAt(callable, any(int m | m < n))
956954
)
957955
or
958956
parameter = callable.getAParameter().(BlockParameter) and
@@ -1123,18 +1121,6 @@ private module ParameterNodes {
11231121
*
11241122
* by adding read steps out of the synthesized parameter node to the relevant
11251123
* keyword parameters.
1126-
*
1127-
* In order to avoid redundancy (and improve performance) in cases like
1128-
*
1129-
* ```rb
1130-
* foo(p1: taint(1), p2: taint(2))
1131-
* ```
1132-
*
1133-
* where direct keyword matching is possible, we use a special `HashSplatContent`
1134-
* (instead of reusing `KnownElementContent`) when we construct a synthesized hash
1135-
* splat argument (`SynthHashSplatArgumentNode`) at the call site, and then only
1136-
* add read steps out of this node for actual hash-splat arguments (which will use
1137-
* a normal `KnownElementContent`).
11381124
*/
11391125
class SynthHashSplatParameterNode extends ParameterNodeImpl, TSynthHashSplatParameterNode {
11401126
private DataFlowCallable callable;
@@ -1188,18 +1174,6 @@ private module ParameterNodes {
11881174
* by adding read steps out of the synthesized parameter node to the relevant
11891175
* positional parameters.
11901176
*
1191-
* In order to avoid redundancy (and improve performance) in cases like
1192-
*
1193-
* ```rb
1194-
* foo(a, b, c)
1195-
* ```
1196-
*
1197-
* where direct positional matching is possible, we use a special `SplatContent`
1198-
* (instead of reusing `KnownElementContent`) when we construct a synthesized
1199-
* splat argument (`SynthSplatArgumentNode`) at the call site, and then only
1200-
* add read steps out of this node for actual splat arguments (which will use
1201-
* `KnownElementContent` or `TSplatContent(_, true)`).
1202-
*
12031177
* We don't yet correctly handle cases where a positional argument follows the
12041178
* splat argument, e.g. in
12051179
*
@@ -1217,12 +1191,8 @@ private module ParameterNodes {
12171191
/** Holds if a read-step should be added into parameter `p`. */
12181192
predicate readInto(ParameterNode p, ContentSet c) {
12191193
exists(int n |
1220-
isParameterNode(p, callable, any(ParameterPosition pos | pos.isPositional(n))) and
1221-
not exists(int i | splatParameterAt(callable.asCfgScope(), i) and i < n)
1194+
isParameterNode(p, callable, any(ParameterPosition pos | pos.isPositional(n)))
12221195
|
1223-
// Important: do not include `TSplatContent(_, false)` here, as normal parameter matching is possible
1224-
c = getSplatContent(n, true)
1225-
or
12261196
c = getArrayContent(n)
12271197
or
12281198
c.isSingleton(TUnknownElementContent())
@@ -1232,7 +1202,13 @@ private module ParameterNodes {
12321202
final override Parameter getParameter() { none() }
12331203

12341204
final override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
1235-
c = callable and pos.isSynthSplat()
1205+
c = callable and
1206+
exists(int actualSplat | pos.isSynthSplat(actualSplat) |
1207+
exists(TSynthSplatParameterShiftNode(c, actualSplat, _))
1208+
or
1209+
not exists(TSynthSplatParameterShiftNode(c, _, _)) and
1210+
actualSplat = -1
1211+
)
12361212
}
12371213

12381214
final override CfgScope getCfgScope() { result = callable.asCfgScope() }
@@ -1271,11 +1247,7 @@ private module ParameterNodes {
12711247
*/
12721248
predicate readFrom(SynthSplatParameterNode synthSplat, ContentSet cs) {
12731249
synthSplat.isParameterOf(callable, _) and
1274-
(
1275-
cs = getSplatContent(pos + splatPos, _)
1276-
or
1277-
cs = getArrayContent(pos + splatPos)
1278-
)
1250+
cs = getArrayContent(pos + splatPos)
12791251
}
12801252

12811253
/**
@@ -1454,24 +1426,7 @@ module ArgumentNodes {
14541426
not cv.isSymbol(_)
14551427
)
14561428
|
1457-
if call instanceof CfgNodes::ExprNodes::HashLiteralCfgNode
1458-
then
1459-
/*
1460-
* Needed for cases like
1461-
*
1462-
* ```rb
1463-
* hash = { a: taint, b: safe }
1464-
*
1465-
* def foo(a:, b:)
1466-
* sink(a)
1467-
* end
1468-
*
1469-
* foo(**hash)
1470-
* ```
1471-
*/
1472-
1473-
c.isSingleton(Content::getElementContent(cv))
1474-
else c.isSingleton(THashSplatContent(cv))
1429+
c.isSingleton(Content::getElementContent(cv))
14751430
)
14761431
}
14771432

@@ -1506,31 +1461,10 @@ module ArgumentNodes {
15061461
* `call`, into a synthetic splat argument.
15071462
*/
15081463
predicate synthSplatStore(CfgNodes::ExprNodes::CallCfgNode call, Argument arg, ContentSet c) {
1509-
exists(int n |
1510-
exists(ArgumentPosition pos |
1511-
arg.isArgumentOf(call, pos) and
1512-
pos.isPositional(n) and
1513-
not exists(int i | splatArgumentAt(call, i) and i < n)
1514-
)
1515-
|
1516-
if call instanceof CfgNodes::ExprNodes::ArrayLiteralCfgNode
1517-
then
1518-
/*
1519-
* Needed for cases like
1520-
*
1521-
* ```rb
1522-
* arr = [taint, safe]
1523-
*
1524-
* def foo(a, b)
1525-
* sink(a)
1526-
* end
1527-
*
1528-
* foo(*arr)
1529-
* ```
1530-
*/
1531-
1532-
c = getArrayContent(n)
1533-
else c = getSplatContent(n, false)
1464+
exists(int n, ArgumentPosition pos |
1465+
arg.isArgumentOf(call, pos) and
1466+
pos.isPositional(n) and
1467+
c = getArrayContent(n)
15341468
)
15351469
}
15361470

@@ -1552,7 +1486,14 @@ module ArgumentNodes {
15521486

15531487
override predicate sourceArgumentOf(CfgNodes::ExprNodes::CallCfgNode call, ArgumentPosition pos) {
15541488
call = call_ and
1555-
pos.isSynthSplat()
1489+
exists(int actualSplat | pos.isSynthSplat(actualSplat) |
1490+
any(SynthSplatArgumentShiftNode shift |
1491+
shift = TSynthSplatArgumentShiftNode(_, actualSplat, _)
1492+
).storeInto(this, _)
1493+
or
1494+
not any(SynthSplatArgumentShiftNode shift).storeInto(this, _) and
1495+
actualSplat = -1
1496+
)
15561497
}
15571498

15581499
override string toStringImpl() { result = "synthetic splat argument" }
@@ -1583,8 +1524,6 @@ module ArgumentNodes {
15831524
predicate readFrom(Node splatArg, ContentSet cs) {
15841525
splatArg.asExpr().(Argument).isArgumentOf(c, any(ArgumentPosition p | p.isSplat(splatPos))) and
15851526
(
1586-
cs = getSplatContent(n - splatPos, _)
1587-
or
15881527
cs = getArrayContent(n - splatPos)
15891528
or
15901529
n = -1 and
@@ -1599,7 +1538,7 @@ module ArgumentNodes {
15991538
predicate storeInto(SynthSplatArgumentNode synthSplat, ContentSet cs) {
16001539
synthSplat = TSynthSplatArgumentNode(c) and
16011540
(
1602-
cs = getSplatContent(n, true)
1541+
cs = getArrayContent(n)
16031542
or
16041543
n = -1 and
16051544
cs.isSingleton(TUnknownElementContent())
@@ -1813,10 +1752,6 @@ private ContentSet getArrayContent(int n) {
18131752
)
18141753
}
18151754

1816-
private ContentSet getSplatContent(int n, boolean adjusted) {
1817-
result.isSingleton(TSplatContent(n, adjusted))
1818-
}
1819-
18201755
/**
18211756
* Subset of `storeStep` that should be shared with type-tracking.
18221757
*/
@@ -1977,13 +1912,8 @@ DataFlowType getNodeType(Node n) {
19771912
result = TLambdaDataFlowType(c)
19781913
)
19791914
or
1980-
result = TSynthHashSplatArgumentType(n.(SynthHashSplatArgumentNode).getMethodName())
1981-
or
1982-
result = TSynthSplatArgumentType(n.(SynthSplatArgumentNode).getMethodName())
1983-
or
19841915
not n instanceof LambdaSelfReferenceNode and
19851916
not mustHaveLambdaType(n, _) and
1986-
not n instanceof SynthHashSplatOrSplatArgumentNode and
19871917
result = TUnknownDataFlowType()
19881918
}
19891919

@@ -2209,17 +2139,6 @@ class ContentApprox extends TContentApprox {
22092139
result = "approximated element " + approx
22102140
)
22112141
or
2212-
exists(boolean shifted, string s |
2213-
this = TSplatContentApprox(shifted) and
2214-
(if shifted = true then s = " (shifted)" else s = "") and
2215-
result = "approximated splat position" + s
2216-
)
2217-
or
2218-
exists(string s |
2219-
this = THashSplatContentApprox(s) and
2220-
result = "approximated hash-splat position " + s
2221-
)
2222-
or
22232142
exists(Content c |
22242143
this = TNonElementContentApprox(c) and
22252144
result = c.toString()
@@ -2259,13 +2178,6 @@ ContentApprox getContentApprox(Content c) {
22592178
result =
22602179
TKnownElementContentApprox(approxKnownElementIndex(c.(Content::KnownElementContent).getIndex()))
22612180
or
2262-
exists(boolean shifted |
2263-
c = TSplatContent(_, shifted) and
2264-
result = TSplatContentApprox(shifted)
2265-
)
2266-
or
2267-
result = THashSplatContentApprox(approxKnownElementIndex(c.(Content::HashSplatContent).getKey()))
2268-
or
22692181
result = TNonElementContentApprox(c)
22702182
}
22712183

‎ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ module Content {
586586
*
587587
* we have an implicit splat argument containing `[1, 2, 3]`.
588588
*/
589-
class SplatContent extends ElementContent, TSplatContent {
589+
deprecated class SplatContent extends Content, TSplatContent {
590590
private int i;
591591
private boolean shifted;
592592

@@ -629,7 +629,7 @@ module Content {
629629
*
630630
* we have an implicit hash-splat argument containing `{:a => 1, :b => 2, :c => 3}`.
631631
*/
632-
class HashSplatContent extends ElementContent, THashSplatContent {
632+
deprecated class HashSplatContent extends Content, THashSplatContent {
633633
private ConstantValue::ConstantSymbolValue cv;
634634

635635
HashSplatContent() { this = THashSplatContent(cv) }
@@ -797,20 +797,13 @@ class ContentSet extends TContentSet {
797797
private Content getAnElementReadContent() {
798798
exists(Content::KnownElementContent c | this.isKnownOrUnknownElement(c) |
799799
result = c or
800-
result = TSplatContent(c.getIndex().getInt(), _) or
801-
result = THashSplatContent(c.getIndex()) or
802800
result = TUnknownElementContent()
803801
)
804802
or
805803
exists(int lower, boolean includeUnknown |
806804
this = TElementLowerBoundContent(lower, includeUnknown)
807805
|
808-
exists(int i |
809-
result.(Content::KnownElementContent).getIndex().isInt(i) or
810-
result = TSplatContent(i, _)
811-
|
812-
i >= lower
813-
)
806+
exists(int i | result.(Content::KnownElementContent).getIndex().isInt(i) | i >= lower)
814807
or
815808
includeUnknown = true and
816809
result = TUnknownElementContent()
@@ -821,11 +814,6 @@ class ContentSet extends TContentSet {
821814
|
822815
type = result.(Content::KnownElementContent).getIndex().getValueType()
823816
or
824-
type = "int" and
825-
result instanceof Content::SplatContent
826-
or
827-
type = result.(Content::HashSplatContent).getKey().getValueType()
828-
or
829817
includeUnknown = true and
830818
result = TUnknownElementContent()
831819
)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
failures
21
testFailures
2+
failures

‎ruby/ql/test/library-tests/dataflow/array-flow/array-flow.expected

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2356,6 +2356,16 @@ edges
23562356
| array_flow.rb:1686:14:1686:14 | w | array_flow.rb:1690:10:1690:10 | w | provenance | |
23572357
| array_flow.rb:1686:18:1686:18 | a [element 2] | array_flow.rb:1686:11:1686:11 | z | provenance | |
23582358
| array_flow.rb:1686:18:1686:18 | a [element 3] | array_flow.rb:1686:14:1686:14 | w | provenance | |
2359+
| array_flow.rb:1693:10:1693:14 | *args [element 1] | array_flow.rb:1694:17:1694:20 | args [element 1] | provenance | |
2360+
| array_flow.rb:1694:16:1694:20 | * ... [element 1] | array_flow.rb:1694:5:1694:21 | call to [] [element 1] | provenance | |
2361+
| array_flow.rb:1694:17:1694:20 | args [element 1] | array_flow.rb:1694:16:1694:20 | * ... [element 1] | provenance | |
2362+
| array_flow.rb:1697:13:1697:13 | y | array_flow.rb:1699:10:1699:10 | y | provenance | |
2363+
| array_flow.rb:1704:5:1704:5 | a [element 1] | array_flow.rb:1705:11:1705:11 | a [element 1] | provenance | |
2364+
| array_flow.rb:1704:9:1704:31 | call to m141 [element 1] | array_flow.rb:1704:5:1704:5 | a [element 1] | provenance | |
2365+
| array_flow.rb:1704:17:1704:27 | call to source | array_flow.rb:1693:10:1693:14 | *args [element 1] | provenance | |
2366+
| array_flow.rb:1704:17:1704:27 | call to source | array_flow.rb:1704:9:1704:31 | call to m141 [element 1] | provenance | |
2367+
| array_flow.rb:1705:10:1705:11 | * ... [element 1] | array_flow.rb:1697:13:1697:13 | y | provenance | |
2368+
| array_flow.rb:1705:11:1705:11 | a [element 1] | array_flow.rb:1705:10:1705:11 | * ... [element 1] | provenance | |
23592369
nodes
23602370
| array_flow.rb:2:5:2:5 | a [element 0] | semmle.label | a [element 0] |
23612371
| array_flow.rb:2:9:2:20 | * ... [element 0] | semmle.label | * ... [element 0] |
@@ -4849,11 +4859,23 @@ nodes
48494859
| array_flow.rb:1686:18:1686:18 | a [element 3] | semmle.label | a [element 3] |
48504860
| array_flow.rb:1689:10:1689:10 | z | semmle.label | z |
48514861
| array_flow.rb:1690:10:1690:10 | w | semmle.label | w |
4862+
| array_flow.rb:1693:10:1693:14 | *args [element 1] | semmle.label | *args [element 1] |
4863+
| array_flow.rb:1694:5:1694:21 | call to [] [element 1] | semmle.label | call to [] [element 1] |
4864+
| array_flow.rb:1694:16:1694:20 | * ... [element 1] | semmle.label | * ... [element 1] |
4865+
| array_flow.rb:1694:17:1694:20 | args [element 1] | semmle.label | args [element 1] |
4866+
| array_flow.rb:1697:13:1697:13 | y | semmle.label | y |
4867+
| array_flow.rb:1699:10:1699:10 | y | semmle.label | y |
4868+
| array_flow.rb:1704:5:1704:5 | a [element 1] | semmle.label | a [element 1] |
4869+
| array_flow.rb:1704:9:1704:31 | call to m141 [element 1] | semmle.label | call to m141 [element 1] |
4870+
| array_flow.rb:1704:17:1704:27 | call to source | semmle.label | call to source |
4871+
| array_flow.rb:1705:10:1705:11 | * ... [element 1] | semmle.label | * ... [element 1] |
4872+
| array_flow.rb:1705:11:1705:11 | a [element 1] | semmle.label | a [element 1] |
48524873
subpaths
48534874
| array_flow.rb:251:9:251:9 | a [element 2] | array_flow.rb:251:30:251:30 | x | array_flow.rb:253:9:253:25 | call to [] [element 0] | array_flow.rb:251:9:254:7 | call to collect_concat [element] |
48544875
| array_flow.rb:507:9:507:9 | a [element 3] | array_flow.rb:507:26:507:26 | x | array_flow.rb:509:9:509:9 | x | array_flow.rb:507:9:510:7 | call to filter_map [element] |
48554876
| array_flow.rb:571:9:571:9 | a [element 2] | array_flow.rb:571:24:571:24 | x | array_flow.rb:573:9:573:25 | call to [] [element 0] | array_flow.rb:571:9:574:7 | call to flat_map [element] |
48564877
| array_flow.rb:1678:9:1678:9 | a [element 2] | array_flow.rb:1678:19:1678:19 | x | array_flow.rb:1679:9:1679:9 | x | array_flow.rb:1678:9:1680:7 | call to map [element] |
4878+
| array_flow.rb:1704:17:1704:27 | call to source | array_flow.rb:1693:10:1693:14 | *args [element 1] | array_flow.rb:1694:5:1694:21 | call to [] [element 1] | array_flow.rb:1704:9:1704:31 | call to m141 [element 1] |
48574879
testFailures
48584880
arrayLiteral
48594881
| array_flow.rb:9:9:9:25 | call to [] |
@@ -5046,6 +5068,7 @@ arrayLiteral
50465068
| array_flow.rb:1668:14:1668:41 | ...[...] |
50475069
| array_flow.rb:1677:9:1677:29 | call to [] |
50485070
| array_flow.rb:1685:9:1685:44 | call to [] |
5071+
| array_flow.rb:1694:5:1694:21 | call to [] |
50495072
#select
50505073
| array_flow.rb:3:10:3:13 | ...[...] | array_flow.rb:2:10:2:20 | call to source | array_flow.rb:3:10:3:13 | ...[...] | $@ | array_flow.rb:2:10:2:20 | call to source | call to source |
50515074
| array_flow.rb:5:10:5:13 | ...[...] | array_flow.rb:2:10:2:20 | call to source | array_flow.rb:5:10:5:13 | ...[...] | $@ | array_flow.rb:2:10:2:20 | call to source | call to source |
@@ -5749,3 +5772,4 @@ arrayLiteral
57495772
| array_flow.rb:1681:10:1681:13 | ...[...] | array_flow.rb:1677:16:1677:28 | call to source | array_flow.rb:1681:10:1681:13 | ...[...] | $@ | array_flow.rb:1677:16:1677:28 | call to source | call to source |
57505773
| array_flow.rb:1689:10:1689:10 | z | array_flow.rb:1685:16:1685:28 | call to source | array_flow.rb:1689:10:1689:10 | z | $@ | array_flow.rb:1685:16:1685:28 | call to source | call to source |
57515774
| array_flow.rb:1690:10:1690:10 | w | array_flow.rb:1685:31:1685:43 | call to source | array_flow.rb:1690:10:1690:10 | w | $@ | array_flow.rb:1685:31:1685:43 | call to source | call to source |
5775+
| array_flow.rb:1699:10:1699:10 | y | array_flow.rb:1704:17:1704:27 | call to source | array_flow.rb:1699:10:1699:10 | y | $@ | array_flow.rb:1704:17:1704:27 | call to source | call to source |

‎ruby/ql/test/library-tests/dataflow/array-flow/array_flow.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1689,3 +1689,18 @@ def m140
16891689
sink z # $ hasValueFlow=140.1
16901690
sink w # $ hasValueFlow=140.2
16911691
end
1692+
1693+
def m141(*args)
1694+
::Array.[](*args)
1695+
end
1696+
1697+
def m142(x, y, z)
1698+
sink(x)
1699+
sink(y) # $ hasValueFlow=143
1700+
sink(z)
1701+
end
1702+
1703+
def m143
1704+
a = m141(0, source(143), 1)
1705+
m142(*a)
1706+
end

‎ruby/ql/test/library-tests/dataflow/array-flow/type-tracking-array-flow.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,5 @@ testFailures
6464
| array_flow.rb:1626:19:1626:70 | # $ hasValueFlow=136.2 $ SPURIOUS hasValueFlow=136.1 | Missing result:hasValueFlow=136.1 |
6565
| array_flow.rb:1626:19:1626:70 | # $ hasValueFlow=136.2 $ SPURIOUS hasValueFlow=136.1 | Missing result:hasValueFlow=136.2 |
6666
| array_flow.rb:1627:19:1627:40 | # $ hasValueFlow=136.1 | Missing result:hasValueFlow=136.1 |
67+
| array_flow.rb:1699:13:1699:32 | # $ hasValueFlow=143 | Missing result:hasValueFlow=143 |
6768
failures

‎ruby/ql/test/library-tests/dataflow/flow-summaries/semantics.expected

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,14 @@ edges
7878
| semantics.rb:60:5:60:5 | a | semantics.rb:66:14:66:15 | &... | provenance | |
7979
| semantics.rb:60:9:60:18 | call to source | semantics.rb:60:5:60:5 | a | provenance | |
8080
| semantics.rb:60:9:60:18 | call to source | semantics.rb:60:5:60:5 | a | provenance | |
81-
| semantics.rb:61:10:61:15 | call to s10 [splat position 0] | semantics.rb:61:10:61:15 | call to s10 | provenance | |
81+
| semantics.rb:61:10:61:15 | call to s10 [element 0] | semantics.rb:61:10:61:15 | call to s10 | provenance | |
8282
| semantics.rb:61:14:61:14 | a | semantics.rb:61:10:61:15 | call to s10 | provenance | |
8383
| semantics.rb:61:14:61:14 | a | semantics.rb:61:10:61:15 | call to s10 | provenance | |
84-
| semantics.rb:61:14:61:14 | a | semantics.rb:61:10:61:15 | call to s10 [splat position 0] | provenance | |
85-
| semantics.rb:62:10:62:18 | call to s10 [splat position 1] | semantics.rb:62:10:62:18 | call to s10 | provenance | |
84+
| semantics.rb:61:14:61:14 | a | semantics.rb:61:10:61:15 | call to s10 [element 0] | provenance | |
85+
| semantics.rb:62:10:62:18 | call to s10 [element 1] | semantics.rb:62:10:62:18 | call to s10 | provenance | |
8686
| semantics.rb:62:17:62:17 | a | semantics.rb:62:10:62:18 | call to s10 | provenance | |
8787
| semantics.rb:62:17:62:17 | a | semantics.rb:62:10:62:18 | call to s10 | provenance | |
88-
| semantics.rb:62:17:62:17 | a | semantics.rb:62:10:62:18 | call to s10 [splat position 1] | provenance | |
88+
| semantics.rb:62:17:62:17 | a | semantics.rb:62:10:62:18 | call to s10 [element 1] | provenance | |
8989
| semantics.rb:63:19:63:19 | a | semantics.rb:63:10:63:20 | call to s10 | provenance | |
9090
| semantics.rb:63:19:63:19 | a | semantics.rb:63:10:63:20 | call to s10 | provenance | |
9191
| semantics.rb:64:27:64:27 | a | semantics.rb:64:10:64:28 | call to s10 | provenance | |
@@ -144,14 +144,14 @@ edges
144144
| semantics.rb:108:5:108:5 | b | semantics.rb:110:27:110:27 | b | provenance | |
145145
| semantics.rb:108:9:108:18 | call to source | semantics.rb:108:5:108:5 | b | provenance | |
146146
| semantics.rb:108:9:108:18 | call to source | semantics.rb:108:5:108:5 | b | provenance | |
147-
| semantics.rb:109:10:109:28 | call to s15 [hash-splat position :foo] | semantics.rb:109:10:109:34 | ...[...] | provenance | |
148-
| semantics.rb:109:10:109:28 | call to s15 [hash-splat position :foo] | semantics.rb:109:10:109:34 | ...[...] | provenance | |
149-
| semantics.rb:109:19:109:19 | a | semantics.rb:109:10:109:28 | call to s15 [hash-splat position :foo] | provenance | |
150-
| semantics.rb:109:19:109:19 | a | semantics.rb:109:10:109:28 | call to s15 [hash-splat position :foo] | provenance | |
151-
| semantics.rb:110:10:110:28 | call to s15 [hash-splat position :bar] | semantics.rb:110:10:110:34 | ...[...] | provenance | |
152-
| semantics.rb:110:10:110:28 | call to s15 [hash-splat position :bar] | semantics.rb:110:10:110:34 | ...[...] | provenance | |
153-
| semantics.rb:110:27:110:27 | b | semantics.rb:110:10:110:28 | call to s15 [hash-splat position :bar] | provenance | |
154-
| semantics.rb:110:27:110:27 | b | semantics.rb:110:10:110:28 | call to s15 [hash-splat position :bar] | provenance | |
147+
| semantics.rb:109:10:109:28 | call to s15 [element :foo] | semantics.rb:109:10:109:34 | ...[...] | provenance | |
148+
| semantics.rb:109:10:109:28 | call to s15 [element :foo] | semantics.rb:109:10:109:34 | ...[...] | provenance | |
149+
| semantics.rb:109:19:109:19 | a | semantics.rb:109:10:109:28 | call to s15 [element :foo] | provenance | |
150+
| semantics.rb:109:19:109:19 | a | semantics.rb:109:10:109:28 | call to s15 [element :foo] | provenance | |
151+
| semantics.rb:110:10:110:28 | call to s15 [element :bar] | semantics.rb:110:10:110:34 | ...[...] | provenance | |
152+
| semantics.rb:110:10:110:28 | call to s15 [element :bar] | semantics.rb:110:10:110:34 | ...[...] | provenance | |
153+
| semantics.rb:110:27:110:27 | b | semantics.rb:110:10:110:28 | call to s15 [element :bar] | provenance | |
154+
| semantics.rb:110:27:110:27 | b | semantics.rb:110:10:110:28 | call to s15 [element :bar] | provenance | |
155155
| semantics.rb:114:5:114:5 | a | semantics.rb:116:14:116:14 | a | provenance | |
156156
| semantics.rb:114:5:114:5 | a | semantics.rb:116:14:116:14 | a | provenance | |
157157
| semantics.rb:114:5:114:5 | a | semantics.rb:119:17:119:17 | a | provenance | |
@@ -192,18 +192,18 @@ edges
192192
| semantics.rb:126:5:126:5 | b | semantics.rb:129:17:129:17 | b | provenance | |
193193
| semantics.rb:126:9:126:18 | call to source | semantics.rb:126:5:126:5 | b | provenance | |
194194
| semantics.rb:126:9:126:18 | call to source | semantics.rb:126:5:126:5 | b | provenance | |
195-
| semantics.rb:127:10:127:18 | call to s17 [splat position 0] | semantics.rb:127:10:127:18 | call to s17 | provenance | |
196-
| semantics.rb:127:10:127:18 | call to s17 [splat position 1] | semantics.rb:127:10:127:18 | call to s17 | provenance | |
197-
| semantics.rb:127:14:127:14 | a | semantics.rb:127:10:127:18 | call to s17 [splat position 0] | provenance | |
198-
| semantics.rb:127:17:127:17 | b | semantics.rb:127:10:127:18 | call to s17 [splat position 1] | provenance | |
199-
| semantics.rb:128:10:128:18 | call to s17 [splat position 0] | semantics.rb:128:10:128:21 | ...[...] | provenance | |
200-
| semantics.rb:128:10:128:18 | call to s17 [splat position 0] | semantics.rb:128:10:128:21 | ...[...] | provenance | |
201-
| semantics.rb:128:14:128:14 | a | semantics.rb:128:10:128:18 | call to s17 [splat position 0] | provenance | |
202-
| semantics.rb:128:14:128:14 | a | semantics.rb:128:10:128:18 | call to s17 [splat position 0] | provenance | |
203-
| semantics.rb:129:10:129:18 | call to s17 [splat position 1] | semantics.rb:129:10:129:21 | ...[...] | provenance | |
204-
| semantics.rb:129:10:129:18 | call to s17 [splat position 1] | semantics.rb:129:10:129:21 | ...[...] | provenance | |
205-
| semantics.rb:129:17:129:17 | b | semantics.rb:129:10:129:18 | call to s17 [splat position 1] | provenance | |
206-
| semantics.rb:129:17:129:17 | b | semantics.rb:129:10:129:18 | call to s17 [splat position 1] | provenance | |
195+
| semantics.rb:127:10:127:18 | call to s17 [element 0] | semantics.rb:127:10:127:18 | call to s17 | provenance | |
196+
| semantics.rb:127:10:127:18 | call to s17 [element 1] | semantics.rb:127:10:127:18 | call to s17 | provenance | |
197+
| semantics.rb:127:14:127:14 | a | semantics.rb:127:10:127:18 | call to s17 [element 0] | provenance | |
198+
| semantics.rb:127:17:127:17 | b | semantics.rb:127:10:127:18 | call to s17 [element 1] | provenance | |
199+
| semantics.rb:128:10:128:18 | call to s17 [element 0] | semantics.rb:128:10:128:21 | ...[...] | provenance | |
200+
| semantics.rb:128:10:128:18 | call to s17 [element 0] | semantics.rb:128:10:128:21 | ...[...] | provenance | |
201+
| semantics.rb:128:14:128:14 | a | semantics.rb:128:10:128:18 | call to s17 [element 0] | provenance | |
202+
| semantics.rb:128:14:128:14 | a | semantics.rb:128:10:128:18 | call to s17 [element 0] | provenance | |
203+
| semantics.rb:129:10:129:18 | call to s17 [element 1] | semantics.rb:129:10:129:21 | ...[...] | provenance | |
204+
| semantics.rb:129:10:129:18 | call to s17 [element 1] | semantics.rb:129:10:129:21 | ...[...] | provenance | |
205+
| semantics.rb:129:17:129:17 | b | semantics.rb:129:10:129:18 | call to s17 [element 1] | provenance | |
206+
| semantics.rb:129:17:129:17 | b | semantics.rb:129:10:129:18 | call to s17 [element 1] | provenance | |
207207
| semantics.rb:133:5:133:5 | a | semantics.rb:135:12:135:12 | a | provenance | |
208208
| semantics.rb:133:5:133:5 | a | semantics.rb:135:12:135:12 | a | provenance | |
209209
| semantics.rb:133:5:133:5 | a | semantics.rb:137:14:137:14 | a | provenance | |
@@ -1191,12 +1191,12 @@ nodes
11911191
| semantics.rb:60:9:60:18 | call to source | semmle.label | call to source |
11921192
| semantics.rb:61:10:61:15 | call to s10 | semmle.label | call to s10 |
11931193
| semantics.rb:61:10:61:15 | call to s10 | semmle.label | call to s10 |
1194-
| semantics.rb:61:10:61:15 | call to s10 [splat position 0] | semmle.label | call to s10 [splat position 0] |
1194+
| semantics.rb:61:10:61:15 | call to s10 [element 0] | semmle.label | call to s10 [element 0] |
11951195
| semantics.rb:61:14:61:14 | a | semmle.label | a |
11961196
| semantics.rb:61:14:61:14 | a | semmle.label | a |
11971197
| semantics.rb:62:10:62:18 | call to s10 | semmle.label | call to s10 |
11981198
| semantics.rb:62:10:62:18 | call to s10 | semmle.label | call to s10 |
1199-
| semantics.rb:62:10:62:18 | call to s10 [splat position 1] | semmle.label | call to s10 [splat position 1] |
1199+
| semantics.rb:62:10:62:18 | call to s10 [element 1] | semmle.label | call to s10 [element 1] |
12001200
| semantics.rb:62:17:62:17 | a | semmle.label | a |
12011201
| semantics.rb:62:17:62:17 | a | semmle.label | a |
12021202
| semantics.rb:63:10:63:20 | call to s10 | semmle.label | call to s10 |
@@ -1269,14 +1269,14 @@ nodes
12691269
| semantics.rb:108:5:108:5 | b | semmle.label | b |
12701270
| semantics.rb:108:9:108:18 | call to source | semmle.label | call to source |
12711271
| semantics.rb:108:9:108:18 | call to source | semmle.label | call to source |
1272-
| semantics.rb:109:10:109:28 | call to s15 [hash-splat position :foo] | semmle.label | call to s15 [hash-splat position :foo] |
1273-
| semantics.rb:109:10:109:28 | call to s15 [hash-splat position :foo] | semmle.label | call to s15 [hash-splat position :foo] |
1272+
| semantics.rb:109:10:109:28 | call to s15 [element :foo] | semmle.label | call to s15 [element :foo] |
1273+
| semantics.rb:109:10:109:28 | call to s15 [element :foo] | semmle.label | call to s15 [element :foo] |
12741274
| semantics.rb:109:10:109:34 | ...[...] | semmle.label | ...[...] |
12751275
| semantics.rb:109:10:109:34 | ...[...] | semmle.label | ...[...] |
12761276
| semantics.rb:109:19:109:19 | a | semmle.label | a |
12771277
| semantics.rb:109:19:109:19 | a | semmle.label | a |
1278-
| semantics.rb:110:10:110:28 | call to s15 [hash-splat position :bar] | semmle.label | call to s15 [hash-splat position :bar] |
1279-
| semantics.rb:110:10:110:28 | call to s15 [hash-splat position :bar] | semmle.label | call to s15 [hash-splat position :bar] |
1278+
| semantics.rb:110:10:110:28 | call to s15 [element :bar] | semmle.label | call to s15 [element :bar] |
1279+
| semantics.rb:110:10:110:28 | call to s15 [element :bar] | semmle.label | call to s15 [element :bar] |
12801280
| semantics.rb:110:10:110:34 | ...[...] | semmle.label | ...[...] |
12811281
| semantics.rb:110:10:110:34 | ...[...] | semmle.label | ...[...] |
12821282
| semantics.rb:110:27:110:27 | b | semmle.label | b |
@@ -1322,18 +1322,18 @@ nodes
13221322
| semantics.rb:126:9:126:18 | call to source | semmle.label | call to source |
13231323
| semantics.rb:126:9:126:18 | call to source | semmle.label | call to source |
13241324
| semantics.rb:127:10:127:18 | call to s17 | semmle.label | call to s17 |
1325-
| semantics.rb:127:10:127:18 | call to s17 [splat position 0] | semmle.label | call to s17 [splat position 0] |
1326-
| semantics.rb:127:10:127:18 | call to s17 [splat position 1] | semmle.label | call to s17 [splat position 1] |
1325+
| semantics.rb:127:10:127:18 | call to s17 [element 0] | semmle.label | call to s17 [element 0] |
1326+
| semantics.rb:127:10:127:18 | call to s17 [element 1] | semmle.label | call to s17 [element 1] |
13271327
| semantics.rb:127:14:127:14 | a | semmle.label | a |
13281328
| semantics.rb:127:17:127:17 | b | semmle.label | b |
1329-
| semantics.rb:128:10:128:18 | call to s17 [splat position 0] | semmle.label | call to s17 [splat position 0] |
1330-
| semantics.rb:128:10:128:18 | call to s17 [splat position 0] | semmle.label | call to s17 [splat position 0] |
1329+
| semantics.rb:128:10:128:18 | call to s17 [element 0] | semmle.label | call to s17 [element 0] |
1330+
| semantics.rb:128:10:128:18 | call to s17 [element 0] | semmle.label | call to s17 [element 0] |
13311331
| semantics.rb:128:10:128:21 | ...[...] | semmle.label | ...[...] |
13321332
| semantics.rb:128:10:128:21 | ...[...] | semmle.label | ...[...] |
13331333
| semantics.rb:128:14:128:14 | a | semmle.label | a |
13341334
| semantics.rb:128:14:128:14 | a | semmle.label | a |
1335-
| semantics.rb:129:10:129:18 | call to s17 [splat position 1] | semmle.label | call to s17 [splat position 1] |
1336-
| semantics.rb:129:10:129:18 | call to s17 [splat position 1] | semmle.label | call to s17 [splat position 1] |
1335+
| semantics.rb:129:10:129:18 | call to s17 [element 1] | semmle.label | call to s17 [element 1] |
1336+
| semantics.rb:129:10:129:18 | call to s17 [element 1] | semmle.label | call to s17 [element 1] |
13371337
| semantics.rb:129:10:129:21 | ...[...] | semmle.label | ...[...] |
13381338
| semantics.rb:129:10:129:21 | ...[...] | semmle.label | ...[...] |
13391339
| semantics.rb:129:17:129:17 | b | semmle.label | b |

‎ruby/ql/test/library-tests/dataflow/params/TypeTracker.expected

Lines changed: 810 additions & 1679 deletions
Large diffs are not rendered by default.

‎ruby/ql/test/library-tests/dataflow/params/params-flow.expected

Lines changed: 2 additions & 45 deletions
Large diffs are not rendered by default.

‎ruby/ql/test/library-tests/dataflow/params/params_flow.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,10 @@ def splatstuff(*x)
6969
def splatmid(x, y, *z, w, r)
7070
sink x # $ hasValueFlow=27 $ hasValueFlow=32 $ hasValueFlow=45
7171
sink y # $ hasValueFlow=28 $ hasValueFlow=46 $ hasValueFlow=33
72-
sink z[0] # MISSING: $ hasValueFlow=47 $ hasValueFlow=29 $ hasValueFlow=34
72+
sink z[0] # $ MISSING: hasValueFlow=47 $ hasValueFlow=29 $ hasValueFlow=34
7373
sink z[1] # $ MISSING: hasValueFlow=48 $ hasValueFlow=35
74-
sink w # $ hasValueFlow=30 $ hasValueFlow=50 $ MISSING: hasValueFlow=36
75-
sink r # $ hasValueFlow=31 $ hasValueFlow=51 $ MISSING: hasValueFlow=37
74+
sink w # $ MISSING: hasValueFlow=30 $ hasValueFlow=50 $ hasValueFlow=36
75+
sink r # $ MISSING: hasValueFlow=31 $ hasValueFlow=51 $ hasValueFlow=37
7676
end
7777

7878
splatmid(taint(27), taint(28), taint(29), taint(30), taint(31))
@@ -82,9 +82,9 @@ def splatmid(x, y, *z, w, r)
8282

8383
def pos_many(t, u, v, w, x, y, z)
8484
sink t # $ hasValueFlow=38 $ hasValueFlow=66
85-
sink u # $ hasValueFlow=39 $ hasValueFlow=67 $ SPURIOUS: hasValueFlow=68
85+
sink u # $ hasValueFlow=39 $ hasValueFlow=67
8686
sink v # $ hasValueFlow=40
87-
sink w # $ hasValueFlow=41 $ SPURIOUS: hasValueFlow=44
87+
sink w # $ hasValueFlow=41
8888
sink x # $ hasValueFlow=42
8989
sink y # $ hasValueFlow=43
9090
sink z # $ MISSING: hasValueFlow=44
@@ -99,7 +99,7 @@ def splatmidsmall(a, *splats, b)
9999
sink a # $ hasValueFlow=52 $ hasValueFlow=55
100100
sink splats[0] # $ MISSING: hasValueFlow=53
101101
sink splats[1]
102-
sink b # $ hasValueFlow=57 $ MISSING: hasValueFlow=54
102+
sink b # $ MISSING: hasValueFlow=57 $ hasValueFlow=54
103103
end
104104

105105
splatmidsmall(taint(52), *[taint(53), taint(54)])

‎ruby/ql/test/library-tests/dataflow/type-tracker/TypeTracker.expected

Lines changed: 41 additions & 60 deletions
Large diffs are not rendered by default.

‎ruby/ql/test/library-tests/frameworks/action_controller/params-flow.expected

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,21 +67,21 @@ edges
6767
| params_flow.rb:107:10:107:33 | call to values_at [element 0] | params_flow.rb:107:10:107:33 | call to values_at | provenance | |
6868
| params_flow.rb:107:10:107:33 | call to values_at [element 1] | params_flow.rb:107:10:107:33 | call to values_at | provenance | |
6969
| params_flow.rb:111:10:111:15 | call to params | params_flow.rb:111:10:111:29 | call to merge | provenance | |
70-
| params_flow.rb:112:10:112:29 | call to merge [splat position 0] | params_flow.rb:112:10:112:29 | call to merge | provenance | |
70+
| params_flow.rb:112:10:112:29 | call to merge [element 0] | params_flow.rb:112:10:112:29 | call to merge | provenance | |
7171
| params_flow.rb:112:23:112:28 | call to params | params_flow.rb:112:10:112:29 | call to merge | provenance | |
72-
| params_flow.rb:112:23:112:28 | call to params | params_flow.rb:112:10:112:29 | call to merge [splat position 0] | provenance | |
72+
| params_flow.rb:112:23:112:28 | call to params | params_flow.rb:112:10:112:29 | call to merge [element 0] | provenance | |
7373
| params_flow.rb:116:10:116:15 | call to params | params_flow.rb:116:10:116:37 | call to reverse_merge | provenance | |
7474
| params_flow.rb:117:31:117:36 | call to params | params_flow.rb:117:10:117:37 | call to reverse_merge | provenance | |
7575
| params_flow.rb:121:10:121:15 | call to params | params_flow.rb:121:10:121:43 | call to with_defaults | provenance | |
7676
| params_flow.rb:122:31:122:36 | call to params | params_flow.rb:122:10:122:37 | call to with_defaults | provenance | |
7777
| params_flow.rb:126:10:126:15 | call to params | params_flow.rb:126:10:126:30 | call to merge! | provenance | |
78-
| params_flow.rb:127:10:127:30 | call to merge! [splat position 0] | params_flow.rb:127:10:127:30 | call to merge! | provenance | |
78+
| params_flow.rb:127:10:127:30 | call to merge! [element 0] | params_flow.rb:127:10:127:30 | call to merge! | provenance | |
7979
| params_flow.rb:127:24:127:29 | call to params | params_flow.rb:127:10:127:30 | call to merge! | provenance | |
80-
| params_flow.rb:127:24:127:29 | call to params | params_flow.rb:127:10:127:30 | call to merge! [splat position 0] | provenance | |
80+
| params_flow.rb:127:24:127:29 | call to params | params_flow.rb:127:10:127:30 | call to merge! [element 0] | provenance | |
8181
| params_flow.rb:130:5:130:5 | [post] p | params_flow.rb:131:10:131:10 | p | provenance | |
82-
| params_flow.rb:130:5:130:5 | [post] p [splat position 0] | params_flow.rb:131:10:131:10 | p | provenance | |
82+
| params_flow.rb:130:5:130:5 | [post] p [element 0] | params_flow.rb:131:10:131:10 | p | provenance | |
8383
| params_flow.rb:130:14:130:19 | call to params | params_flow.rb:130:5:130:5 | [post] p | provenance | |
84-
| params_flow.rb:130:14:130:19 | call to params | params_flow.rb:130:5:130:5 | [post] p [splat position 0] | provenance | |
84+
| params_flow.rb:130:14:130:19 | call to params | params_flow.rb:130:5:130:5 | [post] p [element 0] | provenance | |
8585
| params_flow.rb:135:10:135:15 | call to params | params_flow.rb:135:10:135:38 | call to reverse_merge! | provenance | |
8686
| params_flow.rb:136:32:136:37 | call to params | params_flow.rb:136:10:136:38 | call to reverse_merge! | provenance | |
8787
| params_flow.rb:139:5:139:5 | [post] p | params_flow.rb:140:10:140:10 | p | provenance | |
@@ -213,7 +213,7 @@ nodes
213213
| params_flow.rb:111:10:111:15 | call to params | semmle.label | call to params |
214214
| params_flow.rb:111:10:111:29 | call to merge | semmle.label | call to merge |
215215
| params_flow.rb:112:10:112:29 | call to merge | semmle.label | call to merge |
216-
| params_flow.rb:112:10:112:29 | call to merge [splat position 0] | semmle.label | call to merge [splat position 0] |
216+
| params_flow.rb:112:10:112:29 | call to merge [element 0] | semmle.label | call to merge [element 0] |
217217
| params_flow.rb:112:23:112:28 | call to params | semmle.label | call to params |
218218
| params_flow.rb:116:10:116:15 | call to params | semmle.label | call to params |
219219
| params_flow.rb:116:10:116:37 | call to reverse_merge | semmle.label | call to reverse_merge |
@@ -226,10 +226,10 @@ nodes
226226
| params_flow.rb:126:10:126:15 | call to params | semmle.label | call to params |
227227
| params_flow.rb:126:10:126:30 | call to merge! | semmle.label | call to merge! |
228228
| params_flow.rb:127:10:127:30 | call to merge! | semmle.label | call to merge! |
229-
| params_flow.rb:127:10:127:30 | call to merge! [splat position 0] | semmle.label | call to merge! [splat position 0] |
229+
| params_flow.rb:127:10:127:30 | call to merge! [element 0] | semmle.label | call to merge! [element 0] |
230230
| params_flow.rb:127:24:127:29 | call to params | semmle.label | call to params |
231231
| params_flow.rb:130:5:130:5 | [post] p | semmle.label | [post] p |
232-
| params_flow.rb:130:5:130:5 | [post] p [splat position 0] | semmle.label | [post] p [splat position 0] |
232+
| params_flow.rb:130:5:130:5 | [post] p [element 0] | semmle.label | [post] p [element 0] |
233233
| params_flow.rb:130:14:130:19 | call to params | semmle.label | call to params |
234234
| params_flow.rb:131:10:131:10 | p | semmle.label | p |
235235
| params_flow.rb:135:10:135:15 | call to params | semmle.label | call to params |

0 commit comments

Comments
 (0)
Please sign in to comment.