@@ -345,12 +345,14 @@ module MakeModelGeneratorFactory<
345345 /**
346346 * Gets the summary model of `api`, if it follows the `fluent` programming pattern (returns `this`).
347347 */
348- private string captureQualifierFlow ( DataFlowSummaryTargetApi api ) {
348+ private string captureQualifierFlow ( DataFlowSummaryTargetApi api , string input , string output ) {
349349 exists ( ReturnNodeExt ret |
350350 api = returnNodeEnclosingCallable ( ret ) and
351351 isOwnInstanceAccessNode ( ret )
352352 ) and
353- result = ModelPrintingSummary:: asLiftedValueModel ( api , qualifierString ( ) , "ReturnValue" )
353+ input = qualifierString ( ) and
354+ output = "ReturnValue" and
355+ result = ModelPrintingSummary:: asLiftedValueModel ( api , input , output )
354356 }
355357
356358 private int accessPathLimit0 ( ) { result = 2 }
@@ -430,7 +432,7 @@ module MakeModelGeneratorFactory<
430432 predicate isSink ( DataFlow:: Node sink ) {
431433 sink instanceof ReturnNodeExt and
432434 not isOwnInstanceAccessNode ( sink ) and
433- not exists ( captureQualifierFlow ( getAsExprEnclosingCallable ( sink ) ) )
435+ not exists ( captureQualifierFlow ( getAsExprEnclosingCallable ( sink ) , _ , _ ) )
434436 }
435437
436438 predicate isAdditionalFlowStep = PropagateFlowConfigInput:: isAdditionalFlowStep / 4 ;
@@ -559,11 +561,24 @@ module MakeModelGeneratorFactory<
559561 *
560562 * `preservesValue` is `true` if the summary is value-preserving, and `false` otherwise.
561563 */
562- private string captureThroughFlow ( DataFlowSummaryTargetApi api , boolean preservesValue ) {
563- exists ( string input , string output |
564- preservesValue = max ( boolean b | captureThroughFlow0 ( api , _, input , _, output , b ) ) and
565- result = ModelPrintingSummary:: asLiftedModel ( api , input , output , preservesValue )
566- )
564+ private string captureThroughFlow (
565+ DataFlowSummaryTargetApi api , string input , string output , boolean preservesValue
566+ ) {
567+ preservesValue = max ( boolean b | captureThroughFlow0 ( api , _, input , _, output , b ) ) and
568+ result = ModelPrintingSummary:: asLiftedModel ( api , input , output , preservesValue )
569+ }
570+
571+ /**
572+ * Gets the summary model(s) of `api`, if there is flow `input` to
573+ * `output`. `preservesValue` is `true` if the summary is value-
574+ * preserving, and `false` otherwise.
575+ */
576+ string captureFlow (
577+ DataFlowSummaryTargetApi api , string input , string output , boolean preservesValue
578+ ) {
579+ result = captureQualifierFlow ( api , input , output ) and preservesValue = true
580+ or
581+ result = captureThroughFlow ( api , input , output , preservesValue )
567582 }
568583
569584 /**
@@ -573,9 +588,7 @@ module MakeModelGeneratorFactory<
573588 * `preservesValue` is `true` if the summary is value-preserving, and `false` otherwise.
574589 */
575590 string captureFlow ( DataFlowSummaryTargetApi api , boolean preservesValue ) {
576- result = captureQualifierFlow ( api ) and preservesValue = true
577- or
578- result = captureThroughFlow ( api , preservesValue )
591+ result = captureFlow ( api , _, _, preservesValue )
579592 }
580593
581594 /**
@@ -947,19 +960,20 @@ module MakeModelGeneratorFactory<
947960 }
948961
949962 /**
950- * Gets the content based summary model(s) of the API `api` (if there is flow from a parameter to
951- * the return value or a parameter ). `lift` is true, if the model should be lifted, otherwise false.
963+ * Gets the content based summary model(s) of the API `api` (if there is flow from `input` to
964+ * `output` ). `lift` is true, if the model should be lifted, otherwise false.
952965 * `preservesValue` is `true` if the summary is value-preserving, and `false` otherwise.
953966 *
954967 * Models are lifted to the best type in case the read and store access paths do not
955968 * contain a field or synthetic field access.
956969 */
957- string captureFlow ( ContentDataFlowSummaryTargetApi api , boolean lift , boolean preservesValue ) {
958- exists ( string input , string output |
959- captureFlow0 ( api , input , output , _, lift ) and
960- preservesValue = max ( boolean p | captureFlow0 ( api , input , output , p , lift ) ) and
961- result = ContentModelPrinting:: asModel ( api , input , output , preservesValue , lift )
962- )
970+ string captureFlow (
971+ ContentDataFlowSummaryTargetApi api , string input , string output , boolean lift ,
972+ boolean preservesValue
973+ ) {
974+ captureFlow0 ( api , input , output , _, lift ) and
975+ preservesValue = max ( boolean p | captureFlow0 ( api , input , output , p , lift ) ) and
976+ result = ContentModelPrinting:: asModel ( api , input , output , preservesValue , lift )
963977 }
964978 }
965979
@@ -972,23 +986,30 @@ module MakeModelGeneratorFactory<
972986 * generate flow summaries using the heuristic based summary generator.
973987 */
974988 string captureFlow ( DataFlowSummaryTargetApi api , boolean lift ) {
975- exists ( boolean preservesValue |
976- result = ContentSensitive:: captureFlow ( api , lift , preservesValue )
977- or
978- not exists ( DataFlowSummaryTargetApi api0 |
979- // If the heuristic summary is value-preserving then we keep both
980- // summaries. However, if we can generate any content-sensitive
981- // summary (value-preserving or not) then we don't include any taint-
982- // based heuristic summary.
983- preservesValue = false
989+ result = ContentSensitive:: captureFlow ( api , _, _, lift , _)
990+ or
991+ exists ( boolean preservesValue , string input , string output |
992+ not exists (
993+ DataFlowSummaryTargetApi api0 , string input0 , string output0 , boolean preservesValue0
994+ |
995+ // If the heuristic summary is taint-based, and we can generate a content-sensitive
996+ // summary that is value-preserving then we omit generating any heuristic summary.
997+ preservesValue = false and
998+ preservesValue0 = true
999+ or
1000+ // However, if they're both value-preserving (or both taint-based) then we only
1001+ // generate a heuristic summary if we didn't generate a content-sensitive summary.
1002+ preservesValue = preservesValue0 and
1003+ input0 = input and
1004+ output0 = output
9841005 |
9851006 ( api0 = api or api .lift ( ) = api0 ) and
986- exists ( ContentSensitive:: captureFlow ( api0 , false , _ ) )
1007+ exists ( ContentSensitive:: captureFlow ( api0 , input0 , output0 , false , preservesValue0 ) )
9871008 or
9881009 api0 .lift ( ) = api .lift ( ) and
989- exists ( ContentSensitive:: captureFlow ( api0 , true , _ ) )
1010+ exists ( ContentSensitive:: captureFlow ( api0 , input0 , output0 , true , preservesValue0 ) )
9901011 ) and
991- result = Heuristic:: captureFlow ( api , preservesValue ) and
1012+ result = Heuristic:: captureFlow ( api , input , output , preservesValue ) and
9921013 lift = true
9931014 )
9941015 }
0 commit comments