@@ -8,6 +8,8 @@ private import semmle.javascript.dataflow.internal.VariableCapture
88private import semmle.javascript.dataflow.internal.sharedlib.DataFlowImplCommon as DataFlowImplCommon
99private import semmle.javascript.internal.flow_summaries.AllFlowSummaries
1010private import sharedlib.FlowSummaryImpl as FlowSummaryImpl
11+ private import semmle.javascript.dataflow.internal.FlowSummaryPrivate as FlowSummaryPrivate
12+ private import semmle.javascript.dataflow.FlowSummary as FlowSummary
1113private import semmle.javascript.dataflow.internal.BarrierGuards
1214
1315class DataFlowSecondLevelScope = Unit ;
@@ -117,7 +119,8 @@ private DataFlow::Node getAnOutNodeImpl(DataFlowCall call, ReturnKind kind) {
117119 or
118120 kind = MkNormalReturnKind ( ) and result = call .asAccessorCall ( ) .( DataFlow:: PropRead )
119121 or
120- FlowSummaryImpl:: Private:: summaryOutNode ( call , result .( FlowSummaryNode ) .getSummaryNode ( ) , kind )
122+ FlowSummaryImpl:: Private:: summaryOutNode ( call .( SummaryCall ) .getReceiver ( ) ,
123+ result .( FlowSummaryNode ) .getSummaryNode ( ) , kind )
121124}
122125
123126class ReturnNode extends DataFlow:: Node {
@@ -275,7 +278,8 @@ private predicate isArgumentNodeImpl(Node n, DataFlowCall call, ArgumentPosition
275278 // argument to setter (TODO: this has no post-update node)
276279 pos .asPositional ( ) = 0 and n = call .asAccessorCall ( ) .( DataFlow:: PropWrite ) .getRhs ( )
277280 or
278- FlowSummaryImpl:: Private:: summaryArgumentNode ( call , n .( FlowSummaryNode ) .getSummaryNode ( ) , pos )
281+ FlowSummaryImpl:: Private:: summaryArgumentNode ( call .( SummaryCall ) .getReceiver ( ) ,
282+ n .( FlowSummaryNode ) .getSummaryNode ( ) , pos )
279283}
280284
281285predicate isArgumentNode ( ArgumentNode n , DataFlowCall call , ArgumentPosition pos ) {
@@ -802,8 +806,8 @@ private predicate valuePreservingStep(Node node1, Node node2) {
802806 or
803807 node2 = FlowSteps:: getThrowTarget ( node1 )
804808 or
805- FlowSummaryImpl :: Private :: Steps:: summaryLocalStep ( node1 .( FlowSummaryNode ) .getSummaryNode ( ) ,
806- node2 .( FlowSummaryNode ) .getSummaryNode ( ) , true )
809+ FlowSummaryPrivate :: Steps:: summaryLocalStep ( node1 .( FlowSummaryNode ) .getSummaryNode ( ) ,
810+ node2 .( FlowSummaryNode ) .getSummaryNode ( ) , true , _ ) // TODO: preserve 'model'
807811 or
808812 // Step from post-update nodes to local sources of the pre-update node. This emulates how JS usually tracks side effects.
809813 exists ( PostUpdateNode postUpdate |
@@ -828,7 +832,7 @@ predicate simpleLocalFlowStep(Node node1, Node node2) {
828832 nodeGetEnclosingCallable ( pragma [ only_bind_out ] ( node2 ) )
829833 or
830834 exists ( FlowSummaryImpl:: Private:: SummaryNode input , FlowSummaryImpl:: Private:: SummaryNode output |
831- FlowSummaryImpl :: Private :: Steps:: summaryStoreStep ( input , MkAwaited ( ) , output ) and
835+ FlowSummaryPrivate :: Steps:: summaryStoreStep ( input , MkAwaited ( ) , output ) and
832836 node1 = TFlowSummaryNode ( input ) and
833837 (
834838 node2 = TFlowSummaryNode ( output ) and
@@ -837,7 +841,7 @@ predicate simpleLocalFlowStep(Node node1, Node node2) {
837841 node2 = TFlowSummaryIntermediateAwaitStoreNode ( input )
838842 )
839843 or
840- FlowSummaryImpl :: Private :: Steps:: summaryReadStep ( input , MkAwaited ( ) , output ) and
844+ FlowSummaryPrivate :: Steps:: summaryReadStep ( input , MkAwaited ( ) , output ) and
841845 node1 = TFlowSummaryNode ( input ) and
842846 node2 = TFlowSummaryNode ( output )
843847 )
@@ -859,7 +863,7 @@ predicate jumpStep(Node node1, Node node2) {
859863 valuePreservingStep ( node1 , node2 ) and
860864 node1 .getContainer ( ) != node2 .getContainer ( )
861865 or
862- FlowSummaryImpl :: Private :: Steps:: summaryJumpStep ( node1 .( FlowSummaryNode ) .getSummaryNode ( ) ,
866+ FlowSummaryPrivate :: Steps:: summaryJumpStep ( node1 .( FlowSummaryNode ) .getSummaryNode ( ) ,
863867 node2 .( FlowSummaryNode ) .getSummaryNode ( ) )
864868 or
865869 DataFlow:: AdditionalFlowStep:: jumpStep ( node1 , node2 )
@@ -882,8 +886,8 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
882886 )
883887 or
884888 exists ( ContentSet contentSet |
885- FlowSummaryImpl :: Private :: Steps:: summaryReadStep ( node1 .( FlowSummaryNode ) .getSummaryNode ( ) ,
886- contentSet , node2 .( FlowSummaryNode ) .getSummaryNode ( ) )
889+ FlowSummaryPrivate :: Steps:: summaryReadStep ( node1 .( FlowSummaryNode ) .getSummaryNode ( ) , contentSet ,
890+ node2 .( FlowSummaryNode ) .getSummaryNode ( ) )
887891 |
888892 not isSpecialContentSet ( contentSet ) and
889893 c = contentSet
@@ -894,7 +898,7 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
894898 or
895899 // For deep reads, generate read edges with a self-loop
896900 exists ( Node origin , ContentSet contentSet |
897- FlowSummaryImpl :: Private :: Steps:: summaryReadStep ( origin .( FlowSummaryNode ) .getSummaryNode ( ) ,
901+ FlowSummaryPrivate :: Steps:: summaryReadStep ( origin .( FlowSummaryNode ) .getSummaryNode ( ) ,
898902 contentSet , node2 .( FlowSummaryNode ) .getSummaryNode ( ) ) and
899903 node1 = [ origin , node2 ]
900904 |
@@ -938,13 +942,13 @@ predicate storeStep(Node node1, ContentSet c, Node node2) {
938942 node2 = tryGetPostUpdate ( write .getBase ( ) )
939943 )
940944 or
941- FlowSummaryImpl :: Private :: Steps:: summaryStoreStep ( node1 .( FlowSummaryNode ) .getSummaryNode ( ) , c ,
945+ FlowSummaryPrivate :: Steps:: summaryStoreStep ( node1 .( FlowSummaryNode ) .getSummaryNode ( ) , c ,
942946 node2 .( FlowSummaryNode ) .getSummaryNode ( ) ) and
943947 not isSpecialContentSet ( c )
944948 or
945949 // Store into Awaited
946950 exists ( FlowSummaryImpl:: Private:: SummaryNode input , FlowSummaryImpl:: Private:: SummaryNode output |
947- FlowSummaryImpl :: Private :: Steps:: summaryStoreStep ( input , MkAwaited ( ) , output ) and
951+ FlowSummaryPrivate :: Steps:: summaryStoreStep ( input , MkAwaited ( ) , output ) and
948952 node1 = TFlowSummaryIntermediateAwaitStoreNode ( input ) and
949953 node2 = TFlowSummaryNode ( output ) and
950954 c = ContentSet:: promiseValue ( )
@@ -964,15 +968,14 @@ predicate storeStep(Node node1, ContentSet c, Node node2) {
964968 * in `x.f = newValue`.
965969 */
966970predicate clearsContent ( Node n , ContentSet c ) {
967- FlowSummaryImpl :: Private :: Steps:: summaryClearsContent ( n .( FlowSummaryNode ) .getSummaryNode ( ) , c )
971+ FlowSummaryPrivate :: Steps:: summaryClearsContent ( n .( FlowSummaryNode ) .getSummaryNode ( ) , c )
968972 or
969973 // Clear promise content before storing into promise value, to avoid creating nested promises
970974 n = TFlowSummaryIntermediateAwaitStoreNode ( _) and
971975 c = MkPromiseFilter ( )
972976 or
973977 // After reading from Awaited, the output must not be stored in a promise content
974- FlowSummaryImpl:: Private:: Steps:: summaryReadStep ( _, MkAwaited ( ) ,
975- n .( FlowSummaryNode ) .getSummaryNode ( ) ) and
978+ FlowSummaryPrivate:: Steps:: summaryReadStep ( _, MkAwaited ( ) , n .( FlowSummaryNode ) .getSummaryNode ( ) ) and
976979 c = MkPromiseFilter ( )
977980 or
978981 any ( AdditionalFlowInternal flow ) .clearsContent ( n , c )
@@ -998,12 +1001,11 @@ predicate clearsContent(Node n, ContentSet c) {
9981001 * at node `n`.
9991002 */
10001003predicate expectsContent ( Node n , ContentSet c ) {
1001- FlowSummaryImpl :: Private :: Steps:: summaryExpectsContent ( n .( FlowSummaryNode ) .getSummaryNode ( ) , c )
1004+ FlowSummaryPrivate :: Steps:: summaryExpectsContent ( n .( FlowSummaryNode ) .getSummaryNode ( ) , c )
10021005 or
10031006 // After storing into Awaited, the result must be stored in a promise-content.
10041007 // There is a value step from the input directly to this node, hence the need for expectsContent.
1005- FlowSummaryImpl:: Private:: Steps:: summaryStoreStep ( _, MkAwaited ( ) ,
1006- n .( FlowSummaryNode ) .getSummaryNode ( ) ) and
1008+ FlowSummaryPrivate:: Steps:: summaryStoreStep ( _, MkAwaited ( ) , n .( FlowSummaryNode ) .getSummaryNode ( ) ) and
10071009 c = MkPromiseFilter ( )
10081010 or
10091011 any ( AdditionalFlowInternal flow ) .expectsContent ( n , c )
@@ -1035,7 +1037,10 @@ int accessPathLimit() { result = 2 }
10351037 * by default as a heuristic.
10361038 */
10371039predicate allowParameterReturnInSelf ( ParameterNode p ) {
1038- FlowSummaryImpl:: Private:: summaryAllowParameterReturnInSelf ( p )
1040+ exists ( DataFlowCallable callable , ParameterPosition pos |
1041+ isParameterNodeImpl ( p , callable , pos ) and
1042+ FlowSummaryImpl:: Private:: summaryAllowParameterReturnInSelf ( callable .asLibraryCallable ( ) , pos )
1043+ )
10391044 or
10401045 exists ( Function f |
10411046 VariableCaptureOutput:: heuristicAllowInstanceParameterReturnInSelf ( f ) and
0 commit comments