@@ -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,117 @@ 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+ SourceSinkReportingElement getASourceReportingElement (
174+ Input:: SourceBase source , Impl:: Private:: SummaryComponent sc
175+ ) {
176+ exists ( Call call | call .getTarget ( ) = source |
177+ sc = Impl:: Private:: SummaryComponent:: return ( _) and
178+ result = call
179+ or
180+ exists ( ArgumentPosition pos |
181+ sc = Impl:: Private:: SummaryComponent:: argument ( pos ) and
182+ result = pos .getArgument ( call )
183+ )
184+ )
185+ or
186+ exists ( ParameterPosition pos |
187+ sc = Impl:: Private:: SummaryComponent:: parameter ( pos ) and
188+ result = pos .getParameter ( source )
189+ )
190+ }
191+
192+ pragma [ nomagic]
193+ private IndirectReturnOutNode getIndirectReturn ( CallInstruction call , NormalReturnKind rk ) {
194+ result .getCallInstruction ( ) = call and
195+ pragma [ only_bind_out ] ( result .getIndirectionIndex ( ) ) =
196+ pragma [ only_bind_out ] ( rk .getIndirectionIndex ( ) )
197+ }
198+
199+ bindingset [ e, sc]
200+ Node getSourceDataFlowNode ( SourceSinkReportingElement e , Impl:: Private:: SummaryComponent sc ) {
201+ exists ( DataFlowCall call |
202+ exists ( ArgumentPosition pos |
203+ sc = Impl:: Private:: SummaryComponent:: argument ( pos ) and
204+ pos .getArgument ( call .asCallInstruction ( ) .getUnconvertedResultExpression ( ) ) = e
205+ |
206+ pos .getIndirectionIndex ( ) = 0 and
207+ result .( PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( ) = e
208+ or
209+ result .( PostUpdateNode ) .getPreUpdateNode ( ) .asIndirectExpr ( pos .getIndirectionIndex ( ) ) = e
210+ )
211+ or
212+ exists ( ReturnKind rk |
213+ sc = Impl:: Private:: SummaryComponent:: return ( rk ) and
214+ e = call .asCallInstruction ( ) .getUnconvertedResultExpression ( )
215+ |
216+ rk .getIndirectionIndex ( ) = 0 and
217+ simpleOutNode ( result , call .asCallInstruction ( ) )
218+ or
219+ result = getIndirectReturn ( call .asCallInstruction ( ) , rk )
220+ )
221+ )
222+ or
223+ exists ( ParameterPosition pos , ParameterNode p |
224+ sc = Impl:: Private:: SummaryComponent:: parameter ( pos ) and
225+ p .isParameterOf ( e .getEnclosingCallable ( ) , pos ) and
226+ result = p
227+ )
228+ }
142229
143- DataFlowCallable getEnclosingCallable ( ) { none ( ) }
230+ SourceSinkReportingElement getASinkReportingElement (
231+ Input:: SinkBase sink , Impl:: Private:: SummaryComponent sc
232+ ) {
233+ exists ( Call call , ArgumentPosition pos |
234+ call .getTarget ( ) = sink and
235+ sc = Impl:: Private:: SummaryComponent:: argument ( pos ) and
236+ result = pos .getArgument ( call )
237+ )
238+ }
144239
145- SourceSinkReportingElement getASuccessor ( Impl:: Private:: SummaryComponent sc ) { none ( ) }
240+ Node getSinkDataFlowNode ( SourceSinkReportingElement e , Impl:: Private:: SummaryComponent sc ) {
241+ exists ( ArgumentPosition pos , CallInstruction call |
242+ sc = Impl:: Private:: SummaryComponent:: argument ( pos ) and
243+ pos .getArgument ( call .getUnconvertedResultExpression ( ) ) = e and
244+ result .( ArgumentNode ) .sourceArgumentOf ( call , pos )
245+ )
146246 }
147247}
148248
@@ -319,3 +419,41 @@ module Private {
319419}
320420
321421module Public = Impl:: Public;
422+
423+ private class SourceModelFunction extends Public:: SourceElement instanceof Function {
424+ private string namespace ;
425+ private string type ;
426+ private boolean subtypes ;
427+ private string name ;
428+ private string signature ;
429+ private string ext ;
430+
431+ SourceModelFunction ( ) {
432+ sourceModel ( namespace , type , subtypes , name , signature , ext , _, _, _, _) and
433+ this = interpretElement ( namespace , type , subtypes , name , signature , ext )
434+ }
435+
436+ override predicate isSource (
437+ string output , string kind , Public:: Provenance provenance , string model
438+ ) {
439+ sourceModel ( namespace , type , subtypes , name , signature , ext , output , kind , provenance , model )
440+ }
441+ }
442+
443+ private class SinkModelFunction extends Public:: SinkElement instanceof Function {
444+ private string namespace ;
445+ private string type ;
446+ private boolean subtypes ;
447+ private string name ;
448+ private string signature ;
449+ private string ext ;
450+
451+ SinkModelFunction ( ) {
452+ sinkModel ( namespace , type , subtypes , name , signature , ext , _, _, _, _) and
453+ this = interpretElement ( namespace , type , subtypes , name , signature , ext )
454+ }
455+
456+ override predicate isSink ( string input , string kind , Public:: Provenance provenance , string model ) {
457+ sinkModel ( namespace , type , subtypes , name , signature , ext , input , kind , provenance , model )
458+ }
459+ }
0 commit comments