@@ -661,7 +661,7 @@ private module Cached {
661
661
name = [ input , output ] .regexpFind ( "(?<=(^|\\.)Field\\[)[^\\]]+(?=\\])" , _, _) .trim ( )
662
662
)
663
663
} or
664
- TSplatContent ( int i , Boolean shifted ) { i in [ 0 .. 10 ] } or
664
+ deprecated TSplatContent ( int i , Boolean shifted ) { i in [ 0 .. 10 ] } or
665
665
THashSplatContent ( ConstantValue:: ConstantSymbolValue cv ) or
666
666
TCapturedVariableContent ( VariableCapture:: CapturedVariable v ) or
667
667
// Only used by type-tracking
@@ -686,7 +686,6 @@ private module Cached {
686
686
TUnknownElementContentApprox ( ) or
687
687
TKnownIntegerElementContentApprox ( ) or
688
688
TKnownElementContentApprox ( string approx ) { approx = approxKnownElementIndex ( _) } or
689
- TSplatContentApprox ( Boolean shifted ) or
690
689
THashSplatContentApprox ( string approx ) { approx = approxKnownElementIndex ( _) } or
691
690
TNonElementContentApprox ( Content c ) { not c instanceof Content:: ElementContent } or
692
691
TCapturedVariableContentApprox ( VariableCapture:: CapturedVariable v )
@@ -701,14 +700,10 @@ private module Cached {
701
700
TSynthHashSplatArgumentType ( string methodName ) {
702
701
methodName = any ( SynthHashSplatArgumentNode n ) .getMethodName ( )
703
702
} or
704
- TSynthSplatArgumentType ( string methodName ) {
705
- methodName = any ( SynthSplatArgumentNode n ) .getMethodName ( )
706
- } or
707
703
TUnknownDataFlowType ( )
708
704
}
709
705
710
- class TElementContent =
711
- TKnownElementContent or TUnknownElementContent or TSplatContent or THashSplatContent ;
706
+ class TElementContent = TKnownElementContent or TUnknownElementContent or THashSplatContent ;
712
707
713
708
import Cached
714
709
@@ -1188,18 +1183,6 @@ private module ParameterNodes {
1188
1183
* by adding read steps out of the synthesized parameter node to the relevant
1189
1184
* positional parameters.
1190
1185
*
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
- *
1203
1186
* We don't yet correctly handle cases where a positional argument follows the
1204
1187
* splat argument, e.g. in
1205
1188
*
@@ -1220,9 +1203,6 @@ private module ParameterNodes {
1220
1203
isParameterNode ( p , callable , any ( ParameterPosition pos | pos .isPositional ( n ) ) ) and
1221
1204
not exists ( int i | splatParameterAt ( callable .asCfgScope ( ) , i ) and i < n )
1222
1205
|
1223
- // Important: do not include `TSplatContent(_, false)` here, as normal parameter matching is possible
1224
- c = getSplatContent ( n , true )
1225
- or
1226
1206
c = getArrayContent ( n )
1227
1207
or
1228
1208
c .isSingleton ( TUnknownElementContent ( ) )
@@ -1232,7 +1212,13 @@ private module ParameterNodes {
1232
1212
final override Parameter getParameter ( ) { none ( ) }
1233
1213
1234
1214
final override predicate isParameterOf ( DataFlowCallable c , ParameterPosition pos ) {
1235
- c = callable and pos .isSynthSplat ( )
1215
+ c = callable and
1216
+ exists ( boolean hasActualSplat |
1217
+ pos .isSynthSplat ( hasActualSplat ) and
1218
+ if exists ( TSynthSplatParameterShiftNode ( c , _, _) )
1219
+ then hasActualSplat = true
1220
+ else hasActualSplat = false
1221
+ )
1236
1222
}
1237
1223
1238
1224
final override CfgScope getCfgScope ( ) { result = callable .asCfgScope ( ) }
@@ -1271,11 +1257,7 @@ private module ParameterNodes {
1271
1257
*/
1272
1258
predicate readFrom ( SynthSplatParameterNode synthSplat , ContentSet cs ) {
1273
1259
synthSplat .isParameterOf ( callable , _) and
1274
- (
1275
- cs = getSplatContent ( pos + splatPos , _)
1276
- or
1277
- cs = getArrayContent ( pos + splatPos )
1278
- )
1260
+ cs = getArrayContent ( pos + splatPos )
1279
1261
}
1280
1262
1281
1263
/**
@@ -1506,31 +1488,11 @@ module ArgumentNodes {
1506
1488
* `call`, into a synthetic splat argument.
1507
1489
*/
1508
1490
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 )
1491
+ exists ( int n , ArgumentPosition pos |
1492
+ arg .isArgumentOf ( call , pos ) and
1493
+ pos .isPositional ( n ) and
1494
+ not exists ( int i | splatArgumentAt ( call , i ) and i < n ) and
1495
+ c = getArrayContent ( n )
1534
1496
)
1535
1497
}
1536
1498
@@ -1552,7 +1514,9 @@ module ArgumentNodes {
1552
1514
1553
1515
override predicate sourceArgumentOf ( CfgNodes:: ExprNodes:: CallCfgNode call , ArgumentPosition pos ) {
1554
1516
call = call_ and
1555
- pos .isSynthSplat ( )
1517
+ if any ( SynthSplatArgumentShiftNode shift ) .storeInto ( this , _)
1518
+ then pos .isSynthSplat ( true )
1519
+ else pos .isSynthSplat ( false )
1556
1520
}
1557
1521
1558
1522
override string toStringImpl ( ) { result = "synthetic splat argument" }
@@ -1583,8 +1547,6 @@ module ArgumentNodes {
1583
1547
predicate readFrom ( Node splatArg , ContentSet cs ) {
1584
1548
splatArg .asExpr ( ) .( Argument ) .isArgumentOf ( c , any ( ArgumentPosition p | p .isSplat ( splatPos ) ) ) and
1585
1549
(
1586
- cs = getSplatContent ( n - splatPos , _)
1587
- or
1588
1550
cs = getArrayContent ( n - splatPos )
1589
1551
or
1590
1552
n = - 1 and
@@ -1599,7 +1561,7 @@ module ArgumentNodes {
1599
1561
predicate storeInto ( SynthSplatArgumentNode synthSplat , ContentSet cs ) {
1600
1562
synthSplat = TSynthSplatArgumentNode ( c ) and
1601
1563
(
1602
- cs = getSplatContent ( n , true )
1564
+ cs = getArrayContent ( n )
1603
1565
or
1604
1566
n = - 1 and
1605
1567
cs .isSingleton ( TUnknownElementContent ( ) )
@@ -1813,10 +1775,6 @@ private ContentSet getArrayContent(int n) {
1813
1775
)
1814
1776
}
1815
1777
1816
- private ContentSet getSplatContent ( int n , boolean adjusted ) {
1817
- result .isSingleton ( TSplatContent ( n , adjusted ) )
1818
- }
1819
-
1820
1778
/**
1821
1779
* Subset of `storeStep` that should be shared with type-tracking.
1822
1780
*/
@@ -1979,11 +1937,9 @@ DataFlowType getNodeType(Node n) {
1979
1937
or
1980
1938
result = TSynthHashSplatArgumentType ( n .( SynthHashSplatArgumentNode ) .getMethodName ( ) )
1981
1939
or
1982
- result = TSynthSplatArgumentType ( n .( SynthSplatArgumentNode ) .getMethodName ( ) )
1983
- or
1984
1940
not n instanceof LambdaSelfReferenceNode and
1985
1941
not mustHaveLambdaType ( n , _) and
1986
- not n instanceof SynthHashSplatOrSplatArgumentNode and
1942
+ not n instanceof SynthHashSplatArgumentNode and
1987
1943
result = TUnknownDataFlowType ( )
1988
1944
}
1989
1945
@@ -2209,12 +2165,6 @@ class ContentApprox extends TContentApprox {
2209
2165
result = "approximated element " + approx
2210
2166
)
2211
2167
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
2168
exists ( string s |
2219
2169
this = THashSplatContentApprox ( s ) and
2220
2170
result = "approximated hash-splat position " + s
@@ -2259,11 +2209,6 @@ ContentApprox getContentApprox(Content c) {
2259
2209
result =
2260
2210
TKnownElementContentApprox ( approxKnownElementIndex ( c .( Content:: KnownElementContent ) .getIndex ( ) ) )
2261
2211
or
2262
- exists ( boolean shifted |
2263
- c = TSplatContent ( _, shifted ) and
2264
- result = TSplatContentApprox ( shifted )
2265
- )
2266
- or
2267
2212
result = THashSplatContentApprox ( approxKnownElementIndex ( c .( Content:: HashSplatContent ) .getKey ( ) ) )
2268
2213
or
2269
2214
result = TNonElementContentApprox ( c )
0 commit comments