mirror of
https://github.com/github/codeql.git
synced 2026-02-20 00:43:44 +01:00
C++: Switch MAD syntax from *Argument[0] style to Argument[*0] style.
This commit is contained in:
@@ -32,35 +32,42 @@
|
||||
* or method, or a parameter.
|
||||
* 7. The `input` column specifies how data enters the element selected by the
|
||||
* first 6 columns, and the `output` column specifies how data leaves the
|
||||
* element selected by the first 6 columns. An `input` can be either "",
|
||||
* "Argument[n]", "Argument[n1..n2]", "ReturnValue":
|
||||
* element selected by the first 6 columns. An `input` can be either:
|
||||
* - "": Selects a write to the selected element in case this is a field.
|
||||
* - "Argument[n]": Selects an argument in a call to the selected element.
|
||||
* The arguments are zero-indexed, and `-1` specifies the qualifier object,
|
||||
* that is, `*this`.
|
||||
* - "Argument[n1..n2]": Similar to "Argument[n]" but select any argument in
|
||||
* the given range. The range is inclusive at both ends.
|
||||
* - one or more "*" can be added in front of the argument index to indicate
|
||||
* indirection, for example, `Argument[*0]` indicates the first indirection
|
||||
* of the 0th argument.
|
||||
* - `n1..n2` syntax can be used to indicate a range of arguments, inclusive
|
||||
* at both ends. One or more "*" can be added in front of the range to
|
||||
* indicate indirection on all arguments in the range, for example `*n1..n2`.
|
||||
* - "ReturnValue": Selects a value being returned by the selected element.
|
||||
* This requires that the selected element is a method with a body.
|
||||
* One or more "*" can be added as an argument to indicate indirection, for
|
||||
* example, "ReturnValue[*]" indicates the first indirection of the return
|
||||
* value.
|
||||
*
|
||||
* An `output` can be either "", "Argument[n]", "Argument[n1..n2]", "Parameter",
|
||||
* "Parameter[n]", "Parameter[n1..n2]", or "ReturnValue":
|
||||
* An `output` can be either:
|
||||
* - "": Selects a read of a selected field, or a selected parameter.
|
||||
* - "Argument[n]": Selects the post-update value of an argument in a call to the
|
||||
* selected element. That is, the value of the argument after the call returns.
|
||||
* The arguments are zero-indexed, and `-1` specifies the qualifier object,
|
||||
* that is, `*this`.
|
||||
* - "Argument[n1..n2]": Similar to "Argument[n]" but select any argument in
|
||||
* the given range. The range is inclusive at both ends.
|
||||
* - "Argument[n]": Selects the post-update value of an argument in a call to
|
||||
* the selected element. That is, the value of the argument after the call
|
||||
* returns. The arguments are zero-indexed, and `-1` specifies the qualifier
|
||||
* object, that is, `*this`.
|
||||
* - one or more "*" can be added in front of the argument index to indicate
|
||||
* indirection, for example, `Argument[*0]` indicates the first indirection
|
||||
* of the 0th argument.
|
||||
* - `n1..n2` syntax can be used to indicate a range of arguments, inclusive
|
||||
* at both ends. One or more "*" can be added in front of the range to
|
||||
* indicate indirection on all arguments in the range, for example `*n1..n2`.
|
||||
* - "Parameter": Selects the value of a parameter of the selected element.
|
||||
* "Parameter" is also allowed in case the selected element is already a
|
||||
* parameter itself.
|
||||
* - "Parameter[n]": Similar to "Parameter" but restricted to a specific
|
||||
* numbered parameter. The parameters are zero-indexed, and `-1` specifies
|
||||
* the qualifier object, that is, `*this`.
|
||||
* - "Parameter[n1..n2]": Similar to "Parameter[n]" but selects any parameter
|
||||
* in the given range. The range is inclusive at both ends.
|
||||
* - "ReturnValue": Selects the return value of a call to the selected element.
|
||||
* The syntax is the same as for "Argument", for example "Parameter[0]",
|
||||
* "Parameter[*0]", "Parameter[0..2]" etc. "Parameter" is also allowed in
|
||||
* case the selected element is already a parameter itself.
|
||||
* - "ReturnValue": Selects a value being returned by the selected element.
|
||||
* One or more "*" can be added as an argument to indicate indirection, for
|
||||
* example, "ReturnValue[*]" indicates the first indirection of the return
|
||||
* value.
|
||||
* 8. The `kind` column is a tag that can be referenced from QL to determine to
|
||||
* which classes the interpreted elements should be added. For example, for
|
||||
* sources "remote" indicates a default remote flow source, and for summaries
|
||||
|
||||
@@ -32,16 +32,16 @@ module Input implements InputSig<DataFlowImplSpecific::CppDataFlow> {
|
||||
|
||||
string encodeReturn(ReturnKind rk, string arg) {
|
||||
rk != getStandardReturnValueKind() and
|
||||
result = indirectionString(rk.(NormalReturnKind).getIndirectionIndex()) + "ReturnValue" and
|
||||
arg = ""
|
||||
result = "ReturnValue" and
|
||||
arg = indirectionString(rk.(NormalReturnKind).getIndirectionIndex())
|
||||
}
|
||||
|
||||
string encodeContent(ContentSet cs, string arg) {
|
||||
exists(FieldContent c |
|
||||
cs.isSingleton(c) and
|
||||
// FieldContent indices have 0 for the address, 1 for content, so we need to subtract one.
|
||||
result = indirectionString(c.getIndirectionIndex() - 1) + "Field" and
|
||||
arg = c.getField().getName()
|
||||
result = "Field" and
|
||||
arg = indirectionString(c.getIndirectionIndex() - 1) + c.getField().getName()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -54,15 +54,17 @@ module Input implements InputSig<DataFlowImplSpecific::CppDataFlow> {
|
||||
bindingset[token]
|
||||
ParameterPosition decodeUnknownParameterPosition(AccessPath::AccessPathTokenBase token) {
|
||||
// needed to support `Argument[x..y]` ranges, `Argument[-1]`, and indirections `*Argument[0]`.
|
||||
exists(int indirection |
|
||||
token.getName() = indirectionString(indirection) + "Argument" and
|
||||
exists(int pos | pos = AccessPath::parseInt(token.getAnArgument()) |
|
||||
pos >= 0 and indirection = 0 and result = TDirectPosition(pos)
|
||||
exists(int indirection, string argPosString, int argPos |
|
||||
token.getName() = "Argument" and
|
||||
token.getAnArgument() = indirectionString(indirection) + argPosString and
|
||||
argPos = AccessPath::parseInt(argPosString) and
|
||||
(
|
||||
argPos >= 0 and indirection = 0 and result = TDirectPosition(argPos)
|
||||
or
|
||||
pos >= 0 and indirection > 0 and result = TIndirectionPosition(pos, indirection)
|
||||
argPos >= 0 and indirection > 0 and result = TIndirectionPosition(argPos, indirection)
|
||||
or
|
||||
// `Argument[-1]` is the qualifier object `*this`, not the `this` pointer itself
|
||||
pos = -1 and result = TIndirectionPosition(pos, indirection + 1)
|
||||
argPos = -1 and result = TIndirectionPosition(argPos, indirection + 1)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -70,26 +72,37 @@ module Input implements InputSig<DataFlowImplSpecific::CppDataFlow> {
|
||||
bindingset[token]
|
||||
ArgumentPosition decodeUnknownArgumentPosition(AccessPath::AccessPathTokenBase token) {
|
||||
// needed to support `Argument[x..y]` ranges, `Argument[-1]`, and indirections `*Argument[0]`.
|
||||
exists(int indirection |
|
||||
token.getName() = indirectionString(indirection) + "Parameter" and
|
||||
exists(int pos | pos = AccessPath::parseInt(token.getAnArgument()) |
|
||||
pos >= 0 and indirection = 0 and result = TDirectPosition(pos)
|
||||
exists(int indirection, string paramPosString, int paramPos |
|
||||
token.getName() = "Parameter" and
|
||||
token.getAnArgument() = indirectionString(indirection) + paramPosString and
|
||||
paramPos = AccessPath::parseInt(paramPosString) and
|
||||
(
|
||||
paramPos >= 0 and indirection = 0 and result = TDirectPosition(paramPos)
|
||||
or
|
||||
pos >= 0 and indirection > 0 and result = TIndirectionPosition(pos, indirection)
|
||||
paramPos >= 0 and indirection > 0 and result = TIndirectionPosition(paramPos, indirection)
|
||||
or
|
||||
// `Argument[-1]` is the qualifier object `*this`, not the `this` pointer itself
|
||||
pos = -1 and result = TIndirectionPosition(pos, indirection + 1)
|
||||
paramPos = -1 and result = TIndirectionPosition(paramPos, indirection + 1)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
bindingset[token]
|
||||
ContentSet decodeUnknownContent(AccessPath::AccessPathTokenBase token) {
|
||||
// field content (with indirection support).
|
||||
// field content (no indirection support)
|
||||
exists(FieldContent c |
|
||||
result.isSingleton(c) and
|
||||
token.getName() = c.getField().getName() and
|
||||
not exists(token.getArgumentList()) and
|
||||
c.getIndirectionIndex() = 1
|
||||
)
|
||||
or
|
||||
// field content (with indirection support)
|
||||
exists(FieldContent c |
|
||||
result.isSingleton(c) and
|
||||
token.getName() = c.getField().getName() and
|
||||
// FieldContent indices have 0 for the address, 1 for content, so we need to subtract one.
|
||||
token = indirectionString(c.getIndirectionIndex() - 1) + c.getField().getName()
|
||||
token.getAnArgument() = indirectionString(c.getIndirectionIndex() - 1)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user