@@ -2048,11 +2048,64 @@ private module FlowExploration {
20482048 result = distSrcExt ( TCallable ( c , config ) ) - 1
20492049 }
20502050
2051+ private newtype TPartialAccessPath =
2052+ TPartialNil ( DataFlowType t ) or
2053+ TPartialCons ( Content f , int len ) { len in [ 1 .. 5 ] }
2054+
2055+ /**
2056+ * Conceptually a list of `Content`s followed by a `Type`, but only the first
2057+ * element of the list and its length are tracked. If data flows from a source to
2058+ * a given node with a given `AccessPath`, this indicates the sequence of
2059+ * dereference operations needed to get from the value in the node to the
2060+ * tracked object. The final type indicates the type of the tracked object.
2061+ */
2062+ private class PartialAccessPath extends TPartialAccessPath {
2063+ abstract string toString ( ) ;
2064+
2065+ Content getHead ( ) { this = TPartialCons ( result , _) }
2066+
2067+ int len ( ) {
2068+ this = TPartialNil ( _) and result = 0
2069+ or
2070+ this = TPartialCons ( _, result )
2071+ }
2072+
2073+ DataFlowType getType ( ) {
2074+ this = TPartialNil ( result )
2075+ or
2076+ exists ( Content head | this = TPartialCons ( head , _) | result = head .getContainerType ( ) )
2077+ }
2078+
2079+ abstract AccessPathFront getFront ( ) ;
2080+ }
2081+
2082+ private class PartialAccessPathNil extends PartialAccessPath , TPartialNil {
2083+ override string toString ( ) {
2084+ exists ( DataFlowType t | this = TPartialNil ( t ) | result = ppReprType ( t ) )
2085+ }
2086+
2087+ override AccessPathFront getFront ( ) {
2088+ exists ( DataFlowType t | this = TPartialNil ( t ) | result = TFrontNil ( t ) )
2089+ }
2090+ }
2091+
2092+ private class PartialAccessPathCons extends PartialAccessPath , TPartialCons {
2093+ override string toString ( ) {
2094+ exists ( Content f , int len | this = TPartialCons ( f , len ) |
2095+ result = f .toString ( ) + ", ... (" + len .toString ( ) + ")"
2096+ )
2097+ }
2098+
2099+ override AccessPathFront getFront ( ) {
2100+ exists ( Content f | this = TPartialCons ( f , _) | result = TFrontHead ( f ) )
2101+ }
2102+ }
2103+
20512104 private newtype TPartialPathNode =
2052- TPartialPathNodeMk ( Node node , CallContext cc , AccessPath ap , Configuration config ) {
2105+ TPartialPathNodeMk ( Node node , CallContext cc , PartialAccessPath ap , Configuration config ) {
20532106 config .isSource ( node ) and
20542107 cc instanceof CallContextAny and
2055- ap = TNil ( getErasedRepr ( node .getType ( ) ) ) and
2108+ ap = TPartialNil ( getErasedRepr ( node .getType ( ) ) ) and
20562109 not fullBarrier ( node , config ) and
20572110 exists ( config .explorationLimit ( ) )
20582111 or
@@ -2062,7 +2115,7 @@ private module FlowExploration {
20622115
20632116 pragma [ nomagic]
20642117 private predicate partialPathNodeMk0 (
2065- Node node , CallContext cc , AccessPath ap , Configuration config
2118+ Node node , CallContext cc , PartialAccessPath ap , Configuration config
20662119 ) {
20672120 exists ( PartialPathNode mid |
20682121 partialPathStep ( mid , node , cc , ap , config ) and
@@ -2138,7 +2191,7 @@ private module FlowExploration {
21382191
21392192 CallContext cc ;
21402193
2141- AccessPath ap ;
2194+ PartialAccessPath ap ;
21422195
21432196 Configuration config ;
21442197
@@ -2148,7 +2201,7 @@ private module FlowExploration {
21482201
21492202 CallContext getCallContext ( ) { result = cc }
21502203
2151- AccessPath getAp ( ) { result = ap }
2204+ PartialAccessPath getAp ( ) { result = ap }
21522205
21532206 override Configuration getConfiguration ( ) { result = config }
21542207
@@ -2161,7 +2214,7 @@ private module FlowExploration {
21612214 }
21622215
21632216 private predicate partialPathStep (
2164- PartialPathNodePriv mid , Node node , CallContext cc , AccessPath ap , Configuration config
2217+ PartialPathNodePriv mid , Node node , CallContext cc , PartialAccessPath ap , Configuration config
21652218 ) {
21662219 localFlowStep ( mid .getNode ( ) , node , config ) and
21672220 cc = mid .getCallContext ( ) and
@@ -2170,8 +2223,8 @@ private module FlowExploration {
21702223 or
21712224 additionalLocalFlowStep ( mid .getNode ( ) , node , config ) and
21722225 cc = mid .getCallContext ( ) and
2173- mid .getAp ( ) instanceof AccessPathNil and
2174- ap = TNil ( getErasedRepr ( node .getType ( ) ) ) and
2226+ mid .getAp ( ) instanceof PartialAccessPathNil and
2227+ ap = TPartialNil ( getErasedRepr ( node .getType ( ) ) ) and
21752228 config = mid .getConfiguration ( )
21762229 or
21772230 jumpStep ( mid .getNode ( ) , node , config ) and
@@ -2181,15 +2234,15 @@ private module FlowExploration {
21812234 or
21822235 additionalJumpStep ( mid .getNode ( ) , node , config ) and
21832236 cc instanceof CallContextAny and
2184- mid .getAp ( ) instanceof AccessPathNil and
2185- ap = TNil ( getErasedRepr ( node .getType ( ) ) ) and
2237+ mid .getAp ( ) instanceof PartialAccessPathNil and
2238+ ap = TPartialNil ( getErasedRepr ( node .getType ( ) ) ) and
21862239 config = mid .getConfiguration ( )
21872240 or
21882241 partialPathStoreStep ( mid , _, _, node , ap ) and
21892242 cc = mid .getCallContext ( ) and
21902243 config = mid .getConfiguration ( )
21912244 or
2192- exists ( AccessPath ap0 , Content f |
2245+ exists ( PartialAccessPath ap0 , Content f |
21932246 partialPathReadStep ( mid , ap0 , f , node , cc , config ) and
21942247 apConsFwd ( ap , f , ap0 , config )
21952248 )
@@ -2210,7 +2263,7 @@ private module FlowExploration {
22102263
22112264 pragma [ inline]
22122265 private predicate partialPathStoreStep (
2213- PartialPathNodePriv mid , AccessPath ap1 , Content f , Node node , AccessPath ap2
2266+ PartialPathNodePriv mid , PartialAccessPath ap1 , Content f , Node node , PartialAccessPath ap2
22142267 ) {
22152268 ap1 = mid .getAp ( ) and
22162269 store ( mid .getNode ( ) , f , node ) and
@@ -2220,7 +2273,9 @@ private module FlowExploration {
22202273 }
22212274
22222275 pragma [ nomagic]
2223- private predicate apConsFwd ( AccessPath ap1 , Content f , AccessPath ap2 , Configuration config ) {
2276+ private predicate apConsFwd (
2277+ PartialAccessPath ap1 , Content f , PartialAccessPath ap2 , Configuration config
2278+ ) {
22242279 exists ( PartialPathNodePriv mid |
22252280 partialPathStoreStep ( mid , ap1 , f , _, ap2 ) and
22262281 config = mid .getConfiguration ( )
@@ -2229,7 +2284,7 @@ private module FlowExploration {
22292284
22302285 pragma [ nomagic]
22312286 private predicate partialPathReadStep (
2232- PartialPathNodePriv mid , AccessPath ap , Content f , Node node , CallContext cc ,
2287+ PartialPathNodePriv mid , PartialAccessPath ap , Content f , Node node , CallContext cc ,
22332288 Configuration config
22342289 ) {
22352290 ap = mid .getAp ( ) and
@@ -2240,7 +2295,7 @@ private module FlowExploration {
22402295 }
22412296
22422297 private predicate partialPathOutOfCallable0 (
2243- PartialPathNodePriv mid , ReturnPosition pos , CallContext innercc , AccessPath ap ,
2298+ PartialPathNodePriv mid , ReturnPosition pos , CallContext innercc , PartialAccessPath ap ,
22442299 Configuration config
22452300 ) {
22462301 pos = getReturnPosition ( mid .getNode ( ) ) and
@@ -2252,8 +2307,8 @@ private module FlowExploration {
22522307
22532308 pragma [ noinline]
22542309 private predicate partialPathOutOfCallable1 (
2255- PartialPathNodePriv mid , DataFlowCall call , ReturnKind kind , CallContext cc , AccessPath ap ,
2256- Configuration config
2310+ PartialPathNodePriv mid , DataFlowCall call , ReturnKind kind , CallContext cc ,
2311+ PartialAccessPath ap , Configuration config
22572312 ) {
22582313 exists ( ReturnPosition pos , DataFlowCallable c , CallContext innercc |
22592314 partialPathOutOfCallable0 ( mid , pos , innercc , ap , config ) and
@@ -2266,7 +2321,7 @@ private module FlowExploration {
22662321 }
22672322
22682323 private predicate partialPathOutOfCallable (
2269- PartialPathNodePriv mid , OutNode out , CallContext cc , AccessPath ap , Configuration config
2324+ PartialPathNodePriv mid , OutNode out , CallContext cc , PartialAccessPath ap , Configuration config
22702325 ) {
22712326 exists ( ReturnKind kind , DataFlowCall call |
22722327 partialPathOutOfCallable1 ( mid , call , kind , cc , ap , config )
@@ -2276,7 +2331,7 @@ private module FlowExploration {
22762331 }
22772332
22782333 private predicate partialPathOutOfArgument (
2279- PartialPathNodePriv mid , PostUpdateNode node , CallContext cc , AccessPath ap ,
2334+ PartialPathNodePriv mid , PostUpdateNode node , CallContext cc , PartialAccessPath ap ,
22802335 Configuration config
22812336 ) {
22822337 exists (
@@ -2302,7 +2357,7 @@ private module FlowExploration {
23022357 pragma [ noinline]
23032358 private predicate partialPathIntoArg (
23042359 PartialPathNodePriv mid , int i , CallContext cc , DataFlowCall call , boolean emptyAp ,
2305- AccessPath ap , Configuration config
2360+ PartialAccessPath ap , Configuration config
23062361 ) {
23072362 exists ( ArgumentNode arg |
23082363 arg = mid .getNode ( ) and
@@ -2311,24 +2366,24 @@ private module FlowExploration {
23112366 ap = mid .getAp ( ) and
23122367 config = mid .getConfiguration ( )
23132368 |
2314- ap instanceof AccessPathNil and emptyAp = true
2369+ ap instanceof PartialAccessPathNil and emptyAp = true
23152370 or
2316- ap instanceof AccessPathCons and emptyAp = false
2371+ ap instanceof PartialAccessPathCons and emptyAp = false
23172372 )
23182373 }
23192374
23202375 pragma [ nomagic]
23212376 private predicate partialPathIntoCallable0 (
23222377 PartialPathNodePriv mid , DataFlowCallable callable , int i , CallContext outercc ,
2323- DataFlowCall call , boolean emptyAp , AccessPath ap , Configuration config
2378+ DataFlowCall call , boolean emptyAp , PartialAccessPath ap , Configuration config
23242379 ) {
23252380 partialPathIntoArg ( mid , i , outercc , call , emptyAp , ap , config ) and
23262381 callable = resolveCall ( call , outercc )
23272382 }
23282383
23292384 private predicate partialPathIntoCallable (
23302385 PartialPathNodePriv mid , ParameterNode p , CallContext outercc , CallContextCall innercc ,
2331- DataFlowCall call , AccessPath ap , Configuration config
2386+ DataFlowCall call , PartialAccessPath ap , Configuration config
23322387 ) {
23332388 exists ( int i , DataFlowCallable callable , boolean emptyAp |
23342389 partialPathIntoCallable0 ( mid , callable , i , outercc , call , emptyAp , ap , config ) and
@@ -2342,7 +2397,8 @@ private module FlowExploration {
23422397
23432398 pragma [ nomagic]
23442399 private predicate paramFlowsThroughInPartialPath (
2345- ParameterNode p , ReturnKind kind , CallContextCall cc , AccessPathNil apnil , Configuration config
2400+ ParameterNode p , ReturnKind kind , CallContextCall cc , PartialAccessPathNil apnil ,
2401+ Configuration config
23462402 ) {
23472403 exists ( PartialPathNodePriv mid , ReturnNode ret |
23482404 mid .getNode ( ) = ret and
@@ -2362,17 +2418,18 @@ private module FlowExploration {
23622418 pragma [ noinline]
23632419 private predicate partialPathThroughCallable0 (
23642420 DataFlowCall call , PartialPathNodePriv mid , ReturnKind kind , CallContext cc ,
2365- AccessPathNil apnil , Configuration config
2421+ PartialAccessPathNil apnil , Configuration config
23662422 ) {
2367- exists ( ParameterNode p , CallContext innercc , AccessPathNil midapnil |
2423+ exists ( ParameterNode p , CallContext innercc , PartialAccessPathNil midapnil |
23682424 partialPathIntoCallable ( mid , p , cc , innercc , call , midapnil , config ) and
23692425 paramFlowsThroughInPartialPath ( p , kind , innercc , apnil , config ) and
23702426 not parameterValueFlowsThrough ( p , kind , innercc )
23712427 )
23722428 }
23732429
23742430 private predicate partialPathThroughCallable (
2375- PartialPathNodePriv mid , OutNode out , CallContext cc , AccessPathNil apnil , Configuration config
2431+ PartialPathNodePriv mid , OutNode out , CallContext cc , PartialAccessPathNil apnil ,
2432+ Configuration config
23762433 ) {
23772434 exists ( DataFlowCall call , ReturnKind kind |
23782435 partialPathThroughCallable0 ( call , mid , kind , cc , apnil , config ) and
@@ -2382,8 +2439,8 @@ private module FlowExploration {
23822439
23832440 pragma [ noinline]
23842441 private predicate valuePartialPathThroughCallable0 (
2385- DataFlowCall call , PartialPathNodePriv mid , ReturnKind kind , CallContext cc , AccessPath ap ,
2386- Configuration config
2442+ DataFlowCall call , PartialPathNodePriv mid , ReturnKind kind , CallContext cc ,
2443+ PartialAccessPath ap , Configuration config
23872444 ) {
23882445 exists ( ParameterNode p , CallContext innercc |
23892446 partialPathIntoCallable ( mid , p , cc , innercc , call , ap , config ) and
@@ -2392,7 +2449,7 @@ private module FlowExploration {
23922449 }
23932450
23942451 private predicate valuePartialPathThroughCallable (
2395- PartialPathNodePriv mid , OutNode out , CallContext cc , AccessPath ap , Configuration config
2452+ PartialPathNodePriv mid , OutNode out , CallContext cc , PartialAccessPath ap , Configuration config
23962453 ) {
23972454 exists ( DataFlowCall call , ReturnKind kind |
23982455 valuePartialPathThroughCallable0 ( call , mid , kind , cc , ap , config ) and
0 commit comments