Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit dec5fc0

Browse files
committed
C++: Switch MAD syntax from *Argument[0] style to Argument[*0] style.
1 parent 40270e1 commit dec5fc0

5 files changed

Lines changed: 88 additions & 68 deletions

File tree

cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,35 +32,42 @@
3232
* or method, or a parameter.
3333
* 7. The `input` column specifies how data enters the element selected by the
3434
* first 6 columns, and the `output` column specifies how data leaves the
35-
* element selected by the first 6 columns. An `input` can be either "",
36-
* "Argument[n]", "Argument[n1..n2]", "ReturnValue":
35+
* element selected by the first 6 columns. An `input` can be either:
3736
* - "": Selects a write to the selected element in case this is a field.
3837
* - "Argument[n]": Selects an argument in a call to the selected element.
3938
* The arguments are zero-indexed, and `-1` specifies the qualifier object,
4039
* that is, `*this`.
41-
* - "Argument[n1..n2]": Similar to "Argument[n]" but select any argument in
42-
* the given range. The range is inclusive at both ends.
40+
* - one or more "*" can be added in front of the argument index to indicate
41+
* indirection, for example, `Argument[*0]` indicates the first indirection
42+
* of the 0th argument.
43+
* - `n1..n2` syntax can be used to indicate a range of arguments, inclusive
44+
* at both ends. One or more "*" can be added in front of the range to
45+
* indicate indirection on all arguments in the range, for example `*n1..n2`.
4346
* - "ReturnValue": Selects a value being returned by the selected element.
44-
* This requires that the selected element is a method with a body.
47+
* One or more "*" can be added as an argument to indicate indirection, for
48+
* example, "ReturnValue[*]" indicates the first indirection of the return
49+
* value.
4550
*
46-
* An `output` can be either "", "Argument[n]", "Argument[n1..n2]", "Parameter",
47-
* "Parameter[n]", "Parameter[n1..n2]", or "ReturnValue":
51+
* An `output` can be either:
4852
* - "": Selects a read of a selected field, or a selected parameter.
49-
* - "Argument[n]": Selects the post-update value of an argument in a call to the
50-
* selected element. That is, the value of the argument after the call returns.
51-
* The arguments are zero-indexed, and `-1` specifies the qualifier object,
52-
* that is, `*this`.
53-
* - "Argument[n1..n2]": Similar to "Argument[n]" but select any argument in
54-
* the given range. The range is inclusive at both ends.
53+
* - "Argument[n]": Selects the post-update value of an argument in a call to
54+
* the selected element. That is, the value of the argument after the call
55+
* returns. The arguments are zero-indexed, and `-1` specifies the qualifier
56+
* object, that is, `*this`.
57+
* - one or more "*" can be added in front of the argument index to indicate
58+
* indirection, for example, `Argument[*0]` indicates the first indirection
59+
* of the 0th argument.
60+
* - `n1..n2` syntax can be used to indicate a range of arguments, inclusive
61+
* at both ends. One or more "*" can be added in front of the range to
62+
* indicate indirection on all arguments in the range, for example `*n1..n2`.
5563
* - "Parameter": Selects the value of a parameter of the selected element.
56-
* "Parameter" is also allowed in case the selected element is already a
57-
* parameter itself.
58-
* - "Parameter[n]": Similar to "Parameter" but restricted to a specific
59-
* numbered parameter. The parameters are zero-indexed, and `-1` specifies
60-
* the qualifier object, that is, `*this`.
61-
* - "Parameter[n1..n2]": Similar to "Parameter[n]" but selects any parameter
62-
* in the given range. The range is inclusive at both ends.
63-
* - "ReturnValue": Selects the return value of a call to the selected element.
64+
* The syntax is the same as for "Argument", for example "Parameter[0]",
65+
* "Parameter[*0]", "Parameter[0..2]" etc. "Parameter" is also allowed in
66+
* case the selected element is already a parameter itself.
67+
* - "ReturnValue": Selects a value being returned by the selected element.
68+
* One or more "*" can be added as an argument to indicate indirection, for
69+
* example, "ReturnValue[*]" indicates the first indirection of the return
70+
* value.
6471
* 8. The `kind` column is a tag that can be referenced from QL to determine to
6572
* which classes the interpreted elements should be added. For example, for
6673
* sources "remote" indicates a default remote flow source, and for summaries

cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,16 @@ module Input implements InputSig<DataFlowImplSpecific::CppDataFlow> {
3232

3333
string encodeReturn(ReturnKind rk, string arg) {
3434
rk != getStandardReturnValueKind() and
35-
result = indirectionString(rk.(NormalReturnKind).getIndirectionIndex()) + "ReturnValue" and
36-
arg = ""
35+
result = "ReturnValue" and
36+
arg = indirectionString(rk.(NormalReturnKind).getIndirectionIndex())
3737
}
3838

3939
string encodeContent(ContentSet cs, string arg) {
4040
exists(FieldContent c |
4141
cs.isSingleton(c) and
4242
// FieldContent indices have 0 for the address, 1 for content, so we need to subtract one.
43-
result = indirectionString(c.getIndirectionIndex() - 1) + "Field" and
44-
arg = c.getField().getName()
43+
result = "Field" and
44+
arg = indirectionString(c.getIndirectionIndex() - 1) + c.getField().getName()
4545
)
4646
}
4747

@@ -54,42 +54,55 @@ module Input implements InputSig<DataFlowImplSpecific::CppDataFlow> {
5454
bindingset[token]
5555
ParameterPosition decodeUnknownParameterPosition(AccessPath::AccessPathTokenBase token) {
5656
// needed to support `Argument[x..y]` ranges, `Argument[-1]`, and indirections `*Argument[0]`.
57-
exists(int indirection |
58-
token.getName() = indirectionString(indirection) + "Argument" and
59-
exists(int pos | pos = AccessPath::parseInt(token.getAnArgument()) |
60-
pos >= 0 and indirection = 0 and result = TDirectPosition(pos)
57+
exists(int indirection, string argPosString, int argPos |
58+
token.getName() = "Argument" and
59+
token.getAnArgument() = indirectionString(indirection) + argPosString and
60+
argPos = AccessPath::parseInt(argPosString) and
61+
(
62+
argPos >= 0 and indirection = 0 and result = TDirectPosition(argPos)
6163
or
62-
pos >= 0 and indirection > 0 and result = TIndirectionPosition(pos, indirection)
64+
argPos >= 0 and indirection > 0 and result = TIndirectionPosition(argPos, indirection)
6365
or
6466
// `Argument[-1]` is the qualifier object `*this`, not the `this` pointer itself
65-
pos = -1 and result = TIndirectionPosition(pos, indirection + 1)
67+
argPos = -1 and result = TIndirectionPosition(argPos, indirection + 1)
6668
)
6769
)
6870
}
6971

7072
bindingset[token]
7173
ArgumentPosition decodeUnknownArgumentPosition(AccessPath::AccessPathTokenBase token) {
7274
// needed to support `Argument[x..y]` ranges, `Argument[-1]`, and indirections `*Argument[0]`.
73-
exists(int indirection |
74-
token.getName() = indirectionString(indirection) + "Parameter" and
75-
exists(int pos | pos = AccessPath::parseInt(token.getAnArgument()) |
76-
pos >= 0 and indirection = 0 and result = TDirectPosition(pos)
75+
exists(int indirection, string paramPosString, int paramPos |
76+
token.getName() = "Parameter" and
77+
token.getAnArgument() = indirectionString(indirection) + paramPosString and
78+
paramPos = AccessPath::parseInt(paramPosString) and
79+
(
80+
paramPos >= 0 and indirection = 0 and result = TDirectPosition(paramPos)
7781
or
78-
pos >= 0 and indirection > 0 and result = TIndirectionPosition(pos, indirection)
82+
paramPos >= 0 and indirection > 0 and result = TIndirectionPosition(paramPos, indirection)
7983
or
8084
// `Argument[-1]` is the qualifier object `*this`, not the `this` pointer itself
81-
pos = -1 and result = TIndirectionPosition(pos, indirection + 1)
85+
paramPos = -1 and result = TIndirectionPosition(paramPos, indirection + 1)
8286
)
8387
)
8488
}
8589

8690
bindingset[token]
8791
ContentSet decodeUnknownContent(AccessPath::AccessPathTokenBase token) {
88-
// field content (with indirection support).
92+
// field content (no indirection support)
8993
exists(FieldContent c |
9094
result.isSingleton(c) and
95+
token.getName() = c.getField().getName() and
96+
not exists(token.getArgumentList()) and
97+
c.getIndirectionIndex() = 1
98+
)
99+
or
100+
// field content (with indirection support)
101+
exists(FieldContent c |
102+
result.isSingleton(c) and
103+
token.getName() = c.getField().getName() and
91104
// FieldContent indices have 0 for the address, 1 for content, so we need to subtract one.
92-
token = indirectionString(c.getIndirectionIndex() - 1) + c.getField().getName()
105+
token.getAnArgument() = indirectionString(c.getIndirectionIndex() - 1)
93106
)
94107
}
95108
}

cpp/ql/test/library-tests/dataflow/models-as-data/FlowSummaryNode.expected

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
| tests.cpp:128:5:128:19 | [summary param] 0 in madArg0ToReturn | ParameterNode | madArg0ToReturn | madArg0ToReturn |
22
| tests.cpp:128:5:128:19 | [summary] to write: ReturnValue in madArg0ToReturn | ReturnNode | madArg0ToReturn | madArg0ToReturn |
33
| tests.cpp:129:6:129:28 | [summary param] 0 in madArg0ToReturnIndirect | ParameterNode | madArg0ToReturnIndirect | madArg0ToReturnIndirect |
4-
| tests.cpp:129:6:129:28 | [summary] to write: *ReturnValue in madArg0ToReturnIndirect | ReturnNode | madArg0ToReturnIndirect | madArg0ToReturnIndirect |
4+
| tests.cpp:129:6:129:28 | [summary] to write: ReturnValue[*] in madArg0ToReturnIndirect | ReturnNode | madArg0ToReturnIndirect | madArg0ToReturnIndirect |
55
| tests.cpp:131:5:131:28 | [summary param] 0 in madArg0ToReturnValueFlow | ParameterNode | madArg0ToReturnValueFlow | madArg0ToReturnValueFlow |
66
| tests.cpp:131:5:131:28 | [summary] to write: ReturnValue in madArg0ToReturnValueFlow | ReturnNode | madArg0ToReturnValueFlow | madArg0ToReturnValueFlow |
77
| tests.cpp:132:5:132:27 | [summary param] 0 indirection in madArg0IndirectToReturn | ParameterNode | madArg0IndirectToReturn | madArg0IndirectToReturn |
@@ -23,17 +23,17 @@
2323
| tests.cpp:139:5:139:32 | [summary] read: Argument[0 indirection].Field[value] in madArg0IndirectFieldToReturn | | madArg0IndirectFieldToReturn | madArg0IndirectFieldToReturn |
2424
| tests.cpp:139:5:139:32 | [summary] to write: ReturnValue in madArg0IndirectFieldToReturn | ReturnNode | madArg0IndirectFieldToReturn | madArg0IndirectFieldToReturn |
2525
| tests.cpp:140:5:140:32 | [summary param] 0 in madArg0FieldIndirectToReturn | ParameterNode | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
26-
| tests.cpp:140:5:140:32 | [summary] read: Argument[0].*Field[ptr] in madArg0FieldIndirectToReturn | | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
26+
| tests.cpp:140:5:140:32 | [summary] read: Argument[0].Field[*ptr] in madArg0FieldIndirectToReturn | | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
2727
| tests.cpp:140:5:140:32 | [summary] to write: ReturnValue in madArg0FieldIndirectToReturn | ReturnNode | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
2828
| tests.cpp:141:13:141:32 | [summary param] 0 in madArg0ToReturnField | ParameterNode | madArg0ToReturnField | madArg0ToReturnField |
2929
| tests.cpp:141:13:141:32 | [summary] to write: ReturnValue in madArg0ToReturnField | ReturnNode | madArg0ToReturnField | madArg0ToReturnField |
3030
| tests.cpp:141:13:141:32 | [summary] to write: ReturnValue.Field[value] in madArg0ToReturnField | | madArg0ToReturnField | madArg0ToReturnField |
3131
| tests.cpp:142:14:142:41 | [summary param] 0 in madArg0ToReturnIndirectField | ParameterNode | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
32-
| tests.cpp:142:14:142:41 | [summary] to write: *ReturnValue in madArg0ToReturnIndirectField | ReturnNode | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
33-
| tests.cpp:142:14:142:41 | [summary] to write: *ReturnValue.Field[value] in madArg0ToReturnIndirectField | | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
32+
| tests.cpp:142:14:142:41 | [summary] to write: ReturnValue[*] in madArg0ToReturnIndirectField | ReturnNode | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
33+
| tests.cpp:142:14:142:41 | [summary] to write: ReturnValue[*].Field[value] in madArg0ToReturnIndirectField | | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
3434
| tests.cpp:143:13:143:40 | [summary param] 0 in madArg0ToReturnFieldIndirect | ParameterNode | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
3535
| tests.cpp:143:13:143:40 | [summary] to write: ReturnValue in madArg0ToReturnFieldIndirect | ReturnNode | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
36-
| tests.cpp:143:13:143:40 | [summary] to write: ReturnValue.*Field[ptr] in madArg0ToReturnFieldIndirect | | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
36+
| tests.cpp:143:13:143:40 | [summary] to write: ReturnValue.Field[*ptr] in madArg0ToReturnFieldIndirect | | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
3737
| tests.cpp:227:7:227:19 | [summary param] 0 in madArg0ToSelf | ParameterNode | madArg0ToSelf | madArg0ToSelf |
3838
| tests.cpp:227:7:227:19 | [summary param] this indirection in madArg0ToSelf | ParameterNode | madArg0ToSelf | madArg0ToSelf |
3939
| tests.cpp:227:7:227:19 | [summary] to write: Argument[this indirection] in madArg0ToSelf | PostUpdateNode | madArg0ToSelf | madArg0ToSelf |

cpp/ql/test/library-tests/dataflow/models-as-data/testModels.qll

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,18 @@ private class TestSources extends SourceModelCsv {
1111
";;false;remoteMadSource;;;ReturnValue;remote",
1212
";;false;localMadSourceVoid;;;ReturnValue;local",
1313
";;false;localMadSourceHasBody;;;ReturnValue;local",
14-
";;false;remoteMadSourceIndirect;;;*ReturnValue;remote",
15-
";;false;remoteMadSourceDoubleIndirect;;;**ReturnValue;remote",
16-
";;false;remoteMadSourceIndirectArg0;;;*Argument[0];remote",
17-
";;false;remoteMadSourceIndirectArg1;;;*Argument[1];remote",
14+
";;false;remoteMadSourceIndirect;;;ReturnValue[*];remote",
15+
";;false;remoteMadSourceDoubleIndirect;;;ReturnValue[**];remote",
16+
";;false;remoteMadSourceIndirectArg0;;;Argument[*0];remote",
17+
";;false;remoteMadSourceIndirectArg1;;;Argument[*1];remote",
1818
";;false;remoteMadSourceVar;;;;remote",
1919
";;false;remoteMadSourceVarIndirect;;;*;remote",
2020
";;false;remoteMadSourceParam0;;;Parameter[0];remote",
2121
"MyNamespace;;false;namespaceLocalMadSource;;;ReturnValue;local",
2222
"MyNamespace;;false;namespaceLocalMadSourceVar;;;;local",
2323
"MyNamespace::MyNamespace2;;false;namespace2LocalMadSource;;;ReturnValue;local",
2424
";MyClass;true;memberRemoteMadSource;;;ReturnValue;remote",
25-
";MyClass;true;memberRemoteMadSourceIndirectArg0;;;*Argument[0];remote",
25+
";MyClass;true;memberRemoteMadSourceIndirectArg0;;;Argument[*0];remote",
2626
";MyClass;true;memberRemoteMadSourceVar;;;;remote",
2727
";MyClass;true;subtypeRemoteMadSource1;;;ReturnValue;remote",
2828
";MyClass;false;subtypeNonSource;;;ReturnValue;remote", // the tests define this in MyDerivedClass, so it should *not* be recongized as a source
@@ -44,8 +44,8 @@ private class TestSinks extends SinkModelCsv {
4444
";;false;madSinkArg1;;;Argument[1];test-sink",
4545
";;false;madSinkArg01;;;Argument[0..1];test-sink",
4646
";;false;madSinkArg02;;;Argument[0,2];test-sink",
47-
";;false;madSinkIndirectArg0;;;*Argument[0];test-sink",
48-
";;false;madSinkDoubleIndirectArg0;;;**Argument[0];test-sink",
47+
";;false;madSinkIndirectArg0;;;Argument[*0];test-sink",
48+
";;false;madSinkDoubleIndirectArg0;;;Argument[**0];test-sink",
4949
";;false;madSinkVar;;;;test-sink",
5050
";;false;madSinkVarIndirect;;;*;test-sink",
5151
";;false;madSinkParam0;;;Parameter[0];test-sink",
@@ -70,20 +70,20 @@ private class TestSummaries extends SummaryModelCsv {
7070
row =
7171
[
7272
";;false;madArg0ToReturn;;;Argument[0];ReturnValue;taint",
73-
";;false;madArg0ToReturnIndirect;;;Argument[0];*ReturnValue;taint",
73+
";;false;madArg0ToReturnIndirect;;;Argument[0];ReturnValue[*];taint",
7474
";;false;madArg0ToReturnValueFlow;;;Argument[0];ReturnValue;value",
75-
";;false;madArg0IndirectToReturn;;;*Argument[0];ReturnValue;taint",
76-
";;false;madArg0DoubleIndirectToReturn;;;**Argument[0];ReturnValue;taint",
75+
";;false;madArg0IndirectToReturn;;;Argument[*0];ReturnValue;taint",
76+
";;false;madArg0DoubleIndirectToReturn;;;Argument[**0];ReturnValue;taint",
7777
";;false;madArg0NotIndirectToReturn;;;Argument[0];ReturnValue;taint",
78-
";;false;madArg0ToArg1Indirect;;;Argument[0];*Argument[1];taint",
79-
";;false;madArg0IndirectToArg1Indirect;;;*Argument[0];*Argument[1];taint",
78+
";;false;madArg0ToArg1Indirect;;;Argument[0];Argument[*1];taint",
79+
";;false;madArg0IndirectToArg1Indirect;;;Argument[*0];Argument[*1];taint",
8080
";;false;madArg0FieldToReturn;;;Argument[0].value;ReturnValue;taint",
81-
";;false;madArg0IndirectFieldToReturn;;;*Argument[0].value;ReturnValue;taint",
82-
";;false;madArg0FieldIndirectToReturn;;;Argument[0].*ptr;ReturnValue;taint",
81+
";;false;madArg0IndirectFieldToReturn;;;Argument[*0].value;ReturnValue;taint",
82+
";;false;madArg0FieldIndirectToReturn;;;Argument[0].ptr[*];ReturnValue;taint",
8383
";;false;madArg0ToReturnField;;;Argument[0];ReturnValue.value;taint",
84-
";;false;madArg0ToReturnIndirectField;;;Argument[0];*ReturnValue.value;taint",
85-
";;false;madArg0ToReturnFieldIndirect;;;Argument[0];ReturnValue.*ptr;taint",
86-
";;false;madArg0ToReturnFieldNotIndirect;;;Argument[0];ReturnValue.*ptr;taint",
84+
";;false;madArg0ToReturnIndirectField;;;Argument[0];ReturnValue[*].value;taint",
85+
";;false;madArg0ToReturnFieldIndirect;;;Argument[0];ReturnValue.ptr[*];taint",
86+
";;false;madArg0ToReturnFieldNotIndirect;;;Argument[0];ReturnValue.ptr[*];taint",
8787
";MyClass;true;madArg0ToSelf;;;Argument[0];Argument[-1];taint",
8888
";MyClass;true;madSelfToReturn;;;Argument[-1];ReturnValue;taint",
8989
";MyClass;true;madArg0ToField;;;Argument[0];Argument[-1].val;taint",

cpp/ql/test/library-tests/dataflow/models-as-data/tests.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ void test_sources() {
4848
int a, b, c, d;
4949

5050
remoteMadSourceIndirectArg0(&a, &b);
51-
sink(a); // $ MISSING: ir
52-
sink(a);
51+
sink(a); // $ ir
52+
sink(a); // $ SPURIOUS: ir
5353
remoteMadSourceIndirectArg1(c, d);
5454
sink(c);
55-
sink(d); // $ MISSING: ir
55+
sink(d); // $ ir
5656

5757
sink(remoteMadSourceVar); // $ ir
5858
sink(*remoteMadSourceVarIndirect); // $ MISSING: ir
@@ -100,9 +100,9 @@ void test_sinks() {
100100

101101
int a = source();
102102
int *a_ptr = &a;
103-
madSinkIndirectArg0(&a); // $ MISSING: ir
104-
madSinkIndirectArg0(a_ptr); // $ MISSING: ir
105-
madSinkDoubleIndirectArg0(&a_ptr); // $ MISSING: ir
103+
madSinkIndirectArg0(&a); // $ ir
104+
madSinkIndirectArg0(a_ptr); // $ ir
105+
madSinkDoubleIndirectArg0(&a_ptr); // $ ir
106106

107107
madSinkVar = source(); // $ ir
108108

@@ -272,7 +272,7 @@ void test_class_members() {
272272

273273
int a;
274274
mc.memberRemoteMadSourceIndirectArg0(&a);
275-
sink(a); // $ MISSING: ir
275+
sink(a); // $ ir
276276

277277
sink(mc.memberRemoteMadSourceVar); // $ ir
278278

0 commit comments

Comments
 (0)