@@ -17,11 +17,9 @@ module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
1717
1818 class SummarizedCallableBase = Function ;
1919
20- class SourceBase extends Void {
21- Location getLocation ( ) { none ( ) }
22- }
20+ class SourceBase = Function ;
2321
24- class SinkBase = SourceBase ;
22+ class SinkBase = Function ;
2523
2624 class FlowSummaryCallBase = CallInstruction ;
2725
@@ -134,15 +132,120 @@ module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
134132
135133private import Make< Location , DataFlowImplSpecific:: CppDataFlow , Input > as Impl
136134
135+ private class ConversionCall extends Call {
136+ ConversionCall ( ) { this .getTarget ( ) instanceof ConversionOperator }
137+ }
138+
137139private module Input2 implements Impl:: Private:: InputSig2 {
138140 private import codeql.util.Void
139141
140- class SourceSinkReportingElement extends Void {
141- Location getLocation ( ) { none ( ) }
142+ class SourceSinkReportingElement extends Element {
143+ SourceSinkReportingElement ( ) { this instanceof Expr or this instanceof Parameter }
144+
145+ DataFlowCallable getEnclosingCallable ( ) {
146+ result .asSourceCallable ( ) =
147+ [ this .( Expr ) .getEnclosingFunction ( ) , this .( Parameter ) .getFunction ( ) ]
148+ }
149+
150+ /**
151+ * Gets the member function corresponding to an overloaded `operator()` when this element is
152+ * invoked.
153+ */
154+ private MemberFunction getOperatorCallFunction ( ) {
155+ // An `operator()` on a struct
156+ result .getClassAndName ( "operator()" ) .getADerivedClass * ( ) = this .( Expr ) .getUnspecifiedType ( )
157+ or
158+ // A lambda that has undergone "lambda to function-pointer conversion"
159+ result = this .( ConversionCall ) .getQualifier ( ) .( LambdaExpression ) .getLambdaFunction ( )
160+ }
161+
162+ SourceSinkReportingElement getASuccessor ( Impl:: Private:: SummaryComponent sc ) {
163+ exists ( ParameterPosition pos | sc = Impl:: Private:: SummaryComponent:: parameter ( pos ) |
164+ // Taking the address of a function
165+ result = pos .getParameter ( this .( FunctionAccess ) .getTarget ( ) )
166+ or
167+ // Passing an object with an overloaded `operator()`
168+ result = pos .getParameter ( this .getOperatorCallFunction ( ) )
169+ )
170+ }
171+ }
172+
173+ bindingset [ source, sc]
174+ SourceSinkReportingElement getASourceReportingElement (
175+ Input:: SourceBase source , Impl:: Private:: SummaryComponent sc
176+ ) {
177+ exists ( Call call | call .getTarget ( ) = source |
178+ sc = Impl:: Private:: SummaryComponent:: return ( _) and
179+ result = call
180+ or
181+ exists ( ArgumentPosition pos |
182+ sc = Impl:: Private:: SummaryComponent:: argument ( pos ) and
183+ result = pos .getArgument ( call )
184+ )
185+ )
186+ or
187+ exists ( ParameterPosition pos |
188+ sc = Impl:: Private:: SummaryComponent:: parameter ( pos ) and
189+ result = pos .getParameter ( source )
190+ )
191+ }
192+
193+ pragma [ nomagic]
194+ private IndirectReturnOutNode getIndirectReturn ( CallInstruction call , NormalReturnKind rk ) {
195+ result .getCallInstruction ( ) = call and
196+ pragma [ only_bind_out ] ( result .getIndirectionIndex ( ) ) =
197+ pragma [ only_bind_out ] ( rk .getIndirectionIndex ( ) )
198+ }
199+
200+ bindingset [ e, sc]
201+ Node getSourceDataFlowNode ( SourceSinkReportingElement e , Impl:: Private:: SummaryComponent sc ) {
202+ exists ( DataFlowCall call |
203+ exists ( ArgumentPosition pos |
204+ sc = Impl:: Private:: SummaryComponent:: argument ( pos ) and
205+ pos .getArgument ( call .asCallInstruction ( ) .getUnconvertedResultExpression ( ) ) = e
206+ |
207+ pos .getIndirectionIndex ( ) = 0 and
208+ result .( PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( ) = e
209+ or
210+ result .( PostUpdateNode ) .getPreUpdateNode ( ) .asIndirectExpr ( pos .getIndirectionIndex ( ) ) = e
211+ )
212+ or
213+ exists ( ReturnKind rk |
214+ sc = Impl:: Private:: SummaryComponent:: return ( rk ) and
215+ e = call .asCallInstruction ( ) .getUnconvertedResultExpression ( )
216+ |
217+ rk .getIndirectionIndex ( ) = 0 and
218+ simpleOutNode ( result , call .asCallInstruction ( ) )
219+ or
220+ result = getIndirectReturn ( call .asCallInstruction ( ) , rk )
221+ )
222+ )
223+ or
224+ exists ( ParameterPosition pos , ParameterNode p |
225+ sc = Impl:: Private:: SummaryComponent:: parameter ( pos ) and
226+ p .isParameterOf ( e .getEnclosingCallable ( ) , pos ) and
227+ result = p
228+ )
229+ }
142230
143- DataFlowCallable getEnclosingCallable ( ) { none ( ) }
231+ bindingset [ sink, sc]
232+ SourceSinkReportingElement getASinkReportingElement (
233+ Input:: SinkBase sink , Impl:: Private:: SummaryComponent sc
234+ ) {
235+ exists ( Call call , ArgumentPosition pos |
236+ call .getTarget ( ) = sink and
237+ sc = Impl:: Private:: SummaryComponent:: argument ( pos ) and
238+ result = pos .getArgument ( call )
239+ )
240+ }
144241
145- SourceSinkReportingElement getASuccessor ( Impl:: Private:: SummaryComponent sc ) { none ( ) }
242+ bindingset [ e, sc]
243+ Node getSinkDataFlowNode ( SourceSinkReportingElement e , Impl:: Private:: SummaryComponent sc ) {
244+ exists ( ArgumentPosition pos , CallInstruction call |
245+ sc = Impl:: Private:: SummaryComponent:: argument ( pos ) and
246+ pos .getArgument ( call .getUnconvertedResultExpression ( ) ) = e and
247+ result .( ArgumentNode ) .sourceArgumentOf ( call , pos )
248+ )
146249 }
147250}
148251
@@ -319,3 +422,41 @@ module Private {
319422}
320423
321424module Public = Impl:: Public;
425+
426+ private class SourceModelFunction extends Public:: SourceElement instanceof Function {
427+ private string namespace ;
428+ private string type ;
429+ private boolean subtypes ;
430+ private string name ;
431+ private string signature ;
432+ private string ext ;
433+
434+ SourceModelFunction ( ) {
435+ sourceModel ( namespace , type , subtypes , name , signature , ext , _, _, _, _) and
436+ this = interpretElement ( namespace , type , subtypes , name , signature , ext )
437+ }
438+
439+ override predicate isSource (
440+ string output , string kind , Public:: Provenance provenance , string model
441+ ) {
442+ sourceModel ( namespace , type , subtypes , name , signature , ext , output , kind , provenance , model )
443+ }
444+ }
445+
446+ private class SinkModelFunction extends Public:: SinkElement instanceof Function {
447+ private string namespace ;
448+ private string type ;
449+ private boolean subtypes ;
450+ private string name ;
451+ private string signature ;
452+ private string ext ;
453+
454+ SinkModelFunction ( ) {
455+ sinkModel ( namespace , type , subtypes , name , signature , ext , _, _, _, _) and
456+ this = interpretElement ( namespace , type , subtypes , name , signature , ext )
457+ }
458+
459+ override predicate isSink ( string input , string kind , Public:: Provenance provenance , string model ) {
460+ sinkModel ( namespace , type , subtypes , name , signature , ext , input , kind , provenance , model )
461+ }
462+ }
0 commit comments