@@ -15,22 +15,13 @@ import semmle.code.csharp.frameworks.system.Text
1515import semmle.code.csharp.frameworks.Format
1616import FormatFlow:: PathGraph
1717
18- module FormatInvalidConfig implements DataFlow:: ConfigSig {
19- predicate isSource ( DataFlow:: Node n ) { n .asExpr ( ) instanceof StringLiteral }
20-
21- predicate isSink ( DataFlow:: Node n ) {
22- exists ( FormatStringParseCall c | n .asExpr ( ) = c .getFormatExpr ( ) )
23- }
24- }
25-
26- module FormatInvalid = DataFlow:: Global< FormatInvalidConfig > ;
27-
28- module FormatLiteralConfig implements DataFlow:: ConfigSig {
18+ module FormatFlowConfig implements DataFlow:: ConfigSig {
2919 predicate isSource ( DataFlow:: Node n ) { n .asExpr ( ) instanceof StringLiteral }
3020
3121 predicate isAdditionalFlowStep ( DataFlow:: Node pred , DataFlow:: Node succ ) {
3222 // Add flow via `System.Text.CompositeFormat.Parse`.
33- exists ( ParseFormatStringCall call |
23+ exists ( FormatCall call |
24+ call .getTarget ( ) instanceof CompositeFormatParseMethod and
3425 pred .asExpr ( ) = call .getFormatExpr ( ) and
3526 succ .asExpr ( ) = call
3627 )
@@ -39,31 +30,28 @@ module FormatLiteralConfig implements DataFlow::ConfigSig {
3930 predicate isSink ( DataFlow:: Node n ) { exists ( FormatCall c | n .asExpr ( ) = c .getFormatExpr ( ) ) }
4031}
4132
42- module FormatLiteral = DataFlow:: Global< FormatLiteralConfig > ;
43-
44- module FormatFlow =
45- DataFlow:: MergePathGraph< FormatInvalid:: PathNode , FormatLiteral:: PathNode ,
46- FormatInvalid:: PathGraph , FormatLiteral:: PathGraph > ;
33+ module FormatFlow = DataFlow:: Global< FormatFlowConfig > ;
4734
4835private predicate invalidFormatString (
49- InvalidFormatString src , FormatInvalid :: PathNode source , FormatInvalid :: PathNode sink , string msg ,
50- FormatStringParseCall call , string callString
36+ InvalidFormatString src , FormatFlow :: PathNode source , FormatFlow :: PathNode sink , string msg ,
37+ FormatCall call , string callString
5138) {
5239 source .getNode ( ) .asExpr ( ) = src and
5340 sink .getNode ( ) .asExpr ( ) = call .getFormatExpr ( ) and
54- FormatInvalid :: flowPath ( source , sink ) and
41+ FormatFlow :: flowPath ( source , sink ) and
5542 msg = "Invalid format string used in $@ formatting call." and
5643 callString = "this"
5744}
5845
5946private predicate unusedArgument (
60- FormatCall call , FormatLiteral :: PathNode source , FormatLiteral :: PathNode sink , string msg ,
47+ FormatCall call , FormatFlow :: PathNode source , FormatFlow :: PathNode sink , string msg ,
6148 ValidFormatString src , string srcString , Expr unusedExpr , string unusedString
6249) {
6350 exists ( int unused |
6451 source .getNode ( ) .asExpr ( ) = src and
6552 sink .getNode ( ) .asExpr ( ) = call .getFormatExpr ( ) and
66- FormatLiteral:: flowPath ( source , sink ) and
53+ not call .getTarget ( ) instanceof CompositeFormatParseMethod and
54+ FormatFlow:: flowPath ( source , sink ) and
6755 unused = call .getASuppliedArgument ( ) and
6856 not unused = src .getAnInsert ( ) and
6957 not src .getValue ( ) = "" and
@@ -75,13 +63,14 @@ private predicate unusedArgument(
7563}
7664
7765private predicate missingArgument (
78- FormatCall call , FormatLiteral :: PathNode source , FormatLiteral :: PathNode sink , string msg ,
66+ FormatCall call , FormatFlow :: PathNode source , FormatFlow :: PathNode sink , string msg ,
7967 ValidFormatString src , string srcString
8068) {
8169 exists ( int used , int supplied |
8270 source .getNode ( ) .asExpr ( ) = src and
8371 sink .getNode ( ) .asExpr ( ) = call .getFormatExpr ( ) and
84- FormatLiteral:: flowPath ( source , sink ) and
72+ not call .getTarget ( ) instanceof CompositeFormatParseMethod and
73+ FormatFlow:: flowPath ( source , sink ) and
8574 used = src .getAnInsert ( ) and
8675 supplied = call .getSuppliedArguments ( ) and
8776 used >= supplied and
9483 Element alert , FormatFlow:: PathNode source , FormatFlow:: PathNode sink , string msg , Element extra1 ,
9584 string extra1String , Element extra2 , string extra2String
9685where
97- invalidFormatString ( alert , source . asPathNode1 ( ) , sink . asPathNode1 ( ) , msg , extra1 , extra1String ) and
86+ invalidFormatString ( alert , source , sink , msg , extra1 , extra1String ) and
9887 extra2 = extra1 and
9988 extra2String = extra1String
10089 or
101- unusedArgument ( alert , source .asPathNode2 ( ) , sink .asPathNode2 ( ) , msg , extra1 , extra1String , extra2 ,
102- extra2String )
90+ unusedArgument ( alert , source , sink , msg , extra1 , extra1String , extra2 , extra2String )
10391 or
104- missingArgument ( alert , source . asPathNode2 ( ) , sink . asPathNode2 ( ) , msg , extra1 , extra1String ) and
92+ missingArgument ( alert , source , sink , msg , extra1 , extra1String ) and
10593 extra2 = extra1 and
10694 extra2String = extra1String
10795select alert , source , sink , msg , extra1 , extra1String , extra2 , extra2String
0 commit comments