@@ -8,6 +8,7 @@ private import DataFlowUtil
88private import FlowSummaryImpl:: Private
99private import FlowSummaryImpl:: Public
1010private import semmle.go.dataflow.ExternalFlow
11+ private import DataFlowImplCommon
1112
1213private module FlowSummaries {
1314 private import semmle.go.dataflow.FlowSummary as F
@@ -65,6 +66,8 @@ predicate summaryElement(DataFlowCallable c, string input, string output, string
6566/** Gets the summary component for specification component `c`, if any. */
6667bindingset [ c]
6768SummaryComponent interpretComponentSpecific ( string c ) {
69+ exists ( int pos | parseReturn ( c , pos ) and result = SummaryComponent:: return ( getReturnKind ( pos ) ) )
70+ or
6871 exists ( Content content | parseContent ( c , content ) and result = SummaryComponent:: content ( content ) )
6972}
7073
@@ -92,8 +95,20 @@ private string getContentSpecificCsv(Content c) {
9295/** Gets the textual representation of the content in the format used for flow summaries. */
9396string getComponentSpecificCsv ( SummaryComponent sc ) {
9497 exists ( Content c | sc = TContentSummaryComponent ( c ) and result = getContentSpecificCsv ( c ) )
98+ or
99+ exists ( ReturnKind rk , int n | n = rk .getIndex ( ) |
100+ sc = TReturnSummaryComponent ( rk ) and
101+ result = "ReturnValue[" + n + "]" and
102+ n != 0
103+ )
95104}
96105
106+ /** Holds if input specification component `c` needs a reference. */
107+ predicate inputNeedsReferenceSpecific ( string c ) { none ( ) }
108+
109+ /** Holds if output specification component `c` needs a reference. */
110+ predicate outputNeedsReferenceSpecific ( string c ) { parseReturn ( c , _) }
111+
97112private newtype TSourceOrSinkElement =
98113 TEntityElement ( Entity e ) or
99114 TAstElement ( AstNode n )
@@ -144,7 +159,7 @@ predicate sinkElement(SourceOrSinkElement e, string input, string kind) {
144159}
145160
146161/** Gets the return kind corresponding to specification `"ReturnValue"`. */
147- ReturnKind getReturnValueKind ( ) { any ( ) }
162+ ReturnKind getReturnValueKind ( ) { result = getReturnKind ( 0 ) }
148163
149164private newtype TInterpretNode =
150165 TElement ( SourceOrSinkElement n ) or
@@ -191,6 +206,10 @@ class InterpretNode extends TInterpretNode {
191206/** Provides additional sink specification logic required for annotations. */
192207pragma [ inline]
193208predicate interpretOutputSpecific ( string c , InterpretNode mid , InterpretNode node ) {
209+ exists ( int pos | node .asNode ( ) = getAnOutNodeExt ( mid .asCall ( ) , TValueReturn ( getReturnKind ( pos ) ) ) |
210+ parseReturn ( c , pos )
211+ )
212+ or
194213 exists ( Node n , SourceOrSinkElement e |
195214 n = node .asNode ( ) and
196215 e = mid .asElement ( )
@@ -206,9 +225,32 @@ predicate interpretOutputSpecific(string c, InterpretNode mid, InterpretNode nod
206225/** Provides additional source specification logic required for annotations. */
207226pragma [ inline]
208227predicate interpretInputSpecific ( string c , InterpretNode mid , InterpretNode n ) {
228+ exists ( int pos , ReturnNodeExt ret |
229+ parseReturn ( c , pos ) and
230+ ret = n .asNode ( ) and
231+ ret .getKind ( ) .( ValueReturnKind ) .getKind ( ) = getReturnKind ( pos ) and
232+ mid .asCallable ( ) = getNodeEnclosingCallable ( ret )
233+ )
234+ or
209235 exists ( DataFlow:: Write fw , Field f |
210236 c = "" and
211237 f = mid .asElement ( ) .asEntity ( ) and
212238 fw .writesField ( _, f , n .asNode ( ) )
213239 )
214240}
241+
242+ /** Holds if specification component `c` parses as return value `n`. */
243+ predicate parseReturn ( string c , int n ) {
244+ External:: specSplit ( _, c , _) and
245+ (
246+ c = "ReturnValue" and n = 0
247+ or
248+ c .regexpCapture ( "ReturnValue\\[([-0-9]+)\\]" , 1 ) .toInt ( ) = n
249+ or
250+ exists ( int n1 , int n2 |
251+ c .regexpCapture ( "ReturnValue\\[([-0-9]+)\\.\\.([0-9]+)\\]" , 1 ) .toInt ( ) = n1 and
252+ c .regexpCapture ( "ReturnValue\\[([-0-9]+)\\.\\.([0-9]+)\\]" , 2 ) .toInt ( ) = n2 and
253+ n = [ n1 .. n2 ]
254+ )
255+ )
256+ }
0 commit comments