@@ -68,6 +68,7 @@ import java
68
68
private import semmle.code.java.dataflow.DataFlow:: DataFlow
69
69
private import internal.DataFlowPrivate
70
70
private import internal.FlowSummaryImpl:: Private:: External
71
+ private import internal.FlowSummaryImplSpecific
71
72
private import FlowSummary
72
73
73
74
/**
@@ -359,7 +360,8 @@ private predicate summaryModel(string row) {
359
360
any ( SummaryModelCsv s ) .row ( row )
360
361
}
361
362
362
- private predicate sourceModel (
363
+ /** Holds if a source model exists for the given parameters. */
364
+ predicate sourceModel (
363
365
string namespace , string type , boolean subtypes , string name , string signature , string ext ,
364
366
string output , string kind
365
367
) {
@@ -377,7 +379,8 @@ private predicate sourceModel(
377
379
)
378
380
}
379
381
380
- private predicate sinkModel (
382
+ /** Holds if a sink model exists for the given parameters. */
383
+ predicate sinkModel (
381
384
string namespace , string type , boolean subtypes , string name , string signature , string ext ,
382
385
string input , string kind
383
386
) {
@@ -395,7 +398,8 @@ private predicate sinkModel(
395
398
)
396
399
}
397
400
398
- private predicate summaryModel (
401
+ /** Holds if a summary model exists for the given parameters. */
402
+ predicate summaryModel (
399
403
string namespace , string type , boolean subtypes , string name , string signature , string ext ,
400
404
string input , string output , string kind
401
405
) {
@@ -600,7 +604,8 @@ private Element interpretElement0(
600
604
)
601
605
}
602
606
603
- private Element interpretElement (
607
+ /** Gets the source/sink/summary element corresponding to the supplied parameters. */
608
+ Element interpretElement (
604
609
string namespace , string type , boolean subtypes , string name , string signature , string ext
605
610
) {
606
611
elementSpec ( namespace , type , subtypes , name , signature , ext ) and
@@ -611,166 +616,25 @@ private Element interpretElement(
611
616
)
612
617
}
613
618
614
- private predicate sourceElement ( Element e , string output , string kind ) {
615
- exists (
616
- string namespace , string type , boolean subtypes , string name , string signature , string ext
617
- |
618
- sourceModel ( namespace , type , subtypes , name , signature , ext , output , kind ) and
619
- e = interpretElement ( namespace , type , subtypes , name , signature , ext )
620
- )
621
- }
622
-
623
- private predicate sinkElement ( Element e , string input , string kind ) {
624
- exists (
625
- string namespace , string type , boolean subtypes , string name , string signature , string ext
626
- |
627
- sinkModel ( namespace , type , subtypes , name , signature , ext , input , kind ) and
628
- e = interpretElement ( namespace , type , subtypes , name , signature , ext )
629
- )
630
- }
631
-
632
- /**
633
- * Holds if an external flow summary exists for `e` with input specification
634
- * `input`, output specification `output`, and kind `kind`.
635
- */
636
- predicate summaryElement ( Element e , string input , string output , string kind ) {
637
- exists (
638
- string namespace , string type , boolean subtypes , string name , string signature , string ext
639
- |
640
- summaryModel ( namespace , type , subtypes , name , signature , ext , input , output , kind ) and
641
- e = interpretElement ( namespace , type , subtypes , name , signature , ext )
642
- )
643
- }
644
-
645
- /** Gets a specification used in a source model, sink model, or summary model. */
646
- string inOutSpec ( ) {
647
- sourceModel ( _, _, _, _, _, _, result , _) or
648
- sinkModel ( _, _, _, _, _, _, result , _) or
649
- summaryModel ( _, _, _, _, _, _, result , _, _) or
650
- summaryModel ( _, _, _, _, _, _, _, result , _)
651
- }
652
-
653
- private predicate inputNeedsReference ( string c ) {
654
- c = "Argument" or
655
- parseArg ( c , _)
656
- }
657
-
658
- private predicate outputNeedsReference ( string c ) {
659
- c = "Argument" or
660
- parseArg ( c , _) or
661
- c = "ReturnValue"
662
- }
663
-
664
- private predicate sourceElementRef ( Top ref , string output , string kind ) {
665
- exists ( Element e |
666
- sourceElement ( e , output , kind ) and
667
- if outputNeedsReference ( specLast ( output ) )
668
- then ref .( Call ) .getCallee ( ) .getSourceDeclaration ( ) = e
669
- else ref = e
670
- )
671
- }
672
-
673
- private predicate sinkElementRef ( Top ref , string input , string kind ) {
674
- exists ( Element e |
675
- sinkElement ( e , input , kind ) and
676
- if inputNeedsReference ( specLast ( input ) )
677
- then ref .( Call ) .getCallee ( ) .getSourceDeclaration ( ) = e
678
- else ref = e
679
- )
680
- }
681
-
682
- private predicate summaryElementRef ( Top ref , string input , string output , string kind ) {
683
- exists ( Element e |
684
- summaryElement ( e , input , output , kind ) and
685
- if inputNeedsReference ( specLast ( input ) )
686
- then ref .( Call ) .getCallee ( ) .getSourceDeclaration ( ) = e
687
- else ref = e
688
- )
689
- }
690
-
691
- private newtype TAstOrNode =
692
- TAst ( Top t ) or
693
- TNode ( Node n )
694
-
695
- private predicate interpretOutput ( string output , int idx , Top ref , TAstOrNode node ) {
696
- (
697
- sourceElementRef ( ref , output , _) or
698
- summaryElementRef ( ref , _, output , _)
699
- ) and
700
- specLength ( output , idx ) and
701
- node = TAst ( ref )
702
- or
703
- exists ( Top mid , string c , Node n |
704
- interpretOutput ( output , idx + 1 , ref , TAst ( mid ) ) and
705
- specSplit ( output , c , idx ) and
706
- node = TNode ( n )
707
- |
708
- exists ( int pos | n .( PostUpdateNode ) .getPreUpdateNode ( ) .( ArgumentNode ) .argumentOf ( mid , pos ) |
709
- c = "Argument" or parseArg ( c , pos )
710
- )
711
- or
712
- exists ( int pos | n .( ParameterNode ) .isParameterOf ( mid , pos ) |
713
- c = "Parameter" or parseParam ( c , pos )
714
- )
715
- or
716
- ( c = "Parameter" or c = "" ) and
717
- n .asParameter ( ) = mid
718
- or
719
- c = "ReturnValue" and
720
- n .asExpr ( ) .( Call ) = mid
721
- or
722
- c = "" and
723
- n .asExpr ( ) .( FieldRead ) .getField ( ) = mid
724
- )
725
- }
726
-
727
- private predicate interpretInput ( string input , int idx , Top ref , TAstOrNode node ) {
728
- (
729
- sinkElementRef ( ref , input , _) or
730
- summaryElementRef ( ref , input , _, _)
731
- ) and
732
- specLength ( input , idx ) and
733
- node = TAst ( ref )
734
- or
735
- exists ( Top mid , string c , Node n |
736
- interpretInput ( input , idx + 1 , ref , TAst ( mid ) ) and
737
- specSplit ( input , c , idx ) and
738
- node = TNode ( n )
739
- |
740
- exists ( int pos | n .( ArgumentNode ) .argumentOf ( mid , pos ) | c = "Argument" or parseArg ( c , pos ) )
741
- or
742
- exists ( ReturnStmt ret |
743
- c = "ReturnValue" and
744
- n .asExpr ( ) = ret .getResult ( ) and
745
- mid = ret .getEnclosingCallable ( )
746
- )
747
- or
748
- exists ( FieldWrite fw |
749
- c = "" and
750
- fw .getField ( ) = mid and
751
- n .asExpr ( ) = fw .getRHS ( )
752
- )
753
- )
754
- }
619
+ cached
620
+ private module Cached {
621
+ /**
622
+ * Holds if `node` is specified as a source with the given kind in a CSV flow
623
+ * model.
624
+ */
625
+ cached
626
+ predicate sourceNode ( Node node , string kind ) {
627
+ exists ( InterpretNode n | isSourceNode ( n , kind ) and n .asNode ( ) = node )
628
+ }
755
629
756
- /**
757
- * Holds if `node` is specified as a source with the given kind in a CSV flow
758
- * model.
759
- */
760
- predicate sourceNode ( Node node , string kind ) {
761
- exists ( Top ref , string output |
762
- sourceElementRef ( ref , output , kind ) and
763
- interpretOutput ( output , 0 , ref , TNode ( node ) )
764
- )
630
+ /**
631
+ * Holds if `node` is specified as a sink with the given kind in a CSV flow
632
+ * model.
633
+ */
634
+ cached
635
+ predicate sinkNode ( Node node , string kind ) {
636
+ exists ( InterpretNode n | isSinkNode ( n , kind ) and n .asNode ( ) = node )
637
+ }
765
638
}
766
639
767
- /**
768
- * Holds if `node` is specified as a sink with the given kind in a CSV flow
769
- * model.
770
- */
771
- predicate sinkNode ( Node node , string kind ) {
772
- exists ( Top ref , string input |
773
- sinkElementRef ( ref , input , kind ) and
774
- interpretInput ( input , 0 , ref , TNode ( node ) )
775
- )
776
- }
640
+ import Cached
0 commit comments