mirror of
https://github.com/github/codeql.git
synced 2026-04-29 10:45:15 +02:00
Merge remote-tracking branch 'upstream/master' into dataflow-ref-parameter
I've accepted the new test output, which shows that this branch fixes two false negatives in the test cases from #2088.
This commit is contained in:
@@ -30,7 +30,7 @@ private predicate additionalLogicalCheck(Expr e, string operation, int valueToCh
|
||||
/**
|
||||
* An `Operation` that seems to be checking for leap year.
|
||||
*/
|
||||
class CheckForLeapYearOperation extends Operation {
|
||||
class CheckForLeapYearOperation extends Expr {
|
||||
CheckForLeapYearOperation() {
|
||||
exists(BinaryArithmeticOperation bo | bo = this |
|
||||
bo.getAnOperand().getValue().toInt() = 4 and
|
||||
@@ -39,8 +39,6 @@ class CheckForLeapYearOperation extends Operation {
|
||||
additionalLogicalCheck(this.getEnclosingElement(), "%", 400)
|
||||
)
|
||||
}
|
||||
|
||||
override string getOperator() { result = "LeapYearCheck" }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* on each other without introducing mutual recursion among those configurations.
|
||||
*/
|
||||
|
||||
private import DataFlowImplCommon
|
||||
private import DataFlowImplCommon::Public
|
||||
private import DataFlowImplSpecific::Private
|
||||
import DataFlowImplSpecific::Public
|
||||
|
||||
@@ -1075,6 +1075,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
|
||||
flowCandFwd(mid, fromArg, _, config) and
|
||||
store(mid, f, node) and
|
||||
nodeCand(node, unbind(config)) and
|
||||
readStoreCand(f, unbind(config)) and
|
||||
apf.headUsesContent(f)
|
||||
)
|
||||
or
|
||||
@@ -1175,12 +1176,12 @@ private predicate flowCand0(Node node, boolean toReturn, AccessPathFront apf, Co
|
||||
exists(Content f, AccessPathFront apf0 |
|
||||
flowCandStore(node, f, toReturn, apf0, config) and
|
||||
apf0.headUsesContent(f) and
|
||||
consCand(f, apf, unbind(config))
|
||||
consCand(f, apf, config)
|
||||
)
|
||||
or
|
||||
exists(Content f, AccessPathFront apf0 |
|
||||
flowCandRead(node, f, toReturn, apf0, config) and
|
||||
consCandFwd(f, apf0, unbind(config)) and
|
||||
consCandFwd(f, apf0, config) and
|
||||
apf.headUsesContent(f)
|
||||
)
|
||||
}
|
||||
@@ -1221,8 +1222,8 @@ private newtype TAccessPath =
|
||||
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
|
||||
|
||||
/**
|
||||
* Conceptually a list of `Content`s followed by a `Type`, but only the first
|
||||
* element of the list and its length are tracked. If data flows from a source to
|
||||
* Conceptually a list of `Content`s followed by a `Type`, but only the first two
|
||||
* elements of the list and its length are tracked. If data flows from a source to
|
||||
* a given node with a given `AccessPath`, this indicates the sequence of
|
||||
* dereference operations needed to get from the value in the node to the
|
||||
* tracked object. The final type indicates the type of the tracked object.
|
||||
@@ -1260,7 +1261,7 @@ abstract private class AccessPath extends TAccessPath {
|
||||
|
||||
private class AccessPathNil extends AccessPath, TNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(" : " + ppReprType(t)))
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
@@ -1276,7 +1277,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
override string toString() {
|
||||
exists(Content f, DataFlowType t | this = TConsNil(f, t) |
|
||||
// The `concat` becomes "" if `ppReprType` has no result.
|
||||
result = f.toString() + concat(" : " + ppReprType(t))
|
||||
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1293,8 +1294,8 @@ private class AccessPathConsCons extends AccessPathCons, TConsCons {
|
||||
override string toString() {
|
||||
exists(Content f1, Content f2, int len | this = TConsCons(f1, f2, len) |
|
||||
if len = 2
|
||||
then result = f1.toString() + ", " + f2.toString()
|
||||
else result = f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")"
|
||||
then result = "[" + f1.toString() + ", " + f2.toString() + "]"
|
||||
else result = "[" + f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")]"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1625,7 +1626,7 @@ abstract class PathNode extends TPathNode {
|
||||
this instanceof PathNodeSink and result = ""
|
||||
or
|
||||
exists(string s | s = this.(PathNodeMid).getAp().toString() |
|
||||
if s = "" then result = "" else result = " [" + s + "]"
|
||||
if s = "" then result = "" else result = " " + s
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2070,7 +2071,7 @@ private module FlowExploration {
|
||||
|
||||
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(" : " + ppReprType(t)))
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
@@ -2082,8 +2083,8 @@ private module FlowExploration {
|
||||
override string toString() {
|
||||
exists(Content f, int len | this = TPartialCons(f, len) |
|
||||
if len = 1
|
||||
then result = f.toString()
|
||||
else result = f.toString() + ", ... (" + len.toString() + ")"
|
||||
then result = "[" + f.toString() + "]"
|
||||
else result = "[" + f.toString() + ", ... (" + len.toString() + ")]"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2160,7 +2161,7 @@ private module FlowExploration {
|
||||
|
||||
private string ppAp() {
|
||||
exists(string s | s = this.(PartialPathNodePriv).getAp().toString() |
|
||||
if s = "" then result = "" else result = " [" + s + "]"
|
||||
if s = "" then result = "" else result = " " + s
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* on each other without introducing mutual recursion among those configurations.
|
||||
*/
|
||||
|
||||
private import DataFlowImplCommon
|
||||
private import DataFlowImplCommon::Public
|
||||
private import DataFlowImplSpecific::Private
|
||||
import DataFlowImplSpecific::Public
|
||||
|
||||
@@ -1075,6 +1075,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
|
||||
flowCandFwd(mid, fromArg, _, config) and
|
||||
store(mid, f, node) and
|
||||
nodeCand(node, unbind(config)) and
|
||||
readStoreCand(f, unbind(config)) and
|
||||
apf.headUsesContent(f)
|
||||
)
|
||||
or
|
||||
@@ -1175,12 +1176,12 @@ private predicate flowCand0(Node node, boolean toReturn, AccessPathFront apf, Co
|
||||
exists(Content f, AccessPathFront apf0 |
|
||||
flowCandStore(node, f, toReturn, apf0, config) and
|
||||
apf0.headUsesContent(f) and
|
||||
consCand(f, apf, unbind(config))
|
||||
consCand(f, apf, config)
|
||||
)
|
||||
or
|
||||
exists(Content f, AccessPathFront apf0 |
|
||||
flowCandRead(node, f, toReturn, apf0, config) and
|
||||
consCandFwd(f, apf0, unbind(config)) and
|
||||
consCandFwd(f, apf0, config) and
|
||||
apf.headUsesContent(f)
|
||||
)
|
||||
}
|
||||
@@ -1221,8 +1222,8 @@ private newtype TAccessPath =
|
||||
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
|
||||
|
||||
/**
|
||||
* Conceptually a list of `Content`s followed by a `Type`, but only the first
|
||||
* element of the list and its length are tracked. If data flows from a source to
|
||||
* Conceptually a list of `Content`s followed by a `Type`, but only the first two
|
||||
* elements of the list and its length are tracked. If data flows from a source to
|
||||
* a given node with a given `AccessPath`, this indicates the sequence of
|
||||
* dereference operations needed to get from the value in the node to the
|
||||
* tracked object. The final type indicates the type of the tracked object.
|
||||
@@ -1260,7 +1261,7 @@ abstract private class AccessPath extends TAccessPath {
|
||||
|
||||
private class AccessPathNil extends AccessPath, TNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(" : " + ppReprType(t)))
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
@@ -1276,7 +1277,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
override string toString() {
|
||||
exists(Content f, DataFlowType t | this = TConsNil(f, t) |
|
||||
// The `concat` becomes "" if `ppReprType` has no result.
|
||||
result = f.toString() + concat(" : " + ppReprType(t))
|
||||
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1293,8 +1294,8 @@ private class AccessPathConsCons extends AccessPathCons, TConsCons {
|
||||
override string toString() {
|
||||
exists(Content f1, Content f2, int len | this = TConsCons(f1, f2, len) |
|
||||
if len = 2
|
||||
then result = f1.toString() + ", " + f2.toString()
|
||||
else result = f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")"
|
||||
then result = "[" + f1.toString() + ", " + f2.toString() + "]"
|
||||
else result = "[" + f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")]"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1625,7 +1626,7 @@ abstract class PathNode extends TPathNode {
|
||||
this instanceof PathNodeSink and result = ""
|
||||
or
|
||||
exists(string s | s = this.(PathNodeMid).getAp().toString() |
|
||||
if s = "" then result = "" else result = " [" + s + "]"
|
||||
if s = "" then result = "" else result = " " + s
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2070,7 +2071,7 @@ private module FlowExploration {
|
||||
|
||||
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(" : " + ppReprType(t)))
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
@@ -2082,8 +2083,8 @@ private module FlowExploration {
|
||||
override string toString() {
|
||||
exists(Content f, int len | this = TPartialCons(f, len) |
|
||||
if len = 1
|
||||
then result = f.toString()
|
||||
else result = f.toString() + ", ... (" + len.toString() + ")"
|
||||
then result = "[" + f.toString() + "]"
|
||||
else result = "[" + f.toString() + ", ... (" + len.toString() + ")]"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2160,7 +2161,7 @@ private module FlowExploration {
|
||||
|
||||
private string ppAp() {
|
||||
exists(string s | s = this.(PartialPathNodePriv).getAp().toString() |
|
||||
if s = "" then result = "" else result = " [" + s + "]"
|
||||
if s = "" then result = "" else result = " " + s
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* on each other without introducing mutual recursion among those configurations.
|
||||
*/
|
||||
|
||||
private import DataFlowImplCommon
|
||||
private import DataFlowImplCommon::Public
|
||||
private import DataFlowImplSpecific::Private
|
||||
import DataFlowImplSpecific::Public
|
||||
|
||||
@@ -1075,6 +1075,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
|
||||
flowCandFwd(mid, fromArg, _, config) and
|
||||
store(mid, f, node) and
|
||||
nodeCand(node, unbind(config)) and
|
||||
readStoreCand(f, unbind(config)) and
|
||||
apf.headUsesContent(f)
|
||||
)
|
||||
or
|
||||
@@ -1175,12 +1176,12 @@ private predicate flowCand0(Node node, boolean toReturn, AccessPathFront apf, Co
|
||||
exists(Content f, AccessPathFront apf0 |
|
||||
flowCandStore(node, f, toReturn, apf0, config) and
|
||||
apf0.headUsesContent(f) and
|
||||
consCand(f, apf, unbind(config))
|
||||
consCand(f, apf, config)
|
||||
)
|
||||
or
|
||||
exists(Content f, AccessPathFront apf0 |
|
||||
flowCandRead(node, f, toReturn, apf0, config) and
|
||||
consCandFwd(f, apf0, unbind(config)) and
|
||||
consCandFwd(f, apf0, config) and
|
||||
apf.headUsesContent(f)
|
||||
)
|
||||
}
|
||||
@@ -1221,8 +1222,8 @@ private newtype TAccessPath =
|
||||
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
|
||||
|
||||
/**
|
||||
* Conceptually a list of `Content`s followed by a `Type`, but only the first
|
||||
* element of the list and its length are tracked. If data flows from a source to
|
||||
* Conceptually a list of `Content`s followed by a `Type`, but only the first two
|
||||
* elements of the list and its length are tracked. If data flows from a source to
|
||||
* a given node with a given `AccessPath`, this indicates the sequence of
|
||||
* dereference operations needed to get from the value in the node to the
|
||||
* tracked object. The final type indicates the type of the tracked object.
|
||||
@@ -1260,7 +1261,7 @@ abstract private class AccessPath extends TAccessPath {
|
||||
|
||||
private class AccessPathNil extends AccessPath, TNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(" : " + ppReprType(t)))
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
@@ -1276,7 +1277,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
override string toString() {
|
||||
exists(Content f, DataFlowType t | this = TConsNil(f, t) |
|
||||
// The `concat` becomes "" if `ppReprType` has no result.
|
||||
result = f.toString() + concat(" : " + ppReprType(t))
|
||||
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1293,8 +1294,8 @@ private class AccessPathConsCons extends AccessPathCons, TConsCons {
|
||||
override string toString() {
|
||||
exists(Content f1, Content f2, int len | this = TConsCons(f1, f2, len) |
|
||||
if len = 2
|
||||
then result = f1.toString() + ", " + f2.toString()
|
||||
else result = f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")"
|
||||
then result = "[" + f1.toString() + ", " + f2.toString() + "]"
|
||||
else result = "[" + f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")]"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1625,7 +1626,7 @@ abstract class PathNode extends TPathNode {
|
||||
this instanceof PathNodeSink and result = ""
|
||||
or
|
||||
exists(string s | s = this.(PathNodeMid).getAp().toString() |
|
||||
if s = "" then result = "" else result = " [" + s + "]"
|
||||
if s = "" then result = "" else result = " " + s
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2070,7 +2071,7 @@ private module FlowExploration {
|
||||
|
||||
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(" : " + ppReprType(t)))
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
@@ -2082,8 +2083,8 @@ private module FlowExploration {
|
||||
override string toString() {
|
||||
exists(Content f, int len | this = TPartialCons(f, len) |
|
||||
if len = 1
|
||||
then result = f.toString()
|
||||
else result = f.toString() + ", ... (" + len.toString() + ")"
|
||||
then result = "[" + f.toString() + "]"
|
||||
else result = "[" + f.toString() + ", ... (" + len.toString() + ")]"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2160,7 +2161,7 @@ private module FlowExploration {
|
||||
|
||||
private string ppAp() {
|
||||
exists(string s | s = this.(PartialPathNodePriv).getAp().toString() |
|
||||
if s = "" then result = "" else result = " [" + s + "]"
|
||||
if s = "" then result = "" else result = " " + s
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* on each other without introducing mutual recursion among those configurations.
|
||||
*/
|
||||
|
||||
private import DataFlowImplCommon
|
||||
private import DataFlowImplCommon::Public
|
||||
private import DataFlowImplSpecific::Private
|
||||
import DataFlowImplSpecific::Public
|
||||
|
||||
@@ -1075,6 +1075,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
|
||||
flowCandFwd(mid, fromArg, _, config) and
|
||||
store(mid, f, node) and
|
||||
nodeCand(node, unbind(config)) and
|
||||
readStoreCand(f, unbind(config)) and
|
||||
apf.headUsesContent(f)
|
||||
)
|
||||
or
|
||||
@@ -1175,12 +1176,12 @@ private predicate flowCand0(Node node, boolean toReturn, AccessPathFront apf, Co
|
||||
exists(Content f, AccessPathFront apf0 |
|
||||
flowCandStore(node, f, toReturn, apf0, config) and
|
||||
apf0.headUsesContent(f) and
|
||||
consCand(f, apf, unbind(config))
|
||||
consCand(f, apf, config)
|
||||
)
|
||||
or
|
||||
exists(Content f, AccessPathFront apf0 |
|
||||
flowCandRead(node, f, toReturn, apf0, config) and
|
||||
consCandFwd(f, apf0, unbind(config)) and
|
||||
consCandFwd(f, apf0, config) and
|
||||
apf.headUsesContent(f)
|
||||
)
|
||||
}
|
||||
@@ -1221,8 +1222,8 @@ private newtype TAccessPath =
|
||||
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
|
||||
|
||||
/**
|
||||
* Conceptually a list of `Content`s followed by a `Type`, but only the first
|
||||
* element of the list and its length are tracked. If data flows from a source to
|
||||
* Conceptually a list of `Content`s followed by a `Type`, but only the first two
|
||||
* elements of the list and its length are tracked. If data flows from a source to
|
||||
* a given node with a given `AccessPath`, this indicates the sequence of
|
||||
* dereference operations needed to get from the value in the node to the
|
||||
* tracked object. The final type indicates the type of the tracked object.
|
||||
@@ -1260,7 +1261,7 @@ abstract private class AccessPath extends TAccessPath {
|
||||
|
||||
private class AccessPathNil extends AccessPath, TNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(" : " + ppReprType(t)))
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
@@ -1276,7 +1277,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
override string toString() {
|
||||
exists(Content f, DataFlowType t | this = TConsNil(f, t) |
|
||||
// The `concat` becomes "" if `ppReprType` has no result.
|
||||
result = f.toString() + concat(" : " + ppReprType(t))
|
||||
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1293,8 +1294,8 @@ private class AccessPathConsCons extends AccessPathCons, TConsCons {
|
||||
override string toString() {
|
||||
exists(Content f1, Content f2, int len | this = TConsCons(f1, f2, len) |
|
||||
if len = 2
|
||||
then result = f1.toString() + ", " + f2.toString()
|
||||
else result = f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")"
|
||||
then result = "[" + f1.toString() + ", " + f2.toString() + "]"
|
||||
else result = "[" + f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")]"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1625,7 +1626,7 @@ abstract class PathNode extends TPathNode {
|
||||
this instanceof PathNodeSink and result = ""
|
||||
or
|
||||
exists(string s | s = this.(PathNodeMid).getAp().toString() |
|
||||
if s = "" then result = "" else result = " [" + s + "]"
|
||||
if s = "" then result = "" else result = " " + s
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2070,7 +2071,7 @@ private module FlowExploration {
|
||||
|
||||
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(" : " + ppReprType(t)))
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
@@ -2082,8 +2083,8 @@ private module FlowExploration {
|
||||
override string toString() {
|
||||
exists(Content f, int len | this = TPartialCons(f, len) |
|
||||
if len = 1
|
||||
then result = f.toString()
|
||||
else result = f.toString() + ", ... (" + len.toString() + ")"
|
||||
then result = "[" + f.toString() + "]"
|
||||
else result = "[" + f.toString() + ", ... (" + len.toString() + ")]"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2160,7 +2161,7 @@ private module FlowExploration {
|
||||
|
||||
private string ppAp() {
|
||||
exists(string s | s = this.(PartialPathNodePriv).getAp().toString() |
|
||||
if s = "" then result = "" else result = " [" + s + "]"
|
||||
if s = "" then result = "" else result = " " + s
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@
|
||||
* on each other without introducing mutual recursion among those configurations.
|
||||
*/
|
||||
|
||||
private import DataFlowImplCommon
|
||||
private import DataFlowImplCommon::Public
|
||||
private import DataFlowImplSpecific::Private
|
||||
import DataFlowImplSpecific::Public
|
||||
|
||||
@@ -1075,6 +1075,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
|
||||
flowCandFwd(mid, fromArg, _, config) and
|
||||
store(mid, f, node) and
|
||||
nodeCand(node, unbind(config)) and
|
||||
readStoreCand(f, unbind(config)) and
|
||||
apf.headUsesContent(f)
|
||||
)
|
||||
or
|
||||
@@ -1175,12 +1176,12 @@ private predicate flowCand0(Node node, boolean toReturn, AccessPathFront apf, Co
|
||||
exists(Content f, AccessPathFront apf0 |
|
||||
flowCandStore(node, f, toReturn, apf0, config) and
|
||||
apf0.headUsesContent(f) and
|
||||
consCand(f, apf, unbind(config))
|
||||
consCand(f, apf, config)
|
||||
)
|
||||
or
|
||||
exists(Content f, AccessPathFront apf0 |
|
||||
flowCandRead(node, f, toReturn, apf0, config) and
|
||||
consCandFwd(f, apf0, unbind(config)) and
|
||||
consCandFwd(f, apf0, config) and
|
||||
apf.headUsesContent(f)
|
||||
)
|
||||
}
|
||||
@@ -1221,8 +1222,8 @@ private newtype TAccessPath =
|
||||
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
|
||||
|
||||
/**
|
||||
* Conceptually a list of `Content`s followed by a `Type`, but only the first
|
||||
* element of the list and its length are tracked. If data flows from a source to
|
||||
* Conceptually a list of `Content`s followed by a `Type`, but only the first two
|
||||
* elements of the list and its length are tracked. If data flows from a source to
|
||||
* a given node with a given `AccessPath`, this indicates the sequence of
|
||||
* dereference operations needed to get from the value in the node to the
|
||||
* tracked object. The final type indicates the type of the tracked object.
|
||||
@@ -1260,7 +1261,7 @@ abstract private class AccessPath extends TAccessPath {
|
||||
|
||||
private class AccessPathNil extends AccessPath, TNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(" : " + ppReprType(t)))
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
@@ -1276,7 +1277,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
override string toString() {
|
||||
exists(Content f, DataFlowType t | this = TConsNil(f, t) |
|
||||
// The `concat` becomes "" if `ppReprType` has no result.
|
||||
result = f.toString() + concat(" : " + ppReprType(t))
|
||||
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1293,8 +1294,8 @@ private class AccessPathConsCons extends AccessPathCons, TConsCons {
|
||||
override string toString() {
|
||||
exists(Content f1, Content f2, int len | this = TConsCons(f1, f2, len) |
|
||||
if len = 2
|
||||
then result = f1.toString() + ", " + f2.toString()
|
||||
else result = f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")"
|
||||
then result = "[" + f1.toString() + ", " + f2.toString() + "]"
|
||||
else result = "[" + f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")]"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1625,7 +1626,7 @@ abstract class PathNode extends TPathNode {
|
||||
this instanceof PathNodeSink and result = ""
|
||||
or
|
||||
exists(string s | s = this.(PathNodeMid).getAp().toString() |
|
||||
if s = "" then result = "" else result = " [" + s + "]"
|
||||
if s = "" then result = "" else result = " " + s
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2070,7 +2071,7 @@ private module FlowExploration {
|
||||
|
||||
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(" : " + ppReprType(t)))
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
@@ -2082,8 +2083,8 @@ private module FlowExploration {
|
||||
override string toString() {
|
||||
exists(Content f, int len | this = TPartialCons(f, len) |
|
||||
if len = 1
|
||||
then result = f.toString()
|
||||
else result = f.toString() + ", ... (" + len.toString() + ")"
|
||||
then result = "[" + f.toString() + "]"
|
||||
else result = "[" + f.toString() + ", ... (" + len.toString() + ")]"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2160,7 +2161,7 @@ private module FlowExploration {
|
||||
|
||||
private string ppAp() {
|
||||
exists(string s | s = this.(PartialPathNodePriv).getAp().toString() |
|
||||
if s = "" then result = "" else result = " [" + s + "]"
|
||||
if s = "" then result = "" else result = " " + s
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -511,7 +511,7 @@ module FlowVar_internal {
|
||||
exists(VariableAccess va |
|
||||
va.getTarget() = result and
|
||||
readAccess(va) and
|
||||
bbNotInLoop(va.getBasicBlock())
|
||||
exists(BasicBlock bb | bb = va.getBasicBlock() | not this.bbInLoop(bb))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -534,10 +534,8 @@ module FlowVar_internal {
|
||||
bbInLoopCondition(bb)
|
||||
}
|
||||
|
||||
predicate bbNotInLoop(BasicBlock bb) {
|
||||
not this.bbInLoop(bb) and
|
||||
bb.getEnclosingFunction() = this.getEnclosingFunction()
|
||||
}
|
||||
/** Holds if `sbb` is inside this loop. */
|
||||
predicate sbbInLoop(SubBasicBlock sbb) { this.bbInLoop(sbb.getBasicBlock()) }
|
||||
|
||||
/**
|
||||
* Holds if `bb` is a basic block inside this loop where `v` has not been
|
||||
@@ -558,22 +556,19 @@ module FlowVar_internal {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if some loop always assigns to `v` before leaving through an edge
|
||||
* from `bbInside` in its condition to `bbOutside` outside the loop, where
|
||||
* (`sbbDef`, `v`) is a `BlockVar` defined outside the loop. Also, `v` must
|
||||
* be used outside the loop.
|
||||
* Holds if `loop` always assigns to `v` before leaving through an edge
|
||||
* from `bbInside` in its condition to `bbOutside` outside the loop. Also,
|
||||
* `v` must be used outside the loop.
|
||||
*/
|
||||
predicate skipLoop(
|
||||
SubBasicBlock sbbInside, SubBasicBlock sbbOutside, SubBasicBlock sbbDef, Variable v
|
||||
SubBasicBlock sbbInside, SubBasicBlock sbbOutside, Variable v, AlwaysTrueUponEntryLoop loop
|
||||
) {
|
||||
exists(AlwaysTrueUponEntryLoop loop, BasicBlock bbInside, BasicBlock bbOutside |
|
||||
exists(BasicBlock bbInside, BasicBlock bbOutside |
|
||||
loop.alwaysAssignsBeforeLeavingCondition(bbInside, bbOutside, v) and
|
||||
bbInside = sbbInside.getBasicBlock() and
|
||||
bbOutside = sbbOutside.getBasicBlock() and
|
||||
sbbInside.lastInBB() and
|
||||
sbbOutside.firstInBB() and
|
||||
loop.bbNotInLoop(sbbDef.getBasicBlock()) and
|
||||
exists(TBlockVar(sbbDef, v))
|
||||
sbbOutside.firstInBB()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -592,7 +587,7 @@ module FlowVar_internal {
|
||||
start = TBlockVar(sbbDef, v) and
|
||||
result = mid.getASuccessor() and
|
||||
variableLiveInSBB(result, v) and
|
||||
not skipLoop(mid, result, sbbDef, v) and
|
||||
forall(AlwaysTrueUponEntryLoop loop | skipLoop(mid, result, v, loop) | loop.sbbInLoop(sbbDef)) and
|
||||
not assignmentLikeOperation(result, v, _, _)
|
||||
)
|
||||
}
|
||||
@@ -711,10 +706,11 @@ module FlowVar_internal {
|
||||
predicate dominatedByOverwrite(UninitializedLocalVariable v, VariableAccess va) {
|
||||
exists(BasicBlock bb, int vaIndex |
|
||||
va = bb.getNode(vaIndex) and
|
||||
va.getTarget() = v
|
||||
|
|
||||
va.getTarget() = v and
|
||||
vaIndex > indexOfFirstOverwriteInBB(v, bb)
|
||||
or
|
||||
va = bb.getNode(vaIndex) and
|
||||
va.getTarget() = v and
|
||||
bbStrictlyDominates(getAnOverwritingBB(v), bb)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,25 +4,17 @@ private import semmle.code.cpp.ir.dataflow.DataFlow
|
||||
private import semmle.code.cpp.ir.IR
|
||||
|
||||
/**
|
||||
* A predictable expression is one where an external user can predict
|
||||
* A predictable instruction is one where an external user can predict
|
||||
* the value. For example, a literal in the source code is considered
|
||||
* predictable.
|
||||
*/
|
||||
// TODO: Change to use Instruction instead of Expr. Naive attempt breaks
|
||||
// TaintedAllocationSize qltest.
|
||||
private predicate predictable(Expr expr) {
|
||||
expr instanceof Literal
|
||||
or
|
||||
exists(BinaryOperation binop | binop = expr |
|
||||
predictable(binop.getLeftOperand()) and predictable(binop.getRightOperand())
|
||||
)
|
||||
or
|
||||
exists(UnaryOperation unop | unop = expr | predictable(unop.getOperand()))
|
||||
}
|
||||
|
||||
// TODO: remove when `predictable` has an `Instruction` parameter instead of `Expr`.
|
||||
private predicate predictableInstruction(Instruction instr) {
|
||||
predictable(DataFlow::instructionNode(instr).asExpr())
|
||||
instr instanceof ConstantInstruction
|
||||
or
|
||||
instr instanceof StringConstantInstruction
|
||||
or
|
||||
// This could be a conversion on a string literal
|
||||
predictableInstruction(instr.(UnaryInstruction).getUnary())
|
||||
}
|
||||
|
||||
private class DefaultTaintTrackingCfg extends DataFlow::Configuration {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* on each other without introducing mutual recursion among those configurations.
|
||||
*/
|
||||
|
||||
private import DataFlowImplCommon
|
||||
private import DataFlowImplCommon::Public
|
||||
private import DataFlowImplSpecific::Private
|
||||
import DataFlowImplSpecific::Public
|
||||
|
||||
@@ -1075,6 +1075,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
|
||||
flowCandFwd(mid, fromArg, _, config) and
|
||||
store(mid, f, node) and
|
||||
nodeCand(node, unbind(config)) and
|
||||
readStoreCand(f, unbind(config)) and
|
||||
apf.headUsesContent(f)
|
||||
)
|
||||
or
|
||||
@@ -1175,12 +1176,12 @@ private predicate flowCand0(Node node, boolean toReturn, AccessPathFront apf, Co
|
||||
exists(Content f, AccessPathFront apf0 |
|
||||
flowCandStore(node, f, toReturn, apf0, config) and
|
||||
apf0.headUsesContent(f) and
|
||||
consCand(f, apf, unbind(config))
|
||||
consCand(f, apf, config)
|
||||
)
|
||||
or
|
||||
exists(Content f, AccessPathFront apf0 |
|
||||
flowCandRead(node, f, toReturn, apf0, config) and
|
||||
consCandFwd(f, apf0, unbind(config)) and
|
||||
consCandFwd(f, apf0, config) and
|
||||
apf.headUsesContent(f)
|
||||
)
|
||||
}
|
||||
@@ -1221,8 +1222,8 @@ private newtype TAccessPath =
|
||||
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
|
||||
|
||||
/**
|
||||
* Conceptually a list of `Content`s followed by a `Type`, but only the first
|
||||
* element of the list and its length are tracked. If data flows from a source to
|
||||
* Conceptually a list of `Content`s followed by a `Type`, but only the first two
|
||||
* elements of the list and its length are tracked. If data flows from a source to
|
||||
* a given node with a given `AccessPath`, this indicates the sequence of
|
||||
* dereference operations needed to get from the value in the node to the
|
||||
* tracked object. The final type indicates the type of the tracked object.
|
||||
@@ -1260,7 +1261,7 @@ abstract private class AccessPath extends TAccessPath {
|
||||
|
||||
private class AccessPathNil extends AccessPath, TNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(" : " + ppReprType(t)))
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
@@ -1276,7 +1277,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
override string toString() {
|
||||
exists(Content f, DataFlowType t | this = TConsNil(f, t) |
|
||||
// The `concat` becomes "" if `ppReprType` has no result.
|
||||
result = f.toString() + concat(" : " + ppReprType(t))
|
||||
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1293,8 +1294,8 @@ private class AccessPathConsCons extends AccessPathCons, TConsCons {
|
||||
override string toString() {
|
||||
exists(Content f1, Content f2, int len | this = TConsCons(f1, f2, len) |
|
||||
if len = 2
|
||||
then result = f1.toString() + ", " + f2.toString()
|
||||
else result = f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")"
|
||||
then result = "[" + f1.toString() + ", " + f2.toString() + "]"
|
||||
else result = "[" + f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")]"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1625,7 +1626,7 @@ abstract class PathNode extends TPathNode {
|
||||
this instanceof PathNodeSink and result = ""
|
||||
or
|
||||
exists(string s | s = this.(PathNodeMid).getAp().toString() |
|
||||
if s = "" then result = "" else result = " [" + s + "]"
|
||||
if s = "" then result = "" else result = " " + s
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2070,7 +2071,7 @@ private module FlowExploration {
|
||||
|
||||
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(" : " + ppReprType(t)))
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
@@ -2082,8 +2083,8 @@ private module FlowExploration {
|
||||
override string toString() {
|
||||
exists(Content f, int len | this = TPartialCons(f, len) |
|
||||
if len = 1
|
||||
then result = f.toString()
|
||||
else result = f.toString() + ", ... (" + len.toString() + ")"
|
||||
then result = "[" + f.toString() + "]"
|
||||
else result = "[" + f.toString() + ", ... (" + len.toString() + ")]"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2160,7 +2161,7 @@ private module FlowExploration {
|
||||
|
||||
private string ppAp() {
|
||||
exists(string s | s = this.(PartialPathNodePriv).getAp().toString() |
|
||||
if s = "" then result = "" else result = " [" + s + "]"
|
||||
if s = "" then result = "" else result = " " + s
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* on each other without introducing mutual recursion among those configurations.
|
||||
*/
|
||||
|
||||
private import DataFlowImplCommon
|
||||
private import DataFlowImplCommon::Public
|
||||
private import DataFlowImplSpecific::Private
|
||||
import DataFlowImplSpecific::Public
|
||||
|
||||
@@ -1075,6 +1075,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
|
||||
flowCandFwd(mid, fromArg, _, config) and
|
||||
store(mid, f, node) and
|
||||
nodeCand(node, unbind(config)) and
|
||||
readStoreCand(f, unbind(config)) and
|
||||
apf.headUsesContent(f)
|
||||
)
|
||||
or
|
||||
@@ -1175,12 +1176,12 @@ private predicate flowCand0(Node node, boolean toReturn, AccessPathFront apf, Co
|
||||
exists(Content f, AccessPathFront apf0 |
|
||||
flowCandStore(node, f, toReturn, apf0, config) and
|
||||
apf0.headUsesContent(f) and
|
||||
consCand(f, apf, unbind(config))
|
||||
consCand(f, apf, config)
|
||||
)
|
||||
or
|
||||
exists(Content f, AccessPathFront apf0 |
|
||||
flowCandRead(node, f, toReturn, apf0, config) and
|
||||
consCandFwd(f, apf0, unbind(config)) and
|
||||
consCandFwd(f, apf0, config) and
|
||||
apf.headUsesContent(f)
|
||||
)
|
||||
}
|
||||
@@ -1221,8 +1222,8 @@ private newtype TAccessPath =
|
||||
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
|
||||
|
||||
/**
|
||||
* Conceptually a list of `Content`s followed by a `Type`, but only the first
|
||||
* element of the list and its length are tracked. If data flows from a source to
|
||||
* Conceptually a list of `Content`s followed by a `Type`, but only the first two
|
||||
* elements of the list and its length are tracked. If data flows from a source to
|
||||
* a given node with a given `AccessPath`, this indicates the sequence of
|
||||
* dereference operations needed to get from the value in the node to the
|
||||
* tracked object. The final type indicates the type of the tracked object.
|
||||
@@ -1260,7 +1261,7 @@ abstract private class AccessPath extends TAccessPath {
|
||||
|
||||
private class AccessPathNil extends AccessPath, TNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(" : " + ppReprType(t)))
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
@@ -1276,7 +1277,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
override string toString() {
|
||||
exists(Content f, DataFlowType t | this = TConsNil(f, t) |
|
||||
// The `concat` becomes "" if `ppReprType` has no result.
|
||||
result = f.toString() + concat(" : " + ppReprType(t))
|
||||
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1293,8 +1294,8 @@ private class AccessPathConsCons extends AccessPathCons, TConsCons {
|
||||
override string toString() {
|
||||
exists(Content f1, Content f2, int len | this = TConsCons(f1, f2, len) |
|
||||
if len = 2
|
||||
then result = f1.toString() + ", " + f2.toString()
|
||||
else result = f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")"
|
||||
then result = "[" + f1.toString() + ", " + f2.toString() + "]"
|
||||
else result = "[" + f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")]"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1625,7 +1626,7 @@ abstract class PathNode extends TPathNode {
|
||||
this instanceof PathNodeSink and result = ""
|
||||
or
|
||||
exists(string s | s = this.(PathNodeMid).getAp().toString() |
|
||||
if s = "" then result = "" else result = " [" + s + "]"
|
||||
if s = "" then result = "" else result = " " + s
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2070,7 +2071,7 @@ private module FlowExploration {
|
||||
|
||||
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(" : " + ppReprType(t)))
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
@@ -2082,8 +2083,8 @@ private module FlowExploration {
|
||||
override string toString() {
|
||||
exists(Content f, int len | this = TPartialCons(f, len) |
|
||||
if len = 1
|
||||
then result = f.toString()
|
||||
else result = f.toString() + ", ... (" + len.toString() + ")"
|
||||
then result = "[" + f.toString() + "]"
|
||||
else result = "[" + f.toString() + ", ... (" + len.toString() + ")]"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2160,7 +2161,7 @@ private module FlowExploration {
|
||||
|
||||
private string ppAp() {
|
||||
exists(string s | s = this.(PartialPathNodePriv).getAp().toString() |
|
||||
if s = "" then result = "" else result = " [" + s + "]"
|
||||
if s = "" then result = "" else result = " " + s
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* on each other without introducing mutual recursion among those configurations.
|
||||
*/
|
||||
|
||||
private import DataFlowImplCommon
|
||||
private import DataFlowImplCommon::Public
|
||||
private import DataFlowImplSpecific::Private
|
||||
import DataFlowImplSpecific::Public
|
||||
|
||||
@@ -1075,6 +1075,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
|
||||
flowCandFwd(mid, fromArg, _, config) and
|
||||
store(mid, f, node) and
|
||||
nodeCand(node, unbind(config)) and
|
||||
readStoreCand(f, unbind(config)) and
|
||||
apf.headUsesContent(f)
|
||||
)
|
||||
or
|
||||
@@ -1175,12 +1176,12 @@ private predicate flowCand0(Node node, boolean toReturn, AccessPathFront apf, Co
|
||||
exists(Content f, AccessPathFront apf0 |
|
||||
flowCandStore(node, f, toReturn, apf0, config) and
|
||||
apf0.headUsesContent(f) and
|
||||
consCand(f, apf, unbind(config))
|
||||
consCand(f, apf, config)
|
||||
)
|
||||
or
|
||||
exists(Content f, AccessPathFront apf0 |
|
||||
flowCandRead(node, f, toReturn, apf0, config) and
|
||||
consCandFwd(f, apf0, unbind(config)) and
|
||||
consCandFwd(f, apf0, config) and
|
||||
apf.headUsesContent(f)
|
||||
)
|
||||
}
|
||||
@@ -1221,8 +1222,8 @@ private newtype TAccessPath =
|
||||
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
|
||||
|
||||
/**
|
||||
* Conceptually a list of `Content`s followed by a `Type`, but only the first
|
||||
* element of the list and its length are tracked. If data flows from a source to
|
||||
* Conceptually a list of `Content`s followed by a `Type`, but only the first two
|
||||
* elements of the list and its length are tracked. If data flows from a source to
|
||||
* a given node with a given `AccessPath`, this indicates the sequence of
|
||||
* dereference operations needed to get from the value in the node to the
|
||||
* tracked object. The final type indicates the type of the tracked object.
|
||||
@@ -1260,7 +1261,7 @@ abstract private class AccessPath extends TAccessPath {
|
||||
|
||||
private class AccessPathNil extends AccessPath, TNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(" : " + ppReprType(t)))
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
@@ -1276,7 +1277,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
override string toString() {
|
||||
exists(Content f, DataFlowType t | this = TConsNil(f, t) |
|
||||
// The `concat` becomes "" if `ppReprType` has no result.
|
||||
result = f.toString() + concat(" : " + ppReprType(t))
|
||||
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1293,8 +1294,8 @@ private class AccessPathConsCons extends AccessPathCons, TConsCons {
|
||||
override string toString() {
|
||||
exists(Content f1, Content f2, int len | this = TConsCons(f1, f2, len) |
|
||||
if len = 2
|
||||
then result = f1.toString() + ", " + f2.toString()
|
||||
else result = f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")"
|
||||
then result = "[" + f1.toString() + ", " + f2.toString() + "]"
|
||||
else result = "[" + f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")]"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1625,7 +1626,7 @@ abstract class PathNode extends TPathNode {
|
||||
this instanceof PathNodeSink and result = ""
|
||||
or
|
||||
exists(string s | s = this.(PathNodeMid).getAp().toString() |
|
||||
if s = "" then result = "" else result = " [" + s + "]"
|
||||
if s = "" then result = "" else result = " " + s
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2070,7 +2071,7 @@ private module FlowExploration {
|
||||
|
||||
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(" : " + ppReprType(t)))
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
@@ -2082,8 +2083,8 @@ private module FlowExploration {
|
||||
override string toString() {
|
||||
exists(Content f, int len | this = TPartialCons(f, len) |
|
||||
if len = 1
|
||||
then result = f.toString()
|
||||
else result = f.toString() + ", ... (" + len.toString() + ")"
|
||||
then result = "[" + f.toString() + "]"
|
||||
else result = "[" + f.toString() + ", ... (" + len.toString() + ")]"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2160,7 +2161,7 @@ private module FlowExploration {
|
||||
|
||||
private string ppAp() {
|
||||
exists(string s | s = this.(PartialPathNodePriv).getAp().toString() |
|
||||
if s = "" then result = "" else result = " [" + s + "]"
|
||||
if s = "" then result = "" else result = " " + s
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* on each other without introducing mutual recursion among those configurations.
|
||||
*/
|
||||
|
||||
private import DataFlowImplCommon
|
||||
private import DataFlowImplCommon::Public
|
||||
private import DataFlowImplSpecific::Private
|
||||
import DataFlowImplSpecific::Public
|
||||
|
||||
@@ -1075,6 +1075,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
|
||||
flowCandFwd(mid, fromArg, _, config) and
|
||||
store(mid, f, node) and
|
||||
nodeCand(node, unbind(config)) and
|
||||
readStoreCand(f, unbind(config)) and
|
||||
apf.headUsesContent(f)
|
||||
)
|
||||
or
|
||||
@@ -1175,12 +1176,12 @@ private predicate flowCand0(Node node, boolean toReturn, AccessPathFront apf, Co
|
||||
exists(Content f, AccessPathFront apf0 |
|
||||
flowCandStore(node, f, toReturn, apf0, config) and
|
||||
apf0.headUsesContent(f) and
|
||||
consCand(f, apf, unbind(config))
|
||||
consCand(f, apf, config)
|
||||
)
|
||||
or
|
||||
exists(Content f, AccessPathFront apf0 |
|
||||
flowCandRead(node, f, toReturn, apf0, config) and
|
||||
consCandFwd(f, apf0, unbind(config)) and
|
||||
consCandFwd(f, apf0, config) and
|
||||
apf.headUsesContent(f)
|
||||
)
|
||||
}
|
||||
@@ -1221,8 +1222,8 @@ private newtype TAccessPath =
|
||||
TConsCons(Content f1, Content f2, int len) { consCand(f1, TFrontHead(f2), _) and len in [2 .. 5] }
|
||||
|
||||
/**
|
||||
* Conceptually a list of `Content`s followed by a `Type`, but only the first
|
||||
* element of the list and its length are tracked. If data flows from a source to
|
||||
* Conceptually a list of `Content`s followed by a `Type`, but only the first two
|
||||
* elements of the list and its length are tracked. If data flows from a source to
|
||||
* a given node with a given `AccessPath`, this indicates the sequence of
|
||||
* dereference operations needed to get from the value in the node to the
|
||||
* tracked object. The final type indicates the type of the tracked object.
|
||||
@@ -1260,7 +1261,7 @@ abstract private class AccessPath extends TAccessPath {
|
||||
|
||||
private class AccessPathNil extends AccessPath, TNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(" : " + ppReprType(t)))
|
||||
exists(DataFlowType t | this = TNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
@@ -1276,7 +1277,7 @@ private class AccessPathConsNil extends AccessPathCons, TConsNil {
|
||||
override string toString() {
|
||||
exists(Content f, DataFlowType t | this = TConsNil(f, t) |
|
||||
// The `concat` becomes "" if `ppReprType` has no result.
|
||||
result = f.toString() + concat(" : " + ppReprType(t))
|
||||
result = "[" + f.toString() + "]" + concat(" : " + ppReprType(t))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1293,8 +1294,8 @@ private class AccessPathConsCons extends AccessPathCons, TConsCons {
|
||||
override string toString() {
|
||||
exists(Content f1, Content f2, int len | this = TConsCons(f1, f2, len) |
|
||||
if len = 2
|
||||
then result = f1.toString() + ", " + f2.toString()
|
||||
else result = f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")"
|
||||
then result = "[" + f1.toString() + ", " + f2.toString() + "]"
|
||||
else result = "[" + f1.toString() + ", " + f2.toString() + ", ... (" + len.toString() + ")]"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1625,7 +1626,7 @@ abstract class PathNode extends TPathNode {
|
||||
this instanceof PathNodeSink and result = ""
|
||||
or
|
||||
exists(string s | s = this.(PathNodeMid).getAp().toString() |
|
||||
if s = "" then result = "" else result = " [" + s + "]"
|
||||
if s = "" then result = "" else result = " " + s
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2070,7 +2071,7 @@ private module FlowExploration {
|
||||
|
||||
private class PartialAccessPathNil extends PartialAccessPath, TPartialNil {
|
||||
override string toString() {
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(" : " + ppReprType(t)))
|
||||
exists(DataFlowType t | this = TPartialNil(t) | result = concat(": " + ppReprType(t)))
|
||||
}
|
||||
|
||||
override AccessPathFront getFront() {
|
||||
@@ -2082,8 +2083,8 @@ private module FlowExploration {
|
||||
override string toString() {
|
||||
exists(Content f, int len | this = TPartialCons(f, len) |
|
||||
if len = 1
|
||||
then result = f.toString()
|
||||
else result = f.toString() + ", ... (" + len.toString() + ")"
|
||||
then result = "[" + f.toString() + "]"
|
||||
else result = "[" + f.toString() + ", ... (" + len.toString() + ")]"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2160,7 +2161,7 @@ private module FlowExploration {
|
||||
|
||||
private string ppAp() {
|
||||
exists(string s | s = this.(PartialPathNodePriv).getAp().toString() |
|
||||
if s = "" then result = "" else result = " [" + s + "]"
|
||||
if s = "" then result = "" else result = " " + s
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
||||
private import implementations.IdentityFunction
|
||||
private import implementations.Inet
|
||||
private import implementations.Memcpy
|
||||
private import implementations.Memset
|
||||
private import implementations.Printf
|
||||
private import implementations.Pure
|
||||
private import implementations.Strcat
|
||||
|
||||
41
cpp/ql/src/semmle/code/cpp/models/implementations/Memset.qll
Normal file
41
cpp/ql/src/semmle/code/cpp/models/implementations/Memset.qll
Normal file
@@ -0,0 +1,41 @@
|
||||
import semmle.code.cpp.Function
|
||||
import semmle.code.cpp.models.interfaces.ArrayFunction
|
||||
import semmle.code.cpp.models.interfaces.DataFlow
|
||||
import semmle.code.cpp.models.interfaces.Alias
|
||||
|
||||
/**
|
||||
* The standard function `memset` and its assorted variants
|
||||
*/
|
||||
class MemsetFunction extends ArrayFunction, DataFlowFunction, AliasFunction {
|
||||
MemsetFunction() {
|
||||
hasGlobalName("memset") or
|
||||
hasGlobalName("wmemset") or
|
||||
hasGlobalName("bzero") or
|
||||
hasGlobalName("__builtin_memset") or
|
||||
hasGlobalName("__builtin_memset_chk") or
|
||||
hasQualifiedName("std", "memset") or
|
||||
hasQualifiedName("std", "wmemset")
|
||||
}
|
||||
|
||||
override predicate hasArrayOutput(int bufParam) { bufParam = 0 }
|
||||
|
||||
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
|
||||
input.isParameter(0) and
|
||||
output.isReturnValue()
|
||||
}
|
||||
|
||||
override predicate hasArrayWithVariableSize(int bufParam, int countParam) {
|
||||
bufParam = 0 and
|
||||
(if hasGlobalName("bzero") then countParam = 1 else countParam = 2)
|
||||
}
|
||||
|
||||
override predicate parameterNeverEscapes(int index) { hasGlobalName("bzero") and index = 0 }
|
||||
|
||||
override predicate parameterEscapesOnlyViaReturn(int index) {
|
||||
not hasGlobalName("bzero") and index = 0
|
||||
}
|
||||
|
||||
override predicate parameterIsAlwaysReturned(int index) {
|
||||
not hasGlobalName("bzero") and index = 0
|
||||
}
|
||||
}
|
||||
@@ -521,18 +521,21 @@ params(
|
||||
|
||||
overrides(int new: @function ref, int old: @function ref);
|
||||
|
||||
#keyset[id, type_id]
|
||||
membervariables(
|
||||
unique int id: @membervariable,
|
||||
int id: @membervariable,
|
||||
int type_id: @type ref,
|
||||
string name: string ref
|
||||
);
|
||||
|
||||
#keyset[id, type_id]
|
||||
globalvariables(
|
||||
unique int id: @globalvariable,
|
||||
int id: @globalvariable,
|
||||
int type_id: @type ref,
|
||||
string name: string ref
|
||||
);
|
||||
|
||||
#keyset[id, type_id]
|
||||
localvariables(
|
||||
int id: @localvariable,
|
||||
int type_id: @type ref,
|
||||
@@ -1061,10 +1064,12 @@ compgenerated(unique int id: @element ref);
|
||||
* destructed in reverse construction order, so for a given `element`
|
||||
* these should be called from highest to lowest `i`.
|
||||
*/
|
||||
#keyset[element, destructor_call]
|
||||
#keyset[element, i]
|
||||
synthetic_destructor_call(
|
||||
int element: @element ref,
|
||||
int i: int ref,
|
||||
unique int destructor_call: @routineexpr ref
|
||||
int destructor_call: @routineexpr ref
|
||||
);
|
||||
|
||||
namespaces(
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
12
cpp/ql/test/duplication-tests/constants/constants.cpp
Normal file
12
cpp/ql/test/duplication-tests/constants/constants.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
int x = int();
|
||||
float y = float();
|
||||
double z = double();
|
||||
|
||||
/* This produces a getValueText() of 0 for R() in line 9, which is debatable. */
|
||||
struct R {};
|
||||
struct S {
|
||||
S() : S(R()) { }
|
||||
S(R) { }
|
||||
};
|
||||
S s;
|
||||
4
cpp/ql/test/duplication-tests/constants/expr.expected
Normal file
4
cpp/ql/test/duplication-tests/constants/expr.expected
Normal file
@@ -0,0 +1,4 @@
|
||||
| constants.cpp:2:9:2:13 | 0 | int() |
|
||||
| constants.cpp:3:11:3:17 | 0.0 | float() |
|
||||
| constants.cpp:4:12:4:19 | 0.0 | double() |
|
||||
| constants.cpp:9:11:9:13 | 0 | 0 |
|
||||
4
cpp/ql/test/duplication-tests/constants/expr.ql
Normal file
4
cpp/ql/test/duplication-tests/constants/expr.ql
Normal file
@@ -0,0 +1,4 @@
|
||||
import cpp
|
||||
|
||||
from Expr e
|
||||
select e, e.getValueText()
|
||||
@@ -235,3 +235,92 @@
|
||||
| taint.cpp:258:7:258:12 | call to source | taint.cpp:255:35:255:35 | c | |
|
||||
| taint.cpp:258:7:258:12 | call to source | taint.cpp:258:3:258:14 | ... = ... | |
|
||||
| taint.cpp:260:10:260:10 | ref arg w | taint.cpp:261:7:261:7 | w | |
|
||||
| taint.cpp:266:12:266:12 | x | taint.cpp:268:9:268:9 | x | |
|
||||
| taint.cpp:275:6:275:11 | call to source | taint.cpp:275:2:275:13 | ... = ... | |
|
||||
| taint.cpp:275:6:275:11 | call to source | taint.cpp:280:7:280:7 | t | |
|
||||
| taint.cpp:275:6:275:11 | call to source | taint.cpp:285:9:285:9 | t | |
|
||||
| taint.cpp:275:6:275:11 | call to source | taint.cpp:286:12:286:12 | t | |
|
||||
| taint.cpp:275:6:275:11 | call to source | taint.cpp:289:7:289:7 | t | |
|
||||
| taint.cpp:276:6:276:6 | 0 | taint.cpp:276:2:276:6 | ... = ... | |
|
||||
| taint.cpp:276:6:276:6 | 0 | taint.cpp:281:7:281:7 | x | |
|
||||
| taint.cpp:277:6:277:6 | 0 | taint.cpp:277:2:277:6 | ... = ... | |
|
||||
| taint.cpp:277:6:277:6 | 0 | taint.cpp:282:7:282:7 | y | |
|
||||
| taint.cpp:278:6:278:6 | 0 | taint.cpp:278:2:278:6 | ... = ... | |
|
||||
| taint.cpp:278:6:278:6 | 0 | taint.cpp:283:7:283:7 | z | |
|
||||
| taint.cpp:278:6:278:6 | 0 | taint.cpp:287:9:287:9 | z | |
|
||||
| taint.cpp:285:6:285:7 | call to id | taint.cpp:285:2:285:10 | ... = ... | |
|
||||
| taint.cpp:285:6:285:7 | call to id | taint.cpp:290:7:290:7 | x | |
|
||||
| taint.cpp:286:6:286:7 | call to id | taint.cpp:286:2:286:14 | ... = ... | |
|
||||
| taint.cpp:286:6:286:7 | call to id | taint.cpp:291:7:291:7 | y | |
|
||||
| taint.cpp:287:6:287:7 | call to id | taint.cpp:287:2:287:10 | ... = ... | |
|
||||
| taint.cpp:287:6:287:7 | call to id | taint.cpp:292:7:292:7 | z | |
|
||||
| taint.cpp:297:29:297:29 | b | taint.cpp:297:29:297:29 | b | |
|
||||
| taint.cpp:297:29:297:29 | b | taint.cpp:299:6:299:6 | b | |
|
||||
| taint.cpp:299:6:299:6 | b | taint.cpp:297:21:297:21 | a | |
|
||||
| taint.cpp:299:6:299:6 | b | taint.cpp:299:2:299:6 | ... = ... | |
|
||||
| taint.cpp:302:28:302:28 | b | taint.cpp:304:6:304:6 | b | |
|
||||
| taint.cpp:304:6:304:6 | b | taint.cpp:302:21:302:21 | a | |
|
||||
| taint.cpp:304:6:304:6 | b | taint.cpp:304:2:304:6 | ... = ... | |
|
||||
| taint.cpp:307:21:307:21 | a | taint.cpp:309:3:309:3 | a | |
|
||||
| taint.cpp:307:28:307:28 | b | taint.cpp:309:7:309:7 | b | |
|
||||
| taint.cpp:309:3:309:3 | a | taint.cpp:309:2:309:3 | * ... | TAINT |
|
||||
| taint.cpp:309:7:309:7 | b | taint.cpp:309:2:309:7 | ... = ... | |
|
||||
| taint.cpp:312:21:312:21 | a | taint.cpp:317:3:317:3 | a | |
|
||||
| taint.cpp:312:28:312:28 | b | taint.cpp:316:6:316:6 | b | |
|
||||
| taint.cpp:316:6:316:6 | b | taint.cpp:316:6:316:10 | ... + ... | TAINT |
|
||||
| taint.cpp:316:6:316:10 | ... + ... | taint.cpp:316:2:316:10 | ... = ... | |
|
||||
| taint.cpp:316:6:316:10 | ... + ... | taint.cpp:317:7:317:7 | c | |
|
||||
| taint.cpp:316:10:316:10 | 1 | taint.cpp:316:6:316:10 | ... + ... | TAINT |
|
||||
| taint.cpp:317:3:317:3 | a | taint.cpp:317:2:317:3 | * ... | TAINT |
|
||||
| taint.cpp:317:7:317:7 | c | taint.cpp:317:2:317:7 | ... = ... | |
|
||||
| taint.cpp:320:23:320:23 | a | taint.cpp:322:6:322:6 | a | |
|
||||
| taint.cpp:320:31:320:31 | b | taint.cpp:323:6:323:6 | b | |
|
||||
| taint.cpp:322:6:322:6 | a | taint.cpp:322:6:322:10 | ... + ... | TAINT |
|
||||
| taint.cpp:322:6:322:10 | ... + ... | taint.cpp:320:23:320:23 | a | |
|
||||
| taint.cpp:322:6:322:10 | ... + ... | taint.cpp:322:2:322:10 | ... = ... | |
|
||||
| taint.cpp:322:10:322:10 | 1 | taint.cpp:322:6:322:10 | ... + ... | TAINT |
|
||||
| taint.cpp:323:6:323:6 | b | taint.cpp:323:6:323:10 | ... + ... | TAINT |
|
||||
| taint.cpp:323:6:323:10 | ... + ... | taint.cpp:320:31:320:31 | b | |
|
||||
| taint.cpp:323:6:323:10 | ... + ... | taint.cpp:323:2:323:10 | ... = ... | |
|
||||
| taint.cpp:323:10:323:10 | 1 | taint.cpp:323:6:323:10 | ... + ... | TAINT |
|
||||
| taint.cpp:330:6:330:11 | call to source | taint.cpp:330:2:330:13 | ... = ... | |
|
||||
| taint.cpp:330:6:330:11 | call to source | taint.cpp:337:7:337:7 | t | |
|
||||
| taint.cpp:330:6:330:11 | call to source | taint.cpp:344:15:344:15 | t | |
|
||||
| taint.cpp:330:6:330:11 | call to source | taint.cpp:345:15:345:15 | t | |
|
||||
| taint.cpp:330:6:330:11 | call to source | taint.cpp:346:16:346:16 | t | |
|
||||
| taint.cpp:330:6:330:11 | call to source | taint.cpp:347:16:347:16 | t | |
|
||||
| taint.cpp:330:6:330:11 | call to source | taint.cpp:348:17:348:17 | t | |
|
||||
| taint.cpp:330:6:330:11 | call to source | taint.cpp:350:7:350:7 | t | |
|
||||
| taint.cpp:331:6:331:6 | 0 | taint.cpp:331:2:331:6 | ... = ... | |
|
||||
| taint.cpp:331:6:331:6 | 0 | taint.cpp:338:7:338:7 | a | |
|
||||
| taint.cpp:331:6:331:6 | 0 | taint.cpp:344:12:344:12 | a | |
|
||||
| taint.cpp:331:6:331:6 | 0 | taint.cpp:351:7:351:7 | a | |
|
||||
| taint.cpp:332:6:332:6 | 0 | taint.cpp:332:2:332:6 | ... = ... | |
|
||||
| taint.cpp:332:6:332:6 | 0 | taint.cpp:339:7:339:7 | b | |
|
||||
| taint.cpp:332:6:332:6 | 0 | taint.cpp:345:12:345:12 | b | |
|
||||
| taint.cpp:332:6:332:6 | 0 | taint.cpp:352:7:352:7 | b | |
|
||||
| taint.cpp:333:6:333:6 | 0 | taint.cpp:333:2:333:6 | ... = ... | |
|
||||
| taint.cpp:333:6:333:6 | 0 | taint.cpp:340:7:340:7 | c | |
|
||||
| taint.cpp:333:6:333:6 | 0 | taint.cpp:346:13:346:13 | c | |
|
||||
| taint.cpp:333:6:333:6 | 0 | taint.cpp:353:7:353:7 | c | |
|
||||
| taint.cpp:334:6:334:6 | 0 | taint.cpp:334:2:334:6 | ... = ... | |
|
||||
| taint.cpp:334:6:334:6 | 0 | taint.cpp:341:7:341:7 | d | |
|
||||
| taint.cpp:334:6:334:6 | 0 | taint.cpp:347:13:347:13 | d | |
|
||||
| taint.cpp:334:6:334:6 | 0 | taint.cpp:354:7:354:7 | d | |
|
||||
| taint.cpp:335:6:335:6 | 0 | taint.cpp:335:2:335:6 | ... = ... | |
|
||||
| taint.cpp:335:6:335:6 | 0 | taint.cpp:342:7:342:7 | e | |
|
||||
| taint.cpp:335:6:335:6 | 0 | taint.cpp:348:14:348:14 | e | |
|
||||
| taint.cpp:335:6:335:6 | 0 | taint.cpp:355:7:355:7 | e | |
|
||||
| taint.cpp:344:12:344:12 | ref arg a | taint.cpp:351:7:351:7 | a | |
|
||||
| taint.cpp:344:15:344:15 | ref arg t | taint.cpp:345:15:345:15 | t | |
|
||||
| taint.cpp:344:15:344:15 | ref arg t | taint.cpp:346:16:346:16 | t | |
|
||||
| taint.cpp:344:15:344:15 | ref arg t | taint.cpp:347:16:347:16 | t | |
|
||||
| taint.cpp:344:15:344:15 | ref arg t | taint.cpp:348:17:348:17 | t | |
|
||||
| taint.cpp:344:15:344:15 | ref arg t | taint.cpp:350:7:350:7 | t | |
|
||||
| taint.cpp:345:12:345:12 | ref arg b | taint.cpp:352:7:352:7 | b | |
|
||||
| taint.cpp:346:12:346:13 | ref arg & ... | taint.cpp:353:7:353:7 | c | |
|
||||
| taint.cpp:346:13:346:13 | c | taint.cpp:346:12:346:13 | & ... | |
|
||||
| taint.cpp:347:12:347:13 | ref arg & ... | taint.cpp:354:7:354:7 | d | |
|
||||
| taint.cpp:347:13:347:13 | d | taint.cpp:347:12:347:13 | & ... | |
|
||||
| taint.cpp:348:14:348:14 | ref arg e | taint.cpp:355:7:355:7 | e | |
|
||||
| taint.cpp:348:17:348:17 | ref arg t | taint.cpp:350:7:350:7 | t | |
|
||||
|
||||
@@ -260,3 +260,97 @@ void test_lambdas()
|
||||
e(t, u, w);
|
||||
sink(w); // tainted
|
||||
}
|
||||
|
||||
// --- taint through return value ---
|
||||
|
||||
int id(int x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
void test_return()
|
||||
{
|
||||
int x, y, z, t;
|
||||
|
||||
t = source();
|
||||
x = 0;
|
||||
y = 0;
|
||||
z = 0;
|
||||
|
||||
sink(t); // tainted
|
||||
sink(x);
|
||||
sink(y);
|
||||
sink(z);
|
||||
|
||||
x = id(t);
|
||||
y = id(id(t));
|
||||
z = id(z);
|
||||
|
||||
sink(t); // tainted
|
||||
sink(x); // tainted
|
||||
sink(y); // tainted
|
||||
sink(z);
|
||||
}
|
||||
|
||||
// --- taint through parameters ---
|
||||
|
||||
void myAssign1(int &a, int &b)
|
||||
{
|
||||
a = b;
|
||||
}
|
||||
|
||||
void myAssign2(int &a, int b)
|
||||
{
|
||||
a = b;
|
||||
}
|
||||
|
||||
void myAssign3(int *a, int b)
|
||||
{
|
||||
*a = b;
|
||||
}
|
||||
|
||||
void myAssign4(int *a, int b)
|
||||
{
|
||||
int c;
|
||||
|
||||
c = b + 1;
|
||||
*a = c;
|
||||
}
|
||||
|
||||
void myNotAssign(int &a, int &b)
|
||||
{
|
||||
a = a + 1;
|
||||
b = b + 1;
|
||||
}
|
||||
|
||||
void test_outparams()
|
||||
{
|
||||
int t, a, b, c, d, e;
|
||||
|
||||
t = source();
|
||||
a = 0;
|
||||
b = 0;
|
||||
c = 0;
|
||||
d = 0;
|
||||
e = 0;
|
||||
|
||||
sink(t); // tainted
|
||||
sink(a);
|
||||
sink(b);
|
||||
sink(c);
|
||||
sink(d);
|
||||
sink(e);
|
||||
|
||||
myAssign1(a, t);
|
||||
myAssign2(b, t);
|
||||
myAssign3(&c, t);
|
||||
myAssign4(&d, t);
|
||||
myNotAssign(e, t);
|
||||
|
||||
sink(t); // tainted
|
||||
sink(a); // tainted
|
||||
sink(b); // tainted
|
||||
sink(c); // tainted [NOT DETECTED]
|
||||
sink(d); // tainted [NOT DETECTED]
|
||||
sink(e);
|
||||
}
|
||||
|
||||
@@ -29,3 +29,11 @@
|
||||
| taint.cpp:250:8:250:8 | a | taint.cpp:223:10:223:15 | call to source |
|
||||
| taint.cpp:256:8:256:8 | a | taint.cpp:223:10:223:15 | call to source |
|
||||
| taint.cpp:261:7:261:7 | w | taint.cpp:258:7:258:12 | call to source |
|
||||
| taint.cpp:280:7:280:7 | t | taint.cpp:275:6:275:11 | call to source |
|
||||
| taint.cpp:289:7:289:7 | t | taint.cpp:275:6:275:11 | call to source |
|
||||
| taint.cpp:290:7:290:7 | x | taint.cpp:275:6:275:11 | call to source |
|
||||
| taint.cpp:291:7:291:7 | y | taint.cpp:275:6:275:11 | call to source |
|
||||
| taint.cpp:337:7:337:7 | t | taint.cpp:330:6:330:11 | call to source |
|
||||
| taint.cpp:350:7:350:7 | t | taint.cpp:330:6:330:11 | call to source |
|
||||
| taint.cpp:351:7:351:7 | a | taint.cpp:330:6:330:11 | call to source |
|
||||
| taint.cpp:352:7:352:7 | b | taint.cpp:330:6:330:11 | call to source |
|
||||
|
||||
@@ -22,3 +22,6 @@
|
||||
| taint.cpp:250:8:250:8 | taint.cpp:223:10:223:15 | AST only |
|
||||
| taint.cpp:256:8:256:8 | taint.cpp:223:10:223:15 | AST only |
|
||||
| taint.cpp:261:7:261:7 | taint.cpp:258:7:258:12 | AST only |
|
||||
| taint.cpp:350:7:350:7 | taint.cpp:330:6:330:11 | AST only |
|
||||
| taint.cpp:351:7:351:7 | taint.cpp:330:6:330:11 | AST only |
|
||||
| taint.cpp:352:7:352:7 | taint.cpp:330:6:330:11 | AST only |
|
||||
|
||||
@@ -9,3 +9,8 @@
|
||||
| taint.cpp:167:8:167:13 | Call: call to source | taint.cpp:167:8:167:13 | Call: call to source |
|
||||
| taint.cpp:168:8:168:14 | Load: tainted | taint.cpp:164:19:164:24 | Call: call to source |
|
||||
| taint.cpp:210:7:210:7 | Load: x | taint.cpp:207:6:207:11 | Call: call to source |
|
||||
| taint.cpp:280:7:280:7 | Load: t | taint.cpp:275:6:275:11 | Call: call to source |
|
||||
| taint.cpp:289:7:289:7 | Load: t | taint.cpp:275:6:275:11 | Call: call to source |
|
||||
| taint.cpp:290:7:290:7 | Load: x | taint.cpp:275:6:275:11 | Call: call to source |
|
||||
| taint.cpp:291:7:291:7 | Load: y | taint.cpp:275:6:275:11 | Call: call to source |
|
||||
| taint.cpp:337:7:337:7 | Load: t | taint.cpp:330:6:330:11 | Call: call to source |
|
||||
|
||||
Reference in New Issue
Block a user