@@ -127,6 +127,38 @@ module Public {
127
127
SummaryComponentStack return ( ReturnKind rk ) { result = singleton ( SummaryComponent:: return ( rk ) ) }
128
128
}
129
129
130
+ private predicate noComponentSpecificCsv ( SummaryComponent sc ) {
131
+ not exists ( getComponentSpecificCsv ( sc ) )
132
+ }
133
+
134
+ /** Gets a textual representation of this component used for flow summaries. */
135
+ private string getComponentCsv ( SummaryComponent sc ) {
136
+ result = getComponentSpecificCsv ( sc )
137
+ or
138
+ noComponentSpecificCsv ( sc ) and
139
+ (
140
+ exists ( int i | sc = TParameterSummaryComponent ( i ) and result = "Parameter[" + i + "]" )
141
+ or
142
+ exists ( int i | sc = TArgumentSummaryComponent ( i ) and result = "Argument[" + i + "]" )
143
+ or
144
+ sc = TReturnSummaryComponent ( getReturnValueKind ( ) ) and result = "ReturnValue"
145
+ )
146
+ }
147
+
148
+ /** Gets a textual representation of this stack used for flow summaries. */
149
+ string getComponentStackCsv ( SummaryComponentStack stack ) {
150
+ exists ( SummaryComponent head , SummaryComponentStack tail |
151
+ head = stack .head ( ) and
152
+ tail = stack .tail ( ) and
153
+ result = getComponentCsv ( head ) + " of " + getComponentStackCsv ( tail )
154
+ )
155
+ or
156
+ exists ( SummaryComponent c |
157
+ stack = TSingletonSummaryComponentStack ( c ) and
158
+ result = getComponentCsv ( c )
159
+ )
160
+ }
161
+
130
162
/**
131
163
* A class that exists for QL technical reasons only (the IPA type used
132
164
* to represent component stacks needs to be bounded).
@@ -970,18 +1002,31 @@ module Private {
970
1002
module TestOutput {
971
1003
/** A flow summary to include in the `summary/3` query predicate. */
972
1004
abstract class RelevantSummarizedCallable extends SummarizedCallable {
973
- /** Gets the string representation of this callable used by `summary/3 `. */
974
- string getFullString ( ) { result = this . toString ( ) }
1005
+ /** Gets the string representation of this callable used by `summary/1 `. */
1006
+ abstract string getCallableCsv ( ) ;
975
1007
}
976
1008
977
- /** A query predicate for outputting flow summaries in QL tests. */
978
- query predicate summary ( string callable , string flow , boolean preservesValue ) {
1009
+ /** Render the kind in the format used in flow summaries. */
1010
+ private string renderKind ( boolean preservesValue ) {
1011
+ preservesValue = true and result = "value"
1012
+ or
1013
+ preservesValue = false and result = "taint"
1014
+ }
1015
+
1016
+ /**
1017
+ * A query predicate for outputting flow summaries in semi-colon separated format in QL tests.
1018
+ * The syntax is: "namespace;type;overrides;name;signature;ext;inputspec;outputspec;kind",
1019
+ * ext is hardcoded to empty.
1020
+ */
1021
+ query predicate summary ( string csv ) {
979
1022
exists (
980
- RelevantSummarizedCallable c , SummaryComponentStack input , SummaryComponentStack output
1023
+ RelevantSummarizedCallable c , SummaryComponentStack input , SummaryComponentStack output ,
1024
+ boolean preservesValue
981
1025
|
982
- callable = c .getFullString ( ) and
983
1026
c .propagatesFlow ( input , output , preservesValue ) and
984
- flow = input + " -> " + output
1027
+ csv =
1028
+ c .getCallableCsv ( ) + ";;" + getComponentStackCsv ( input ) + ";" +
1029
+ getComponentStackCsv ( output ) + ";" + renderKind ( preservesValue )
985
1030
)
986
1031
}
987
1032
}
0 commit comments