@@ -127,6 +127,38 @@ module Public {
127127 SummaryComponentStack return ( ReturnKind rk ) { result = singleton ( SummaryComponent:: return ( rk ) ) }
128128 }
129129
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+
130162 /**
131163 * A class that exists for QL technical reasons only (the IPA type used
132164 * to represent component stacks needs to be bounded).
@@ -970,18 +1002,31 @@ module Private {
9701002 module TestOutput {
9711003 /** A flow summary to include in the `summary/3` query predicate. */
9721004 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 ( ) ;
9751007 }
9761008
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 ) {
9791022 exists (
980- RelevantSummarizedCallable c , SummaryComponentStack input , SummaryComponentStack output
1023+ RelevantSummarizedCallable c , SummaryComponentStack input , SummaryComponentStack output ,
1024+ boolean preservesValue
9811025 |
982- callable = c .getFullString ( ) and
9831026 c .propagatesFlow ( input , output , preservesValue ) and
984- flow = input + " -> " + output
1027+ csv =
1028+ c .getCallableCsv ( ) + ";;" + getComponentStackCsv ( input ) + ";" +
1029+ getComponentStackCsv ( output ) + ";" + renderKind ( preservesValue )
9851030 )
9861031 }
9871032 }
0 commit comments