@@ -15,22 +15,13 @@ import semmle.code.csharp.frameworks.system.Text
15
15
import semmle.code.csharp.frameworks.Format
16
16
import FormatFlow:: PathGraph
17
17
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 {
29
19
predicate isSource ( DataFlow:: Node n ) { n .asExpr ( ) instanceof StringLiteral }
30
20
31
21
predicate isAdditionalFlowStep ( DataFlow:: Node pred , DataFlow:: Node succ ) {
32
22
// Add flow via `System.Text.CompositeFormat.Parse`.
33
- exists ( ParseFormatStringCall call |
23
+ exists ( FormatCall call |
24
+ call .getTarget ( ) instanceof CompositeFormatParseMethod and
34
25
pred .asExpr ( ) = call .getFormatExpr ( ) and
35
26
succ .asExpr ( ) = call
36
27
)
@@ -39,31 +30,28 @@ module FormatLiteralConfig implements DataFlow::ConfigSig {
39
30
predicate isSink ( DataFlow:: Node n ) { exists ( FormatCall c | n .asExpr ( ) = c .getFormatExpr ( ) ) }
40
31
}
41
32
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 > ;
47
34
48
35
private 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
51
38
) {
52
39
source .getNode ( ) .asExpr ( ) = src and
53
40
sink .getNode ( ) .asExpr ( ) = call .getFormatExpr ( ) and
54
- FormatInvalid :: flowPath ( source , sink ) and
41
+ FormatFlow :: flowPath ( source , sink ) and
55
42
msg = "Invalid format string used in $@ formatting call." and
56
43
callString = "this"
57
44
}
58
45
59
46
private predicate unusedArgument (
60
- FormatCall call , FormatLiteral :: PathNode source , FormatLiteral :: PathNode sink , string msg ,
47
+ FormatCall call , FormatFlow :: PathNode source , FormatFlow :: PathNode sink , string msg ,
61
48
ValidFormatString src , string srcString , Expr unusedExpr , string unusedString
62
49
) {
63
50
exists ( int unused |
64
51
source .getNode ( ) .asExpr ( ) = src and
65
52
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
67
55
unused = call .getASuppliedArgument ( ) and
68
56
not unused = src .getAnInsert ( ) and
69
57
not src .getValue ( ) = "" and
@@ -75,13 +63,14 @@ private predicate unusedArgument(
75
63
}
76
64
77
65
private predicate missingArgument (
78
- FormatCall call , FormatLiteral :: PathNode source , FormatLiteral :: PathNode sink , string msg ,
66
+ FormatCall call , FormatFlow :: PathNode source , FormatFlow :: PathNode sink , string msg ,
79
67
ValidFormatString src , string srcString
80
68
) {
81
69
exists ( int used , int supplied |
82
70
source .getNode ( ) .asExpr ( ) = src and
83
71
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
85
74
used = src .getAnInsert ( ) and
86
75
supplied = call .getSuppliedArguments ( ) and
87
76
used >= supplied and
94
83
Element alert , FormatFlow:: PathNode source , FormatFlow:: PathNode sink , string msg , Element extra1 ,
95
84
string extra1String , Element extra2 , string extra2String
96
85
where
97
- invalidFormatString ( alert , source . asPathNode1 ( ) , sink . asPathNode1 ( ) , msg , extra1 , extra1String ) and
86
+ invalidFormatString ( alert , source , sink , msg , extra1 , extra1String ) and
98
87
extra2 = extra1 and
99
88
extra2String = extra1String
100
89
or
101
- unusedArgument ( alert , source .asPathNode2 ( ) , sink .asPathNode2 ( ) , msg , extra1 , extra1String , extra2 ,
102
- extra2String )
90
+ unusedArgument ( alert , source , sink , msg , extra1 , extra1String , extra2 , extra2String )
103
91
or
104
- missingArgument ( alert , source . asPathNode2 ( ) , sink . asPathNode2 ( ) , msg , extra1 , extra1String ) and
92
+ missingArgument ( alert , source , sink , msg , extra1 , extra1String ) and
105
93
extra2 = extra1 and
106
94
extra2String = extra1String
107
95
select alert , source , sink , msg , extra1 , extra1String , extra2 , extra2String
0 commit comments