@@ -661,7 +661,7 @@ private module Cached {
661661 name = [ input , output ] .regexpFind ( "(?<=(^|\\.)Field\\[)[^\\]]+(?=\\])" , _, _) .trim ( )
662662 )
663663 } or
664- TSplatContent ( int i , Boolean shifted ) { i in [ 0 .. 10 ] } or
664+ deprecated TSplatContent ( int i , Boolean shifted ) { i in [ 0 .. 10 ] } or
665665 THashSplatContent ( ConstantValue:: ConstantSymbolValue cv ) or
666666 TCapturedVariableContent ( VariableCapture:: CapturedVariable v ) or
667667 // Only used by type-tracking
@@ -686,7 +686,6 @@ private module Cached {
686686 TUnknownElementContentApprox ( ) or
687687 TKnownIntegerElementContentApprox ( ) or
688688 TKnownElementContentApprox ( string approx ) { approx = approxKnownElementIndex ( _) } or
689- TSplatContentApprox ( Boolean shifted ) or
690689 THashSplatContentApprox ( string approx ) { approx = approxKnownElementIndex ( _) } or
691690 TNonElementContentApprox ( Content c ) { not c instanceof Content:: ElementContent } or
692691 TCapturedVariableContentApprox ( VariableCapture:: CapturedVariable v )
@@ -701,14 +700,10 @@ private module Cached {
701700 TSynthHashSplatArgumentType ( string methodName ) {
702701 methodName = any ( SynthHashSplatArgumentNode n ) .getMethodName ( )
703702 } or
704- TSynthSplatArgumentType ( string methodName ) {
705- methodName = any ( SynthSplatArgumentNode n ) .getMethodName ( )
706- } or
707703 TUnknownDataFlowType ( )
708704}
709705
710- class TElementContent =
711- TKnownElementContent or TUnknownElementContent or TSplatContent or THashSplatContent ;
706+ class TElementContent = TKnownElementContent or TUnknownElementContent or THashSplatContent ;
712707
713708import Cached
714709
@@ -1188,18 +1183,6 @@ private module ParameterNodes {
11881183 * by adding read steps out of the synthesized parameter node to the relevant
11891184 * positional parameters.
11901185 *
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- *
12031186 * We don't yet correctly handle cases where a positional argument follows the
12041187 * splat argument, e.g. in
12051188 *
@@ -1220,9 +1203,6 @@ private module ParameterNodes {
12201203 isParameterNode ( p , callable , any ( ParameterPosition pos | pos .isPositional ( n ) ) ) and
12211204 not exists ( int i | splatParameterAt ( callable .asCfgScope ( ) , i ) and i < n )
12221205 |
1223- // Important: do not include `TSplatContent(_, false)` here, as normal parameter matching is possible
1224- c = getSplatContent ( n , true )
1225- or
12261206 c = getArrayContent ( n )
12271207 or
12281208 c .isSingleton ( TUnknownElementContent ( ) )
@@ -1232,7 +1212,13 @@ private module ParameterNodes {
12321212 final override Parameter getParameter ( ) { none ( ) }
12331213
12341214 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+ )
12361222 }
12371223
12381224 final override CfgScope getCfgScope ( ) { result = callable .asCfgScope ( ) }
@@ -1271,11 +1257,7 @@ private module ParameterNodes {
12711257 */
12721258 predicate readFrom ( SynthSplatParameterNode synthSplat , ContentSet cs ) {
12731259 synthSplat .isParameterOf ( callable , _) and
1274- (
1275- cs = getSplatContent ( pos + splatPos , _)
1276- or
1277- cs = getArrayContent ( pos + splatPos )
1278- )
1260+ cs = getArrayContent ( pos + splatPos )
12791261 }
12801262
12811263 /**
@@ -1506,31 +1488,11 @@ module ArgumentNodes {
15061488 * `call`, into a synthetic splat argument.
15071489 */
15081490 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 )
15341496 )
15351497 }
15361498
@@ -1552,7 +1514,12 @@ module ArgumentNodes {
15521514
15531515 override predicate sourceArgumentOf ( CfgNodes:: ExprNodes:: CallCfgNode call , ArgumentPosition pos ) {
15541516 call = call_ and
1555- pos .isSynthSplat ( )
1517+ exists ( boolean hasActualSplat |
1518+ pos .isSynthSplat ( hasActualSplat ) and
1519+ if any ( SynthSplatArgumentShiftNode shift ) .storeInto ( this , _)
1520+ then hasActualSplat = true
1521+ else hasActualSplat = false
1522+ )
15561523 }
15571524
15581525 override string toStringImpl ( ) { result = "synthetic splat argument" }
@@ -1583,8 +1550,6 @@ module ArgumentNodes {
15831550 predicate readFrom ( Node splatArg , ContentSet cs ) {
15841551 splatArg .asExpr ( ) .( Argument ) .isArgumentOf ( c , any ( ArgumentPosition p | p .isSplat ( splatPos ) ) ) and
15851552 (
1586- cs = getSplatContent ( n - splatPos , _)
1587- or
15881553 cs = getArrayContent ( n - splatPos )
15891554 or
15901555 n = - 1 and
@@ -1599,7 +1564,7 @@ module ArgumentNodes {
15991564 predicate storeInto ( SynthSplatArgumentNode synthSplat , ContentSet cs ) {
16001565 synthSplat = TSynthSplatArgumentNode ( c ) and
16011566 (
1602- cs = getSplatContent ( n , true )
1567+ cs = getArrayContent ( n )
16031568 or
16041569 n = - 1 and
16051570 cs .isSingleton ( TUnknownElementContent ( ) )
@@ -1813,10 +1778,6 @@ private ContentSet getArrayContent(int n) {
18131778 )
18141779}
18151780
1816- private ContentSet getSplatContent ( int n , boolean adjusted ) {
1817- result .isSingleton ( TSplatContent ( n , adjusted ) )
1818- }
1819-
18201781/**
18211782 * Subset of `storeStep` that should be shared with type-tracking.
18221783 */
@@ -1979,11 +1940,9 @@ DataFlowType getNodeType(Node n) {
19791940 or
19801941 result = TSynthHashSplatArgumentType ( n .( SynthHashSplatArgumentNode ) .getMethodName ( ) )
19811942 or
1982- result = TSynthSplatArgumentType ( n .( SynthSplatArgumentNode ) .getMethodName ( ) )
1983- or
19841943 not n instanceof LambdaSelfReferenceNode and
19851944 not mustHaveLambdaType ( n , _) and
1986- not n instanceof SynthHashSplatOrSplatArgumentNode and
1945+ not n instanceof SynthHashSplatArgumentNode and
19871946 result = TUnknownDataFlowType ( )
19881947}
19891948
@@ -2209,12 +2168,6 @@ class ContentApprox extends TContentApprox {
22092168 result = "approximated element " + approx
22102169 )
22112170 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
22182171 exists ( string s |
22192172 this = THashSplatContentApprox ( s ) and
22202173 result = "approximated hash-splat position " + s
@@ -2259,11 +2212,6 @@ ContentApprox getContentApprox(Content c) {
22592212 result =
22602213 TKnownElementContentApprox ( approxKnownElementIndex ( c .( Content:: KnownElementContent ) .getIndex ( ) ) )
22612214 or
2262- exists ( boolean shifted |
2263- c = TSplatContent ( _, shifted ) and
2264- result = TSplatContentApprox ( shifted )
2265- )
2266- or
22672215 result = THashSplatContentApprox ( approxKnownElementIndex ( c .( Content:: HashSplatContent ) .getKey ( ) ) )
22682216 or
22692217 result = TNonElementContentApprox ( c )
0 commit comments