67
67
import java
68
68
private import semmle.code.java.dataflow.DataFlow:: DataFlow
69
69
private import internal.DataFlowPrivate
70
+ private import FlowSummary
70
71
71
72
/**
72
73
* A module importing the frameworks that provide external flow data,
@@ -459,7 +460,8 @@ module CsvValidation {
459
460
summaryModel ( _, _, _, _, _, _, input , _, _) and pred = "summary"
460
461
|
461
462
specSplit ( input , part , _) and
462
- not part .regexpMatch ( "|Argument|ReturnValue" ) and
463
+ not part .regexpMatch ( "|ReturnValue|ArrayElement|Element" ) and
464
+ not ( part = "Argument" and pred = "sink" ) and
463
465
not parseArg ( part , _) and
464
466
msg = "Unrecognized input specification \"" + part + "\" in " + pred + " model."
465
467
)
@@ -470,7 +472,8 @@ module CsvValidation {
470
472
summaryModel ( _, _, _, _, _, _, _, output , _) and pred = "summary"
471
473
|
472
474
specSplit ( output , part , _) and
473
- not part .regexpMatch ( "|Argument|Parameter|ReturnValue" ) and
475
+ not part .regexpMatch ( "|ReturnValue|ArrayElement|Element" ) and
476
+ not ( part = [ "Argument" , "Parameter" ] and pred = "source" ) and
474
477
not parseArg ( part , _) and
475
478
not parseParam ( part , _) and
476
479
msg = "Unrecognized output specification \"" + part + "\" in " + pred + " model."
@@ -675,6 +678,75 @@ private predicate summaryElementRef(Top ref, string input, string output, string
675
678
)
676
679
}
677
680
681
+ private SummaryComponent interpretComponent ( string c ) {
682
+ specSplit ( _, c , _) and
683
+ (
684
+ exists ( int pos | parseArg ( c , pos ) and result = SummaryComponent:: argument ( pos ) )
685
+ or
686
+ exists ( int pos | parseParam ( c , pos ) and result = SummaryComponent:: parameter ( pos ) )
687
+ or
688
+ c = "ReturnValue" and result = SummaryComponent:: return ( )
689
+ or
690
+ c = "ArrayElement" and result = SummaryComponent:: content ( any ( ArrayContent c0 ) )
691
+ or
692
+ c = "Element" and result = SummaryComponent:: content ( any ( CollectionContent c0 ) )
693
+ // or
694
+ // c = "MapKey" and result = SummaryComponent::content(any(MapKeyContent c0))
695
+ // or
696
+ // c = "MapValue" and result = SummaryComponent::content(any(MapValueContent c0))
697
+ )
698
+ }
699
+
700
+ private predicate interpretSpec ( string spec , int idx , SummaryComponentStack stack ) {
701
+ exists ( string c |
702
+ summaryElement ( _, spec , _, _) or
703
+ summaryElement ( _, _, spec , _)
704
+ |
705
+ len ( spec , idx + 1 ) and
706
+ specSplit ( spec , c , idx ) and
707
+ stack = SummaryComponentStack:: singleton ( interpretComponent ( c ) )
708
+ )
709
+ or
710
+ exists ( SummaryComponent head , SummaryComponentStack tail |
711
+ interpretSpec ( spec , idx , head , tail ) and
712
+ stack = SummaryComponentStack:: push ( head , tail )
713
+ )
714
+ }
715
+
716
+ private predicate interpretSpec (
717
+ string output , int idx , SummaryComponent head , SummaryComponentStack tail
718
+ ) {
719
+ exists ( string c |
720
+ interpretSpec ( output , idx + 1 , tail ) and
721
+ specSplit ( output , c , idx ) and
722
+ head = interpretComponent ( c )
723
+ )
724
+ }
725
+
726
+ private class MkStack extends RequiredSummaryComponentStack {
727
+ MkStack ( ) { interpretSpec ( _, _, _, this ) }
728
+
729
+ override predicate required ( SummaryComponent c ) { interpretSpec ( _, _, c , this ) }
730
+ }
731
+
732
+ private class SummarizedCallableExternal extends SummarizedCallable {
733
+ SummarizedCallableExternal ( ) { summaryElement ( this , _, _, _) }
734
+
735
+ override predicate propagatesFlow (
736
+ SummaryComponentStack input , SummaryComponentStack output , boolean preservesValue
737
+ ) {
738
+ exists ( string inSpec , string outSpec , string kind |
739
+ summaryElement ( this , inSpec , outSpec , kind ) and
740
+ interpretSpec ( inSpec , 0 , input ) and
741
+ interpretSpec ( outSpec , 0 , output )
742
+ |
743
+ kind = "value" and preservesValue = true
744
+ or
745
+ kind = "taint" and preservesValue = false
746
+ )
747
+ }
748
+ }
749
+
678
750
private newtype TAstOrNode =
679
751
TAst ( Top t ) or
680
752
TNode ( Node n )
@@ -761,15 +833,3 @@ predicate sinkNode(Node node, string kind) {
761
833
interpretInput ( input , 0 , ref , TNode ( node ) )
762
834
)
763
835
}
764
-
765
- /**
766
- * Holds if `node1` to `node2` is specified as a flow step with the given kind
767
- * in a CSV flow model.
768
- */
769
- predicate summaryStep ( Node node1 , Node node2 , string kind ) {
770
- exists ( Top ref , string input , string output |
771
- summaryElementRef ( ref , input , output , kind ) and
772
- interpretInput ( input , 0 , ref , TNode ( node1 ) ) and
773
- interpretOutput ( output , 0 , ref , TNode ( node2 ) )
774
- )
775
- }
0 commit comments