Merge commit '52d8acc1a198c5ea29c1dddceda1d6c0fb75de14' into dataflow-defbyref-to-field

This is a partial merge from master. In particular, it takes in #3382
and #3385.
This commit is contained in:
Jonas Jensen
2020-05-07 16:46:11 +02:00
71 changed files with 1816 additions and 1119 deletions

View File

@@ -1,8 +1,8 @@
/cpp/ @Semmle/cpp-analysis
/csharp/ @Semmle/cs
/java/ @Semmle/java
/javascript/ @Semmle/js
/python/ @Semmle/python
/cpp/ @github/codeql-c-analysis
/csharp/ @github/codeql-csharp
/java/ @github/codeql-java
/javascript/ @github/codeql-javascript
/python/ @github/codeql-python
/cpp/**/*.qhelp @hubwriter
/csharp/**/*.qhelp @jf205
/java/**/*.qhelp @felicitymay

View File

@@ -21,7 +21,7 @@ where
destBase = baseType(destType) and
destBase.getSize() != sourceBase.getSize() and
not dest.isInMacroExpansion() and
// If the source type is a char* or void* then don't
// If the source type is a `char*` or `void*` then don't
// produce a result, because it is likely to be a false
// positive.
not sourceBase instanceof CharType and

View File

@@ -21,7 +21,7 @@ where
destBase = baseType(destType) and
destBase.getSize() != sourceBase.getSize() and
not dest.isInMacroExpansion() and
// If the source type is a char* or void* then don't
// If the source type is a `char*` or `void*` then don't
// produce a result, because it is likely to be a false
// positive.
not sourceBase instanceof CharType and

View File

@@ -24,7 +24,7 @@ private predicate isCharSzPtrExpr(Expr e) {
from Expr sizeofExpr, Expr e
where
// If we see an addWithSizeof then we expect the type of
// the pointer expression to be char* or void*. Otherwise it
// the pointer expression to be `char*` or `void*`. Otherwise it
// is probably a mistake.
addWithSizeof(e, sizeofExpr, _) and not isCharSzPtrExpr(e)
select sizeofExpr,

View File

@@ -103,6 +103,9 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
/**
* Holds if this function is declared to be `constexpr`.
*
* Note that this does not hold if the function has been declared
* `consteval`.
*/
predicate isDeclaredConstexpr() { this.hasSpecifier("declared_constexpr") }
@@ -115,9 +118,16 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* template <typename T> constexpr int g(T x) { return f(x); }
* ```
* `g<int>` is declared constexpr, but is not constexpr.
*
* Will also hold if this function is `consteval`.
*/
predicate isConstexpr() { this.hasSpecifier("is_constexpr") }
/**
* Holds if this function is declared to be `consteval`.
*/
predicate isConsteval() { this.hasSpecifier("is_consteval") }
/**
* Holds if this function is declared with `__attribute__((naked))` or
* `__declspec(naked)`.

View File

@@ -92,13 +92,7 @@ int getBufferSize(Expr bufferExpr, Element why) {
// dataflow (all sources must be the same size)
bufferExprNode = DataFlow::exprNode(bufferExpr) and
result =
min(Expr def |
DataFlow::localFlowStep(DataFlow::exprNode(def), bufferExprNode)
|
getBufferSize(def, _)
) and
result =
max(Expr def |
unique(Expr def |
DataFlow::localFlowStep(DataFlow::exprNode(def), bufferExprNode)
|
getBufferSize(def, _)

View File

@@ -532,13 +532,7 @@ library class ExprEvaluator extends int {
interestingVariableAccess(e, va, v, true) and
// All assignments must have the same int value
result =
min(Expr value |
value = v.getAnAssignedValue() and not ignoreVariableAssignment(e, v, value)
|
getValueInternalNonSubExpr(value)
) and
result =
max(Expr value |
unique(Expr value |
value = v.getAnAssignedValue() and not ignoreVariableAssignment(e, v, value)
|
getValueInternalNonSubExpr(value)

View File

@@ -183,11 +183,14 @@ private predicate referenceFromVariableAccess(VariableAccess va, Expr reference)
)
}
private predicate valueMayEscapeAt(Expr e) {
private predicate addressMayEscapeAt(Expr e) {
exists(Call call |
e = call.getAnArgument().getFullyConverted() and
not stdIdentityFunction(call.getTarget()) and
not stdAddressOf(call.getTarget())
or
e = call.getQualifier().getFullyConverted() and
e.getUnderlyingType() instanceof PointerType
)
or
exists(AssignExpr assign | e = assign.getRValue().getFullyConverted())
@@ -205,8 +208,8 @@ private predicate valueMayEscapeAt(Expr e) {
exists(AsmStmt asm | e = asm.getAChild().(Expr).getFullyConverted())
}
private predicate valueMayEscapeMutablyAt(Expr e) {
valueMayEscapeAt(e) and
private predicate addressMayEscapeMutablyAt(Expr e) {
addressMayEscapeAt(e) and
exists(Type t | t = e.getType().getUnderlyingType() |
exists(PointerType pt |
pt = t
@@ -225,6 +228,22 @@ private predicate valueMayEscapeMutablyAt(Expr e) {
)
}
private predicate lvalueMayEscapeAt(Expr e) {
// A call qualifier, like `q` in `q.f()`, is special in that the address of
// `q` escapes even though `q` is not a pointer or a reference.
exists(Call call |
e = call.getQualifier().getFullyConverted() and
e.getType().getUnspecifiedType() instanceof Class
)
}
private predicate lvalueMayEscapeMutablyAt(Expr e) {
lvalueMayEscapeAt(e) and
// A qualifier of a call to a const member function is converted to a const
// class type.
not e.getType().isConst()
}
private predicate addressFromVariableAccess(VariableAccess va, Expr e) {
pointerFromVariableAccess(va, e)
or
@@ -271,8 +290,11 @@ private module EscapesTree_Cached {
*/
cached
predicate variableAddressEscapesTree(VariableAccess va, Expr e) {
valueMayEscapeAt(e) and
addressMayEscapeAt(e) and
addressFromVariableAccess(va, e)
or
lvalueMayEscapeAt(e) and
lvalueFromVariableAccess(va, e)
}
/**
@@ -301,8 +323,11 @@ private module EscapesTree_Cached {
*/
cached
predicate variableAddressEscapesTreeNonConst(VariableAccess va, Expr e) {
valueMayEscapeMutablyAt(e) and
addressMayEscapeMutablyAt(e) and
addressFromVariableAccess(va, e)
or
lvalueMayEscapeMutablyAt(e) and
lvalueFromVariableAccess(va, e)
}
/**

View File

@@ -505,8 +505,6 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
// Expr -> Expr
exprToExprStep_nocfg(nodeFrom.asExpr(), nodeTo.asExpr())
or
exprToExprStep_nocfg(nodeFrom.(PostUpdateNode).getPreUpdateNode().asExpr(), nodeTo.asExpr())
or
// Node -> FlowVar -> VariableAccess
exists(FlowVar var |
(
@@ -674,7 +672,7 @@ private module FieldFlow {
exists(FieldConfiguration cfg | cfg.hasFlow(node1, node2)) and
// This configuration should not be able to cross function boundaries, but
// we double-check here just to be sure.
node1.getFunction() = node2.getFunction()
node1.getEnclosingCallable() = node2.getEnclosingCallable()
}
}

View File

@@ -9,9 +9,8 @@ private import semmle.code.cpp.dataflow.EscapesTree
*/
abstract class Call extends Expr, NameQualifiableElement {
/**
* Gets the number of actual parameters in this call; use
* `getArgument(i)` with `i` between `0` and `result - 1` to
* retrieve actuals.
* Gets the number of arguments (actual parameters) of this call. The count
* does _not_ include the qualifier of the call, if any.
*/
int getNumberOfArguments() { result = count(this.getAnArgument()) }
@@ -32,21 +31,24 @@ abstract class Call extends Expr, NameQualifiableElement {
Expr getQualifier() { result = this.getChild(-1) }
/**
* Gets an argument for this call.
* Gets an argument for this call. To get the qualifier of this call, if
* any, use `getQualifier()`.
*/
Expr getAnArgument() { exists(int i | result = this.getChild(i) and i >= 0) }
/**
* Gets the nth argument for this call.
*
* The range of `n` is from `0` to `getNumberOfArguments() - 1`.
* The range of `n` is from `0` to `getNumberOfArguments() - 1`. To get the
* qualifier of this call, if any, use `getQualifier()`.
*/
Expr getArgument(int n) { result = this.getChild(n) and n >= 0 }
/**
* Gets a sub expression of the argument at position `index`. If the
* Gets a subexpression of the argument at position `index`. If the
* argument itself contains calls, such calls will be considered
* leafs in the expression tree.
* leaves in the expression tree. The qualifier of the call, if any, is not
* considered to be an argument.
*
* Example: the call `f(2, 3 + 4, g(4 + 5))` has sub expression(s)
* `2` at index 0; `3`, `4`, and `3 + 4` at index 1; and `g(4 + 5)`

View File

@@ -101,23 +101,24 @@ class IRBlock extends IRBlockBase {
private predicate startsBasicBlock(Instruction instr) {
not instr instanceof PhiInstruction and
(
count(Instruction predecessor | instr = predecessor.getASuccessor()) != 1 // Multiple predecessors or no predecessor
or
exists(Instruction predecessor |
instr = predecessor.getASuccessor() and
strictcount(Instruction other | other = predecessor.getASuccessor()) > 1
) // Predecessor has multiple successors
or
exists(Instruction predecessor, EdgeKind kind |
instr = predecessor.getSuccessor(kind) and
not kind instanceof GotoEdge
) // Incoming edge is not a GotoEdge
or
exists(Instruction predecessor |
instr = Construction::getInstructionBackEdgeSuccessor(predecessor, _)
) // A back edge enters this instruction
)
not adjacentInBlock(_, instr)
}
/** Holds if `i2` follows `i1` in a `IRBlock`. */
private predicate adjacentInBlock(Instruction i1, Instruction i2) {
// - i2 must be the only successor of i1
i2 = unique(Instruction i | i = i1.getASuccessor()) and
// - i1 must be the only predecessor of i2
i1 = unique(Instruction i | i.getASuccessor() = i2) and
// - The edge between the two must be a GotoEdge. We just check that one
// exists since we've already checked that it's unique.
exists(GotoEdge edgeKind | exists(i1.getSuccessor(edgeKind))) and
// - The edge must not be a back edge. This means we get the same back edges
// in the basic-block graph as we do in the raw CFG.
not exists(Construction::getInstructionBackEdgeSuccessor(i1, _))
// This predicate could be simplified to remove one of the `unique`s if we
// were willing to rely on the CFG being well-formed and thus never having
// more than one successor to an instruction that has a `GotoEdge` out of it.
}
private predicate isEntryBlock(TIRBlock block) {
@@ -129,12 +130,6 @@ private module Cached {
cached
newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) }
/** Holds if `i2` follows `i1` in a `IRBlock`. */
private predicate adjacentInBlock(Instruction i1, Instruction i2) {
exists(GotoEdge edgeKind | i2 = i1.getSuccessor(edgeKind)) and
not startsBasicBlock(i2)
}
/** Holds if `i` is the `index`th instruction the block starting with `first`. */
private Instruction getInstructionFromFirst(Instruction first, int index) =
shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index)

View File

@@ -190,14 +190,15 @@ class Instruction extends Construction::TInstruction {
final Language::Location getLocation() { result = getAST().getLocation() }
/**
* Gets the `Expr` whose result is computed by this instruction, if any.
* Gets the `Expr` whose result is computed by this instruction, if any. The `Expr` may be a
* conversion.
*/
final Language::Expr getConvertedResultExpression() {
result = Construction::getInstructionConvertedResultExpression(this)
}
/**
* Gets the unconverted `Expr` whose result is computed by this instruction, if any.
* Gets the unconverted form of the `Expr` whose result is computed by this instruction, if any.
*/
final Language::Expr getUnconvertedResultExpression() {
result = Construction::getInstructionUnconvertedResultExpression(this)

View File

@@ -14,8 +14,7 @@ int getConstantValue(Instruction instr) {
or
exists(PhiInstruction phi |
phi = instr and
result = max(Operand op | op = phi.getAnInputOperand() | getConstantValue(op.getDef())) and
result = min(Operand op | op = phi.getAnInputOperand() | getConstantValue(op.getDef()))
result = unique(Operand op | op = phi.getAnInputOperand() | getConstantValue(op.getDef()))
)
}

View File

@@ -101,23 +101,24 @@ class IRBlock extends IRBlockBase {
private predicate startsBasicBlock(Instruction instr) {
not instr instanceof PhiInstruction and
(
count(Instruction predecessor | instr = predecessor.getASuccessor()) != 1 // Multiple predecessors or no predecessor
or
exists(Instruction predecessor |
instr = predecessor.getASuccessor() and
strictcount(Instruction other | other = predecessor.getASuccessor()) > 1
) // Predecessor has multiple successors
or
exists(Instruction predecessor, EdgeKind kind |
instr = predecessor.getSuccessor(kind) and
not kind instanceof GotoEdge
) // Incoming edge is not a GotoEdge
or
exists(Instruction predecessor |
instr = Construction::getInstructionBackEdgeSuccessor(predecessor, _)
) // A back edge enters this instruction
)
not adjacentInBlock(_, instr)
}
/** Holds if `i2` follows `i1` in a `IRBlock`. */
private predicate adjacentInBlock(Instruction i1, Instruction i2) {
// - i2 must be the only successor of i1
i2 = unique(Instruction i | i = i1.getASuccessor()) and
// - i1 must be the only predecessor of i2
i1 = unique(Instruction i | i.getASuccessor() = i2) and
// - The edge between the two must be a GotoEdge. We just check that one
// exists since we've already checked that it's unique.
exists(GotoEdge edgeKind | exists(i1.getSuccessor(edgeKind))) and
// - The edge must not be a back edge. This means we get the same back edges
// in the basic-block graph as we do in the raw CFG.
not exists(Construction::getInstructionBackEdgeSuccessor(i1, _))
// This predicate could be simplified to remove one of the `unique`s if we
// were willing to rely on the CFG being well-formed and thus never having
// more than one successor to an instruction that has a `GotoEdge` out of it.
}
private predicate isEntryBlock(TIRBlock block) {
@@ -129,12 +130,6 @@ private module Cached {
cached
newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) }
/** Holds if `i2` follows `i1` in a `IRBlock`. */
private predicate adjacentInBlock(Instruction i1, Instruction i2) {
exists(GotoEdge edgeKind | i2 = i1.getSuccessor(edgeKind)) and
not startsBasicBlock(i2)
}
/** Holds if `i` is the `index`th instruction the block starting with `first`. */
private Instruction getInstructionFromFirst(Instruction first, int index) =
shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index)

View File

@@ -190,14 +190,15 @@ class Instruction extends Construction::TInstruction {
final Language::Location getLocation() { result = getAST().getLocation() }
/**
* Gets the `Expr` whose result is computed by this instruction, if any.
* Gets the `Expr` whose result is computed by this instruction, if any. The `Expr` may be a
* conversion.
*/
final Language::Expr getConvertedResultExpression() {
result = Construction::getInstructionConvertedResultExpression(this)
}
/**
* Gets the unconverted `Expr` whose result is computed by this instruction, if any.
* Gets the unconverted form of the `Expr` whose result is computed by this instruction, if any.
*/
final Language::Expr getUnconvertedResultExpression() {
result = Construction::getInstructionUnconvertedResultExpression(this)

View File

@@ -14,8 +14,7 @@ int getConstantValue(Instruction instr) {
or
exists(PhiInstruction phi |
phi = instr and
result = max(Operand op | op = phi.getAnInputOperand() | getConstantValue(op.getDef())) and
result = min(Operand op | op = phi.getAnInputOperand() | getConstantValue(op.getDef()))
result = unique(Operand op | op = phi.getAnInputOperand() | getConstantValue(op.getDef()))
)
}

View File

@@ -101,23 +101,24 @@ class IRBlock extends IRBlockBase {
private predicate startsBasicBlock(Instruction instr) {
not instr instanceof PhiInstruction and
(
count(Instruction predecessor | instr = predecessor.getASuccessor()) != 1 // Multiple predecessors or no predecessor
or
exists(Instruction predecessor |
instr = predecessor.getASuccessor() and
strictcount(Instruction other | other = predecessor.getASuccessor()) > 1
) // Predecessor has multiple successors
or
exists(Instruction predecessor, EdgeKind kind |
instr = predecessor.getSuccessor(kind) and
not kind instanceof GotoEdge
) // Incoming edge is not a GotoEdge
or
exists(Instruction predecessor |
instr = Construction::getInstructionBackEdgeSuccessor(predecessor, _)
) // A back edge enters this instruction
)
not adjacentInBlock(_, instr)
}
/** Holds if `i2` follows `i1` in a `IRBlock`. */
private predicate adjacentInBlock(Instruction i1, Instruction i2) {
// - i2 must be the only successor of i1
i2 = unique(Instruction i | i = i1.getASuccessor()) and
// - i1 must be the only predecessor of i2
i1 = unique(Instruction i | i.getASuccessor() = i2) and
// - The edge between the two must be a GotoEdge. We just check that one
// exists since we've already checked that it's unique.
exists(GotoEdge edgeKind | exists(i1.getSuccessor(edgeKind))) and
// - The edge must not be a back edge. This means we get the same back edges
// in the basic-block graph as we do in the raw CFG.
not exists(Construction::getInstructionBackEdgeSuccessor(i1, _))
// This predicate could be simplified to remove one of the `unique`s if we
// were willing to rely on the CFG being well-formed and thus never having
// more than one successor to an instruction that has a `GotoEdge` out of it.
}
private predicate isEntryBlock(TIRBlock block) {
@@ -129,12 +130,6 @@ private module Cached {
cached
newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) }
/** Holds if `i2` follows `i1` in a `IRBlock`. */
private predicate adjacentInBlock(Instruction i1, Instruction i2) {
exists(GotoEdge edgeKind | i2 = i1.getSuccessor(edgeKind)) and
not startsBasicBlock(i2)
}
/** Holds if `i` is the `index`th instruction the block starting with `first`. */
private Instruction getInstructionFromFirst(Instruction first, int index) =
shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index)

View File

@@ -190,14 +190,15 @@ class Instruction extends Construction::TInstruction {
final Language::Location getLocation() { result = getAST().getLocation() }
/**
* Gets the `Expr` whose result is computed by this instruction, if any.
* Gets the `Expr` whose result is computed by this instruction, if any. The `Expr` may be a
* conversion.
*/
final Language::Expr getConvertedResultExpression() {
result = Construction::getInstructionConvertedResultExpression(this)
}
/**
* Gets the unconverted `Expr` whose result is computed by this instruction, if any.
* Gets the unconverted form of the `Expr` whose result is computed by this instruction, if any.
*/
final Language::Expr getUnconvertedResultExpression() {
result = Construction::getInstructionUnconvertedResultExpression(this)

View File

@@ -14,8 +14,7 @@ int getConstantValue(Instruction instr) {
or
exists(PhiInstruction phi |
phi = instr and
result = max(Operand op | op = phi.getAnInputOperand() | getConstantValue(op.getDef())) and
result = min(Operand op | op = phi.getAnInputOperand() | getConstantValue(op.getDef()))
result = unique(Operand op | op = phi.getAnInputOperand() | getConstantValue(op.getDef()))
)
}

View File

@@ -271,33 +271,32 @@ class OperatorNewAllocationFunction extends AllocationFunction {
}
/**
* The predicate analyzes a `sizeExpr`, which is an argument to an allocation
* function like malloc, and tries to split it into an expression `lengthExpr`
* that describes the length of the allocated array, and the size of the allocated
* element type `sizeof`.
* If this is not possible, the allocation is considered to be of size 1 and of
* length `sizeExpr`.
* Holds if `sizeExpr` is an expression consisting of a subexpression
* `lengthExpr` multiplied by a constant `sizeof` that is the result of a
* `sizeof()` expression. Alternatively if there isn't a suitable `sizeof()`
* expression, `lengthExpr = sizeExpr` and `sizeof = 1`. For example:
* ```
* malloc(a * 2 * sizeof(char32_t));
* ```
* In this case if the `sizeExpr` is the argument to `malloc`, the `lengthExpr`
* is `a * 2` and `sizeof` is `4`.
*/
private predicate deconstructSizeExpr(Expr sizeExpr, Expr lengthExpr, int sizeof) {
if
sizeExpr instanceof MulExpr and
exists(SizeofOperator sizeofOp, Expr lengthOp |
sizeofOp = sizeExpr.(MulExpr).getAnOperand() and
lengthOp = sizeExpr.(MulExpr).getAnOperand() and
not lengthOp instanceof SizeofOperator and
exists(sizeofOp.getValue().toInt())
)
then
exists(SizeofOperator sizeofOp |
sizeofOp = sizeExpr.(MulExpr).getAnOperand() and
lengthExpr = sizeExpr.(MulExpr).getAnOperand() and
not lengthExpr instanceof SizeofOperator and
sizeof = sizeofOp.getValue().toInt()
)
else (
lengthExpr = sizeExpr and
sizeof = 1
exists(SizeofOperator sizeofOp |
sizeofOp = sizeExpr.(MulExpr).getAnOperand() and
lengthExpr = sizeExpr.(MulExpr).getAnOperand() and
not lengthExpr instanceof SizeofOperator and
sizeof = sizeofOp.getValue().toInt()
)
or
not exists(SizeofOperator sizeofOp, Expr lengthOp |
sizeofOp = sizeExpr.(MulExpr).getAnOperand() and
lengthOp = sizeExpr.(MulExpr).getAnOperand() and
not lengthOp instanceof SizeofOperator and
exists(sizeofOp.getValue().toInt())
) and
lengthExpr = sizeExpr and
sizeof = 1
}
/**

View File

@@ -0,0 +1,9 @@
struct S1 {
[[deprecated]] int a;
int b;
};
struct S2 {
int x;
[[deprecated, gnu::unused]] int b;
};

View File

@@ -0,0 +1,3 @@
| field_attributes.cpp:2:22:2:22 | a | field_attributes.cpp:2:5:2:14 | deprecated |
| field_attributes.cpp:8:35:8:35 | b | field_attributes.cpp:8:5:8:14 | deprecated |
| field_attributes.cpp:8:35:8:35 | b | field_attributes.cpp:8:17:8:27 | unused |

View File

@@ -0,0 +1,3 @@
import cpp
select any(Variable v) as v, v.getAnAttribute()

View File

@@ -3,6 +3,7 @@
| ms_var_attributes.cpp:7:5:7:10 | myInt2 | ms_var_attributes.h:4:1:4:9 | dllexport |
| ms_var_attributes.cpp:8:15:8:20 | myInt4 | ms_var_attributes.cpp:8:1:8:9 | dllexport |
| ms_var_attributes.cpp:9:5:9:10 | myInt5 | ms_var_attributes.h:7:1:7:9 | dllexport |
| ms_var_attributes.cpp:12:42:12:46 | field | ms_var_attributes.cpp:12:14:12:21 | property |
| ms_var_attributes.h:5:22:5:27 | myInt3 | ms_var_attributes.h:5:1:5:9 | dllexport |
| var_attributes.c:1:12:1:19 | weak_var | var_attributes.c:1:36:1:39 | weak |
| var_attributes.c:2:12:2:22 | weakref_var | var_attributes.c:2:39:2:45 | weakref |

View File

@@ -91,6 +91,7 @@
| file://:0:0:0:0 | implicit_int |
| file://:0:0:0:0 | inline |
| file://:0:0:0:0 | int |
| file://:0:0:0:0 | is_consteval |
| file://:0:0:0:0 | is_constexpr |
| file://:0:0:0:0 | is_thread_local |
| file://:0:0:0:0 | long |

View File

@@ -66,6 +66,7 @@
| file://:0:0:0:0 | initializer for <error> |
| file://:0:0:0:0 | inline |
| file://:0:0:0:0 | int |
| file://:0:0:0:0 | is_consteval |
| file://:0:0:0:0 | is_constexpr |
| file://:0:0:0:0 | is_thread_local |
| file://:0:0:0:0 | long |

View File

@@ -16,10 +16,8 @@
| example.c:26:18:26:24 | ref arg & ... | example.c:26:2:26:7 | coords |
| example.c:26:18:26:24 | ref arg & ... | example.c:26:19:26:24 | coords [inner post update] |
| example.c:26:19:26:24 | coords | example.c:26:18:26:24 | & ... |
| example.c:26:19:26:24 | coords [inner post update] | example.c:26:18:26:24 | & ... |
| example.c:28:22:28:25 | ref arg & ... | example.c:28:23:28:25 | pos [inner post update] |
| example.c:28:23:28:25 | pos | example.c:28:22:28:25 | & ... |
| example.c:28:23:28:25 | pos [inner post update] | example.c:28:22:28:25 | & ... |
| test.cpp:6:12:6:17 | call to source | test.cpp:7:8:7:9 | t1 |
| test.cpp:6:12:6:17 | call to source | test.cpp:8:8:8:9 | t1 |
| test.cpp:6:12:6:17 | call to source | test.cpp:9:8:9:9 | t1 |
@@ -48,11 +46,9 @@
| test.cpp:383:12:383:13 | 0 | test.cpp:384:33:384:35 | tmp |
| test.cpp:383:12:383:13 | 0 | test.cpp:385:8:385:10 | tmp |
| test.cpp:384:10:384:13 | & ... | test.cpp:384:3:384:8 | call to memcpy |
| test.cpp:384:10:384:13 | ref arg & ... | test.cpp:384:3:384:8 | call to memcpy |
| test.cpp:384:10:384:13 | ref arg & ... | test.cpp:384:11:384:13 | tmp [inner post update] |
| test.cpp:384:10:384:13 | ref arg & ... | test.cpp:385:8:385:10 | tmp |
| test.cpp:384:11:384:13 | tmp | test.cpp:384:10:384:13 | & ... |
| test.cpp:384:11:384:13 | tmp [inner post update] | test.cpp:384:10:384:13 | & ... |
| test.cpp:384:17:384:23 | source1 | test.cpp:384:10:384:13 | ref arg & ... |
| test.cpp:384:17:384:23 | source1 | test.cpp:384:16:384:23 | & ... |
| test.cpp:388:53:388:59 | source1 | test.cpp:391:17:391:23 | source1 |
@@ -64,11 +60,9 @@
| test.cpp:389:12:389:13 | 0 | test.cpp:394:10:394:12 | tmp |
| test.cpp:390:19:390:21 | tmp | test.cpp:390:18:390:21 | & ... |
| test.cpp:391:10:391:13 | & ... | test.cpp:391:3:391:8 | call to memcpy |
| test.cpp:391:10:391:13 | ref arg & ... | test.cpp:391:3:391:8 | call to memcpy |
| test.cpp:391:10:391:13 | ref arg & ... | test.cpp:391:11:391:13 | tmp [inner post update] |
| test.cpp:391:10:391:13 | ref arg & ... | test.cpp:392:8:392:10 | tmp |
| test.cpp:391:10:391:13 | ref arg & ... | test.cpp:394:10:394:12 | tmp |
| test.cpp:391:11:391:13 | tmp | test.cpp:391:10:391:13 | & ... |
| test.cpp:391:11:391:13 | tmp [inner post update] | test.cpp:391:10:391:13 | & ... |
| test.cpp:391:17:391:23 | source1 | test.cpp:391:10:391:13 | ref arg & ... |
| test.cpp:391:17:391:23 | source1 | test.cpp:391:16:391:23 | & ... |

View File

@@ -92,27 +92,23 @@
| format.cpp:116:28:116:29 | ref arg & ... | format.cpp:116:29:116:29 | i [inner post update] | |
| format.cpp:116:28:116:29 | ref arg & ... | format.cpp:117:8:117:8 | i | |
| format.cpp:116:29:116:29 | i | format.cpp:116:28:116:29 | & ... | |
| format.cpp:116:29:116:29 | i [inner post update] | format.cpp:116:28:116:29 | & ... | |
| format.cpp:120:10:120:11 | 0 | format.cpp:121:40:121:40 | i | |
| format.cpp:120:10:120:11 | 0 | format.cpp:122:8:122:8 | i | |
| format.cpp:121:39:121:40 | ref arg & ... | format.cpp:121:40:121:40 | i [inner post update] | |
| format.cpp:121:39:121:40 | ref arg & ... | format.cpp:122:8:122:8 | i | |
| format.cpp:121:40:121:40 | i | format.cpp:121:39:121:40 | & ... | |
| format.cpp:121:40:121:40 | i [inner post update] | format.cpp:121:39:121:40 | & ... | |
| format.cpp:125:21:125:24 | {...} | format.cpp:126:32:126:37 | buffer | |
| format.cpp:125:21:125:24 | {...} | format.cpp:127:8:127:13 | buffer | |
| format.cpp:125:23:125:23 | 0 | format.cpp:125:21:125:24 | {...} | TAINT |
| format.cpp:126:31:126:37 | ref arg & ... | format.cpp:126:32:126:37 | buffer [inner post update] | |
| format.cpp:126:31:126:37 | ref arg & ... | format.cpp:127:8:127:13 | buffer | |
| format.cpp:126:32:126:37 | buffer | format.cpp:126:31:126:37 | & ... | |
| format.cpp:126:32:126:37 | buffer [inner post update] | format.cpp:126:31:126:37 | & ... | |
| format.cpp:130:21:130:24 | {...} | format.cpp:131:40:131:45 | buffer | |
| format.cpp:130:21:130:24 | {...} | format.cpp:132:8:132:13 | buffer | |
| format.cpp:130:23:130:23 | 0 | format.cpp:130:21:130:24 | {...} | TAINT |
| format.cpp:131:39:131:45 | ref arg & ... | format.cpp:131:40:131:45 | buffer [inner post update] | |
| format.cpp:131:39:131:45 | ref arg & ... | format.cpp:132:8:132:13 | buffer | |
| format.cpp:131:40:131:45 | buffer | format.cpp:131:39:131:45 | & ... | |
| format.cpp:131:40:131:45 | buffer [inner post update] | format.cpp:131:39:131:45 | & ... | |
| stl.cpp:67:12:67:17 | call to source | stl.cpp:71:7:71:7 | a | |
| stl.cpp:68:16:68:20 | 123 | stl.cpp:68:16:68:21 | call to basic_string | TAINT |
| stl.cpp:68:16:68:21 | call to basic_string | stl.cpp:72:7:72:7 | b | |
@@ -307,7 +303,6 @@
| taint.cpp:165:24:165:24 | 0 | taint.cpp:165:22:165:25 | {...} | TAINT |
| taint.cpp:168:8:168:14 | ref arg tainted | taint.cpp:172:18:172:24 | tainted | |
| taint.cpp:170:10:170:15 | buffer | taint.cpp:170:3:170:8 | call to strcpy | |
| taint.cpp:170:10:170:15 | ref arg buffer | taint.cpp:170:3:170:8 | call to strcpy | |
| taint.cpp:170:10:170:15 | ref arg buffer | taint.cpp:171:8:171:13 | buffer | |
| taint.cpp:170:10:170:15 | ref arg buffer | taint.cpp:172:10:172:15 | buffer | |
| taint.cpp:170:10:170:15 | ref arg buffer | taint.cpp:173:8:173:13 | buffer | |
@@ -317,7 +312,6 @@
| taint.cpp:171:8:171:13 | ref arg buffer | taint.cpp:173:8:173:13 | buffer | |
| taint.cpp:172:10:172:15 | buffer | taint.cpp:172:3:172:8 | call to strcat | |
| taint.cpp:172:10:172:15 | buffer | taint.cpp:172:10:172:15 | ref arg buffer | TAINT |
| taint.cpp:172:10:172:15 | ref arg buffer | taint.cpp:172:3:172:8 | call to strcat | |
| taint.cpp:172:10:172:15 | ref arg buffer | taint.cpp:173:8:173:13 | buffer | |
| taint.cpp:172:18:172:24 | tainted | taint.cpp:172:10:172:15 | ref arg buffer | TAINT |
| taint.cpp:180:19:180:19 | p | taint.cpp:181:9:181:9 | p | |
@@ -325,16 +319,13 @@
| taint.cpp:185:11:185:16 | call to source | taint.cpp:186:11:186:11 | x | |
| taint.cpp:186:10:186:11 | ref arg & ... | taint.cpp:186:11:186:11 | x [inner post update] | |
| taint.cpp:186:11:186:11 | x | taint.cpp:186:10:186:11 | & ... | |
| taint.cpp:186:11:186:11 | x [inner post update] | taint.cpp:186:10:186:11 | & ... | |
| taint.cpp:192:23:192:28 | source | taint.cpp:194:13:194:18 | source | |
| taint.cpp:193:6:193:6 | x | taint.cpp:194:10:194:10 | x | |
| taint.cpp:193:6:193:6 | x | taint.cpp:195:7:195:7 | x | |
| taint.cpp:194:9:194:10 | & ... | taint.cpp:194:2:194:7 | call to memcpy | |
| taint.cpp:194:9:194:10 | ref arg & ... | taint.cpp:194:2:194:7 | call to memcpy | |
| taint.cpp:194:9:194:10 | ref arg & ... | taint.cpp:194:10:194:10 | x [inner post update] | |
| taint.cpp:194:9:194:10 | ref arg & ... | taint.cpp:195:7:195:7 | x | |
| taint.cpp:194:10:194:10 | x | taint.cpp:194:9:194:10 | & ... | |
| taint.cpp:194:10:194:10 | x [inner post update] | taint.cpp:194:9:194:10 | & ... | |
| taint.cpp:194:13:194:18 | source | taint.cpp:194:2:194:7 | call to memcpy | TAINT |
| taint.cpp:194:13:194:18 | source | taint.cpp:194:9:194:10 | ref arg & ... | TAINT |
| taint.cpp:194:21:194:31 | sizeof(int) | taint.cpp:194:2:194:7 | call to memcpy | TAINT |
@@ -495,11 +486,9 @@
| taint.cpp:346:12:346:13 | ref arg & ... | taint.cpp:346:13:346:13 | c [inner post update] | |
| 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:346:13:346:13 | c [inner post update] | taint.cpp:346:12:346:13 | & ... | |
| taint.cpp:347:12:347:13 | ref arg & ... | taint.cpp:347:13:347:13 | d [inner post update] | |
| 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:347:13:347:13 | d [inner post update] | 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 | |
| taint.cpp:365:24:365:29 | source | taint.cpp:369:13:369:18 | source | |

View File

@@ -11,9 +11,9 @@
| addressOf.cpp:38:20:38:20 | i | non-const address |
| addressOf.cpp:40:15:40:15 | i | non-const address |
| addressOf.cpp:42:19:42:22 | iref | non-const address |
| addressOf.cpp:48:3:48:4 | f1 | |
| addressOf.cpp:48:3:48:4 | f1 | const address |
| addressOf.cpp:49:15:49:22 | captured | non-const address |
| addressOf.cpp:50:3:50:4 | f2 | |
| addressOf.cpp:50:3:50:4 | f2 | const address |
| addressOf.cpp:51:10:51:17 | captured | |
| addressOf.cpp:56:16:56:16 | i | |
| addressOf.cpp:56:19:56:19 | i | |

View File

@@ -110,6 +110,7 @@
| file://:0:0:0:0 | int |
| file://:0:0:0:0 | int & |
| file://:0:0:0:0 | int * |
| file://:0:0:0:0 | is_consteval |
| file://:0:0:0:0 | is_constexpr |
| file://:0:0:0:0 | is_thread_local |
| file://:0:0:0:0 | long |

View File

@@ -59,6 +59,7 @@
| file://:0:0:0:0 | int | Other |
| file://:0:0:0:0 | int * | Other |
| file://:0:0:0:0 | int[0] | Other |
| file://:0:0:0:0 | is_consteval | Other |
| file://:0:0:0:0 | is_constexpr | Other |
| file://:0:0:0:0 | is_thread_local | Other |
| file://:0:0:0:0 | long | Other |

View File

@@ -68,6 +68,8 @@ module Stages {
or
exists(any(DataFlow::Node n).getType())
or
exists(any(DataFlow::Node n).getTypeBound())
or
exists(any(DataFlow::Node n).getLocation())
or
exists(any(DataFlow::Node n).toString())

View File

@@ -16,113 +16,49 @@ private import semmle.code.csharp.frameworks.system.threading.Tasks
private import semmle.code.csharp.frameworks.system.Web
private import semmle.code.csharp.frameworks.system.web.ui.WebControls
private import semmle.code.csharp.frameworks.system.Xml
private import semmle.code.csharp.dataflow.internal.DataFlowPublic
private import semmle.code.csharp.dataflow.internal.DelegateDataFlow
cached
private module Cached {
/**
* INTERNAL: Do not use.
*
* Holds if `source` can flow to `sink` using a call to a library
* callable.
*/
cached
predicate libraryFlow(Expr source, Expr sink, boolean preservesValue) {
exists(LibraryTypeDataFlow ltdf, CallableFlowSource csource, CallableFlowSink csink, Call c |
source = csource.getSource(c) and
ltdf.callableFlow(csource, csink, c.getTarget().getSourceDeclaration(), preservesValue) and
sink = csink.getSink(c)
)
}
private newtype TAccessPath =
TNilAccessPath() or
TAccessPathConsNil(Content c)
/**
* INTERNAL: Do not use.
*
* Holds if `source` can flow to the `out`/`ref` argument `outRef` using a call to a library
* callable.
*/
cached
predicate libraryFlowOutRef(MethodCall mc, Expr source, Parameter outRef, boolean preservesValue) {
exists(
LibraryTypeDataFlow ltdf, CallableFlowSource csource, CallableFlowSinkArg csink, Method sm
|
source = csource.getSource(mc) and
mc.getTarget().getAParameter() = outRef and
sm = mc.getTarget().getSourceDeclaration() and
ltdf.callableFlow(csource, csink, sm, preservesValue) and
csink = getFlowSinkArg(sm, outRef.getPosition())
)
}
/** An access path of length 0 or 1. */
class AccessPath extends TAccessPath {
/** Gets the head of this access path, if any. */
Content getHead() { this = TAccessPathConsNil(result) }
/**
* INTERNAL: Do not use.
*
* Holds if output from the `i`th delegate argument of `call` can flow to `sink`, using
* the library target `callable`.
*/
cached
predicate libraryFlowDelegateCallOut(
Call call, Callable callable, Expr sink, boolean preservesValue, int i
) {
exists(LibraryTypeDataFlow ltdf, CallableFlowSourceDelegateArg csource, CallableFlowSink csink |
ltdf.callableFlow(csource, csink, callable, preservesValue) and
call.getTarget().getSourceDeclaration() = callable and
csource = getDelegateFlowSourceArg(callable, i) and
sink = csink.getSink(call)
)
}
/** Holds if this access path contains content `c`. */
predicate contains(Content c) { this = TAccessPathConsNil(c) }
/**
* INTERNAL: Do not use.
*
* Holds if `source` can flow to the `i`th parameter of the delegate at argument
* `j`. The call `call` is the call in which `sink` is an argument and`callable`
* is the library target.
*/
cached
predicate libraryFlowDelegateCallIn(
Call call, Callable callable, Expr source, boolean preservesValue, int i, int j
) {
exists(LibraryTypeDataFlow ltdf, CallableFlowSource csource, CallableFlowSinkDelegateArg csink |
ltdf.callableFlow(csource, csink, callable, preservesValue) and
call.getTarget().getSourceDeclaration() = callable and
csink = getDelegateFlowSinkArg(callable, j, i) and
source = csource.getSource(call)
)
}
/**
* INTERNAL: Do not use.
*
* Holds if output from the `i`th delegate argument of `call` can flow to the `j`th parameter
* of the of delegate at argument `k`, using the library target `callable`.
*/
cached
predicate libraryFlowDelegateCallOutIn(
Call call, Callable callable, boolean preservesValue, int i, int j, int k
) {
exists(
LibraryTypeDataFlow ltdf, CallableFlowSourceDelegateArg csource,
CallableFlowSinkDelegateArg csink
|
ltdf.callableFlow(csource, csink, callable, preservesValue) and
call.getTarget().getSourceDeclaration() = callable and
csource = getDelegateFlowSourceArg(callable, i) and
csink = getDelegateFlowSinkArg(callable, k, j)
)
/** Gets a textual representation of this access path. */
string toString() {
result = this.getHead().toString()
or
this = TNilAccessPath() and
result = "<empty>"
}
}
import Cached
/** Provides predicates for constructing access paths. */
module AccessPath {
/** Gets the empty access path. */
AccessPath empty() { result = TNilAccessPath() }
/** Gets a singleton property access path. */
AccessPath property(Property p) {
result = TAccessPathConsNil(any(PropertyContent c | c.getProperty() = p.getSourceDeclaration()))
}
}
/** An unbound callable. */
library class SourceDeclarationCallable extends Callable {
SourceDeclarationCallable() { this = getSourceDeclaration() }
class SourceDeclarationCallable extends Callable {
SourceDeclarationCallable() { this = this.getSourceDeclaration() }
}
/** An unbound method. */
library class SourceDeclarationMethod extends SourceDeclarationCallable, Method { }
class SourceDeclarationMethod extends SourceDeclarationCallable, Method { }
// Internal representation of callable flow sources
private newtype TCallableFlowSource =
TCallableFlowSourceQualifier() or
TCallableFlowSourceArg(int i) { hasArgumentPosition(_, i) } or
@@ -160,83 +96,119 @@ private predicate hasDelegateArgumentPosition2(SourceDeclarationCallable c, int
)
}
/** A flow source in a call to a library callable. */
/** A flow source specification. */
class CallableFlowSource extends TCallableFlowSource {
/** Gets a textual representation of this flow source. */
/** Gets a textual representation of this flow source specification. */
string toString() { none() }
/** Gets the source of flow for call `c`, if any. */
Expr getSource(Call c) { none() }
/**
* Gets the type of the source for call `c`. Unlike `getSource()`, this
* is defined for all flow source specifications.
*/
Type getSourceType(Call c) { result = this.getSource(c).getType() }
}
/** A flow source in a call to a library callable: qualifier. */
/** A flow source specification: (method call) qualifier. */
class CallableFlowSourceQualifier extends CallableFlowSource, TCallableFlowSourceQualifier {
override string toString() { result = "qualifier" }
override Expr getSource(Call c) { result = c.getChild(-1) }
}
/** A flow source in a call to a library callable: argument. */
/** A flow source specification: (method call) argument. */
class CallableFlowSourceArg extends CallableFlowSource, TCallableFlowSourceArg {
override string toString() { result = "argument " + this.getArgumentIndex() }
private int i;
CallableFlowSourceArg() { this = TCallableFlowSourceArg(i) }
/** Gets the index of this argument. */
int getArgumentIndex() { this = TCallableFlowSourceArg(result) }
int getArgumentIndex() { result = i }
override Expr getSource(Call c) { result = c.getArgument(getArgumentIndex()) }
override string toString() { result = "argument " + i }
override Expr getSource(Call c) { result = c.getArgument(i) }
}
/** A flow source in a call to a library callable: output from delegate argument. */
/** A flow source specification: output from delegate argument. */
class CallableFlowSourceDelegateArg extends CallableFlowSource, TCallableFlowSourceDelegateArg {
override string toString() { result = "output from argument " + getArgumentIndex().toString() }
private int i;
CallableFlowSourceDelegateArg() { this = TCallableFlowSourceDelegateArg(i) }
/** Gets the index of this delegate argument. */
int getArgumentIndex() { this = TCallableFlowSourceDelegateArg(result) }
int getArgumentIndex() { result = i }
override string toString() { result = "output from argument " + i }
override Expr getSource(Call c) { none() }
override Type getSourceType(Call c) { result = c.getArgument(i).getType() }
}
// Internal representation of callable flow sinks
private newtype TCallableFlowSink =
TCallableFlowSinkQualifier() or
TCallableFlowSinkReturn() or
TCallableFlowSinkArg(int i) { exists(SourceDeclarationCallable c | exists(c.getParameter(i))) } or
TCallableFlowSinkDelegateArg(int i, int j) { hasDelegateArgumentPosition2(_, i, j) }
/** A flow sink in a call to a library callable. */
/** A flow sink specification. */
class CallableFlowSink extends TCallableFlowSink {
/** Gets a textual representation of this flow sink. */
/** Gets a textual representation of this flow sink specification. */
string toString() { none() }
/** Gets the sink of flow for call `c`, if any. */
Expr getSink(Call c) { none() }
/**
* Gets the type of the sink for call `c`. Unlike `getSink()`, this is defined
* for all flow sink specifications.
*/
Type getSinkType(Call c) { result = this.getSink(c).getType() }
}
/** A flow sink in a call to a library callable: qualifier. */
/** A flow sink specification: (method call) qualifier. */
class CallableFlowSinkQualifier extends CallableFlowSink, TCallableFlowSinkQualifier {
override string toString() { result = "qualifier" }
override Expr getSink(Call c) { result = c.getChild(-1) }
}
/** A flow sink in a call to a library callable: return value. */
/** A flow sink specification: return value. */
class CallableFlowSinkReturn extends CallableFlowSink, TCallableFlowSinkReturn {
override string toString() { result = "return" }
override Expr getSink(Call c) { result = c }
}
/** The flow sink in an argument to a call to a library method. */
/** A flow sink specification: (method call) argument. */
class CallableFlowSinkArg extends CallableFlowSink, TCallableFlowSinkArg {
override string toString() { result = "argument " + this.getArgumentIndex() }
private int i;
CallableFlowSinkArg() { this = TCallableFlowSinkArg(i) }
/** Gets the index of this `out`/`ref` argument. */
int getArgumentIndex() { this = TCallableFlowSinkArg(result) }
int getArgumentIndex() { result = i }
/** Gets the `out`/`ref` argument of method call `mc` matching this specification. */
Expr getArgument(MethodCall mc) {
exists(Parameter p |
p = mc.getTarget().getParameter(i) and
p.isOutOrRef() and
result = mc.getArgumentForParameter(p)
)
}
override string toString() { result = "argument " + i }
override Expr getSink(Call c) {
// The uses of the `i`th argument are the actual sinks
none()
}
override Type getSinkType(Call c) { result = this.getArgument(c).getType() }
}
/** Gets the flow source for argument `i` of callable `callable`. */
@@ -245,12 +217,6 @@ private CallableFlowSourceArg getFlowSourceArg(SourceDeclarationCallable callabl
hasArgumentPosition(callable, i)
}
/** Gets the flow sink for argument `i` of callable `callable`. */
private CallableFlowSinkArg getFlowSinkArg(SourceDeclarationCallable callable, int i) {
i = result.getArgumentIndex() and
hasArgumentPosition(callable, i)
}
/** Gets the flow source for argument `i` of delegate `callable`. */
private CallableFlowSourceDelegateArg getDelegateFlowSourceArg(
SourceDeclarationCallable callable, int i
@@ -267,11 +233,23 @@ private CallableFlowSinkDelegateArg getDelegateFlowSinkArg(
hasDelegateArgumentPosition2(callable, i, j)
}
/** The flow sink in a call to a library callable: parameter of a delegate argument. */
/** A flow sink specification: parameter of a delegate argument. */
class CallableFlowSinkDelegateArg extends CallableFlowSink, TCallableFlowSinkDelegateArg {
private int delegateIndex;
private int parameterIndex;
CallableFlowSinkDelegateArg() {
this = TCallableFlowSinkDelegateArg(delegateIndex, parameterIndex)
}
/** Gets the index of the delegate argument. */
int getDelegateIndex() { result = delegateIndex }
/** Gets the index of the delegate parameter. */
int getDelegateParameterIndex() { result = parameterIndex }
override string toString() {
result =
"parameter " + getDelegateParameterIndex() + " of argument " + getDelegateIndex().toString()
result = "parameter " + parameterIndex + " of argument " + delegateIndex
}
override Expr getSink(Call c) {
@@ -279,18 +257,20 @@ class CallableFlowSinkDelegateArg extends CallableFlowSink, TCallableFlowSinkDel
none()
}
/** Gets the index of the delegate argument. */
int getDelegateIndex() { this = TCallableFlowSinkDelegateArg(result, _) }
/** Gets the index of the delegate parameter. */
int getDelegateParameterIndex() { this = TCallableFlowSinkDelegateArg(_, result) }
override Type getSinkType(Call c) {
result =
c
.getArgument(delegateIndex)
.(DelegateArgumentToLibraryCallable)
.getDelegateType()
.getParameter(parameterIndex)
.getType()
}
}
/**
* A specification of data flow for a library (non-source code) type.
*/
/** A specification of data flow for a library (non-source code) type. */
abstract class LibraryTypeDataFlow extends Type {
LibraryTypeDataFlow() { this = getSourceDeclaration() }
LibraryTypeDataFlow() { this = this.getSourceDeclaration() }
/**
* Holds if data may flow from `source` to `sink` when calling callable `c`.
@@ -300,10 +280,27 @@ abstract class LibraryTypeDataFlow extends Type {
* to `x.ToString()` when `x` is a `string`, but not from `x` to `x.ToLower()`.
*/
pragma[nomagic]
abstract predicate callableFlow(
predicate callableFlow(
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
);
) {
none()
}
/**
* Holds if data may flow from `source` to `sink` when calling callable `c`.
*
* `sourceAp` describes the contents of `source` that flows to `sink`
* (if any), and `sinkContent` describes the contents of `sink` that it
* flows to (if any).
*/
pragma[nomagic]
predicate callableFlow(
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
SourceDeclarationCallable c
) {
none()
}
}
/** Data flow for `System.Int32`. */
@@ -614,38 +611,20 @@ class SystemTextStringBuilderFlow extends LibraryTypeDataFlow, SystemTextStringB
}
/** Data flow for `System.Lazy<>`. */
class SystemLazyFlow extends LibraryTypeDataFlow {
SystemLazyFlow() { this instanceof SystemLazyClass }
class SystemLazyFlow extends LibraryTypeDataFlow, SystemLazyClass {
override predicate callableFlow(
CallableFlowSource source, CallableFlowSink sink, SourceDeclarationCallable c,
boolean preservesValue
) {
(
constructorFlow(source, sink, c)
or
exists(Property p |
propertyFlow(p) and
source = TCallableFlowSourceQualifier() and
sink = TCallableFlowSinkReturn() and
c = p.getGetter()
)
) and
preservesValue = true
}
private predicate constructorFlow(
CallableFlowSourceDelegateArg source, CallableFlowSink sink, Constructor c
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
SourceDeclarationCallable c
) {
exists(SystemFuncDelegateType t, int i | t.getNumberOfTypeParameters() = 1 |
c.getDeclaringType() = this and
c.(Constructor).getDeclaringType() = this and
c.getParameter(i).getType().getSourceDeclaration() = t and
source = getDelegateFlowSourceArg(c, i) and
sink = TCallableFlowSinkReturn()
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::property(this.getValueProperty())
)
}
private predicate propertyFlow(Property p) { p = this.(SystemLazyClass).getValueProperty() }
}
/**

View File

@@ -173,15 +173,16 @@ abstract class ControlFlowReachabilityConfiguration extends string {
* Holds if there is a control-flow path from `cfn1` to `cfn2`, where `cfn1` is a
* control-flow node for `e1` and `cfn2` is a control-flow node for `e2`.
*/
pragma[nomagic]
predicate hasExprPath(Expr e1, ControlFlow::Node cfn1, Expr e2, ControlFlow::Node cfn2) {
exists(ControlFlow::BasicBlock bb, boolean isSuccessor, int i, int j |
this.reachesBasicBlockExprBase(e1, e2, _, _, isSuccessor, cfn1, i, bb) and
cfn2 = bb.getNode(j) and
cfn2 = e2.getAControlFlowNode()
|
isSuccessor = true and j > i
isSuccessor = true and j >= i
or
isSuccessor = false and i > j
isSuccessor = false and i >= j
)
or
exists(ControlFlow::BasicBlock bb |
@@ -195,6 +196,7 @@ abstract class ControlFlowReachabilityConfiguration extends string {
* Holds if there is a control-flow path from `cfn` to `cfnDef`, where `cfn` is a
* control-flow node for `e` and `cfnDef` is a control-flow node for `def`.
*/
pragma[nomagic]
predicate hasDefPath(
Expr e, ControlFlow::Node cfn, AssignableDefinition def, ControlFlow::Node cfnDef
) {
@@ -203,9 +205,9 @@ abstract class ControlFlowReachabilityConfiguration extends string {
cfnDef = bb.getNode(j) and
def.getAControlFlowNode() = cfnDef
|
isSuccessor = true and j > i
isSuccessor = true and j >= i
or
isSuccessor = false and i > j
isSuccessor = false and i >= j
)
or
exists(ControlFlow::BasicBlock bb |
@@ -219,6 +221,7 @@ abstract class ControlFlowReachabilityConfiguration extends string {
* Holds if there is a control-flow path from `n1` to `n2`. `n2` is either an
* expression node or an SSA definition node.
*/
pragma[nomagic]
predicate hasNodePath(ExprNode n1, Node n2) {
exists(Expr e1, ControlFlow::Node cfn1, Expr e2, ControlFlow::Node cfn2 |
this.hasExprPath(e1, cfn1, e2, cfn2)

View File

@@ -346,11 +346,14 @@ class ImplicitDelegateDataFlowCall extends DelegateDataFlowCall, TImplicitDelega
/** Gets the number of parameters of the supplied delegate. */
int getNumberOfDelegateParameters() { result = arg.getDelegateType().getNumberOfParameters() }
/** Gets the type of the `i`th parameter of the supplied delegate. */
Type getDelegateParameterType(int i) { result = arg.getDelegateType().getParameter(i).getType() }
/** Gets the return type of the supplied delegate. */
Type getDelegateReturnType() { result = arg.getDelegateType().getReturnType() }
override DotNet::Callable getARuntimeTarget(CallContext::CallContext cc) {
result = cfn.getElement().(DelegateArgumentToLibraryCallable).getARuntimeTarget(cc)
result = arg.getARuntimeTarget(cc)
}
override ControlFlow::Nodes::ElementNode getControlFlowNode() { result = cfn }

View File

@@ -81,9 +81,6 @@ module LocalFlow {
) {
exactScope = false and
(
// Flow using library code
libraryFlow(e1, e2, scope, isSuccessor, true)
or
e1 = e2.(ParenthesizedExpr).getExpr() and
scope = e2 and
isSuccessor = true
@@ -244,39 +241,9 @@ module LocalFlow {
nodeTo = TImplicitCapturedArgumentNode(call, def.getSourceVariable().getAssignable())
)
}
private Expr getALibraryFlowParentFrom(Expr exprFrom, Expr exprTo, boolean preservesValue) {
libraryFlow(exprFrom, exprTo, preservesValue) and
result = exprFrom
or
result.getAChildExpr() = getALibraryFlowParentFrom(exprFrom, exprTo, preservesValue)
}
private Expr getALibraryFlowParentTo(Expr exprFrom, Expr exprTo, boolean preservesValue) {
libraryFlow(exprFrom, exprTo, preservesValue) and
result = exprTo
or
exists(Expr mid | mid = getALibraryFlowParentTo(exprFrom, exprTo, preservesValue) |
result.getAChildExpr() = mid and
not mid = getALibraryFlowParentFrom(exprFrom, exprTo, preservesValue)
)
}
pragma[noinline]
predicate libraryFlow(
Expr exprFrom, Expr exprTo, Expr scope, boolean isSuccessor, boolean preservesValue
) {
// To not pollute the definitions in `LibraryTypeDataFlow.qll` with syntactic scope,
// simply use the nearest common parent expression for `exprFrom` and `exprTo`
scope = getALibraryFlowParentFrom(exprFrom, exprTo, preservesValue) and
scope = getALibraryFlowParentTo(exprFrom, exprTo, preservesValue) and
// Similarly, for simplicity allow following both forwards and backwards edges from
// `exprFrom` to `exprTo`
(isSuccessor = true or isSuccessor = false)
}
}
/** An argument of a C# call. */
/** An argument of a C# call (including qualifier arguments). */
private class Argument extends Expr {
private Expr call;
private int arg;
@@ -292,39 +259,85 @@ private class Argument extends Expr {
this = call.(DelegateCall).getArgument(arg)
}
/** Holds if this expression is the `i`th argument of `c`. */
/**
* Holds if this expression is the `i`th argument of `c`.
*
* Qualifier arguments have index `-1`.
*/
predicate isArgumentOf(Expr c, int i) { c = call and i = arg }
}
/**
* Holds if `e` is an assignment of `src` to a non-static field or field-like
* property `f` of `q`.
* Holds if `e` is an assignment of `src` to field or property `c` of `q`.
*/
private predicate instanceFieldLikeAssign(Expr e, FieldLike f, Expr src, Expr q) {
exists(FieldLikeAccess fa, AssignableDefinition def |
private predicate fieldOrPropertyAssign(Expr e, Content c, Expr src, Expr q) {
exists(FieldOrPropertyAccess fa, FieldOrProperty f, AssignableDefinition def |
def.getTargetAccess() = fa and
f = fa.getTarget().getSourceDeclaration() and
not f.isStatic() and
f = fa.getTarget() and
c = f.getContent() and
src = def.getSource() and
q = fa.getQualifier() and
e = def.getExpr()
|
f.isFieldLike() and
f instanceof InstanceFieldOrProperty
or
exists(AccessPath ap |
LibraryFlow::libraryFlow(_, _, ap, _, _, _) and
ap.contains(f.getContent())
)
)
}
/**
* Holds if `oc` has an object initializer that assigns `src` to non-static field or
* field-like property `f`.
* Holds if `oc` has an object initializer that assigns `src` to field or
* property `c`.
*/
private predicate instanceFieldLikeInit(ObjectCreation oc, FieldLike f, Expr src) {
exists(MemberInitializer mi |
private predicate fieldOrPropertyInit(ObjectCreation oc, Content c, Expr src) {
exists(MemberInitializer mi, FieldOrProperty f |
mi = oc.getInitializer().(ObjectInitializer).getAMemberInitializer() and
f = mi.getInitializedMember().getSourceDeclaration() and
not f.isStatic() and
f = mi.getInitializedMember() and
c = f.getContent() and
src = mi.getRValue()
|
f.isFieldLike() and
f instanceof InstanceFieldOrProperty
or
exists(AccessPath ap |
LibraryFlow::libraryFlow(_, _, ap, _, _, _) and
ap.contains(f.getContent())
)
)
}
private Type getCSharpType(DotNet::Type t) {
/** Holds if property `p1` overrides or implements source declaration property `p2`. */
private predicate overridesOrImplementsSourceDecl(Property p1, Property p2) {
p1.getOverridee*().getSourceDeclaration() = p2
or
p1.getAnUltimateImplementee().getSourceDeclaration() = p2
}
/**
* Holds if `e2` is an expression that reads field or property `c` from
* expresion `e1`. This takes overriding into account for properties written
* from library code.
*/
private predicate fieldOrPropertyRead(Expr e1, Content c, FieldOrPropertyRead e2) {
e1 = e2.getQualifier() and
exists(FieldOrProperty ret | c = ret.getContent() |
ret.isFieldLike() and
ret = e2.getTarget()
or
exists(AccessPath ap, Property target |
LibraryFlow::libraryFlow(_, _, _, _, ap, _) and
ap.contains(ret.getContent()) and
target.getGetter() = e2.(PropertyCall).getARuntimeTarget() and
overridesOrImplementsSourceDecl(target, ret)
)
)
}
Type getCSharpType(DotNet::Type t) {
result = t
or
result.matchesHandle(t)
@@ -359,8 +372,7 @@ private module Cached {
TSsaDefinitionNode(Ssa::Definition def) or
TInstanceParameterNode(Callable c) { c.hasBody() and not c.(Modifiable).isStatic() } or
TCilParameterNode(CIL::Parameter p) { p.getMethod().hasBody() } or
TTaintedParameterNode(Parameter p) { explicitParameterNode(_, p) } or
TTaintedReturnNode(ControlFlow::Nodes::ElementNode cfn) {
TYieldReturnNode(ControlFlow::Nodes::ElementNode cfn) {
any(Callable c).canYieldReturn(cfn.getElement())
} or
TImplicitCapturedArgumentNode(ControlFlow::Nodes::ElementNode cfn, LocalScopeVariable v) {
@@ -374,6 +386,14 @@ private module Cached {
cfn.getElement() instanceof DelegateArgumentToLibraryCallable and
any(DelegateArgumentConfiguration x).hasExprPath(_, cfn, _, call)
} or
TImplicitDelegateArgumentNode(ControlFlow::Nodes::ElementNode cfn, int i, int j) {
exists(Call call, CallableFlowSinkDelegateArg sink |
LibraryFlow::libraryFlow(call, _, _, sink, _, _) and
i = sink.getDelegateIndex() and
j = sink.getDelegateParameterIndex() and
call.getArgument(i).getAControlFlowNode() = cfn
)
} or
TMallocNode(ControlFlow::Nodes::ElementNode cfn) { cfn.getElement() instanceof ObjectCreation } or
TExprPostUpdateNode(ControlFlow::Nodes::ElementNode cfn) {
exists(Argument a, Type t |
@@ -386,13 +406,19 @@ private module Cached {
t = any(TypeParameter tp | not tp.isValueType())
)
or
instanceFieldLikeAssign(_, _, _, cfn.getElement())
fieldOrPropertyAssign(_, _, _, cfn.getElement())
or
exists(TExprPostUpdateNode upd, FieldLikeAccess fla |
exists(TExprPostUpdateNode upd, FieldOrPropertyAccess fla |
upd = TExprPostUpdateNode(fla.getAControlFlowNode())
|
cfn.getElement() = fla.getQualifier()
)
} or
TLibraryCodeNode(
ControlFlow::Node callCfn, CallableFlowSource source, AccessPath sourceAp,
CallableFlowSink sink, AccessPath sinkAp, boolean preservesValue
) {
LibraryFlow::libraryFlow(callCfn.getElement(), source, sourceAp, sink, sinkAp, preservesValue)
}
/**
@@ -415,11 +441,15 @@ private module Cached {
or
LocalFlow::localFlowCapturedVarStep(nodeFrom, nodeTo)
or
flowOutOfDelegateLibraryCall(nodeFrom, nodeTo, true)
or
flowThroughLibraryCallableOutRef(_, nodeFrom, nodeTo, true)
or
LocalFlow::localFlowStepCil(nodeFrom, nodeTo)
or
exists(LibraryCodeNode n | n.preservesValue() |
n = nodeTo and
nodeFrom = n.getPredecessor(AccessPath::empty())
or
n = nodeFrom and
nodeTo = n.getSuccessor(AccessPath::empty())
)
}
/**
@@ -446,25 +476,26 @@ private module Cached {
cached
newtype TContent =
TFieldLikeContent(FieldLike f) { not f.isStatic() and f.getSourceDeclaration() = f }
TFieldContent(Field f) { f = f.getSourceDeclaration() } or
TPropertyContent(Property p) { p = p.getSourceDeclaration() }
/**
* Holds if data can flow from `node1` to `node2` via an assignment to
* content `c`.
*/
cached
predicate storeStepImpl(ExprNode node1, Content c, PostUpdateNode node2) {
exists(StoreStepConfiguration x, Node preNode2 |
preNode2 = node2.getPreUpdateNode() and
predicate storeStepImpl(Node node1, Content c, Node node2) {
exists(StoreStepConfiguration x, ExprNode preNode2 |
preNode2 = node2.(PostUpdateNode).getPreUpdateNode() and
x.hasNodePath(node1, preNode2) and
instanceFieldLikeAssign(_, c.(FieldLikeContent).getField(), node1.asExpr(), preNode2.asExpr())
fieldOrPropertyAssign(_, c, node1.asExpr(), preNode2.getExpr())
)
or
exists(StoreStepConfiguration x |
x.hasNodePath(node1, node2) and
instanceFieldLikeInit(node2.(ObjectCreationNode).getExpr(), c.(FieldLikeContent).getField(),
node1.asExpr())
exists(StoreStepConfiguration x | x.hasNodePath(node1, node2) |
fieldOrPropertyInit(node2.(ObjectCreationNode).getExpr(), c, node1.asExpr())
)
or
node2 = node1.(LibraryCodeNode).getSuccessor(any(AccessPath ap | ap.getHead() = c))
}
/**
@@ -474,9 +505,10 @@ private module Cached {
predicate readStepImpl(Node node1, Content c, Node node2) {
exists(ReadStepConfiguration x |
x.hasNodePath(node1, node2) and
c.(FieldLikeContent).getField() =
node2.asExpr().(FieldLikeRead).getTarget().getSourceDeclaration()
fieldOrPropertyRead(node1.asExpr(), c, node2.asExpr())
)
or
node1 = node2.(LibraryCodeNode).getPredecessor(any(AccessPath ap | ap.getHead() = c))
}
/**
@@ -495,19 +527,6 @@ private module Cached {
)
}
/**
* Gets a representative type for `t` for the purpose of pruning possible flow.
*/
cached
DataFlowType getErasedRepr(DotNet::Type t) {
exists(Type t0 | result = Gvn::getGlobalValueNumber(t0) |
t0 = getCSharpType(t)
or
not exists(getCSharpType(t)) and
t0 instanceof ObjectType
)
}
/**
* Holds if GVNs `t1` and `t2` may have a common sub type. Neither `t1` nor
* `t2` are allowed to be type parameters.
@@ -607,44 +626,6 @@ private module ParameterNodes {
override string toString() { result = "this" }
}
/**
* A tainted parameter. Tainted parameters are a mere implementation detail, used
* to restrict tainted flow into callables to just taint tracking (just like flow
* out of `TaintedReturnNode`s is restricted to taint tracking).
*/
class TaintedParameterNode extends ParameterNode, TTaintedParameterNode {
private Parameter parameter;
TaintedParameterNode() { this = TTaintedParameterNode(parameter) }
/** Gets the underlying parameter node. */
ExplicitParameterNode getUnderlyingNode() { explicitParameterNode(result, parameter) }
// `getParameter()` is explicitly *not* overriden to return `parameter`,
// as that would otherwise enable tainted parameters to accidentally be
// used by users of the library
override predicate isParameterOf(DataFlowCallable c, int i) {
c = parameter.getCallable() and
// we model tainted parameters as if they had been extra parameters after
// the actual parameters
i = parameter.getPosition() + c.getNumberOfParameters()
}
override Callable getEnclosingCallable() {
result = this.getUnderlyingNode().getEnclosingCallable()
}
override Type getType() {
// Taint tracking steps are allowed to change the type of the tracked object,
// so `result = this.getUnderlyingNode().getType()` is too restrictive
result instanceof ObjectType
}
override Location getLocation() { result = this.getUnderlyingNode().getLocation() }
override string toString() { result = this.getUnderlyingNode().toString() }
}
module ImplicitCapturedParameterNodeImpl {
/** An implicit entry definition for a captured variable. */
class SsaCapturedEntryDefinition extends Ssa::ImplicitEntryDefinition {
@@ -688,7 +669,7 @@ private module ParameterNodes {
* An implicit parameter is added in order to be able to track flow into
* capturing callables, as if an explicit `ref` parameter had been used:
*
* ```
* ```csharp
* void M() { void M() {
* int i = 0; int i = 0;
* void In() { => void In(ref int i0) { // implicit i0 parameter
@@ -741,47 +722,6 @@ private module ArgumentNodes {
}
}
/**
* Holds if `arg` is an argument of a call, which resolves to a library callable
* that is known to forward `arg` into the `i`th parameter of a supplied
* delegate `delegate`.
*
* For example, in
*
* ```
* x.Select(Foo);
* ```
*
* `arg = x`, `i = 0`, `call = x.Select(Foo)`, and `delegate = Foo`.
*/
private predicate flowIntoCallableLibraryCall(
ExplicitArgumentNode arg, ImplicitDelegateDataFlowCall delegate, int i
) {
exists(DataFlowCall call, int j, boolean preservesValue |
preservesValue = true and i = j
or
preservesValue = false and i = j + delegate.getNumberOfDelegateParameters()
|
exists(DelegateArgumentConfiguration x, Call callExpr, ExprNode argExpr |
x
.hasExprPath(argExpr.getExpr(), argExpr.getControlFlowNode(), callExpr,
call.getControlFlowNode())
|
exists(int k |
libraryFlowDelegateCallIn(callExpr, _, argExpr.getExpr(), preservesValue, j, k) and
arg = argExpr and
delegate.isArgumentOf(call, k)
)
or
exists(int k, int l | libraryFlowDelegateCallOutIn(callExpr, _, preservesValue, k, j, l) |
delegate.isArgumentOf(call, l) and
arg.(ImplicitDelegateOutNode).isArgumentOf(call, k) and
arg = TImplicitDelegateOutNode(argExpr.getControlFlowNode(), _)
)
)
)
}
private class ArgumentConfiguration extends ControlFlowReachabilityConfiguration {
ArgumentConfiguration() { this = "ArgumentConfiguration" }
@@ -801,10 +741,6 @@ private module ArgumentNodes {
this.asExpr() instanceof Argument
or
this.asExpr() = any(CIL::Call call).getAnArgument()
or
libraryFlowDelegateCallIn(_, _, this.asExpr(), _, _, _)
or
this.(ImplicitDelegateOutNode).isArgumentOf(_, _)
}
override predicate argumentOf(DataFlowCall call, int pos) {
@@ -821,8 +757,6 @@ private module ArgumentNodes {
c = call.getExpr() and
arg = c.getArgument(pos)
)
or
flowIntoCallableLibraryCall(this, call, pos)
}
}
@@ -833,7 +767,7 @@ private module ArgumentNodes {
* An implicit node is added in order to be able to track flow into capturing
* callables, as if an explicit parameter had been used:
*
* ```
* ```csharp
* void M() { void M() {
* int i = 0; int i = 0;
* void Out() { i = 1; } => void Out(ref int i0) { i0 = 1; }
@@ -913,6 +847,43 @@ private module ArgumentNodes {
override string toString() { result = "malloc" }
}
/**
* A data flow node that represents an implicit argument of an implicit delegate
* call in library code. For example, in
*
* ```csharp
* x.Select(Foo);
* ```
*
* `x` is an implicit argument of the implicit call to `Foo`.
*/
class ImplicitDelegateArgumentNode extends ArgumentNode, TImplicitDelegateArgumentNode {
private ControlFlow::Node cfn;
private int delegateIndex;
private int parameterIndex;
ImplicitDelegateArgumentNode() {
this = TImplicitDelegateArgumentNode(cfn, delegateIndex, parameterIndex)
}
private ImplicitDelegateDataFlowCall getDelegateCall() { result.getControlFlowNode() = cfn }
override predicate argumentOf(DataFlowCall call, int pos) {
call = this.getDelegateCall() and
pos = parameterIndex
}
override Callable getEnclosingCallable() { result = cfn.getEnclosingCallable() }
override Type getType() {
result = this.getDelegateCall().getDelegateParameterType(parameterIndex)
}
override Location getLocation() { result = cfn.getLocation() }
override string toString() { result = "[implicit argument " + parameterIndex + "] " + cfn }
}
}
import ArgumentNodes
@@ -964,31 +935,29 @@ private module ReturnNodes {
}
/**
* A tainted return node. Tainted return nodes are a mere implementation detail,
* used to restrict tainted flow out of callables to just taint tracking (just
* like flow in to `TaintedReturnParameter`s is restricted to taint tracking).
* A `yield return` node. A node is synthesized in order to be able to model
* `yield return`s as stores into collections, i.e., there is flow from `e`
* to `yield return e [e]`.
*/
class TaintedReturnNode extends ReturnNode, TTaintedReturnNode {
class YieldReturnNode extends ReturnNode, PostUpdateNode, TYieldReturnNode {
private ControlFlow::Nodes::ElementNode cfn;
private YieldReturnStmt yrs;
TaintedReturnNode() { this = TTaintedReturnNode(cfn) }
YieldReturnNode() { this = TYieldReturnNode(cfn) and yrs.getExpr().getAControlFlowNode() = cfn }
/** Gets the underlying return node. */
ExprReturnNode getUnderlyingNode() { result.getControlFlowNode() = cfn }
YieldReturnStmt getYieldReturnStmt() { result = yrs }
override YieldReturnKind getKind() { any() }
override Callable getEnclosingCallable() {
result = this.getUnderlyingNode().getEnclosingCallable()
}
override ExprNode getPreUpdateNode() { result.getControlFlowNode() = cfn }
override Type getType() {
result = this.getUnderlyingNode().getEnclosingCallable().getReturnType()
}
override Callable getEnclosingCallable() { result = yrs.getEnclosingCallable() }
override Location getLocation() { result = this.getUnderlyingNode().getLocation() }
override Type getType() { result = yrs.getEnclosingCallable().getReturnType() }
override string toString() { result = this.getUnderlyingNode().toString() }
override Location getLocation() { result = yrs.getLocation() }
override string toString() { result = yrs.toString() }
}
/**
@@ -998,7 +967,7 @@ private module ReturnNodes {
* An implicit node is added in order to be able to track flow out of capturing
* callables, as if an explicit `ref` parameter had been used:
*
* ```
* ```csharp
* void M() { void M() {
* int i = 0; int i = 0;
* void Out() { void Out(ref int i0) {
@@ -1188,68 +1157,290 @@ private module OutNodes {
import OutNodes
private class FlowThroughLibraryCallableOutRefConfiguration extends ControlFlowReachabilityConfiguration {
FlowThroughLibraryCallableOutRefConfiguration() {
this = "FlowThroughLibraryCallableOutRefConfiguration"
}
override predicate candidateDef(
Expr e, AssignableDefinition def, ControlFlowElement scope, boolean exactScope,
boolean isSuccessor
/**
* Provides predicates related to flow through library code, based on
* the flow summaries in `LibraryTypeDataFlow.qll`.
*/
module LibraryFlow {
pragma[nomagic]
private ValueOrRefType getPreciseSourceProperty0(
Call call, CallableFlowSource source, AccessPath sourceAp, Property p
) {
exists(MethodCall mc, Parameter outRef | libraryFlowOutRef(mc, e, outRef, _) |
def.getTargetAccess() = mc.getArgumentForParameter(outRef) and
def instanceof AssignableDefinitions::OutRefDefinition and
scope = mc and
isSuccessor = true and
exactScope = false
exists(LibraryTypeDataFlow ltdf, Property p0 |
ltdf.callableFlow(source, sourceAp, _, _, call.getTarget().getSourceDeclaration()) and
sourceAp = AccessPath::property(p0) and
overridesOrImplementsSourceDecl(p, p0) and
result = source.getSourceType(call)
)
}
/**
* Gets a precise source property for source `source` and access path `sourceAp`,
* in the context of `call`. For example, in
*
* ```csharp
* var list = new List<string>();
* var count = list.Count();
* ```
*
* the step from `list` to `list.Count()`, which may be modeled as a read of
* the `Count` property from `ICollection<T>`, can be strengthened to be a
* read of the `Count` property from `List<T>`.
*/
pragma[nomagic]
private Property getPreciseSourceProperty(
Call call, CallableFlowSource source, AccessPath sourceAp
) {
getPreciseSourceProperty0(call, source, sourceAp, result).hasMember(result)
}
pragma[nomagic]
private ValueOrRefType getPreciseSinkProperty0(
Call call, CallableFlowSink sink, AccessPath sinkAp, Property p
) {
exists(LibraryTypeDataFlow ltdf, Property p0 |
ltdf.callableFlow(_, _, sink, sinkAp, call.getTarget().getSourceDeclaration()) and
sinkAp = AccessPath::property(p0) and
overridesOrImplementsSourceDecl(p, p0) and
result = sink.getSinkType(call)
)
}
/**
* Gets a precise sink property for sink `sink` and access path `sinkAp`,
* in the context of `call`. For example, in
*
* ```csharp
* var list = new List<string>();
* list.Add("taint");
* var enumerator = list.getEnumerator();
* ```
*
* the step from `list` to `list.getEnumerator()`, which may be modeled as a
* read of a collection element followed by a store into the `Current`
* property, can be strengthened to be a store into the `Current` property
* from `List<T>.Enumerator`, rather than the generic `Current` property
* from `IEnumerator<T>`.
*/
pragma[nomagic]
private Property getPreciseSinkProperty(Call call, CallableFlowSink sink, AccessPath sinkAp) {
getPreciseSinkProperty0(call, sink, sinkAp, result).hasMember(result)
}
/**
* Holds if data can flow from a node of kind `source` to a node of kind `sink`,
* using a call to a library callable.
*
* `sourceAp` describes the contents of the source node that flows to the sink
* (if any), and `sinkAp` describes the contents of the sink that it flows to
* (if any).
*
* `preservesValue = false` implies that both `sourceAp` and `sinkAp` are empty.
*/
pragma[nomagic]
predicate libraryFlow(
Call call, CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink,
AccessPath sinkAp, boolean preservesValue
) {
exists(LibraryTypeDataFlow ltdf, SourceDeclarationCallable c |
c = call.getTarget().getSourceDeclaration()
|
ltdf.callableFlow(source, sink, c, preservesValue) and
sourceAp = AccessPath::empty() and
sinkAp = AccessPath::empty()
or
preservesValue = true and
exists(AccessPath sourceAp0, AccessPath sinkAp0 |
ltdf.callableFlow(source, sourceAp0, sink, sinkAp0, c) and
(
not sourceAp0 = AccessPath::property(_) and
sourceAp = sourceAp0
or
exists(Property p |
overridesOrImplementsSourceDecl(p,
getPreciseSourceProperty(call, source, sourceAp0).getSourceDeclaration()) and
sourceAp = AccessPath::property(p)
)
) and
(
not sinkAp0 = AccessPath::property(_) and
sinkAp = sinkAp0
or
sinkAp = AccessPath::property(getPreciseSinkProperty(call, sink, sinkAp0))
)
)
)
}
class LibrarySourceConfiguration extends ControlFlowReachabilityConfiguration {
LibrarySourceConfiguration() { this = "LibrarySourceConfiguration" }
override predicate candidate(
Expr e1, Expr e2, ControlFlowElement scope, boolean exactScope, boolean isSuccessor
) {
exists(CallableFlowSource source |
libraryFlow(e2, source, _, _, _, _) and
e1 = source.getSource(e2) and
scope = e2 and
exactScope = false and
isSuccessor = true
)
}
}
class LibrarySinkConfiguration extends ControlFlowReachabilityConfiguration {
LibrarySinkConfiguration() { this = "LibrarySinkConfiguration" }
override predicate candidate(
Expr e1, Expr e2, ControlFlowElement scope, boolean exactScope, boolean isSuccessor
) {
exists(CallableFlowSink sink |
libraryFlow(e1, _, _, sink, _, _) and
e2 = sink.getSink(e1) and
scope = e1 and
exactScope = false and
isSuccessor = false
)
}
override predicate candidateDef(
Expr e, AssignableDefinition def, ControlFlowElement scope, boolean exactScope,
boolean isSuccessor
) {
exists(CallableFlowSinkArg sink |
libraryFlow(e, _, _, sink, _, _) and
scope = e and
exactScope = false and
isSuccessor = true and
def.getTargetAccess() = sink.getArgument(e) and
def instanceof AssignableDefinitions::OutRefDefinition
)
}
}
}
/**
* Holds if `arg` is an argument of the method call `mc`, where the target
* of `mc` is a library callable that forwards `arg` to an `out`/`ref` argument
* `node`. Example:
*
* ```
* int i;
* Int32.TryParse("42", out i);
* ```
*
* `mc = Int32.TryParse("42", out i)`, `arg = "42"`, and `node` is the access
* to `i` in `out i`.
*/
predicate flowThroughLibraryCallableOutRef(
MethodCall mc, ExprNode arg, SsaDefinitionNode node, boolean preservesValue
) {
libraryFlowOutRef(mc, arg.getExpr(), _, preservesValue) and
any(FlowThroughLibraryCallableOutRefConfiguration x).hasNodePath(arg, node)
/** A data-flow node used to model flow through library code. */
class LibraryCodeNode extends Node, TLibraryCodeNode {
private ControlFlow::Node callCfn;
private CallableFlowSource source;
private AccessPath sourceAp;
private CallableFlowSink sink;
private AccessPath sinkAp;
private boolean preservesValue;
LibraryCodeNode() {
this = TLibraryCodeNode(callCfn, source, sourceAp, sink, sinkAp, preservesValue)
}
/** Holds if this node is part of a value-preserving library step. */
predicate preservesValue() { preservesValue = true }
/**
* Gets the predecessor of this library-code node. The head of `ap` describes
* the content that is read from when entering this node (if any).
*/
Node getPredecessor(AccessPath ap) {
ap = sourceAp and
(
// The source is either an argument or a qualifier, for example
// `s` in `int.Parse(s)`
exists(LibraryFlow::LibrarySourceConfiguration x, Call call |
callCfn = call.getAControlFlowNode() and
x.hasExprPath(source.getSource(call), result.(ExprNode).getControlFlowNode(), _, callCfn)
)
or
// The source is the output of a supplied delegate argument, for
// example the output of `Foo` in `new Lazy(Foo)`
exists(DataFlowCall call, int pos |
pos = source.(CallableFlowSourceDelegateArg).getArgumentIndex() and
result.(ImplicitDelegateOutNode).isArgumentOf(call, pos) and
callCfn = call.getControlFlowNode()
)
)
}
/**
* Gets the successor of this library-code node. The head of `ap` describes
* the content that is stored into when leaving this node (if any).
*/
Node getSuccessor(AccessPath ap) {
ap = sinkAp and
(
exists(LibraryFlow::LibrarySinkConfiguration x, Call call, ExprNode e |
callCfn = call.getAControlFlowNode() and
x.hasExprPath(_, callCfn, sink.getSink(call), e.getControlFlowNode())
|
// The sink is an ordinary return value, for example `int.Parse(s)`
sink instanceof CallableFlowSinkReturn and
result = e
or
// The sink is a qualifier, for example `list` in `list.Add(x)`
sink instanceof CallableFlowSinkQualifier and
if sinkAp = AccessPath::empty()
then result = e
else result.(ExprPostUpdateNode).getPreUpdateNode() = e
)
or
// The sink is an `out`/`ref` argument, for example `out i` in
// `int.TryParse(s, out i)`
exists(LibraryFlow::LibrarySinkConfiguration x, OutRefReturnKind k |
result =
any(ParamOutNode out |
out.getCall(k).getControlFlowNode() = callCfn and
sink.(CallableFlowSinkArg).getArgumentIndex() = k.getPosition() and
x.hasDefPath(_, callCfn, out.getDefinition(), _)
)
)
or
// The sink is a parameter of a supplied delegate argument, for example
// the parameter of `Foo` in `list.Select(Foo)`.
//
// This is implemented using a node that represents the implicit argument
// (`ImplicitDelegateArgumentNode`) of the implicit call
// (`ImplicitDelegateDataFlowCall`) to `Foo`.
exists(
DataFlowCall call, ImplicitDelegateDataFlowCall dcall, int delegateIndex, int parameterIndex
|
sink =
any(CallableFlowSinkDelegateArg s |
delegateIndex = s.getDelegateIndex() and
parameterIndex = s.getDelegateParameterIndex()
) and
result = TImplicitDelegateArgumentNode(dcall.getControlFlowNode(), _, parameterIndex) and
dcall.isArgumentOf(call, delegateIndex) and
callCfn = call.getControlFlowNode()
)
)
}
override Callable getEnclosingCallable() { result = callCfn.getEnclosingCallable() }
override DataFlowType getTypeBound() {
preservesValue = true and
sourceAp = AccessPath::empty() and
result = this.getPredecessor(_).getTypeBound()
or
result = sourceAp.getHead().getType()
or
preservesValue = false and
result = this.getSuccessor(_).getTypeBound()
}
override Location getLocation() { result = callCfn.getLocation() }
override string toString() { result = "[library code] " + callCfn }
}
/**
* Holds if the output from the delegate `delegate` flows to `out`. The delegate
* is passed as an argument to a library callable, which invokes the delegate.
* Example:
*
* ```
* x.Select(Foo);
* ```
*
* `delegate = Foo`, `out = x.Select(Foo)`, and `preservesValue = false`.
*/
predicate flowOutOfDelegateLibraryCall(
ImplicitDelegateOutNode delegate, ExprOutNode out, boolean preservesValue
) {
exists(DataFlowCall call, int i |
libraryFlowDelegateCallOut(call.getExpr(), _, out.getExpr(), preservesValue, i) and
delegate.isArgumentOf(call, i) and
out.getControlFlowNode() = call.getControlFlowNode()
)
}
/** A field or a property. */
private class FieldOrProperty extends Assignable, Modifiable {
FieldOrProperty() {
this instanceof Field
or
this instanceof Property
}
private class FieldLike extends Assignable, Modifiable {
FieldLike() {
/** Holds if this is either a field or a field-like property. */
predicate isFieldLike() {
this instanceof Field or
this =
any(Property p |
@@ -1261,42 +1452,54 @@ private class FieldLike extends Assignable, Modifiable {
)
)
}
/** Gets the content that matches this field or property. */
Content getContent() {
result.(FieldContent).getField() = this.getSourceDeclaration()
or
result.(PropertyContent).getProperty() = this.getSourceDeclaration()
}
}
private class FieldLikeAccess extends AssignableAccess, QualifiableExpr {
FieldLikeAccess() { this.getTarget() instanceof FieldLike }
private class InstanceFieldOrProperty extends FieldOrProperty {
InstanceFieldOrProperty() { not this.isStatic() }
}
private class FieldLikeRead extends FieldLikeAccess, AssignableRead { }
private class FieldOrPropertyAccess extends AssignableAccess, QualifiableExpr {
FieldOrPropertyAccess() { this.getTarget() instanceof FieldOrProperty }
}
/**
* Holds if the field-like read `flr` is not completely determined by explicit
* SSA updates.
*/
private predicate hasNonlocalValue(FieldLikeRead flr) {
flr = any(Ssa::ImplicitUntrackedDefinition udef).getARead()
or
exists(Ssa::Definition def, Ssa::ImplicitDefinition idef |
def.getARead() = flr and
idef = def.getAnUltimateDefinition()
|
idef instanceof Ssa::ImplicitEntryDefinition or
idef instanceof Ssa::ImplicitCallDefinition
)
private class FieldOrPropertyRead extends FieldOrPropertyAccess, AssignableRead {
/**
* Holds if this field-like read is not completely determined by explicit
* SSA updates.
*/
predicate hasNonlocalValue() {
this = any(Ssa::ImplicitUntrackedDefinition udef).getARead()
or
exists(Ssa::Definition def, Ssa::ImplicitDefinition idef |
def.getARead() = this and
idef = def.getAnUltimateDefinition()
|
idef instanceof Ssa::ImplicitEntryDefinition or
idef instanceof Ssa::ImplicitCallDefinition
)
}
}
/** A write to a static field/property. */
private class StaticFieldLikeJumpNode extends NonLocalJumpNode, ExprNode {
FieldLike fl;
FieldLikeRead flr;
FieldOrProperty fl;
FieldOrPropertyRead flr;
ExprNode succ;
StaticFieldLikeJumpNode() {
fl.isStatic() and
fl.isFieldLike() and
fl.getAnAssignedValue() = this.getExpr() and
fl.getAnAccess() = flr and
flr = succ.getExpr() and
hasNonlocalValue(flr)
flr.hasNonlocalValue()
}
override ExprNode getAJumpSuccessor(boolean preservesValue) {
@@ -1306,41 +1509,6 @@ private class StaticFieldLikeJumpNode extends NonLocalJumpNode, ExprNode {
predicate jumpStep = jumpStepImpl/2;
/**
* A reference contained in an object. Currently limited to instance fields
* and field-like instance properties.
*/
class Content extends TContent {
/** Gets a textual representation of this content. */
abstract string toString();
abstract Location getLocation();
/** Gets the type of the object containing this content. */
abstract DataFlowType getContainerType();
/** Gets the type of this content. */
abstract DataFlowType getType();
}
private class FieldLikeContent extends Content, TFieldLikeContent {
private FieldLike f;
FieldLikeContent() { this = TFieldLikeContent(f) }
FieldLike getField() { result = f }
override string toString() { result = f.toString() }
override Location getLocation() { result = f.getLocation() }
override DataFlowType getContainerType() {
result = Gvn::getGlobalValueNumber(f.getDeclaringType())
}
override DataFlowType getType() { result = Gvn::getGlobalValueNumber(f.getType()) }
}
private class StoreStepConfiguration extends ControlFlowReachabilityConfiguration {
StoreStepConfiguration() { this = "StoreStepConfiguration" }
@@ -1349,11 +1517,11 @@ private class StoreStepConfiguration extends ControlFlowReachabilityConfiguratio
) {
exactScope = false and
isSuccessor = false and
instanceFieldLikeAssign(scope, _, e1, e2)
fieldOrPropertyAssign(scope, _, e1, e2)
or
exactScope = false and
isSuccessor = false and
instanceFieldLikeInit(e2, _, e1) and
fieldOrPropertyInit(e2, _, e1) and
scope = e2
}
}
@@ -1368,7 +1536,7 @@ private class ReadStepConfiguration extends ControlFlowReachabilityConfiguration
) {
exactScope = false and
isSuccessor = true and
e1 = e2.(FieldLikeRead).getQualifier() and
fieldOrPropertyRead(e1, _, e2) and
scope = e2
}
}
@@ -1432,7 +1600,7 @@ private module PostUpdateNodes {
override MallocNode getPreUpdateNode() { this = TExprNode(result.getControlFlowNode()) }
}
private class ExprPostUpdateNode extends PostUpdateNode, TExprPostUpdateNode {
class ExprPostUpdateNode extends PostUpdateNode, TExprPostUpdateNode {
private ControlFlow::Nodes::ElementNode cfn;
ExprPostUpdateNode() { this = TExprPostUpdateNode(cfn) }
@@ -1508,3 +1676,6 @@ int accessPathLimit() { result = 3 }
* This predicate is only used for consistency checks.
*/
predicate isImmutableOrUnobservable(Node n) { none() }
pragma[inline]
DataFlowType getErasedRepr(DataFlowType t) { result = t }

View File

@@ -5,6 +5,7 @@ private import DataFlowDispatch
private import DataFlowPrivate
private import semmle.code.csharp.Caching
private import semmle.code.csharp.controlflow.Guards
private import semmle.code.csharp.Unification
/**
* An element, viewed as a node in a data flow graph. Either an expression
@@ -40,8 +41,17 @@ class Node extends TNode {
cached
DotNet::Type getType() { none() }
/** Gets an upper bound on the type of this node. */
DotNet::Type getTypeBound() { result = this.getType() } // stub implementation
/** INTERNAL: Do not use. Gets an upper bound on the type of this node. */
cached
DataFlowType getTypeBound() {
Stages::DataFlowStage::forceCachingInSameStage() and
exists(Type t0 | result = Gvn::getGlobalValueNumber(t0) |
t0 = getCSharpType(this.getType())
or
not exists(getCSharpType(this.getType())) and
t0 instanceof ObjectType
)
}
/** Gets the enclosing callable of this node. */
cached
@@ -136,8 +146,7 @@ class ParameterNode extends Node {
this.(SsaDefinitionNode).getDefinition() instanceof
ImplicitCapturedParameterNodeImpl::SsaCapturedEntryDefinition or
this = TInstanceParameterNode(_) or
this = TCilParameterNode(_) or
this = TTaintedParameterNode(_)
this = TCilParameterNode(_)
}
/** Gets the parameter corresponding to this node, if any. */
@@ -231,3 +240,60 @@ class BarrierGuard extends Guard {
)
}
}
/**
* A reference contained in an object. This is either a field or a property.
*/
class Content extends TContent {
/** Gets a textual representation of this content. */
string toString() { none() }
/** Gets the location of this content. */
Location getLocation() { none() }
/** Gets the type of the object containing this content. */
DataFlowType getContainerType() { none() }
/** Gets the type of this content. */
DataFlowType getType() { none() }
}
/** A reference to a field. */
class FieldContent extends Content, TFieldContent {
private Field f;
FieldContent() { this = TFieldContent(f) }
/** Gets the field that is referenced. */
Field getField() { result = f }
override string toString() { result = f.toString() }
override Location getLocation() { result = f.getLocation() }
override DataFlowType getContainerType() {
result = Gvn::getGlobalValueNumber(f.getDeclaringType())
}
override DataFlowType getType() { result = Gvn::getGlobalValueNumber(f.getType()) }
}
/** A reference to a property. */
class PropertyContent extends Content, TPropertyContent {
private Property p;
PropertyContent() { this = TPropertyContent(p) }
/** Gets the property that is referenced. */
Property getProperty() { result = p }
override string toString() { result = p.toString() }
override Location getLocation() { result = p.getLocation() }
override DataFlowType getContainerType() {
result = Gvn::getGlobalValueNumber(p.getDeclaringType())
}
override DataFlowType getType() { result = Gvn::getGlobalValueNumber(p.getType()) }
}

View File

@@ -118,6 +118,9 @@ library class DelegateArgumentToLibraryCallable extends Expr {
/** Gets the call that this argument belongs to. */
Call getCall() { result = call }
/** Gets the index of this delegate argument in the call. */
int getArgumentIndex() { this = this.getCall().getArgument(result) }
/** Gets the delegate type of this argument. */
DelegateType getDelegateType() { result = dt }

View File

@@ -45,9 +45,6 @@ private class LocalTaintExprStepConfiguration extends ControlFlowReachabilityCon
) {
exactScope = false and
(
// Taint propagation using library code
LocalFlow::libraryFlow(e1, e2, scope, isSuccessor, false)
or
// Taint from assigned value to element qualifier (`x[i] = 0`)
exists(AssignExpr ae |
e1 = ae.getRValue() and
@@ -162,11 +159,7 @@ module Cached {
Stages::DataFlowStage::forceCachingInSameStage() and
any(LocalTaintExprStepConfiguration x).hasNodePath(nodeFrom, nodeTo)
or
nodeTo = nodeFrom.(TaintedParameterNode).getUnderlyingNode()
or
nodeFrom = nodeTo.(TaintedReturnNode).getUnderlyingNode()
or
flowOutOfDelegateLibraryCall(nodeFrom, nodeTo, false)
nodeFrom = nodeTo.(YieldReturnNode).getPreUpdateNode()
or
localTaintStepCil(nodeFrom, nodeTo)
or
@@ -180,7 +173,13 @@ module Cached {
access.(PropertyRead).getQualifier() = nodeFrom.asExpr()
)
or
flowThroughLibraryCallableOutRef(_, nodeFrom, nodeTo, false)
exists(LibraryCodeNode n | not n.preservesValue() |
n = nodeTo and
nodeFrom = n.getPredecessor(AccessPath::empty())
or
n = nodeFrom and
nodeTo = n.getSuccessor(AccessPath::empty())
)
}
}

View File

@@ -566,10 +566,10 @@ class IndexerAccess extends AssignableMemberAccess, ElementAccess, IndexerAccess
* }
* ```
*/
class IndexerRead extends IndexerAccess, AssignableRead {
override IndexerRead getANextRead() { result = AssignableRead.super.getANextRead() }
class IndexerRead extends IndexerAccess, ElementRead {
override IndexerRead getANextRead() { result = ElementRead.super.getANextRead() }
override IndexerRead getAReachableRead() { result = AssignableRead.super.getAReachableRead() }
override IndexerRead getAReachableRead() { result = ElementRead.super.getAReachableRead() }
}
/**
@@ -586,7 +586,7 @@ class IndexerRead extends IndexerAccess, AssignableRead {
* }
* ```
*/
class IndexerWrite extends IndexerAccess, AssignableWrite { }
class IndexerWrite extends IndexerAccess, ElementWrite { }
/**
* An access to a virtual indexer - an indexer that is virtual or defined in
@@ -818,7 +818,7 @@ class ArrayAccess extends ElementAccess, @array_access_expr {
* }
* ```
*/
class ArrayRead extends ArrayAccess, AssignableRead { }
class ArrayRead extends ArrayAccess, ElementRead { }
/**
* An access to an array that updates the underlying value, for example
@@ -830,7 +830,7 @@ class ArrayRead extends ArrayAccess, AssignableRead { }
* }
* ```
*/
class ArrayWrite extends ArrayAccess, AssignableWrite { }
class ArrayWrite extends ArrayAccess, ElementWrite { }
/**
* An access to a namespace, for example `System` in `nameof(System)`.

View File

@@ -3,7 +3,7 @@
*/
import csharp
import semmle.code.csharp.dataflow.LibraryTypeDataFlow
private import semmle.code.csharp.dataflow.LibraryTypeDataFlow
/** Definitions relating to the `Json.NET` package. */
module JsonNET {

View File

@@ -101,23 +101,24 @@ class IRBlock extends IRBlockBase {
private predicate startsBasicBlock(Instruction instr) {
not instr instanceof PhiInstruction and
(
count(Instruction predecessor | instr = predecessor.getASuccessor()) != 1 // Multiple predecessors or no predecessor
or
exists(Instruction predecessor |
instr = predecessor.getASuccessor() and
strictcount(Instruction other | other = predecessor.getASuccessor()) > 1
) // Predecessor has multiple successors
or
exists(Instruction predecessor, EdgeKind kind |
instr = predecessor.getSuccessor(kind) and
not kind instanceof GotoEdge
) // Incoming edge is not a GotoEdge
or
exists(Instruction predecessor |
instr = Construction::getInstructionBackEdgeSuccessor(predecessor, _)
) // A back edge enters this instruction
)
not adjacentInBlock(_, instr)
}
/** Holds if `i2` follows `i1` in a `IRBlock`. */
private predicate adjacentInBlock(Instruction i1, Instruction i2) {
// - i2 must be the only successor of i1
i2 = unique(Instruction i | i = i1.getASuccessor()) and
// - i1 must be the only predecessor of i2
i1 = unique(Instruction i | i.getASuccessor() = i2) and
// - The edge between the two must be a GotoEdge. We just check that one
// exists since we've already checked that it's unique.
exists(GotoEdge edgeKind | exists(i1.getSuccessor(edgeKind))) and
// - The edge must not be a back edge. This means we get the same back edges
// in the basic-block graph as we do in the raw CFG.
not exists(Construction::getInstructionBackEdgeSuccessor(i1, _))
// This predicate could be simplified to remove one of the `unique`s if we
// were willing to rely on the CFG being well-formed and thus never having
// more than one successor to an instruction that has a `GotoEdge` out of it.
}
private predicate isEntryBlock(TIRBlock block) {
@@ -129,12 +130,6 @@ private module Cached {
cached
newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) }
/** Holds if `i2` follows `i1` in a `IRBlock`. */
private predicate adjacentInBlock(Instruction i1, Instruction i2) {
exists(GotoEdge edgeKind | i2 = i1.getSuccessor(edgeKind)) and
not startsBasicBlock(i2)
}
/** Holds if `i` is the `index`th instruction the block starting with `first`. */
private Instruction getInstructionFromFirst(Instruction first, int index) =
shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index)

View File

@@ -190,14 +190,15 @@ class Instruction extends Construction::TInstruction {
final Language::Location getLocation() { result = getAST().getLocation() }
/**
* Gets the `Expr` whose result is computed by this instruction, if any.
* Gets the `Expr` whose result is computed by this instruction, if any. The `Expr` may be a
* conversion.
*/
final Language::Expr getConvertedResultExpression() {
result = Construction::getInstructionConvertedResultExpression(this)
}
/**
* Gets the unconverted `Expr` whose result is computed by this instruction, if any.
* Gets the unconverted form of the `Expr` whose result is computed by this instruction, if any.
*/
final Language::Expr getUnconvertedResultExpression() {
result = Construction::getInstructionUnconvertedResultExpression(this)

View File

@@ -101,23 +101,24 @@ class IRBlock extends IRBlockBase {
private predicate startsBasicBlock(Instruction instr) {
not instr instanceof PhiInstruction and
(
count(Instruction predecessor | instr = predecessor.getASuccessor()) != 1 // Multiple predecessors or no predecessor
or
exists(Instruction predecessor |
instr = predecessor.getASuccessor() and
strictcount(Instruction other | other = predecessor.getASuccessor()) > 1
) // Predecessor has multiple successors
or
exists(Instruction predecessor, EdgeKind kind |
instr = predecessor.getSuccessor(kind) and
not kind instanceof GotoEdge
) // Incoming edge is not a GotoEdge
or
exists(Instruction predecessor |
instr = Construction::getInstructionBackEdgeSuccessor(predecessor, _)
) // A back edge enters this instruction
)
not adjacentInBlock(_, instr)
}
/** Holds if `i2` follows `i1` in a `IRBlock`. */
private predicate adjacentInBlock(Instruction i1, Instruction i2) {
// - i2 must be the only successor of i1
i2 = unique(Instruction i | i = i1.getASuccessor()) and
// - i1 must be the only predecessor of i2
i1 = unique(Instruction i | i.getASuccessor() = i2) and
// - The edge between the two must be a GotoEdge. We just check that one
// exists since we've already checked that it's unique.
exists(GotoEdge edgeKind | exists(i1.getSuccessor(edgeKind))) and
// - The edge must not be a back edge. This means we get the same back edges
// in the basic-block graph as we do in the raw CFG.
not exists(Construction::getInstructionBackEdgeSuccessor(i1, _))
// This predicate could be simplified to remove one of the `unique`s if we
// were willing to rely on the CFG being well-formed and thus never having
// more than one successor to an instruction that has a `GotoEdge` out of it.
}
private predicate isEntryBlock(TIRBlock block) {
@@ -129,12 +130,6 @@ private module Cached {
cached
newtype TIRBlock = MkIRBlock(Instruction firstInstr) { startsBasicBlock(firstInstr) }
/** Holds if `i2` follows `i1` in a `IRBlock`. */
private predicate adjacentInBlock(Instruction i1, Instruction i2) {
exists(GotoEdge edgeKind | i2 = i1.getSuccessor(edgeKind)) and
not startsBasicBlock(i2)
}
/** Holds if `i` is the `index`th instruction the block starting with `first`. */
private Instruction getInstructionFromFirst(Instruction first, int index) =
shortestDistances(startsBasicBlock/1, adjacentInBlock/2)(first, result, index)

View File

@@ -190,14 +190,15 @@ class Instruction extends Construction::TInstruction {
final Language::Location getLocation() { result = getAST().getLocation() }
/**
* Gets the `Expr` whose result is computed by this instruction, if any.
* Gets the `Expr` whose result is computed by this instruction, if any. The `Expr` may be a
* conversion.
*/
final Language::Expr getConvertedResultExpression() {
result = Construction::getInstructionConvertedResultExpression(this)
}
/**
* Gets the unconverted `Expr` whose result is computed by this instruction, if any.
* Gets the unconverted form of the `Expr` whose result is computed by this instruction, if any.
*/
final Language::Expr getUnconvertedResultExpression() {
result = Construction::getInstructionUnconvertedResultExpression(this)

View File

@@ -7,18 +7,15 @@
| CSharp7.cs:17:9:17:11 | this | CSharp7.cs:17:18:17:22 | this access |
| CSharp7.cs:21:9:21:11 | this | CSharp7.cs:21:16:21:20 | this access |
| CSharp7.cs:22:9:22:11 | this | CSharp7.cs:22:16:22:20 | this access |
| CSharp7.cs:22:9:22:11 | value | CSharp7.cs:22:9:22:11 | value |
| CSharp7.cs:22:9:22:11 | value | CSharp7.cs:22:24:22:28 | access to parameter value |
| CSharp7.cs:25:5:25:27 | this | CSharp7.cs:16:9:16:13 | this access |
| CSharp7.cs:26:6:26:28 | this | CSharp7.cs:26:35:26:39 | this access |
| CSharp7.cs:31:19:31:19 | i | CSharp7.cs:31:19:31:19 | i |
| CSharp7.cs:31:19:31:19 | i | CSharp7.cs:33:16:33:16 | access to parameter i |
| CSharp7.cs:33:16:33:16 | access to parameter i | CSharp7.cs:33:16:33:20 | ... > ... |
| CSharp7.cs:33:16:33:16 | access to parameter i | CSharp7.cs:33:24:33:24 | access to parameter i |
| CSharp7.cs:33:24:33:24 | access to parameter i | CSharp7.cs:33:16:33:59 | ... ? ... : ... |
| CSharp7.cs:33:28:33:59 | throw ... | CSharp7.cs:33:16:33:59 | ... ? ... : ... |
| CSharp7.cs:41:13:41:21 | "tainted" | CSharp7.cs:41:9:41:21 | SSA def(x) |
| CSharp7.cs:44:19:44:19 | x | CSharp7.cs:44:19:44:19 | x |
| CSharp7.cs:44:19:44:19 | x | CSharp7.cs:46:13:46:13 | access to parameter x |
| CSharp7.cs:46:13:46:13 | access to parameter x | CSharp7.cs:46:9:46:13 | SSA def(y) |
| CSharp7.cs:49:10:49:10 | this | CSharp7.cs:51:9:51:24 | this access |
@@ -65,7 +62,6 @@
| CSharp7.cs:78:31:78:31 | access to local variable a | CSharp7.cs:78:27:78:32 | (..., ...) |
| CSharp7.cs:79:23:79:24 | "" | CSharp7.cs:79:22:79:28 | (..., ...) |
| CSharp7.cs:79:27:79:27 | access to local variable x | CSharp7.cs:79:22:79:28 | (..., ...) |
| CSharp7.cs:82:21:82:21 | x | CSharp7.cs:82:21:82:21 | x |
| CSharp7.cs:82:21:82:21 | x | CSharp7.cs:84:20:84:20 | access to parameter x |
| CSharp7.cs:84:16:84:24 | (..., ...) | CSharp7.cs:84:16:84:26 | access to field a |
| CSharp7.cs:84:20:84:20 | access to parameter x | CSharp7.cs:84:16:84:24 | (..., ...) |
@@ -116,19 +112,15 @@
| CSharp7.cs:119:19:119:20 | access to local variable m2 | CSharp7.cs:119:19:119:26 | access to field Item1 |
| CSharp7.cs:123:28:123:36 | "DefUse3" | CSharp7.cs:123:22:123:36 | ... = ... |
| CSharp7.cs:129:9:129:12 | this | CSharp7.cs:135:24:135:25 | this access |
| CSharp7.cs:131:20:131:20 | x | CSharp7.cs:131:20:131:20 | x |
| CSharp7.cs:131:20:131:20 | x | CSharp7.cs:131:32:131:32 | access to parameter x |
| CSharp7.cs:131:32:131:32 | access to parameter x | CSharp7.cs:131:32:131:36 | ... + ... |
| CSharp7.cs:131:36:131:36 | 1 | CSharp7.cs:131:32:131:36 | ... + ... |
| CSharp7.cs:133:22:133:22 | t | CSharp7.cs:133:22:133:22 | t |
| CSharp7.cs:133:22:133:22 | t | CSharp7.cs:133:39:133:39 | access to parameter t |
| CSharp7.cs:135:24:135:25 | this access | CSharp7.cs:155:16:155:17 | this access |
| CSharp7.cs:139:29:139:29 | x | CSharp7.cs:139:29:139:29 | x |
| CSharp7.cs:139:29:139:29 | x | CSharp7.cs:139:34:139:34 | access to parameter x |
| CSharp7.cs:139:34:139:34 | access to parameter x | CSharp7.cs:139:34:139:38 | ... + ... |
| CSharp7.cs:139:38:139:38 | 1 | CSharp7.cs:139:34:139:38 | ... + ... |
| CSharp7.cs:141:9:141:51 | this | CSharp7.cs:141:38:141:39 | this access |
| CSharp7.cs:141:20:141:20 | x | CSharp7.cs:141:20:141:20 | x |
| CSharp7.cs:141:20:141:20 | x | CSharp7.cs:141:26:141:26 | access to parameter x |
| CSharp7.cs:141:26:141:26 | access to parameter x | CSharp7.cs:141:26:141:30 | ... > ... |
| CSharp7.cs:141:26:141:26 | access to parameter x | CSharp7.cs:141:41:141:41 | access to parameter x |
@@ -137,17 +129,13 @@
| CSharp7.cs:141:38:141:46 | call to local function f7 | CSharp7.cs:141:34:141:46 | ... + ... |
| CSharp7.cs:141:50:141:50 | 0 | CSharp7.cs:141:26:141:50 | ... ? ... : ... |
| CSharp7.cs:143:9:143:31 | this | CSharp7.cs:143:26:143:27 | this access |
| CSharp7.cs:143:20:143:20 | x | CSharp7.cs:143:20:143:20 | x |
| CSharp7.cs:143:20:143:20 | x | CSharp7.cs:143:29:143:29 | access to parameter x |
| CSharp7.cs:145:9:149:9 | this | CSharp7.cs:148:20:148:21 | this access |
| CSharp7.cs:147:13:147:35 | this | CSharp7.cs:147:30:147:31 | this access |
| CSharp7.cs:147:24:147:24 | x | CSharp7.cs:147:24:147:24 | x |
| CSharp7.cs:147:24:147:24 | x | CSharp7.cs:147:33:147:33 | access to parameter x |
| CSharp7.cs:158:10:158:17 | this | CSharp7.cs:170:9:170:9 | this access |
| CSharp7.cs:161:18:161:18 | t | CSharp7.cs:161:18:161:18 | t |
| CSharp7.cs:161:18:161:18 | t | CSharp7.cs:161:24:161:24 | access to parameter t |
| CSharp7.cs:163:9:168:9 | this | CSharp7.cs:166:13:166:16 | this access |
| CSharp7.cs:163:26:163:26 | u | CSharp7.cs:163:26:163:26 | u |
| CSharp7.cs:163:26:163:26 | u | CSharp7.cs:167:22:167:22 | access to parameter u |
| CSharp7.cs:165:13:165:43 | this | CSharp7.cs:165:37:165:40 | this access |
| CSharp7.cs:166:13:166:16 | this access | CSharp7.cs:167:20:167:20 | this access |
@@ -156,13 +144,10 @@
| CSharp7.cs:176:16:176:30 | SSA def(src) | CSharp7.cs:181:23:181:25 | access to local variable src |
| CSharp7.cs:176:22:176:30 | "tainted" | CSharp7.cs:176:16:176:30 | SSA def(src) |
| CSharp7.cs:177:9:177:40 | this | CSharp7.cs:177:31:177:31 | this access |
| CSharp7.cs:177:25:177:25 | s | CSharp7.cs:177:25:177:25 | s |
| CSharp7.cs:177:25:177:25 | s | CSharp7.cs:177:33:177:33 | access to parameter s |
| CSharp7.cs:177:31:177:34 | call to local function g | CSharp7.cs:177:31:177:39 | ... + ... |
| CSharp7.cs:177:38:177:39 | "" | CSharp7.cs:177:31:177:39 | ... + ... |
| CSharp7.cs:178:25:178:25 | s | CSharp7.cs:178:25:178:25 | s |
| CSharp7.cs:178:25:178:25 | s | CSharp7.cs:178:31:178:31 | access to parameter s |
| CSharp7.cs:179:25:179:25 | s | CSharp7.cs:179:25:179:25 | s |
| CSharp7.cs:179:25:179:25 | s | CSharp7.cs:179:37:179:37 | access to parameter s |
| CSharp7.cs:181:21:181:21 | this access | CSharp7.cs:182:21:182:21 | this access |
| CSharp7.cs:181:23:181:25 | [post] access to local variable src | CSharp7.cs:182:23:182:25 | access to local variable src |
@@ -189,9 +174,7 @@
| CSharp7.cs:199:26:199:35 | [post] this access | CSharp7.cs:200:9:200:18 | this access |
| CSharp7.cs:199:26:199:35 | this access | CSharp7.cs:200:9:200:18 | this access |
| CSharp7.cs:199:33:199:34 | access to local variable r1 | CSharp7.cs:200:16:200:17 | access to local variable r1 |
| CSharp7.cs:203:24:203:24 | p | CSharp7.cs:203:24:203:24 | p |
| CSharp7.cs:203:24:203:24 | p | CSharp7.cs:206:20:206:20 | access to parameter p |
| CSharp7.cs:205:28:205:28 | q | CSharp7.cs:205:28:205:28 | q |
| CSharp7.cs:205:28:205:28 | q | CSharp7.cs:205:44:205:44 | access to parameter q |
| CSharp7.cs:216:13:216:17 | false | CSharp7.cs:216:9:216:17 | SSA def(x) |
| CSharp7.cs:217:17:217:17 | 0 | CSharp7.cs:217:16:217:23 | (..., ...) |
@@ -248,13 +231,16 @@
| CSharp7.cs:283:13:283:48 | SSA def(dict) | CSharp7.cs:284:20:284:23 | access to local variable dict |
| CSharp7.cs:283:20:283:48 | object creation of type Dictionary<Int32,String> | CSharp7.cs:283:13:283:48 | SSA def(dict) |
| CSharp7.cs:284:13:284:62 | SSA def(list) | CSharp7.cs:286:39:286:42 | access to local variable list |
| CSharp7.cs:284:20:284:23 | access to local variable dict | CSharp7.cs:284:20:284:62 | [library code] call to method Select |
| CSharp7.cs:284:20:284:62 | [library code] call to method Select | CSharp7.cs:284:20:284:62 | call to method Select |
| CSharp7.cs:284:20:284:62 | [library code] call to method Select | CSharp7.cs:284:32:284:61 | [implicit argument 0] (...) => ... |
| CSharp7.cs:284:20:284:62 | call to method Select | CSharp7.cs:284:13:284:62 | SSA def(list) |
| CSharp7.cs:284:32:284:35 | item | CSharp7.cs:284:32:284:35 | item |
| CSharp7.cs:284:32:284:35 | item | CSharp7.cs:284:41:284:44 | access to parameter item |
| CSharp7.cs:284:32:284:61 | [output] (...) => ... | CSharp7.cs:284:20:284:62 | call to method Select |
| CSharp7.cs:284:32:284:61 | [output] (...) => ... | CSharp7.cs:284:20:284:62 | [library code] call to method Select |
| CSharp7.cs:284:41:284:44 | access to parameter item | CSharp7.cs:284:51:284:54 | access to parameter item |
| CSharp7.cs:284:41:284:48 | access to property Key | CSharp7.cs:284:40:284:61 | (..., ...) |
| CSharp7.cs:284:51:284:54 | access to parameter item | CSharp7.cs:284:51:284:60 | access to property Value |
| CSharp7.cs:284:51:284:54 | access to parameter item | CSharp7.cs:284:51:284:60 | [library code] access to property Value |
| CSharp7.cs:284:51:284:60 | [library code] access to property Value | CSharp7.cs:284:51:284:60 | access to property Value |
| CSharp7.cs:284:51:284:60 | access to property Value | CSharp7.cs:284:40:284:61 | (..., ...) |
| CSharp7.cs:286:39:286:42 | access to local variable list | CSharp7.cs:288:36:288:39 | access to local variable list |
| CSharp7.cs:288:36:288:39 | access to local variable list | CSharp7.cs:290:32:290:35 | access to local variable list |

View File

@@ -149,7 +149,10 @@ edges
| GlobalDataFlow.cs:163:22:163:43 | call to method TaintedParam : String | GlobalDataFlow.cs:164:15:164:20 | access to local variable sink23 |
| GlobalDataFlow.cs:179:35:179:48 | "taint source" : String | GlobalDataFlow.cs:180:21:180:26 | delegate call : String |
| GlobalDataFlow.cs:180:21:180:26 | delegate call : String | GlobalDataFlow.cs:181:15:181:19 | access to local variable sink9 |
| GlobalDataFlow.cs:189:39:189:41 | [output] delegate creation of type Func<String> : String | GlobalDataFlow.cs:190:15:190:20 | access to local variable sink10 |
| GlobalDataFlow.cs:189:22:189:42 | [library code] object creation of type Lazy<String> : String | GlobalDataFlow.cs:189:22:189:42 | object creation of type Lazy<String> [Value] : String |
| GlobalDataFlow.cs:189:22:189:42 | object creation of type Lazy<String> [Value] : String | GlobalDataFlow.cs:189:22:189:48 | access to property Value : String |
| GlobalDataFlow.cs:189:22:189:48 | access to property Value : String | GlobalDataFlow.cs:190:15:190:20 | access to local variable sink10 |
| GlobalDataFlow.cs:189:39:189:41 | [output] delegate creation of type Func<String> : String | GlobalDataFlow.cs:189:22:189:42 | [library code] object creation of type Lazy<String> : String |
| GlobalDataFlow.cs:197:22:197:32 | access to property OutProperty : String | GlobalDataFlow.cs:198:15:198:20 | access to local variable sink19 |
| GlobalDataFlow.cs:236:26:236:35 | sinkParam0 : String | GlobalDataFlow.cs:238:16:238:25 | access to parameter sinkParam0 : String |
| GlobalDataFlow.cs:236:26:236:35 | sinkParam0 : String | GlobalDataFlow.cs:239:15:239:24 | access to parameter sinkParam0 |
@@ -300,6 +303,9 @@ nodes
| GlobalDataFlow.cs:179:35:179:48 | "taint source" : String | semmle.label | "taint source" : String |
| GlobalDataFlow.cs:180:21:180:26 | delegate call : String | semmle.label | delegate call : String |
| GlobalDataFlow.cs:181:15:181:19 | access to local variable sink9 | semmle.label | access to local variable sink9 |
| GlobalDataFlow.cs:189:22:189:42 | [library code] object creation of type Lazy<String> : String | semmle.label | [library code] object creation of type Lazy<String> : String |
| GlobalDataFlow.cs:189:22:189:42 | object creation of type Lazy<String> [Value] : String | semmle.label | object creation of type Lazy<String> [Value] : String |
| GlobalDataFlow.cs:189:22:189:48 | access to property Value : String | semmle.label | access to property Value : String |
| GlobalDataFlow.cs:189:39:189:41 | [output] delegate creation of type Func<String> : String | semmle.label | [output] delegate creation of type Func<String> : String |
| GlobalDataFlow.cs:190:15:190:20 | access to local variable sink10 | semmle.label | access to local variable sink10 |
| GlobalDataFlow.cs:197:22:197:32 | access to property OutProperty : String | semmle.label | access to property OutProperty : String |

View File

@@ -142,22 +142,28 @@ edges
| GlobalDataFlow.cs:80:22:80:85 | call to method SelectEven : IEnumerable<T> | GlobalDataFlow.cs:81:15:81:20 | access to local variable sink13 |
| GlobalDataFlow.cs:80:22:80:85 | call to method SelectEven : IEnumerable<T> | GlobalDataFlow.cs:82:23:82:66 | (...) ... : String[] |
| GlobalDataFlow.cs:80:23:80:65 | (...) ... : String[] | GlobalDataFlow.cs:80:22:80:85 | call to method SelectEven : IEnumerable<T> |
| GlobalDataFlow.cs:82:23:82:66 | (...) ... : String[] | GlobalDataFlow.cs:82:76:82:86 | [output] delegate creation of type Func<String,String> : T |
| GlobalDataFlow.cs:82:23:82:66 | (...) ... : String[] | GlobalDataFlow.cs:294:31:294:40 | sinkParam8 : String[] |
| GlobalDataFlow.cs:82:76:82:86 | [output] delegate creation of type Func<String,String> : T | GlobalDataFlow.cs:83:15:83:20 | access to local variable sink14 |
| GlobalDataFlow.cs:82:76:82:86 | [output] delegate creation of type Func<String,String> : T | GlobalDataFlow.cs:84:23:84:66 | (...) ... : String[] |
| GlobalDataFlow.cs:82:76:82:86 | [output] delegate creation of type Func<String,String> : T | GlobalDataFlow.cs:88:23:88:66 | (...) ... : String[] |
| GlobalDataFlow.cs:82:76:82:86 | [output] delegate creation of type Func<String,String> : T | GlobalDataFlow.cs:90:75:90:80 | access to local variable sink14 : String |
| GlobalDataFlow.cs:84:23:84:66 | (...) ... : String[] | GlobalDataFlow.cs:84:117:84:127 | [output] (...) => ... : String |
| GlobalDataFlow.cs:82:23:82:66 | (...) ... : String[] | GlobalDataFlow.cs:82:76:82:86 | [implicit argument 0] delegate creation of type Func<String,String> : String |
| GlobalDataFlow.cs:82:76:82:86 | [implicit argument 0] delegate creation of type Func<String,String> : String | GlobalDataFlow.cs:82:76:82:86 | [output] delegate creation of type Func<String,String> : String |
| GlobalDataFlow.cs:82:76:82:86 | [implicit argument 0] delegate creation of type Func<String,String> : String | GlobalDataFlow.cs:294:31:294:40 | sinkParam8 : String |
| GlobalDataFlow.cs:82:76:82:86 | [output] delegate creation of type Func<String,String> : String | GlobalDataFlow.cs:83:15:83:20 | access to local variable sink14 |
| GlobalDataFlow.cs:82:76:82:86 | [output] delegate creation of type Func<String,String> : String | GlobalDataFlow.cs:84:23:84:66 | (...) ... : String[] |
| GlobalDataFlow.cs:82:76:82:86 | [output] delegate creation of type Func<String,String> : String | GlobalDataFlow.cs:88:23:88:66 | (...) ... : String[] |
| GlobalDataFlow.cs:82:76:82:86 | [output] delegate creation of type Func<String,String> : String | GlobalDataFlow.cs:90:83:90:101 | [implicit argument 0] (...) => ... : String |
| GlobalDataFlow.cs:84:23:84:66 | (...) ... : String[] | GlobalDataFlow.cs:84:117:84:127 | [implicit argument 0] (...) => ... : String |
| GlobalDataFlow.cs:84:117:84:127 | [implicit argument 0] (...) => ... : String | GlobalDataFlow.cs:84:117:84:127 | [output] (...) => ... : String |
| GlobalDataFlow.cs:84:117:84:127 | [output] (...) => ... : String | GlobalDataFlow.cs:85:15:85:20 | access to local variable sink15 |
| GlobalDataFlow.cs:84:117:84:127 | [output] (...) => ... : String | GlobalDataFlow.cs:86:70:86:113 | (...) ... : String[] |
| GlobalDataFlow.cs:86:70:86:113 | (...) ... : String[] | GlobalDataFlow.cs:86:117:86:127 | [output] (...) => ... : String |
| GlobalDataFlow.cs:86:70:86:113 | (...) ... : String[] | GlobalDataFlow.cs:86:117:86:127 | [implicit argument 1] (...) => ... : String |
| GlobalDataFlow.cs:86:117:86:127 | [implicit argument 1] (...) => ... : String | GlobalDataFlow.cs:86:117:86:127 | [output] (...) => ... : String |
| GlobalDataFlow.cs:86:117:86:127 | [output] (...) => ... : String | GlobalDataFlow.cs:87:15:87:20 | access to local variable sink16 |
| GlobalDataFlow.cs:88:23:88:66 | (...) ... : String[] | GlobalDataFlow.cs:88:83:88:101 | [output] (...) => ... : String |
| GlobalDataFlow.cs:88:83:88:101 | [output] (...) => ... : String | GlobalDataFlow.cs:88:104:88:109 | [output] (...) => ... : String |
| GlobalDataFlow.cs:88:23:88:66 | (...) ... : String[] | GlobalDataFlow.cs:88:83:88:101 | [implicit argument 1] (...) => ... : String |
| GlobalDataFlow.cs:88:83:88:101 | [implicit argument 1] (...) => ... : String | GlobalDataFlow.cs:88:83:88:101 | [output] (...) => ... : String |
| GlobalDataFlow.cs:88:83:88:101 | [output] (...) => ... : String | GlobalDataFlow.cs:88:104:88:109 | [implicit argument 0] (...) => ... : String |
| GlobalDataFlow.cs:88:104:88:109 | [implicit argument 0] (...) => ... : String | GlobalDataFlow.cs:88:104:88:109 | [output] (...) => ... : String |
| GlobalDataFlow.cs:88:104:88:109 | [output] (...) => ... : String | GlobalDataFlow.cs:89:15:89:20 | access to local variable sink17 |
| GlobalDataFlow.cs:90:75:90:80 | access to local variable sink14 : String | GlobalDataFlow.cs:90:83:90:101 | [output] (...) => ... : String |
| GlobalDataFlow.cs:90:83:90:101 | [output] (...) => ... : String | GlobalDataFlow.cs:90:104:90:109 | [output] (...) => ... : String |
| GlobalDataFlow.cs:90:83:90:101 | [implicit argument 0] (...) => ... : String | GlobalDataFlow.cs:90:83:90:101 | [output] (...) => ... : String |
| GlobalDataFlow.cs:90:83:90:101 | [output] (...) => ... : String | GlobalDataFlow.cs:90:104:90:109 | [implicit argument 0] (...) => ... : String |
| GlobalDataFlow.cs:90:104:90:109 | [implicit argument 0] (...) => ... : String | GlobalDataFlow.cs:90:104:90:109 | [output] (...) => ... : String |
| GlobalDataFlow.cs:90:104:90:109 | [output] (...) => ... : String | GlobalDataFlow.cs:91:15:91:20 | access to local variable sink18 |
| GlobalDataFlow.cs:90:104:90:109 | [output] (...) => ... : String | GlobalDataFlow.cs:94:15:94:20 | access to local variable sink21 |
| GlobalDataFlow.cs:90:104:90:109 | [output] (...) => ... : String | GlobalDataFlow.cs:97:15:97:20 | access to local variable sink22 |
@@ -173,23 +179,26 @@ edges
| GlobalDataFlow.cs:163:22:163:43 | call to method TaintedParam : String | GlobalDataFlow.cs:164:15:164:20 | access to local variable sink23 |
| GlobalDataFlow.cs:179:35:179:48 | "taint source" : String | GlobalDataFlow.cs:180:21:180:26 | delegate call : String |
| GlobalDataFlow.cs:180:21:180:26 | delegate call : String | GlobalDataFlow.cs:181:15:181:19 | access to local variable sink9 |
| GlobalDataFlow.cs:189:39:189:41 | [output] delegate creation of type Func<String> : String | GlobalDataFlow.cs:190:15:190:20 | access to local variable sink10 |
| GlobalDataFlow.cs:189:22:189:42 | [library code] object creation of type Lazy<String> : String | GlobalDataFlow.cs:189:22:189:42 | object creation of type Lazy<String> [Value] : String |
| GlobalDataFlow.cs:189:22:189:42 | object creation of type Lazy<String> [Value] : String | GlobalDataFlow.cs:189:22:189:48 | access to property Value : String |
| GlobalDataFlow.cs:189:22:189:48 | access to property Value : String | GlobalDataFlow.cs:190:15:190:20 | access to local variable sink10 |
| GlobalDataFlow.cs:189:39:189:41 | [output] delegate creation of type Func<String> : String | GlobalDataFlow.cs:189:22:189:42 | [library code] object creation of type Lazy<String> : String |
| GlobalDataFlow.cs:197:22:197:32 | access to property OutProperty : String | GlobalDataFlow.cs:198:15:198:20 | access to local variable sink19 |
| GlobalDataFlow.cs:207:46:207:59 | "taint source" : String | GlobalDataFlow.cs:212:22:212:28 | access to local variable tainted : IQueryable<String> |
| GlobalDataFlow.cs:207:46:207:59 | "taint source" : String | GlobalDataFlow.cs:214:22:214:28 | access to local variable tainted : IQueryable<String> |
| GlobalDataFlow.cs:207:46:207:59 | "taint source" : String | GlobalDataFlow.cs:216:22:216:28 | access to local variable tainted : IQueryable<String> |
| GlobalDataFlow.cs:210:35:210:45 | sinkParam10 : IQueryable<String> | GlobalDataFlow.cs:210:58:210:68 | access to parameter sinkParam10 |
| GlobalDataFlow.cs:211:71:211:71 | x : IQueryable<String> | GlobalDataFlow.cs:211:89:211:89 | access to parameter x : String |
| GlobalDataFlow.cs:207:46:207:59 | "taint source" : String | GlobalDataFlow.cs:212:37:212:38 | [implicit argument 0] access to local variable f1 : String |
| GlobalDataFlow.cs:207:46:207:59 | "taint source" : String | GlobalDataFlow.cs:214:37:214:38 | [implicit argument 0] access to local variable f2 : String |
| GlobalDataFlow.cs:207:46:207:59 | "taint source" : String | GlobalDataFlow.cs:216:37:216:48 | [implicit argument 0] delegate creation of type Func<String,String> : String |
| GlobalDataFlow.cs:210:35:210:45 | sinkParam10 : String | GlobalDataFlow.cs:210:58:210:68 | access to parameter sinkParam10 |
| GlobalDataFlow.cs:211:71:211:71 | x : String | GlobalDataFlow.cs:211:89:211:89 | access to parameter x : String |
| GlobalDataFlow.cs:211:89:211:89 | access to parameter x : String | GlobalDataFlow.cs:300:32:300:41 | sinkParam9 : String |
| GlobalDataFlow.cs:212:22:212:28 | access to local variable tainted : IQueryable<String> | GlobalDataFlow.cs:210:35:210:45 | sinkParam10 : IQueryable<String> |
| GlobalDataFlow.cs:212:22:212:28 | access to local variable tainted : IQueryable<String> | GlobalDataFlow.cs:212:37:212:38 | [output] access to local variable f1 : String |
| GlobalDataFlow.cs:212:37:212:38 | [implicit argument 0] access to local variable f1 : String | GlobalDataFlow.cs:210:35:210:45 | sinkParam10 : String |
| GlobalDataFlow.cs:212:37:212:38 | [implicit argument 0] access to local variable f1 : String | GlobalDataFlow.cs:212:37:212:38 | [output] access to local variable f1 : String |
| GlobalDataFlow.cs:212:37:212:38 | [output] access to local variable f1 : String | GlobalDataFlow.cs:213:15:213:20 | access to local variable sink24 |
| GlobalDataFlow.cs:214:22:214:28 | access to local variable tainted : IQueryable<String> | GlobalDataFlow.cs:211:71:211:71 | x : IQueryable<String> |
| GlobalDataFlow.cs:214:22:214:28 | access to local variable tainted : IQueryable<String> | GlobalDataFlow.cs:214:37:214:38 | [output] access to local variable f2 : String |
| GlobalDataFlow.cs:214:37:214:38 | [implicit argument 0] access to local variable f2 : String | GlobalDataFlow.cs:211:71:211:71 | x : String |
| GlobalDataFlow.cs:214:37:214:38 | [implicit argument 0] access to local variable f2 : String | GlobalDataFlow.cs:214:37:214:38 | [output] access to local variable f2 : String |
| GlobalDataFlow.cs:214:37:214:38 | [output] access to local variable f2 : String | GlobalDataFlow.cs:215:15:215:20 | access to local variable sink25 |
| GlobalDataFlow.cs:216:22:216:28 | access to local variable tainted : IQueryable<String> | GlobalDataFlow.cs:216:37:216:48 | [output] delegate creation of type Func<String,String> : T |
| GlobalDataFlow.cs:216:22:216:28 | access to local variable tainted : IQueryable<String> | GlobalDataFlow.cs:306:32:306:42 | sinkParam11 : IQueryable<String> |
| GlobalDataFlow.cs:216:37:216:48 | [output] delegate creation of type Func<String,String> : T | GlobalDataFlow.cs:217:15:217:20 | access to local variable sink26 |
| GlobalDataFlow.cs:216:37:216:48 | [implicit argument 0] delegate creation of type Func<String,String> : String | GlobalDataFlow.cs:216:37:216:48 | [output] delegate creation of type Func<String,String> : String |
| GlobalDataFlow.cs:216:37:216:48 | [implicit argument 0] delegate creation of type Func<String,String> : String | GlobalDataFlow.cs:306:32:306:42 | sinkParam11 : String |
| GlobalDataFlow.cs:216:37:216:48 | [output] delegate creation of type Func<String,String> : String | GlobalDataFlow.cs:217:15:217:20 | access to local variable sink26 |
| GlobalDataFlow.cs:236:26:236:35 | sinkParam0 : String | GlobalDataFlow.cs:238:16:238:25 | access to parameter sinkParam0 : String |
| GlobalDataFlow.cs:236:26:236:35 | sinkParam0 : String | GlobalDataFlow.cs:239:15:239:24 | access to parameter sinkParam0 |
| GlobalDataFlow.cs:238:16:238:25 | access to parameter sinkParam0 : String | GlobalDataFlow.cs:236:26:236:35 | sinkParam0 : String |
@@ -199,17 +208,17 @@ edges
| GlobalDataFlow.cs:257:26:257:35 | sinkParam5 : String | GlobalDataFlow.cs:259:15:259:24 | access to parameter sinkParam5 |
| GlobalDataFlow.cs:262:26:262:35 | sinkParam6 : String | GlobalDataFlow.cs:264:15:264:24 | access to parameter sinkParam6 |
| GlobalDataFlow.cs:267:26:267:35 | sinkParam7 : String | GlobalDataFlow.cs:269:15:269:24 | access to parameter sinkParam7 |
| GlobalDataFlow.cs:294:31:294:40 | sinkParam8 : String[] | GlobalDataFlow.cs:296:15:296:24 | access to parameter sinkParam8 |
| GlobalDataFlow.cs:294:31:294:40 | sinkParam8 : String | GlobalDataFlow.cs:296:15:296:24 | access to parameter sinkParam8 |
| GlobalDataFlow.cs:300:32:300:41 | sinkParam9 : String | GlobalDataFlow.cs:302:15:302:24 | access to parameter sinkParam9 |
| GlobalDataFlow.cs:306:32:306:42 | sinkParam11 : IQueryable<String> | GlobalDataFlow.cs:308:15:308:25 | access to parameter sinkParam11 |
| GlobalDataFlow.cs:306:32:306:42 | sinkParam11 : String | GlobalDataFlow.cs:308:15:308:25 | access to parameter sinkParam11 |
| GlobalDataFlow.cs:320:16:320:29 | "taint source" : String | GlobalDataFlow.cs:153:21:153:25 | call to method Out : String |
| GlobalDataFlow.cs:320:16:320:29 | "taint source" : String | GlobalDataFlow.cs:189:39:189:41 | [output] delegate creation of type Func<String> : String |
| GlobalDataFlow.cs:325:9:325:26 | SSA def(x) : String | GlobalDataFlow.cs:156:20:156:24 | SSA def(sink7) : String |
| GlobalDataFlow.cs:325:13:325:26 | "taint source" : String | GlobalDataFlow.cs:325:9:325:26 | SSA def(x) : String |
| GlobalDataFlow.cs:330:9:330:26 | SSA def(x) : String | GlobalDataFlow.cs:159:20:159:24 | SSA def(sink8) : String |
| GlobalDataFlow.cs:330:13:330:26 | "taint source" : String | GlobalDataFlow.cs:330:9:330:26 | SSA def(x) : String |
| GlobalDataFlow.cs:336:22:336:35 | "taint source" : IEnumerable<String> | GlobalDataFlow.cs:161:22:161:31 | call to method OutYield : IEnumerable<String> |
| GlobalDataFlow.cs:336:22:336:35 | "taint source" : String | GlobalDataFlow.cs:336:22:336:35 | "taint source" : IEnumerable<String> |
| GlobalDataFlow.cs:336:9:336:36 | yield return ...; : IEnumerable<String> | GlobalDataFlow.cs:161:22:161:31 | call to method OutYield : IEnumerable<String> |
| GlobalDataFlow.cs:336:22:336:35 | "taint source" : String | GlobalDataFlow.cs:336:9:336:36 | yield return ...; : IEnumerable<String> |
| GlobalDataFlow.cs:361:41:361:41 | x : String | GlobalDataFlow.cs:363:11:363:11 | access to parameter x : String |
| GlobalDataFlow.cs:361:41:361:41 | x : String | GlobalDataFlow.cs:363:11:363:11 | access to parameter x : String |
| GlobalDataFlow.cs:363:11:363:11 | access to parameter x : String | GlobalDataFlow.cs:53:15:53:15 | x : String |
@@ -334,20 +343,26 @@ nodes
| GlobalDataFlow.cs:80:23:80:65 | (...) ... : String[] | semmle.label | (...) ... : String[] |
| GlobalDataFlow.cs:81:15:81:20 | access to local variable sink13 | semmle.label | access to local variable sink13 |
| GlobalDataFlow.cs:82:23:82:66 | (...) ... : String[] | semmle.label | (...) ... : String[] |
| GlobalDataFlow.cs:82:76:82:86 | [output] delegate creation of type Func<String,String> : T | semmle.label | [output] delegate creation of type Func<String,String> : T |
| GlobalDataFlow.cs:82:76:82:86 | [implicit argument 0] delegate creation of type Func<String,String> : String | semmle.label | [implicit argument 0] delegate creation of type Func<String,String> : String |
| GlobalDataFlow.cs:82:76:82:86 | [output] delegate creation of type Func<String,String> : String | semmle.label | [output] delegate creation of type Func<String,String> : String |
| GlobalDataFlow.cs:83:15:83:20 | access to local variable sink14 | semmle.label | access to local variable sink14 |
| GlobalDataFlow.cs:84:23:84:66 | (...) ... : String[] | semmle.label | (...) ... : String[] |
| GlobalDataFlow.cs:84:117:84:127 | [implicit argument 0] (...) => ... : String | semmle.label | [implicit argument 0] (...) => ... : String |
| GlobalDataFlow.cs:84:117:84:127 | [output] (...) => ... : String | semmle.label | [output] (...) => ... : String |
| GlobalDataFlow.cs:85:15:85:20 | access to local variable sink15 | semmle.label | access to local variable sink15 |
| GlobalDataFlow.cs:86:70:86:113 | (...) ... : String[] | semmle.label | (...) ... : String[] |
| GlobalDataFlow.cs:86:117:86:127 | [implicit argument 1] (...) => ... : String | semmle.label | [implicit argument 1] (...) => ... : String |
| GlobalDataFlow.cs:86:117:86:127 | [output] (...) => ... : String | semmle.label | [output] (...) => ... : String |
| GlobalDataFlow.cs:87:15:87:20 | access to local variable sink16 | semmle.label | access to local variable sink16 |
| GlobalDataFlow.cs:88:23:88:66 | (...) ... : String[] | semmle.label | (...) ... : String[] |
| GlobalDataFlow.cs:88:83:88:101 | [implicit argument 1] (...) => ... : String | semmle.label | [implicit argument 1] (...) => ... : String |
| GlobalDataFlow.cs:88:83:88:101 | [output] (...) => ... : String | semmle.label | [output] (...) => ... : String |
| GlobalDataFlow.cs:88:104:88:109 | [implicit argument 0] (...) => ... : String | semmle.label | [implicit argument 0] (...) => ... : String |
| GlobalDataFlow.cs:88:104:88:109 | [output] (...) => ... : String | semmle.label | [output] (...) => ... : String |
| GlobalDataFlow.cs:89:15:89:20 | access to local variable sink17 | semmle.label | access to local variable sink17 |
| GlobalDataFlow.cs:90:75:90:80 | access to local variable sink14 : String | semmle.label | access to local variable sink14 : String |
| GlobalDataFlow.cs:90:83:90:101 | [implicit argument 0] (...) => ... : String | semmle.label | [implicit argument 0] (...) => ... : String |
| GlobalDataFlow.cs:90:83:90:101 | [output] (...) => ... : String | semmle.label | [output] (...) => ... : String |
| GlobalDataFlow.cs:90:104:90:109 | [implicit argument 0] (...) => ... : String | semmle.label | [implicit argument 0] (...) => ... : String |
| GlobalDataFlow.cs:90:104:90:109 | [output] (...) => ... : String | semmle.label | [output] (...) => ... : String |
| GlobalDataFlow.cs:91:15:91:20 | access to local variable sink18 | semmle.label | access to local variable sink18 |
| GlobalDataFlow.cs:94:15:94:20 | access to local variable sink21 | semmle.label | access to local variable sink21 |
@@ -371,23 +386,26 @@ nodes
| GlobalDataFlow.cs:179:35:179:48 | "taint source" : String | semmle.label | "taint source" : String |
| GlobalDataFlow.cs:180:21:180:26 | delegate call : String | semmle.label | delegate call : String |
| GlobalDataFlow.cs:181:15:181:19 | access to local variable sink9 | semmle.label | access to local variable sink9 |
| GlobalDataFlow.cs:189:22:189:42 | [library code] object creation of type Lazy<String> : String | semmle.label | [library code] object creation of type Lazy<String> : String |
| GlobalDataFlow.cs:189:22:189:42 | object creation of type Lazy<String> [Value] : String | semmle.label | object creation of type Lazy<String> [Value] : String |
| GlobalDataFlow.cs:189:22:189:48 | access to property Value : String | semmle.label | access to property Value : String |
| GlobalDataFlow.cs:189:39:189:41 | [output] delegate creation of type Func<String> : String | semmle.label | [output] delegate creation of type Func<String> : String |
| GlobalDataFlow.cs:190:15:190:20 | access to local variable sink10 | semmle.label | access to local variable sink10 |
| GlobalDataFlow.cs:197:22:197:32 | access to property OutProperty : String | semmle.label | access to property OutProperty : String |
| GlobalDataFlow.cs:198:15:198:20 | access to local variable sink19 | semmle.label | access to local variable sink19 |
| GlobalDataFlow.cs:207:46:207:59 | "taint source" : String | semmle.label | "taint source" : String |
| GlobalDataFlow.cs:210:35:210:45 | sinkParam10 : IQueryable<String> | semmle.label | sinkParam10 : IQueryable<String> |
| GlobalDataFlow.cs:210:35:210:45 | sinkParam10 : String | semmle.label | sinkParam10 : String |
| GlobalDataFlow.cs:210:58:210:68 | access to parameter sinkParam10 | semmle.label | access to parameter sinkParam10 |
| GlobalDataFlow.cs:211:71:211:71 | x : IQueryable<String> | semmle.label | x : IQueryable<String> |
| GlobalDataFlow.cs:211:71:211:71 | x : String | semmle.label | x : String |
| GlobalDataFlow.cs:211:89:211:89 | access to parameter x : String | semmle.label | access to parameter x : String |
| GlobalDataFlow.cs:212:22:212:28 | access to local variable tainted : IQueryable<String> | semmle.label | access to local variable tainted : IQueryable<String> |
| GlobalDataFlow.cs:212:37:212:38 | [implicit argument 0] access to local variable f1 : String | semmle.label | [implicit argument 0] access to local variable f1 : String |
| GlobalDataFlow.cs:212:37:212:38 | [output] access to local variable f1 : String | semmle.label | [output] access to local variable f1 : String |
| GlobalDataFlow.cs:213:15:213:20 | access to local variable sink24 | semmle.label | access to local variable sink24 |
| GlobalDataFlow.cs:214:22:214:28 | access to local variable tainted : IQueryable<String> | semmle.label | access to local variable tainted : IQueryable<String> |
| GlobalDataFlow.cs:214:37:214:38 | [implicit argument 0] access to local variable f2 : String | semmle.label | [implicit argument 0] access to local variable f2 : String |
| GlobalDataFlow.cs:214:37:214:38 | [output] access to local variable f2 : String | semmle.label | [output] access to local variable f2 : String |
| GlobalDataFlow.cs:215:15:215:20 | access to local variable sink25 | semmle.label | access to local variable sink25 |
| GlobalDataFlow.cs:216:22:216:28 | access to local variable tainted : IQueryable<String> | semmle.label | access to local variable tainted : IQueryable<String> |
| GlobalDataFlow.cs:216:37:216:48 | [output] delegate creation of type Func<String,String> : T | semmle.label | [output] delegate creation of type Func<String,String> : T |
| GlobalDataFlow.cs:216:37:216:48 | [implicit argument 0] delegate creation of type Func<String,String> : String | semmle.label | [implicit argument 0] delegate creation of type Func<String,String> : String |
| GlobalDataFlow.cs:216:37:216:48 | [output] delegate creation of type Func<String,String> : String | semmle.label | [output] delegate creation of type Func<String,String> : String |
| GlobalDataFlow.cs:217:15:217:20 | access to local variable sink26 | semmle.label | access to local variable sink26 |
| GlobalDataFlow.cs:236:26:236:35 | sinkParam0 : String | semmle.label | sinkParam0 : String |
| GlobalDataFlow.cs:238:16:238:25 | access to parameter sinkParam0 : String | semmle.label | access to parameter sinkParam0 : String |
@@ -404,18 +422,18 @@ nodes
| GlobalDataFlow.cs:264:15:264:24 | access to parameter sinkParam6 | semmle.label | access to parameter sinkParam6 |
| GlobalDataFlow.cs:267:26:267:35 | sinkParam7 : String | semmle.label | sinkParam7 : String |
| GlobalDataFlow.cs:269:15:269:24 | access to parameter sinkParam7 | semmle.label | access to parameter sinkParam7 |
| GlobalDataFlow.cs:294:31:294:40 | sinkParam8 : String[] | semmle.label | sinkParam8 : String[] |
| GlobalDataFlow.cs:294:31:294:40 | sinkParam8 : String | semmle.label | sinkParam8 : String |
| GlobalDataFlow.cs:296:15:296:24 | access to parameter sinkParam8 | semmle.label | access to parameter sinkParam8 |
| GlobalDataFlow.cs:300:32:300:41 | sinkParam9 : String | semmle.label | sinkParam9 : String |
| GlobalDataFlow.cs:302:15:302:24 | access to parameter sinkParam9 | semmle.label | access to parameter sinkParam9 |
| GlobalDataFlow.cs:306:32:306:42 | sinkParam11 : IQueryable<String> | semmle.label | sinkParam11 : IQueryable<String> |
| GlobalDataFlow.cs:306:32:306:42 | sinkParam11 : String | semmle.label | sinkParam11 : String |
| GlobalDataFlow.cs:308:15:308:25 | access to parameter sinkParam11 | semmle.label | access to parameter sinkParam11 |
| GlobalDataFlow.cs:320:16:320:29 | "taint source" : String | semmle.label | "taint source" : String |
| GlobalDataFlow.cs:325:9:325:26 | SSA def(x) : String | semmle.label | SSA def(x) : String |
| GlobalDataFlow.cs:325:13:325:26 | "taint source" : String | semmle.label | "taint source" : String |
| GlobalDataFlow.cs:330:9:330:26 | SSA def(x) : String | semmle.label | SSA def(x) : String |
| GlobalDataFlow.cs:330:13:330:26 | "taint source" : String | semmle.label | "taint source" : String |
| GlobalDataFlow.cs:336:22:336:35 | "taint source" : IEnumerable<String> | semmle.label | "taint source" : IEnumerable<String> |
| GlobalDataFlow.cs:336:9:336:36 | yield return ...; : IEnumerable<String> | semmle.label | yield return ...; : IEnumerable<String> |
| GlobalDataFlow.cs:336:22:336:35 | "taint source" : String | semmle.label | "taint source" : String |
| GlobalDataFlow.cs:361:41:361:41 | x : String | semmle.label | x : String |
| GlobalDataFlow.cs:361:41:361:41 | x : String | semmle.label | x : String |

View File

@@ -1,3 +1,4 @@
callableFlow
| LibraryTypeDataFlow.DataContract.get_AString() | qualifier -> return | false |
| System.Array.Add(object) | argument 0 -> qualifier | false |
| System.Array.AsReadOnly<T>(T[]) | qualifier -> return | false |
@@ -661,10 +662,6 @@
| System.Int32.TryParse(string, NumberStyles, IFormatProvider, out int) | argument 0 -> return | false |
| System.Int32.TryParse(string, out int) | argument 0 -> argument 1 | false |
| System.Int32.TryParse(string, out int) | argument 0 -> return | false |
| System.Lazy<>.Lazy(Func<T>) | output from argument 0 -> return | true |
| System.Lazy<>.Lazy(Func<T>, LazyThreadSafetyMode) | output from argument 0 -> return | true |
| System.Lazy<>.Lazy(Func<T>, bool) | output from argument 0 -> return | true |
| System.Lazy<>.get_Value() | qualifier -> return | true |
| System.Linq.Enumerable.Aggregate<TSource, TAccumulate, TResult>(IEnumerable<TSource>, TAccumulate, Func<TAccumulate, TSource, TAccumulate>, Func<TAccumulate, TResult>) | argument 0 -> parameter 1 of argument 2 | false |
| System.Linq.Enumerable.Aggregate<TSource, TAccumulate, TResult>(IEnumerable<TSource>, TAccumulate, Func<TAccumulate, TSource, TAccumulate>, Func<TAccumulate, TResult>) | argument 1 -> parameter 0 of argument 2 | false |
| System.Linq.Enumerable.Aggregate<TSource, TAccumulate, TResult>(IEnumerable<TSource>, TAccumulate, Func<TAccumulate, TSource, TAccumulate>, Func<TAccumulate, TResult>) | output from argument 2 -> parameter 0 of argument 3 | false |
@@ -1686,3 +1683,7 @@
| System.Web.HttpUtility.HtmlEncode(string) | argument 0 -> return | false |
| System.Web.HttpUtility.UrlEncode(string) | argument 0 -> return | false |
| System.Web.UI.WebControls.TextBox.get_Text() | qualifier -> return | false |
callableFlowAccessPath
| System.Lazy<>.Lazy(Func<T>) | output from argument 0 [<empty>] -> return [Value] |
| System.Lazy<>.Lazy(Func<T>, LazyThreadSafetyMode) | output from argument 0 [<empty>] -> return [Value] |
| System.Lazy<>.Lazy(Func<T>, bool) | output from argument 0 [<empty>] -> return [Value] |

View File

@@ -1,22 +1,27 @@
import semmle.code.csharp.dataflow.LibraryTypeDataFlow
predicate callableFlow(string callable, string flow, boolean preservesValue) {
query predicate callableFlow(string callable, string flow, boolean preservesValue) {
exists(LibraryTypeDataFlow x, CallableFlowSource source, CallableFlowSink sink, Callable c |
c.(Modifiable).isPublic() and
c.getDeclaringType().isPublic() and
x.callableFlow(source, sink, c, preservesValue) and
callable = c.getQualifiedNameWithTypes() and
flow = source.toString() + " -> " + sink.toString()
flow = source + " -> " + sink and
// Remove certain results to make the test output consistent
// between different versions of .NET Core.
not callable = "System.IO.FileStream.CopyToAsync(Stream, int, CancellationToken)"
)
}
from string entity, string flow, boolean preservesValue
where
callableFlow(entity, flow, preservesValue) and
/*
* Remove certain results to make the test output consistent
* between different versions of .NET Core.
*/
not entity = "System.IO.FileStream.CopyToAsync(Stream, int, CancellationToken)"
select entity, flow, preservesValue
query predicate callableFlowAccessPath(string callable, string flow) {
exists(
LibraryTypeDataFlow x, CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink,
AccessPath sinkAp, Callable c
|
c.(Modifiable).isPublic() and
c.getDeclaringType().isPublic() and
x.callableFlow(source, sourceAp, sink, sinkAp, c) and
callable = c.getQualifiedNameWithTypes() and
flow = source + " [" + sourceAp + "] -> " + sink + " [" + sinkAp + "]"
)
}

View File

@@ -143,8 +143,9 @@
| LocalDataFlow.cs:128:15:128:20 | [post] access to local variable sink49 | LocalDataFlow.cs:129:34:129:39 | access to local variable sink49 |
| LocalDataFlow.cs:128:15:128:20 | access to local variable sink49 | LocalDataFlow.cs:129:34:129:39 | access to local variable sink49 |
| LocalDataFlow.cs:129:13:129:40 | SSA def(sink50) | LocalDataFlow.cs:130:15:130:20 | access to local variable sink50 |
| LocalDataFlow.cs:129:22:129:40 | [library code] call to method Copy | LocalDataFlow.cs:129:22:129:40 | call to method Copy |
| LocalDataFlow.cs:129:22:129:40 | call to method Copy | LocalDataFlow.cs:129:13:129:40 | SSA def(sink50) |
| LocalDataFlow.cs:129:34:129:39 | access to local variable sink49 | LocalDataFlow.cs:129:22:129:40 | call to method Copy |
| LocalDataFlow.cs:129:34:129:39 | access to local variable sink49 | LocalDataFlow.cs:129:22:129:40 | [library code] call to method Copy |
| LocalDataFlow.cs:130:15:130:20 | [post] access to local variable sink50 | LocalDataFlow.cs:131:44:131:49 | access to local variable sink50 |
| LocalDataFlow.cs:130:15:130:20 | access to local variable sink50 | LocalDataFlow.cs:131:44:131:49 | access to local variable sink50 |
| LocalDataFlow.cs:131:13:131:54 | SSA def(sink51) | LocalDataFlow.cs:132:15:132:20 | access to local variable sink51 |
@@ -189,8 +190,9 @@
| LocalDataFlow.cs:152:15:152:22 | [post] access to local variable nonSink0 | LocalDataFlow.cs:153:32:153:39 | access to local variable nonSink0 |
| LocalDataFlow.cs:152:15:152:22 | access to local variable nonSink0 | LocalDataFlow.cs:153:32:153:39 | access to local variable nonSink0 |
| LocalDataFlow.cs:153:9:153:40 | SSA def(nonSink0) | LocalDataFlow.cs:154:15:154:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:153:20:153:40 | [library code] call to method Copy | LocalDataFlow.cs:153:20:153:40 | call to method Copy |
| LocalDataFlow.cs:153:20:153:40 | call to method Copy | LocalDataFlow.cs:153:9:153:40 | SSA def(nonSink0) |
| LocalDataFlow.cs:153:32:153:39 | access to local variable nonSink0 | LocalDataFlow.cs:153:20:153:40 | call to method Copy |
| LocalDataFlow.cs:153:32:153:39 | access to local variable nonSink0 | LocalDataFlow.cs:153:20:153:40 | [library code] call to method Copy |
| LocalDataFlow.cs:154:15:154:22 | [post] access to local variable nonSink0 | LocalDataFlow.cs:155:42:155:49 | access to local variable nonSink0 |
| LocalDataFlow.cs:154:15:154:22 | access to local variable nonSink0 | LocalDataFlow.cs:155:42:155:49 | access to local variable nonSink0 |
| LocalDataFlow.cs:155:9:155:54 | SSA def(nonSink0) | LocalDataFlow.cs:156:15:156:22 | access to local variable nonSink0 |
@@ -284,7 +286,8 @@
| LocalDataFlow.cs:216:15:216:22 | access to local variable nonSink0 | LocalDataFlow.cs:225:28:225:35 | access to local variable nonSink0 |
| LocalDataFlow.cs:219:13:219:127 | SSA def(sink33) | LocalDataFlow.cs:220:15:220:20 | access to local variable sink33 |
| LocalDataFlow.cs:219:22:219:127 | (...) ... | LocalDataFlow.cs:219:13:219:127 | SSA def(sink33) |
| LocalDataFlow.cs:219:30:219:119 | call to method Insert | LocalDataFlow.cs:219:30:219:127 | call to method Clone |
| LocalDataFlow.cs:219:30:219:119 | call to method Insert | LocalDataFlow.cs:219:30:219:127 | [library code] call to method Clone |
| LocalDataFlow.cs:219:30:219:127 | [library code] call to method Clone | LocalDataFlow.cs:219:30:219:127 | call to method Clone |
| LocalDataFlow.cs:219:30:219:127 | call to method Clone | LocalDataFlow.cs:219:22:219:127 | (...) ... |
| LocalDataFlow.cs:220:15:220:20 | [post] access to local variable sink33 | LocalDataFlow.cs:221:22:221:27 | access to local variable sink33 |
| LocalDataFlow.cs:220:15:220:20 | access to local variable sink33 | LocalDataFlow.cs:221:22:221:27 | access to local variable sink33 |
@@ -294,7 +297,8 @@
| LocalDataFlow.cs:221:22:221:63 | call to method Split | LocalDataFlow.cs:221:13:221:63 | SSA def(sink48) |
| LocalDataFlow.cs:225:9:225:127 | SSA def(nonSink0) | LocalDataFlow.cs:226:15:226:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:225:20:225:127 | (...) ... | LocalDataFlow.cs:225:9:225:127 | SSA def(nonSink0) |
| LocalDataFlow.cs:225:28:225:119 | call to method Insert | LocalDataFlow.cs:225:28:225:127 | call to method Clone |
| LocalDataFlow.cs:225:28:225:119 | call to method Insert | LocalDataFlow.cs:225:28:225:127 | [library code] call to method Clone |
| LocalDataFlow.cs:225:28:225:127 | [library code] call to method Clone | LocalDataFlow.cs:225:28:225:127 | call to method Clone |
| LocalDataFlow.cs:225:28:225:127 | call to method Clone | LocalDataFlow.cs:225:20:225:127 | (...) ... |
| LocalDataFlow.cs:226:15:226:22 | [post] access to local variable nonSink0 | LocalDataFlow.cs:227:25:227:32 | access to local variable nonSink0 |
| LocalDataFlow.cs:226:15:226:22 | access to local variable nonSink0 | LocalDataFlow.cs:227:25:227:32 | access to local variable nonSink0 |
@@ -358,16 +362,18 @@
| LocalDataFlow.cs:270:9:270:41 | SSA def(nonSink0) | LocalDataFlow.cs:271:15:271:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:270:20:270:41 | access to property Text | LocalDataFlow.cs:270:9:270:41 | SSA def(nonSink0) |
| LocalDataFlow.cs:274:13:274:51 | SSA def(sink67) | LocalDataFlow.cs:275:15:275:20 | access to local variable sink67 |
| LocalDataFlow.cs:274:22:274:51 | [library code] call to method Run | LocalDataFlow.cs:274:22:274:51 | call to method Run |
| LocalDataFlow.cs:274:22:274:51 | call to method Run | LocalDataFlow.cs:274:13:274:51 | SSA def(sink67) |
| LocalDataFlow.cs:274:31:274:50 | [output] (...) => ... | LocalDataFlow.cs:274:22:274:51 | call to method Run |
| LocalDataFlow.cs:274:31:274:50 | [output] (...) => ... | LocalDataFlow.cs:274:22:274:51 | [library code] call to method Run |
| LocalDataFlow.cs:275:15:275:20 | [post] access to local variable sink67 | LocalDataFlow.cs:276:28:276:33 | access to local variable sink67 |
| LocalDataFlow.cs:275:15:275:20 | access to local variable sink67 | LocalDataFlow.cs:276:28:276:33 | access to local variable sink67 |
| LocalDataFlow.cs:276:13:276:33 | SSA def(sink68) | LocalDataFlow.cs:277:15:277:20 | access to local variable sink68 |
| LocalDataFlow.cs:276:22:276:33 | await ... | LocalDataFlow.cs:276:13:276:33 | SSA def(sink68) |
| LocalDataFlow.cs:276:28:276:33 | access to local variable sink67 | LocalDataFlow.cs:276:22:276:33 | await ... |
| LocalDataFlow.cs:280:13:280:42 | SSA def(nonSink21) | LocalDataFlow.cs:281:15:281:23 | access to local variable nonSink21 |
| LocalDataFlow.cs:280:25:280:42 | [library code] call to method Run | LocalDataFlow.cs:280:25:280:42 | call to method Run |
| LocalDataFlow.cs:280:25:280:42 | call to method Run | LocalDataFlow.cs:280:13:280:42 | SSA def(nonSink21) |
| LocalDataFlow.cs:280:34:280:41 | [output] (...) => ... | LocalDataFlow.cs:280:25:280:42 | call to method Run |
| LocalDataFlow.cs:280:34:280:41 | [output] (...) => ... | LocalDataFlow.cs:280:25:280:42 | [library code] call to method Run |
| LocalDataFlow.cs:281:15:281:23 | [post] access to local variable nonSink21 | LocalDataFlow.cs:282:26:282:34 | access to local variable nonSink21 |
| LocalDataFlow.cs:281:15:281:23 | access to local variable nonSink21 | LocalDataFlow.cs:282:26:282:34 | access to local variable nonSink21 |
| LocalDataFlow.cs:282:9:282:34 | SSA def(nonSink0) | LocalDataFlow.cs:283:15:283:22 | access to local variable nonSink0 |

View File

@@ -24,7 +24,6 @@
| Capture.cs:58:21:58:21 | 1 | Capture.cs:58:17:58:21 | SSA def(i) |
| Capture.cs:61:17:61:17 | 1 | Capture.cs:61:13:61:17 | SSA def(i) |
| Capture.cs:63:9:63:17 | SSA call def(i) | Capture.cs:64:13:64:13 | access to local variable i |
| LocalDataFlow.cs:49:30:49:30 | b | LocalDataFlow.cs:49:30:49:30 | b |
| LocalDataFlow.cs:49:30:49:30 | b | LocalDataFlow.cs:85:21:85:21 | access to parameter b |
| LocalDataFlow.cs:52:13:52:34 | SSA def(sink0) | LocalDataFlow.cs:53:15:53:19 | access to local variable sink0 |
| LocalDataFlow.cs:52:21:52:34 | "taint source" | LocalDataFlow.cs:52:13:52:34 | SSA def(sink0) |
@@ -108,142 +107,184 @@
| LocalDataFlow.cs:106:15:106:22 | [post] access to local variable nonSink3 | LocalDataFlow.cs:171:33:171:40 | access to local variable nonSink3 |
| LocalDataFlow.cs:106:15:106:22 | access to local variable nonSink3 | LocalDataFlow.cs:171:33:171:40 | access to local variable nonSink3 |
| LocalDataFlow.cs:109:13:109:39 | SSA def(sink15) | LocalDataFlow.cs:110:15:110:20 | access to local variable sink15 |
| LocalDataFlow.cs:109:22:109:39 | [library code] call to method Parse | LocalDataFlow.cs:109:22:109:39 | call to method Parse |
| LocalDataFlow.cs:109:22:109:39 | call to method Parse | LocalDataFlow.cs:109:13:109:39 | SSA def(sink15) |
| LocalDataFlow.cs:109:34:109:38 | [post] access to local variable sink9 | LocalDataFlow.cs:112:37:112:41 | access to local variable sink9 |
| LocalDataFlow.cs:109:34:109:38 | access to local variable sink9 | LocalDataFlow.cs:109:22:109:39 | call to method Parse |
| LocalDataFlow.cs:109:34:109:38 | access to local variable sink9 | LocalDataFlow.cs:109:22:109:39 | [library code] call to method Parse |
| LocalDataFlow.cs:109:34:109:38 | access to local variable sink9 | LocalDataFlow.cs:112:37:112:41 | access to local variable sink9 |
| LocalDataFlow.cs:110:15:110:20 | access to local variable sink15 | LocalDataFlow.cs:161:22:161:27 | access to local variable sink15 |
| LocalDataFlow.cs:112:13:112:56 | SSA def(sink16) | LocalDataFlow.cs:113:15:113:20 | access to local variable sink16 |
| LocalDataFlow.cs:112:22:112:56 | [library code] call to method TryParse | LocalDataFlow.cs:112:22:112:56 | call to method TryParse |
| LocalDataFlow.cs:112:22:112:56 | call to method TryParse | LocalDataFlow.cs:112:13:112:56 | SSA def(sink16) |
| LocalDataFlow.cs:112:37:112:41 | [post] access to local variable sink9 | LocalDataFlow.cs:114:44:114:48 | access to local variable sink9 |
| LocalDataFlow.cs:112:37:112:41 | access to local variable sink9 | LocalDataFlow.cs:112:22:112:56 | call to method TryParse |
| LocalDataFlow.cs:112:37:112:41 | access to local variable sink9 | LocalDataFlow.cs:112:22:112:56 | [library code] call to method TryParse |
| LocalDataFlow.cs:112:37:112:41 | access to local variable sink9 | LocalDataFlow.cs:112:22:112:56 | [library code] call to method TryParse |
| LocalDataFlow.cs:112:37:112:41 | access to local variable sink9 | LocalDataFlow.cs:114:44:114:48 | access to local variable sink9 |
| LocalDataFlow.cs:114:13:114:49 | SSA def(sink17) | LocalDataFlow.cs:115:15:115:20 | access to local variable sink17 |
| LocalDataFlow.cs:114:22:114:29 | [post] access to local variable nonSink0 | LocalDataFlow.cs:116:36:116:43 | access to local variable nonSink0 |
| LocalDataFlow.cs:114:22:114:29 | access to local variable nonSink0 | LocalDataFlow.cs:114:22:114:49 | call to method Replace |
| LocalDataFlow.cs:114:22:114:29 | access to local variable nonSink0 | LocalDataFlow.cs:114:22:114:49 | [library code] call to method Replace |
| LocalDataFlow.cs:114:22:114:29 | access to local variable nonSink0 | LocalDataFlow.cs:116:36:116:43 | access to local variable nonSink0 |
| LocalDataFlow.cs:114:22:114:49 | [library code] call to method Replace | LocalDataFlow.cs:114:22:114:49 | call to method Replace |
| LocalDataFlow.cs:114:22:114:49 | [library code] call to method Replace | LocalDataFlow.cs:114:22:114:49 | call to method Replace |
| LocalDataFlow.cs:114:22:114:49 | call to method Replace | LocalDataFlow.cs:114:13:114:49 | SSA def(sink17) |
| LocalDataFlow.cs:114:44:114:48 | [post] access to local variable sink9 | LocalDataFlow.cs:116:46:116:50 | access to local variable sink9 |
| LocalDataFlow.cs:114:44:114:48 | access to local variable sink9 | LocalDataFlow.cs:114:22:114:49 | call to method Replace |
| LocalDataFlow.cs:114:44:114:48 | access to local variable sink9 | LocalDataFlow.cs:114:22:114:49 | [library code] call to method Replace |
| LocalDataFlow.cs:114:44:114:48 | access to local variable sink9 | LocalDataFlow.cs:116:46:116:50 | access to local variable sink9 |
| LocalDataFlow.cs:116:13:116:51 | SSA def(sink18) | LocalDataFlow.cs:117:15:117:20 | access to local variable sink18 |
| LocalDataFlow.cs:116:22:116:51 | [library code] call to method Format | LocalDataFlow.cs:116:22:116:51 | call to method Format |
| LocalDataFlow.cs:116:22:116:51 | [library code] call to method Format | LocalDataFlow.cs:116:22:116:51 | call to method Format |
| LocalDataFlow.cs:116:22:116:51 | call to method Format | LocalDataFlow.cs:116:13:116:51 | SSA def(sink18) |
| LocalDataFlow.cs:116:36:116:43 | [post] access to local variable nonSink0 | LocalDataFlow.cs:118:44:118:51 | access to local variable nonSink0 |
| LocalDataFlow.cs:116:36:116:43 | access to local variable nonSink0 | LocalDataFlow.cs:116:22:116:51 | call to method Format |
| LocalDataFlow.cs:116:36:116:43 | access to local variable nonSink0 | LocalDataFlow.cs:116:22:116:51 | [library code] call to method Format |
| LocalDataFlow.cs:116:36:116:43 | access to local variable nonSink0 | LocalDataFlow.cs:118:44:118:51 | access to local variable nonSink0 |
| LocalDataFlow.cs:116:46:116:50 | [post] access to local variable sink9 | LocalDataFlow.cs:120:33:120:37 | access to local variable sink9 |
| LocalDataFlow.cs:116:46:116:50 | access to local variable sink9 | LocalDataFlow.cs:116:22:116:51 | call to method Format |
| LocalDataFlow.cs:116:46:116:50 | access to local variable sink9 | LocalDataFlow.cs:116:22:116:51 | [library code] call to method Format |
| LocalDataFlow.cs:116:46:116:50 | access to local variable sink9 | LocalDataFlow.cs:120:33:120:37 | access to local variable sink9 |
| LocalDataFlow.cs:117:15:117:20 | [post] access to local variable sink18 | LocalDataFlow.cs:118:36:118:41 | access to local variable sink18 |
| LocalDataFlow.cs:117:15:117:20 | access to local variable sink18 | LocalDataFlow.cs:118:36:118:41 | access to local variable sink18 |
| LocalDataFlow.cs:118:13:118:52 | SSA def(sink19) | LocalDataFlow.cs:119:15:119:20 | access to local variable sink19 |
| LocalDataFlow.cs:118:22:118:52 | [library code] call to method Format | LocalDataFlow.cs:118:22:118:52 | call to method Format |
| LocalDataFlow.cs:118:22:118:52 | [library code] call to method Format | LocalDataFlow.cs:118:22:118:52 | call to method Format |
| LocalDataFlow.cs:118:22:118:52 | call to method Format | LocalDataFlow.cs:118:13:118:52 | SSA def(sink19) |
| LocalDataFlow.cs:118:36:118:41 | access to local variable sink18 | LocalDataFlow.cs:118:22:118:52 | call to method Format |
| LocalDataFlow.cs:118:36:118:41 | access to local variable sink18 | LocalDataFlow.cs:118:22:118:52 | [library code] call to method Format |
| LocalDataFlow.cs:118:44:118:51 | [post] access to local variable nonSink0 | LocalDataFlow.cs:137:32:137:39 | access to local variable nonSink0 |
| LocalDataFlow.cs:118:44:118:51 | access to local variable nonSink0 | LocalDataFlow.cs:118:22:118:52 | call to method Format |
| LocalDataFlow.cs:118:44:118:51 | access to local variable nonSink0 | LocalDataFlow.cs:118:22:118:52 | [library code] call to method Format |
| LocalDataFlow.cs:118:44:118:51 | access to local variable nonSink0 | LocalDataFlow.cs:137:32:137:39 | access to local variable nonSink0 |
| LocalDataFlow.cs:120:13:120:38 | SSA def(sink45) | LocalDataFlow.cs:121:15:121:20 | access to local variable sink45 |
| LocalDataFlow.cs:120:22:120:38 | [library code] call to method Parse | LocalDataFlow.cs:120:22:120:38 | call to method Parse |
| LocalDataFlow.cs:120:22:120:38 | call to method Parse | LocalDataFlow.cs:120:13:120:38 | SSA def(sink45) |
| LocalDataFlow.cs:120:33:120:37 | [post] access to local variable sink9 | LocalDataFlow.cs:123:36:123:40 | access to local variable sink9 |
| LocalDataFlow.cs:120:33:120:37 | access to local variable sink9 | LocalDataFlow.cs:120:22:120:38 | call to method Parse |
| LocalDataFlow.cs:120:33:120:37 | access to local variable sink9 | LocalDataFlow.cs:120:22:120:38 | [library code] call to method Parse |
| LocalDataFlow.cs:120:33:120:37 | access to local variable sink9 | LocalDataFlow.cs:123:36:123:40 | access to local variable sink9 |
| LocalDataFlow.cs:123:13:123:56 | SSA def(sink46) | LocalDataFlow.cs:124:15:124:20 | access to local variable sink46 |
| LocalDataFlow.cs:123:22:123:56 | [library code] call to method TryParse | LocalDataFlow.cs:123:22:123:56 | call to method TryParse |
| LocalDataFlow.cs:123:22:123:56 | call to method TryParse | LocalDataFlow.cs:123:13:123:56 | SSA def(sink46) |
| LocalDataFlow.cs:123:36:123:40 | [post] access to local variable sink9 | LocalDataFlow.cs:163:22:163:26 | access to local variable sink9 |
| LocalDataFlow.cs:123:36:123:40 | access to local variable sink9 | LocalDataFlow.cs:123:22:123:56 | call to method TryParse |
| LocalDataFlow.cs:123:36:123:40 | access to local variable sink9 | LocalDataFlow.cs:123:22:123:56 | [library code] call to method TryParse |
| LocalDataFlow.cs:123:36:123:40 | access to local variable sink9 | LocalDataFlow.cs:123:22:123:56 | [library code] call to method TryParse |
| LocalDataFlow.cs:123:36:123:40 | access to local variable sink9 | LocalDataFlow.cs:163:22:163:26 | access to local variable sink9 |
| LocalDataFlow.cs:124:15:124:20 | access to local variable sink46 | LocalDataFlow.cs:125:37:125:42 | access to local variable sink46 |
| LocalDataFlow.cs:125:13:125:43 | SSA def(sink47) | LocalDataFlow.cs:126:15:126:20 | access to local variable sink47 |
| LocalDataFlow.cs:125:22:125:43 | [library code] call to method ToByte | LocalDataFlow.cs:125:22:125:43 | call to method ToByte |
| LocalDataFlow.cs:125:22:125:43 | call to method ToByte | LocalDataFlow.cs:125:13:125:43 | SSA def(sink47) |
| LocalDataFlow.cs:125:37:125:42 | access to local variable sink46 | LocalDataFlow.cs:125:22:125:43 | call to method ToByte |
| LocalDataFlow.cs:125:37:125:42 | access to local variable sink46 | LocalDataFlow.cs:125:22:125:43 | [library code] call to method ToByte |
| LocalDataFlow.cs:126:15:126:20 | access to local variable sink47 | LocalDataFlow.cs:127:40:127:45 | access to local variable sink47 |
| LocalDataFlow.cs:127:13:127:46 | SSA def(sink49) | LocalDataFlow.cs:128:15:128:20 | access to local variable sink49 |
| LocalDataFlow.cs:127:22:127:46 | [library code] call to method Concat | LocalDataFlow.cs:127:22:127:46 | call to method Concat |
| LocalDataFlow.cs:127:22:127:46 | [library code] call to method Concat | LocalDataFlow.cs:127:22:127:46 | call to method Concat |
| LocalDataFlow.cs:127:22:127:46 | call to method Concat | LocalDataFlow.cs:127:13:127:46 | SSA def(sink49) |
| LocalDataFlow.cs:127:36:127:37 | "" | LocalDataFlow.cs:127:22:127:46 | call to method Concat |
| LocalDataFlow.cs:127:40:127:45 | (...) ... | LocalDataFlow.cs:127:22:127:46 | call to method Concat |
| LocalDataFlow.cs:127:36:127:37 | "" | LocalDataFlow.cs:127:22:127:46 | [library code] call to method Concat |
| LocalDataFlow.cs:127:40:127:45 | (...) ... | LocalDataFlow.cs:127:22:127:46 | [library code] call to method Concat |
| LocalDataFlow.cs:127:40:127:45 | access to local variable sink47 | LocalDataFlow.cs:127:40:127:45 | (...) ... |
| LocalDataFlow.cs:128:15:128:20 | [post] access to local variable sink49 | LocalDataFlow.cs:129:34:129:39 | access to local variable sink49 |
| LocalDataFlow.cs:128:15:128:20 | access to local variable sink49 | LocalDataFlow.cs:129:34:129:39 | access to local variable sink49 |
| LocalDataFlow.cs:129:13:129:40 | SSA def(sink50) | LocalDataFlow.cs:130:15:130:20 | access to local variable sink50 |
| LocalDataFlow.cs:129:22:129:40 | [library code] call to method Copy | LocalDataFlow.cs:129:22:129:40 | call to method Copy |
| LocalDataFlow.cs:129:22:129:40 | call to method Copy | LocalDataFlow.cs:129:13:129:40 | SSA def(sink50) |
| LocalDataFlow.cs:129:34:129:39 | access to local variable sink49 | LocalDataFlow.cs:129:22:129:40 | call to method Copy |
| LocalDataFlow.cs:129:34:129:39 | access to local variable sink49 | LocalDataFlow.cs:129:22:129:40 | [library code] call to method Copy |
| LocalDataFlow.cs:130:15:130:20 | [post] access to local variable sink50 | LocalDataFlow.cs:131:44:131:49 | access to local variable sink50 |
| LocalDataFlow.cs:130:15:130:20 | access to local variable sink50 | LocalDataFlow.cs:131:44:131:49 | access to local variable sink50 |
| LocalDataFlow.cs:131:13:131:54 | SSA def(sink51) | LocalDataFlow.cs:132:15:132:20 | access to local variable sink51 |
| LocalDataFlow.cs:131:22:131:54 | [library code] call to method Join | LocalDataFlow.cs:131:22:131:54 | call to method Join |
| LocalDataFlow.cs:131:22:131:54 | [library code] call to method Join | LocalDataFlow.cs:131:22:131:54 | call to method Join |
| LocalDataFlow.cs:131:22:131:54 | [library code] call to method Join | LocalDataFlow.cs:131:22:131:54 | call to method Join |
| LocalDataFlow.cs:131:22:131:54 | [library code] call to method Join | LocalDataFlow.cs:131:22:131:54 | call to method Join |
| LocalDataFlow.cs:131:22:131:54 | call to method Join | LocalDataFlow.cs:131:13:131:54 | SSA def(sink51) |
| LocalDataFlow.cs:131:34:131:37 | ", " | LocalDataFlow.cs:131:22:131:54 | call to method Join |
| LocalDataFlow.cs:131:40:131:41 | "" | LocalDataFlow.cs:131:22:131:54 | call to method Join |
| LocalDataFlow.cs:131:44:131:49 | access to local variable sink50 | LocalDataFlow.cs:131:22:131:54 | call to method Join |
| LocalDataFlow.cs:131:52:131:53 | "" | LocalDataFlow.cs:131:22:131:54 | call to method Join |
| LocalDataFlow.cs:131:34:131:37 | ", " | LocalDataFlow.cs:131:22:131:54 | [library code] call to method Join |
| LocalDataFlow.cs:131:40:131:41 | "" | LocalDataFlow.cs:131:22:131:54 | [library code] call to method Join |
| LocalDataFlow.cs:131:44:131:49 | access to local variable sink50 | LocalDataFlow.cs:131:22:131:54 | [library code] call to method Join |
| LocalDataFlow.cs:131:52:131:53 | "" | LocalDataFlow.cs:131:22:131:54 | [library code] call to method Join |
| LocalDataFlow.cs:132:15:132:20 | [post] access to local variable sink51 | LocalDataFlow.cs:133:35:133:40 | access to local variable sink51 |
| LocalDataFlow.cs:132:15:132:20 | access to local variable sink51 | LocalDataFlow.cs:133:35:133:40 | access to local variable sink51 |
| LocalDataFlow.cs:133:13:133:41 | SSA def(sink52) | LocalDataFlow.cs:134:15:134:20 | access to local variable sink52 |
| LocalDataFlow.cs:133:22:133:23 | "" | LocalDataFlow.cs:133:22:133:41 | call to method Insert |
| LocalDataFlow.cs:133:22:133:23 | "" | LocalDataFlow.cs:133:22:133:41 | [library code] call to method Insert |
| LocalDataFlow.cs:133:22:133:41 | [library code] call to method Insert | LocalDataFlow.cs:133:22:133:41 | call to method Insert |
| LocalDataFlow.cs:133:22:133:41 | [library code] call to method Insert | LocalDataFlow.cs:133:22:133:41 | call to method Insert |
| LocalDataFlow.cs:133:22:133:41 | call to method Insert | LocalDataFlow.cs:133:13:133:41 | SSA def(sink52) |
| LocalDataFlow.cs:133:35:133:40 | access to local variable sink51 | LocalDataFlow.cs:133:22:133:41 | call to method Insert |
| LocalDataFlow.cs:133:35:133:40 | access to local variable sink51 | LocalDataFlow.cs:133:22:133:41 | [library code] call to method Insert |
| LocalDataFlow.cs:137:9:137:40 | SSA def(nonSink2) | LocalDataFlow.cs:138:15:138:22 | access to local variable nonSink2 |
| LocalDataFlow.cs:137:20:137:40 | [library code] call to method Parse | LocalDataFlow.cs:137:20:137:40 | call to method Parse |
| LocalDataFlow.cs:137:20:137:40 | call to method Parse | LocalDataFlow.cs:137:9:137:40 | SSA def(nonSink2) |
| LocalDataFlow.cs:137:32:137:39 | [post] access to local variable nonSink0 | LocalDataFlow.cs:139:39:139:46 | access to local variable nonSink0 |
| LocalDataFlow.cs:137:32:137:39 | access to local variable nonSink0 | LocalDataFlow.cs:137:20:137:40 | call to method Parse |
| LocalDataFlow.cs:137:32:137:39 | access to local variable nonSink0 | LocalDataFlow.cs:137:20:137:40 | [library code] call to method Parse |
| LocalDataFlow.cs:137:32:137:39 | access to local variable nonSink0 | LocalDataFlow.cs:139:39:139:46 | access to local variable nonSink0 |
| LocalDataFlow.cs:139:13:139:61 | SSA def(nonSink7) | LocalDataFlow.cs:140:15:140:22 | access to local variable nonSink7 |
| LocalDataFlow.cs:139:24:139:61 | [library code] call to method TryParse | LocalDataFlow.cs:139:24:139:61 | call to method TryParse |
| LocalDataFlow.cs:139:24:139:61 | call to method TryParse | LocalDataFlow.cs:139:13:139:61 | SSA def(nonSink7) |
| LocalDataFlow.cs:139:39:139:46 | [post] access to local variable nonSink0 | LocalDataFlow.cs:141:20:141:27 | access to local variable nonSink0 |
| LocalDataFlow.cs:139:39:139:46 | access to local variable nonSink0 | LocalDataFlow.cs:139:24:139:61 | call to method TryParse |
| LocalDataFlow.cs:139:39:139:46 | access to local variable nonSink0 | LocalDataFlow.cs:139:24:139:61 | [library code] call to method TryParse |
| LocalDataFlow.cs:139:39:139:46 | access to local variable nonSink0 | LocalDataFlow.cs:139:24:139:61 | [library code] call to method TryParse |
| LocalDataFlow.cs:139:39:139:46 | access to local variable nonSink0 | LocalDataFlow.cs:141:20:141:27 | access to local variable nonSink0 |
| LocalDataFlow.cs:141:9:141:50 | SSA def(nonSink0) | LocalDataFlow.cs:142:15:142:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:141:20:141:27 | [post] access to local variable nonSink0 | LocalDataFlow.cs:141:42:141:49 | access to local variable nonSink0 |
| LocalDataFlow.cs:141:20:141:27 | access to local variable nonSink0 | LocalDataFlow.cs:141:20:141:50 | call to method Replace |
| LocalDataFlow.cs:141:20:141:27 | access to local variable nonSink0 | LocalDataFlow.cs:141:20:141:50 | [library code] call to method Replace |
| LocalDataFlow.cs:141:20:141:27 | access to local variable nonSink0 | LocalDataFlow.cs:141:42:141:49 | access to local variable nonSink0 |
| LocalDataFlow.cs:141:20:141:50 | [library code] call to method Replace | LocalDataFlow.cs:141:20:141:50 | call to method Replace |
| LocalDataFlow.cs:141:20:141:50 | [library code] call to method Replace | LocalDataFlow.cs:141:20:141:50 | call to method Replace |
| LocalDataFlow.cs:141:20:141:50 | call to method Replace | LocalDataFlow.cs:141:9:141:50 | SSA def(nonSink0) |
| LocalDataFlow.cs:141:42:141:49 | access to local variable nonSink0 | LocalDataFlow.cs:141:20:141:50 | call to method Replace |
| LocalDataFlow.cs:141:42:141:49 | access to local variable nonSink0 | LocalDataFlow.cs:141:20:141:50 | [library code] call to method Replace |
| LocalDataFlow.cs:142:15:142:22 | [post] access to local variable nonSink0 | LocalDataFlow.cs:143:34:143:41 | access to local variable nonSink0 |
| LocalDataFlow.cs:142:15:142:22 | access to local variable nonSink0 | LocalDataFlow.cs:143:34:143:41 | access to local variable nonSink0 |
| LocalDataFlow.cs:143:9:143:52 | SSA def(nonSink0) | LocalDataFlow.cs:144:15:144:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:143:20:143:52 | [library code] call to method Format | LocalDataFlow.cs:143:20:143:52 | call to method Format |
| LocalDataFlow.cs:143:20:143:52 | [library code] call to method Format | LocalDataFlow.cs:143:20:143:52 | call to method Format |
| LocalDataFlow.cs:143:20:143:52 | call to method Format | LocalDataFlow.cs:143:9:143:52 | SSA def(nonSink0) |
| LocalDataFlow.cs:143:34:143:41 | [post] access to local variable nonSink0 | LocalDataFlow.cs:143:44:143:51 | access to local variable nonSink0 |
| LocalDataFlow.cs:143:34:143:41 | access to local variable nonSink0 | LocalDataFlow.cs:143:20:143:52 | call to method Format |
| LocalDataFlow.cs:143:34:143:41 | access to local variable nonSink0 | LocalDataFlow.cs:143:20:143:52 | [library code] call to method Format |
| LocalDataFlow.cs:143:34:143:41 | access to local variable nonSink0 | LocalDataFlow.cs:143:44:143:51 | access to local variable nonSink0 |
| LocalDataFlow.cs:143:44:143:51 | access to local variable nonSink0 | LocalDataFlow.cs:143:20:143:52 | call to method Format |
| LocalDataFlow.cs:143:44:143:51 | access to local variable nonSink0 | LocalDataFlow.cs:143:20:143:52 | [library code] call to method Format |
| LocalDataFlow.cs:144:15:144:22 | [post] access to local variable nonSink0 | LocalDataFlow.cs:145:31:145:38 | access to local variable nonSink0 |
| LocalDataFlow.cs:144:15:144:22 | access to local variable nonSink0 | LocalDataFlow.cs:145:31:145:38 | access to local variable nonSink0 |
| LocalDataFlow.cs:145:9:145:39 | SSA def(nonSink7) | LocalDataFlow.cs:146:15:146:22 | access to local variable nonSink7 |
| LocalDataFlow.cs:145:20:145:39 | [library code] call to method Parse | LocalDataFlow.cs:145:20:145:39 | call to method Parse |
| LocalDataFlow.cs:145:20:145:39 | call to method Parse | LocalDataFlow.cs:145:9:145:39 | SSA def(nonSink7) |
| LocalDataFlow.cs:145:31:145:38 | [post] access to local variable nonSink0 | LocalDataFlow.cs:147:34:147:41 | access to local variable nonSink0 |
| LocalDataFlow.cs:145:31:145:38 | access to local variable nonSink0 | LocalDataFlow.cs:145:20:145:39 | call to method Parse |
| LocalDataFlow.cs:145:31:145:38 | access to local variable nonSink0 | LocalDataFlow.cs:145:20:145:39 | [library code] call to method Parse |
| LocalDataFlow.cs:145:31:145:38 | access to local variable nonSink0 | LocalDataFlow.cs:147:34:147:41 | access to local variable nonSink0 |
| LocalDataFlow.cs:147:9:147:57 | SSA def(nonSink7) | LocalDataFlow.cs:148:15:148:22 | access to local variable nonSink7 |
| LocalDataFlow.cs:147:20:147:57 | [library code] call to method TryParse | LocalDataFlow.cs:147:20:147:57 | call to method TryParse |
| LocalDataFlow.cs:147:20:147:57 | call to method TryParse | LocalDataFlow.cs:147:9:147:57 | SSA def(nonSink7) |
| LocalDataFlow.cs:147:34:147:41 | access to local variable nonSink0 | LocalDataFlow.cs:147:20:147:57 | call to method TryParse |
| LocalDataFlow.cs:147:34:147:41 | access to local variable nonSink0 | LocalDataFlow.cs:147:20:147:57 | [library code] call to method TryParse |
| LocalDataFlow.cs:147:34:147:41 | access to local variable nonSink0 | LocalDataFlow.cs:147:20:147:57 | [library code] call to method TryParse |
| LocalDataFlow.cs:148:15:148:22 | access to local variable nonSink7 | LocalDataFlow.cs:149:40:149:47 | access to local variable nonSink7 |
| LocalDataFlow.cs:149:13:149:48 | SSA def(nonSink14) | LocalDataFlow.cs:150:15:150:23 | access to local variable nonSink14 |
| LocalDataFlow.cs:149:25:149:48 | [library code] call to method ToByte | LocalDataFlow.cs:149:25:149:48 | call to method ToByte |
| LocalDataFlow.cs:149:25:149:48 | call to method ToByte | LocalDataFlow.cs:149:13:149:48 | SSA def(nonSink14) |
| LocalDataFlow.cs:149:40:149:47 | access to local variable nonSink7 | LocalDataFlow.cs:149:25:149:48 | call to method ToByte |
| LocalDataFlow.cs:149:40:149:47 | access to local variable nonSink7 | LocalDataFlow.cs:149:25:149:48 | [library code] call to method ToByte |
| LocalDataFlow.cs:149:40:149:47 | access to local variable nonSink7 | LocalDataFlow.cs:151:38:151:45 | access to local variable nonSink7 |
| LocalDataFlow.cs:151:9:151:46 | SSA def(nonSink0) | LocalDataFlow.cs:152:15:152:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:151:20:151:46 | [library code] call to method Concat | LocalDataFlow.cs:151:20:151:46 | call to method Concat |
| LocalDataFlow.cs:151:20:151:46 | [library code] call to method Concat | LocalDataFlow.cs:151:20:151:46 | call to method Concat |
| LocalDataFlow.cs:151:20:151:46 | call to method Concat | LocalDataFlow.cs:151:9:151:46 | SSA def(nonSink0) |
| LocalDataFlow.cs:151:34:151:35 | "" | LocalDataFlow.cs:151:20:151:46 | call to method Concat |
| LocalDataFlow.cs:151:38:151:45 | (...) ... | LocalDataFlow.cs:151:20:151:46 | call to method Concat |
| LocalDataFlow.cs:151:34:151:35 | "" | LocalDataFlow.cs:151:20:151:46 | [library code] call to method Concat |
| LocalDataFlow.cs:151:38:151:45 | (...) ... | LocalDataFlow.cs:151:20:151:46 | [library code] call to method Concat |
| LocalDataFlow.cs:151:38:151:45 | access to local variable nonSink7 | LocalDataFlow.cs:151:38:151:45 | (...) ... |
| LocalDataFlow.cs:152:15:152:22 | [post] access to local variable nonSink0 | LocalDataFlow.cs:153:32:153:39 | access to local variable nonSink0 |
| LocalDataFlow.cs:152:15:152:22 | access to local variable nonSink0 | LocalDataFlow.cs:153:32:153:39 | access to local variable nonSink0 |
| LocalDataFlow.cs:153:9:153:40 | SSA def(nonSink0) | LocalDataFlow.cs:154:15:154:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:153:20:153:40 | [library code] call to method Copy | LocalDataFlow.cs:153:20:153:40 | call to method Copy |
| LocalDataFlow.cs:153:20:153:40 | call to method Copy | LocalDataFlow.cs:153:9:153:40 | SSA def(nonSink0) |
| LocalDataFlow.cs:153:32:153:39 | access to local variable nonSink0 | LocalDataFlow.cs:153:20:153:40 | call to method Copy |
| LocalDataFlow.cs:153:32:153:39 | access to local variable nonSink0 | LocalDataFlow.cs:153:20:153:40 | [library code] call to method Copy |
| LocalDataFlow.cs:154:15:154:22 | [post] access to local variable nonSink0 | LocalDataFlow.cs:155:42:155:49 | access to local variable nonSink0 |
| LocalDataFlow.cs:154:15:154:22 | access to local variable nonSink0 | LocalDataFlow.cs:155:42:155:49 | access to local variable nonSink0 |
| LocalDataFlow.cs:155:9:155:54 | SSA def(nonSink0) | LocalDataFlow.cs:156:15:156:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:155:20:155:54 | [library code] call to method Join | LocalDataFlow.cs:155:20:155:54 | call to method Join |
| LocalDataFlow.cs:155:20:155:54 | [library code] call to method Join | LocalDataFlow.cs:155:20:155:54 | call to method Join |
| LocalDataFlow.cs:155:20:155:54 | [library code] call to method Join | LocalDataFlow.cs:155:20:155:54 | call to method Join |
| LocalDataFlow.cs:155:20:155:54 | [library code] call to method Join | LocalDataFlow.cs:155:20:155:54 | call to method Join |
| LocalDataFlow.cs:155:20:155:54 | call to method Join | LocalDataFlow.cs:155:9:155:54 | SSA def(nonSink0) |
| LocalDataFlow.cs:155:32:155:35 | ", " | LocalDataFlow.cs:155:20:155:54 | call to method Join |
| LocalDataFlow.cs:155:38:155:39 | "" | LocalDataFlow.cs:155:20:155:54 | call to method Join |
| LocalDataFlow.cs:155:42:155:49 | access to local variable nonSink0 | LocalDataFlow.cs:155:20:155:54 | call to method Join |
| LocalDataFlow.cs:155:52:155:53 | "" | LocalDataFlow.cs:155:20:155:54 | call to method Join |
| LocalDataFlow.cs:155:32:155:35 | ", " | LocalDataFlow.cs:155:20:155:54 | [library code] call to method Join |
| LocalDataFlow.cs:155:38:155:39 | "" | LocalDataFlow.cs:155:20:155:54 | [library code] call to method Join |
| LocalDataFlow.cs:155:42:155:49 | access to local variable nonSink0 | LocalDataFlow.cs:155:20:155:54 | [library code] call to method Join |
| LocalDataFlow.cs:155:52:155:53 | "" | LocalDataFlow.cs:155:20:155:54 | [library code] call to method Join |
| LocalDataFlow.cs:156:15:156:22 | [post] access to local variable nonSink0 | LocalDataFlow.cs:157:33:157:40 | access to local variable nonSink0 |
| LocalDataFlow.cs:156:15:156:22 | access to local variable nonSink0 | LocalDataFlow.cs:157:33:157:40 | access to local variable nonSink0 |
| LocalDataFlow.cs:157:9:157:41 | SSA def(nonSink0) | LocalDataFlow.cs:158:15:158:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:157:20:157:21 | "" | LocalDataFlow.cs:157:20:157:41 | call to method Insert |
| LocalDataFlow.cs:157:20:157:21 | "" | LocalDataFlow.cs:157:20:157:41 | [library code] call to method Insert |
| LocalDataFlow.cs:157:20:157:41 | [library code] call to method Insert | LocalDataFlow.cs:157:20:157:41 | call to method Insert |
| LocalDataFlow.cs:157:20:157:41 | [library code] call to method Insert | LocalDataFlow.cs:157:20:157:41 | call to method Insert |
| LocalDataFlow.cs:157:20:157:41 | call to method Insert | LocalDataFlow.cs:157:9:157:41 | SSA def(nonSink0) |
| LocalDataFlow.cs:157:33:157:40 | access to local variable nonSink0 | LocalDataFlow.cs:157:20:157:41 | call to method Insert |
| LocalDataFlow.cs:157:33:157:40 | access to local variable nonSink0 | LocalDataFlow.cs:157:20:157:41 | [library code] call to method Insert |
| LocalDataFlow.cs:158:15:158:22 | [post] access to local variable nonSink0 | LocalDataFlow.cs:195:39:195:46 | access to local variable nonSink0 |
| LocalDataFlow.cs:158:15:158:22 | access to local variable nonSink0 | LocalDataFlow.cs:195:39:195:46 | access to local variable nonSink0 |
| LocalDataFlow.cs:161:13:161:32 | SSA def(sink20) | LocalDataFlow.cs:162:15:162:20 | access to local variable sink20 |
@@ -279,199 +320,262 @@
| LocalDataFlow.cs:179:20:179:36 | ... \|\| ... | LocalDataFlow.cs:179:9:179:36 | SSA def(nonSink7) |
| LocalDataFlow.cs:179:32:179:36 | false | LocalDataFlow.cs:179:20:179:36 | ... \|\| ... |
| LocalDataFlow.cs:183:13:183:42 | SSA def(sink26) | LocalDataFlow.cs:184:15:184:20 | access to local variable sink26 |
| LocalDataFlow.cs:183:22:183:42 | [library code] object creation of type Uri | LocalDataFlow.cs:183:22:183:42 | object creation of type Uri |
| LocalDataFlow.cs:183:22:183:42 | object creation of type Uri | LocalDataFlow.cs:183:13:183:42 | SSA def(sink26) |
| LocalDataFlow.cs:183:37:183:41 | access to local variable sink9 | LocalDataFlow.cs:183:22:183:42 | object creation of type Uri |
| LocalDataFlow.cs:183:37:183:41 | access to local variable sink9 | LocalDataFlow.cs:183:22:183:42 | [library code] object creation of type Uri |
| LocalDataFlow.cs:184:15:184:20 | [post] access to local variable sink26 | LocalDataFlow.cs:185:22:185:27 | access to local variable sink26 |
| LocalDataFlow.cs:184:15:184:20 | access to local variable sink26 | LocalDataFlow.cs:185:22:185:27 | access to local variable sink26 |
| LocalDataFlow.cs:185:13:185:38 | SSA def(sink27) | LocalDataFlow.cs:186:15:186:20 | access to local variable sink27 |
| LocalDataFlow.cs:185:22:185:27 | [post] access to local variable sink26 | LocalDataFlow.cs:187:22:187:27 | access to local variable sink26 |
| LocalDataFlow.cs:185:22:185:27 | access to local variable sink26 | LocalDataFlow.cs:185:22:185:38 | call to method ToString |
| LocalDataFlow.cs:185:22:185:27 | access to local variable sink26 | LocalDataFlow.cs:185:22:185:38 | [library code] call to method ToString |
| LocalDataFlow.cs:185:22:185:27 | access to local variable sink26 | LocalDataFlow.cs:187:22:187:27 | access to local variable sink26 |
| LocalDataFlow.cs:185:22:185:38 | [library code] call to method ToString | LocalDataFlow.cs:185:22:185:38 | call to method ToString |
| LocalDataFlow.cs:185:22:185:38 | call to method ToString | LocalDataFlow.cs:185:13:185:38 | SSA def(sink27) |
| LocalDataFlow.cs:187:13:187:40 | SSA def(sink28) | LocalDataFlow.cs:188:15:188:20 | access to local variable sink28 |
| LocalDataFlow.cs:187:22:187:27 | [post] access to local variable sink26 | LocalDataFlow.cs:189:22:189:27 | access to local variable sink26 |
| LocalDataFlow.cs:187:22:187:27 | access to local variable sink26 | LocalDataFlow.cs:187:22:187:40 | access to property PathAndQuery |
| LocalDataFlow.cs:187:22:187:27 | access to local variable sink26 | LocalDataFlow.cs:187:22:187:40 | [library code] access to property PathAndQuery |
| LocalDataFlow.cs:187:22:187:27 | access to local variable sink26 | LocalDataFlow.cs:189:22:189:27 | access to local variable sink26 |
| LocalDataFlow.cs:187:22:187:40 | [library code] access to property PathAndQuery | LocalDataFlow.cs:187:22:187:40 | access to property PathAndQuery |
| LocalDataFlow.cs:187:22:187:40 | access to property PathAndQuery | LocalDataFlow.cs:187:13:187:40 | SSA def(sink28) |
| LocalDataFlow.cs:189:13:189:33 | SSA def(sink29) | LocalDataFlow.cs:190:15:190:20 | access to local variable sink29 |
| LocalDataFlow.cs:189:22:189:27 | [post] access to local variable sink26 | LocalDataFlow.cs:191:22:191:27 | access to local variable sink26 |
| LocalDataFlow.cs:189:22:189:27 | access to local variable sink26 | LocalDataFlow.cs:189:22:189:33 | access to property Query |
| LocalDataFlow.cs:189:22:189:27 | access to local variable sink26 | LocalDataFlow.cs:189:22:189:33 | [library code] access to property Query |
| LocalDataFlow.cs:189:22:189:27 | access to local variable sink26 | LocalDataFlow.cs:191:22:191:27 | access to local variable sink26 |
| LocalDataFlow.cs:189:22:189:33 | [library code] access to property Query | LocalDataFlow.cs:189:22:189:33 | access to property Query |
| LocalDataFlow.cs:189:22:189:33 | access to property Query | LocalDataFlow.cs:189:13:189:33 | SSA def(sink29) |
| LocalDataFlow.cs:191:13:191:42 | SSA def(sink30) | LocalDataFlow.cs:192:15:192:20 | access to local variable sink30 |
| LocalDataFlow.cs:191:22:191:27 | access to local variable sink26 | LocalDataFlow.cs:191:22:191:42 | access to property OriginalString |
| LocalDataFlow.cs:191:22:191:27 | access to local variable sink26 | LocalDataFlow.cs:191:22:191:42 | [library code] access to property OriginalString |
| LocalDataFlow.cs:191:22:191:42 | [library code] access to property OriginalString | LocalDataFlow.cs:191:22:191:42 | access to property OriginalString |
| LocalDataFlow.cs:191:22:191:42 | access to property OriginalString | LocalDataFlow.cs:191:13:191:42 | SSA def(sink30) |
| LocalDataFlow.cs:192:15:192:20 | [post] access to local variable sink30 | LocalDataFlow.cs:207:49:207:54 | access to local variable sink30 |
| LocalDataFlow.cs:192:15:192:20 | access to local variable sink30 | LocalDataFlow.cs:207:49:207:54 | access to local variable sink30 |
| LocalDataFlow.cs:195:13:195:47 | SSA def(nonSink8) | LocalDataFlow.cs:196:15:196:22 | access to local variable nonSink8 |
| LocalDataFlow.cs:195:24:195:47 | [library code] object creation of type Uri | LocalDataFlow.cs:195:24:195:47 | object creation of type Uri |
| LocalDataFlow.cs:195:24:195:47 | object creation of type Uri | LocalDataFlow.cs:195:13:195:47 | SSA def(nonSink8) |
| LocalDataFlow.cs:195:39:195:46 | access to local variable nonSink0 | LocalDataFlow.cs:195:24:195:47 | object creation of type Uri |
| LocalDataFlow.cs:195:39:195:46 | access to local variable nonSink0 | LocalDataFlow.cs:195:24:195:47 | [library code] object creation of type Uri |
| LocalDataFlow.cs:196:15:196:22 | [post] access to local variable nonSink8 | LocalDataFlow.cs:197:20:197:27 | access to local variable nonSink8 |
| LocalDataFlow.cs:196:15:196:22 | access to local variable nonSink8 | LocalDataFlow.cs:197:20:197:27 | access to local variable nonSink8 |
| LocalDataFlow.cs:197:9:197:38 | SSA def(nonSink0) | LocalDataFlow.cs:198:15:198:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:197:20:197:27 | [post] access to local variable nonSink8 | LocalDataFlow.cs:199:20:199:27 | access to local variable nonSink8 |
| LocalDataFlow.cs:197:20:197:27 | access to local variable nonSink8 | LocalDataFlow.cs:197:20:197:38 | call to method ToString |
| LocalDataFlow.cs:197:20:197:27 | access to local variable nonSink8 | LocalDataFlow.cs:197:20:197:38 | [library code] call to method ToString |
| LocalDataFlow.cs:197:20:197:27 | access to local variable nonSink8 | LocalDataFlow.cs:199:20:199:27 | access to local variable nonSink8 |
| LocalDataFlow.cs:197:20:197:38 | [library code] call to method ToString | LocalDataFlow.cs:197:20:197:38 | call to method ToString |
| LocalDataFlow.cs:197:20:197:38 | call to method ToString | LocalDataFlow.cs:197:9:197:38 | SSA def(nonSink0) |
| LocalDataFlow.cs:199:9:199:40 | SSA def(nonSink0) | LocalDataFlow.cs:200:15:200:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:199:20:199:27 | [post] access to local variable nonSink8 | LocalDataFlow.cs:201:20:201:27 | access to local variable nonSink8 |
| LocalDataFlow.cs:199:20:199:27 | access to local variable nonSink8 | LocalDataFlow.cs:199:20:199:40 | access to property PathAndQuery |
| LocalDataFlow.cs:199:20:199:27 | access to local variable nonSink8 | LocalDataFlow.cs:199:20:199:40 | [library code] access to property PathAndQuery |
| LocalDataFlow.cs:199:20:199:27 | access to local variable nonSink8 | LocalDataFlow.cs:201:20:201:27 | access to local variable nonSink8 |
| LocalDataFlow.cs:199:20:199:40 | [library code] access to property PathAndQuery | LocalDataFlow.cs:199:20:199:40 | access to property PathAndQuery |
| LocalDataFlow.cs:199:20:199:40 | access to property PathAndQuery | LocalDataFlow.cs:199:9:199:40 | SSA def(nonSink0) |
| LocalDataFlow.cs:201:9:201:33 | SSA def(nonSink0) | LocalDataFlow.cs:202:15:202:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:201:20:201:27 | [post] access to local variable nonSink8 | LocalDataFlow.cs:203:20:203:27 | access to local variable nonSink8 |
| LocalDataFlow.cs:201:20:201:27 | access to local variable nonSink8 | LocalDataFlow.cs:201:20:201:33 | access to property Query |
| LocalDataFlow.cs:201:20:201:27 | access to local variable nonSink8 | LocalDataFlow.cs:201:20:201:33 | [library code] access to property Query |
| LocalDataFlow.cs:201:20:201:27 | access to local variable nonSink8 | LocalDataFlow.cs:203:20:203:27 | access to local variable nonSink8 |
| LocalDataFlow.cs:201:20:201:33 | [library code] access to property Query | LocalDataFlow.cs:201:20:201:33 | access to property Query |
| LocalDataFlow.cs:201:20:201:33 | access to property Query | LocalDataFlow.cs:201:9:201:33 | SSA def(nonSink0) |
| LocalDataFlow.cs:203:9:203:42 | SSA def(nonSink0) | LocalDataFlow.cs:204:15:204:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:203:20:203:27 | access to local variable nonSink8 | LocalDataFlow.cs:203:20:203:42 | access to property OriginalString |
| LocalDataFlow.cs:203:20:203:27 | access to local variable nonSink8 | LocalDataFlow.cs:203:20:203:42 | [library code] access to property OriginalString |
| LocalDataFlow.cs:203:20:203:42 | [library code] access to property OriginalString | LocalDataFlow.cs:203:20:203:42 | access to property OriginalString |
| LocalDataFlow.cs:203:20:203:42 | access to property OriginalString | LocalDataFlow.cs:203:9:203:42 | SSA def(nonSink0) |
| LocalDataFlow.cs:204:15:204:22 | [post] access to local variable nonSink0 | LocalDataFlow.cs:213:51:213:58 | access to local variable nonSink0 |
| LocalDataFlow.cs:204:15:204:22 | access to local variable nonSink0 | LocalDataFlow.cs:213:51:213:58 | access to local variable nonSink0 |
| LocalDataFlow.cs:207:13:207:55 | SSA def(sink31) | LocalDataFlow.cs:208:15:208:20 | access to local variable sink31 |
| LocalDataFlow.cs:207:22:207:55 | [library code] object creation of type StringReader | LocalDataFlow.cs:207:22:207:55 | object creation of type StringReader |
| LocalDataFlow.cs:207:22:207:55 | object creation of type StringReader | LocalDataFlow.cs:207:13:207:55 | SSA def(sink31) |
| LocalDataFlow.cs:207:49:207:54 | access to local variable sink30 | LocalDataFlow.cs:207:22:207:55 | object creation of type StringReader |
| LocalDataFlow.cs:207:49:207:54 | access to local variable sink30 | LocalDataFlow.cs:207:22:207:55 | [library code] object creation of type StringReader |
| LocalDataFlow.cs:208:15:208:20 | [post] access to local variable sink31 | LocalDataFlow.cs:209:22:209:27 | access to local variable sink31 |
| LocalDataFlow.cs:208:15:208:20 | access to local variable sink31 | LocalDataFlow.cs:209:22:209:27 | access to local variable sink31 |
| LocalDataFlow.cs:209:13:209:39 | SSA def(sink32) | LocalDataFlow.cs:210:15:210:20 | access to local variable sink32 |
| LocalDataFlow.cs:209:22:209:27 | access to local variable sink31 | LocalDataFlow.cs:209:22:209:39 | call to method ReadToEnd |
| LocalDataFlow.cs:209:22:209:27 | access to local variable sink31 | LocalDataFlow.cs:209:22:209:39 | [library code] call to method ReadToEnd |
| LocalDataFlow.cs:209:22:209:39 | [library code] call to method ReadToEnd | LocalDataFlow.cs:209:22:209:39 | call to method ReadToEnd |
| LocalDataFlow.cs:209:22:209:39 | call to method ReadToEnd | LocalDataFlow.cs:209:13:209:39 | SSA def(sink32) |
| LocalDataFlow.cs:210:15:210:20 | [post] access to local variable sink32 | LocalDataFlow.cs:219:30:219:35 | access to local variable sink32 |
| LocalDataFlow.cs:210:15:210:20 | access to local variable sink32 | LocalDataFlow.cs:219:30:219:35 | access to local variable sink32 |
| LocalDataFlow.cs:213:13:213:59 | SSA def(nonSink9) | LocalDataFlow.cs:214:15:214:22 | access to local variable nonSink9 |
| LocalDataFlow.cs:213:24:213:59 | [library code] object creation of type StringReader | LocalDataFlow.cs:213:24:213:59 | object creation of type StringReader |
| LocalDataFlow.cs:213:24:213:59 | object creation of type StringReader | LocalDataFlow.cs:213:13:213:59 | SSA def(nonSink9) |
| LocalDataFlow.cs:213:51:213:58 | access to local variable nonSink0 | LocalDataFlow.cs:213:24:213:59 | object creation of type StringReader |
| LocalDataFlow.cs:213:51:213:58 | access to local variable nonSink0 | LocalDataFlow.cs:213:24:213:59 | [library code] object creation of type StringReader |
| LocalDataFlow.cs:214:15:214:22 | [post] access to local variable nonSink9 | LocalDataFlow.cs:215:20:215:27 | access to local variable nonSink9 |
| LocalDataFlow.cs:214:15:214:22 | access to local variable nonSink9 | LocalDataFlow.cs:215:20:215:27 | access to local variable nonSink9 |
| LocalDataFlow.cs:215:9:215:39 | SSA def(nonSink0) | LocalDataFlow.cs:216:15:216:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:215:20:215:27 | access to local variable nonSink9 | LocalDataFlow.cs:215:20:215:39 | call to method ReadToEnd |
| LocalDataFlow.cs:215:20:215:27 | access to local variable nonSink9 | LocalDataFlow.cs:215:20:215:39 | [library code] call to method ReadToEnd |
| LocalDataFlow.cs:215:20:215:39 | [library code] call to method ReadToEnd | LocalDataFlow.cs:215:20:215:39 | call to method ReadToEnd |
| LocalDataFlow.cs:215:20:215:39 | call to method ReadToEnd | LocalDataFlow.cs:215:9:215:39 | SSA def(nonSink0) |
| LocalDataFlow.cs:216:15:216:22 | [post] access to local variable nonSink0 | LocalDataFlow.cs:225:28:225:35 | access to local variable nonSink0 |
| LocalDataFlow.cs:216:15:216:22 | access to local variable nonSink0 | LocalDataFlow.cs:225:28:225:35 | access to local variable nonSink0 |
| LocalDataFlow.cs:219:13:219:127 | SSA def(sink33) | LocalDataFlow.cs:220:15:220:20 | access to local variable sink33 |
| LocalDataFlow.cs:219:22:219:127 | (...) ... | LocalDataFlow.cs:219:13:219:127 | SSA def(sink33) |
| LocalDataFlow.cs:219:30:219:35 | access to local variable sink32 | LocalDataFlow.cs:219:30:219:48 | call to method Substring |
| LocalDataFlow.cs:219:30:219:48 | call to method Substring | LocalDataFlow.cs:219:30:219:67 | call to method ToLowerInvariant |
| LocalDataFlow.cs:219:30:219:67 | call to method ToLowerInvariant | LocalDataFlow.cs:219:30:219:77 | call to method ToUpper |
| LocalDataFlow.cs:219:30:219:77 | call to method ToUpper | LocalDataFlow.cs:219:30:219:87 | call to method Trim |
| LocalDataFlow.cs:219:30:219:87 | call to method Trim | LocalDataFlow.cs:219:30:219:105 | call to method Replace |
| LocalDataFlow.cs:219:30:219:105 | call to method Replace | LocalDataFlow.cs:219:30:219:119 | call to method Insert |
| LocalDataFlow.cs:219:30:219:119 | call to method Insert | LocalDataFlow.cs:219:30:219:127 | call to method Clone |
| LocalDataFlow.cs:219:30:219:35 | access to local variable sink32 | LocalDataFlow.cs:219:30:219:48 | [library code] call to method Substring |
| LocalDataFlow.cs:219:30:219:48 | [library code] call to method Substring | LocalDataFlow.cs:219:30:219:48 | call to method Substring |
| LocalDataFlow.cs:219:30:219:48 | call to method Substring | LocalDataFlow.cs:219:30:219:67 | [library code] call to method ToLowerInvariant |
| LocalDataFlow.cs:219:30:219:67 | [library code] call to method ToLowerInvariant | LocalDataFlow.cs:219:30:219:67 | call to method ToLowerInvariant |
| LocalDataFlow.cs:219:30:219:67 | call to method ToLowerInvariant | LocalDataFlow.cs:219:30:219:77 | [library code] call to method ToUpper |
| LocalDataFlow.cs:219:30:219:77 | [library code] call to method ToUpper | LocalDataFlow.cs:219:30:219:77 | call to method ToUpper |
| LocalDataFlow.cs:219:30:219:77 | call to method ToUpper | LocalDataFlow.cs:219:30:219:87 | [library code] call to method Trim |
| LocalDataFlow.cs:219:30:219:87 | [library code] call to method Trim | LocalDataFlow.cs:219:30:219:87 | call to method Trim |
| LocalDataFlow.cs:219:30:219:87 | call to method Trim | LocalDataFlow.cs:219:30:219:105 | [library code] call to method Replace |
| LocalDataFlow.cs:219:30:219:105 | [library code] call to method Replace | LocalDataFlow.cs:219:30:219:105 | call to method Replace |
| LocalDataFlow.cs:219:30:219:105 | [library code] call to method Replace | LocalDataFlow.cs:219:30:219:105 | call to method Replace |
| LocalDataFlow.cs:219:30:219:105 | call to method Replace | LocalDataFlow.cs:219:30:219:119 | [library code] call to method Insert |
| LocalDataFlow.cs:219:30:219:119 | [library code] call to method Insert | LocalDataFlow.cs:219:30:219:119 | call to method Insert |
| LocalDataFlow.cs:219:30:219:119 | [library code] call to method Insert | LocalDataFlow.cs:219:30:219:119 | call to method Insert |
| LocalDataFlow.cs:219:30:219:119 | call to method Insert | LocalDataFlow.cs:219:30:219:127 | [library code] call to method Clone |
| LocalDataFlow.cs:219:30:219:119 | call to method Insert | LocalDataFlow.cs:219:30:219:127 | [library code] call to method Clone |
| LocalDataFlow.cs:219:30:219:127 | [library code] call to method Clone | LocalDataFlow.cs:219:30:219:127 | call to method Clone |
| LocalDataFlow.cs:219:30:219:127 | [library code] call to method Clone | LocalDataFlow.cs:219:30:219:127 | call to method Clone |
| LocalDataFlow.cs:219:30:219:127 | call to method Clone | LocalDataFlow.cs:219:22:219:127 | (...) ... |
| LocalDataFlow.cs:219:102:219:104 | "b" | LocalDataFlow.cs:219:30:219:105 | call to method Replace |
| LocalDataFlow.cs:219:117:219:118 | "" | LocalDataFlow.cs:219:30:219:119 | call to method Insert |
| LocalDataFlow.cs:219:102:219:104 | "b" | LocalDataFlow.cs:219:30:219:105 | [library code] call to method Replace |
| LocalDataFlow.cs:219:117:219:118 | "" | LocalDataFlow.cs:219:30:219:119 | [library code] call to method Insert |
| LocalDataFlow.cs:220:15:220:20 | [post] access to local variable sink33 | LocalDataFlow.cs:221:22:221:27 | access to local variable sink33 |
| LocalDataFlow.cs:220:15:220:20 | access to local variable sink33 | LocalDataFlow.cs:221:22:221:27 | access to local variable sink33 |
| LocalDataFlow.cs:221:13:221:63 | SSA def(sink48) | LocalDataFlow.cs:222:15:222:20 | access to local variable sink48 |
| LocalDataFlow.cs:221:22:221:27 | [post] access to local variable sink33 | LocalDataFlow.cs:231:40:231:45 | access to local variable sink33 |
| LocalDataFlow.cs:221:22:221:27 | access to local variable sink33 | LocalDataFlow.cs:221:22:221:39 | call to method Normalize |
| LocalDataFlow.cs:221:22:221:27 | access to local variable sink33 | LocalDataFlow.cs:221:22:221:39 | [library code] call to method Normalize |
| LocalDataFlow.cs:221:22:221:27 | access to local variable sink33 | LocalDataFlow.cs:231:40:231:45 | access to local variable sink33 |
| LocalDataFlow.cs:221:22:221:39 | call to method Normalize | LocalDataFlow.cs:221:22:221:52 | call to method Remove |
| LocalDataFlow.cs:221:22:221:52 | call to method Remove | LocalDataFlow.cs:221:22:221:63 | call to method Split |
| LocalDataFlow.cs:221:22:221:39 | [library code] call to method Normalize | LocalDataFlow.cs:221:22:221:39 | call to method Normalize |
| LocalDataFlow.cs:221:22:221:39 | call to method Normalize | LocalDataFlow.cs:221:22:221:52 | [library code] call to method Remove |
| LocalDataFlow.cs:221:22:221:52 | [library code] call to method Remove | LocalDataFlow.cs:221:22:221:52 | call to method Remove |
| LocalDataFlow.cs:221:22:221:52 | call to method Remove | LocalDataFlow.cs:221:22:221:63 | [library code] call to method Split |
| LocalDataFlow.cs:221:22:221:63 | [library code] call to method Split | LocalDataFlow.cs:221:22:221:63 | call to method Split |
| LocalDataFlow.cs:221:22:221:63 | call to method Split | LocalDataFlow.cs:221:13:221:63 | SSA def(sink48) |
| LocalDataFlow.cs:225:9:225:127 | SSA def(nonSink0) | LocalDataFlow.cs:226:15:226:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:225:20:225:127 | (...) ... | LocalDataFlow.cs:225:9:225:127 | SSA def(nonSink0) |
| LocalDataFlow.cs:225:28:225:35 | access to local variable nonSink0 | LocalDataFlow.cs:225:28:225:48 | call to method Substring |
| LocalDataFlow.cs:225:28:225:48 | call to method Substring | LocalDataFlow.cs:225:28:225:67 | call to method ToLowerInvariant |
| LocalDataFlow.cs:225:28:225:67 | call to method ToLowerInvariant | LocalDataFlow.cs:225:28:225:77 | call to method ToUpper |
| LocalDataFlow.cs:225:28:225:77 | call to method ToUpper | LocalDataFlow.cs:225:28:225:87 | call to method Trim |
| LocalDataFlow.cs:225:28:225:87 | call to method Trim | LocalDataFlow.cs:225:28:225:105 | call to method Replace |
| LocalDataFlow.cs:225:28:225:105 | call to method Replace | LocalDataFlow.cs:225:28:225:119 | call to method Insert |
| LocalDataFlow.cs:225:28:225:119 | call to method Insert | LocalDataFlow.cs:225:28:225:127 | call to method Clone |
| LocalDataFlow.cs:225:28:225:35 | access to local variable nonSink0 | LocalDataFlow.cs:225:28:225:48 | [library code] call to method Substring |
| LocalDataFlow.cs:225:28:225:48 | [library code] call to method Substring | LocalDataFlow.cs:225:28:225:48 | call to method Substring |
| LocalDataFlow.cs:225:28:225:48 | call to method Substring | LocalDataFlow.cs:225:28:225:67 | [library code] call to method ToLowerInvariant |
| LocalDataFlow.cs:225:28:225:67 | [library code] call to method ToLowerInvariant | LocalDataFlow.cs:225:28:225:67 | call to method ToLowerInvariant |
| LocalDataFlow.cs:225:28:225:67 | call to method ToLowerInvariant | LocalDataFlow.cs:225:28:225:77 | [library code] call to method ToUpper |
| LocalDataFlow.cs:225:28:225:77 | [library code] call to method ToUpper | LocalDataFlow.cs:225:28:225:77 | call to method ToUpper |
| LocalDataFlow.cs:225:28:225:77 | call to method ToUpper | LocalDataFlow.cs:225:28:225:87 | [library code] call to method Trim |
| LocalDataFlow.cs:225:28:225:87 | [library code] call to method Trim | LocalDataFlow.cs:225:28:225:87 | call to method Trim |
| LocalDataFlow.cs:225:28:225:87 | call to method Trim | LocalDataFlow.cs:225:28:225:105 | [library code] call to method Replace |
| LocalDataFlow.cs:225:28:225:105 | [library code] call to method Replace | LocalDataFlow.cs:225:28:225:105 | call to method Replace |
| LocalDataFlow.cs:225:28:225:105 | [library code] call to method Replace | LocalDataFlow.cs:225:28:225:105 | call to method Replace |
| LocalDataFlow.cs:225:28:225:105 | call to method Replace | LocalDataFlow.cs:225:28:225:119 | [library code] call to method Insert |
| LocalDataFlow.cs:225:28:225:119 | [library code] call to method Insert | LocalDataFlow.cs:225:28:225:119 | call to method Insert |
| LocalDataFlow.cs:225:28:225:119 | [library code] call to method Insert | LocalDataFlow.cs:225:28:225:119 | call to method Insert |
| LocalDataFlow.cs:225:28:225:119 | call to method Insert | LocalDataFlow.cs:225:28:225:127 | [library code] call to method Clone |
| LocalDataFlow.cs:225:28:225:119 | call to method Insert | LocalDataFlow.cs:225:28:225:127 | [library code] call to method Clone |
| LocalDataFlow.cs:225:28:225:127 | [library code] call to method Clone | LocalDataFlow.cs:225:28:225:127 | call to method Clone |
| LocalDataFlow.cs:225:28:225:127 | [library code] call to method Clone | LocalDataFlow.cs:225:28:225:127 | call to method Clone |
| LocalDataFlow.cs:225:28:225:127 | call to method Clone | LocalDataFlow.cs:225:20:225:127 | (...) ... |
| LocalDataFlow.cs:225:102:225:104 | "b" | LocalDataFlow.cs:225:28:225:105 | call to method Replace |
| LocalDataFlow.cs:225:117:225:118 | "" | LocalDataFlow.cs:225:28:225:119 | call to method Insert |
| LocalDataFlow.cs:225:102:225:104 | "b" | LocalDataFlow.cs:225:28:225:105 | [library code] call to method Replace |
| LocalDataFlow.cs:225:117:225:118 | "" | LocalDataFlow.cs:225:28:225:119 | [library code] call to method Insert |
| LocalDataFlow.cs:226:15:226:22 | [post] access to local variable nonSink0 | LocalDataFlow.cs:227:25:227:32 | access to local variable nonSink0 |
| LocalDataFlow.cs:226:15:226:22 | access to local variable nonSink0 | LocalDataFlow.cs:227:25:227:32 | access to local variable nonSink0 |
| LocalDataFlow.cs:227:13:227:68 | SSA def(nonSink15) | LocalDataFlow.cs:228:15:228:23 | access to local variable nonSink15 |
| LocalDataFlow.cs:227:25:227:32 | [post] access to local variable nonSink0 | LocalDataFlow.cs:240:43:240:50 | access to local variable nonSink0 |
| LocalDataFlow.cs:227:25:227:32 | access to local variable nonSink0 | LocalDataFlow.cs:227:25:227:44 | call to method Normalize |
| LocalDataFlow.cs:227:25:227:32 | access to local variable nonSink0 | LocalDataFlow.cs:227:25:227:44 | [library code] call to method Normalize |
| LocalDataFlow.cs:227:25:227:32 | access to local variable nonSink0 | LocalDataFlow.cs:240:43:240:50 | access to local variable nonSink0 |
| LocalDataFlow.cs:227:25:227:44 | call to method Normalize | LocalDataFlow.cs:227:25:227:57 | call to method Remove |
| LocalDataFlow.cs:227:25:227:57 | call to method Remove | LocalDataFlow.cs:227:25:227:68 | call to method Split |
| LocalDataFlow.cs:227:25:227:44 | [library code] call to method Normalize | LocalDataFlow.cs:227:25:227:44 | call to method Normalize |
| LocalDataFlow.cs:227:25:227:44 | call to method Normalize | LocalDataFlow.cs:227:25:227:57 | [library code] call to method Remove |
| LocalDataFlow.cs:227:25:227:57 | [library code] call to method Remove | LocalDataFlow.cs:227:25:227:57 | call to method Remove |
| LocalDataFlow.cs:227:25:227:57 | call to method Remove | LocalDataFlow.cs:227:25:227:68 | [library code] call to method Split |
| LocalDataFlow.cs:227:25:227:68 | [library code] call to method Split | LocalDataFlow.cs:227:25:227:68 | call to method Split |
| LocalDataFlow.cs:227:25:227:68 | call to method Split | LocalDataFlow.cs:227:13:227:68 | SSA def(nonSink15) |
| LocalDataFlow.cs:231:13:231:46 | SSA def(sink34) | LocalDataFlow.cs:232:15:232:20 | access to local variable sink34 |
| LocalDataFlow.cs:231:22:231:46 | [library code] object creation of type StringBuilder | LocalDataFlow.cs:231:22:231:46 | object creation of type StringBuilder |
| LocalDataFlow.cs:231:22:231:46 | object creation of type StringBuilder | LocalDataFlow.cs:231:13:231:46 | SSA def(sink34) |
| LocalDataFlow.cs:231:40:231:45 | access to local variable sink33 | LocalDataFlow.cs:231:22:231:46 | object creation of type StringBuilder |
| LocalDataFlow.cs:231:40:231:45 | access to local variable sink33 | LocalDataFlow.cs:231:22:231:46 | [library code] object creation of type StringBuilder |
| LocalDataFlow.cs:232:15:232:20 | [post] access to local variable sink34 | LocalDataFlow.cs:233:22:233:27 | access to local variable sink34 |
| LocalDataFlow.cs:232:15:232:20 | access to local variable sink34 | LocalDataFlow.cs:233:22:233:27 | access to local variable sink34 |
| LocalDataFlow.cs:233:13:233:38 | SSA def(sink35) | LocalDataFlow.cs:234:15:234:20 | access to local variable sink35 |
| LocalDataFlow.cs:233:22:233:27 | access to local variable sink34 | LocalDataFlow.cs:233:22:233:38 | call to method ToString |
| LocalDataFlow.cs:233:22:233:27 | access to local variable sink34 | LocalDataFlow.cs:233:22:233:38 | [library code] call to method ToString |
| LocalDataFlow.cs:233:22:233:38 | [library code] call to method ToString | LocalDataFlow.cs:233:22:233:38 | call to method ToString |
| LocalDataFlow.cs:233:22:233:38 | call to method ToString | LocalDataFlow.cs:233:13:233:38 | SSA def(sink35) |
| LocalDataFlow.cs:234:15:234:20 | [post] access to local variable sink35 | LocalDataFlow.cs:236:27:236:32 | access to local variable sink35 |
| LocalDataFlow.cs:234:15:234:20 | access to local variable sink35 | LocalDataFlow.cs:236:27:236:32 | access to local variable sink35 |
| LocalDataFlow.cs:235:13:235:42 | SSA def(sink36) | LocalDataFlow.cs:236:9:236:14 | access to local variable sink36 |
| LocalDataFlow.cs:235:22:235:42 | [library code] object creation of type StringBuilder | LocalDataFlow.cs:235:22:235:42 | object creation of type StringBuilder |
| LocalDataFlow.cs:235:22:235:42 | object creation of type StringBuilder | LocalDataFlow.cs:235:13:235:42 | SSA def(sink36) |
| LocalDataFlow.cs:235:40:235:41 | "" | LocalDataFlow.cs:235:22:235:42 | object creation of type StringBuilder |
| LocalDataFlow.cs:235:40:235:41 | "" | LocalDataFlow.cs:235:22:235:42 | [library code] object creation of type StringBuilder |
| LocalDataFlow.cs:236:9:236:14 | [post] access to local variable sink36 | LocalDataFlow.cs:237:15:237:20 | access to local variable sink36 |
| LocalDataFlow.cs:236:9:236:14 | access to local variable sink36 | LocalDataFlow.cs:237:15:237:20 | access to local variable sink36 |
| LocalDataFlow.cs:236:27:236:32 | access to local variable sink35 | LocalDataFlow.cs:236:9:236:14 | access to local variable sink36 |
| LocalDataFlow.cs:236:9:236:33 | [library code] call to method AppendLine | LocalDataFlow.cs:236:9:236:14 | access to local variable sink36 |
| LocalDataFlow.cs:236:27:236:32 | access to local variable sink35 | LocalDataFlow.cs:236:9:236:33 | [library code] call to method AppendLine |
| LocalDataFlow.cs:240:13:240:51 | SSA def(nonSink10) | LocalDataFlow.cs:241:15:241:23 | access to local variable nonSink10 |
| LocalDataFlow.cs:240:25:240:51 | [library code] object creation of type StringBuilder | LocalDataFlow.cs:240:25:240:51 | object creation of type StringBuilder |
| LocalDataFlow.cs:240:25:240:51 | object creation of type StringBuilder | LocalDataFlow.cs:240:13:240:51 | SSA def(nonSink10) |
| LocalDataFlow.cs:240:43:240:50 | access to local variable nonSink0 | LocalDataFlow.cs:240:25:240:51 | object creation of type StringBuilder |
| LocalDataFlow.cs:240:43:240:50 | access to local variable nonSink0 | LocalDataFlow.cs:240:25:240:51 | [library code] object creation of type StringBuilder |
| LocalDataFlow.cs:241:15:241:23 | [post] access to local variable nonSink10 | LocalDataFlow.cs:242:20:242:28 | access to local variable nonSink10 |
| LocalDataFlow.cs:241:15:241:23 | access to local variable nonSink10 | LocalDataFlow.cs:242:20:242:28 | access to local variable nonSink10 |
| LocalDataFlow.cs:242:9:242:39 | SSA def(nonSink0) | LocalDataFlow.cs:243:15:243:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:242:20:242:28 | [post] access to local variable nonSink10 | LocalDataFlow.cs:244:9:244:17 | access to local variable nonSink10 |
| LocalDataFlow.cs:242:20:242:28 | access to local variable nonSink10 | LocalDataFlow.cs:242:20:242:39 | call to method ToString |
| LocalDataFlow.cs:242:20:242:28 | access to local variable nonSink10 | LocalDataFlow.cs:242:20:242:39 | [library code] call to method ToString |
| LocalDataFlow.cs:242:20:242:28 | access to local variable nonSink10 | LocalDataFlow.cs:244:9:244:17 | access to local variable nonSink10 |
| LocalDataFlow.cs:242:20:242:39 | [library code] call to method ToString | LocalDataFlow.cs:242:20:242:39 | call to method ToString |
| LocalDataFlow.cs:242:20:242:39 | call to method ToString | LocalDataFlow.cs:242:9:242:39 | SSA def(nonSink0) |
| LocalDataFlow.cs:243:15:243:22 | [post] access to local variable nonSink0 | LocalDataFlow.cs:244:30:244:37 | access to local variable nonSink0 |
| LocalDataFlow.cs:243:15:243:22 | access to local variable nonSink0 | LocalDataFlow.cs:244:30:244:37 | access to local variable nonSink0 |
| LocalDataFlow.cs:244:9:244:17 | [post] access to local variable nonSink10 | LocalDataFlow.cs:245:15:245:23 | access to local variable nonSink10 |
| LocalDataFlow.cs:244:9:244:17 | access to local variable nonSink10 | LocalDataFlow.cs:245:15:245:23 | access to local variable nonSink10 |
| LocalDataFlow.cs:244:30:244:37 | access to local variable nonSink0 | LocalDataFlow.cs:244:9:244:17 | access to local variable nonSink10 |
| LocalDataFlow.cs:244:9:244:38 | [library code] call to method AppendLine | LocalDataFlow.cs:244:9:244:17 | access to local variable nonSink10 |
| LocalDataFlow.cs:244:30:244:37 | access to local variable nonSink0 | LocalDataFlow.cs:244:9:244:38 | [library code] call to method AppendLine |
| LocalDataFlow.cs:248:13:248:52 | SSA def(taintedDataContract) | LocalDataFlow.cs:249:22:249:40 | access to local variable taintedDataContract |
| LocalDataFlow.cs:248:13:248:52 | SSA qualifier def(taintedDataContract.AList) | LocalDataFlow.cs:251:22:251:46 | access to property AList |
| LocalDataFlow.cs:248:35:248:52 | object creation of type DataContract | LocalDataFlow.cs:248:13:248:52 | SSA def(taintedDataContract) |
| LocalDataFlow.cs:249:13:249:48 | SSA def(sink53) | LocalDataFlow.cs:250:15:250:20 | access to local variable sink53 |
| LocalDataFlow.cs:249:22:249:40 | [post] access to local variable taintedDataContract | LocalDataFlow.cs:251:22:251:40 | access to local variable taintedDataContract |
| LocalDataFlow.cs:249:22:249:40 | access to local variable taintedDataContract | LocalDataFlow.cs:249:22:249:48 | [library code] access to property AString |
| LocalDataFlow.cs:249:22:249:40 | access to local variable taintedDataContract | LocalDataFlow.cs:249:22:249:48 | access to property AString |
| LocalDataFlow.cs:249:22:249:40 | access to local variable taintedDataContract | LocalDataFlow.cs:251:22:251:40 | access to local variable taintedDataContract |
| LocalDataFlow.cs:249:22:249:48 | [library code] access to property AString | LocalDataFlow.cs:249:22:249:48 | access to property AString |
| LocalDataFlow.cs:249:22:249:48 | access to property AString | LocalDataFlow.cs:249:13:249:48 | SSA def(sink53) |
| LocalDataFlow.cs:251:13:251:57 | SSA def(sink54) | LocalDataFlow.cs:252:15:252:20 | access to local variable sink54 |
| LocalDataFlow.cs:251:22:251:40 | [post] access to local variable taintedDataContract | LocalDataFlow.cs:258:20:258:38 | access to local variable taintedDataContract |
| LocalDataFlow.cs:251:22:251:40 | access to local variable taintedDataContract | LocalDataFlow.cs:251:22:251:46 | [library code] access to property AList |
| LocalDataFlow.cs:251:22:251:40 | access to local variable taintedDataContract | LocalDataFlow.cs:251:22:251:46 | access to property AList |
| LocalDataFlow.cs:251:22:251:40 | access to local variable taintedDataContract | LocalDataFlow.cs:258:20:258:38 | access to local variable taintedDataContract |
| LocalDataFlow.cs:251:22:251:46 | [library code] access to property AList | LocalDataFlow.cs:251:22:251:46 | access to property AList |
| LocalDataFlow.cs:251:22:251:46 | [post] access to property AList | LocalDataFlow.cs:260:20:260:44 | access to property AList |
| LocalDataFlow.cs:251:22:251:46 | access to property AList | LocalDataFlow.cs:251:22:251:49 | access to indexer |
| LocalDataFlow.cs:251:22:251:46 | access to property AList | LocalDataFlow.cs:260:20:260:44 | access to property AList |
| LocalDataFlow.cs:251:22:251:49 | access to indexer | LocalDataFlow.cs:251:22:251:57 | [library code] access to property AString |
| LocalDataFlow.cs:251:22:251:49 | access to indexer | LocalDataFlow.cs:251:22:251:57 | access to property AString |
| LocalDataFlow.cs:251:22:251:57 | [library code] access to property AString | LocalDataFlow.cs:251:22:251:57 | access to property AString |
| LocalDataFlow.cs:251:22:251:57 | access to property AString | LocalDataFlow.cs:251:13:251:57 | SSA def(sink54) |
| LocalDataFlow.cs:255:13:255:55 | SSA def(nonTaintedDataContract) | LocalDataFlow.cs:256:20:256:41 | access to local variable nonTaintedDataContract |
| LocalDataFlow.cs:255:38:255:55 | object creation of type DataContract | LocalDataFlow.cs:255:13:255:55 | SSA def(nonTaintedDataContract) |
| LocalDataFlow.cs:256:9:256:49 | SSA def(nonSink0) | LocalDataFlow.cs:257:15:257:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:256:20:256:41 | access to local variable nonTaintedDataContract | LocalDataFlow.cs:256:20:256:49 | [library code] access to property AString |
| LocalDataFlow.cs:256:20:256:41 | access to local variable nonTaintedDataContract | LocalDataFlow.cs:256:20:256:49 | access to property AString |
| LocalDataFlow.cs:256:20:256:49 | [library code] access to property AString | LocalDataFlow.cs:256:20:256:49 | access to property AString |
| LocalDataFlow.cs:256:20:256:49 | access to property AString | LocalDataFlow.cs:256:9:256:49 | SSA def(nonSink0) |
| LocalDataFlow.cs:258:9:258:44 | SSA def(nonSink2) | LocalDataFlow.cs:259:15:259:22 | access to local variable nonSink2 |
| LocalDataFlow.cs:258:20:258:38 | [post] access to local variable taintedDataContract | LocalDataFlow.cs:260:20:260:38 | access to local variable taintedDataContract |
| LocalDataFlow.cs:258:20:258:38 | access to local variable taintedDataContract | LocalDataFlow.cs:260:20:260:38 | access to local variable taintedDataContract |
| LocalDataFlow.cs:258:20:258:44 | access to property AnInt | LocalDataFlow.cs:258:9:258:44 | SSA def(nonSink2) |
| LocalDataFlow.cs:260:9:260:53 | SSA def(nonSink2) | LocalDataFlow.cs:261:15:261:22 | access to local variable nonSink2 |
| LocalDataFlow.cs:260:20:260:38 | access to local variable taintedDataContract | LocalDataFlow.cs:260:20:260:44 | [library code] access to property AList |
| LocalDataFlow.cs:260:20:260:38 | access to local variable taintedDataContract | LocalDataFlow.cs:260:20:260:44 | access to property AList |
| LocalDataFlow.cs:260:20:260:44 | [library code] access to property AList | LocalDataFlow.cs:260:20:260:44 | access to property AList |
| LocalDataFlow.cs:260:20:260:44 | access to property AList | LocalDataFlow.cs:260:20:260:47 | access to indexer |
| LocalDataFlow.cs:260:20:260:53 | access to property AnInt | LocalDataFlow.cs:260:9:260:53 | SSA def(nonSink2) |
| LocalDataFlow.cs:264:17:264:37 | SSA def(taintedTextBox) | LocalDataFlow.cs:265:22:265:35 | access to local variable taintedTextBox |
| LocalDataFlow.cs:264:34:264:37 | null | LocalDataFlow.cs:264:17:264:37 | SSA def(taintedTextBox) |
| LocalDataFlow.cs:265:13:265:40 | SSA def(sink60) | LocalDataFlow.cs:266:15:266:20 | access to local variable sink60 |
| LocalDataFlow.cs:265:22:265:35 | access to local variable taintedTextBox | LocalDataFlow.cs:265:22:265:40 | access to property Text |
| LocalDataFlow.cs:265:22:265:35 | access to local variable taintedTextBox | LocalDataFlow.cs:265:22:265:40 | [library code] access to property Text |
| LocalDataFlow.cs:265:22:265:40 | [library code] access to property Text | LocalDataFlow.cs:265:22:265:40 | access to property Text |
| LocalDataFlow.cs:265:22:265:40 | access to property Text | LocalDataFlow.cs:265:13:265:40 | SSA def(sink60) |
| LocalDataFlow.cs:269:17:269:40 | SSA def(nonTaintedTextBox) | LocalDataFlow.cs:270:20:270:36 | access to local variable nonTaintedTextBox |
| LocalDataFlow.cs:269:37:269:40 | null | LocalDataFlow.cs:269:17:269:40 | SSA def(nonTaintedTextBox) |
| LocalDataFlow.cs:270:9:270:41 | SSA def(nonSink0) | LocalDataFlow.cs:271:15:271:22 | access to local variable nonSink0 |
| LocalDataFlow.cs:270:20:270:36 | access to local variable nonTaintedTextBox | LocalDataFlow.cs:270:20:270:41 | access to property Text |
| LocalDataFlow.cs:270:20:270:36 | access to local variable nonTaintedTextBox | LocalDataFlow.cs:270:20:270:41 | [library code] access to property Text |
| LocalDataFlow.cs:270:20:270:41 | [library code] access to property Text | LocalDataFlow.cs:270:20:270:41 | access to property Text |
| LocalDataFlow.cs:270:20:270:41 | access to property Text | LocalDataFlow.cs:270:9:270:41 | SSA def(nonSink0) |
| LocalDataFlow.cs:274:13:274:51 | SSA def(sink67) | LocalDataFlow.cs:275:15:275:20 | access to local variable sink67 |
| LocalDataFlow.cs:274:22:274:51 | [library code] call to method Run | LocalDataFlow.cs:274:22:274:51 | call to method Run |
| LocalDataFlow.cs:274:22:274:51 | call to method Run | LocalDataFlow.cs:274:13:274:51 | SSA def(sink67) |
| LocalDataFlow.cs:274:31:274:50 | [output] (...) => ... | LocalDataFlow.cs:274:22:274:51 | call to method Run |
| LocalDataFlow.cs:274:31:274:50 | [output] (...) => ... | LocalDataFlow.cs:274:22:274:51 | [library code] call to method Run |
| LocalDataFlow.cs:275:15:275:20 | [post] access to local variable sink67 | LocalDataFlow.cs:276:28:276:33 | access to local variable sink67 |
| LocalDataFlow.cs:275:15:275:20 | access to local variable sink67 | LocalDataFlow.cs:276:28:276:33 | access to local variable sink67 |
| LocalDataFlow.cs:276:13:276:33 | SSA def(sink68) | LocalDataFlow.cs:277:15:277:20 | access to local variable sink68 |
| LocalDataFlow.cs:276:22:276:33 | await ... | LocalDataFlow.cs:276:13:276:33 | SSA def(sink68) |
| LocalDataFlow.cs:276:28:276:33 | access to local variable sink67 | LocalDataFlow.cs:276:22:276:33 | await ... |
| LocalDataFlow.cs:280:13:280:42 | SSA def(nonSink21) | LocalDataFlow.cs:281:15:281:23 | access to local variable nonSink21 |
| LocalDataFlow.cs:280:25:280:42 | [library code] call to method Run | LocalDataFlow.cs:280:25:280:42 | call to method Run |
| LocalDataFlow.cs:280:25:280:42 | call to method Run | LocalDataFlow.cs:280:13:280:42 | SSA def(nonSink21) |
| LocalDataFlow.cs:280:34:280:41 | [output] (...) => ... | LocalDataFlow.cs:280:25:280:42 | call to method Run |
| LocalDataFlow.cs:280:34:280:41 | [output] (...) => ... | LocalDataFlow.cs:280:25:280:42 | [library code] call to method Run |
| LocalDataFlow.cs:281:15:281:23 | [post] access to local variable nonSink21 | LocalDataFlow.cs:282:26:282:34 | access to local variable nonSink21 |
| LocalDataFlow.cs:281:15:281:23 | access to local variable nonSink21 | LocalDataFlow.cs:282:26:282:34 | access to local variable nonSink21 |
| LocalDataFlow.cs:282:9:282:34 | SSA def(nonSink0) | LocalDataFlow.cs:283:15:283:22 | access to local variable nonSink0 |
@@ -525,28 +629,20 @@
| LocalDataFlow.cs:327:31:327:38 | access to local variable nonSink0 | LocalDataFlow.cs:327:22:327:38 | ... ?? ... |
| LocalDataFlow.cs:347:28:347:30 | this | LocalDataFlow.cs:347:41:347:45 | this access |
| LocalDataFlow.cs:347:50:347:52 | this | LocalDataFlow.cs:347:56:347:60 | this access |
| LocalDataFlow.cs:347:50:347:52 | value | LocalDataFlow.cs:347:50:347:52 | value |
| LocalDataFlow.cs:347:50:347:52 | value | LocalDataFlow.cs:347:64:347:68 | access to parameter value |
| LocalDataFlow.cs:353:41:353:47 | tainted | LocalDataFlow.cs:353:41:353:47 | tainted |
| LocalDataFlow.cs:353:41:353:47 | tainted | LocalDataFlow.cs:355:15:355:21 | access to parameter tainted |
| LocalDataFlow.cs:358:44:358:53 | nonTainted | LocalDataFlow.cs:358:44:358:53 | nonTainted |
| LocalDataFlow.cs:358:44:358:53 | nonTainted | LocalDataFlow.cs:360:15:360:24 | access to parameter nonTainted |
| LocalDataFlow.cs:363:44:363:44 | x | LocalDataFlow.cs:363:44:363:44 | x |
| LocalDataFlow.cs:363:44:363:44 | x | LocalDataFlow.cs:366:21:366:21 | access to parameter x |
| LocalDataFlow.cs:363:67:363:68 | os | LocalDataFlow.cs:363:67:363:68 | os |
| LocalDataFlow.cs:363:67:363:68 | os | LocalDataFlow.cs:369:32:369:33 | access to parameter os |
| LocalDataFlow.cs:366:21:366:21 | access to parameter x | LocalDataFlow.cs:366:16:366:21 | ... = ... |
| LocalDataFlow.cs:369:32:369:33 | access to parameter os | LocalDataFlow.cs:369:26:369:33 | ... = ... |
| LocalDataFlow.cs:374:41:374:44 | args | LocalDataFlow.cs:374:41:374:44 | args |
| LocalDataFlow.cs:374:41:374:44 | args | LocalDataFlow.cs:376:29:376:32 | access to parameter args |
| LocalDataFlow.cs:376:29:376:32 | [post] access to parameter args | LocalDataFlow.cs:377:27:377:30 | access to parameter args |
| LocalDataFlow.cs:376:29:376:32 | access to parameter args | LocalDataFlow.cs:376:29:376:32 | call to operator implicit conversion |
| LocalDataFlow.cs:376:29:376:32 | access to parameter args | LocalDataFlow.cs:377:27:377:30 | access to parameter args |
| SSA.cs:5:17:5:17 | SSA entry def(this.S) | SSA.cs:67:9:67:14 | access to field S |
| SSA.cs:5:17:5:17 | this | SSA.cs:67:9:67:12 | this access |
| SSA.cs:5:26:5:32 | tainted | SSA.cs:5:26:5:32 | tainted |
| SSA.cs:5:26:5:32 | tainted | SSA.cs:8:24:8:30 | access to parameter tainted |
| SSA.cs:5:42:5:51 | nonTainted | SSA.cs:5:42:5:51 | nonTainted |
| SSA.cs:5:42:5:51 | nonTainted | SSA.cs:12:24:12:33 | access to parameter nonTainted |
| SSA.cs:8:13:8:30 | SSA def(ssaSink0) | SSA.cs:9:15:9:22 | access to local variable ssaSink0 |
| SSA.cs:8:24:8:30 | access to parameter tainted | SSA.cs:8:13:8:30 | SSA def(ssaSink0) |
@@ -826,7 +922,6 @@
| SSA.cs:136:23:136:28 | SSA def(this.S) | SSA.cs:137:15:137:20 | access to field S |
| SSA.cs:136:23:136:28 | SSA qualifier def(this.S.SsaFieldNonSink0) | SSA.cs:137:15:137:37 | access to field SsaFieldNonSink0 |
| SSA.cs:136:23:136:28 | access to field S | SSA.cs:136:23:136:28 | SSA def(this.S) |
| SSA.cs:144:34:144:34 | t | SSA.cs:144:34:144:34 | t |
| SSA.cs:144:34:144:34 | t | SSA.cs:146:13:146:13 | access to parameter t |
| SSA.cs:146:13:146:13 | (...) ... | SSA.cs:146:13:146:21 | ... == ... |
| SSA.cs:146:13:146:13 | access to parameter t | SSA.cs:146:13:146:13 | (...) ... |
@@ -835,7 +930,6 @@
| SSA.cs:147:17:147:26 | default(...) | SSA.cs:147:13:147:26 | SSA def(t) |
| SSA.cs:149:13:149:17 | SSA def(t) | SSA.cs:144:17:144:26 | SSA phi(t) |
| SSA.cs:149:17:149:17 | access to parameter t | SSA.cs:149:13:149:17 | SSA def(t) |
| SSA.cs:152:36:152:36 | t | SSA.cs:152:36:152:36 | t |
| SSA.cs:152:36:152:36 | t | SSA.cs:154:13:154:13 | access to parameter t |
| SSA.cs:154:13:154:13 | (...) ... | SSA.cs:154:13:154:21 | ... == ... |
| SSA.cs:154:13:154:13 | access to parameter t | SSA.cs:152:17:152:28 | SSA phi(t) |
@@ -844,9 +938,7 @@
| SSA.cs:155:25:155:25 | SSA def(t) | SSA.cs:152:17:152:28 | SSA phi(t) |
| SSA.cs:155:25:155:25 | access to parameter t | SSA.cs:152:17:152:28 | SSA phi(t) |
| SSA.cs:166:10:166:13 | this | SSA.cs:166:19:166:22 | this access |
| SSA.cs:168:22:168:28 | tainted | SSA.cs:168:22:168:28 | tainted |
| SSA.cs:168:22:168:28 | tainted | SSA.cs:173:24:173:30 | access to parameter tainted |
| SSA.cs:168:35:168:35 | i | SSA.cs:168:35:168:35 | i |
| SSA.cs:168:35:168:35 | i | SSA.cs:171:13:171:13 | access to parameter i |
| SSA.cs:170:16:170:28 | SSA def(ssaSink5) | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) |
| SSA.cs:170:27:170:28 | "" | SSA.cs:170:16:170:28 | SSA def(ssaSink5) |
@@ -863,9 +955,7 @@
| SSA.cs:177:21:177:28 | access to local variable ssaSink5 | SSA.cs:176:21:176:28 | access to local variable ssaSink5 |
| SSA.cs:177:21:177:28 | access to local variable ssaSink5 | SSA.cs:180:9:180:24 | SSA phi(ssaSink5) |
| SSA.cs:180:9:180:24 | SSA phi(ssaSink5) | SSA.cs:180:15:180:22 | access to local variable ssaSink5 |
| Splitting.cs:3:18:3:18 | b | Splitting.cs:3:18:3:18 | b |
| Splitting.cs:3:18:3:18 | b | Splitting.cs:6:13:6:13 | access to parameter b |
| Splitting.cs:3:28:3:34 | tainted | Splitting.cs:3:28:3:34 | tainted |
| Splitting.cs:3:28:3:34 | tainted | Splitting.cs:5:17:5:23 | access to parameter tainted |
| Splitting.cs:5:13:5:23 | SSA def(x) | Splitting.cs:8:19:8:19 | [b (line 3): true] access to local variable x |
| Splitting.cs:5:13:5:23 | SSA def(x) | Splitting.cs:12:15:12:15 | [b (line 3): false] access to local variable x |
@@ -878,7 +968,6 @@
| Splitting.cs:9:17:9:17 | [b (line 3): true] access to local variable x | Splitting.cs:12:15:12:15 | [b (line 3): true] access to local variable x |
| Splitting.cs:12:15:12:15 | [b (line 3): true] access to local variable x | Splitting.cs:14:19:14:19 | access to local variable x |
| Splitting.cs:12:15:12:15 | [post] [b (line 3): true] access to local variable x | Splitting.cs:14:19:14:19 | access to local variable x |
| Splitting.cs:17:18:17:18 | b | Splitting.cs:17:18:17:18 | b |
| Splitting.cs:17:18:17:18 | b | Splitting.cs:20:13:20:13 | access to parameter b |
| Splitting.cs:19:13:19:18 | SSA def(x) | Splitting.cs:22:19:22:19 | [b (line 17): true] access to local variable x |
| Splitting.cs:19:13:19:18 | SSA def(x) | Splitting.cs:25:15:25:15 | [b (line 17): false] access to local variable x |
@@ -891,7 +980,6 @@
| Splitting.cs:25:15:25:15 | [b (line 17): true] access to local variable x | Splitting.cs:27:19:27:19 | access to local variable x |
| Splitting.cs:25:15:25:15 | [post] [b (line 17): false] access to local variable x | Splitting.cs:29:19:29:19 | access to local variable x |
| Splitting.cs:25:15:25:15 | [post] [b (line 17): true] access to local variable x | Splitting.cs:27:19:27:19 | access to local variable x |
| Splitting.cs:32:18:32:18 | b | Splitting.cs:32:18:32:18 | b |
| Splitting.cs:32:18:32:18 | b | Splitting.cs:35:13:35:13 | access to parameter b |
| Splitting.cs:35:13:35:13 | access to parameter b | Splitting.cs:39:15:39:15 | [b (line 32): false] access to parameter b |
| Splitting.cs:35:13:35:13 | access to parameter b | Splitting.cs:39:15:39:15 | [b (line 32): true] access to parameter b |
@@ -912,7 +1000,6 @@
| Splitting.cs:40:23:40:23 | [b (line 32): true] access to local variable x | Splitting.cs:40:15:40:23 | [b (line 32): true] (...) ... |
| Splitting.cs:41:19:41:21 | [b (line 32): false] "d" | Splitting.cs:41:15:41:21 | [b (line 32): false] ... = ... |
| Splitting.cs:41:19:41:21 | [b (line 32): true] "d" | Splitting.cs:41:15:41:21 | [b (line 32): true] ... = ... |
| Splitting.cs:46:18:46:18 | b | Splitting.cs:46:18:46:18 | b |
| Splitting.cs:46:18:46:18 | b | Splitting.cs:49:13:49:13 | access to parameter b |
| Splitting.cs:48:13:48:18 | SSA def(x) | Splitting.cs:53:13:53:13 | [b (line 46): false] access to local variable x |
| Splitting.cs:48:17:48:18 | "" | Splitting.cs:48:13:48:18 | SSA def(x) |

View File

@@ -70,7 +70,7 @@ The process must begin with the first step and must conclude with the final step
d. Provide one or more `@tags` describing the query.
- Tags are free-form, but we have some conventions, especially for tagging security queries with corresponding CWE numbers.
- Tags are free-form, but we have some conventions. At a minimum, most queries should have at least one of `correctness`, `maintainability` or `security` to indicate the general kind of issue the query is intended to find. Security queries should also be tagged with corresponding [CWE](https://cwe.mitre.org/data/definitions/1000.html) numbers, for example `external/cwe/cwe-119` (prefer the most specific CWE that encompasses the target of the query).
7. **Move your query out of `experimental`**

View File

@@ -290,6 +290,7 @@ private class AmdDependencyImport extends Import {
* ```
*/
class AmdModule extends Module {
cached
AmdModule() { strictcount(AmdModuleDefinition def | amdModuleTopLevel(def, this)) = 1 }
/** Gets the definition of this module. */

View File

@@ -748,24 +748,18 @@ private predicate basicFlowStep(
* This predicate is field insensitive (it does not distinguish between `x` and `x.p`)
* and hence should only be used for purposes of approximation.
*/
pragma[inline]
private predicate exploratoryFlowStep(
DataFlow::Node pred, DataFlow::Node succ, DataFlow::Configuration cfg
) {
isRelevantForward(pred, cfg) and
isLive() and
(
basicFlowStepNoBarrier(pred, succ, _, cfg) or
basicStoreStep(pred, succ, _) or
basicLoadStep(pred, succ, _) or
isAdditionalStoreStep(pred, succ, _, cfg) or
isAdditionalLoadStep(pred, succ, _, cfg) or
isAdditionalLoadStoreStep(pred, succ, _, _, cfg) or
// the following three disjuncts taken together over-approximate flow through
// higher-order calls
callback(pred, succ) or
succ = pred.(DataFlow::FunctionNode).getAParameter() or
exploratoryBoundInvokeStep(pred, succ)
)
basicFlowStepNoBarrier(pred, succ, _, cfg) or
exploratoryLoadStep(pred, succ, cfg) or
isAdditionalLoadStoreStep(pred, succ, _, _, cfg) or
// the following three disjuncts taken together over-approximate flow through
// higher-order calls
callback(pred, succ) or
succ = pred.(DataFlow::FunctionNode).getAParameter() or
exploratoryBoundInvokeStep(pred, succ)
}
/**
@@ -792,15 +786,106 @@ private predicate isSink(DataFlow::Node nd, DataFlow::Configuration cfg, FlowLab
cfg.isSink(nd, lbl)
}
/**
* Holds if there exists a load-step from `pred` to `succ` under configuration `cfg`,
* and the forwards exploratory flow has found a relevant store-step with the same property as the load-step.
*/
private predicate exploratoryLoadStep(
DataFlow::Node pred, DataFlow::Node succ, DataFlow::Configuration cfg
) {
exists(string prop | prop = getAForwardRelevantLoadProperty(cfg) |
isAdditionalLoadStep(pred, succ, prop, cfg)
or
basicLoadStep(pred, succ, prop)
)
}
/**
* Gets a property where the forwards exploratory flow has found a relevant store-step with that property.
* The property is therefore relevant for load-steps in the forward exploratory flow.
*
* This private predicate is only used in `exploratoryLoadStep`, and exists as a separate predicate to give the compiler a hint about join-ordering.
*/
private string getAForwardRelevantLoadProperty(DataFlow::Configuration cfg) {
exists(DataFlow::Node previous | isRelevantForward(previous, cfg) |
basicStoreStep(previous, _, result) or
isAdditionalStoreStep(previous, _, result, cfg)
)
or
result = getAPropertyUsedInLoadStore(cfg)
}
/**
* Gets a property that is used in an `additionalLoadStoreStep` where the loaded and stored property are not the same.
*
* The properties from this predicate are used as a white-list of properties for load/store steps that should always be considered in the exploratory flow.
*/
private string getAPropertyUsedInLoadStore(DataFlow::Configuration cfg) {
exists(string loadProp, string storeProp |
isAdditionalLoadStoreStep(_, _, loadProp, storeProp, cfg) and
storeProp != loadProp and
result = [storeProp, loadProp]
)
}
/**
* Holds if there exists a store-step from `pred` to `succ` under configuration `cfg`,
* and somewhere in the program there exists a load-step that could possibly read the stored value.
*/
private predicate exploratoryForwardStoreStep(
DataFlow::Node pred, DataFlow::Node succ, DataFlow::Configuration cfg
) {
exists(string prop |
basicLoadStep(_, _, prop) or
isAdditionalLoadStep(_, _, prop, cfg) or
prop = getAPropertyUsedInLoadStore(cfg)
|
isAdditionalStoreStep(pred, succ, prop, cfg) or
basicStoreStep(pred, succ, prop)
)
}
/**
* Holds if there exists a store-step from `pred` to `succ` under configuration `cfg`,
* and `succ` has been found to be relevant during the backwards exploratory flow,
* and the backwards exploratory flow has found a relevant load-step with the same property as the store-step.
*/
private predicate exploratoryBackwardStoreStep(
DataFlow::Node pred, DataFlow::Node succ, DataFlow::Configuration cfg
) {
exists(string prop | prop = getABackwardsRelevantStoreProperty(cfg) |
isAdditionalStoreStep(pred, succ, prop, cfg) or
basicStoreStep(pred, succ, prop)
)
}
/**
* Gets a property where the backwards exploratory flow has found a relevant load-step with that property.
* The property is therefore relevant for store-steps in the backwards exploratory flow.
*
* This private predicate is only used in `exploratoryBackwardStoreStep`, and exists as a separate predicate to give the compiler a hint about join-ordering.
*/
private string getABackwardsRelevantStoreProperty(DataFlow::Configuration cfg) {
exists(DataFlow::Node mid | isRelevant(mid, cfg) |
basicLoadStep(mid, _, result) or
isAdditionalLoadStep(mid, _, result, cfg)
)
or
result = getAPropertyUsedInLoadStore(cfg)
}
/**
* Holds if `nd` may be reachable from a source under `cfg`.
*
* No call/return matching is done, so this is a relatively coarse over-approximation.
*/
private predicate isRelevantForward(DataFlow::Node nd, DataFlow::Configuration cfg) {
isSource(nd, cfg, _)
isSource(nd, cfg, _) and isLive()
or
exists(DataFlow::Node mid | isRelevantForward(mid, cfg) and exploratoryFlowStep(mid, nd, cfg))
exists(DataFlow::Node mid | isRelevantForward(mid, cfg) |
exploratoryFlowStep(mid, nd, cfg) or
exploratoryForwardStoreStep(mid, nd, cfg)
)
}
/**
@@ -809,13 +894,21 @@ private predicate isRelevantForward(DataFlow::Node nd, DataFlow::Configuration c
* No call/return matching is done, so this is a relatively coarse over-approximation.
*/
private predicate isRelevant(DataFlow::Node nd, DataFlow::Configuration cfg) {
isRelevantForward(nd, cfg) and
isSink(nd, cfg, _)
isRelevantForward(nd, cfg) and isSink(nd, cfg, _)
or
exists(DataFlow::Node mid |
isRelevant(mid, cfg) and
exploratoryFlowStep(nd, mid, cfg) and
isRelevantForward(nd, cfg)
exists(DataFlow::Node mid | isRelevant(mid, cfg) | isRelevantBackStep(mid, nd, cfg))
}
/**
* Holds if there is backwards data-flow step from `mid` to `nd` under `cfg`.
*/
private predicate isRelevantBackStep(
DataFlow::Node mid, DataFlow::Node nd, DataFlow::Configuration cfg
) {
isRelevantForward(nd, cfg) and
(
exploratoryFlowStep(nd, mid, cfg) or
exploratoryBackwardStoreStep(nd, mid, cfg)
)
}

View File

@@ -118,7 +118,11 @@ module DataFlow {
predicate accessesGlobal(string g) { globalVarRef(g).flowsTo(this) }
/** Holds if this node may evaluate to the string `s`, possibly through local data flow. */
predicate mayHaveStringValue(string s) { getAPredecessor().mayHaveStringValue(s) }
predicate mayHaveStringValue(string s) {
getAPredecessor().mayHaveStringValue(s)
or
s = getStringValue()
}
/** Gets the string value of this node, if it is a string literal or constant string concatenation. */
string getStringValue() { result = asExpr().getStringValue() }
@@ -297,11 +301,6 @@ module DataFlow {
/** Gets the expression or declaration this node corresponds to. */
override AST::ValueNode getAstNode() { result = astNode }
override predicate mayHaveStringValue(string s) {
Node.super.mayHaveStringValue(s) or
astNode.(ConstantString).getStringValue() = s
}
override BasicBlock getBasicBlock() { astNode = result.getANode() }
override predicate hasLocationInfo(
@@ -587,6 +586,7 @@ module DataFlow {
* This predicate is undefined for spread properties, accessor
* properties, and most uses of `Object.defineProperty`.
*/
pragma[nomagic]
abstract Node getRhs();
/**
@@ -648,25 +648,24 @@ module DataFlow {
* writes to the corresponding property.
*/
private class ObjectDefinePropertyAsPropWrite extends PropWrite, ValueNode {
CallToObjectDefineProperty odp;
override MethodCallExpr astNode;
ObjectDefinePropertyAsPropWrite() { odp = this }
override Node getBase() { result = odp.getBaseObject() }
override Expr getPropertyNameExpr() { result = odp.getArgument(1).asExpr() }
override string getPropertyName() { result = odp.getPropertyName() }
override Node getRhs() {
// not using `CallToObjectDefineProperty::getAPropertyAttribute` for performance reasons
exists(ObjectLiteralNode propdesc |
propdesc.flowsTo(odp.getPropertyDescriptor()) and
propdesc.hasPropertyWrite("value", result)
)
ObjectDefinePropertyAsPropWrite() {
astNode.getReceiver().(GlobalVarAccess).getName() = "Object" and
astNode.getMethodName() = "defineProperty"
}
override ControlFlowNode getWriteNode() { result = odp.getAstNode() }
override Node getBase() { result = astNode.getArgument(0).flow() }
override Expr getPropertyNameExpr() { result = astNode.getArgument(1) }
override string getPropertyName() { result = astNode.getArgument(1).getStringValue() }
override Node getRhs() {
result = astNode.getArgument(2).(ObjectExpr).getPropertyByName("value").getInit().flow()
}
override ControlFlowNode getWriteNode() { result = astNode }
}
/**

View File

@@ -156,6 +156,7 @@ class InvokeNode extends DataFlow::SourceNode {
* Holds if the `i`th argument of this invocation is an object literal whose property
* `name` is set to `result`.
*/
pragma[nomagic]
DataFlow::ValueNode getOptionArgument(int i, string name) {
getOptionsArgument(i).hasPropertyWrite(name, result)
}

View File

@@ -70,6 +70,7 @@ class SourceNode extends DataFlow::Node {
* Holds if there is an assignment to property `propName` on this node,
* and the right hand side of the assignment is `rhs`.
*/
pragma[nomagic]
predicate hasPropertyWrite(string propName, DataFlow::Node rhs) {
rhs = getAPropertyWrite(propName).getRhs()
}

View File

@@ -461,6 +461,7 @@ class ComponentDirective extends CustomDirective, MkCustomComponent {
override DataFlow::Node getDefinition() { result = comp }
pragma[nomagic]
override DataFlow::ValueNode getMemberInit(string name) {
comp.getConfig().hasPropertyWrite(name, result)
}

View File

@@ -37,12 +37,50 @@ private class OrdinaryJQueryObject extends JQueryObjectInternal {
OrdinaryJQueryObject() {
exists(JQuery::MethodCall jq |
this.flow().getALocalSource() = jq and
// `jQuery.val()` does _not_ return a jQuery object
jq.getMethodName() != "val"
returnsAJQueryObject(jq, jq.getMethodName())
)
}
}
/**
* Holds if the jQuery method call `call`, with name `methodName`, returns a JQuery object.
*
* The `call` parameter has type `DataFlow::CallNode` instead of `JQuery::MethodCall` to avoid non-monotonic recursion.
* The not is placed inside the predicate to avoid non-monotonic recursion.
*/
bindingset[methodName, call]
private predicate returnsAJQueryObject(DataFlow::CallNode call, string methodName) {
not (
neverReturnsJQuery(methodName)
or
methodName = "val" and call.getNumArgument() = 0 // `jQuery.val()`
or
methodName = ["html", "text"] and call.getNumArgument() = 0 // `jQuery.html()`/`jQuery.text()`
or
// `jQuery.attr(key)`/`jQuery.prop(key)`
methodName = ["attr", "prop"] and
call.getNumArgument() = 1 and
call.getArgument(0).mayHaveStringValue(_)
)
}
/**
* Holds if a jQuery method named `name` never returns a JQuery object.
*/
private predicate neverReturnsJQuery(string name) {
forex(ExternalMemberDecl decl |
decl.getBaseName() = "jQuery" and
decl.getName() = name
|
not decl
.getDocumentation()
.getATagByTitle("return")
.getType()
.getAnUnderlyingType()
.hasQualifiedName("jQuery")
)
}
/**
* DEPRECATED. Use `JQuery::MethodCall` instead.
*

View File

@@ -17,3 +17,15 @@ WARNING: Type JQueryMethodCall has been deprecated and may be removed in future
| tst.js:5:1:5:15 | window.jQuery() | $ |
| tst.js:6:1:6:32 | angular ... .attr() | attr |
| tst.js:7:1:7:14 | $("<br>", doc) | $ |
| tst.js:11:1:11:8 | $("foo") | $ |
| tst.js:11:1:11:15 | $("foo").html() | html |
| tst.js:12:1:12:8 | $("foo") | $ |
| tst.js:12:1:12:20 | $("foo").html("foo") | html |
| tst.js:12:1:12:31 | $("foo" ... query() | isJquery |
| tst.js:13:1:13:8 | $("foo") | $ |
| tst.js:13:1:13:17 | $("foo").data({}) | data |
| tst.js:13:1:13:28 | $("foo" ... query() | isJquery |
| tst.js:15:1:15:8 | $("foo") | $ |
| tst.js:15:1:15:20 | $("foo").attr("bar") | attr |
| tst.js:17:1:17:8 | $.trim() | trim |
| tst.js:18:1:18:10 | $.ajax({}) | ajax |

View File

@@ -8,3 +8,8 @@ WARNING: Type JQueryMethodCall has been deprecated and may be removed in future
| tst2.js:2:1:2:7 | jq("a") | tst2.js:2:4:2:6 | "a" |
| tst.js:3:1:3:9 | $("<a/>") | tst.js:3:3:3:8 | "<a/>" |
| tst.js:7:1:7:14 | $("<br>", doc) | tst.js:7:3:7:8 | "<br>" |
| tst.js:11:1:11:8 | $("foo") | tst.js:11:3:11:7 | "foo" |
| tst.js:12:1:12:8 | $("foo") | tst.js:12:3:12:7 | "foo" |
| tst.js:12:1:12:20 | $("foo").html("foo") | tst.js:12:15:12:19 | "foo" |
| tst.js:13:1:13:8 | $("foo") | tst.js:13:3:13:7 | "foo" |
| tst.js:15:1:15:8 | $("foo") | tst.js:15:3:15:7 | "foo" |

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2017 The Closure Compiler Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Externs for jQuery 3.1
*
* Note that some functions use different return types depending on the number
* of parameters passed in. In these cases, you may need to annotate the type
* of the result in your code, so the JSCompiler understands which type you're
* expecting. For example:
* <code>var elt = /** @type {Element} * / (foo.get(0));</code>
*
* @see http://api.jquery.com/
* @externs
*/
/**
* @typedef {(Window|Document|Element|Array<Element>|string|jQuery|
* NodeList)}
*/
var jQuerySelector;
/**
* @constructor
* @param {(jQuerySelector|Object|function())=} arg1
* @param {(Element|jQuery|Document|
* Object<string, (string|function(!jQuery.Event))>)=} arg2
* @throws {Error} on invalid selector
* @return {!jQuery}
* @implements {Iterable}
*/
function jQuery(arg1, arg2) { };
/**
* @const
*/
var $ = jQuery;
/**
* @param {(string|jQueryAjaxSettings|Object<string,*>)} arg1
* @param {(jQueryAjaxSettings|Object<string, *>)=} settings
* @return {!jQuery.jqXHR}
*/
jQuery.ajax = function (arg1, settings) { };
/**
* @param {string} str
* @return {string}
* @nosideeffects
*/
jQuery.trim = function (str) { };

View File

@@ -5,3 +5,14 @@ window.$();
window.jQuery();
angular.element("<div/>").attr()
$("<br>", doc);
$("foo").html().doesNotReturnJquery();
$("foo").html("foo").isJquery();
$("foo").data({}).isJquery();
$("foo").attr("bar").doesNotReturnJquery();
$.trim().doesNotReturnJquery();
$.ajax({}).doesNotReturnJquery()

View File

@@ -12,6 +12,7 @@
*/
import python
import semmle.python.filters.Tests
predicate has_string_type(Value v) {
v.getClass() = ClassValue::str()
@@ -28,7 +29,10 @@ where
iter.pointsTo(seq, seq_origin) and
has_string_type(str) and
seq.getClass().isIterable() and
not has_string_type(seq)
not has_string_type(seq) and
// suppress occurrences from tests
not seq_origin.getScope().getScope*() instanceof TestScope and
not str_origin.getScope().getScope*() instanceof TestScope
select loop,
"Iteration over $@, of class " + seq.getClass().getName() + ", may also iterate over $@.",
seq_origin, "sequence", str_origin, "string"

View File

@@ -22,6 +22,10 @@ abstract class ExternalStringKind extends StringKind {
urlsplit(fromnode, tonode) and result.(ExternalUrlSplitResult).getItem() = this
or
urlparse(fromnode, tonode) and result.(ExternalUrlParseResult).getItem() = this
or
parse_qs(fromnode, tonode) and result.(ExternalStringDictKind).getValue() = this
or
parse_qsl(fromnode, tonode) and result.(SequenceKind).getItem().(SequenceKind).getItem() = this
}
}
@@ -181,16 +185,74 @@ private predicate urlparse(ControlFlowNode fromnode, CallNode tonode) {
)
}
private predicate parse_qs(ControlFlowNode fromnode, CallNode tonode) {
// This could be implemented as `exists(FunctionValue` without the explicit six part,
// but then our tests will need to import +100 modules, so for now this slightly
// altered version gets to live on.
exists(Value parse_qs |
(
parse_qs = Value::named("six.moves.urllib.parse.parse_qs")
or
// Python 2
parse_qs = Value::named("urlparse.parse_qs")
or
// Python 2 deprecated version of `urlparse.parse_qs`
parse_qs = Value::named("cgi.parse_qs")
or
// Python 3
parse_qs = Value::named("urllib.parse.parse_qs")
) and
tonode = parse_qs.getACall() and
(
tonode.getArg(0) = fromnode
or
tonode.getArgByName("qs") = fromnode
)
)
}
private predicate parse_qsl(ControlFlowNode fromnode, CallNode tonode) {
// This could be implemented as `exists(FunctionValue` without the explicit six part,
// but then our tests will need to import +100 modules, so for now this slightly
// altered version gets to live on.
exists(Value parse_qsl |
(
parse_qsl = Value::named("six.moves.urllib.parse.parse_qsl")
or
// Python 2
parse_qsl = Value::named("urlparse.parse_qsl")
or
// Python 2 deprecated version of `urlparse.parse_qsl`
parse_qsl = Value::named("cgi.parse_qsl")
or
// Python 3
parse_qsl = Value::named("urllib.parse.parse_qsl")
) and
tonode = parse_qsl.getACall() and
(
tonode.getArg(0) = fromnode
or
tonode.getArgByName("qs") = fromnode
)
)
}
/** A kind of "taint", representing an open file-like object from an external source. */
class ExternalFileObject extends TaintKind {
ExternalFileObject() { this = "file[" + any(ExternalStringKind key) + "]" }
ExternalStringKind valueKind;
ExternalFileObject() { this = "file[" + valueKind + "]" }
/** Gets the taint kind for the contents of this file */
TaintKind getValue() { this = "file[" + result + "]" }
TaintKind getValue() { result = valueKind }
override TaintKind getTaintOfMethodResult(string name) {
name = "read" and result = this.getValue()
name in ["read", "readline"] and result = this.getValue()
or
name = "readlines" and result.(SequenceKind).getItem() = this.getValue()
}
override TaintKind getTaintForIteration() { result = this.getValue() }
}
/**

View File

@@ -0,0 +1,19 @@
# This example illustrates that not all valid results are useful.
# The alert in this file should be suppressed.
# see https://github.com/Semmle/ql/issues/3207
def foo(l):
for (k, v) in l:
print(k, v)
foo([('a', 42), ('b', 43)])
import unittest
class FooTest(unittest.TestCase):
def test_valid(self):
foo([('a', 42), ('b', 43)])
def test_not_valid(self):
with six.assertRaises(self, ValueError):
foo("not valid")

View File

@@ -34,3 +34,11 @@ class ExceptionInfoSource extends TaintSource {
override string toString() { result = "Exception info source" }
}
class ExternalFileObjectSource extends TaintSource {
ExternalFileObjectSource() { this.(NameNode).getId() = "TAINTED_FILE" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalFileObject }
override string toString() { result = "Tainted file source" }
}

View File

@@ -1,146 +1,162 @@
| Taint [externally controlled string] | test.py:67 | test.py:67:20:67:43 | urlsplit() | | --> | Taint [externally controlled string] | test.py:69 | test.py:69:10:69:21 | urlsplit_res | |
| Taint [externally controlled string] | test.py:68 | test.py:68:20:68:43 | urlparse() | | --> | Taint [externally controlled string] | test.py:69 | test.py:69:24:69:35 | urlparse_res | |
| Taint [externally controlled string] | test.py:98 | test.py:98:9:98:37 | Attribute() | | --> | Taint externally controlled string | test.py:98 | test.py:98:9:98:40 | Subscript | |
| Taint [externally controlled string] | test.py:102 | test.py:102:9:102:38 | Attribute() | | --> | Taint externally controlled string | test.py:102 | test.py:102:9:102:41 | Subscript | |
| Taint [externally controlled string] | test.py:104 | test.py:104:9:104:37 | Attribute() | | --> | Taint externally controlled string | test.py:104 | test.py:104:9:104:41 | Subscript | |
| Taint [externally controlled string] | test.py:107 | test.py:107:9:107:30 | Attribute() | | --> | Taint externally controlled string | test.py:107 | test.py:107:9:107:33 | Subscript | |
| Taint [externally controlled string] | test.py:109 | test.py:109:9:109:35 | Attribute() | | --> | Taint externally controlled string | test.py:109 | test.py:109:9:109:38 | Subscript | |
| Taint exception.info | test.py:44 | test.py:44:22:44:26 | taint | p1 = exception.info | --> | Taint exception.info | test.py:45 | test.py:45:17:45:21 | taint | p1 = exception.info |
| Taint exception.info | test.py:45 | test.py:45:17:45:21 | taint | p1 = exception.info | --> | Taint exception.info | test.py:45 | test.py:45:12:45:22 | func() | p1 = exception.info |
| Taint exception.info | test.py:45 | test.py:45:17:45:21 | taint | p1 = exception.info | --> | Taint exception.info | test.py:52 | test.py:52:19:52:21 | arg | p0 = exception.info |
| Taint exception.info | test.py:48 | test.py:48:12:48:33 | TAINTED_EXCEPTION_INFO | | --> | Taint exception.info | test.py:49 | test.py:49:37:49:40 | info | |
| Taint exception.info | test.py:49 | test.py:49:11:49:41 | cross_over() | | --> | Taint exception.info | test.py:50 | test.py:50:10:50:12 | res | |
| Taint exception.info | test.py:49 | test.py:49:37:49:40 | info | | --> | Taint exception.info | test.py:44 | test.py:44:22:44:26 | taint | p1 = exception.info |
| Taint exception.info | test.py:49 | test.py:49:37:49:40 | info | | --> | Taint exception.info | test.py:49 | test.py:49:11:49:41 | cross_over() | |
| Taint exception.info | test.py:52 | test.py:52:19:52:21 | arg | p0 = exception.info | --> | Taint exception.info | test.py:53 | test.py:53:12:53:14 | arg | p0 = exception.info |
| Taint externally controlled string | test.py:5 | test.py:5:22:5:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:6 | test.py:6:31:6:44 | tainted_string | |
| Taint externally controlled string | test.py:6 | test.py:6:31:6:44 | tainted_string | | --> | Taint json[externally controlled string] | test.py:6 | test.py:6:20:6:45 | Attribute() | |
| Taint externally controlled string | test.py:7 | test.py:7:9:7:25 | Subscript | | --> | Taint externally controlled string | test.py:8 | test.py:8:9:8:9 | a | |
| Taint externally controlled string | test.py:7 | test.py:7:9:7:25 | Subscript | | --> | Taint externally controlled string | test.py:10 | test.py:10:10:10:10 | a | |
| Taint externally controlled string | test.py:8 | test.py:8:9:8:18 | Attribute() | | --> | Taint externally controlled string | test.py:9 | test.py:9:9:9:9 | b | |
| Taint externally controlled string | test.py:8 | test.py:8:9:8:18 | Attribute() | | --> | Taint externally controlled string | test.py:10 | test.py:10:13:10:13 | b | |
| Taint externally controlled string | test.py:9 | test.py:9:9:9:14 | Subscript | | --> | Taint externally controlled string | test.py:10 | test.py:10:16:10:16 | c | |
| Taint externally controlled string | test.py:13 | test.py:13:22:13:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:14 | test.py:14:9:14:22 | tainted_string | |
| Taint externally controlled string | test.py:13 | test.py:13:22:13:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:15 | test.py:15:9:15:22 | tainted_string | |
| Taint externally controlled string | test.py:13 | test.py:13:22:13:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:16 | test.py:16:9:16:22 | tainted_string | |
| Taint externally controlled string | test.py:13 | test.py:13:22:13:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:17 | test.py:17:9:17:22 | tainted_string | |
| Taint externally controlled string | test.py:13 | test.py:13:22:13:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:18 | test.py:18:18:18:31 | tainted_string | |
| Taint externally controlled string | test.py:13 | test.py:13:22:13:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:19 | test.py:19:14:19:27 | tainted_string | |
| Taint externally controlled string | test.py:13 | test.py:13:22:13:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:20 | test.py:20:9:20:22 | tainted_string | |
| Taint externally controlled string | test.py:14 | test.py:14:9:14:22 | tainted_string | | --> | Taint externally controlled string | test.py:14 | test.py:14:9:14:31 | Attribute() | |
| Taint externally controlled string | test.py:14 | test.py:14:9:14:31 | Attribute() | | --> | Taint externally controlled string | test.py:21 | test.py:21:10:21:10 | a | |
| Taint externally controlled string | test.py:15 | test.py:15:9:15:22 | tainted_string | | --> | Taint externally controlled string | test.py:15 | test.py:15:9:15:29 | Attribute() | |
| Taint externally controlled string | test.py:15 | test.py:15:9:15:29 | Attribute() | | --> | Taint externally controlled string | test.py:21 | test.py:21:13:21:13 | b | |
| Taint externally controlled string | test.py:16 | test.py:16:9:16:22 | tainted_string | | --> | Taint externally controlled string | test.py:16 | test.py:16:9:16:25 | Subscript | |
| Taint externally controlled string | test.py:16 | test.py:16:9:16:25 | Subscript | | --> | Taint externally controlled string | test.py:21 | test.py:21:16:21:16 | c | |
| Taint externally controlled string | test.py:17 | test.py:17:9:17:22 | tainted_string | | --> | Taint externally controlled string | test.py:17 | test.py:17:9:17:27 | Subscript | |
| Taint externally controlled string | test.py:17 | test.py:17:9:17:27 | Subscript | | --> | Taint externally controlled string | test.py:21 | test.py:21:19:21:19 | d | |
| Taint externally controlled string | test.py:18 | test.py:18:9:18:32 | reversed() | | --> | Taint externally controlled string | test.py:21 | test.py:21:22:21:22 | e | |
| Taint externally controlled string | test.py:18 | test.py:18:18:18:31 | tainted_string | | --> | Taint externally controlled string | test.py:18 | test.py:18:9:18:32 | reversed() | |
| Taint externally controlled string | test.py:19 | test.py:19:9:19:28 | copy() | | --> | Taint externally controlled string | test.py:21 | test.py:21:25:21:25 | f | |
| Taint externally controlled string | test.py:19 | test.py:19:14:19:27 | tainted_string | | --> | Taint externally controlled string | test.py:19 | test.py:19:9:19:28 | copy() | |
| Taint externally controlled string | test.py:20 | test.py:20:9:20:22 | tainted_string | | --> | Taint externally controlled string | test.py:20 | test.py:20:9:20:30 | Attribute() | |
| Taint externally controlled string | test.py:20 | test.py:20:9:20:30 | Attribute() | | --> | Taint externally controlled string | test.py:21 | test.py:21:28:21:28 | g | |
| Taint externally controlled string | test.py:24 | test.py:24:22:24:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:25 | test.py:25:8:25:21 | tainted_string | |
| Taint externally controlled string | test.py:24 | test.py:24:22:24:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:28 | test.py:28:14:28:27 | tainted_string | |
| Taint externally controlled string | test.py:31 | test.py:31:22:31:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:32 | test.py:32:8:32:21 | tainted_string | |
| Taint externally controlled string | test.py:31 | test.py:31:22:31:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:32 | test.py:32:34:32:47 | tainted_string | |
| Taint externally controlled string | test.py:31 | test.py:31:22:31:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:35 | test.py:35:14:35:27 | tainted_string | |
| Taint externally controlled string | test.py:38 | test.py:38:22:38:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:39 | test.py:39:13:39:26 | tainted_string | |
| Taint externally controlled string | test.py:38 | test.py:38:22:38:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:40 | test.py:40:15:40:28 | tainted_string | |
| Taint externally controlled string | test.py:38 | test.py:38:22:38:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:41 | test.py:41:15:41:28 | tainted_string | |
| Taint externally controlled string | test.py:39 | test.py:39:9:39:27 | str() | | --> | Taint externally controlled string | test.py:42 | test.py:42:10:42:10 | a | |
| Taint externally controlled string | test.py:39 | test.py:39:13:39:26 | tainted_string | | --> | Taint externally controlled string | test.py:39 | test.py:39:9:39:27 | str() | |
| Taint externally controlled string | test.py:40 | test.py:40:9:40:29 | bytes() | | --> | Taint externally controlled string | test.py:42 | test.py:42:13:42:13 | b | |
| Taint externally controlled string | test.py:40 | test.py:40:15:40:28 | tainted_string | | --> | Taint externally controlled string | test.py:40 | test.py:40:9:40:29 | bytes() | |
| Taint externally controlled string | test.py:41 | test.py:41:9:41:46 | bytes() | | --> | Taint externally controlled string | test.py:42 | test.py:42:16:42:16 | c | |
| Taint externally controlled string | test.py:41 | test.py:41:15:41:28 | tainted_string | | --> | Taint externally controlled string | test.py:41 | test.py:41:9:41:46 | bytes() | |
| Taint externally controlled string | test.py:44 | test.py:44:22:44:26 | taint | p1 = externally controlled string | --> | Taint externally controlled string | test.py:45 | test.py:45:17:45:21 | taint | p1 = externally controlled string |
| Taint externally controlled string | test.py:45 | test.py:45:17:45:21 | taint | p1 = externally controlled string | --> | Taint externally controlled string | test.py:45 | test.py:45:12:45:22 | func() | p1 = externally controlled string |
| Taint externally controlled string | test.py:45 | test.py:45:17:45:21 | taint | p1 = externally controlled string | --> | Taint externally controlled string | test.py:52 | test.py:52:19:52:21 | arg | p0 = externally controlled string |
| Taint externally controlled string | test.py:52 | test.py:52:19:52:21 | arg | p0 = externally controlled string | --> | Taint externally controlled string | test.py:53 | test.py:53:12:53:14 | arg | p0 = externally controlled string |
| Taint externally controlled string | test.py:56 | test.py:56:11:56:24 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:57 | test.py:57:38:57:40 | ext | |
| Taint externally controlled string | test.py:57 | test.py:57:11:57:41 | cross_over() | | --> | Taint externally controlled string | test.py:58 | test.py:58:10:58:12 | res | |
| Taint externally controlled string | test.py:57 | test.py:57:38:57:40 | ext | | --> | Taint externally controlled string | test.py:44 | test.py:44:22:44:26 | taint | p1 = externally controlled string |
| Taint externally controlled string | test.py:57 | test.py:57:38:57:40 | ext | | --> | Taint externally controlled string | test.py:57 | test.py:57:11:57:41 | cross_over() | |
| Taint externally controlled string | test.py:66 | test.py:66:22:66:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:67 | test.py:67:29:67:42 | tainted_string | |
| Taint externally controlled string | test.py:66 | test.py:66:22:66:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:68 | test.py:68:29:68:42 | tainted_string | |
| Taint externally controlled string | test.py:67 | test.py:67:29:67:42 | tainted_string | | --> | Taint [externally controlled string] | test.py:67 | test.py:67:20:67:43 | urlsplit() | |
| Taint externally controlled string | test.py:68 | test.py:68:29:68:42 | tainted_string | | --> | Taint [externally controlled string] | test.py:68 | test.py:68:20:68:43 | urlparse() | |
| Taint externally controlled string | test.py:72 | test.py:72:22:72:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:74 | test.py:74:9:74:22 | tainted_string | |
| Taint externally controlled string | test.py:72 | test.py:72:22:72:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:76 | test.py:76:12:76:25 | tainted_string | |
| Taint externally controlled string | test.py:74 | test.py:74:9:74:22 | tainted_string | | --> | Taint externally controlled string | test.py:74 | test.py:74:9:74:30 | Attribute() | |
| Taint externally controlled string | test.py:74 | test.py:74:9:74:30 | Attribute() | | --> | Taint externally controlled string | test.py:79 | test.py:79:10:79:10 | a | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:85 | test.py:85:9:85:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:86 | test.py:86:9:86:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:87 | test.py:87:9:87:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:88 | test.py:88:9:88:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:89 | test.py:89:9:89:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:90 | test.py:90:9:90:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:91 | test.py:91:9:91:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:92 | test.py:92:9:92:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:93 | test.py:93:9:93:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:94 | test.py:94:9:94:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:95 | test.py:95:9:95:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:96 | test.py:96:9:96:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:97 | test.py:97:9:97:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:98 | test.py:98:9:98:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:99 | test.py:99:9:99:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:100 | test.py:100:9:100:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:101 | test.py:101:9:101:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:102 | test.py:102:9:102:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:103 | test.py:103:9:103:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:104 | test.py:104:9:104:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:105 | test.py:105:9:105:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:106 | test.py:106:9:106:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:107 | test.py:107:9:107:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:108 | test.py:108:9:108:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:109 | test.py:109:9:109:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:110 | test.py:110:9:110:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:111 | test.py:111:9:111:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:112 | test.py:112:9:112:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:115 | test.py:115:9:115:22 | tainted_string | |
| Taint externally controlled string | test.py:82 | test.py:82:22:82:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:116 | test.py:116:9:116:22 | tainted_string | |
| Taint externally controlled string | test.py:85 | test.py:85:9:85:22 | tainted_string | | --> | Taint externally controlled string | test.py:85 | test.py:85:9:85:35 | Attribute() | |
| Taint externally controlled string | test.py:86 | test.py:86:9:86:22 | tainted_string | | --> | Taint externally controlled string | test.py:86 | test.py:86:9:86:33 | Attribute() | |
| Taint externally controlled string | test.py:87 | test.py:87:9:87:22 | tainted_string | | --> | Taint externally controlled string | test.py:87 | test.py:87:9:87:31 | Attribute() | |
| Taint externally controlled string | test.py:88 | test.py:88:9:88:22 | tainted_string | | --> | Taint externally controlled string | test.py:88 | test.py:88:9:88:38 | Attribute() | |
| Taint externally controlled string | test.py:89 | test.py:89:9:89:22 | tainted_string | | --> | Taint externally controlled string | test.py:89 | test.py:89:9:89:38 | Attribute() | |
| Taint externally controlled string | test.py:89 | test.py:89:9:89:38 | Attribute() | | --> | Taint externally controlled string | test.py:89 | test.py:89:9:89:54 | Attribute() | |
| Taint externally controlled string | test.py:90 | test.py:90:9:90:22 | tainted_string | | --> | Taint externally controlled string | test.py:90 | test.py:90:9:90:35 | Attribute() | |
| Taint externally controlled string | test.py:91 | test.py:91:9:91:22 | tainted_string | | --> | Taint externally controlled string | test.py:91 | test.py:91:9:91:37 | Attribute() | |
| Taint externally controlled string | test.py:92 | test.py:92:9:92:22 | tainted_string | | --> | Taint externally controlled string | test.py:92 | test.py:92:9:92:46 | Attribute() | |
| Taint externally controlled string | test.py:93 | test.py:93:9:93:22 | tainted_string | | --> | Taint externally controlled string | test.py:93 | test.py:93:9:93:33 | Attribute() | |
| Taint externally controlled string | test.py:94 | test.py:94:9:94:22 | tainted_string | | --> | Taint externally controlled string | test.py:94 | test.py:94:9:94:30 | Attribute() | |
| Taint externally controlled string | test.py:95 | test.py:95:9:95:22 | tainted_string | | --> | Taint externally controlled string | test.py:95 | test.py:95:9:95:31 | Attribute() | |
| Taint [[externally controlled string]] | test.py:74 | test.py:74:9:74:33 | parse_qsl() | | --> | Taint [[externally controlled string]] | test.py:75 | test.py:75:19:75:19 | d | |
| Taint [externally controlled string] | test.py:71 | test.py:71:9:71:32 | urlsplit() | | --> | Taint [externally controlled string] | test.py:75 | test.py:75:10:75:10 | a | |
| Taint [externally controlled string] | test.py:72 | test.py:72:9:72:32 | urlparse() | | --> | Taint [externally controlled string] | test.py:75 | test.py:75:13:75:13 | b | |
| Taint [externally controlled string] | test.py:104 | test.py:104:9:104:37 | Attribute() | | --> | Taint externally controlled string | test.py:104 | test.py:104:9:104:40 | Subscript | |
| Taint [externally controlled string] | test.py:108 | test.py:108:9:108:38 | Attribute() | | --> | Taint externally controlled string | test.py:108 | test.py:108:9:108:41 | Subscript | |
| Taint [externally controlled string] | test.py:110 | test.py:110:9:110:37 | Attribute() | | --> | Taint externally controlled string | test.py:110 | test.py:110:9:110:41 | Subscript | |
| Taint [externally controlled string] | test.py:113 | test.py:113:9:113:30 | Attribute() | | --> | Taint externally controlled string | test.py:113 | test.py:113:9:113:33 | Subscript | |
| Taint [externally controlled string] | test.py:115 | test.py:115:9:115:35 | Attribute() | | --> | Taint externally controlled string | test.py:115 | test.py:115:9:115:38 | Subscript | |
| Taint exception.info | test.py:45 | test.py:45:22:45:26 | taint | p1 = exception.info | --> | Taint exception.info | test.py:46 | test.py:46:17:46:21 | taint | p1 = exception.info |
| Taint exception.info | test.py:46 | test.py:46:17:46:21 | taint | p1 = exception.info | --> | Taint exception.info | test.py:46 | test.py:46:12:46:22 | func() | p1 = exception.info |
| Taint exception.info | test.py:46 | test.py:46:17:46:21 | taint | p1 = exception.info | --> | Taint exception.info | test.py:53 | test.py:53:19:53:21 | arg | p0 = exception.info |
| Taint exception.info | test.py:49 | test.py:49:12:49:33 | TAINTED_EXCEPTION_INFO | | --> | Taint exception.info | test.py:50 | test.py:50:37:50:40 | info | |
| Taint exception.info | test.py:50 | test.py:50:11:50:41 | cross_over() | | --> | Taint exception.info | test.py:51 | test.py:51:10:51:12 | res | |
| Taint exception.info | test.py:50 | test.py:50:37:50:40 | info | | --> | Taint exception.info | test.py:45 | test.py:45:22:45:26 | taint | p1 = exception.info |
| Taint exception.info | test.py:50 | test.py:50:37:50:40 | info | | --> | Taint exception.info | test.py:50 | test.py:50:11:50:41 | cross_over() | |
| Taint exception.info | test.py:53 | test.py:53:19:53:21 | arg | p0 = exception.info | --> | Taint exception.info | test.py:54 | test.py:54:12:54:14 | arg | p0 = exception.info |
| Taint externally controlled string | test.py:6 | test.py:6:22:6:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:7 | test.py:7:31:7:44 | tainted_string | |
| Taint externally controlled string | test.py:7 | test.py:7:31:7:44 | tainted_string | | --> | Taint json[externally controlled string] | test.py:7 | test.py:7:20:7:45 | Attribute() | |
| Taint externally controlled string | test.py:8 | test.py:8:9:8:25 | Subscript | | --> | Taint externally controlled string | test.py:9 | test.py:9:9:9:9 | a | |
| Taint externally controlled string | test.py:8 | test.py:8:9:8:25 | Subscript | | --> | Taint externally controlled string | test.py:11 | test.py:11:10:11:10 | a | |
| Taint externally controlled string | test.py:9 | test.py:9:9:9:18 | Attribute() | | --> | Taint externally controlled string | test.py:10 | test.py:10:9:10:9 | b | |
| Taint externally controlled string | test.py:9 | test.py:9:9:9:18 | Attribute() | | --> | Taint externally controlled string | test.py:11 | test.py:11:13:11:13 | b | |
| Taint externally controlled string | test.py:10 | test.py:10:9:10:14 | Subscript | | --> | Taint externally controlled string | test.py:11 | test.py:11:16:11:16 | c | |
| Taint externally controlled string | test.py:14 | test.py:14:22:14:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:15 | test.py:15:9:15:22 | tainted_string | |
| Taint externally controlled string | test.py:14 | test.py:14:22:14:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:16 | test.py:16:9:16:22 | tainted_string | |
| Taint externally controlled string | test.py:14 | test.py:14:22:14:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:17 | test.py:17:9:17:22 | tainted_string | |
| Taint externally controlled string | test.py:14 | test.py:14:22:14:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:18 | test.py:18:9:18:22 | tainted_string | |
| Taint externally controlled string | test.py:14 | test.py:14:22:14:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:19 | test.py:19:18:19:31 | tainted_string | |
| Taint externally controlled string | test.py:14 | test.py:14:22:14:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:20 | test.py:20:14:20:27 | tainted_string | |
| Taint externally controlled string | test.py:14 | test.py:14:22:14:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:21 | test.py:21:9:21:22 | tainted_string | |
| Taint externally controlled string | test.py:15 | test.py:15:9:15:22 | tainted_string | | --> | Taint externally controlled string | test.py:15 | test.py:15:9:15:31 | Attribute() | |
| Taint externally controlled string | test.py:15 | test.py:15:9:15:31 | Attribute() | | --> | Taint externally controlled string | test.py:22 | test.py:22:10:22:10 | a | |
| Taint externally controlled string | test.py:16 | test.py:16:9:16:22 | tainted_string | | --> | Taint externally controlled string | test.py:16 | test.py:16:9:16:29 | Attribute() | |
| Taint externally controlled string | test.py:16 | test.py:16:9:16:29 | Attribute() | | --> | Taint externally controlled string | test.py:22 | test.py:22:13:22:13 | b | |
| Taint externally controlled string | test.py:17 | test.py:17:9:17:22 | tainted_string | | --> | Taint externally controlled string | test.py:17 | test.py:17:9:17:25 | Subscript | |
| Taint externally controlled string | test.py:17 | test.py:17:9:17:25 | Subscript | | --> | Taint externally controlled string | test.py:22 | test.py:22:16:22:16 | c | |
| Taint externally controlled string | test.py:18 | test.py:18:9:18:22 | tainted_string | | --> | Taint externally controlled string | test.py:18 | test.py:18:9:18:27 | Subscript | |
| Taint externally controlled string | test.py:18 | test.py:18:9:18:27 | Subscript | | --> | Taint externally controlled string | test.py:22 | test.py:22:19:22:19 | d | |
| Taint externally controlled string | test.py:19 | test.py:19:9:19:32 | reversed() | | --> | Taint externally controlled string | test.py:22 | test.py:22:22:22:22 | e | |
| Taint externally controlled string | test.py:19 | test.py:19:18:19:31 | tainted_string | | --> | Taint externally controlled string | test.py:19 | test.py:19:9:19:32 | reversed() | |
| Taint externally controlled string | test.py:20 | test.py:20:9:20:28 | copy() | | --> | Taint externally controlled string | test.py:22 | test.py:22:25:22:25 | f | |
| Taint externally controlled string | test.py:20 | test.py:20:14:20:27 | tainted_string | | --> | Taint externally controlled string | test.py:20 | test.py:20:9:20:28 | copy() | |
| Taint externally controlled string | test.py:21 | test.py:21:9:21:22 | tainted_string | | --> | Taint externally controlled string | test.py:21 | test.py:21:9:21:30 | Attribute() | |
| Taint externally controlled string | test.py:21 | test.py:21:9:21:30 | Attribute() | | --> | Taint externally controlled string | test.py:22 | test.py:22:28:22:28 | g | |
| Taint externally controlled string | test.py:25 | test.py:25:22:25:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:26 | test.py:26:8:26:21 | tainted_string | |
| Taint externally controlled string | test.py:25 | test.py:25:22:25:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:29 | test.py:29:14:29:27 | tainted_string | |
| Taint externally controlled string | test.py:32 | test.py:32:22:32:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:33 | test.py:33:8:33:21 | tainted_string | |
| Taint externally controlled string | test.py:32 | test.py:32:22:32:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:33 | test.py:33:34:33:47 | tainted_string | |
| Taint externally controlled string | test.py:32 | test.py:32:22:32:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:36 | test.py:36:14:36:27 | tainted_string | |
| Taint externally controlled string | test.py:39 | test.py:39:22:39:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:40 | test.py:40:13:40:26 | tainted_string | |
| Taint externally controlled string | test.py:39 | test.py:39:22:39:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:41 | test.py:41:15:41:28 | tainted_string | |
| Taint externally controlled string | test.py:39 | test.py:39:22:39:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:42 | test.py:42:15:42:28 | tainted_string | |
| Taint externally controlled string | test.py:40 | test.py:40:9:40:27 | str() | | --> | Taint externally controlled string | test.py:43 | test.py:43:10:43:10 | a | |
| Taint externally controlled string | test.py:40 | test.py:40:13:40:26 | tainted_string | | --> | Taint externally controlled string | test.py:40 | test.py:40:9:40:27 | str() | |
| Taint externally controlled string | test.py:41 | test.py:41:9:41:29 | bytes() | | --> | Taint externally controlled string | test.py:43 | test.py:43:13:43:13 | b | |
| Taint externally controlled string | test.py:41 | test.py:41:15:41:28 | tainted_string | | --> | Taint externally controlled string | test.py:41 | test.py:41:9:41:29 | bytes() | |
| Taint externally controlled string | test.py:42 | test.py:42:9:42:46 | bytes() | | --> | Taint externally controlled string | test.py:43 | test.py:43:16:43:16 | c | |
| Taint externally controlled string | test.py:42 | test.py:42:15:42:28 | tainted_string | | --> | Taint externally controlled string | test.py:42 | test.py:42:9:42:46 | bytes() | |
| Taint externally controlled string | test.py:45 | test.py:45:22:45:26 | taint | p1 = externally controlled string | --> | Taint externally controlled string | test.py:46 | test.py:46:17:46:21 | taint | p1 = externally controlled string |
| Taint externally controlled string | test.py:46 | test.py:46:17:46:21 | taint | p1 = externally controlled string | --> | Taint externally controlled string | test.py:46 | test.py:46:12:46:22 | func() | p1 = externally controlled string |
| Taint externally controlled string | test.py:46 | test.py:46:17:46:21 | taint | p1 = externally controlled string | --> | Taint externally controlled string | test.py:53 | test.py:53:19:53:21 | arg | p0 = externally controlled string |
| Taint externally controlled string | test.py:53 | test.py:53:19:53:21 | arg | p0 = externally controlled string | --> | Taint externally controlled string | test.py:54 | test.py:54:12:54:14 | arg | p0 = externally controlled string |
| Taint externally controlled string | test.py:57 | test.py:57:11:57:24 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:58 | test.py:58:38:58:40 | ext | |
| Taint externally controlled string | test.py:58 | test.py:58:11:58:41 | cross_over() | | --> | Taint externally controlled string | test.py:59 | test.py:59:10:59:12 | res | |
| Taint externally controlled string | test.py:58 | test.py:58:38:58:40 | ext | | --> | Taint externally controlled string | test.py:45 | test.py:45:22:45:26 | taint | p1 = externally controlled string |
| Taint externally controlled string | test.py:58 | test.py:58:38:58:40 | ext | | --> | Taint externally controlled string | test.py:58 | test.py:58:11:58:41 | cross_over() | |
| Taint externally controlled string | test.py:70 | test.py:70:22:70:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:71 | test.py:71:18:71:31 | tainted_string | |
| Taint externally controlled string | test.py:70 | test.py:70:22:70:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:72 | test.py:72:18:72:31 | tainted_string | |
| Taint externally controlled string | test.py:70 | test.py:70:22:70:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:73 | test.py:73:18:73:31 | tainted_string | |
| Taint externally controlled string | test.py:70 | test.py:70:22:70:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:74 | test.py:74:19:74:32 | tainted_string | |
| Taint externally controlled string | test.py:71 | test.py:71:18:71:31 | tainted_string | | --> | Taint [externally controlled string] | test.py:71 | test.py:71:9:71:32 | urlsplit() | |
| Taint externally controlled string | test.py:72 | test.py:72:18:72:31 | tainted_string | | --> | Taint [externally controlled string] | test.py:72 | test.py:72:9:72:32 | urlparse() | |
| Taint externally controlled string | test.py:73 | test.py:73:18:73:31 | tainted_string | | --> | Taint {externally controlled string} | test.py:73 | test.py:73:9:73:32 | parse_qs() | |
| Taint externally controlled string | test.py:74 | test.py:74:19:74:32 | tainted_string | | --> | Taint [[externally controlled string]] | test.py:74 | test.py:74:9:74:33 | parse_qsl() | |
| Taint externally controlled string | test.py:78 | test.py:78:22:78:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:80 | test.py:80:9:80:22 | tainted_string | |
| Taint externally controlled string | test.py:78 | test.py:78:22:78:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:82 | test.py:82:12:82:25 | tainted_string | |
| Taint externally controlled string | test.py:80 | test.py:80:9:80:22 | tainted_string | | --> | Taint externally controlled string | test.py:80 | test.py:80:9:80:30 | Attribute() | |
| Taint externally controlled string | test.py:80 | test.py:80:9:80:30 | Attribute() | | --> | Taint externally controlled string | test.py:85 | test.py:85:10:85:10 | a | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:91 | test.py:91:9:91:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:92 | test.py:92:9:92:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:93 | test.py:93:9:93:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:94 | test.py:94:9:94:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:95 | test.py:95:9:95:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:96 | test.py:96:9:96:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:97 | test.py:97:9:97:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:98 | test.py:98:9:98:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:99 | test.py:99:9:99:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:100 | test.py:100:9:100:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:101 | test.py:101:9:101:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:102 | test.py:102:9:102:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:103 | test.py:103:9:103:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:104 | test.py:104:9:104:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:105 | test.py:105:9:105:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:106 | test.py:106:9:106:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:107 | test.py:107:9:107:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:108 | test.py:108:9:108:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:109 | test.py:109:9:109:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:110 | test.py:110:9:110:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:111 | test.py:111:9:111:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:112 | test.py:112:9:112:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:113 | test.py:113:9:113:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:114 | test.py:114:9:114:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:115 | test.py:115:9:115:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:116 | test.py:116:9:116:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:117 | test.py:117:9:117:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:118 | test.py:118:9:118:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:121 | test.py:121:9:121:22 | tainted_string | |
| Taint externally controlled string | test.py:88 | test.py:88:22:88:35 | TAINTED_STRING | | --> | Taint externally controlled string | test.py:122 | test.py:122:9:122:22 | tainted_string | |
| Taint externally controlled string | test.py:91 | test.py:91:9:91:22 | tainted_string | | --> | Taint externally controlled string | test.py:91 | test.py:91:9:91:35 | Attribute() | |
| Taint externally controlled string | test.py:92 | test.py:92:9:92:22 | tainted_string | | --> | Taint externally controlled string | test.py:92 | test.py:92:9:92:33 | Attribute() | |
| Taint externally controlled string | test.py:93 | test.py:93:9:93:22 | tainted_string | | --> | Taint externally controlled string | test.py:93 | test.py:93:9:93:31 | Attribute() | |
| Taint externally controlled string | test.py:94 | test.py:94:9:94:22 | tainted_string | | --> | Taint externally controlled string | test.py:94 | test.py:94:9:94:38 | Attribute() | |
| Taint externally controlled string | test.py:95 | test.py:95:9:95:22 | tainted_string | | --> | Taint externally controlled string | test.py:95 | test.py:95:9:95:38 | Attribute() | |
| Taint externally controlled string | test.py:95 | test.py:95:9:95:38 | Attribute() | | --> | Taint externally controlled string | test.py:95 | test.py:95:9:95:54 | Attribute() | |
| Taint externally controlled string | test.py:96 | test.py:96:9:96:22 | tainted_string | | --> | Taint externally controlled string | test.py:96 | test.py:96:9:96:35 | Attribute() | |
| Taint externally controlled string | test.py:97 | test.py:97:9:97:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:97 | test.py:97:9:97:37 | Attribute() | |
| Taint externally controlled string | test.py:98 | test.py:98:9:98:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:98 | test.py:98:9:98:37 | Attribute() | |
| Taint externally controlled string | test.py:99 | test.py:99:9:99:22 | tainted_string | | --> | Taint externally controlled string | test.py:99 | test.py:99:9:99:42 | Attribute() | |
| Taint externally controlled string | test.py:100 | test.py:100:9:100:22 | tainted_string | | --> | Taint externally controlled string | test.py:100 | test.py:100:9:100:33 | Attribute() | |
| Taint externally controlled string | test.py:101 | test.py:101:9:101:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:101 | test.py:101:9:101:38 | Attribute() | |
| Taint externally controlled string | test.py:102 | test.py:102:9:102:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:102 | test.py:102:9:102:38 | Attribute() | |
| Taint externally controlled string | test.py:97 | test.py:97:9:97:22 | tainted_string | | --> | Taint externally controlled string | test.py:97 | test.py:97:9:97:37 | Attribute() | |
| Taint externally controlled string | test.py:98 | test.py:98:9:98:22 | tainted_string | | --> | Taint externally controlled string | test.py:98 | test.py:98:9:98:46 | Attribute() | |
| Taint externally controlled string | test.py:99 | test.py:99:9:99:22 | tainted_string | | --> | Taint externally controlled string | test.py:99 | test.py:99:9:99:33 | Attribute() | |
| Taint externally controlled string | test.py:100 | test.py:100:9:100:22 | tainted_string | | --> | Taint externally controlled string | test.py:100 | test.py:100:9:100:30 | Attribute() | |
| Taint externally controlled string | test.py:101 | test.py:101:9:101:22 | tainted_string | | --> | Taint externally controlled string | test.py:101 | test.py:101:9:101:31 | Attribute() | |
| Taint externally controlled string | test.py:102 | test.py:102:9:102:22 | tainted_string | | --> | Taint externally controlled string | test.py:102 | test.py:102:9:102:35 | Attribute() | |
| Taint externally controlled string | test.py:103 | test.py:103:9:103:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:103 | test.py:103:9:103:37 | Attribute() | |
| Taint externally controlled string | test.py:104 | test.py:104:9:104:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:104 | test.py:104:9:104:37 | Attribute() | |
| Taint externally controlled string | test.py:105 | test.py:105:9:105:22 | tainted_string | | --> | Taint externally controlled string | test.py:105 | test.py:105:9:105:31 | Attribute() | |
| Taint externally controlled string | test.py:106 | test.py:106:9:106:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:106 | test.py:106:9:106:30 | Attribute() | |
| Taint externally controlled string | test.py:107 | test.py:107:9:107:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:107 | test.py:107:9:107:30 | Attribute() | |
| Taint externally controlled string | test.py:108 | test.py:108:9:108:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:108 | test.py:108:9:108:35 | Attribute() | |
| Taint externally controlled string | test.py:109 | test.py:109:9:109:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:109 | test.py:109:9:109:35 | Attribute() | |
| Taint externally controlled string | test.py:110 | test.py:110:9:110:22 | tainted_string | | --> | Taint externally controlled string | test.py:110 | test.py:110:9:110:30 | Attribute() | |
| Taint externally controlled string | test.py:111 | test.py:111:9:111:22 | tainted_string | | --> | Taint externally controlled string | test.py:111 | test.py:111:9:111:33 | Attribute() | |
| Taint externally controlled string | test.py:112 | test.py:112:9:112:22 | tainted_string | | --> | Taint externally controlled string | test.py:112 | test.py:112:9:112:30 | Attribute() | |
| Taint externally controlled string | test.py:115 | test.py:115:9:115:22 | tainted_string | | --> | Taint externally controlled string | test.py:115 | test.py:115:9:115:30 | Attribute() | |
| Taint externally controlled string | test.py:116 | test.py:116:9:116:22 | tainted_string | | --> | Taint externally controlled string | test.py:116 | test.py:116:9:116:33 | Attribute() | |
| Taint json[externally controlled string] | test.py:6 | test.py:6:20:6:45 | Attribute() | | --> | Taint json[externally controlled string] | test.py:7 | test.py:7:9:7:20 | tainted_json | |
| Taint json[externally controlled string] | test.py:7 | test.py:7:9:7:20 | tainted_json | | --> | Taint externally controlled string | test.py:7 | test.py:7:9:7:25 | Subscript | |
| Taint json[externally controlled string] | test.py:7 | test.py:7:9:7:20 | tainted_json | | --> | Taint json[externally controlled string] | test.py:7 | test.py:7:9:7:25 | Subscript | |
| Taint json[externally controlled string] | test.py:7 | test.py:7:9:7:25 | Subscript | | --> | Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:9 | a | |
| Taint json[externally controlled string] | test.py:7 | test.py:7:9:7:25 | Subscript | | --> | Taint json[externally controlled string] | test.py:10 | test.py:10:10:10:10 | a | |
| Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:9 | a | | --> | Taint externally controlled string | test.py:8 | test.py:8:9:8:18 | Attribute() | |
| Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:9 | a | | --> | Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:18 | Attribute() | |
| Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:18 | Attribute() | | --> | Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:9 | b | |
| Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:18 | Attribute() | | --> | Taint json[externally controlled string] | test.py:10 | test.py:10:13:10:13 | b | |
| Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:9 | b | | --> | Taint externally controlled string | test.py:9 | test.py:9:9:9:14 | Subscript | |
| Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:9 | b | | --> | Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:14 | Subscript | |
| Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:14 | Subscript | | --> | Taint json[externally controlled string] | test.py:10 | test.py:10:16:10:16 | c | |
| Taint externally controlled string | test.py:105 | test.py:105:9:105:22 | tainted_string | | --> | Taint externally controlled string | test.py:105 | test.py:105:9:105:42 | Attribute() | |
| Taint externally controlled string | test.py:106 | test.py:106:9:106:22 | tainted_string | | --> | Taint externally controlled string | test.py:106 | test.py:106:9:106:33 | Attribute() | |
| Taint externally controlled string | test.py:107 | test.py:107:9:107:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:107 | test.py:107:9:107:38 | Attribute() | |
| Taint externally controlled string | test.py:108 | test.py:108:9:108:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:108 | test.py:108:9:108:38 | Attribute() | |
| Taint externally controlled string | test.py:109 | test.py:109:9:109:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:109 | test.py:109:9:109:37 | Attribute() | |
| Taint externally controlled string | test.py:110 | test.py:110:9:110:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:110 | test.py:110:9:110:37 | Attribute() | |
| Taint externally controlled string | test.py:111 | test.py:111:9:111:22 | tainted_string | | --> | Taint externally controlled string | test.py:111 | test.py:111:9:111:31 | Attribute() | |
| Taint externally controlled string | test.py:112 | test.py:112:9:112:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:112 | test.py:112:9:112:30 | Attribute() | |
| Taint externally controlled string | test.py:113 | test.py:113:9:113:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:113 | test.py:113:9:113:30 | Attribute() | |
| Taint externally controlled string | test.py:114 | test.py:114:9:114:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:114 | test.py:114:9:114:35 | Attribute() | |
| Taint externally controlled string | test.py:115 | test.py:115:9:115:22 | tainted_string | | --> | Taint [externally controlled string] | test.py:115 | test.py:115:9:115:35 | Attribute() | |
| Taint externally controlled string | test.py:116 | test.py:116:9:116:22 | tainted_string | | --> | Taint externally controlled string | test.py:116 | test.py:116:9:116:30 | Attribute() | |
| Taint externally controlled string | test.py:117 | test.py:117:9:117:22 | tainted_string | | --> | Taint externally controlled string | test.py:117 | test.py:117:9:117:33 | Attribute() | |
| Taint externally controlled string | test.py:118 | test.py:118:9:118:22 | tainted_string | | --> | Taint externally controlled string | test.py:118 | test.py:118:9:118:30 | Attribute() | |
| Taint externally controlled string | test.py:121 | test.py:121:9:121:22 | tainted_string | | --> | Taint externally controlled string | test.py:121 | test.py:121:9:121:30 | Attribute() | |
| Taint externally controlled string | test.py:122 | test.py:122:9:122:22 | tainted_string | | --> | Taint externally controlled string | test.py:122 | test.py:122:9:122:33 | Attribute() | |
| Taint externally controlled string | test.py:133 | test.py:133:5:133:29 | For | | --> | Taint externally controlled string | test.py:134 | test.py:134:14:134:17 | line | |
| Taint file[externally controlled string] | test.py:126 | test.py:126:20:126:31 | TAINTED_FILE | | --> | Taint file[externally controlled string] | test.py:128 | test.py:128:9:128:20 | tainted_file | |
| Taint file[externally controlled string] | test.py:126 | test.py:126:20:126:31 | TAINTED_FILE | | --> | Taint file[externally controlled string] | test.py:129 | test.py:129:9:129:20 | tainted_file | |
| Taint file[externally controlled string] | test.py:126 | test.py:126:20:126:31 | TAINTED_FILE | | --> | Taint file[externally controlled string] | test.py:130 | test.py:130:9:130:20 | tainted_file | |
| Taint file[externally controlled string] | test.py:126 | test.py:126:20:126:31 | TAINTED_FILE | | --> | Taint file[externally controlled string] | test.py:131 | test.py:131:9:131:20 | tainted_file | |
| Taint file[externally controlled string] | test.py:126 | test.py:126:20:126:31 | TAINTED_FILE | | --> | Taint file[externally controlled string] | test.py:133 | test.py:133:17:133:28 | tainted_file | |
| Taint file[externally controlled string] | test.py:129 | test.py:129:9:129:20 | tainted_file | | --> | Taint externally controlled string | test.py:129 | test.py:129:9:129:27 | Attribute() | |
| Taint file[externally controlled string] | test.py:130 | test.py:130:9:130:20 | tainted_file | | --> | Taint externally controlled string | test.py:130 | test.py:130:9:130:31 | Attribute() | |
| Taint file[externally controlled string] | test.py:131 | test.py:131:9:131:20 | tainted_file | | --> | Taint [externally controlled string] | test.py:131 | test.py:131:9:131:32 | Attribute() | |
| Taint file[externally controlled string] | test.py:133 | test.py:133:17:133:28 | tainted_file | | --> | Taint externally controlled string | test.py:133 | test.py:133:5:133:29 | For | |
| Taint json[externally controlled string] | test.py:7 | test.py:7:20:7:45 | Attribute() | | --> | Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:20 | tainted_json | |
| Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:20 | tainted_json | | --> | Taint externally controlled string | test.py:8 | test.py:8:9:8:25 | Subscript | |
| Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:20 | tainted_json | | --> | Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:25 | Subscript | |
| Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:25 | Subscript | | --> | Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:9 | a | |
| Taint json[externally controlled string] | test.py:8 | test.py:8:9:8:25 | Subscript | | --> | Taint json[externally controlled string] | test.py:11 | test.py:11:10:11:10 | a | |
| Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:9 | a | | --> | Taint externally controlled string | test.py:9 | test.py:9:9:9:18 | Attribute() | |
| Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:9 | a | | --> | Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:18 | Attribute() | |
| Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:18 | Attribute() | | --> | Taint json[externally controlled string] | test.py:10 | test.py:10:9:10:9 | b | |
| Taint json[externally controlled string] | test.py:9 | test.py:9:9:9:18 | Attribute() | | --> | Taint json[externally controlled string] | test.py:11 | test.py:11:13:11:13 | b | |
| Taint json[externally controlled string] | test.py:10 | test.py:10:9:10:9 | b | | --> | Taint externally controlled string | test.py:10 | test.py:10:9:10:14 | Subscript | |
| Taint json[externally controlled string] | test.py:10 | test.py:10:9:10:9 | b | | --> | Taint json[externally controlled string] | test.py:10 | test.py:10:9:10:14 | Subscript | |
| Taint json[externally controlled string] | test.py:10 | test.py:10:9:10:14 | Subscript | | --> | Taint json[externally controlled string] | test.py:11 | test.py:11:16:11:16 | c | |
| Taint {externally controlled string} | test.py:73 | test.py:73:9:73:32 | parse_qs() | | --> | Taint {externally controlled string} | test.py:75 | test.py:75:16:75:16 | c | |

View File

@@ -1,56 +1,63 @@
| test.py:10 | test_json | a | externally controlled string |
| test.py:10 | test_json | a | json[externally controlled string] |
| test.py:10 | test_json | b | externally controlled string |
| test.py:10 | test_json | b | json[externally controlled string] |
| test.py:10 | test_json | c | externally controlled string |
| test.py:10 | test_json | c | json[externally controlled string] |
| test.py:21 | test_str | a | externally controlled string |
| test.py:21 | test_str | b | externally controlled string |
| test.py:21 | test_str | c | externally controlled string |
| test.py:21 | test_str | d | externally controlled string |
| test.py:21 | test_str | e | externally controlled string |
| test.py:21 | test_str | f | externally controlled string |
| test.py:21 | test_str | g | externally controlled string |
| test.py:26 | test_const_sanitizer1 | tainted_string | NO TAINT |
| test.py:28 | test_const_sanitizer1 | tainted_string | externally controlled string |
| test.py:33 | test_const_sanitizer2 | tainted_string | NO TAINT |
| test.py:35 | test_const_sanitizer2 | tainted_string | externally controlled string |
| test.py:42 | test_str2 | a | externally controlled string |
| test.py:42 | test_str2 | b | externally controlled string |
| test.py:42 | test_str2 | c | externally controlled string |
| test.py:50 | test_exc_info | res | exception.info |
| test.py:58 | test_untrusted | res | externally controlled string |
| test.py:69 | test_urlsplit_urlparse | urlparse_res | [externally controlled string] |
| test.py:69 | test_urlsplit_urlparse | urlsplit_res | [externally controlled string] |
| test.py:79 | test_method_reference | a | externally controlled string |
| test.py:79 | test_method_reference | b | NO TAINT |
| test.py:85 | test_str_methods | Attribute() | externally controlled string |
| test.py:86 | test_str_methods | Attribute() | externally controlled string |
| test.py:87 | test_str_methods | Attribute() | externally controlled string |
| test.py:88 | test_str_methods | Attribute() | externally controlled string |
| test.py:89 | test_str_methods | Attribute() | externally controlled string |
| test.py:90 | test_str_methods | Attribute() | externally controlled string |
| test.py:11 | test_json | a | externally controlled string |
| test.py:11 | test_json | a | json[externally controlled string] |
| test.py:11 | test_json | b | externally controlled string |
| test.py:11 | test_json | b | json[externally controlled string] |
| test.py:11 | test_json | c | externally controlled string |
| test.py:11 | test_json | c | json[externally controlled string] |
| test.py:22 | test_str | a | externally controlled string |
| test.py:22 | test_str | b | externally controlled string |
| test.py:22 | test_str | c | externally controlled string |
| test.py:22 | test_str | d | externally controlled string |
| test.py:22 | test_str | e | externally controlled string |
| test.py:22 | test_str | f | externally controlled string |
| test.py:22 | test_str | g | externally controlled string |
| test.py:27 | test_const_sanitizer1 | tainted_string | NO TAINT |
| test.py:29 | test_const_sanitizer1 | tainted_string | externally controlled string |
| test.py:34 | test_const_sanitizer2 | tainted_string | NO TAINT |
| test.py:36 | test_const_sanitizer2 | tainted_string | externally controlled string |
| test.py:43 | test_str2 | a | externally controlled string |
| test.py:43 | test_str2 | b | externally controlled string |
| test.py:43 | test_str2 | c | externally controlled string |
| test.py:51 | test_exc_info | res | exception.info |
| test.py:59 | test_untrusted | res | externally controlled string |
| test.py:75 | test_urlsplit_urlparse | a | [externally controlled string] |
| test.py:75 | test_urlsplit_urlparse | b | [externally controlled string] |
| test.py:75 | test_urlsplit_urlparse | c | {externally controlled string} |
| test.py:75 | test_urlsplit_urlparse | d | [[externally controlled string]] |
| test.py:85 | test_method_reference | a | externally controlled string |
| test.py:85 | test_method_reference | b | NO TAINT |
| test.py:91 | test_str_methods | Attribute() | externally controlled string |
| test.py:92 | test_str_methods | Attribute() | externally controlled string |
| test.py:93 | test_str_methods | Attribute() | externally controlled string |
| test.py:94 | test_str_methods | Attribute() | externally controlled string |
| test.py:95 | test_str_methods | Attribute() | externally controlled string |
| test.py:96 | test_str_methods | Attribute() | externally controlled string |
| test.py:97 | test_str_methods | Attribute() | [externally controlled string] |
| test.py:98 | test_str_methods | Subscript | externally controlled string |
| test.py:97 | test_str_methods | Attribute() | externally controlled string |
| test.py:98 | test_str_methods | Attribute() | externally controlled string |
| test.py:99 | test_str_methods | Attribute() | externally controlled string |
| test.py:100 | test_str_methods | Attribute() | externally controlled string |
| test.py:101 | test_str_methods | Attribute() | [externally controlled string] |
| test.py:102 | test_str_methods | Subscript | externally controlled string |
| test.py:101 | test_str_methods | Attribute() | externally controlled string |
| test.py:102 | test_str_methods | Attribute() | externally controlled string |
| test.py:103 | test_str_methods | Attribute() | [externally controlled string] |
| test.py:104 | test_str_methods | Subscript | externally controlled string |
| test.py:105 | test_str_methods | Attribute() | externally controlled string |
| test.py:106 | test_str_methods | Attribute() | [externally controlled string] |
| test.py:107 | test_str_methods | Subscript | externally controlled string |
| test.py:108 | test_str_methods | Attribute() | [externally controlled string] |
| test.py:109 | test_str_methods | Subscript | externally controlled string |
| test.py:110 | test_str_methods | Attribute() | externally controlled string |
| test.py:106 | test_str_methods | Attribute() | externally controlled string |
| test.py:107 | test_str_methods | Attribute() | [externally controlled string] |
| test.py:108 | test_str_methods | Subscript | externally controlled string |
| test.py:109 | test_str_methods | Attribute() | [externally controlled string] |
| test.py:110 | test_str_methods | Subscript | externally controlled string |
| test.py:111 | test_str_methods | Attribute() | externally controlled string |
| test.py:112 | test_str_methods | Attribute() | externally controlled string |
| test.py:115 | test_str_methods | Attribute() | externally controlled string |
| test.py:112 | test_str_methods | Attribute() | [externally controlled string] |
| test.py:113 | test_str_methods | Subscript | externally controlled string |
| test.py:114 | test_str_methods | Attribute() | [externally controlled string] |
| test.py:115 | test_str_methods | Subscript | externally controlled string |
| test.py:116 | test_str_methods | Attribute() | externally controlled string |
| test.py:117 | test_str_methods | Attribute() | externally controlled string |
| test.py:118 | test_str_methods | Attribute() | externally controlled string |
| test.py:121 | test_str_methods | Attribute() | externally controlled string |
| test.py:122 | test_str_methods | Attribute() | externally controlled string |
| test.py:128 | test_tainted_file | tainted_file | file[externally controlled string] |
| test.py:129 | test_tainted_file | Attribute() | externally controlled string |
| test.py:130 | test_tainted_file | Attribute() | externally controlled string |
| test.py:131 | test_tainted_file | Attribute() | [externally controlled string] |
| test.py:134 | test_tainted_file | line | externally controlled string |

View File

@@ -1,5 +1,6 @@
import json
from copy import copy
import sys
def test_json():
tainted_string = TAINTED_STRING
@@ -60,13 +61,18 @@ def test_untrusted():
def exc_untrusted_call(arg):
return arg
from six.moves.urllib.parse import urlsplit, urlparse
if sys.version_info[0] == 2:
from urlparse import urlsplit, urlparse, parse_qs, parse_qsl
if sys.version_info[0] == 3:
from urllib.parse import urlsplit, urlparse, parse_qs, parse_qsl
def test_urlsplit_urlparse():
tainted_string = TAINTED_STRING
urlsplit_res = urlsplit(tainted_string)
urlparse_res = urlparse(tainted_string)
test(urlsplit_res, urlparse_res)
a = urlsplit(tainted_string)
b = urlparse(tainted_string)
c = parse_qs(tainted_string)
d = parse_qsl(tainted_string)
test(a, b, c, d)
def test_method_reference():
tainted_string = TAINTED_STRING
@@ -115,3 +121,14 @@ def test_str_methods():
tainted_string.upper(),
tainted_string.zfill(100),
)
def test_tainted_file():
tainted_file = TAINTED_FILE
test(
tainted_file,
tainted_file.read(),
tainted_file.readline(),
tainted_file.readlines(),
)
for line in tainted_file:
test(line)