@@ -6,6 +6,7 @@ private import cpp as Cpp
66private import codeql.dataflow.internal.FlowSummaryImpl
77private import codeql.dataflow.internal.AccessPathSyntax as AccessPath
88private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
9+ private import semmle.code.cpp.ir.dataflow.internal.DataFlowNodes
910private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
1011private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific as DataFlowImplSpecific
1112private import semmle.code.cpp.dataflow.ExternalFlow
@@ -20,8 +21,22 @@ module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
2021
2122 class SinkBase = Void ;
2223
24+ class FlowSummaryCallBase = CallInstruction ;
25+
2326 predicate callableFromSource ( SummarizedCallableBase c ) { exists ( c .getBlock ( ) ) }
2427
28+ FlowSummaryCallBase getASourceCall ( SummarizedCallableBase sc ) {
29+ result .getStaticCallTarget ( ) = sc
30+ }
31+
32+ DataFlowCallable getSummarizedCallableAsDataFlowCallable ( SummarizedCallableBase c ) {
33+ result .asSummarizedCallable ( ) = c
34+ }
35+
36+ DataFlowCallable getSourceCallEnclosingCallable ( FlowSummaryCallBase call ) {
37+ result .asSourceCallable ( ) = call .getEnclosingFunction ( )
38+ }
39+
2540 ArgumentPosition callbackSelfParameterPosition ( ) { result = TDirectPosition ( - 1 ) }
2641
2742 ReturnKind getStandardReturnValueKind ( ) { result = getReturnValueKind ( "" ) }
@@ -30,6 +45,10 @@ module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
3045 arg = repeatStars ( result .( NormalReturnKind ) .getIndirectionIndex ( ) )
3146 }
3247
48+ ParameterPosition getFlowSummaryParameterPosition ( ReturnKind rk ) {
49+ result = TFlowSummaryPosition ( rk )
50+ }
51+
3352 string encodeParameterPosition ( ParameterPosition pos ) { result = pos .toString ( ) }
3453
3554 string encodeArgumentPosition ( ArgumentPosition pos ) { result = pos .toString ( ) }
@@ -40,12 +59,24 @@ module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
4059 arg = repeatStars ( rk .( NormalReturnKind ) .getIndirectionIndex ( ) )
4160 }
4261
62+ bindingset [ namespace, type, base]
63+ private string formatQualifiedName ( string namespace , string type , string base ) {
64+ if namespace = ""
65+ then result = type + "::" + base
66+ else result = namespace + "::" + type + "::" + base
67+ }
68+
4369 string encodeContent ( ContentSet cs , string arg ) {
44- exists ( FieldContent c |
70+ exists ( FieldContent c , string namespace , string type , string base |
4571 cs .isSingleton ( c ) and
4672 // FieldContent indices have 0 for the address, 1 for content, so we need to subtract one.
4773 result = "Field" and
48- arg = repeatStars ( c .getIndirectionIndex ( ) - 1 ) + c .getField ( ) .getName ( )
74+ c .getField ( ) .hasQualifiedName ( namespace , type , base )
75+ |
76+ arg = repeatStars ( c .getIndirectionIndex ( ) - 1 ) + formatQualifiedName ( namespace , type , base )
77+ or
78+ // TODO: This disjunct can be removed once we stop supporting unqualified field names.
79+ arg = repeatStars ( c .getIndirectionIndex ( ) - 1 ) + base
4980 )
5081 or
5182 exists ( ElementContent ec |
@@ -102,10 +133,22 @@ module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
102133private import Make< Location , DataFlowImplSpecific:: CppDataFlow , Input > as Impl
103134
104135private module StepsInput implements Impl:: Private:: StepsInputSig {
136+ Impl:: Private:: SummaryNode getSummaryNode ( Node n ) {
137+ result = n .( FlowSummaryNode ) .getSummaryNode ( )
138+ }
139+
105140 DataFlowCall getACall ( Public:: SummarizedCallable sc ) {
106141 result .getStaticCallTarget ( ) .getUnderlyingCallable ( ) = sc
107142 }
108143
144+ Node getSourceOutNode ( Input:: FlowSummaryCallBase call , ReturnKind rk ) {
145+ exists ( IndirectReturnOutNode out | result = out |
146+ out .getCallInstruction ( ) = call and
147+ pragma [ only_bind_out ] ( rk .( NormalReturnKind ) .getIndirectionIndex ( ) ) =
148+ pragma [ only_bind_out ] ( out .getIndirectionIndex ( ) )
149+ )
150+ }
151+
109152 DataFlowCallable getSourceNodeEnclosingCallable ( Input:: SourceBase source ) { none ( ) }
110153
111154 Node getSourceNode ( Input:: SourceBase source , Impl:: Private:: SummaryComponentStack s ) { none ( ) }
@@ -218,40 +261,11 @@ module SourceSinkInterpretationInput implements
218261
219262 /** Provides additional sink specification logic. */
220263 bindingset [ c]
221- predicate interpretOutput ( string c , InterpretNode mid , InterpretNode node ) {
222- // Allow variables to be picked as output nodes.
223- exists ( Node n , Element ast |
224- n = node .asNode ( ) and
225- ast = mid .asElement ( )
226- |
227- c = "" and
228- n .asExpr ( ) .( VariableAccess ) .getTarget ( ) = ast
229- )
230- }
264+ predicate interpretOutput ( string c , InterpretNode mid , InterpretNode node ) { none ( ) }
231265
232266 /** Provides additional source specification logic. */
233267 bindingset [ c]
234- predicate interpretInput ( string c , InterpretNode mid , InterpretNode node ) {
235- exists ( Node n , Element ast , VariableAccess e |
236- n = node .asNode ( ) and
237- ast = mid .asElement ( ) and
238- e .getTarget ( ) = ast
239- |
240- // Allow variables to be picked as input nodes.
241- // We could simply do this as `e = n.asExpr()`, but that would not allow
242- // us to pick `x` as a sink in an example such as `x = source()` (but
243- // only subsequent uses of `x`) since the variable access on `x` doesn't
244- // actually load the value of `x`. So instead, we pick the instruction
245- // node corresponding to the generated `StoreInstruction` and use the
246- // expression associated with the destination instruction. This means
247- // that the `x` in `x = source()` can be marked as an input.
248- c = "" and
249- exists ( StoreInstruction store |
250- store .getDestinationAddress ( ) .getUnconvertedResultExpression ( ) = e and
251- n .asInstruction ( ) = store
252- )
253- )
254- }
268+ predicate interpretInput ( string c , InterpretNode mid , InterpretNode node ) { none ( ) }
255269}
256270
257271module Private {
0 commit comments