@@ -345,12 +345,14 @@ module MakeModelGeneratorFactory<
345
345
/**
346
346
* Gets the summary model of `api`, if it follows the `fluent` programming pattern (returns `this`).
347
347
*/
348
- private string captureQualifierFlow ( DataFlowSummaryTargetApi api ) {
348
+ private string captureQualifierFlow ( DataFlowSummaryTargetApi api , string input , string output ) {
349
349
exists ( ReturnNodeExt ret |
350
350
api = returnNodeEnclosingCallable ( ret ) and
351
351
isOwnInstanceAccessNode ( ret )
352
352
) and
353
- result = ModelPrintingSummary:: asLiftedValueModel ( api , qualifierString ( ) , "ReturnValue" )
353
+ input = qualifierString ( ) and
354
+ output = "ReturnValue" and
355
+ result = ModelPrintingSummary:: asLiftedValueModel ( api , input , output )
354
356
}
355
357
356
358
private int accessPathLimit0 ( ) { result = 2 }
@@ -430,7 +432,7 @@ module MakeModelGeneratorFactory<
430
432
predicate isSink ( DataFlow:: Node sink ) {
431
433
sink instanceof ReturnNodeExt and
432
434
not isOwnInstanceAccessNode ( sink ) and
433
- not exists ( captureQualifierFlow ( getAsExprEnclosingCallable ( sink ) ) )
435
+ not exists ( captureQualifierFlow ( getAsExprEnclosingCallable ( sink ) , _ , _ ) )
434
436
}
435
437
436
438
predicate isAdditionalFlowStep = PropagateFlowConfigInput:: isAdditionalFlowStep / 4 ;
@@ -559,11 +561,24 @@ module MakeModelGeneratorFactory<
559
561
*
560
562
* `preservesValue` is `true` if the summary is value-preserving, and `false` otherwise.
561
563
*/
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 )
567
582
}
568
583
569
584
/**
@@ -573,9 +588,7 @@ module MakeModelGeneratorFactory<
573
588
* `preservesValue` is `true` if the summary is value-preserving, and `false` otherwise.
574
589
*/
575
590
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 )
579
592
}
580
593
581
594
/**
@@ -947,19 +960,20 @@ module MakeModelGeneratorFactory<
947
960
}
948
961
949
962
/**
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.
952
965
* `preservesValue` is `true` if the summary is value-preserving, and `false` otherwise.
953
966
*
954
967
* Models are lifted to the best type in case the read and store access paths do not
955
968
* contain a field or synthetic field access.
956
969
*/
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 )
963
977
}
964
978
}
965
979
@@ -972,23 +986,30 @@ module MakeModelGeneratorFactory<
972
986
* generate flow summaries using the heuristic based summary generator.
973
987
*/
974
988
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
984
1005
|
985
1006
( api0 = api or api .lift ( ) = api0 ) and
986
- exists ( ContentSensitive:: captureFlow ( api0 , false , _ ) )
1007
+ exists ( ContentSensitive:: captureFlow ( api0 , input0 , output0 , false , preservesValue0 ) )
987
1008
or
988
1009
api0 .lift ( ) = api .lift ( ) and
989
- exists ( ContentSensitive:: captureFlow ( api0 , true , _ ) )
1010
+ exists ( ContentSensitive:: captureFlow ( api0 , input0 , output0 , true , preservesValue0 ) )
990
1011
) and
991
- result = Heuristic:: captureFlow ( api , preservesValue ) and
1012
+ result = Heuristic:: captureFlow ( api , input , output , preservesValue ) and
992
1013
lift = true
993
1014
)
994
1015
}
0 commit comments