8000 C#: Improve arg-param mapping logic to consider arguments passed to `… · github/codeql@9bb8074 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9bb8074

Browse files
committed
C#: Improve arg-param mapping logic to consider arguments passed to params parameters
1 parent 93b0eb9 commit 9bb8074

File tree

4 files changed

+46
-40
lines changed

4 files changed

+46
-40
lines changed

csharp/ql/lib/semmle/code/csharp/exprs/Call.qll

Lines changed: 10 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -57,60 +57,30 @@ class Call extends DotNet::Call, Expr, @call {
5757
*
5858
* This takes into account both positional and named arguments, but does not
5959
* consider default arguments.
60-
*
61-
* An argument must always have a type that is convertible to the relevant
62-
* parameter type. Therefore, `params` arguments are only taken into account
63-
* when they are passed as explicit arrays. For example, in the call to `M1`
64-
* on line 5, `o` is not an argument for `M1`'s `args` parameter, while
65-
* `new object[] { o }` on line 6 is, in
66-
*
67-
* ```csharp
68-
* class C {
69-
* void M1(params object[] args) { }
70-
*
71-
* void M2(object o) {
72-
* M1(o);
73-
* M1(new object[] { o });
74-
* }
75-
* }
76-
* ```
7760
*/
7861
cached
7962
override Expr getArgumentForParameter(DotNet::Parameter p) {
8063
this.getTarget().getAParameter() = p and
8164
(
8265
// Appears in the positional part of the call
83-
result = this.getImplicitArgument(p.getPosition()) and
84-
(
85-
p.(Parameter).isParams()
86-
implies
87-
(
88-
isValidExplicitParamsType(p, result.getType()) and
89-
not this.hasMultipleParamsArguments()
90-
)
91-
)
66+
result = this.getImplicitArgument(p)
9267
or
9368
// Appears in the named part of the call
9469
result = this.getExplicitArgument(p.getName()) and
9570
(p.(Parameter).isParams() implies isValidExplicitParamsType(p, result.getType()))
9671
)
9772
}
9873

99-
/**
100-
* Holds if this call has multiple arguments for a `params` parameter
101-
* of the targeted callable.
102-
*/
103-
private predicate hasMultipleParamsArguments() {
104-
exists(Parameter p | p = this.getTarget().getAParameter() |
105-
p.isParams() and
106-
exists(this.getArgument(any(int i | i > p.getPosition())))
107-
)
108-
}
109-
11074
pragma[noinline]
111-
private Expr getImplicitArgument(int pos) {
112-
result = this.getArgument(pos) and
113-
not exists(result.getExplicitArgumentName())
75+
private Expr getImplicitArgument(DotNet::Parameter p) {
76+
not exists(result.getExplicitArgumentName()) and
77+
(
78+
p.(Parameter).isParams() and
79+
result = this.getArgument(any(int i | i >= p.getPosition()))
80+
or
81+
not p.(Parameter).isParams() and
82+
result = this.getArgument(p.getPosition())
83+
)
11484
}
11585

11686
pragma[nomagic]

csharp/ql/test/library-tests/arguments/argumentByName.expected

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
| arguments.cs:30:9:30:38 | object creation of type ArgumentsTest | arguments.cs:30:30:30:31 | 10 | y |
99
| arguments.cs:30:9:30:38 | object creation of type ArgumentsTest | arguments.cs:30:37:30:37 | 5 | x |
1010
| arguments.cs:35:9:35:19 | call to method f3 | arguments.cs:35:12:35:12 | 0 | o |
11+
| arguments.cs:35:9:35:19 | call to method f3 | arguments.cs:35:15:35:15 | 1 | args |
12+
| arguments.cs:35:9:35:19 | call to method f3 | arguments.cs:35:18:35:18 | 2 | args |
1113
| arguments.cs:36:9:36:33 | call to method f3 | arguments.cs:36:12:36:12 | 0 | o |
1214
| arguments.cs:36:9:36:33 | call to method f3 | arguments.cs:36:15:36:32 | array creation of type Int32[] | args |
1315
| arguments.cs:37:9:37:25 | call to method f3 | arguments.cs:37:24:37:24 | 0 | o |
@@ -18,6 +20,10 @@
1820
| arguments.cs:40:9:40:42 | call to method f3 | arguments.cs:40:18:40:35 | array creation of type Int32[] | args |
1921
| arguments.cs:40:9:40:42 | call to method f3 | arguments.cs:40:41:40:41 | 0 | o |
2022
| arguments.cs:42:9:42:21 | call to method f3 | arguments.cs:42:12:42:12 | 0 | o |
23+
| arguments.cs:42:9:42:21 | call to method f3 | arguments.cs:42:15:42:16 | (...) ... | args |
24+
| arguments.cs:42:9:42:21 | call to method f3 | arguments.cs:42:19:42:20 | (...) ... | args |
25+
| arguments.cs:47:9:47:39 | call to method f4 | arguments.cs:47:12:47:32 | array creation of type Object[] | args |
26+
| arguments.cs:47:9:47:39 | call to method f4 | arguments.cs:47:35:47:38 | null | args |
2127
| arguments.cs:56:9:56:12 | access to property Prop | arguments.cs:56:16:56:16 | 0 | value |
2228
| arguments.cs:57:9:57:12 | access to property Prop | arguments.cs:57:16:57:25 | access to indexer | value |
2329
| arguments.cs:57:16:57:25 | access to indexer | arguments.cs:57:21:57:21 | 1 | a |
@@ -37,16 +43,22 @@
3743
| arguments.cs:64:16:64:27 | access to indexer | arguments.cs:64:21:64:22 | 15 | a |
3844
| arguments.cs:64:16:64:27 | access to indexer | arguments.cs:64:25:64:26 | 16 | b |
3945
| arguments.cs:75:9:75:31 | call to method f8`1 | arguments.cs:75:12:75:12 | 0 | o |
46+
| arguments.cs:75:9:75:31 | call to method f8`1 | arguments.cs:75:15:75:21 | access to array element | args |
47+
| arguments.cs:75:9:75:31 | call to method f8`1 | arguments.cs:75:24:75:30 | access to array element | args |
4048
| arguments.cs:76:9:76:43 | call to method f8`1 | arguments.cs:76:12:76:12 | 0 | o |
4149
| arguments.cs:76:9:76:43 | call to method f8`1 | arguments.cs:76:15:76:42 | array creation of type T[] | args |
4250
| arguments.cs:77:9:77:19 | call to method f8`1 | arguments.cs:77:12:77:12 | 0 | o |
4351
| arguments.cs:77:9:77:19 | call to method f8`1 | arguments.cs:77:15:77:18 | access to parameter args | args |
4452
| arguments.cs:78:9:78:28 | call to method f8`1 | arguments.cs:78:18:78:21 | access to parameter args | args |
4553
| arguments.cs:78:9:78:28 | call to method f8`1 | arguments.cs:78:27:78:27 | 0 | o |
4654
| arguments.cs:80:9:80:31 | call to method f8<Double> | arguments.cs:80:20:80:20 | 0 | o |
55+
| arguments.cs:80:9:80:31 | call to method f8<Double> | arguments.cs:80:23:80:25 | 1.1 | args |
56+
| arguments.cs:80:9:80:31 | call to method f8<Double> | arguments.cs:80:28:80:30 | 2.2 | args |
4757
| arguments.cs:81:9:81:48 | call to method f8<Double> | arguments.cs:81:20:81:20 | 0 | o |
4858
| arguments.cs:81:9:81:48 | call to method f8<Double> | arguments.cs:81:23:81:47 | array creation of type Double[] | args |
4959
| arguments.cs:83:9:83:27 | call to method f8<Double> | arguments.cs:83:20:83:20 | 0 | o |
60+
| arguments.cs:83:9:83:27 | call to method f8<Double> | arguments.cs:83:23:83:23 | (...) ... | args |
61+
| arguments.cs:83:9:83:27 | call to method f8<Double> | arguments.cs:83:26:83:26 | (...) ... | args |
5062
| arguments.cs:84:9:84:44 | call to method f8<Double> | arguments.cs:84:20:84:20 | 0 | o |
5163
| arguments.cs:84:9:84:44 | call to method f8<Double> | arguments.cs:84:23:84:43 | array creation of type Double[] | args |
5264
| arguments.cs:85:9:85:44 | call to method f8<Double> | arguments.cs:85:20:85:20 | 0 | o |

csharp/ql/test/library-tests/arguments/argumentByParameter.expected

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
| arguments.cs:30:9:30:38 | object creation of type ArgumentsTest | arguments.cs:30:30:30:31 | 10 | arguments.cs:5:41:5:41 | y |
99
| arguments.cs:30:9:30:38 | object creation of type ArgumentsTest | arguments.cs:30:37:30:37 | 5 | arguments.cs:5:30:5:30 | x |
1010
| arguments.cs:35:9:35:19 | call to method f3 | arguments.cs:35:12:35:12 | 0 | arguments.cs:33:17:33:17 | o |
11+
| arguments.cs:35:9:35:19 | call to method f3 | arguments.cs:35:15:35:15 | 1 | arguments.cs:33:33:33:36 | args |
12+
| arguments.cs:35:9:35:19 | call to method f3 | arguments.cs:35:18:35:18 | 2 | arguments.cs:33:33:33:36 | args |
1113
| arguments.cs:36:9:36:33 | call to method f3 | arguments.cs:36:12:36:12 | 0 | arguments.cs:33:17:33:17 | o |
1214
| arguments.cs:36:9:36:33 | call to method f3 | arguments.cs:36:15:36:32 | array creation of type Int32[] | arguments.cs:33:33:33:36 | args |
1315
| arguments.cs:37:9:37:25 | call to method f3 | arguments.cs:37:24:37:24 | 0 | arguments.cs:33:17:33:17 | o |
@@ -18,6 +20,10 @@
1820
| arguments.cs:40:9:40:42 | call to method f3 | arguments.cs:40:18:40:35 | array creation of type Int32[] | arguments.cs:33:33:33:36 | args |
1921
| arguments.cs:40:9:40:42 | call to method f3 | arguments.cs:40:41:40:41 | 0 | arguments.cs:33:17:33:17 | o |
2022
| arguments.cs:42:9:42:21 | call to method f3 | arguments.cs:42:12:42:12 | 0 | arguments.cs:33:17:33:17 | o |
23+
| arguments.cs:42:9:42:21 | call to method f3 | arguments.cs:42:15:42:16 | (...) ... | arguments.cs:33:33:33:36 | args |
24+
| arguments.cs:42:9:42:21 | call to method f3 | arguments.cs:42:19:42:20 | (...) ... | arguments.cs:33:33:33:36 | args |
25+
| arguments.cs:47:9:47:39 | call to method f4 | arguments.cs:47:12:47:32 | array creation of type Object[] | arguments.cs:45:29:45:32 | args |
26+
| arguments.cs:47:9:47:39 | call to method f4 | arguments.cs:47:35:47:38 | null | arguments.cs:45:29:45:32 | args |
2127
| arguments.cs:56:9:56:12 | access to property Prop | arguments.cs:56:16:56:16 | 0 | arguments.cs:50:21:50:23 | value |
2228
| arguments.cs:57:9:57:12 | access to property Prop | arguments.cs:57:16:57:25 | access to indexer | arguments.cs:50:21:50:23 | value |
2329
| arguments.cs:57:16:57:25 | access to indexer | arguments.cs:57:21:57:21 | 1 | arguments.cs:52:18:52:18 | a |
@@ -39,16 +45,22 @@
3945
| arguments.cs:64:16:64:27 | access to indexer | arguments.cs:64:21:64:22 | 15 | arguments.cs:52:18:52:18 | a |
4046
| arguments.cs:64:16:64:27 | access to indexer | arguments.cs:64:25:64:26 | 16 | arguments.cs:52:25:52:25 | b |
4147
| arguments.cs:75:9:75:31 | call to method f8`1 | arguments.cs:75:12:75:12 | 0 | arguments.cs:73:20:73:20 | o |
48+
| arguments.cs:75:9:75:31 | call to method f8`1 | arguments.cs:75:15:75:21 | access to array element | arguments.cs:73:34:73:37 | args |
49+
| arguments.cs:75:9:75:31 | call to method f8`1 | arguments.cs:75:24:75:30 | access to array element | arguments.cs:73:34:73:37 | args |
4250
| arguments.cs:76:9:76:43 | call to method f8`1 | arguments.cs:76:12:76:12 | 0 | arguments.cs:73:20:73:20 | o |
4351
| arguments.cs:76:9:76:43 | call to method f8`1 | arguments.cs:76:15:76:42 | array creation of type T[] | arguments.cs:73:34:73:37 | args |
4452
| arguments.cs:77:9:77:19 | call to method f8`1 | arguments.cs:77:12:77:12 | 0 | arguments.cs:73:20:73:20 | o |
4553
| arguments.cs:77:9:77:19 | call to method f8`1 | arguments.cs:77:15:77:18 | access to parameter args | arguments.cs:73:34:73:37 | args |
4654
| arguments.cs:78:9:78:28 | call to method f8`1 | arguments.cs:78:18:78:21 | access to parameter args | arguments.cs:73:34:73:37 | args |
4755
| arguments.cs:78:9:78:28 | call to method f8`1 | arguments.cs:78:27:78:27 | 0 | arguments.cs:73:20:73:20 | o |
4856
| arguments.cs:80:9:80:31 | call to method f8<Double> | arguments.cs:80:20:80:20 | 0 | arguments.cs:73:20:73:20 | o |
57+
| arguments.cs:80:9:80:31 | call to method f8<Double> | arguments.cs:80:23:80:25 | 1.1 | arguments.cs:73:34:73:37 | args |
58+
| arguments.cs:80:9:80:31 | call to method f8<Double> | arguments.cs:80:28:80:30 | 2.2 | arguments.cs:73:34:73:37 | args |
4959
| arguments.cs:81:9:81:48 | call to method f8<Double> | arguments.cs:81:20:81:20 | 0 | arguments.cs:73:20:73:20 | o |
5060
| arguments.cs:81:9:81:48 | call to method f8<Double> | arguments.cs:81:23:81:47 | array creation of type Double[] | arguments.cs:73:34:73:37 | args |
5161
| arguments.cs:83:9:83:27 | call to method f8<Double> | arguments.cs:83:20:83:20 | 0 | arguments.cs:73:20:73:20 | o |
62+
| arguments.cs:83:9:83:27 | call to method f8<Double> | arguments.cs:83:23:83:23 | (...) ... | arguments.cs:73:34:73:37 | args |
63+
| arguments.cs:83:9:83:27 | call to method f8<Double> | arguments.cs:83:26:83:26 | (...) ... | arguments.cs:73:34:73:37 | args |
5264
| arguments.cs:84:9:84:44 | call to method f8<Double> | arguments.cs:84:20:84:20 | 0 | arguments.cs:73:20:73:20 | o |
5365
| arguments.cs:84:9:84:44 | call to method f8<Double> | arguments.cs:84:23:84:43 | array creation of type Double[] | arguments.cs:73:34:73:37 | args |
5466
| arguments.cs:85:9:85:44 | call to method f8<Double> | arguments.cs:85:20:85:20 | 0 | arguments.cs:73:20:73:20 | o |

csharp/ql/test/library-tests/arguments/parameterGetArguments.expected

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,16 @@
1414
| arguments.cs:33:17:33:17 | o | arguments.cs:39:27:39:27 | 0 |
1515
| arguments.cs:33:17:33:17 | o | arguments.cs:40:41:40:41 | 0 |
1616
| arguments.cs:33:17:33:17 | o | arguments.cs:42:12:42:12 | 0 |
17+
| arguments.cs:33:33:33:36 | args | arguments.cs:35:15:35:15 | 1 |
18+
| arguments.cs:33:33:33:36 | args | arguments.cs:35:18:35:18 | 2 |
1719
| arguments.cs:33:33:33:36 | args | arguments.cs:36:15:36:32 | array creation of type Int32[] |
1820
| arguments.cs:33:33:33:36 | args | arguments.cs:38:15:38:18 | access to parameter args |
1921
| arguments.cs:33:33:33:36 | args | arguments.cs:39:18:39:21 | access to parameter args |
2022
| arguments.cs:33:33:33:36 | args | arguments.cs:40:18:40:35 | array creation of type Int32[] |
23+
| arguments.cs:33:33:33:36 | args | arguments.cs:42:15:42:16 | (...) ... |
24+
| arguments.cs:33:33:33:36 | args | arguments.cs:42:19:42:20 | (...) ... |
25+
| arguments.cs:45:29:45:32 | args | arguments.cs:47:12:47:32 | array creation of type Object[] |
26+
| arguments.cs:45:29:45:32 | args | arguments.cs:47:35:47:38 | null |
2127
| arguments.cs:50:21:50:23 | value | arguments.cs:56:16:56:16 | 0 |
2228
| arguments.cs:50:21:50:23 | value | arguments.cs:57:16:57:25 | access to indexer |
2329
| arguments.cs:50:21:50:23 | value | arguments.cs:58:31:58:31 | 5 |
@@ -47,9 +53,15 @@
4753
| arguments.cs:73:20:73:20 | o | arguments.cs:83:20:83:20 | 0 |
4854
| arguments.cs:73:20:73:20 | o | arguments.cs:84:20:84:20 | 0 |
4955
| arguments.cs:73:20:73:20 | o | arguments.cs:85:20:85:20 | 0 |
56+
| arguments.cs:73:34:73:37 | args | arguments.cs:75:15:75:21 | access to array element |
57+
| arguments.cs:73:34:73:37 | args | arguments.cs:75:24:75:30 | access to array element |
5058
| arguments.cs:73:34:73:37 | args | arguments.cs:76:15:76:42 | array creation of type T[] |
5159
| arguments.cs:73:34:73:37 | args | arguments.cs:77:15:77:18 | access to parameter args |
5260
| arguments.cs:73:34:73:37 | args | arguments.cs:78:18:78:21 | access to parameter args |
61+
| arguments.cs:73:34:73:37 | args | arguments.cs:80:23:80:25 | 1.1 |
62+
| arguments.cs:73:34:73:37 | args | arguments.cs:80:28:80:30 | 2.2 |
5363
| arguments.cs:73:34:73:37 | args | arguments.cs:81:23:81:47 | array creation of type Double[] |
64+
| arguments.cs:73:34:73:37 | args | arguments.cs:83:23:83:23 | (...) ... |
65+
| arguments.cs:73:34:73:37 | args | arguments.cs:83:26:83:26 | (...) ... |
5466
| arguments.cs:73:34:73:37 | args | arguments.cs:84:23:84:43 | array creation of type Double[] |
5567
| arguments.cs:73:34:73:37 | args | arguments.cs:85:23:85:43 | array creation of type Double[] |

0 commit comments

Comments
 (0)
0