Merge branch 'main' of github.com:github/codeql into python-port-path-injection

This commit is contained in:
Rasmus Lerchedahl Petersen
2020-10-28 10:24:23 +01:00
116 changed files with 8324 additions and 965 deletions

View File

@@ -350,6 +350,10 @@
"csharp/ql/src/experimental/ir/implementation/raw/gvn/internal/ValueNumberingImports.qll",
"csharp/ql/src/experimental/ir/implementation/unaliased_ssa/gvn/internal/ValueNumberingImports.qll"
],
"C# ControlFlowReachability": [
"csharp/ql/src/semmle/code/csharp/dataflow/internal/ControlFlowReachability.qll",
"csharp/ql/src/semmle/code/csharp/dataflow/internal/rangeanalysis/ControlFlowReachability.qll"
],
"Inline Test Expectations": [
"cpp/ql/test/TestUtilities/InlineExpectationsTest.qll",
"python/ql/test/TestUtilities/InlineExpectationsTest.qll"

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* The `cpp/wrong-type-format-argument` and `cpp/non-portable-printf` queries have been hardened so that they do not produce nonsensical results on databases that contain errors (specifically the `ErroneousType`).

View File

@@ -39,7 +39,7 @@ void good() {
</example>
<references>
<li>MSDN Library for MFC: <a href="http://msdn.microsoft.com/en-us/library/0e5twxsh(v=vs.110).aspx">Exceptions: Catching and Deleting Exceptions</a>.</li>
<li>MSDN Library for MFC: <a href="https://docs.microsoft.com/en-us/cpp/mfc/exceptions-catching-and-deleting-exceptions">Exceptions: Catching and Deleting Exceptions</a>.</li>
</references>

View File

@@ -27,7 +27,7 @@ then removing it will make code more readable. If the static variable is needed
<a href="https://www.securecoding.cert.org/confluence/display/c/MSC12-C.+Detect+and+remove+code+that+has+no+effect+or+is+never+executed">Detect and remove code that has no effect</a>
</li>
<li>
<a href="https://www.securecoding.cert.org/confluence/display/cplusplus/DCL07-CPP.+Minimize+the+scope+of+variables+and+methods">Minimize the scope of variables and methods</a>
<a href="https://wiki.sei.cmu.edu/confluence/display/c/DCL19-C.+Minimize+the+scope+of+variables+and+functions">Minimize the scope of variables and functions</a>
</li>

View File

@@ -41,7 +41,7 @@ this rule.
E. W. Dijkstra Archive: <a href="http://www.cs.utexas.edu/users/EWD/transcriptions/EWD02xx/EWD215.html">A Case against the GO TO Statement (EWD-215)</a>.
</li>
<li>
MSDN Library: <a href="http://msdn.microsoft.com/en-gb/library/b34dt9cd%28v=vs.80%29.aspx">The goto Statement</a>.
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/cpp/goto-statement-cpp">goto Statement (C++)</a>.
</li>
<li>
Mats Henricson and Erik Nyquist, <i>Industrial Strength C++</i>, Rule 4.6. Prentice Hall PTR, 1997.

View File

@@ -27,6 +27,6 @@ this cannot happen.
</example>
<references>
<li>SEI CERT C Coding Standard: <a href="https://wiki.sei.cmu.edu/confluence/display/c/EXP34-C.+Do+not+dereference+null+pointerss">EXP34-C. Do not dereference null pointers</a>.</li>
<li>SEI CERT C Coding Standard: <a href="https://wiki.sei.cmu.edu/confluence/display/c/EXP34-C.+Do+not+dereference+null+pointers">EXP34-C. Do not dereference null pointers</a>.</li>
</references>
</qhelp>

View File

@@ -23,7 +23,7 @@ As a result, this check incorrectly considers all negative numbers as even.
<references>
<li>
MSDN Library: <a href="http://msdn.microsoft.com/en-us/library/ty2ax9z9%28v=vs.71%29.aspx">Multiplicative Operators: *, /, and %</a>.
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/cpp/multiplicative-operators-and-the-modulus-operator">Multiplicative Operators and the Modulus Operator</a>.
</li>
<li>
Wikipedia: <a href="http://en.wikipedia.org/wiki/Modulo_operation#Common_pitfalls">Modulo Operation - Common pitfalls</a>.

View File

@@ -24,7 +24,7 @@
Code Project: <a href="http://www.codeproject.com/Articles/2247/An-introduction-to-bitwise-operators">An introduction to bitwise operators</a>
</li>
<li>
MSDN Library: <a href="https://msdn.microsoft.com/en-us/library/dxda59dh.aspx">Signed Bitwise Operations</a>
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/c-language/signed-bitwise-operations">Signed Bitwise Operations</a>
</li>

View File

@@ -21,7 +21,7 @@ It is best to fully parenthesize complex comparison expressions to explicitly de
<references>
<li>
<a href="http://msdn.microsoft.com/en-us/library/126fe14k%28v=VS.80%29.aspx">Operator Precedence and Associativity</a>
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/cpp/cpp-built-in-operators-precedence-and-associativity">C++ built-in operators, precedence, and associativity</a>
</li>
<li>
<a href="http://www.cplusplus.com/doc/tutorial/operators/">Operators</a>

View File

@@ -24,7 +24,7 @@ as rounding errors will be more prominent when using such values.
<li>
D. Goldberg, <em>What Every Computer Scientist Should Know About Floating-Point Arithmetic</em>,
ACM Computing Surveys, Volume 23, Issue 1, March 1991 (<a href="http://docs.sun.com/source/806-3568/ncg_goldberg.html">available online</a>).
ACM Computing Surveys, Volume 23, Issue 1, March 1991 (<a href="https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html">available online</a>).
</li>

View File

@@ -23,7 +23,7 @@ the expression would produce a result that would be too large to fit in the smal
<references>
<li>
MSDN Library: <a href="http://msdn.microsoft.com/en-us/library/ty2ax9z9%28v=vs.71%29.aspx">Multiplicative Operators: *, /, and %</a>.
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/cpp/multiplicative-operators-and-the-modulus-operator">Multiplicative Operators and the Modulus Operator</a>.
</li>
<li>
Cplusplus.com: <a href="http://www.cplusplus.com/articles/DE18T05o/">Integer overflow</a>.

View File

@@ -23,7 +23,7 @@ the latter occupies eight bytes on a 64-bit machine.</p>
<references>
<li>
MSDN Library: <a href="http://msdn.microsoft.com/en-us/library/hh279667.aspx">Type Conversions and Type Safety (Modern C++)</a>.
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/cpp/type-conversions-and-type-safety-modern-cpp">Type Conversions and Type Safety</a>.
</li>
<li>
Cplusplus.com: <a href="http://www.cplusplus.com/doc/tutorial/typecasting/">Type conversions</a>.

View File

@@ -23,7 +23,7 @@ the function.
<li>CERT C Coding
Standard: <a href="https://www.securecoding.cert.org/confluence/display/c/FIO30-C.+Exclude+user+input+from+format+strings">FIO30-C. Exclude user input from format strings</a>.</li>
<li>cplusplus.com: <a href="http://www.tutorialspoint.com/cplusplus/cpp_functions.htm">C++ Functions</a>.</li>
<li>MSDN Alphabetical Function Reference: <a href="http://msdn.microsoft.com/en-us/library/wc7014hz%28VS.71%29.aspx">printf, wprintf</a>.</li>
<li>CRT Alphabetical Function Reference: <a href="https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/printf-printf-l-wprintf-wprintf-l">printf, _printf_l, wprintf, _wprintf_l</a>.</li>

View File

@@ -155,7 +155,8 @@ where
not actual.getUnspecifiedType().(IntegralType).getSize() = sizeof_IntType()
) and
not arg.isAffectedByMacro() and
not arg.isFromUninstantiatedTemplate(_)
not arg.isFromUninstantiatedTemplate(_) and
not actual.getUnspecifiedType() instanceof ErroneousType
select arg,
"This argument should be of type '" + expected.getName() + "' but is of type '" +
actual.getUnspecifiedType().getName() + "'"

View File

@@ -15,7 +15,7 @@ of days. Alternatively, use an established library routine that already contain
</recommendation>
<references>
<li>U.S. Naval Observatory Website - <a href="https://aa.usno.navy.mil/faq/docs/calendars.php"> Introduction to Calendars</a></li>
<li>NASA / Goddard Space Flight Center - <a href="https://eclipse.gsfc.nasa.gov/SEhelp/calendars.html">Calendars</a></li>
<li>Wikipedia - <a href="https://en.wikipedia.org/wiki/Leap_year_bug"> Leap year bug</a> </li>
<li>Microsoft Azure blog - <a href="https://azure.microsoft.com/en-us/blog/is-your-code-ready-for-the-leap-year/"> Is your code ready for the leap year?</a> </li>
</references>

View File

@@ -22,7 +22,7 @@
</example>
<references>
<li>U.S. Naval Observatory Website - <a href="https://aa.usno.navy.mil/faq/docs/calendars.php"> Introduction to Calendars</a></li>
<li>NASA / Goddard Space Flight Center - <a href="https://eclipse.gsfc.nasa.gov/SEhelp/calendars.html">Calendars</a></li>
<li>Wikipedia - <a href="https://en.wikipedia.org/wiki/Leap_year_bug"> Leap year bug</a> </li>
<li>Microsoft Azure blog - <a href="https://azure.microsoft.com/en-us/blog/is-your-code-ready-for-the-leap-year/"> Is your code ready for the leap year?</a> </li>
</references>

View File

@@ -34,7 +34,7 @@
</example>
<references>
<li>U.S. Naval Observatory Website - <a href="https://aa.usno.navy.mil/faq/docs/calendars.php"> Introduction to Calendars</a></li>
<li>NASA / Goddard Space Flight Center - <a href="https://eclipse.gsfc.nasa.gov/SEhelp/calendars.html">Calendars</a></li>
<li>Wikipedia - <a href="https://en.wikipedia.org/wiki/Leap_year_bug"> Leap year bug</a> </li>
<li>Microsoft Azure blog - <a href="https://azure.microsoft.com/en-us/blog/is-your-code-ready-for-the-leap-year/"> Is your code ready for the leap year?</a> </li>
</references>

View File

@@ -23,7 +23,7 @@
</example>
<references>
<li>U.S. Naval Observatory Website - <a href="https://aa.usno.navy.mil/faq/docs/calendars.php"> Introduction to Calendars</a></li>
<li>NASA / Goddard Space Flight Center - <a href="https://eclipse.gsfc.nasa.gov/SEhelp/calendars.html">Calendars</a></li>
<li>Wikipedia - <a href="https://en.wikipedia.org/wiki/Leap_year_bug"> Leap year bug</a> </li>
<li>Microsoft Azure blog - <a href="https://azure.microsoft.com/en-us/blog/is-your-code-ready-for-the-leap-year/"> Is your code ready for the leap year?</a> </li>
</references>

View File

@@ -23,7 +23,7 @@ indication that there may be cases unhandled by the <code>switch</code> statemen
Tutorialspoint - The C++ Programming Language: <a href="http://www.tutorialspoint.com/cplusplus/cpp_switch_statement.htm">C++ switch statement</a>
</li>
<li>
MSDN Library: <a href="http://msdn.microsoft.com/en-us/library/k0t5wee3%28v=VS.80%29.aspx">The switch Statement</a>
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/cpp/switch-statement-cpp">switch statement (C++)</a>
</li>
<li>
M. Henricson and E. Nyquist, <i>Industrial Strength C++</i>, Chapter 4: Control Flow, Rec 4.5. Prentice Hall PTR, 1997 (<a href="http://mongers.org/industrial-c++/">available online</a>).

View File

@@ -88,7 +88,8 @@ where
not arg.isAffectedByMacro() and
size32 = ilp32.paddedSize(actual) and
size64 = lp64.paddedSize(actual) and
size64 != size32
size64 != size32 and
not actual instanceof ErroneousType
select arg,
"This argument should be of type '" + expected.getName() + "' but is of type '" + actual.getName()
+ "' (which changes size from " + size32 + " to " + size64 + " on 64-bit systems)."

View File

@@ -30,7 +30,7 @@ For an array, the size is the number of elements of the array multiplied by the
Cplusplus.comn: <a href="http://www.cplusplus.com/reference/clibrary/cstring/memset/">memset</a>
</li>
<li>
MSDN Library: <a href="http://msdn.microsoft.com/en-us/library/aa246471%28v=VS.60%29.aspx">memset</a>, <a href="http://msdn.microsoft.com/en-us/library/4s7x1k91%28v=VS.71%29.aspx">sizeof Operator</a>
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/memset-wmemset">memset, wmemset</a>, <a href="https://docs.microsoft.com/en-us/cpp/cpp/sizeof-operator">sizeof Operator</a>
</li>

View File

@@ -25,9 +25,6 @@ outer loop. </p>
<li>
Tutorialspoint - The C++ Programming Language: <a href="http://www.tutorialspoint.com/cplusplus/cpp_nested_loops.htm">C++ nested loops</a>
</li>
<li>
MSDN Library: <a href="http://msdn.microsoft.com/en-us/library/8y82wx12%28v=VS.80%29.aspx">Nested Control Structures</a>
</li>

View File

@@ -20,7 +20,7 @@ object instance).</p>
</example>
<references>
<li>R. Chen, <a href="http://blogs.msdn.com/oldnewthing/archive/2004/05/07/127826.aspx">When should your destructor be virtual?</a>.</li>
<li>R. Chen, <a href="https://devblogs.microsoft.com/oldnewthing/20040507-00/?p=39443">When should your destructor be virtual?</a>.</li>
<li>S. Meyers. <em>Effective C++ 3d ed.</em> pp 40-44. Addison-Wesley Professional, 2005.</li>
</references>
</qhelp>

View File

@@ -27,7 +27,7 @@ and IDE support than macros.</p>
<references>
<li>
<a href="http://msdn.microsoft.com/en-us/library/503x3e3s%28v=vs.80%29.aspx">Macros</a>
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/preprocessor/macros-c-cpp">Macros (C/C++)</a>
</li>
<li>
<a href="http://www.stroustrup.com/icsm-2012-demacro.pdf">Rejuvenating C++ Programs through

View File

@@ -15,7 +15,7 @@
<references>
<li>
<a href="http://msdn.microsoft.com/en-us/library/36k2cdd4%28v=VS.80%29.aspx">The #include Directive</a>
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/preprocessor/hash-include-directive-c-cpp">#include directive (C/C++)</a>
</li>
<li>
<a href="http://gcc.gnu.org/onlinedocs/cpp/Include-Operation.html#Include-Operation">Include operation</a>

View File

@@ -21,7 +21,7 @@ string before converting it to SQL.</p>
</example>
<references>
<li>Microsoft Developer Network: <a href="http://msdn.microsoft.com/en-us/library/ms161953.aspx">SQL Injection</a>.</li>
<li>MSDN Library: <a href="https://docs.microsoft.com/en-us/sql/relational-databases/security/sql-injection">SQL Injection</a>.</li>
<!-- LocalWords: SQL CWE

View File

@@ -1,7 +1,7 @@
/**
* @name Jump-to-definition links
* @description Generates use-definition pairs that provide the data
* for jump-to-definition in the code viewer.
* for jump-to-definition in the code viewer of LGTM.
* @kind definitions
* @id cpp/jump-to-definition
*/
@@ -9,5 +9,10 @@
import definitions
from Top e, Top def, string kind
where def = definitionOf(e, kind)
where
def = definitionOf(e, kind) and
// We need to exclude definitions for elements inside template instantiations,
// as these often lead to multiple links to definitions from the same source location.
// LGTM does not support this bevaviour.
not e.isFromTemplateInstantiation(_)
select e, def, kind

View File

@@ -124,6 +124,7 @@ private predicate constructorCallTypeMention(ConstructorCall cc, TypeMention tm)
/**
* Gets an element, of kind `kind`, that element `e` uses, if any.
* Attention: This predicate yields multiple definitions for a single location.
*
* The `kind` is a string representing what kind of use it is:
* - `"M"` for function and method calls
@@ -196,15 +197,7 @@ Top definitionOf(Top e, string kind) {
not e.(Element).isInMacroExpansion() and
// exclude nested macro invocations, as they will overlap with
// the top macro invocation.
not exists(e.(MacroAccess).getParentInvocation()) and
// exclude results from template instantiations, as:
// (1) these dependencies will often be caused by a choice of
// template parameter, which is non-local to this part of code; and
// (2) overlapping results pointing to different locations will
// be very common.
// It's possible we could allow a subset of these dependencies
// in future, if we're careful to ensure the above don't apply.
not e.isFromTemplateInstantiation(_)
not exists(e.(MacroAccess).getParentInvocation())
) and
// Some entities have many locations. This can arise for an external
// function that is frequently declared but not defined, or perhaps

View File

@@ -15,7 +15,7 @@ as both virtual and non-virtual in one hierarchy as violations.</p>
AV Rule 89, <em>Joint Strike Fighter Air Vehicle C++ Coding Standards</em>. Lockheed Martin Corporation, 2005.
</li>
<li>
<a href="http://msdn.microsoft.com/en-us/library/wcz57btd%28v=vs.80%29.aspx">Virtual Base Classes</a>
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/cpp/multiple-base-classes">Multiple Base Classes</a>.
</li>

View File

@@ -37,7 +37,7 @@ assuming the function had a non-float return type that can fit in a machine word
MISRA C++ Rule 8-4-3, <em>Guidelines for the use of the C++ language in critical systems</em>. The Motor Industry Software Reliability Associate, 2008.
</li>
<li>
<a href="http://msdn.microsoft.com/en-US/library/k68ktdwf%28v=VS.80%29.aspx">The return Statement</a>
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/cpp/return-statement-cpp">return Statement (C++)</a>.
</li>

View File

@@ -37,7 +37,7 @@ better to let the compiler assign values at compile time.
MISRA C++ Rule 8-5-3, <em>Guidelines for the use of the C++ language in critical systems</em>. The Motor Industry Software Reliability Associate, 2008.
</li>
<li>
<a href="http://msdn.microsoft.com/en-us/library/2dzy4k6e%28v=vs.71%29.aspx">C++ Enumeration Declarations</a>
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/cpp/enumerations-cpp">Enumerations (C++)</a>.
</li>

View File

@@ -29,7 +29,7 @@ the break statement only exits from one level of the loop.</p>
<a href="http://www.cs.utexas.edu/users/EWD/transcriptions/EWD02xx/EWD215.html">A Case against the GO TO Statement (EWD-215).</a>
</li>
<li>
<a href="https://msdn.microsoft.com/en-gb/library/b34dt9cd%28v=vs.80%29.aspx">MSDN Library: The goto Statement</a>
MSDN Library: <a href="https://docs.microsoft.com/en-us/cpp/cpp/goto-statement-cpp">goto Statement (C++)</a>.
</li>
<li>
Mats Henricson and Erik Nyquist, <i>Industrial Strength C++</i>, published by Prentice Hall PTR (1997).

View File

@@ -1,7 +1,7 @@
/**
* @name Jump-to-definition links
* @description Generates use-definition pairs that provide the data
* for jump-to-definition in the code viewer.
* for jump-to-definition in the code viewer of VSCode.
* @kind definitions
* @id cpp/ide-jump-to-definition
* @tags ide-contextual-queries/local-definitions

View File

@@ -1,7 +1,7 @@
/**
* @name Find-references links
* @description Generates use-definition pairs that provide the data
* for find-references in the code viewer.
* for find-references in the code viewer of VSCode.
* @kind definitions
* @id cpp/ide-find-references
* @tags ide-contextual-queries/local-references

View File

@@ -1,4 +1,17 @@
import cpp
private import PrintAST
/**
* Print function declarations only if there is a `PrintASTConfiguration`
* that requests that function, or no `PrintASTConfiguration` exists.
*/
private predicate shouldPrintDeclaration(Declaration decl) {
not decl instanceof Function
or
not exists(PrintASTConfiguration c)
or
exists(PrintASTConfiguration config | config.shouldPrintFunction(decl))
}
/**
* Gets a string containing the scope in which this declaration is declared.
@@ -48,6 +61,8 @@ private string getTemplateArgumentString(Declaration d, int i) {
* A `Declaration` extended to add methods for generating strings useful only for dumps and debugging.
*/
abstract private class DumpDeclaration extends Declaration {
DumpDeclaration() { shouldPrintDeclaration(this) }
/**
* Gets a string that uniquely identifies this declaration, suitable for use when debugging queries. Only holds for
* functions, user-defined types, global and namespace-scope variables, and member variables.

View File

@@ -801,12 +801,34 @@ module FlowVar_internal {
}
Expr getAnIteratorAccess(Variable collection) {
exists(Call c, SsaDefinition def, Variable iterator |
c.getQualifier() = collection.getAnAccess() and
c.getTarget() instanceof BeginOrEndFunction and
exists(
Call c, SsaDefinition def, Variable iterator, FunctionInput input, FunctionOutput output
|
c.getTarget().(GetIteratorFunction).getsIterator(input, output) and
(
(
input.isQualifierObject() or
input.isQualifierAddress()
) and
c.getQualifier() = collection.getAnAccess()
or
exists(int index |
input.isParameter(index) or
input.isParameterDeref(index)
|
c.getArgument(index) = collection.getAnAccess()
)
) and
output.isReturnValue() and
def.getAnUltimateDefiningValue(iterator) = c and
result = def.getAUse(iterator)
)
or
exists(Call crement |
crement = result and
[crement.getQualifier(), crement.getArgument(0)] = getAnIteratorAccess(collection) and
crement.getTarget().getName() = ["operator++", "operator--"]
)
}
class IteratorParameter extends Parameter {

View File

@@ -217,4 +217,8 @@ string getInstructionTagId(TInstructionTag tag) {
tag = DynamicInitializationFlagConstantTag() and result = "DynInitFlagConst"
or
tag = DynamicInitializationFlagStoreTag() and result = "DynInitFlagStore"
or
tag = ThisAddressTag() and result = "ThisAddres"
or
tag = ThisLoadTag() and result = "ThisLoad"
}

View File

@@ -92,6 +92,9 @@ class IteratorPointerDereferenceOperator extends Operator, TaintFunction, Iterat
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = iteratorInput and
output.isReturnValue()
or
input.isReturnValueDeref() and
output.isParameterDeref(0)
}
}
@@ -180,6 +183,9 @@ class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunc
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and
output.isReturnValue()
or
input.isReturnValueDeref() and
output.isQualifierObject()
}
}
@@ -274,11 +280,32 @@ class IteratorArrayMemberOperator extends MemberFunction, TaintFunction, Iterato
}
}
/**
* An `operator=` member function of an iterator class that is not a copy or move assignment
* operator.
*
* The `hasTaintFlow` override provides flow through output iterators that return themselves with
* `operator*` and use their own `operator=` to assign to the container.
*/
class IteratorAssignmentMemberOperator extends MemberFunction, TaintFunction {
IteratorAssignmentMemberOperator() {
this.hasName("operator=") and
this.getDeclaringType() instanceof Iterator and
not this instanceof CopyAssignmentOperator and
not this instanceof MoveAssignmentOperator
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(0) and
output.isQualifierObject()
}
}
/**
* A `begin` or `end` member function, or a related member function, that
* returns an iterator.
*/
class BeginOrEndFunction extends MemberFunction, TaintFunction {
class BeginOrEndFunction extends MemberFunction, TaintFunction, GetIteratorFunction {
BeginOrEndFunction() {
this
.hasName(["begin", "cbegin", "rbegin", "crbegin", "end", "cend", "rend", "crend",
@@ -290,4 +317,24 @@ class BeginOrEndFunction extends MemberFunction, TaintFunction {
input.isQualifierObject() and
output.isReturnValue()
}
override predicate getsIterator(FunctionInput input, FunctionOutput output) {
input.isQualifierObject() and
output.isReturnValue()
}
}
/**
* The `std::front_inserter`, `std::inserter`, and `std::back_inserter`
* functions.
*/
class InserterIteratorFunction extends GetIteratorFunction {
InserterIteratorFunction() {
this.hasQualifiedName("std", ["front_inserter", "inserter", "back_inserter"])
}
override predicate getsIterator(FunctionInput input, FunctionOutput output) {
input.isParameterDeref(0) and
output.isReturnValue()
}
}

View File

@@ -15,3 +15,14 @@ import semmle.code.cpp.models.Models
* can be used to write to the iterator's underlying collection.
*/
abstract class IteratorReferenceFunction extends Function { }
/**
* A function which takes a container and returns an iterator over that container.
*/
abstract class GetIteratorFunction extends Function {
/**
* Holds if the return value or buffer represented by `output` is an iterator over the container
* passd in the argument, qualifier, or buffer represented by `input`.
*/
abstract predicate getsIterator(FunctionInput input, FunctionOutput output);
}

View File

@@ -260,6 +260,8 @@
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | (unnamed parameter 0) | |
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | (unnamed parameter 0) | |
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | (unnamed parameter 0) | |
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | (unnamed parameter 0) | |
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | (unnamed parameter 0) | |
| format.cpp:16:21:16:21 | s | format.cpp:22:22:22:22 | s | |
| format.cpp:16:31:16:31 | n | format.cpp:22:25:22:25 | n | |
| format.cpp:16:46:16:51 | format | format.cpp:22:28:22:33 | format | |
@@ -3145,147 +3147,182 @@
| standalone_iterators.cpp:51:37:51:43 | source1 | standalone_iterators.cpp:53:12:53:18 | source1 | |
| standalone_iterators.cpp:51:37:51:43 | source1 | standalone_iterators.cpp:54:14:54:20 | source1 | |
| standalone_iterators.cpp:53:12:53:18 | ref arg source1 | standalone_iterators.cpp:54:14:54:20 | source1 | |
| stl.h:241:30:241:40 | call to allocator | stl.h:241:21:241:41 | noexcept(...) | TAINT |
| stl.h:241:30:241:40 | call to allocator | stl.h:241:21:241:41 | noexcept(...) | TAINT |
| stl.h:241:30:241:40 | call to allocator | stl.h:241:21:241:41 | noexcept(...) | TAINT |
| stl.h:241:30:241:40 | call to allocator | stl.h:241:21:241:41 | noexcept(...) | TAINT |
| stl.h:241:30:241:40 | call to allocator | stl.h:241:21:241:41 | noexcept(...) | TAINT |
| stl.h:241:53:241:63 | 0 | stl.h:241:46:241:64 | (no string representation) | TAINT |
| stl.h:334:9:334:9 | Unknown literal | stl.h:334:9:334:9 | constructor init of field first | TAINT |
| stl.h:334:9:334:9 | Unknown literal | stl.h:334:9:334:9 | constructor init of field second | TAINT |
| stl.h:334:9:334:9 | constructor init of field first [post-this] | stl.h:334:9:334:9 | constructor init of field second [pre-this] | |
| stl.h:334:9:334:9 | constructor init of field first [pre-this] | stl.h:334:9:334:9 | constructor init of field second [pre-this] | |
| stl.h:334:9:334:9 | this | stl.h:334:9:334:9 | constructor init of field first [pre-this] | |
| stl.h:341:3:341:3 | this | stl.h:341:36:341:43 | constructor init of field first [pre-this] | |
| stl.h:341:3:341:3 | this | stl.h:341:36:341:43 | constructor init of field first [pre-this] | |
| stl.h:341:3:341:3 | this | stl.h:341:36:341:43 | constructor init of field first [pre-this] | |
| stl.h:341:3:341:3 | this | stl.h:341:36:341:43 | constructor init of field first [pre-this] | |
| stl.h:341:3:341:3 | this | stl.h:341:36:341:43 | constructor init of field first [pre-this] | |
| stl.h:341:3:341:3 | this | stl.h:341:36:341:43 | constructor init of field first [pre-this] | |
| stl.h:341:3:341:3 | this | stl.h:341:36:341:43 | constructor init of field first [pre-this] | |
| stl.h:341:3:341:6 | this | stl.h:341:36:341:43 | constructor init of field first [pre-this] | |
| stl.h:341:18:341:18 | x | stl.h:341:18:341:18 | x | |
| stl.h:341:18:341:18 | x | stl.h:341:18:341:18 | x | |
| stl.h:341:18:341:18 | x | stl.h:341:18:341:18 | x | |
| stl.h:341:18:341:18 | x | stl.h:341:18:341:18 | x | |
| stl.h:341:18:341:18 | x | stl.h:341:42:341:42 | x | |
| stl.h:341:18:341:18 | x | stl.h:341:42:341:42 | x | |
| stl.h:341:18:341:18 | x | stl.h:341:42:341:42 | x | |
| stl.h:341:18:341:18 | x | stl.h:341:42:341:42 | x | |
| stl.h:341:18:341:18 | x | stl.h:341:42:341:42 | x | |
| stl.h:341:18:341:18 | x | stl.h:341:42:341:42 | x | |
| stl.h:341:18:341:18 | x | stl.h:341:42:341:42 | x | |
| stl.h:341:18:341:18 | x | stl.h:341:42:341:42 | x | |
| stl.h:341:31:341:31 | y | stl.h:341:31:341:31 | y | |
| stl.h:341:31:341:31 | y | stl.h:341:31:341:31 | y | |
| stl.h:341:31:341:31 | y | stl.h:341:31:341:31 | y | |
| stl.h:341:31:341:31 | y | stl.h:341:31:341:31 | y | |
| stl.h:341:31:341:31 | y | stl.h:341:53:341:53 | y | |
| stl.h:341:31:341:31 | y | stl.h:341:53:341:53 | y | |
| stl.h:341:31:341:31 | y | stl.h:341:53:341:53 | y | |
| stl.h:341:31:341:31 | y | stl.h:341:53:341:53 | y | |
| stl.h:341:31:341:31 | y | stl.h:341:53:341:53 | y | |
| stl.h:341:31:341:31 | y | stl.h:341:53:341:53 | y | |
| stl.h:341:31:341:31 | y | stl.h:341:53:341:53 | y | |
| stl.h:341:31:341:31 | y | stl.h:341:53:341:53 | y | |
| stl.h:341:36:341:43 | call to unknown function | stl.h:341:36:341:43 | constructor init of field first | TAINT |
| stl.h:341:36:341:43 | constructor init of field first [post-this] | stl.h:341:46:341:54 | constructor init of field second [pre-this] | |
| stl.h:341:36:341:43 | constructor init of field first [post-this] | stl.h:341:46:341:54 | constructor init of field second [pre-this] | |
| stl.h:341:36:341:43 | constructor init of field first [post-this] | stl.h:341:46:341:54 | constructor init of field second [pre-this] | |
| stl.h:341:36:341:43 | constructor init of field first [post-this] | stl.h:341:46:341:54 | constructor init of field second [pre-this] | |
| stl.h:341:36:341:43 | constructor init of field first [post-this] | stl.h:341:46:341:54 | constructor init of field second [pre-this] | |
| stl.h:341:36:341:43 | constructor init of field first [post-this] | stl.h:341:46:341:54 | constructor init of field second [pre-this] | |
| stl.h:341:36:341:43 | constructor init of field first [post-this] | stl.h:341:46:341:54 | constructor init of field second [pre-this] | |
| stl.h:341:36:341:43 | constructor init of field first [post-this] | stl.h:341:46:341:54 | constructor init of field second [pre-this] | |
| stl.h:341:36:341:43 | constructor init of field first [pre-this] | stl.h:341:46:341:54 | constructor init of field second [pre-this] | |
| stl.h:341:36:341:43 | constructor init of field first [pre-this] | stl.h:341:46:341:54 | constructor init of field second [pre-this] | |
| stl.h:341:36:341:43 | constructor init of field first [pre-this] | stl.h:341:46:341:54 | constructor init of field second [pre-this] | |
| stl.h:341:36:341:43 | constructor init of field first [pre-this] | stl.h:341:46:341:54 | constructor init of field second [pre-this] | |
| stl.h:341:36:341:43 | constructor init of field first [pre-this] | stl.h:341:46:341:54 | constructor init of field second [pre-this] | |
| stl.h:341:36:341:43 | constructor init of field first [pre-this] | stl.h:341:46:341:54 | constructor init of field second [pre-this] | |
| stl.h:341:36:341:43 | constructor init of field first [pre-this] | stl.h:341:46:341:54 | constructor init of field second [pre-this] | |
| stl.h:341:36:341:43 | constructor init of field first [pre-this] | stl.h:341:46:341:54 | constructor init of field second [pre-this] | |
| stl.h:341:42:341:42 | x | stl.h:341:36:341:43 | constructor init of field first | TAINT |
| stl.h:341:42:341:42 | x | stl.h:341:36:341:43 | constructor init of field first | TAINT |
| stl.h:341:42:341:42 | x | stl.h:341:36:341:43 | constructor init of field first | TAINT |
| stl.h:341:42:341:42 | x | stl.h:341:36:341:43 | constructor init of field first | TAINT |
| stl.h:341:42:341:42 | x | stl.h:341:36:341:43 | constructor init of field first | TAINT |
| stl.h:341:42:341:42 | x | stl.h:341:36:341:43 | constructor init of field first | TAINT |
| stl.h:341:42:341:42 | x | stl.h:341:36:341:43 | constructor init of field first | TAINT |
| stl.h:341:46:341:54 | call to unknown function | stl.h:341:46:341:54 | constructor init of field second | TAINT |
| stl.h:341:53:341:53 | y | stl.h:341:46:341:54 | constructor init of field second | TAINT |
| stl.h:341:53:341:53 | y | stl.h:341:46:341:54 | constructor init of field second | TAINT |
| stl.h:341:53:341:53 | y | stl.h:341:46:341:54 | constructor init of field second | TAINT |
| stl.h:341:53:341:53 | y | stl.h:341:46:341:54 | constructor init of field second | TAINT |
| stl.h:341:53:341:53 | y | stl.h:341:46:341:54 | constructor init of field second | TAINT |
| stl.h:341:53:341:53 | y | stl.h:341:46:341:54 | constructor init of field second | TAINT |
| stl.h:341:53:341:53 | y | stl.h:341:46:341:54 | constructor init of field second | TAINT |
| stl.h:347:109:347:109 | x | stl.h:347:109:347:109 | x | |
| stl.h:347:109:347:109 | x | stl.h:347:109:347:109 | x | |
| stl.h:347:109:347:109 | x | stl.h:347:109:347:109 | x | |
| stl.h:347:109:347:109 | x | stl.h:347:109:347:109 | x | |
| stl.h:347:109:347:109 | x | stl.h:347:109:347:109 | x | |
| stl.h:347:109:347:109 | x | stl.h:347:109:347:109 | x | |
| stl.h:347:109:347:109 | x | stl.h:347:109:347:109 | x | |
| stl.h:347:109:347:109 | x | stl.h:348:40:348:40 | x | |
| stl.h:347:109:347:109 | x | stl.h:348:40:348:40 | x | |
| stl.h:347:109:347:109 | x | stl.h:348:40:348:40 | x | |
| stl.h:347:109:347:109 | x | stl.h:348:40:348:40 | x | |
| stl.h:347:109:347:109 | x | stl.h:348:40:348:40 | x | |
| stl.h:347:109:347:109 | x | stl.h:348:40:348:40 | x | |
| stl.h:347:109:347:109 | x | stl.h:348:40:348:40 | x | |
| stl.h:347:117:347:117 | y | stl.h:347:117:347:117 | y | |
| stl.h:347:117:347:117 | y | stl.h:347:117:347:117 | y | |
| stl.h:347:117:347:117 | y | stl.h:347:117:347:117 | y | |
| stl.h:347:117:347:117 | y | stl.h:347:117:347:117 | y | |
| stl.h:347:117:347:117 | y | stl.h:347:117:347:117 | y | |
| stl.h:347:117:347:117 | y | stl.h:347:117:347:117 | y | |
| stl.h:347:117:347:117 | y | stl.h:347:117:347:117 | y | |
| stl.h:347:117:347:117 | y | stl.h:348:61:348:61 | y | |
| stl.h:347:117:347:117 | y | stl.h:348:61:348:61 | y | |
| stl.h:347:117:347:117 | y | stl.h:348:61:348:61 | y | |
| stl.h:347:117:347:117 | y | stl.h:348:61:348:61 | y | |
| stl.h:347:117:347:117 | y | stl.h:348:61:348:61 | y | |
| stl.h:347:117:347:117 | y | stl.h:348:61:348:61 | y | |
| stl.h:347:117:347:117 | y | stl.h:348:61:348:61 | y | |
| stl.h:348:10:348:63 | call to pair | stl.h:348:10:348:63 | call to pair | TAINT |
| stl.h:348:10:348:63 | call to pair | stl.h:348:10:348:63 | call to pair | TAINT |
| stl.h:348:10:348:63 | call to pair | stl.h:348:10:348:63 | call to pair | TAINT |
| stl.h:348:10:348:63 | call to pair | stl.h:348:10:348:63 | call to pair | TAINT |
| stl.h:348:10:348:63 | call to pair | stl.h:348:10:348:63 | call to pair | TAINT |
| stl.h:348:10:348:63 | call to pair | stl.h:348:10:348:63 | call to pair | TAINT |
| stl.h:348:23:348:38 | ref arg call to forward | stl.h:347:109:347:109 | x | |
| stl.h:348:23:348:38 | ref arg call to forward | stl.h:347:109:347:109 | x | |
| stl.h:348:23:348:38 | ref arg call to forward | stl.h:347:109:347:109 | x | |
| stl.h:348:23:348:38 | ref arg call to forward | stl.h:347:109:347:109 | x | |
| stl.h:348:23:348:38 | ref arg call to forward | stl.h:348:40:348:40 | x [inner post update] | |
| stl.h:348:23:348:38 | ref arg call to forward | stl.h:348:40:348:40 | x [inner post update] | |
| stl.h:348:23:348:38 | ref arg call to forward | stl.h:348:40:348:40 | x [inner post update] | |
| stl.h:348:23:348:38 | ref arg call to forward | stl.h:348:40:348:40 | x [inner post update] | |
| stl.h:348:40:348:40 | x | stl.h:348:23:348:38 | call to forward | |
| stl.h:348:40:348:40 | x | stl.h:348:23:348:38 | call to forward | |
| stl.h:348:40:348:40 | x | stl.h:348:23:348:38 | call to forward | |
| stl.h:348:40:348:40 | x | stl.h:348:23:348:38 | call to forward | |
| stl.h:348:40:348:40 | x | stl.h:348:23:348:38 | call to forward | |
| stl.h:348:40:348:40 | x | stl.h:348:23:348:38 | call to forward | |
| stl.h:348:44:348:59 | call to forward | stl.h:348:10:348:63 | call to pair | TAINT |
| stl.h:348:44:348:59 | call to forward | stl.h:348:10:348:63 | call to pair | TAINT |
| stl.h:348:44:348:59 | ref arg call to forward | stl.h:347:117:347:117 | y | |
| stl.h:348:44:348:59 | ref arg call to forward | stl.h:347:117:347:117 | y | |
| stl.h:348:44:348:59 | ref arg call to forward | stl.h:347:117:347:117 | y | |
| stl.h:348:44:348:59 | ref arg call to forward | stl.h:347:117:347:117 | y | |
| stl.h:348:44:348:59 | ref arg call to forward | stl.h:348:61:348:61 | y [inner post update] | |
| stl.h:348:44:348:59 | ref arg call to forward | stl.h:348:61:348:61 | y [inner post update] | |
| stl.h:348:44:348:59 | ref arg call to forward | stl.h:348:61:348:61 | y [inner post update] | |
| stl.h:348:44:348:59 | ref arg call to forward | stl.h:348:61:348:61 | y [inner post update] | |
| stl.h:348:61:348:61 | y | stl.h:348:10:348:63 | call to pair | TAINT |
| stl.h:348:61:348:61 | y | stl.h:348:10:348:63 | call to pair | TAINT |
| stl.h:348:61:348:61 | y | stl.h:348:44:348:59 | call to forward | |
| stl.h:348:61:348:61 | y | stl.h:348:44:348:59 | call to forward | |
| stl.h:348:61:348:61 | y | stl.h:348:44:348:59 | call to forward | |
| stl.h:348:61:348:61 | y | stl.h:348:44:348:59 | call to forward | |
| stl.h:348:61:348:61 | y | stl.h:348:44:348:59 | call to forward | |
| stl.h:348:61:348:61 | y | stl.h:348:44:348:59 | call to forward | |
| standalone_iterators.cpp:83:15:83:16 | call to container | standalone_iterators.cpp:85:35:85:36 | c1 | |
| standalone_iterators.cpp:83:15:83:16 | call to container | standalone_iterators.cpp:87:10:87:11 | c1 | |
| standalone_iterators.cpp:83:19:83:20 | call to container | standalone_iterators.cpp:89:35:89:36 | c2 | |
| standalone_iterators.cpp:83:19:83:20 | call to container | standalone_iterators.cpp:91:10:91:11 | c2 | |
| standalone_iterators.cpp:85:35:85:36 | c1 | standalone_iterators.cpp:85:38:85:42 | call to begin | TAINT |
| standalone_iterators.cpp:85:35:85:36 | ref arg c1 | standalone_iterators.cpp:87:10:87:11 | c1 | |
| standalone_iterators.cpp:85:38:85:42 | call to begin | standalone_iterators.cpp:86:6:86:7 | i1 | |
| standalone_iterators.cpp:86:5:86:5 | ref arg call to operator* | standalone_iterators.cpp:86:8:86:8 | ref arg call to operator-- | TAINT |
| standalone_iterators.cpp:86:5:86:5 | ref arg call to operator* | standalone_iterators.cpp:87:10:87:11 | c1 | |
| standalone_iterators.cpp:86:6:86:7 | i1 | standalone_iterators.cpp:86:8:86:8 | call to operator-- | |
| standalone_iterators.cpp:86:8:86:8 | call to operator-- | standalone_iterators.cpp:86:5:86:5 | call to operator* | TAINT |
| standalone_iterators.cpp:86:8:86:8 | ref arg call to operator-- | standalone_iterators.cpp:86:6:86:7 | ref arg i1 | |
| standalone_iterators.cpp:86:13:86:18 | call to source | standalone_iterators.cpp:86:5:86:5 | ref arg call to operator* | TAINT |
| standalone_iterators.cpp:89:35:89:36 | c2 | standalone_iterators.cpp:89:38:89:42 | call to begin | TAINT |
| standalone_iterators.cpp:89:35:89:36 | ref arg c2 | standalone_iterators.cpp:91:10:91:11 | c2 | |
| standalone_iterators.cpp:89:38:89:42 | call to begin | standalone_iterators.cpp:90:6:90:7 | i2 | |
| standalone_iterators.cpp:90:5:90:5 | ref arg call to operator* | standalone_iterators.cpp:90:8:90:8 | ref arg call to operator-- | TAINT |
| standalone_iterators.cpp:90:5:90:5 | ref arg call to operator* | standalone_iterators.cpp:91:10:91:11 | c2 | |
| standalone_iterators.cpp:90:6:90:7 | i2 | standalone_iterators.cpp:90:8:90:8 | call to operator-- | |
| standalone_iterators.cpp:90:8:90:8 | call to operator-- | standalone_iterators.cpp:90:5:90:5 | call to operator* | TAINT |
| standalone_iterators.cpp:90:8:90:8 | ref arg call to operator-- | standalone_iterators.cpp:90:6:90:7 | ref arg i2 | |
| standalone_iterators.cpp:90:13:90:13 | 0 | standalone_iterators.cpp:90:5:90:5 | ref arg call to operator* | TAINT |
| stl.h:75:8:75:8 | Unknown literal | stl.h:75:8:75:8 | constructor init of field container | TAINT |
| stl.h:75:8:75:8 | Unknown literal | stl.h:75:8:75:8 | constructor init of field container | TAINT |
| stl.h:75:8:75:8 | this | stl.h:75:8:75:8 | constructor init of field container [pre-this] | |
| stl.h:75:8:75:8 | this | stl.h:75:8:75:8 | constructor init of field container [pre-this] | |
| stl.h:95:69:95:69 | x | stl.h:95:69:95:69 | x | |
| stl.h:95:69:95:69 | x | stl.h:95:69:95:69 | x | |
| stl.h:95:69:95:69 | x | stl.h:95:69:95:69 | x | |
| stl.h:95:69:95:69 | x | stl.h:96:42:96:42 | x | |
| stl.h:95:69:95:69 | x | stl.h:96:42:96:42 | x | |
| stl.h:95:69:95:69 | x | stl.h:96:42:96:42 | x | |
| stl.h:96:42:96:42 | ref arg x | stl.h:95:69:95:69 | x | |
| stl.h:96:42:96:42 | ref arg x | stl.h:95:69:95:69 | x | |
| stl.h:292:30:292:40 | call to allocator | stl.h:292:21:292:41 | noexcept(...) | TAINT |
| stl.h:292:30:292:40 | call to allocator | stl.h:292:21:292:41 | noexcept(...) | TAINT |
| stl.h:292:30:292:40 | call to allocator | stl.h:292:21:292:41 | noexcept(...) | TAINT |
| stl.h:292:30:292:40 | call to allocator | stl.h:292:21:292:41 | noexcept(...) | TAINT |
| stl.h:292:30:292:40 | call to allocator | stl.h:292:21:292:41 | noexcept(...) | TAINT |
| stl.h:292:30:292:40 | call to allocator | stl.h:292:21:292:41 | noexcept(...) | TAINT |
| stl.h:292:53:292:63 | 0 | stl.h:292:46:292:64 | (no string representation) | TAINT |
| stl.h:385:9:385:9 | Unknown literal | stl.h:385:9:385:9 | constructor init of field first | TAINT |
| stl.h:385:9:385:9 | Unknown literal | stl.h:385:9:385:9 | constructor init of field second | TAINT |
| stl.h:385:9:385:9 | constructor init of field first [post-this] | stl.h:385:9:385:9 | constructor init of field second [pre-this] | |
| stl.h:385:9:385:9 | constructor init of field first [pre-this] | stl.h:385:9:385:9 | constructor init of field second [pre-this] | |
| stl.h:385:9:385:9 | this | stl.h:385:9:385:9 | constructor init of field first [pre-this] | |
| stl.h:392:3:392:3 | this | stl.h:392:36:392:43 | constructor init of field first [pre-this] | |
| stl.h:392:3:392:3 | this | stl.h:392:36:392:43 | constructor init of field first [pre-this] | |
| stl.h:392:3:392:3 | this | stl.h:392:36:392:43 | constructor init of field first [pre-this] | |
| stl.h:392:3:392:3 | this | stl.h:392:36:392:43 | constructor init of field first [pre-this] | |
| stl.h:392:3:392:3 | this | stl.h:392:36:392:43 | constructor init of field first [pre-this] | |
| stl.h:392:3:392:3 | this | stl.h:392:36:392:43 | constructor init of field first [pre-this] | |
| stl.h:392:3:392:3 | this | stl.h:392:36:392:43 | constructor init of field first [pre-this] | |
| stl.h:392:3:392:6 | this | stl.h:392:36:392:43 | constructor init of field first [pre-this] | |
| stl.h:392:18:392:18 | x | stl.h:392:18:392:18 | x | |
| stl.h:392:18:392:18 | x | stl.h:392:18:392:18 | x | |
| stl.h:392:18:392:18 | x | stl.h:392:18:392:18 | x | |
| stl.h:392:18:392:18 | x | stl.h:392:18:392:18 | x | |
| stl.h:392:18:392:18 | x | stl.h:392:42:392:42 | x | |
| stl.h:392:18:392:18 | x | stl.h:392:42:392:42 | x | |
| stl.h:392:18:392:18 | x | stl.h:392:42:392:42 | x | |
| stl.h:392:18:392:18 | x | stl.h:392:42:392:42 | x | |
| stl.h:392:18:392:18 | x | stl.h:392:42:392:42 | x | |
| stl.h:392:18:392:18 | x | stl.h:392:42:392:42 | x | |
| stl.h:392:18:392:18 | x | stl.h:392:42:392:42 | x | |
| stl.h:392:18:392:18 | x | stl.h:392:42:392:42 | x | |
| stl.h:392:31:392:31 | y | stl.h:392:31:392:31 | y | |
| stl.h:392:31:392:31 | y | stl.h:392:31:392:31 | y | |
| stl.h:392:31:392:31 | y | stl.h:392:31:392:31 | y | |
| stl.h:392:31:392:31 | y | stl.h:392:31:392:31 | y | |
| stl.h:392:31:392:31 | y | stl.h:392:53:392:53 | y | |
| stl.h:392:31:392:31 | y | stl.h:392:53:392:53 | y | |
| stl.h:392:31:392:31 | y | stl.h:392:53:392:53 | y | |
| stl.h:392:31:392:31 | y | stl.h:392:53:392:53 | y | |
| stl.h:392:31:392:31 | y | stl.h:392:53:392:53 | y | |
| stl.h:392:31:392:31 | y | stl.h:392:53:392:53 | y | |
| stl.h:392:31:392:31 | y | stl.h:392:53:392:53 | y | |
| stl.h:392:31:392:31 | y | stl.h:392:53:392:53 | y | |
| stl.h:392:36:392:43 | call to unknown function | stl.h:392:36:392:43 | constructor init of field first | TAINT |
| stl.h:392:36:392:43 | constructor init of field first [post-this] | stl.h:392:46:392:54 | constructor init of field second [pre-this] | |
| stl.h:392:36:392:43 | constructor init of field first [post-this] | stl.h:392:46:392:54 | constructor init of field second [pre-this] | |
| stl.h:392:36:392:43 | constructor init of field first [post-this] | stl.h:392:46:392:54 | constructor init of field second [pre-this] | |
| stl.h:392:36:392:43 | constructor init of field first [post-this] | stl.h:392:46:392:54 | constructor init of field second [pre-this] | |
| stl.h:392:36:392:43 | constructor init of field first [post-this] | stl.h:392:46:392:54 | constructor init of field second [pre-this] | |
| stl.h:392:36:392:43 | constructor init of field first [post-this] | stl.h:392:46:392:54 | constructor init of field second [pre-this] | |
| stl.h:392:36:392:43 | constructor init of field first [post-this] | stl.h:392:46:392:54 | constructor init of field second [pre-this] | |
| stl.h:392:36:392:43 | constructor init of field first [post-this] | stl.h:392:46:392:54 | constructor init of field second [pre-this] | |
| stl.h:392:36:392:43 | constructor init of field first [pre-this] | stl.h:392:46:392:54 | constructor init of field second [pre-this] | |
| stl.h:392:36:392:43 | constructor init of field first [pre-this] | stl.h:392:46:392:54 | constructor init of field second [pre-this] | |
| stl.h:392:36:392:43 | constructor init of field first [pre-this] | stl.h:392:46:392:54 | constructor init of field second [pre-this] | |
| stl.h:392:36:392:43 | constructor init of field first [pre-this] | stl.h:392:46:392:54 | constructor init of field second [pre-this] | |
| stl.h:392:36:392:43 | constructor init of field first [pre-this] | stl.h:392:46:392:54 | constructor init of field second [pre-this] | |
| stl.h:392:36:392:43 | constructor init of field first [pre-this] | stl.h:392:46:392:54 | constructor init of field second [pre-this] | |
| stl.h:392:36:392:43 | constructor init of field first [pre-this] | stl.h:392:46:392:54 | constructor init of field second [pre-this] | |
| stl.h:392:36:392:43 | constructor init of field first [pre-this] | stl.h:392:46:392:54 | constructor init of field second [pre-this] | |
| stl.h:392:42:392:42 | x | stl.h:392:36:392:43 | constructor init of field first | TAINT |
| stl.h:392:42:392:42 | x | stl.h:392:36:392:43 | constructor init of field first | TAINT |
| stl.h:392:42:392:42 | x | stl.h:392:36:392:43 | constructor init of field first | TAINT |
| stl.h:392:42:392:42 | x | stl.h:392:36:392:43 | constructor init of field first | TAINT |
| stl.h:392:42:392:42 | x | stl.h:392:36:392:43 | constructor init of field first | TAINT |
| stl.h:392:42:392:42 | x | stl.h:392:36:392:43 | constructor init of field first | TAINT |
| stl.h:392:42:392:42 | x | stl.h:392:36:392:43 | constructor init of field first | TAINT |
| stl.h:392:46:392:54 | call to unknown function | stl.h:392:46:392:54 | constructor init of field second | TAINT |
| stl.h:392:53:392:53 | y | stl.h:392:46:392:54 | constructor init of field second | TAINT |
| stl.h:392:53:392:53 | y | stl.h:392:46:392:54 | constructor init of field second | TAINT |
| stl.h:392:53:392:53 | y | stl.h:392:46:392:54 | constructor init of field second | TAINT |
| stl.h:392:53:392:53 | y | stl.h:392:46:392:54 | constructor init of field second | TAINT |
| stl.h:392:53:392:53 | y | stl.h:392:46:392:54 | constructor init of field second | TAINT |
| stl.h:392:53:392:53 | y | stl.h:392:46:392:54 | constructor init of field second | TAINT |
| stl.h:392:53:392:53 | y | stl.h:392:46:392:54 | constructor init of field second | TAINT |
| stl.h:398:109:398:109 | x | stl.h:398:109:398:109 | x | |
| stl.h:398:109:398:109 | x | stl.h:398:109:398:109 | x | |
| stl.h:398:109:398:109 | x | stl.h:398:109:398:109 | x | |
| stl.h:398:109:398:109 | x | stl.h:398:109:398:109 | x | |
| stl.h:398:109:398:109 | x | stl.h:398:109:398:109 | x | |
| stl.h:398:109:398:109 | x | stl.h:398:109:398:109 | x | |
| stl.h:398:109:398:109 | x | stl.h:398:109:398:109 | x | |
| stl.h:398:109:398:109 | x | stl.h:399:40:399:40 | x | |
| stl.h:398:109:398:109 | x | stl.h:399:40:399:40 | x | |
| stl.h:398:109:398:109 | x | stl.h:399:40:399:40 | x | |
| stl.h:398:109:398:109 | x | stl.h:399:40:399:40 | x | |
| stl.h:398:109:398:109 | x | stl.h:399:40:399:40 | x | |
| stl.h:398:109:398:109 | x | stl.h:399:40:399:40 | x | |
| stl.h:398:109:398:109 | x | stl.h:399:40:399:40 | x | |
| stl.h:398:117:398:117 | y | stl.h:398:117:398:117 | y | |
| stl.h:398:117:398:117 | y | stl.h:398:117:398:117 | y | |
| stl.h:398:117:398:117 | y | stl.h:398:117:398:117 | y | |
| stl.h:398:117:398:117 | y | stl.h:398:117:398:117 | y | |
| stl.h:398:117:398:117 | y | stl.h:398:117:398:117 | y | |
| stl.h:398:117:398:117 | y | stl.h:398:117:398:117 | y | |
| stl.h:398:117:398:117 | y | stl.h:398:117:398:117 | y | |
| stl.h:398:117:398:117 | y | stl.h:399:61:399:61 | y | |
| stl.h:398:117:398:117 | y | stl.h:399:61:399:61 | y | |
| stl.h:398:117:398:117 | y | stl.h:399:61:399:61 | y | |
| stl.h:398:117:398:117 | y | stl.h:399:61:399:61 | y | |
| stl.h:398:117:398:117 | y | stl.h:399:61:399:61 | y | |
| stl.h:398:117:398:117 | y | stl.h:399:61:399:61 | y | |
| stl.h:398:117:398:117 | y | stl.h:399:61:399:61 | y | |
| stl.h:399:10:399:63 | call to pair | stl.h:399:10:399:63 | call to pair | TAINT |
| stl.h:399:10:399:63 | call to pair | stl.h:399:10:399:63 | call to pair | TAINT |
| stl.h:399:10:399:63 | call to pair | stl.h:399:10:399:63 | call to pair | TAINT |
| stl.h:399:10:399:63 | call to pair | stl.h:399:10:399:63 | call to pair | TAINT |
| stl.h:399:10:399:63 | call to pair | stl.h:399:10:399:63 | call to pair | TAINT |
| stl.h:399:10:399:63 | call to pair | stl.h:399:10:399:63 | call to pair | TAINT |
| stl.h:399:23:399:38 | ref arg call to forward | stl.h:398:109:398:109 | x | |
| stl.h:399:23:399:38 | ref arg call to forward | stl.h:398:109:398:109 | x | |
| stl.h:399:23:399:38 | ref arg call to forward | stl.h:398:109:398:109 | x | |
| stl.h:399:23:399:38 | ref arg call to forward | stl.h:398:109:398:109 | x | |
| stl.h:399:23:399:38 | ref arg call to forward | stl.h:399:40:399:40 | x [inner post update] | |
| stl.h:399:23:399:38 | ref arg call to forward | stl.h:399:40:399:40 | x [inner post update] | |
| stl.h:399:23:399:38 | ref arg call to forward | stl.h:399:40:399:40 | x [inner post update] | |
| stl.h:399:23:399:38 | ref arg call to forward | stl.h:399:40:399:40 | x [inner post update] | |
| stl.h:399:40:399:40 | x | stl.h:399:23:399:38 | call to forward | |
| stl.h:399:40:399:40 | x | stl.h:399:23:399:38 | call to forward | |
| stl.h:399:40:399:40 | x | stl.h:399:23:399:38 | call to forward | |
| stl.h:399:40:399:40 | x | stl.h:399:23:399:38 | call to forward | |
| stl.h:399:40:399:40 | x | stl.h:399:23:399:38 | call to forward | |
| stl.h:399:40:399:40 | x | stl.h:399:23:399:38 | call to forward | |
| stl.h:399:44:399:59 | call to forward | stl.h:399:10:399:63 | call to pair | TAINT |
| stl.h:399:44:399:59 | call to forward | stl.h:399:10:399:63 | call to pair | TAINT |
| stl.h:399:44:399:59 | ref arg call to forward | stl.h:398:117:398:117 | y | |
| stl.h:399:44:399:59 | ref arg call to forward | stl.h:398:117:398:117 | y | |
| stl.h:399:44:399:59 | ref arg call to forward | stl.h:398:117:398:117 | y | |
| stl.h:399:44:399:59 | ref arg call to forward | stl.h:398:117:398:117 | y | |
| stl.h:399:44:399:59 | ref arg call to forward | stl.h:399:61:399:61 | y [inner post update] | |
| stl.h:399:44:399:59 | ref arg call to forward | stl.h:399:61:399:61 | y [inner post update] | |
| stl.h:399:44:399:59 | ref arg call to forward | stl.h:399:61:399:61 | y [inner post update] | |
| stl.h:399:44:399:59 | ref arg call to forward | stl.h:399:61:399:61 | y [inner post update] | |
| stl.h:399:61:399:61 | y | stl.h:399:10:399:63 | call to pair | TAINT |
| stl.h:399:61:399:61 | y | stl.h:399:10:399:63 | call to pair | TAINT |
| stl.h:399:61:399:61 | y | stl.h:399:44:399:59 | call to forward | |
| stl.h:399:61:399:61 | y | stl.h:399:44:399:59 | call to forward | |
| stl.h:399:61:399:61 | y | stl.h:399:44:399:59 | call to forward | |
| stl.h:399:61:399:61 | y | stl.h:399:44:399:59 | call to forward | |
| stl.h:399:61:399:61 | y | stl.h:399:44:399:59 | call to forward | |
| stl.h:399:61:399:61 | y | stl.h:399:44:399:59 | call to forward | |
| string.cpp:25:12:25:17 | call to source | string.cpp:29:7:29:7 | a | |
| string.cpp:26:16:26:20 | 123 | string.cpp:26:16:26:21 | call to basic_string | TAINT |
| string.cpp:26:16:26:21 | call to basic_string | string.cpp:30:7:30:7 | b | |
@@ -6794,66 +6831,75 @@
| vector.cpp:337:38:337:38 | b | vector.cpp:372:5:372:5 | b | |
| vector.cpp:338:22:338:24 | call to vector | vector.cpp:340:34:340:35 | v1 | |
| vector.cpp:338:22:338:24 | call to vector | vector.cpp:342:7:342:8 | v1 | |
| vector.cpp:338:22:338:24 | call to vector | vector.cpp:401:1:401:1 | v1 | |
| vector.cpp:338:22:338:24 | call to vector | vector.cpp:415:1:415:1 | v1 | |
| vector.cpp:338:30:338:32 | call to vector | vector.cpp:344:38:344:39 | v2 | |
| vector.cpp:338:30:338:32 | call to vector | vector.cpp:344:56:344:57 | v2 | |
| vector.cpp:338:30:338:32 | call to vector | vector.cpp:347:7:347:8 | v2 | |
| vector.cpp:338:30:338:32 | call to vector | vector.cpp:401:1:401:1 | v2 | |
| vector.cpp:338:30:338:32 | call to vector | vector.cpp:415:1:415:1 | v2 | |
| vector.cpp:338:38:338:40 | call to vector | vector.cpp:349:15:349:16 | v3 | |
| vector.cpp:338:38:338:40 | call to vector | vector.cpp:352:7:352:8 | v3 | |
| vector.cpp:338:38:338:40 | call to vector | vector.cpp:401:1:401:1 | v3 | |
| vector.cpp:338:38:338:40 | call to vector | vector.cpp:415:1:415:1 | v3 | |
| vector.cpp:338:46:338:48 | call to vector | vector.cpp:354:38:354:39 | v4 | |
| vector.cpp:338:46:338:48 | call to vector | vector.cpp:354:56:354:57 | v4 | |
| vector.cpp:338:46:338:48 | call to vector | vector.cpp:357:7:357:8 | v4 | |
| vector.cpp:338:46:338:48 | call to vector | vector.cpp:401:1:401:1 | v4 | |
| vector.cpp:338:46:338:48 | call to vector | vector.cpp:415:1:415:1 | v4 | |
| vector.cpp:338:54:338:56 | call to vector | vector.cpp:359:34:359:35 | v5 | |
| vector.cpp:338:54:338:56 | call to vector | vector.cpp:361:7:361:8 | v5 | |
| vector.cpp:338:54:338:56 | call to vector | vector.cpp:363:7:363:8 | v5 | |
| vector.cpp:338:54:338:56 | call to vector | vector.cpp:401:1:401:1 | v5 | |
| vector.cpp:338:54:338:56 | call to vector | vector.cpp:415:1:415:1 | v5 | |
| vector.cpp:338:62:338:64 | call to vector | vector.cpp:365:34:365:35 | v6 | |
| vector.cpp:338:62:338:64 | call to vector | vector.cpp:367:7:367:8 | v6 | |
| vector.cpp:338:62:338:64 | call to vector | vector.cpp:368:2:368:3 | v6 | |
| vector.cpp:338:62:338:64 | call to vector | vector.cpp:369:7:369:8 | v6 | |
| vector.cpp:338:62:338:64 | call to vector | vector.cpp:401:1:401:1 | v6 | |
| vector.cpp:338:62:338:64 | call to vector | vector.cpp:415:1:415:1 | v6 | |
| vector.cpp:338:70:338:72 | call to vector | vector.cpp:371:34:371:35 | v7 | |
| vector.cpp:338:70:338:72 | call to vector | vector.cpp:374:8:374:9 | v7 | |
| vector.cpp:338:70:338:72 | call to vector | vector.cpp:377:8:377:9 | v7 | |
| vector.cpp:338:70:338:72 | call to vector | vector.cpp:379:7:379:8 | v7 | |
| vector.cpp:338:70:338:72 | call to vector | vector.cpp:401:1:401:1 | v7 | |
| vector.cpp:338:70:338:72 | call to vector | vector.cpp:415:1:415:1 | v7 | |
| vector.cpp:338:78:338:80 | call to vector | vector.cpp:381:34:381:35 | v8 | |
| vector.cpp:338:78:338:80 | call to vector | vector.cpp:383:7:383:8 | v8 | |
| vector.cpp:338:78:338:80 | call to vector | vector.cpp:385:7:385:8 | v8 | |
| vector.cpp:338:78:338:80 | call to vector | vector.cpp:401:1:401:1 | v8 | |
| vector.cpp:338:78:338:80 | call to vector | vector.cpp:415:1:415:1 | v8 | |
| vector.cpp:338:86:338:88 | call to vector | vector.cpp:387:34:387:35 | v9 | |
| vector.cpp:338:86:338:88 | call to vector | vector.cpp:392:7:392:8 | v9 | |
| vector.cpp:338:86:338:88 | call to vector | vector.cpp:401:1:401:1 | v9 | |
| vector.cpp:338:86:338:88 | call to vector | vector.cpp:415:1:415:1 | v9 | |
| vector.cpp:338:95:338:97 | call to vector | vector.cpp:394:35:394:37 | v10 | |
| vector.cpp:338:95:338:97 | call to vector | vector.cpp:396:7:396:9 | v10 | |
| vector.cpp:338:95:338:97 | call to vector | vector.cpp:401:1:401:1 | v10 | |
| vector.cpp:338:95:338:97 | call to vector | vector.cpp:415:1:415:1 | v10 | |
| vector.cpp:338:104:338:106 | call to vector | vector.cpp:398:35:398:37 | v11 | |
| vector.cpp:338:104:338:106 | call to vector | vector.cpp:400:7:400:9 | v11 | |
| vector.cpp:338:104:338:106 | call to vector | vector.cpp:401:1:401:1 | v11 | |
| vector.cpp:338:104:338:106 | call to vector | vector.cpp:415:1:415:1 | v11 | |
| vector.cpp:338:113:338:115 | call to vector | vector.cpp:402:35:402:37 | v12 | |
| vector.cpp:338:113:338:115 | call to vector | vector.cpp:405:7:405:9 | v12 | |
| vector.cpp:338:113:338:115 | call to vector | vector.cpp:415:1:415:1 | v12 | |
| vector.cpp:338:122:338:124 | call to vector | vector.cpp:407:35:407:37 | v13 | |
| vector.cpp:338:122:338:124 | call to vector | vector.cpp:409:7:409:9 | v13 | |
| vector.cpp:338:122:338:124 | call to vector | vector.cpp:415:1:415:1 | v13 | |
| vector.cpp:338:131:338:133 | call to vector | vector.cpp:411:35:411:37 | v14 | |
| vector.cpp:338:131:338:133 | call to vector | vector.cpp:414:7:414:9 | v14 | |
| vector.cpp:338:131:338:133 | call to vector | vector.cpp:415:1:415:1 | v14 | |
| vector.cpp:340:34:340:35 | ref arg v1 | vector.cpp:342:7:342:8 | v1 | |
| vector.cpp:340:34:340:35 | ref arg v1 | vector.cpp:401:1:401:1 | v1 | |
| vector.cpp:340:34:340:35 | ref arg v1 | vector.cpp:415:1:415:1 | v1 | |
| vector.cpp:340:34:340:35 | v1 | vector.cpp:340:37:340:41 | call to begin | TAINT |
| vector.cpp:340:37:340:41 | call to begin | vector.cpp:341:3:341:4 | i1 | |
| vector.cpp:341:2:341:2 | call to operator* [post update] | vector.cpp:342:7:342:8 | v1 | |
| vector.cpp:341:2:341:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v1 | |
| vector.cpp:341:2:341:2 | call to operator* [post update] | vector.cpp:415:1:415:1 | v1 | |
| vector.cpp:341:2:341:15 | ... = ... | vector.cpp:341:2:341:2 | call to operator* [post update] | |
| vector.cpp:341:3:341:4 | i1 | vector.cpp:341:2:341:2 | call to operator* | TAINT |
| vector.cpp:341:8:341:13 | call to source | vector.cpp:341:2:341:2 | call to operator* [post update] | TAINT |
| vector.cpp:341:8:341:13 | call to source | vector.cpp:341:2:341:15 | ... = ... | |
| vector.cpp:342:7:342:8 | ref arg v1 | vector.cpp:401:1:401:1 | v1 | |
| vector.cpp:342:7:342:8 | ref arg v1 | vector.cpp:415:1:415:1 | v1 | |
| vector.cpp:344:38:344:39 | ref arg v2 | vector.cpp:344:56:344:57 | v2 | |
| vector.cpp:344:38:344:39 | ref arg v2 | vector.cpp:347:7:347:8 | v2 | |
| vector.cpp:344:38:344:39 | ref arg v2 | vector.cpp:401:1:401:1 | v2 | |
| vector.cpp:344:38:344:39 | ref arg v2 | vector.cpp:415:1:415:1 | v2 | |
| vector.cpp:344:38:344:39 | v2 | vector.cpp:344:41:344:45 | call to begin | TAINT |
| vector.cpp:344:41:344:45 | call to begin | vector.cpp:344:50:344:51 | it | |
| vector.cpp:344:41:344:45 | call to begin | vector.cpp:344:68:344:69 | it | |
| vector.cpp:344:41:344:45 | call to begin | vector.cpp:345:4:345:5 | it | |
| vector.cpp:344:56:344:57 | ref arg v2 | vector.cpp:344:56:344:57 | v2 | |
| vector.cpp:344:56:344:57 | ref arg v2 | vector.cpp:347:7:347:8 | v2 | |
| vector.cpp:344:56:344:57 | ref arg v2 | vector.cpp:401:1:401:1 | v2 | |
| vector.cpp:344:56:344:57 | ref arg v2 | vector.cpp:415:1:415:1 | v2 | |
| vector.cpp:344:56:344:57 | v2 | vector.cpp:344:59:344:61 | call to end | TAINT |
| vector.cpp:344:68:344:69 | it | vector.cpp:344:66:344:66 | call to operator++ | |
| vector.cpp:344:68:344:69 | ref arg it | vector.cpp:344:50:344:51 | it | |
@@ -6861,12 +6907,12 @@
| vector.cpp:344:68:344:69 | ref arg it | vector.cpp:345:4:345:5 | it | |
| vector.cpp:345:3:345:3 | call to operator* [post update] | vector.cpp:344:56:344:57 | v2 | |
| vector.cpp:345:3:345:3 | call to operator* [post update] | vector.cpp:347:7:347:8 | v2 | |
| vector.cpp:345:3:345:3 | call to operator* [post update] | vector.cpp:401:1:401:1 | v2 | |
| vector.cpp:345:3:345:3 | call to operator* [post update] | vector.cpp:415:1:415:1 | v2 | |
| vector.cpp:345:3:345:16 | ... = ... | vector.cpp:345:3:345:3 | call to operator* [post update] | |
| vector.cpp:345:4:345:5 | it | vector.cpp:345:3:345:3 | call to operator* | TAINT |
| vector.cpp:345:9:345:14 | call to source | vector.cpp:345:3:345:3 | call to operator* [post update] | TAINT |
| vector.cpp:345:9:345:14 | call to source | vector.cpp:345:3:345:16 | ... = ... | |
| vector.cpp:347:7:347:8 | ref arg v2 | vector.cpp:401:1:401:1 | v2 | |
| vector.cpp:347:7:347:8 | ref arg v2 | vector.cpp:415:1:415:1 | v2 | |
| vector.cpp:349:15:349:15 | (__begin) | vector.cpp:349:15:349:15 | call to operator* | TAINT |
| vector.cpp:349:15:349:15 | (__begin) | vector.cpp:349:15:349:15 | call to operator++ | |
| vector.cpp:349:15:349:15 | (__end) | vector.cpp:349:15:349:15 | call to iterator | |
@@ -6885,17 +6931,17 @@
| vector.cpp:349:15:349:16 | v3 | vector.cpp:349:15:349:15 | call to operator* | TAINT |
| vector.cpp:350:3:350:14 | ... = ... | vector.cpp:350:3:350:3 | x [post update] | |
| vector.cpp:350:7:350:12 | call to source | vector.cpp:350:3:350:14 | ... = ... | |
| vector.cpp:352:7:352:8 | ref arg v3 | vector.cpp:401:1:401:1 | v3 | |
| vector.cpp:352:7:352:8 | ref arg v3 | vector.cpp:415:1:415:1 | v3 | |
| vector.cpp:354:38:354:39 | ref arg v4 | vector.cpp:354:56:354:57 | v4 | |
| vector.cpp:354:38:354:39 | ref arg v4 | vector.cpp:357:7:357:8 | v4 | |
| vector.cpp:354:38:354:39 | ref arg v4 | vector.cpp:401:1:401:1 | v4 | |
| vector.cpp:354:38:354:39 | ref arg v4 | vector.cpp:415:1:415:1 | v4 | |
| vector.cpp:354:38:354:39 | v4 | vector.cpp:354:41:354:45 | call to begin | TAINT |
| vector.cpp:354:41:354:45 | call to begin | vector.cpp:354:50:354:51 | it | |
| vector.cpp:354:41:354:45 | call to begin | vector.cpp:354:68:354:69 | it | |
| vector.cpp:354:41:354:45 | call to begin | vector.cpp:355:32:355:33 | it | |
| vector.cpp:354:56:354:57 | ref arg v4 | vector.cpp:354:56:354:57 | v4 | |
| vector.cpp:354:56:354:57 | ref arg v4 | vector.cpp:357:7:357:8 | v4 | |
| vector.cpp:354:56:354:57 | ref arg v4 | vector.cpp:401:1:401:1 | v4 | |
| vector.cpp:354:56:354:57 | ref arg v4 | vector.cpp:415:1:415:1 | v4 | |
| vector.cpp:354:56:354:57 | v4 | vector.cpp:354:59:354:61 | call to end | TAINT |
| vector.cpp:354:68:354:69 | it | vector.cpp:354:66:354:66 | call to operator++ | |
| vector.cpp:354:68:354:69 | ref arg it | vector.cpp:354:50:354:51 | it | |
@@ -6903,138 +6949,311 @@
| vector.cpp:354:68:354:69 | ref arg it | vector.cpp:355:32:355:33 | it | |
| vector.cpp:355:32:355:33 | call to iterator [post update] | vector.cpp:354:56:354:57 | v4 | |
| vector.cpp:355:32:355:33 | call to iterator [post update] | vector.cpp:357:7:357:8 | v4 | |
| vector.cpp:355:32:355:33 | call to iterator [post update] | vector.cpp:401:1:401:1 | v4 | |
| vector.cpp:355:32:355:33 | call to iterator [post update] | vector.cpp:415:1:415:1 | v4 | |
| vector.cpp:355:32:355:33 | it | vector.cpp:355:32:355:33 | call to iterator | |
| vector.cpp:355:32:355:33 | it [post update] | vector.cpp:354:56:354:57 | v4 | |
| vector.cpp:355:32:355:33 | it [post update] | vector.cpp:357:7:357:8 | v4 | |
| vector.cpp:355:32:355:33 | it [post update] | vector.cpp:401:1:401:1 | v4 | |
| vector.cpp:357:7:357:8 | ref arg v4 | vector.cpp:401:1:401:1 | v4 | |
| vector.cpp:355:32:355:33 | it [post update] | vector.cpp:415:1:415:1 | v4 | |
| vector.cpp:357:7:357:8 | ref arg v4 | vector.cpp:415:1:415:1 | v4 | |
| vector.cpp:359:34:359:35 | ref arg v5 | vector.cpp:361:7:361:8 | v5 | |
| vector.cpp:359:34:359:35 | ref arg v5 | vector.cpp:363:7:363:8 | v5 | |
| vector.cpp:359:34:359:35 | ref arg v5 | vector.cpp:401:1:401:1 | v5 | |
| vector.cpp:359:34:359:35 | ref arg v5 | vector.cpp:415:1:415:1 | v5 | |
| vector.cpp:359:34:359:35 | v5 | vector.cpp:359:37:359:41 | call to begin | TAINT |
| vector.cpp:359:37:359:41 | call to begin | vector.cpp:360:3:360:4 | i5 | |
| vector.cpp:359:37:359:41 | call to begin | vector.cpp:362:3:362:4 | i5 | |
| vector.cpp:360:2:360:2 | call to operator* [post update] | vector.cpp:361:7:361:8 | v5 | |
| vector.cpp:360:2:360:2 | call to operator* [post update] | vector.cpp:363:7:363:8 | v5 | |
| vector.cpp:360:2:360:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v5 | |
| vector.cpp:360:2:360:2 | call to operator* [post update] | vector.cpp:415:1:415:1 | v5 | |
| vector.cpp:360:2:360:15 | ... = ... | vector.cpp:360:2:360:2 | call to operator* [post update] | |
| vector.cpp:360:3:360:4 | i5 | vector.cpp:360:2:360:2 | call to operator* | TAINT |
| vector.cpp:360:8:360:13 | call to source | vector.cpp:360:2:360:2 | call to operator* [post update] | TAINT |
| vector.cpp:360:8:360:13 | call to source | vector.cpp:360:2:360:15 | ... = ... | |
| vector.cpp:361:7:361:8 | ref arg v5 | vector.cpp:363:7:363:8 | v5 | |
| vector.cpp:361:7:361:8 | ref arg v5 | vector.cpp:401:1:401:1 | v5 | |
| vector.cpp:361:7:361:8 | ref arg v5 | vector.cpp:415:1:415:1 | v5 | |
| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:363:7:363:8 | v5 | |
| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v5 | |
| vector.cpp:362:2:362:2 | call to operator* [post update] | vector.cpp:415:1:415:1 | v5 | |
| vector.cpp:362:2:362:8 | ... = ... | vector.cpp:362:2:362:2 | call to operator* [post update] | |
| vector.cpp:362:3:362:4 | i5 | vector.cpp:362:2:362:2 | call to operator* | TAINT |
| vector.cpp:362:8:362:8 | 1 | vector.cpp:362:2:362:2 | call to operator* [post update] | TAINT |
| vector.cpp:362:8:362:8 | 1 | vector.cpp:362:2:362:8 | ... = ... | |
| vector.cpp:363:7:363:8 | ref arg v5 | vector.cpp:401:1:401:1 | v5 | |
| vector.cpp:363:7:363:8 | ref arg v5 | vector.cpp:415:1:415:1 | v5 | |
| vector.cpp:365:34:365:35 | ref arg v6 | vector.cpp:367:7:367:8 | v6 | |
| vector.cpp:365:34:365:35 | ref arg v6 | vector.cpp:368:2:368:3 | v6 | |
| vector.cpp:365:34:365:35 | ref arg v6 | vector.cpp:369:7:369:8 | v6 | |
| vector.cpp:365:34:365:35 | ref arg v6 | vector.cpp:401:1:401:1 | v6 | |
| vector.cpp:365:34:365:35 | ref arg v6 | vector.cpp:415:1:415:1 | v6 | |
| vector.cpp:365:34:365:35 | v6 | vector.cpp:365:37:365:41 | call to begin | TAINT |
| vector.cpp:365:37:365:41 | call to begin | vector.cpp:366:3:366:4 | i6 | |
| vector.cpp:366:2:366:2 | call to operator* [post update] | vector.cpp:367:7:367:8 | v6 | |
| vector.cpp:366:2:366:2 | call to operator* [post update] | vector.cpp:368:2:368:3 | v6 | |
| vector.cpp:366:2:366:2 | call to operator* [post update] | vector.cpp:369:7:369:8 | v6 | |
| vector.cpp:366:2:366:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v6 | |
| vector.cpp:366:2:366:2 | call to operator* [post update] | vector.cpp:415:1:415:1 | v6 | |
| vector.cpp:366:2:366:15 | ... = ... | vector.cpp:366:2:366:2 | call to operator* [post update] | |
| vector.cpp:366:3:366:4 | i6 | vector.cpp:366:2:366:2 | call to operator* | TAINT |
| vector.cpp:366:8:366:13 | call to source | vector.cpp:366:2:366:2 | call to operator* [post update] | TAINT |
| vector.cpp:366:8:366:13 | call to source | vector.cpp:366:2:366:15 | ... = ... | |
| vector.cpp:367:7:367:8 | ref arg v6 | vector.cpp:368:2:368:3 | v6 | |
| vector.cpp:367:7:367:8 | ref arg v6 | vector.cpp:369:7:369:8 | v6 | |
| vector.cpp:367:7:367:8 | ref arg v6 | vector.cpp:401:1:401:1 | v6 | |
| vector.cpp:367:7:367:8 | ref arg v6 | vector.cpp:415:1:415:1 | v6 | |
| vector.cpp:368:2:368:3 | ref arg v6 | vector.cpp:369:7:369:8 | v6 | |
| vector.cpp:368:2:368:3 | ref arg v6 | vector.cpp:401:1:401:1 | v6 | |
| vector.cpp:368:2:368:3 | ref arg v6 | vector.cpp:415:1:415:1 | v6 | |
| vector.cpp:368:7:368:26 | call to vector | vector.cpp:368:2:368:3 | ref arg v6 | TAINT |
| vector.cpp:368:7:368:26 | call to vector | vector.cpp:368:5:368:5 | call to operator= | TAINT |
| vector.cpp:369:7:369:8 | ref arg v6 | vector.cpp:401:1:401:1 | v6 | |
| vector.cpp:369:7:369:8 | ref arg v6 | vector.cpp:415:1:415:1 | v6 | |
| vector.cpp:371:34:371:35 | ref arg v7 | vector.cpp:374:8:374:9 | v7 | |
| vector.cpp:371:34:371:35 | ref arg v7 | vector.cpp:377:8:377:9 | v7 | |
| vector.cpp:371:34:371:35 | ref arg v7 | vector.cpp:379:7:379:8 | v7 | |
| vector.cpp:371:34:371:35 | ref arg v7 | vector.cpp:401:1:401:1 | v7 | |
| vector.cpp:371:34:371:35 | ref arg v7 | vector.cpp:415:1:415:1 | v7 | |
| vector.cpp:371:34:371:35 | v7 | vector.cpp:371:37:371:41 | call to begin | TAINT |
| vector.cpp:371:37:371:41 | call to begin | vector.cpp:373:4:373:5 | i7 | |
| vector.cpp:371:37:371:41 | call to begin | vector.cpp:376:4:376:5 | i7 | |
| vector.cpp:373:3:373:3 | call to operator* [post update] | vector.cpp:374:8:374:9 | v7 | |
| vector.cpp:373:3:373:3 | call to operator* [post update] | vector.cpp:379:7:379:8 | v7 | |
| vector.cpp:373:3:373:3 | call to operator* [post update] | vector.cpp:401:1:401:1 | v7 | |
| vector.cpp:373:3:373:3 | call to operator* [post update] | vector.cpp:415:1:415:1 | v7 | |
| vector.cpp:373:3:373:16 | ... = ... | vector.cpp:373:3:373:3 | call to operator* [post update] | |
| vector.cpp:373:4:373:5 | i7 | vector.cpp:373:3:373:3 | call to operator* | TAINT |
| vector.cpp:373:9:373:14 | call to source | vector.cpp:373:3:373:3 | call to operator* [post update] | TAINT |
| vector.cpp:373:9:373:14 | call to source | vector.cpp:373:3:373:16 | ... = ... | |
| vector.cpp:374:8:374:9 | ref arg v7 | vector.cpp:379:7:379:8 | v7 | |
| vector.cpp:374:8:374:9 | ref arg v7 | vector.cpp:401:1:401:1 | v7 | |
| vector.cpp:374:8:374:9 | ref arg v7 | vector.cpp:415:1:415:1 | v7 | |
| vector.cpp:376:3:376:3 | call to operator* [post update] | vector.cpp:377:8:377:9 | v7 | |
| vector.cpp:376:3:376:3 | call to operator* [post update] | vector.cpp:379:7:379:8 | v7 | |
| vector.cpp:376:3:376:3 | call to operator* [post update] | vector.cpp:401:1:401:1 | v7 | |
| vector.cpp:376:3:376:3 | call to operator* [post update] | vector.cpp:415:1:415:1 | v7 | |
| vector.cpp:376:3:376:9 | ... = ... | vector.cpp:376:3:376:3 | call to operator* [post update] | |
| vector.cpp:376:4:376:5 | i7 | vector.cpp:376:3:376:3 | call to operator* | TAINT |
| vector.cpp:376:9:376:9 | 1 | vector.cpp:376:3:376:3 | call to operator* [post update] | TAINT |
| vector.cpp:376:9:376:9 | 1 | vector.cpp:376:3:376:9 | ... = ... | |
| vector.cpp:377:8:377:9 | ref arg v7 | vector.cpp:379:7:379:8 | v7 | |
| vector.cpp:377:8:377:9 | ref arg v7 | vector.cpp:401:1:401:1 | v7 | |
| vector.cpp:379:7:379:8 | ref arg v7 | vector.cpp:401:1:401:1 | v7 | |
| vector.cpp:377:8:377:9 | ref arg v7 | vector.cpp:415:1:415:1 | v7 | |
| vector.cpp:379:7:379:8 | ref arg v7 | vector.cpp:415:1:415:1 | v7 | |
| vector.cpp:381:34:381:35 | ref arg v8 | vector.cpp:383:7:383:8 | v8 | |
| vector.cpp:381:34:381:35 | ref arg v8 | vector.cpp:385:7:385:8 | v8 | |
| vector.cpp:381:34:381:35 | ref arg v8 | vector.cpp:401:1:401:1 | v8 | |
| vector.cpp:381:34:381:35 | ref arg v8 | vector.cpp:415:1:415:1 | v8 | |
| vector.cpp:381:34:381:35 | v8 | vector.cpp:381:37:381:41 | call to begin | TAINT |
| vector.cpp:381:37:381:41 | call to begin | vector.cpp:382:3:382:4 | i8 | |
| vector.cpp:381:37:381:41 | call to begin | vector.cpp:384:3:384:4 | i8 | |
| vector.cpp:382:2:382:2 | call to operator* [post update] | vector.cpp:383:7:383:8 | v8 | |
| vector.cpp:382:2:382:2 | call to operator* [post update] | vector.cpp:385:7:385:8 | v8 | |
| vector.cpp:382:2:382:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v8 | |
| vector.cpp:382:2:382:2 | call to operator* [post update] | vector.cpp:415:1:415:1 | v8 | |
| vector.cpp:382:2:382:15 | ... = ... | vector.cpp:382:2:382:2 | call to operator* [post update] | |
| vector.cpp:382:3:382:4 | i8 | vector.cpp:382:2:382:2 | call to operator* | TAINT |
| vector.cpp:382:8:382:13 | call to source | vector.cpp:382:2:382:2 | call to operator* [post update] | TAINT |
| vector.cpp:382:8:382:13 | call to source | vector.cpp:382:2:382:15 | ... = ... | |
| vector.cpp:383:7:383:8 | ref arg v8 | vector.cpp:385:7:385:8 | v8 | |
| vector.cpp:383:7:383:8 | ref arg v8 | vector.cpp:401:1:401:1 | v8 | |
| vector.cpp:383:7:383:8 | ref arg v8 | vector.cpp:415:1:415:1 | v8 | |
| vector.cpp:384:2:384:2 | call to operator* [post update] | vector.cpp:385:7:385:8 | v8 | |
| vector.cpp:384:2:384:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v8 | |
| vector.cpp:384:2:384:2 | call to operator* [post update] | vector.cpp:415:1:415:1 | v8 | |
| vector.cpp:384:2:384:8 | ... = ... | vector.cpp:384:2:384:2 | call to operator* [post update] | |
| vector.cpp:384:3:384:4 | i8 | vector.cpp:384:2:384:2 | call to operator* | TAINT |
| vector.cpp:384:8:384:8 | 1 | vector.cpp:384:2:384:2 | call to operator* [post update] | TAINT |
| vector.cpp:384:8:384:8 | 1 | vector.cpp:384:2:384:8 | ... = ... | |
| vector.cpp:385:7:385:8 | ref arg v8 | vector.cpp:401:1:401:1 | v8 | |
| vector.cpp:385:7:385:8 | ref arg v8 | vector.cpp:415:1:415:1 | v8 | |
| vector.cpp:387:34:387:35 | ref arg v9 | vector.cpp:392:7:392:8 | v9 | |
| vector.cpp:387:34:387:35 | ref arg v9 | vector.cpp:401:1:401:1 | v9 | |
| vector.cpp:387:34:387:35 | ref arg v9 | vector.cpp:415:1:415:1 | v9 | |
| vector.cpp:387:34:387:35 | v9 | vector.cpp:387:37:387:41 | call to begin | TAINT |
| vector.cpp:387:37:387:41 | call to begin | vector.cpp:389:3:389:4 | i9 | |
| vector.cpp:387:37:387:41 | call to begin | vector.cpp:390:31:390:32 | i9 | |
| vector.cpp:389:2:389:2 | call to operator* [post update] | vector.cpp:392:7:392:8 | v9 | |
| vector.cpp:389:2:389:2 | call to operator* [post update] | vector.cpp:401:1:401:1 | v9 | |
| vector.cpp:389:2:389:2 | call to operator* [post update] | vector.cpp:415:1:415:1 | v9 | |
| vector.cpp:389:2:389:15 | ... = ... | vector.cpp:389:2:389:2 | call to operator* [post update] | |
| vector.cpp:389:3:389:4 | i9 | vector.cpp:389:2:389:2 | call to operator* | TAINT |
| vector.cpp:389:8:389:13 | call to source | vector.cpp:389:2:389:2 | call to operator* [post update] | TAINT |
| vector.cpp:389:8:389:13 | call to source | vector.cpp:389:2:389:15 | ... = ... | |
| vector.cpp:390:31:390:32 | call to iterator [post update] | vector.cpp:392:7:392:8 | v9 | |
| vector.cpp:390:31:390:32 | call to iterator [post update] | vector.cpp:401:1:401:1 | v9 | |
| vector.cpp:390:31:390:32 | call to iterator [post update] | vector.cpp:415:1:415:1 | v9 | |
| vector.cpp:390:31:390:32 | i9 | vector.cpp:390:31:390:32 | call to iterator | |
| vector.cpp:390:31:390:32 | i9 [post update] | vector.cpp:392:7:392:8 | v9 | |
| vector.cpp:390:31:390:32 | i9 [post update] | vector.cpp:401:1:401:1 | v9 | |
| vector.cpp:392:7:392:8 | ref arg v9 | vector.cpp:401:1:401:1 | v9 | |
| vector.cpp:390:31:390:32 | i9 [post update] | vector.cpp:415:1:415:1 | v9 | |
| vector.cpp:392:7:392:8 | ref arg v9 | vector.cpp:415:1:415:1 | v9 | |
| vector.cpp:394:35:394:37 | ref arg v10 | vector.cpp:396:7:396:9 | v10 | |
| vector.cpp:394:35:394:37 | ref arg v10 | vector.cpp:401:1:401:1 | v10 | |
| vector.cpp:394:35:394:37 | ref arg v10 | vector.cpp:415:1:415:1 | v10 | |
| vector.cpp:394:35:394:37 | v10 | vector.cpp:394:39:394:43 | call to begin | TAINT |
| vector.cpp:394:39:394:43 | call to begin | vector.cpp:395:33:395:35 | i10 | |
| vector.cpp:395:33:395:35 | call to iterator [post update] | vector.cpp:396:7:396:9 | v10 | |
| vector.cpp:395:33:395:35 | call to iterator [post update] | vector.cpp:401:1:401:1 | v10 | |
| vector.cpp:395:33:395:35 | call to iterator [post update] | vector.cpp:415:1:415:1 | v10 | |
| vector.cpp:395:33:395:35 | i10 | vector.cpp:395:33:395:35 | call to iterator | |
| vector.cpp:395:33:395:35 | i10 [post update] | vector.cpp:396:7:396:9 | v10 | |
| vector.cpp:395:33:395:35 | i10 [post update] | vector.cpp:401:1:401:1 | v10 | |
| vector.cpp:396:7:396:9 | ref arg v10 | vector.cpp:401:1:401:1 | v10 | |
| vector.cpp:395:33:395:35 | i10 [post update] | vector.cpp:415:1:415:1 | v10 | |
| vector.cpp:396:7:396:9 | ref arg v10 | vector.cpp:415:1:415:1 | v10 | |
| vector.cpp:398:35:398:37 | ref arg v11 | vector.cpp:400:7:400:9 | v11 | |
| vector.cpp:398:35:398:37 | ref arg v11 | vector.cpp:401:1:401:1 | v11 | |
| vector.cpp:398:35:398:37 | ref arg v11 | vector.cpp:415:1:415:1 | v11 | |
| vector.cpp:398:35:398:37 | v11 | vector.cpp:398:39:398:43 | call to begin | TAINT |
| vector.cpp:398:39:398:43 | call to begin | vector.cpp:399:33:399:35 | i11 | |
| vector.cpp:399:33:399:35 | call to iterator [post update] | vector.cpp:400:7:400:9 | v11 | |
| vector.cpp:399:33:399:35 | call to iterator [post update] | vector.cpp:401:1:401:1 | v11 | |
| vector.cpp:399:33:399:35 | call to iterator [post update] | vector.cpp:415:1:415:1 | v11 | |
| vector.cpp:399:33:399:35 | i11 | vector.cpp:399:33:399:35 | call to iterator | |
| vector.cpp:399:33:399:35 | i11 [post update] | vector.cpp:400:7:400:9 | v11 | |
| vector.cpp:399:33:399:35 | i11 [post update] | vector.cpp:401:1:401:1 | v11 | |
| vector.cpp:400:7:400:9 | ref arg v11 | vector.cpp:401:1:401:1 | v11 | |
| vector.cpp:399:33:399:35 | i11 [post update] | vector.cpp:415:1:415:1 | v11 | |
| vector.cpp:400:7:400:9 | ref arg v11 | vector.cpp:415:1:415:1 | v11 | |
| vector.cpp:402:35:402:37 | ref arg v12 | vector.cpp:405:7:405:9 | v12 | |
| vector.cpp:402:35:402:37 | ref arg v12 | vector.cpp:415:1:415:1 | v12 | |
| vector.cpp:402:35:402:37 | v12 | vector.cpp:402:39:402:43 | call to begin | TAINT |
| vector.cpp:402:39:402:43 | call to begin | vector.cpp:403:3:403:5 | i12 | |
| vector.cpp:402:39:402:43 | call to begin | vector.cpp:404:3:404:5 | i12 | |
| vector.cpp:403:2:403:2 | call to operator* [post update] | vector.cpp:405:7:405:9 | v12 | |
| vector.cpp:403:2:403:2 | call to operator* [post update] | vector.cpp:415:1:415:1 | v12 | |
| vector.cpp:403:2:403:11 | ... = ... | vector.cpp:403:2:403:2 | call to operator* [post update] | |
| vector.cpp:403:3:403:5 | i12 | vector.cpp:403:6:403:6 | call to operator++ | |
| vector.cpp:403:3:403:5 | ref arg i12 | vector.cpp:404:3:404:5 | i12 | |
| vector.cpp:403:6:403:6 | call to operator++ | vector.cpp:403:2:403:2 | call to operator* | TAINT |
| vector.cpp:403:11:403:11 | 0 | vector.cpp:403:2:403:2 | call to operator* [post update] | TAINT |
| vector.cpp:403:11:403:11 | 0 | vector.cpp:403:2:403:11 | ... = ... | |
| vector.cpp:404:2:404:2 | call to operator* [post update] | vector.cpp:405:7:405:9 | v12 | |
| vector.cpp:404:2:404:2 | call to operator* [post update] | vector.cpp:415:1:415:1 | v12 | |
| vector.cpp:404:2:404:16 | ... = ... | vector.cpp:404:2:404:2 | call to operator* [post update] | |
| vector.cpp:404:3:404:5 | i12 | vector.cpp:404:2:404:2 | call to operator* | TAINT |
| vector.cpp:404:9:404:14 | call to source | vector.cpp:404:2:404:2 | call to operator* [post update] | TAINT |
| vector.cpp:404:9:404:14 | call to source | vector.cpp:404:2:404:16 | ... = ... | |
| vector.cpp:405:7:405:9 | ref arg v12 | vector.cpp:415:1:415:1 | v12 | |
| vector.cpp:407:35:407:37 | ref arg v13 | vector.cpp:409:7:409:9 | v13 | |
| vector.cpp:407:35:407:37 | ref arg v13 | vector.cpp:415:1:415:1 | v13 | |
| vector.cpp:407:35:407:37 | v13 | vector.cpp:407:39:407:43 | call to begin | TAINT |
| vector.cpp:407:39:407:43 | call to begin | vector.cpp:408:3:408:5 | i13 | |
| vector.cpp:408:2:408:2 | call to operator* [post update] | vector.cpp:409:7:409:9 | v13 | |
| vector.cpp:408:2:408:2 | call to operator* [post update] | vector.cpp:415:1:415:1 | v13 | |
| vector.cpp:408:2:408:18 | ... = ... | vector.cpp:408:2:408:2 | call to operator* [post update] | |
| vector.cpp:408:3:408:5 | i13 | vector.cpp:408:6:408:6 | call to operator++ | |
| vector.cpp:408:6:408:6 | call to operator++ | vector.cpp:408:2:408:2 | call to operator* | TAINT |
| vector.cpp:408:11:408:16 | call to source | vector.cpp:408:2:408:2 | call to operator* [post update] | TAINT |
| vector.cpp:408:11:408:16 | call to source | vector.cpp:408:2:408:18 | ... = ... | |
| vector.cpp:409:7:409:9 | ref arg v13 | vector.cpp:415:1:415:1 | v13 | |
| vector.cpp:411:35:411:37 | ref arg v14 | vector.cpp:414:7:414:9 | v14 | |
| vector.cpp:411:35:411:37 | ref arg v14 | vector.cpp:415:1:415:1 | v14 | |
| vector.cpp:411:35:411:37 | v14 | vector.cpp:411:39:411:43 | call to begin | TAINT |
| vector.cpp:411:39:411:43 | call to begin | vector.cpp:412:2:412:4 | i14 | |
| vector.cpp:411:39:411:43 | call to begin | vector.cpp:413:3:413:5 | i14 | |
| vector.cpp:412:2:412:4 | i14 | vector.cpp:412:5:412:5 | call to operator++ | |
| vector.cpp:412:2:412:4 | ref arg i14 | vector.cpp:413:3:413:5 | i14 | |
| vector.cpp:413:2:413:2 | call to operator* [post update] | vector.cpp:414:7:414:9 | v14 | |
| vector.cpp:413:2:413:2 | call to operator* [post update] | vector.cpp:415:1:415:1 | v14 | |
| vector.cpp:413:2:413:18 | ... = ... | vector.cpp:413:2:413:2 | call to operator* [post update] | |
| vector.cpp:413:3:413:5 | i14 | vector.cpp:413:6:413:6 | call to operator++ | |
| vector.cpp:413:6:413:6 | call to operator++ | vector.cpp:413:2:413:2 | call to operator* | TAINT |
| vector.cpp:413:11:413:16 | call to source | vector.cpp:413:2:413:2 | call to operator* [post update] | TAINT |
| vector.cpp:413:11:413:16 | call to source | vector.cpp:413:2:413:18 | ... = ... | |
| vector.cpp:414:7:414:9 | ref arg v14 | vector.cpp:415:1:415:1 | v14 | |
| vector.cpp:417:33:417:45 | source_string | vector.cpp:421:23:421:35 | source_string | |
| vector.cpp:417:33:417:45 | source_string | vector.cpp:428:23:428:35 | source_string | |
| vector.cpp:417:33:417:45 | source_string | vector.cpp:442:23:442:35 | source_string | |
| vector.cpp:419:28:419:30 | call to vector | vector.cpp:420:13:420:15 | out | |
| vector.cpp:419:28:419:30 | call to vector | vector.cpp:422:8:422:10 | out | |
| vector.cpp:419:28:419:30 | call to vector | vector.cpp:423:2:423:2 | out | |
| vector.cpp:420:13:420:15 | out | vector.cpp:420:17:420:19 | call to end | TAINT |
| vector.cpp:420:13:420:15 | ref arg out | vector.cpp:422:8:422:10 | out | |
| vector.cpp:420:13:420:15 | ref arg out | vector.cpp:423:2:423:2 | out | |
| vector.cpp:420:17:420:19 | call to end | vector.cpp:421:4:421:5 | it | |
| vector.cpp:421:3:421:3 | call to operator* [post update] | vector.cpp:422:8:422:10 | out | |
| vector.cpp:421:3:421:3 | call to operator* [post update] | vector.cpp:423:2:423:2 | out | |
| vector.cpp:421:3:421:36 | ... = ... | vector.cpp:421:3:421:3 | call to operator* [post update] | |
| vector.cpp:421:4:421:5 | it | vector.cpp:421:6:421:6 | call to operator++ | |
| vector.cpp:421:6:421:6 | call to operator++ | vector.cpp:421:3:421:3 | call to operator* | TAINT |
| vector.cpp:421:11:421:36 | call to basic_string | vector.cpp:421:3:421:3 | call to operator* [post update] | TAINT |
| vector.cpp:421:11:421:36 | call to basic_string | vector.cpp:421:3:421:36 | ... = ... | |
| vector.cpp:421:23:421:35 | source_string | vector.cpp:421:11:421:36 | call to basic_string | TAINT |
| vector.cpp:422:8:422:10 | ref arg out | vector.cpp:423:2:423:2 | out | |
| vector.cpp:426:28:426:30 | call to vector | vector.cpp:427:32:427:34 | out | |
| vector.cpp:426:28:426:30 | call to vector | vector.cpp:429:8:429:10 | out | |
| vector.cpp:426:28:426:30 | call to vector | vector.cpp:430:2:430:2 | out | |
| vector.cpp:427:13:427:30 | call to back_inserter | vector.cpp:428:4:428:5 | it | |
| vector.cpp:427:32:427:34 | ref arg out | vector.cpp:429:8:429:10 | out | |
| vector.cpp:427:32:427:34 | ref arg out | vector.cpp:430:2:430:2 | out | |
| vector.cpp:428:3:428:3 | ref arg call to operator* | vector.cpp:428:6:428:6 | ref arg call to operator++ | TAINT |
| vector.cpp:428:3:428:3 | ref arg call to operator* | vector.cpp:429:8:429:10 | out | |
| vector.cpp:428:3:428:3 | ref arg call to operator* | vector.cpp:430:2:430:2 | out | |
| vector.cpp:428:4:428:5 | it | vector.cpp:428:6:428:6 | call to operator++ | |
| vector.cpp:428:6:428:6 | call to operator++ | vector.cpp:428:3:428:3 | call to operator* | TAINT |
| vector.cpp:428:6:428:6 | ref arg call to operator++ | vector.cpp:428:4:428:5 | ref arg it | |
| vector.cpp:428:11:428:36 | call to basic_string | vector.cpp:428:3:428:3 | ref arg call to operator* | TAINT |
| vector.cpp:428:23:428:35 | source_string | vector.cpp:428:11:428:36 | call to basic_string | TAINT |
| vector.cpp:429:8:429:10 | ref arg out | vector.cpp:430:2:430:2 | out | |
| vector.cpp:433:20:433:22 | call to vector | vector.cpp:434:32:434:34 | out | |
| vector.cpp:433:20:433:22 | call to vector | vector.cpp:436:8:436:10 | out | |
| vector.cpp:433:20:433:22 | call to vector | vector.cpp:437:2:437:2 | out | |
| vector.cpp:434:13:434:30 | call to back_inserter | vector.cpp:435:4:435:5 | it | |
| vector.cpp:434:32:434:34 | ref arg out | vector.cpp:436:8:436:10 | out | |
| vector.cpp:434:32:434:34 | ref arg out | vector.cpp:437:2:437:2 | out | |
| vector.cpp:435:3:435:3 | ref arg call to operator* | vector.cpp:435:6:435:6 | ref arg call to operator++ | TAINT |
| vector.cpp:435:3:435:3 | ref arg call to operator* | vector.cpp:436:8:436:10 | out | |
| vector.cpp:435:3:435:3 | ref arg call to operator* | vector.cpp:437:2:437:2 | out | |
| vector.cpp:435:4:435:5 | it | vector.cpp:435:6:435:6 | call to operator++ | |
| vector.cpp:435:6:435:6 | call to operator++ | vector.cpp:435:3:435:3 | call to operator* | TAINT |
| vector.cpp:435:6:435:6 | ref arg call to operator++ | vector.cpp:435:4:435:5 | ref arg it | |
| vector.cpp:435:11:435:16 | call to source | vector.cpp:435:3:435:3 | ref arg call to operator* | TAINT |
| vector.cpp:436:8:436:10 | ref arg out | vector.cpp:437:2:437:2 | out | |
| vector.cpp:440:28:440:30 | call to vector | vector.cpp:441:32:441:34 | out | |
| vector.cpp:440:28:440:30 | call to vector | vector.cpp:443:8:443:10 | out | |
| vector.cpp:440:28:440:30 | call to vector | vector.cpp:444:2:444:2 | out | |
| vector.cpp:441:13:441:30 | call to back_inserter | vector.cpp:442:6:442:7 | it | |
| vector.cpp:441:32:441:34 | ref arg out | vector.cpp:443:8:443:10 | out | |
| vector.cpp:441:32:441:34 | ref arg out | vector.cpp:444:2:444:2 | out | |
| vector.cpp:442:3:442:3 | ref arg call to operator* | vector.cpp:442:4:442:4 | ref arg call to operator++ | TAINT |
| vector.cpp:442:3:442:3 | ref arg call to operator* | vector.cpp:443:8:443:10 | out | |
| vector.cpp:442:3:442:3 | ref arg call to operator* | vector.cpp:444:2:444:2 | out | |
| vector.cpp:442:4:442:4 | call to operator++ | vector.cpp:442:3:442:3 | call to operator* | TAINT |
| vector.cpp:442:4:442:4 | ref arg call to operator++ | vector.cpp:442:6:442:7 | ref arg it | |
| vector.cpp:442:6:442:7 | it | vector.cpp:442:4:442:4 | call to operator++ | |
| vector.cpp:442:11:442:36 | call to basic_string | vector.cpp:442:3:442:3 | ref arg call to operator* | TAINT |
| vector.cpp:442:23:442:35 | source_string | vector.cpp:442:11:442:36 | call to basic_string | TAINT |
| vector.cpp:443:8:443:10 | ref arg out | vector.cpp:444:2:444:2 | out | |
| vector.cpp:447:20:447:22 | call to vector | vector.cpp:448:32:448:34 | out | |
| vector.cpp:447:20:447:22 | call to vector | vector.cpp:450:8:450:10 | out | |
| vector.cpp:447:20:447:22 | call to vector | vector.cpp:451:2:451:2 | out | |
| vector.cpp:448:13:448:30 | call to back_inserter | vector.cpp:449:6:449:7 | it | |
| vector.cpp:448:32:448:34 | ref arg out | vector.cpp:450:8:450:10 | out | |
| vector.cpp:448:32:448:34 | ref arg out | vector.cpp:451:2:451:2 | out | |
| vector.cpp:449:3:449:3 | ref arg call to operator* | vector.cpp:449:4:449:4 | ref arg call to operator++ | TAINT |
| vector.cpp:449:3:449:3 | ref arg call to operator* | vector.cpp:450:8:450:10 | out | |
| vector.cpp:449:3:449:3 | ref arg call to operator* | vector.cpp:451:2:451:2 | out | |
| vector.cpp:449:4:449:4 | call to operator++ | vector.cpp:449:3:449:3 | call to operator* | TAINT |
| vector.cpp:449:4:449:4 | ref arg call to operator++ | vector.cpp:449:6:449:7 | ref arg it | |
| vector.cpp:449:6:449:7 | it | vector.cpp:449:4:449:4 | call to operator++ | |
| vector.cpp:449:11:449:16 | call to source | vector.cpp:449:3:449:3 | ref arg call to operator* | TAINT |
| vector.cpp:450:8:450:10 | ref arg out | vector.cpp:451:2:451:2 | out | |
| vector.cpp:467:22:467:25 | call to vector | vector.cpp:471:8:471:8 | v | |
| vector.cpp:467:22:467:25 | call to vector | vector.cpp:472:11:472:11 | v | |
| vector.cpp:467:22:467:25 | call to vector | vector.cpp:473:8:473:8 | v | |
| vector.cpp:467:22:467:25 | call to vector | vector.cpp:474:2:474:2 | v | |
| vector.cpp:468:11:468:16 | call to source | vector.cpp:472:18:472:18 | s | |
| vector.cpp:469:10:469:11 | 0 | vector.cpp:472:13:472:13 | i | |
| vector.cpp:471:8:471:8 | ref arg v | vector.cpp:472:11:472:11 | v | |
| vector.cpp:471:8:471:8 | ref arg v | vector.cpp:473:8:473:8 | v | |
| vector.cpp:471:8:471:8 | ref arg v | vector.cpp:474:2:474:2 | v | |
| vector.cpp:472:10:472:14 | & ... | vector.cpp:472:3:472:8 | call to memcpy | |
| vector.cpp:472:10:472:14 | ref arg & ... | vector.cpp:472:12:472:12 | call to operator[] [inner post update] | |
| vector.cpp:472:11:472:11 | ref arg v | vector.cpp:473:8:473:8 | v | |
| vector.cpp:472:11:472:11 | ref arg v | vector.cpp:474:2:474:2 | v | |
| vector.cpp:472:11:472:11 | v | vector.cpp:472:12:472:12 | call to operator[] | TAINT |
| vector.cpp:472:12:472:12 | call to operator[] | vector.cpp:472:10:472:14 | & ... | |
| vector.cpp:472:12:472:12 | call to operator[] [inner post update] | vector.cpp:472:11:472:11 | ref arg v | TAINT |
| vector.cpp:472:17:472:18 | & ... | vector.cpp:472:3:472:8 | call to memcpy | TAINT |
| vector.cpp:472:17:472:18 | & ... | vector.cpp:472:10:472:14 | ref arg & ... | TAINT |
| vector.cpp:472:18:472:18 | s | vector.cpp:472:10:472:14 | ref arg & ... | |
| vector.cpp:472:18:472:18 | s | vector.cpp:472:17:472:18 | & ... | |
| vector.cpp:473:8:473:8 | ref arg v | vector.cpp:474:2:474:2 | v | |
| vector.cpp:477:24:477:27 | call to vector | vector.cpp:483:8:483:9 | cs | |
| vector.cpp:477:24:477:27 | call to vector | vector.cpp:484:11:484:12 | cs | |
| vector.cpp:477:24:477:27 | call to vector | vector.cpp:486:8:486:9 | cs | |
| vector.cpp:477:24:477:27 | call to vector | vector.cpp:487:2:487:2 | cs | |
| vector.cpp:478:21:478:37 | call to source | vector.cpp:480:22:480:24 | src | |
| vector.cpp:478:21:478:37 | call to source | vector.cpp:482:8:482:10 | src | |
| vector.cpp:478:21:478:37 | call to source | vector.cpp:484:25:484:27 | src | |
| vector.cpp:478:21:478:37 | call to source | vector.cpp:485:8:485:10 | src | |
| vector.cpp:479:23:479:24 | 10 | vector.cpp:484:14:484:17 | offs | |
| vector.cpp:480:26:480:31 | call to length | vector.cpp:484:38:484:40 | len | |
| vector.cpp:482:8:482:10 | ref arg src | vector.cpp:484:25:484:27 | src | |
| vector.cpp:482:8:482:10 | ref arg src | vector.cpp:485:8:485:10 | src | |
| vector.cpp:483:8:483:9 | ref arg cs | vector.cpp:484:11:484:12 | cs | |
| vector.cpp:483:8:483:9 | ref arg cs | vector.cpp:486:8:486:9 | cs | |
| vector.cpp:483:8:483:9 | ref arg cs | vector.cpp:487:2:487:2 | cs | |
| vector.cpp:484:10:484:22 | & ... | vector.cpp:484:3:484:8 | call to memcpy | |
| vector.cpp:484:10:484:22 | ref arg & ... | vector.cpp:484:13:484:13 | call to operator[] [inner post update] | |
| vector.cpp:484:11:484:12 | cs | vector.cpp:484:13:484:13 | call to operator[] | TAINT |
| vector.cpp:484:11:484:12 | ref arg cs | vector.cpp:486:8:486:9 | cs | |
| vector.cpp:484:11:484:12 | ref arg cs | vector.cpp:487:2:487:2 | cs | |
| vector.cpp:484:13:484:13 | call to operator[] | vector.cpp:484:10:484:22 | & ... | |
| vector.cpp:484:13:484:13 | call to operator[] [inner post update] | vector.cpp:484:11:484:12 | ref arg cs | TAINT |
| vector.cpp:484:14:484:17 | offs | vector.cpp:484:14:484:21 | ... + ... | TAINT |
| vector.cpp:484:21:484:21 | 1 | vector.cpp:484:14:484:21 | ... + ... | TAINT |
| vector.cpp:484:25:484:27 | src | vector.cpp:484:29:484:33 | call to c_str | TAINT |
| vector.cpp:484:29:484:33 | call to c_str | vector.cpp:484:3:484:8 | call to memcpy | TAINT |
| vector.cpp:484:29:484:33 | call to c_str | vector.cpp:484:10:484:22 | ref arg & ... | TAINT |
| vector.cpp:486:8:486:9 | ref arg cs | vector.cpp:487:2:487:2 | cs | |

View File

@@ -53,3 +53,40 @@ void test_non_iterator(non_iterator source1) {
sink(*(source1++));
sink(*(++source1));
}
int source();
class insert_iterator_by_trait {
public:
insert_iterator_by_trait &operator++();
insert_iterator_by_trait operator++(int);
insert_iterator_by_trait &operator--();
insert_iterator_by_trait operator--(int);
insert_iterator_by_trait operator*();
insert_iterator_by_trait operator=(int x);
};
template<>
struct std::iterator_traits<insert_iterator_by_trait> {
typedef output_iterator_tag iterator_category;
};
class container {
public:
container();
insert_iterator_by_trait begin();
};
void sink(container);
void test_insert_iterator() {
container c1, c2;
insert_iterator_by_trait i1 = c1.begin();
*i1-- = source();
sink(c1);
insert_iterator_by_trait i2 = c2.begin();
*i2-- = 0;
sink(c2);
}

View File

@@ -68,6 +68,57 @@ namespace std {
struct forward_iterator_tag : public input_iterator_tag {};
struct bidirectional_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirectional_iterator_tag {};
struct output_iterator_tag {};
template<class Container>
class back_insert_iterator {
protected:
Container* container = nullptr;
public:
using iterator_category = output_iterator_tag;
using value_type = void;
using difference_type = ptrdiff_t;
using pointer = void;
using reference = void;
using container_type = Container;
constexpr back_insert_iterator() noexcept = default;
constexpr explicit back_insert_iterator(Container& x);
back_insert_iterator& operator=(const typename Container::value_type& value);
back_insert_iterator& operator=(typename Container::value_type&& value);
back_insert_iterator& operator*();
back_insert_iterator& operator++();
back_insert_iterator operator++(int);
};
template<class Container>
constexpr back_insert_iterator<Container> back_inserter(Container& x) {
return back_insert_iterator<Container>(x);
}
template<class Container>
class front_insert_iterator {
protected:
Container* container = nullptr;
public:
using iterator_category = output_iterator_tag;
using value_type = void;
using difference_type = ptrdiff_t;
using pointer = void;
using reference = void;
using container_type = Container;
constexpr front_insert_iterator() noexcept = default;
constexpr explicit front_insert_iterator(Container& x);
constexpr front_insert_iterator& operator=(const typename Container::value_type& value);
constexpr front_insert_iterator& operator=(typename Container::value_type&& value);
constexpr front_insert_iterator& operator*();
constexpr front_insert_iterator& operator++();
constexpr front_insert_iterator operator++(int);
};
template<class Container>
constexpr front_insert_iterator<Container> front_inserter(Container& x) {
return front_insert_iterator<Container>(x);
}
}
// --- string ---

View File

@@ -192,7 +192,7 @@ void *memcpy(void *dest, void *src, int len);
void test_memcpy(int *source) {
int x;
memcpy(&x, source, sizeof(int));
sink(x);
sink(x); // tainted
}
// --- std::swap ---

View File

@@ -258,6 +258,7 @@
| standalone_iterators.cpp:46:10:46:10 | call to operator* | standalone_iterators.cpp:45:39:45:45 | source1 |
| standalone_iterators.cpp:47:10:47:10 | call to operator* | standalone_iterators.cpp:45:39:45:45 | source1 |
| standalone_iterators.cpp:48:10:48:10 | call to operator* | standalone_iterators.cpp:45:39:45:45 | source1 |
| standalone_iterators.cpp:87:10:87:11 | c1 | standalone_iterators.cpp:86:13:86:18 | call to source |
| string.cpp:29:7:29:7 | a | string.cpp:25:12:25:17 | call to source |
| string.cpp:31:7:31:7 | c | string.cpp:27:16:27:21 | call to source |
| string.cpp:33:9:33:13 | call to c_str | string.cpp:27:16:27:21 | call to source |
@@ -653,3 +654,15 @@
| vector.cpp:392:7:392:8 | v9 | vector.cpp:330:10:330:15 | call to source |
| vector.cpp:392:7:392:8 | v9 | vector.cpp:389:8:389:13 | call to source |
| vector.cpp:400:7:400:9 | v11 | vector.cpp:399:38:399:43 | call to source |
| vector.cpp:405:7:405:9 | v12 | vector.cpp:404:9:404:14 | call to source |
| vector.cpp:409:7:409:9 | v13 | vector.cpp:408:11:408:16 | call to source |
| vector.cpp:414:7:414:9 | v14 | vector.cpp:413:11:413:16 | call to source |
| vector.cpp:422:8:422:10 | out | vector.cpp:417:33:417:45 | source_string |
| vector.cpp:429:8:429:10 | out | vector.cpp:417:33:417:45 | source_string |
| vector.cpp:436:8:436:10 | out | vector.cpp:435:11:435:16 | call to source |
| vector.cpp:443:8:443:10 | out | vector.cpp:417:33:417:45 | source_string |
| vector.cpp:450:8:450:10 | out | vector.cpp:449:11:449:16 | call to source |
| vector.cpp:473:8:473:8 | v | vector.cpp:468:11:468:16 | call to source |
| vector.cpp:482:8:482:10 | src | vector.cpp:478:21:478:37 | call to source |
| vector.cpp:485:8:485:10 | src | vector.cpp:478:21:478:37 | call to source |
| vector.cpp:486:8:486:9 | cs | vector.cpp:478:21:478:37 | call to source |

View File

@@ -204,6 +204,7 @@
| standalone_iterators.cpp:42:10:42:10 | standalone_iterators.cpp:39:45:39:51 | AST only |
| standalone_iterators.cpp:47:10:47:10 | standalone_iterators.cpp:45:39:45:45 | AST only |
| standalone_iterators.cpp:48:10:48:10 | standalone_iterators.cpp:45:39:45:45 | AST only |
| standalone_iterators.cpp:87:10:87:11 | standalone_iterators.cpp:86:13:86:18 | AST only |
| string.cpp:33:9:33:13 | string.cpp:27:16:27:21 | AST only |
| string.cpp:39:13:39:17 | string.cpp:14:10:14:15 | AST only |
| string.cpp:43:13:43:17 | string.cpp:14:10:14:15 | AST only |
@@ -379,3 +380,13 @@
| vector.cpp:392:7:392:8 | vector.cpp:330:10:330:15 | AST only |
| vector.cpp:392:7:392:8 | vector.cpp:389:8:389:13 | AST only |
| vector.cpp:400:7:400:9 | vector.cpp:399:38:399:43 | AST only |
| vector.cpp:405:7:405:9 | vector.cpp:404:9:404:14 | AST only |
| vector.cpp:409:7:409:9 | vector.cpp:408:11:408:16 | AST only |
| vector.cpp:414:7:414:9 | vector.cpp:413:11:413:16 | AST only |
| vector.cpp:422:8:422:10 | vector.cpp:417:33:417:45 | AST only |
| vector.cpp:429:8:429:10 | vector.cpp:417:33:417:45 | AST only |
| vector.cpp:436:8:436:10 | vector.cpp:435:11:435:16 | AST only |
| vector.cpp:443:8:443:10 | vector.cpp:417:33:417:45 | AST only |
| vector.cpp:450:8:450:10 | vector.cpp:449:11:449:16 | AST only |
| vector.cpp:473:8:473:8 | vector.cpp:468:11:468:16 | AST only |
| vector.cpp:486:8:486:9 | vector.cpp:478:21:478:37 | AST only |

View File

@@ -416,3 +416,5 @@
| vector.cpp:312:7:312:7 | Argument 0 indirection | vector.cpp:303:14:303:19 | call to source |
| vector.cpp:324:7:324:8 | Argument 0 indirection | vector.cpp:318:15:318:20 | call to source |
| vector.cpp:326:7:326:8 | Argument 0 indirection | vector.cpp:318:15:318:20 | call to source |
| vector.cpp:482:8:482:10 | Argument 0 indirection | vector.cpp:478:21:478:37 | call to source |
| vector.cpp:485:8:485:10 | Argument 0 indirection | vector.cpp:478:21:478:37 | call to source |

View File

@@ -11,7 +11,7 @@ namespace ns_int
}
void sink(int);
void sink(std::vector<int> &);
template<typename T> void sink(std::vector<T> &);
void test_range_based_for_loop_vector(int source1) {
std::vector<int> v(100, source1);
@@ -335,7 +335,7 @@ void vector_iterator_assign_wrapper(std::vector<int>::iterator iter, int i) {
}
void test_vector_output_iterator(int b) {
std::vector<int> v1(10), v2(10), v3(10), v4(10), v5(10), v6(10), v7(10), v8(10), v9(10), v10(10), v11(10);
std::vector<int> v1(10), v2(10), v3(10), v4(10), v5(10), v6(10), v7(10), v8(10), v9(10), v10(10), v11(10), v12(10), v13(10), v14(10);
std::vector<int>::iterator i1 = v1.begin();
*i1 = source();
@@ -398,4 +398,91 @@ void test_vector_output_iterator(int b) {
std::vector<int>::iterator i11 = v11.begin();
vector_iterator_assign_wrapper(i11, source());
sink(v11); // tainted [NOT DETECTED by IR]
std::vector<int>::iterator i12 = v12.begin();
*i12++ = 0;
*i12 = source();
sink(v12); // tainted [NOT DETECTED by IR]
std::vector<int>::iterator i13 = v13.begin();
*i13++ = source();
sink(v13); // tainted [NOT DETECTED by IR]
std::vector<int>::iterator i14 = v14.begin();
i14++;
*i14++ = source();
sink(v14); // tainted [NOT DETECTED by IR]
}
void test_vector_inserter(char *source_string) {
{
std::vector<std::string> out;
auto it = out.end();
*it++ = std::string(source_string);
sink(out); // tainted [NOT DETECTED by IR]
}
{
std::vector<std::string> out;
auto it = std::back_inserter(out);
*it++ = std::string(source_string);
sink(out); // tainted [NOT DETECTED by IR]
}
{
std::vector<int> out;
auto it = std::back_inserter(out);
*it++ = source();
sink(out); // tainted [NOT DETECTED by IR]
}
{
std::vector<std::string> out;
auto it = std::back_inserter(out);
*++it = std::string(source_string);
sink(out); // tainted [NOT DETECTED by IR]
}
{
std::vector<int> out;
auto it = std::back_inserter(out);
*++it = source();
sink(out); // tainted [NOT DETECTED by IR]
}
}
void *memcpy(void *s1, const void *s2, size_t n);
namespace ns_string
{
std::string source();
}
void sink(std::vector<char> &);
void sink(std::string &);
void test_vector_memcpy()
{
{
std::vector<int> v(100);
int s = source();
int i = 0;
sink(v);
memcpy(&v[i], &s, sizeof(int));
sink(v); // tainted [NOT DETECTED by IR]
}
{
std::vector<char> cs(100);
std::string src = ns_string::source();
const size_t offs = 10;
const size_t len = src.length();
sink(src); // tainted
sink(cs);
memcpy(&cs[offs + 1], src.c_str(), len);
sink(src); // tainted
sink(cs); // tainted [NOT DETECTED by IR]
}
}

View File

@@ -40,7 +40,9 @@ string issues(Link e) {
filepath1 = filepath2 and
not end1 < begin2 and
not begin1 > end2 and
e != e2
e != e2 and
not e.isFromTemplateInstantiation(_) and
not e2.isFromTemplateInstantiation(_)
) and
result = "overlaps another link"
}

View File

@@ -258,8 +258,11 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
getAMember().(Virtualizable).getOverridee() = v
}
/** Gets a field (or member constant) with the given name. */
Field getField(string name) { result = getAMember() and result.hasName(name) }
/** Gets a field (or member constant) of this type, if any. */
Field getAField() { result = getAMember() }
Field getAField() { result = this.getField(_) }
/** Gets a member constant of this type, if any. */
MemberConstant getAConstant() { result = getAMember() }

View File

@@ -310,6 +310,22 @@ module ControlFlow {
Split getASplit() { result = splits.getASplit() }
}
/** A control-flow node for an expression. */
class ExprNode extends ElementNode {
Expr e;
ExprNode() { e = unique(Expr e_ | e_ = this.getElement() | e_) }
/** Gets the expression that this control-flow node belongs to. */
Expr getExpr() { result = e }
/** Gets the value of this expression node, if any. */
string getValue() { result = e.getValue() }
/** Gets the type of this expression node. */
Type getType() { result = e.getType() }
}
class Split = SplitImpl;
class FinallySplit = FinallySplitting::FinallySplitImpl;

View File

@@ -1653,6 +1653,67 @@ class SystemCollectionsGenericKeyValuePairStructFlow extends LibraryTypeDataFlow
}
}
/** Data flow for `System.[Value]Tuple<,...,>`. */
class SystemTupleFlow extends LibraryTypeDataFlow, ValueOrRefType {
SystemTupleFlow() {
this.getNamespace() instanceof SystemNamespace and
this.getName().regexpMatch("(Value)?Tuple(<,*>)?")
or
this instanceof TupleType
}
private AccessPath getItemAccessPath(int i) {
result =
unique(AccessPath ap |
i in [1 .. count(this.getAMember())] and
ap in [AccessPath::field(this.getField("Item" + i)),
AccessPath::property(this.getProperty("Item" + i))]
|
ap
)
}
override predicate callableFlow(
CallableFlowSource source, AccessPath sourceAp, CallableFlowSink sink, AccessPath sinkAp,
SourceDeclarationCallable c, boolean preservesValue
) {
preservesValue = true and
(
exists(SystemTupleFlow t, int i |
source = getFlowSourceArg(c, i - 1, _) and
sourceAp = AccessPath::empty() and
sink = TCallableFlowSinkReturn() and
sinkAp = t.getItemAccessPath(i)
|
c.(Constructor).getDeclaringType() = this and
t = this
or
c = this.getAMethod(any(string name | name.regexpMatch("Create(<,*>)?"))) and
t = c.getReturnType().getSourceDeclaration()
)
or
c =
any(ExtensionMethod m |
m.hasName("Deconstruct") and
this = m.getExtendedType().getSourceDeclaration() and
exists(int i |
m.getParameter(i).isOut() and
source = getFlowSourceArg(c, 0, _) and
sourceAp = this.getItemAccessPath(i) and
sink = TCallableFlowSinkArg(i) and
sinkAp = AccessPath::empty()
)
)
or
c = this.getAnIndexer().getGetter() and
source = TCallableFlowSourceQualifier() and
sourceAp = this.getItemAccessPath(_) and
sink = TCallableFlowSinkReturn() and
sinkAp = AccessPath::empty()
)
}
}
/** Data flow for `System.Threading.Tasks.Task`. */
class SystemThreadingTasksTaskFlow extends LibraryTypeDataFlow, SystemThreadingTasksTaskClass {
override predicate callableFlow(

View File

@@ -111,18 +111,6 @@ private predicate evenlyDivisibleExpr(Expr e, int factor) {
)
}
/**
* Holds if `inp` is an input to `phi` along `edge` and this input has index `r`
* in an arbitrary 1-based numbering of the input edges to `phi`.
*/
private predicate rankedPhiInput(
SsaPhiNode phi, SsaVariable inp, SsaReadPositionPhiInputEdge edge, int r
) {
edge.phiInput(phi, inp) and
edge =
rank[r](SsaReadPositionPhiInputEdge e | e.phiInput(phi, _) | e order by getId(e.getOrigBlock()))
}
/**
* Holds if `rix` is the number of input edges to `phi`.
*/

View File

@@ -6,4 +6,41 @@
* three-valued domain `{negative, zero, positive}`.
*/
import semmle.code.csharp.dataflow.internal.rangeanalysis.SignAnalysisCommon
import csharp
private import semmle.code.csharp.dataflow.internal.rangeanalysis.SignAnalysisCommon as Common
/** Holds if `e` can be positive and cannot be negative. */
predicate positiveExpr(Expr e) {
forex(ControlFlow::Node cfn | cfn = e.getAControlFlowNode() |
positive(cfn) or strictlyPositive(cfn)
)
}
/** Holds if `e` can be negative and cannot be positive. */
predicate negativeExpr(Expr e) {
forex(ControlFlow::Node cfn | cfn = e.getAControlFlowNode() |
negative(cfn) or strictlyNegative(cfn)
)
}
/** Holds if `e` is strictly positive. */
predicate strictlyPositiveExpr(Expr e) {
forex(ControlFlow::Node cfn | cfn = e.getAControlFlowNode() | strictlyPositive(cfn))
}
/** Holds if `e` is strictly negative. */
predicate strictlyNegativeExpr(Expr e) {
forex(ControlFlow::Node cfn | cfn = e.getAControlFlowNode() | strictlyNegative(cfn))
}
/** Holds if `e` can be positive and cannot be negative. */
predicate positive(ControlFlow::Nodes::ExprNode e) { Common::positive(e) }
/** Holds if `e` can be negative and cannot be positive. */
predicate negative(ControlFlow::Nodes::ExprNode e) { Common::negative(e) }
/** Holds if `e` is strictly positive. */
predicate strictlyPositive(ControlFlow::Nodes::ExprNode e) { Common::strictlyPositive(e) }
/** Holds if `e` is strictly negative. */
predicate strictlyNegative(ControlFlow::Nodes::ExprNode e) { Common::strictlyNegative(e) }

View File

@@ -1,6 +1,4 @@
import csharp
private import DataFlowPrivate
private import DataFlowPublic
private class ControlFlowScope extends ControlFlowElement {
private boolean exactScope;
@@ -89,21 +87,21 @@ abstract class ControlFlowReachabilityConfiguration extends string {
pragma[nomagic]
private predicate reachesBasicBlockExprBase(
Expr e1, Expr e2, ControlFlowElement scope, boolean exactScope, boolean isSuccessor,
ControlFlow::Nodes::ElementNode cfn1, int i, ControlFlow::BasicBlock bb
Expr e1, Expr e2, boolean isSuccessor, ControlFlow::Nodes::ElementNode cfn1, int i,
ControlFlow::BasicBlock bb
) {
this.candidate(e1, e2, scope, exactScope, isSuccessor) and
this.candidate(e1, e2, _, _, isSuccessor) and
cfn1 = e1.getAControlFlowNode() and
bb.getNode(i) = cfn1
}
pragma[nomagic]
private predicate reachesBasicBlockExprRec(
Expr e1, Expr e2, ControlFlowElement scope, boolean exactScope, boolean isSuccessor,
ControlFlow::Nodes::ElementNode cfn1, ControlFlow::BasicBlock bb
Expr e1, Expr e2, boolean isSuccessor, ControlFlow::Nodes::ElementNode cfn1,
ControlFlow::BasicBlock bb
) {
exists(ControlFlow::BasicBlock mid |
this.reachesBasicBlockExpr(e1, e2, scope, exactScope, isSuccessor, cfn1, mid)
this.reachesBasicBlockExpr(e1, e2, isSuccessor, cfn1, mid)
|
isSuccessor = true and
bb = mid.getASuccessor()
@@ -115,36 +113,35 @@ abstract class ControlFlowReachabilityConfiguration extends string {
pragma[nomagic]
private predicate reachesBasicBlockExpr(
Expr e1, Expr e2, ControlFlowElement scope, boolean exactScope, boolean isSuccessor,
ControlFlow::Nodes::ElementNode cfn1, ControlFlow::BasicBlock bb
Expr e1, Expr e2, boolean isSuccessor, ControlFlow::Nodes::ElementNode cfn1,
ControlFlow::BasicBlock bb
) {
this.reachesBasicBlockExprBase(e1, e2, scope, exactScope, isSuccessor, cfn1, _, bb)
this.reachesBasicBlockExprBase(e1, e2, isSuccessor, cfn1, _, bb)
or
this.candidate(e1, e2, scope, exactScope, isSuccessor) and
exists(ControlFlowElement scope0, boolean exactScope0 |
this.reachesBasicBlockExprRec(e1, e2, scope0, exactScope0, isSuccessor, cfn1, bb)
|
bb = getABasicBlockInScope(scope0, exactScope0)
exists(ControlFlowElement scope, boolean exactScope |
this.candidate(e1, e2, scope, exactScope, isSuccessor) and
this.reachesBasicBlockExprRec(e1, e2, isSuccessor, cfn1, bb) and
bb = getABasicBlockInScope(scope, exactScope)
)
}
pragma[nomagic]
private predicate reachesBasicBlockDefinitionBase(
Expr e, AssignableDefinition def, ControlFlowElement scope, boolean exactScope,
boolean isSuccessor, ControlFlow::Nodes::ElementNode cfn, int i, ControlFlow::BasicBlock bb
Expr e, AssignableDefinition def, boolean isSuccessor, ControlFlow::Nodes::ElementNode cfn,
int i, ControlFlow::BasicBlock bb
) {
this.candidateDef(e, def, scope, exactScope, isSuccessor) and
this.candidateDef(e, def, _, _, isSuccessor) and
cfn = e.getAControlFlowNode() and
bb.getNode(i) = cfn
}
pragma[nomagic]
private predicate reachesBasicBlockDefinitionRec(
Expr e, AssignableDefinition def, ControlFlowElement scope, boolean exactScope,
boolean isSuccessor, ControlFlow::Nodes::ElementNode cfn, ControlFlow::BasicBlock bb
Expr e, AssignableDefinition def, boolean isSuccessor, ControlFlow::Nodes::ElementNode cfn,
ControlFlow::BasicBlock bb
) {
exists(ControlFlow::BasicBlock mid |
this.reachesBasicBlockDefinition(e, def, scope, exactScope, isSuccessor, cfn, mid)
this.reachesBasicBlockDefinition(e, def, isSuccessor, cfn, mid)
|
isSuccessor = true and
bb = mid.getASuccessor()
@@ -156,16 +153,15 @@ abstract class ControlFlowReachabilityConfiguration extends string {
pragma[nomagic]
private predicate reachesBasicBlockDefinition(
Expr e, AssignableDefinition def, ControlFlowElement scope, boolean exactScope,
boolean isSuccessor, ControlFlow::Nodes::ElementNode cfn, ControlFlow::BasicBlock bb
Expr e, AssignableDefinition def, boolean isSuccessor, ControlFlow::Nodes::ElementNode cfn,
ControlFlow::BasicBlock bb
) {
this.reachesBasicBlockDefinitionBase(e, def, scope, exactScope, isSuccessor, cfn, _, bb)
this.reachesBasicBlockDefinitionBase(e, def, isSuccessor, cfn, _, bb)
or
this.candidateDef(e, def, scope, exactScope, isSuccessor) and
exists(ControlFlowElement scope0, boolean exactScope0 |
this.reachesBasicBlockDefinitionRec(e, def, scope0, exactScope0, isSuccessor, cfn, bb)
|
bb = getABasicBlockInScope(scope0, exactScope0)
exists(ControlFlowElement scope, boolean exactScope |
this.candidateDef(e, def, scope, exactScope, isSuccessor) and
this.reachesBasicBlockDefinitionRec(e, def, isSuccessor, cfn, bb) and
bb = getABasicBlockInScope(scope, exactScope)
)
}
@@ -176,7 +172,7 @@ abstract class ControlFlowReachabilityConfiguration extends string {
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
this.reachesBasicBlockExprBase(e1, e2, isSuccessor, cfn1, i, bb) and
cfn2 = bb.getNode(j) and
cfn2 = e2.getAControlFlowNode()
|
@@ -186,7 +182,7 @@ abstract class ControlFlowReachabilityConfiguration extends string {
)
or
exists(ControlFlow::BasicBlock bb |
this.reachesBasicBlockExprRec(e1, e2, _, _, _, cfn1, bb) and
this.reachesBasicBlockExprRec(e1, e2, _, cfn1, bb) and
cfn2 = bb.getANode() and
cfn2 = e2.getAControlFlowNode()
)
@@ -201,7 +197,7 @@ abstract class ControlFlowReachabilityConfiguration extends string {
Expr e, ControlFlow::Node cfn, AssignableDefinition def, ControlFlow::Node cfnDef
) {
exists(ControlFlow::BasicBlock bb, boolean isSuccessor, int i, int j |
this.reachesBasicBlockDefinitionBase(e, def, _, _, isSuccessor, cfn, i, bb) and
this.reachesBasicBlockDefinitionBase(e, def, isSuccessor, cfn, i, bb) and
cfnDef = bb.getNode(j) and
def.getAControlFlowNode() = cfnDef
|
@@ -211,35 +207,9 @@ abstract class ControlFlowReachabilityConfiguration extends string {
)
or
exists(ControlFlow::BasicBlock bb |
this.reachesBasicBlockDefinitionRec(e, def, _, _, _, cfn, bb) and
this.reachesBasicBlockDefinitionRec(e, def, _, cfn, bb) and
def.getAControlFlowNode() = cfnDef and
cfnDef = bb.getANode()
)
}
/**
* 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)
|
cfn1 = n1.getControlFlowNode() and
cfn2 = n2.(ExprNode).getControlFlowNode()
)
or
exists(
Expr e, ControlFlow::Node cfn, AssignableDefinition def, ControlFlow::Node cfnDef,
Ssa::ExplicitDefinition ssaDef
|
this.hasDefPath(e, cfn, def, cfnDef)
|
cfn = n1.getControlFlowNode() and
ssaDef.getADefinition() = def and
ssaDef.getControlFlowNode() = cfnDef and
n2.(SsaDefinitionNode).getDefinition() = ssaDef
)
}
}

View File

@@ -122,6 +122,32 @@ private module ThisFlow {
}
}
/**
* 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(ControlFlowReachabilityConfiguration conf, ExprNode n1, Node n2) {
exists(Expr e1, ControlFlow::Node cfn1, Expr e2, ControlFlow::Node cfn2 |
conf.hasExprPath(e1, cfn1, e2, cfn2)
|
cfn1 = n1.getControlFlowNode() and
cfn2 = n2.(ExprNode).getControlFlowNode()
)
or
exists(
Expr e, ControlFlow::Node cfn, AssignableDefinition def, ControlFlow::Node cfnDef,
Ssa::ExplicitDefinition ssaDef
|
conf.hasDefPath(e, cfn, def, cfnDef)
|
cfn = n1.getControlFlowNode() and
ssaDef.getADefinition() = def and
ssaDef.getControlFlowNode() = cfnDef and
n2.(SsaDefinitionNode).getDefinition() = ssaDef
)
}
/** Provides predicates related to local data flow. */
module LocalFlow {
private class LocalExprStepConfiguration extends ControlFlowReachabilityConfiguration {
@@ -307,7 +333,7 @@ module LocalFlow {
not usesInstanceField(def)
)
or
any(LocalExprStepConfiguration x).hasNodePath(nodeFrom, nodeTo)
hasNodePath(any(LocalExprStepConfiguration x), nodeFrom, nodeTo)
or
ThisFlow::adjacentThisRefs(nodeFrom, nodeTo)
or
@@ -669,7 +695,7 @@ private module Cached {
cached
predicate storeStepImpl(Node node1, Content c, Node node2) {
exists(StoreStepConfiguration x, ExprNode node, boolean postUpdate |
x.hasNodePath(node1, node) and
hasNodePath(x, node1, node) and
if postUpdate = true then node = node2.(PostUpdateNode).getPreUpdateNode() else node = node2
|
fieldOrPropertyStore(_, c, node1.asExpr(), node.getExpr(), postUpdate)
@@ -704,10 +730,10 @@ private module Cached {
cached
predicate readStepImpl(Node node1, Content c, Node node2) {
exists(ReadStepConfiguration x |
x.hasNodePath(node1, node2) and
hasNodePath(x, node1, node2) and
fieldOrPropertyRead(node1.asExpr(), c, node2.asExpr())
or
x.hasNodePath(node1, node2) and
hasNodePath(x, node1, node2) and
arrayRead(node1.asExpr(), node2.asExpr()) and
c instanceof ElementContent
or
@@ -719,7 +745,7 @@ private module Cached {
c instanceof ElementContent
)
or
x.hasNodePath(node1, node2) and
hasNodePath(x, node1, node2) and
node2.asExpr().(AwaitExpr).getExpr() = node1.asExpr() and
c = getResultContent()
)

View File

@@ -105,7 +105,7 @@ private class LocalTaintExprStepConfiguration extends ControlFlowReachabilityCon
private predicate localTaintStepCommon(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
Stages::DataFlowStage::forceCachingInSameStage() and
any(LocalTaintExprStepConfiguration x).hasNodePath(nodeFrom, nodeTo)
hasNodePath(any(LocalTaintExprStepConfiguration x), nodeFrom, nodeTo)
or
localTaintStepCil(nodeFrom, nodeTo)
}

View File

@@ -5,17 +5,16 @@
private import csharp as CS
private import semmle.code.csharp.dataflow.SSA::Ssa as Ssa
private import semmle.code.csharp.dataflow.internal.rangeanalysis.ConstantUtils as CU
private import semmle.code.csharp.dataflow.internal.rangeanalysis.RangeUtils as RU
private import semmle.code.csharp.dataflow.internal.rangeanalysis.SsaUtils as SU
class SsaVariable extends Ssa::Definition {
/** Gets a read of the source variable underlying this SSA definition. */
Expr getAUse() { result = getARead() }
}
class SsaVariable = SU::SsaVariable;
class Expr = CS::Expr;
class Expr = CS::ControlFlow::Nodes::ExprNode;
class IntegralType = CS::IntegralType;
class ConstantIntegerExpr = CU::ConstantIntegerExpr;
/** Holds if `e` is a bound expression and it is not an SSA variable read. */
predicate interestingExprBound(Expr e) { CU::systemArrayLengthAccess(e.(CS::PropertyRead)) }
predicate interestingExprBound(Expr e) { CU::systemArrayLengthAccess(e.getExpr()) }

View File

@@ -4,18 +4,10 @@
private import csharp
private import Ssa
private import SsaUtils
private import RangeUtils
/**
* Holds if property `p` matches `property` in `baseClass` or any overrides.
*/
predicate propertyOverrides(Property p, string baseClass, string property) {
exists(Property p2 |
p2.getSourceDeclaration().getDeclaringType().hasQualifiedName(baseClass) and
p2.hasName(property)
|
p.overridesOrImplementsOrEquals(p2)
)
}
private class ExprNode = ControlFlow::Nodes::ExprNode;
/**
* Holds if `pa` is an access to the `Length` property of an array.
@@ -30,40 +22,42 @@ predicate systemArrayLengthAccess(PropertyAccess pa) {
* - a read of a compile time constant with integer value `val`, or
* - a read of the `Length` of an array with `val` lengths.
*/
private predicate constantIntegerExpr(Expr e, int val) {
private predicate constantIntegerExpr(ExprNode e, int val) {
e.getValue().toInt() = val
or
exists(ExplicitDefinition v, Expr src |
e = v.getARead() and
src = v.getADefinition().getSource() and
exists(ExprNode src |
e = getAnExplicitDefinitionRead(src) and
constantIntegerExpr(src, val)
)
or
isArrayLengthAccess(e, val)
}
private int getArrayLength(ArrayCreation arrCreation, int index) {
constantIntegerExpr(arrCreation.getLengthArgument(index), result)
private int getArrayLength(ExprNode e, int index) {
exists(ArrayCreation arrCreation, ExprNode length |
hasChild(arrCreation, arrCreation.getLengthArgument(index), e, length) and
constantIntegerExpr(length, result)
)
}
private int getArrayLengthRec(ArrayCreation arrCreation, int index) {
private int getArrayLengthRec(ExprNode arrCreation, int index) {
index = 0 and result = getArrayLength(arrCreation, 0)
or
index > 0 and
result = getArrayLength(arrCreation, index) * getArrayLengthRec(arrCreation, index - 1)
}
private predicate isArrayLengthAccess(PropertyAccess pa, int length) {
systemArrayLengthAccess(pa) and
exists(ExplicitDefinition arr, ArrayCreation arrCreation |
getArrayLengthRec(arrCreation, arrCreation.getNumberOfLengthArguments() - 1) = length and
arrCreation = arr.getADefinition().getSource() and
pa.getQualifier() = arr.getARead()
private predicate isArrayLengthAccess(ExprNode e, int length) {
exists(PropertyAccess pa, ExprNode arrCreation |
systemArrayLengthAccess(pa) and
getArrayLengthRec(arrCreation,
arrCreation.getExpr().(ArrayCreation).getNumberOfLengthArguments() - 1) = length and
hasChild(pa, pa.getQualifier(), e, getAnExplicitDefinitionRead(arrCreation))
)
}
/** An expression that always has the same integer value. */
class ConstantIntegerExpr extends Expr {
class ConstantIntegerExpr extends ExprNode {
ConstantIntegerExpr() { constantIntegerExpr(this, _) }
/** Gets the integer value of this expression. */

View File

@@ -0,0 +1,215 @@
import csharp
private class ControlFlowScope extends ControlFlowElement {
private boolean exactScope;
ControlFlowScope() {
exists(ControlFlowReachabilityConfiguration c |
c.candidate(_, _, this, exactScope, _) or
c.candidateDef(_, _, this, exactScope, _)
)
}
predicate isExact() { exactScope = true }
predicate isNonExact() { exactScope = false }
}
private ControlFlowElement getANonExactScopeChild(ControlFlowScope scope) {
scope.isNonExact() and
result = scope
or
result = getANonExactScopeChild(scope).getAChild()
}
pragma[noinline]
private ControlFlow::BasicBlock getABasicBlockInScope(ControlFlowScope scope, boolean exactScope) {
result.getANode().getElement() = getANonExactScopeChild(scope) and
exactScope = false
or
scope.isExact() and
result.getANode().getElement() = scope and
exactScope = true
}
/**
* A helper class for determining control-flow reachability for pairs of
* elements.
*
* This is useful when defining for example expression-based data-flow steps in
* the presence of control-flow splitting, where a data-flow step should make
* sure to stay in the same split.
*
* For example, in
*
* ```csharp
* if (b)
* ....
* var x = "foo";
* if (b)
* ....
* ```
*
* there should only be steps from `[b = true] "foo"` to `[b = true] SSA def(x)`
* and `[b = false] "foo"` to `[b = false] SSA def(x)`, and for example not from
* `[b = true] "foo"` to `[b = false] SSA def(x)`
*/
abstract class ControlFlowReachabilityConfiguration extends string {
bindingset[this]
ControlFlowReachabilityConfiguration() { any() }
/**
* Holds if `e1` and `e2` are expressions for which we want to find a
* control-flow path that follows control flow successors (resp.
* predecessors, as specified by `isSuccesor`) inside the syntactic scope
* `scope`. The Boolean `exactScope` indicates whether a transitive child
* of `scope` is allowed (`exactScope = false`).
*/
predicate candidate(
Expr e1, Expr e2, ControlFlowElement scope, boolean exactScope, boolean isSuccessor
) {
none()
}
/**
* Holds if `e` and `def` are elements for which we want to find a
* control-flow path that follows control flow successors (resp.
* predecessors, as specified by `isSuccesor`) inside the syntactic scope
* `scope`. The Boolean `exactScope` indicates whether a transitive child
* of `scope` is allowed (`exactScope = false`).
*/
predicate candidateDef(
Expr e, AssignableDefinition def, ControlFlowElement scope, boolean exactScope,
boolean isSuccessor
) {
none()
}
pragma[nomagic]
private predicate reachesBasicBlockExprBase(
Expr e1, Expr e2, boolean isSuccessor, ControlFlow::Nodes::ElementNode cfn1, int i,
ControlFlow::BasicBlock bb
) {
this.candidate(e1, e2, _, _, isSuccessor) and
cfn1 = e1.getAControlFlowNode() and
bb.getNode(i) = cfn1
}
pragma[nomagic]
private predicate reachesBasicBlockExprRec(
Expr e1, Expr e2, boolean isSuccessor, ControlFlow::Nodes::ElementNode cfn1,
ControlFlow::BasicBlock bb
) {
exists(ControlFlow::BasicBlock mid |
this.reachesBasicBlockExpr(e1, e2, isSuccessor, cfn1, mid)
|
isSuccessor = true and
bb = mid.getASuccessor()
or
isSuccessor = false and
bb = mid.getAPredecessor()
)
}
pragma[nomagic]
private predicate reachesBasicBlockExpr(
Expr e1, Expr e2, boolean isSuccessor, ControlFlow::Nodes::ElementNode cfn1,
ControlFlow::BasicBlock bb
) {
this.reachesBasicBlockExprBase(e1, e2, isSuccessor, cfn1, _, bb)
or
exists(ControlFlowElement scope, boolean exactScope |
this.candidate(e1, e2, scope, exactScope, isSuccessor) and
this.reachesBasicBlockExprRec(e1, e2, isSuccessor, cfn1, bb) and
bb = getABasicBlockInScope(scope, exactScope)
)
}
pragma[nomagic]
private predicate reachesBasicBlockDefinitionBase(
Expr e, AssignableDefinition def, boolean isSuccessor, ControlFlow::Nodes::ElementNode cfn,
int i, ControlFlow::BasicBlock bb
) {
this.candidateDef(e, def, _, _, isSuccessor) and
cfn = e.getAControlFlowNode() and
bb.getNode(i) = cfn
}
pragma[nomagic]
private predicate reachesBasicBlockDefinitionRec(
Expr e, AssignableDefinition def, boolean isSuccessor, ControlFlow::Nodes::ElementNode cfn,
ControlFlow::BasicBlock bb
) {
exists(ControlFlow::BasicBlock mid |
this.reachesBasicBlockDefinition(e, def, isSuccessor, cfn, mid)
|
isSuccessor = true and
bb = mid.getASuccessor()
or
isSuccessor = false and
bb = mid.getAPredecessor()
)
}
pragma[nomagic]
private predicate reachesBasicBlockDefinition(
Expr e, AssignableDefinition def, boolean isSuccessor, ControlFlow::Nodes::ElementNode cfn,
ControlFlow::BasicBlock bb
) {
this.reachesBasicBlockDefinitionBase(e, def, isSuccessor, cfn, _, bb)
or
exists(ControlFlowElement scope, boolean exactScope |
this.candidateDef(e, def, scope, exactScope, isSuccessor) and
this.reachesBasicBlockDefinitionRec(e, def, isSuccessor, cfn, bb) and
bb = getABasicBlockInScope(scope, exactScope)
)
}
/**
* 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
or
isSuccessor = false and i >= j
)
or
exists(ControlFlow::BasicBlock bb |
this.reachesBasicBlockExprRec(e1, e2, _, cfn1, bb) and
cfn2 = bb.getANode() and
cfn2 = e2.getAControlFlowNode()
)
}
/**
* 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
) {
exists(ControlFlow::BasicBlock bb, boolean isSuccessor, int i, int j |
this.reachesBasicBlockDefinitionBase(e, def, isSuccessor, cfn, i, bb) and
cfnDef = bb.getNode(j) and
def.getAControlFlowNode() = cfnDef
|
isSuccessor = true and j >= i
or
isSuccessor = false and i >= j
)
or
exists(ControlFlow::BasicBlock bb |
this.reachesBasicBlockDefinitionRec(e, def, _, cfn, bb) and
def.getAControlFlowNode() = cfnDef and
cfnDef = bb.getANode()
)
}
}

View File

@@ -1,98 +1,39 @@
module Private {
private import csharp as CS
private import ConstantUtils as CU
private import semmle.code.csharp.controlflow.Guards as G
private import semmle.code.csharp.dataflow.internal.rangeanalysis.RangeUtils as RU
private import SsaUtils as SU
private import SignAnalysisSpecific::Private as SA
private import SsaReadPositionCommon
class BasicBlock = CS::Ssa::BasicBlock;
class SsaVariable extends CS::Ssa::Definition {
CS::AssignableRead getAUse() { result = this.getARead() }
}
class SsaVariable = SU::SsaVariable;
class SsaPhiNode = CS::Ssa::PhiNode;
class Expr = CS::Expr;
class Expr = CS::ControlFlow::Nodes::ExprNode;
class Guard = G::Guard;
class Guard = RU::Guard;
class ConstantIntegerExpr = CU::ConstantIntegerExpr;
class ConditionalExpr extends CS::ConditionalExpr {
/** Gets the "then" expression of this conditional expression. */
Expr getTrueExpr() { result = this.getThen() }
class ConditionalExpr = RU::ExprNode::ConditionalExpr;
/** Gets the "else" expression of this conditional expression. */
Expr getFalseExpr() { result = this.getElse() }
}
class AddExpr = RU::ExprNode::AddExpr;
/** Represent an addition expression. */
class AddExpr extends CS::AddExpr {
/** Gets the LHS operand of this add expression. */
Expr getLhs() { result = this.getLeftOperand() }
class SubExpr = RU::ExprNode::SubExpr;
/** Gets the RHS operand of this add expression. */
Expr getRhs() { result = this.getRightOperand() }
}
class RemExpr = RU::ExprNode::RemExpr;
/** Represent a subtraction expression. */
class SubExpr extends CS::SubExpr {
/** Gets the LHS operand of this subtraction expression. */
Expr getLhs() { result = this.getLeftOperand() }
class BitwiseAndExpr = RU::ExprNode::BitwiseAndExpr;
/** Gets the RHS operand of this subtraction expression. */
Expr getRhs() { result = this.getRightOperand() }
}
class MulExpr = RU::ExprNode::MulExpr;
class RemExpr = CS::RemExpr;
class LShiftExpr = RU::ExprNode::LShiftExpr;
/** Represent a bitwise and or an assign-and expression. */
class BitwiseAndExpr extends CS::Expr {
BitwiseAndExpr() { this instanceof CS::BitwiseAndExpr or this instanceof CS::AssignAndExpr }
predicate guardDirectlyControlsSsaRead = RU::guardControlsSsaRead/3;
/** Gets an operand of this bitwise and operation. */
Expr getAnOperand() {
result = this.(CS::BitwiseAndExpr).getAnOperand() or
result = this.(CS::AssignAndExpr).getRValue() or
result = this.(CS::AssignAndExpr).getLValue()
}
/** Holds if this expression has operands `e1` and `e2`. */
predicate hasOperands(Expr e1, Expr e2) {
this.getAnOperand() = e1 and
this.getAnOperand() = e2 and
e1 != e2
}
}
/** Represent a multiplication or an assign-mul expression. */
class MulExpr extends CS::Expr {
MulExpr() { this instanceof CS::MulExpr or this instanceof CS::AssignMulExpr }
/** Gets an operand of this multiplication. */
Expr getAnOperand() {
result = this.(CS::MulExpr).getAnOperand() or
result = this.(CS::AssignMulExpr).getRValue() or
result = this.(CS::AssignMulExpr).getLValue()
}
}
/** Represent a left shift or an assign-lshift expression. */
class LShiftExpr extends CS::Expr {
LShiftExpr() { this instanceof CS::LShiftExpr or this instanceof CS::AssignLShiftExpr }
/** Gets the RHS operand of this shift. */
Expr getRhs() {
result = this.(CS::LShiftExpr).getRightOperand() or
result = this.(CS::AssignLShiftExpr).getRValue()
}
}
predicate guardDirectlyControlsSsaRead = SA::guardControlsSsaRead/3;
predicate guardControlsSsaRead = SA::guardControlsSsaRead/3;
predicate guardControlsSsaRead = RU::guardControlsSsaRead/3;
predicate valueFlowStep = RU::valueFlowStep/3;
@@ -100,11 +41,44 @@ module Private {
predicate ssaUpdateStep = RU::ssaUpdateStep/3;
Expr getABasicBlockExpr(BasicBlock bb) { result = bb.getANode().getElement() }
Expr getABasicBlockExpr(BasicBlock bb) { result = bb.getANode() }
private predicate id(CS::ControlFlowElement x, CS::ControlFlowElement y) { x = y }
private class CallableOrCFE extends CS::Element {
CallableOrCFE() { this instanceof CS::Callable or this instanceof CS::ControlFlowElement }
}
private predicate idOf(CS::ControlFlowElement x, int y) = equivalenceRelation(id/2)(x, y)
private predicate id(CallableOrCFE x, CallableOrCFE y) { x = y }
int getId(BasicBlock bb) { idOf(bb.getFirstNode().getElement(), result) }
private predicate idOf(CallableOrCFE x, int y) = equivalenceRelation(id/2)(x, y)
private class PhiInputEdgeBlock extends BasicBlock {
PhiInputEdgeBlock() { this = any(SsaReadPositionPhiInputEdge edge).getOrigBlock() }
}
int getId(PhiInputEdgeBlock bb) {
idOf(bb.getFirstNode().getElement(), result)
or
idOf(bb.(CS::ControlFlow::BasicBlocks::EntryBlock).getCallable(), result)
}
private string getSplitString(PhiInputEdgeBlock bb) {
result = bb.getFirstNode().(CS::ControlFlow::Nodes::ElementNode).getSplitsString()
or
not exists(bb.getFirstNode().(CS::ControlFlow::Nodes::ElementNode).getSplitsString()) and
result = ""
}
/**
* Holds if `inp` is an input to `phi` along `edge` and this input has index `r`
* in an arbitrary 1-based numbering of the input edges to `phi`.
*/
predicate rankedPhiInput(SsaPhiNode phi, SsaVariable inp, SsaReadPositionPhiInputEdge edge, int r) {
edge.phiInput(phi, inp) and
edge =
rank[r](SsaReadPositionPhiInputEdge e |
e.phiInput(phi, _)
|
e order by getId(e.getOrigBlock()), getSplitString(e.getOrigBlock())
)
}
}

View File

@@ -1,98 +1,406 @@
/**
* Provides predicates for range and modulus analysis.
*/
private module Impl {
private import csharp
private import Ssa
private import SsaUtils
private import ConstantUtils
private import SsaReadPositionCommon
private import semmle.code.csharp.controlflow.Guards as G
private import ControlFlowReachability
private import csharp
private import Ssa
private import SsaUtils
private import ConstantUtils
private import SsaReadPositionCommon
private import semmle.code.csharp.controlflow.Guards as G
private class BooleanValue = G::AbstractValues::BooleanValue;
private class BooleanValue = G::AbstractValues::BooleanValue;
private class ExprNode = ControlFlow::Nodes::ExprNode;
/**
* Holds if `v` is an `ExplicitDefinition` that equals `e + delta`.
*/
predicate ssaUpdateStep(ExplicitDefinition v, Expr e, int delta) {
v.getADefinition().getExpr().(Assignment).getRValue() = e and delta = 0
or
v.getADefinition().getExpr().(PostIncrExpr).getOperand() = e and delta = 1
or
v.getADefinition().getExpr().(PreIncrExpr).getOperand() = e and delta = 1
or
v.getADefinition().getExpr().(PostDecrExpr).getOperand() = e and delta = -1
or
v.getADefinition().getExpr().(PreDecrExpr).getOperand() = e and delta = -1
}
private class ExprChildReachability extends ControlFlowReachabilityConfiguration {
ExprChildReachability() { this = "ExprChildReachability" }
private G::Guard eqFlowCondAbs(Definition def, Expr e, int delta, boolean isEq, G::AbstractValue v) {
exists(boolean eqpolarity |
result.isEquality(ssaRead(def, delta), e, eqpolarity) and
eqpolarity.booleanXor(v.(BooleanValue).getValue()).booleanNot() = isEq
)
or
exists(G::AbstractValue v0 |
G::Internal::impliesSteps(result, v, eqFlowCondAbs(def, e, delta, isEq, v0), v0)
)
}
override predicate candidate(
Expr e1, Expr e2, ControlFlowElement scope, boolean exactScope, boolean isSuccessor
) {
e2 = e1.getAChild() and
scope = e1 and
exactScope = false and
isSuccessor in [false, true]
}
}
/**
* Gets a condition that tests whether `def` equals `e + delta`.
*
* If the condition evaluates to `testIsTrue`:
* - `isEq = true` : `def == e + delta`
* - `isEq = false` : `def != e + delta`
*/
G::Guard eqFlowCond(Definition def, Expr e, int delta, boolean isEq, boolean testIsTrue) {
exists(BooleanValue v |
result = eqFlowCondAbs(def, e, delta, isEq, v) and
testIsTrue = v.getValue()
)
}
/** Holds if `parent` having child `child` implies `parentNode` having child `childNode`. */
predicate hasChild(Expr parent, Expr child, ExprNode parentNode, ExprNode childNode) {
any(ExprChildReachability x).hasExprPath(parent, parentNode, child, childNode)
}
/**
* Holds if `e1 + delta` equals `e2`.
*/
predicate valueFlowStep(Expr e2, Expr e1, int delta) {
valueFlowStep(e2.(AssignOperation).getExpandedAssignment(), e1, delta)
or
e2.(AssignExpr).getRValue() = e1 and delta = 0
or
e2.(UnaryPlusExpr).getOperand() = e1 and delta = 0
or
e2.(PostIncrExpr).getOperand() = e1 and delta = 0
or
e2.(PostDecrExpr).getOperand() = e1 and delta = 0
or
e2.(PreIncrExpr).getOperand() = e1 and delta = 1
or
e2.(PreDecrExpr).getOperand() = e1 and delta = -1
or
exists(ConstantIntegerExpr x |
e2.(AddExpr).getAnOperand() = e1 and
e2.(AddExpr).getAnOperand() = x and
not e1 = x
|
x.getIntValue() = delta
)
or
exists(ConstantIntegerExpr x |
exists(SubExpr sub |
e2 = sub and
sub.getLeftOperand() = e1 and
sub.getRightOperand() = x
/** Holds if SSA definition `def` equals `e + delta`. */
predicate ssaUpdateStep(ExplicitDefinition def, ExprNode e, int delta) {
exists(ControlFlow::Node cfn | cfn = def.getControlFlowNode() |
e = cfn.(ExprNode::Assignment).getRValue() and delta = 0
or
e = cfn.(ExprNode::PostIncrExpr).getOperand() and delta = 1
or
e = cfn.(ExprNode::PreIncrExpr).getOperand() and delta = 1
or
e = cfn.(ExprNode::PostDecrExpr).getOperand() and delta = -1
or
e = cfn.(ExprNode::PreDecrExpr).getOperand() and delta = -1
)
|
x.getIntValue() = -delta
)
}
/** Holds if `e1 + delta` equals `e2`. */
predicate valueFlowStep(ExprNode e2, ExprNode e1, int delta) {
e2.(ExprNode::AssignExpr).getRValue() = e1 and delta = 0
or
e2.(ExprNode::UnaryPlusExpr).getOperand() = e1 and delta = 0
or
e2.(ExprNode::PostIncrExpr).getOperand() = e1 and delta = 0
or
e2.(ExprNode::PostDecrExpr).getOperand() = e1 and delta = 0
or
e2.(ExprNode::PreIncrExpr).getOperand() = e1 and delta = 1
or
e2.(ExprNode::PreDecrExpr).getOperand() = e1 and delta = -1
or
exists(ConstantIntegerExpr x |
e2.(ExprNode::AddExpr).getAnOperand() = e1 and
e2.(ExprNode::AddExpr).getAnOperand() = x and
e1 != x and
x.getIntValue() = delta
)
or
exists(ConstantIntegerExpr x |
e2.(ExprNode::SubExpr).getLeftOperand() = e1 and
e2.(ExprNode::SubExpr).getRightOperand() = x and
x.getIntValue() = -delta
)
}
/** An expression whose value may control the execution of another element. */
class Guard extends Expr {
Guard() { this instanceof G::Guard }
/**
* Holds if basic block `bb` is guarded by this guard having value `v`.
*/
predicate controlsBasicBlock(BasicBlock bb, G::AbstractValue v) {
this.(G::Guard).controlsBasicBlock(bb, v)
}
/**
* Holds if this guard is an equality test between `e1` and `e2`. If the test is
* negated, that is `!=`, then `polarity` is false, otherwise `polarity` is
* true.
*/
predicate isEquality(ExprNode e1, ExprNode e2, boolean polarity) {
exists(Expr e1_, Expr e2_ |
e1 = unique(ExprNode cfn | hasChild(this, e1_, _, cfn) | cfn) and
e2 = unique(ExprNode cfn | hasChild(this, e2_, _, cfn) | cfn) and
this.(G::Guard).isEquality(e1_, e2_, polarity)
)
}
}
private Guard eqFlowCondAbs(
Definition def, ExprNode e, int delta, boolean isEq, G::AbstractValue v
) {
exists(boolean eqpolarity |
result.isEquality(ssaRead(def, delta), e, eqpolarity) and
eqpolarity.booleanXor(v.(BooleanValue).getValue()).booleanNot() = isEq
)
or
exists(G::AbstractValue v0 |
G::Internal::impliesSteps(result, v, eqFlowCondAbs(def, e, delta, isEq, v0), v0)
)
}
/**
* Gets a condition that tests whether `def` equals `e + delta`.
*
* If the condition evaluates to `testIsTrue`:
* - `isEq = true` : `def == e + delta`
* - `isEq = false` : `def != e + delta`
*/
Guard eqFlowCond(Definition def, ExprNode e, int delta, boolean isEq, boolean testIsTrue) {
exists(BooleanValue v |
result = eqFlowCondAbs(def, e, delta, isEq, v) and
testIsTrue = v.getValue()
)
}
/**
* Holds if `guard` controls the position `controlled` with the value `testIsTrue`.
*/
predicate guardControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
exists(BooleanValue b | b.getValue() = testIsTrue |
guard.controlsBasicBlock(controlled.(SsaReadPositionBlock).getBlock(), b)
)
}
/**
* Holds if property `p` matches `property` in `baseClass` or any overrides.
*/
predicate propertyOverrides(Property p, string baseClass, string property) {
exists(Property p2 |
p2.getSourceDeclaration().getDeclaringType().hasQualifiedName(baseClass) and
p2.hasName(property)
|
p.overridesOrImplementsOrEquals(p2)
)
}
}
import Impl
/**
* Holds if `guard` controls the position `controlled` with the value `testIsTrue`.
* Provides classes for mapping CFG nodes to AST nodes, in a way that respects
* control-flow splitting. For example, in
*
* ```csharp
* int M(bool b)
* {
* var i = b ? 1 : -1;
* i = i - 1;
* if (b)
* return 0;
* return i;
* }
* ```
* the subtraction `i - 1` exists in two copies in the CFG. The class `SubExpr`
* contains each copy, with split-respecting `getLeft/RightOperand()` predicates.
*/
predicate guardControlsSsaRead(G::Guard guard, SsaReadPosition controlled, boolean testIsTrue) {
exists(BooleanValue b | b.getValue() = testIsTrue |
guard.controlsBasicBlock(controlled.(SsaReadPositionBlock).getBlock(), b)
)
module ExprNode {
private import csharp as CS
private class ExprNode = CS::ControlFlow::Nodes::ExprNode;
private import Sign
/** An assignable access. */
class AssignableAccess extends ExprNode {
override CS::AssignableAccess e;
}
/** A field access. */
class FieldAccess extends ExprNode {
override CS::FieldAccess e;
}
/** A character literal. */
class CharLiteral extends ExprNode {
override CS::CharLiteral e;
}
/** An integer literal. */
class IntegerLiteral extends ExprNode {
override CS::IntegerLiteral e;
}
/** A long literal. */
class LongLiteral extends ExprNode {
override CS::LongLiteral e;
}
/** A cast. */
class CastExpr extends ExprNode {
override CS::CastExpr e;
/** Gets the source type of this cast. */
CS::Type getSourceType() { result = e.getSourceType() }
}
/** A floating point literal. */
class RealLiteral extends ExprNode {
override CS::RealLiteral e;
}
/** An assignment. */
class Assignment extends ExprNode {
override CS::Assignment e;
/** Gets the left operand of this assignment. */
ExprNode getLValue() {
result = unique(ExprNode res | hasChild(e, e.getLValue(), this, res) | res)
}
/** Gets the right operand of this assignment. */
ExprNode getRValue() {
result = unique(ExprNode res | hasChild(e, e.getRValue(), this, res) | res)
}
}
/** A simple assignment. */
class AssignExpr extends Assignment {
override CS::AssignExpr e;
}
/** A unary operation. */
class UnaryOperation extends ExprNode {
override CS::UnaryOperation e;
/** Returns the operand of this unary operation. */
ExprNode getOperand() {
result = unique(ExprNode res | hasChild(e, e.getOperand(), this, res) | res)
}
/** Returns the operation representing this unary operation. */
TUnarySignOperation getOp() { none() }
}
/** A prefix increment operation. */
class PreIncrExpr extends UnaryOperation {
override CS::PreIncrExpr e;
override TIncOp getOp() { any() }
}
/** A postfix increment operation. */
class PostIncrExpr extends UnaryOperation {
override CS::PostIncrExpr e;
}
/** A prefix decrement operation. */
class PreDecrExpr extends UnaryOperation {
override CS::PreDecrExpr e;
override TDecOp getOp() { any() }
}
/** A postfix decrement operation. */
class PostDecrExpr extends UnaryOperation {
override CS::PostDecrExpr e;
}
/** A unary plus operation. */
class UnaryPlusExpr extends UnaryOperation {
override CS::UnaryPlusExpr e;
}
/** A unary minus operation. */
class UnaryMinusExpr extends UnaryOperation {
override CS::UnaryMinusExpr e;
override TNegOp getOp() { any() }
}
/** A bitwise complement operation. */
class ComplementExpr extends UnaryOperation {
override CS::ComplementExpr e;
override TBitNotOp getOp() { any() }
}
/** A binary operation. */
class BinaryOperation extends ExprNode {
override CS::BinaryOperation e;
/** Returns the operation representing this binary operation. */
TBinarySignOperation getOp() { none() }
/** Gets the left operand of this binary operation. */
ExprNode getLeftOperand() {
result = unique(ExprNode res | hasChild(e, e.getLeftOperand(), this, res) | res)
}
/** Gets the right operand of this binary operation. */
ExprNode getRightOperand() {
result = unique(ExprNode res | hasChild(e, e.getRightOperand(), this, res) | res)
}
/** Gets the left operand of this binary operation. */
ExprNode getLhs() { result = this.getLeftOperand() }
/** Gets the right operand of this binary operation. */
ExprNode getRhs() { result = this.getRightOperand() }
/** Gets an operand of this binary operation. */
ExprNode getAnOperand() { hasChild(e, e.getAnOperand(), this, result) }
/** Holds if this binary operation has operands `e1` and `e2`. */
predicate hasOperands(ExprNode e1, ExprNode e2) {
this.getAnOperand() = e1 and
this.getAnOperand() = e2 and
e1 != e2
}
}
/** An addition operation. */
class AddExpr extends BinaryOperation {
override CS::AddExpr e;
override TAddOp getOp() { any() }
}
/** A subtraction operation. */
class SubExpr extends BinaryOperation {
override CS::SubExpr e;
override TSubOp getOp() { any() }
}
/** A multiplication operation. */
class MulExpr extends BinaryOperation {
override CS::MulExpr e;
override TMulOp getOp() { any() }
}
/** A division operation. */
class DivExpr extends BinaryOperation {
override CS::DivExpr e;
override TDivOp getOp() { any() }
}
/** A remainder operation. */
class RemExpr extends BinaryOperation {
override CS::RemExpr e;
override TRemOp getOp() { any() }
}
/** A bitwise-and operation. */
class BitwiseAndExpr extends BinaryOperation {
override CS::BitwiseAndExpr e;
override TBitAndOp getOp() { any() }
}
/** A bitwise-or operation. */
class BitwiseOrExpr extends BinaryOperation {
override CS::BitwiseOrExpr e;
override TBitOrOp getOp() { any() }
}
/** A bitwise-xor operation. */
class BitwiseXorExpr extends BinaryOperation {
override CS::BitwiseXorExpr e;
override TBitXorOp getOp() { any() }
}
/** A left-shift operation. */
class LShiftExpr extends BinaryOperation {
override CS::LShiftExpr e;
override TLShiftOp getOp() { any() }
}
/** A right-shift operation. */
class RShiftExpr extends BinaryOperation {
override CS::RShiftExpr e;
override TRShiftOp getOp() { any() }
}
/** A conditional expression. */
class ConditionalExpr extends ExprNode {
override CS::ConditionalExpr e;
/** Gets the "then" expression of this conditional expression. */
ExprNode getTrueExpr() { hasChild(e, e.getThen(), this, result) }
/** Gets the "else" expression of this conditional expression. */
ExprNode getFalseExpr() { hasChild(e, e.getElse(), this, result) }
}
}

View File

@@ -51,7 +51,7 @@ private predicate unknownSign(Expr e) {
or
exists(CastExpr cast, Type fromtyp |
cast = e and
fromtyp = cast.getExpr().getType() and
fromtyp = cast.getSourceType() and
not fromtyp instanceof NumericOrCharType
)
or

View File

@@ -6,11 +6,10 @@ module Private {
private import SsaUtils as SU
private import ConstantUtils as CU
private import RangeUtils as RU
private import semmle.code.csharp.controlflow.Guards as G
private import Sign
import Impl
class Guard = G::Guard;
class Guard = RU::Guard;
class ConstantIntegerExpr = CU::ConstantIntegerExpr;
@@ -18,97 +17,33 @@ module Private {
class SsaPhiNode = CS::Ssa::PhiNode;
class VarAccess = CS::AssignableAccess;
class VarAccess = RU::ExprNode::AssignableAccess;
class FieldAccess = CS::FieldAccess;
class FieldAccess = RU::ExprNode::FieldAccess;
class CharacterLiteral = CS::CharLiteral;
class CharacterLiteral = RU::ExprNode::CharLiteral;
class IntegerLiteral = CS::IntegerLiteral;
class IntegerLiteral = RU::ExprNode::IntegerLiteral;
class LongLiteral = CS::LongLiteral;
class LongLiteral = RU::ExprNode::LongLiteral;
class CastExpr = CS::CastExpr;
class CastExpr = RU::ExprNode::CastExpr;
class Type = CS::Type;
class Expr = CS::Expr;
class Expr = CS::ControlFlow::Nodes::ExprNode;
class VariableUpdate = CS::AssignableDefinition;
class VariableUpdate = CS::Ssa::ExplicitDefinition;
class Field = CS::Field;
class RealLiteral = CS::RealLiteral;
class RealLiteral = RU::ExprNode::RealLiteral;
class DivExpr = CS::DivExpr;
class DivExpr = RU::ExprNode::DivExpr;
/** Class to represent unary operation. */
class UnaryOperation extends Expr {
UnaryOperation() {
this instanceof CS::PreIncrExpr or
this instanceof CS::PreDecrExpr or
this instanceof CS::UnaryMinusExpr or
this instanceof CS::ComplementExpr
}
class UnaryOperation = RU::ExprNode::UnaryOperation;
/** Returns the operand of this expression. */
Expr getOperand() {
result = this.(CS::PreIncrExpr).getOperand() or
result = this.(CS::PreDecrExpr).getOperand() or
result = this.(CS::UnaryMinusExpr).getOperand() or
result = this.(CS::ComplementExpr).getOperand()
}
/** Returns the operation representing this expression. */
TUnarySignOperation getOp() {
this instanceof CS::PreIncrExpr and result = TIncOp()
or
this instanceof CS::PreDecrExpr and result = TDecOp()
or
this instanceof CS::UnaryMinusExpr and result = TNegOp()
or
this instanceof CS::ComplementExpr and result = TBitNotOp()
}
}
/** Class to represent binary operation. */
class BinaryOperation extends CS::BinaryOperation {
BinaryOperation() {
this instanceof CS::AddExpr or
this instanceof CS::SubExpr or
this instanceof CS::MulExpr or
this instanceof CS::DivExpr or
this instanceof CS::RemExpr or
this instanceof CS::BitwiseAndExpr or
this instanceof CS::BitwiseOrExpr or
this instanceof CS::BitwiseXorExpr or
this instanceof CS::LShiftExpr or
this instanceof CS::RShiftExpr
}
/** Returns the operation representing this expression. */
TBinarySignOperation getOp() {
this instanceof CS::AddExpr and result = TAddOp()
or
this instanceof CS::SubExpr and result = TSubOp()
or
this instanceof CS::MulExpr and result = TMulOp()
or
this instanceof CS::DivExpr and result = TDivOp()
or
this instanceof CS::RemExpr and result = TRemOp()
or
this instanceof CS::BitwiseAndExpr and result = TBitAndOp()
or
this instanceof CS::BitwiseOrExpr and result = TBitOrOp()
or
this instanceof CS::BitwiseXorExpr and result = TBitXorOp()
or
this instanceof CS::LShiftExpr and result = TLShiftOp()
or
this instanceof CS::RShiftExpr and result = TRShiftOp()
}
}
class BinaryOperation = RU::ExprNode::BinaryOperation;
predicate ssaRead = SU::ssaRead/2;
@@ -118,21 +53,21 @@ module Private {
private module Impl {
private import csharp
private import SsaUtils
private import RangeUtils
private import ConstantUtils
private import semmle.code.csharp.controlflow.Guards
private import Linq.Helpers
private import Sign
private import SignAnalysisCommon
private import SsaReadPositionCommon
private import semmle.code.csharp.commons.ComparisonTest
private class BooleanValue = AbstractValues::BooleanValue;
private class ExprNode = ControlFlow::Nodes::ExprNode;
/** Gets the character value of expression `e`. */
string getCharValue(Expr e) { result = e.getValue() and e.getType() instanceof CharType }
string getCharValue(ExprNode e) { result = e.getValue() and e.getType() instanceof CharType }
/** Gets the constant `float` value of non-`ConstantIntegerExpr` expressions. */
float getNonIntegerValue(Expr e) {
float getNonIntegerValue(ExprNode e) {
exists(string s |
s = e.getValue() and
result = s.toFloat() and
@@ -144,19 +79,19 @@ private module Impl {
* Holds if `e` is an access to the size of a container (`string`, `Array`,
* `IEnumerable`, or `ICollection`).
*/
predicate containerSizeAccess(Expr e) {
exists(Property p | p = e.(PropertyAccess).getTarget() |
predicate containerSizeAccess(ExprNode e) {
exists(Property p | p = e.getExpr().(PropertyAccess).getTarget() |
propertyOverrides(p, "System.Collections.Generic.IEnumerable<>", "Count") or
propertyOverrides(p, "System.Collections.ICollection", "Count") or
propertyOverrides(p, "System.String", "Length") or
propertyOverrides(p, "System.Array", "Length")
)
or
e instanceof CountCall
e.getExpr() instanceof CountCall
}
/** Holds if `e` is by definition strictly positive. */
predicate positiveExpression(Expr e) { e instanceof SizeofExpr }
predicate positiveExpression(ExprNode e) { e.getExpr() instanceof SizeofExpr }
abstract class NumericOrCharType extends Type { }
@@ -185,43 +120,48 @@ private module Impl {
}
/** Returns the underlying variable update of the explicit SSA variable `v`. */
AssignableDefinition getExplicitSsaAssignment(Ssa::ExplicitDefinition v) {
result = v.getADefinition()
}
Ssa::ExplicitDefinition getExplicitSsaAssignment(Ssa::ExplicitDefinition v) { result = v }
/** Returns the assignment of the variable update `def`. */
Expr getExprFromSsaAssignment(AssignableDefinition def) { result = def.getSource() }
ExprNode getExprFromSsaAssignment(Ssa::ExplicitDefinition def) {
exists(AssignableDefinition adef |
adef = def.getADefinition() and
hasChild(adef.getExpr(), adef.getSource(), def.getControlFlowNode(), result)
)
}
/** Holds if `def` can have any sign. */
predicate explicitSsaDefWithAnySign(AssignableDefinition def) {
not exists(def.getSource()) and
predicate explicitSsaDefWithAnySign(Ssa::ExplicitDefinition def) {
not exists(def.getADefinition().getSource()) and
not def.getElement() instanceof MutatorOperation
}
/** Returns the operand of the operation if `def` is a decrement. */
Expr getDecrementOperand(AssignableDefinition def) {
result = def.getElement().(DecrementOperation).getOperand()
ExprNode getDecrementOperand(Ssa::ExplicitDefinition def) {
hasChild(def.getElement(), def.getElement().(DecrementOperation).getOperand(),
def.getControlFlowNode(), result)
}
/** Returns the operand of the operation if `def` is an increment. */
Expr getIncrementOperand(AssignableDefinition def) {
result = def.getElement().(IncrementOperation).getOperand()
ExprNode getIncrementOperand(Ssa::ExplicitDefinition def) {
hasChild(def.getElement(), def.getElement().(IncrementOperation).getOperand(),
def.getControlFlowNode(), result)
}
/** Gets the variable underlying the implicit SSA variable `v`. */
Declaration getImplicitSsaDeclaration(Ssa::ImplicitDefinition v) {
result = v.getSourceVariable().getAssignable()
/** Gets the variable underlying the implicit SSA variable `def`. */
Declaration getImplicitSsaDeclaration(Ssa::ImplicitDefinition def) {
result = def.getSourceVariable().getAssignable()
}
/** Holds if the variable underlying the implicit SSA variable `v` is not a field. */
predicate nonFieldImplicitSsaDefinition(Ssa::ImplicitDefinition v) {
not getImplicitSsaDeclaration(v) instanceof Field
/** Holds if the variable underlying the implicit SSA variable `def` is not a field. */
predicate nonFieldImplicitSsaDefinition(Ssa::ImplicitDefinition def) {
not getImplicitSsaDeclaration(def) instanceof Field
}
/** Returned an expression that is assigned to `f`. */
Expr getAssignedValueToField(Field f) {
result = f.getAnAssignedValue() or
result = any(AssignOperation a | a.getLValue() = f.getAnAccess())
ExprNode getAssignedValueToField(Field f) {
result.getExpr() in [f.getAnAssignedValue(),
any(AssignOperation a | a.getLValue() = f.getAnAccess())]
}
/** Holds if `f` can have any sign. */
@@ -244,71 +184,78 @@ private module Impl {
/**
* Holds if `e` has type `NumericOrCharType`, but the sign of `e` is unknown.
*/
predicate numericExprWithUnknownSign(Expr e) {
predicate numericExprWithUnknownSign(ExprNode e) {
e.getType() instanceof NumericOrCharType and
not e = getARead(_) and
not e instanceof FieldAccess and
not e instanceof TypeAccess and
not e.getExpr() instanceof FieldAccess and
not e.getExpr() instanceof TypeAccess and
// The expression types that are listed here are the ones handled in `specificSubExprSign`.
// Keep them in sync.
not e instanceof AssignExpr and
not e instanceof AssignOperation and
not e instanceof UnaryPlusExpr and
not e instanceof PostIncrExpr and
not e instanceof PostDecrExpr and
not e instanceof PreIncrExpr and
not e instanceof PreDecrExpr and
not e instanceof UnaryMinusExpr and
not e instanceof ComplementExpr and
not e instanceof AddExpr and
not e instanceof SubExpr and
not e instanceof MulExpr and
not e instanceof DivExpr and
not e instanceof RemExpr and
not e instanceof BitwiseAndExpr and
not e instanceof BitwiseOrExpr and
not e instanceof BitwiseXorExpr and
not e instanceof LShiftExpr and
not e instanceof RShiftExpr and
not e instanceof ConditionalExpr and
not e instanceof RefExpr and
not e instanceof LocalVariableDeclAndInitExpr and
not e instanceof SwitchCaseExpr and
not e instanceof CastExpr and
not e instanceof SwitchExpr and
not e instanceof NullCoalescingExpr
not e.getExpr() instanceof AssignExpr and
not e.getExpr() instanceof AssignOperation and
not e.getExpr() instanceof UnaryPlusExpr and
not e.getExpr() instanceof PostIncrExpr and
not e.getExpr() instanceof PostDecrExpr and
not e.getExpr() instanceof PreIncrExpr and
not e.getExpr() instanceof PreDecrExpr and
not e.getExpr() instanceof UnaryMinusExpr and
not e.getExpr() instanceof ComplementExpr and
not e.getExpr() instanceof AddExpr and
not e.getExpr() instanceof SubExpr and
not e.getExpr() instanceof MulExpr and
not e.getExpr() instanceof DivExpr and
not e.getExpr() instanceof RemExpr and
not e.getExpr() instanceof BitwiseAndExpr and
not e.getExpr() instanceof BitwiseOrExpr and
not e.getExpr() instanceof BitwiseXorExpr and
not e.getExpr() instanceof LShiftExpr and
not e.getExpr() instanceof RShiftExpr and
not e.getExpr() instanceof ConditionalExpr and
not e.getExpr() instanceof RefExpr and
not e.getExpr() instanceof LocalVariableDeclAndInitExpr and
not e.getExpr() instanceof SwitchCaseExpr and
not e.getExpr() instanceof CastExpr and
not e.getExpr() instanceof SwitchExpr and
not e.getExpr() instanceof NullCoalescingExpr
}
/** Returns a sub expression of `e` for expression types where the sign depends on the child. */
Expr getASubExprWithSameSign(Expr e) {
result = e.(AssignExpr).getRValue() or
result = e.(AssignOperation).getExpandedAssignment() or
result = e.(UnaryPlusExpr).getOperand() or
result = e.(PostIncrExpr).getOperand() or
result = e.(PostDecrExpr).getOperand() or
result = e.(ConditionalExpr).getAChild() or
result = e.(NullCoalescingExpr).getAChild() or
result = e.(SwitchExpr).getACase().getBody() or
result = e.(SwitchCaseExpr).getBody() or
result = e.(LocalVariableDeclAndInitExpr).getInitializer() or
result = e.(RefExpr).getExpr() or
result = e.(CastExpr).getExpr()
ExprNode getASubExprWithSameSign(ExprNode e) {
exists(Expr e_, Expr child | hasChild(e_, child, e, result) |
child = e_.(AssignExpr).getRValue() or
child = e_.(UnaryPlusExpr).getOperand() or
child = e_.(PostIncrExpr).getOperand() or
child = e_.(PostDecrExpr).getOperand() or
child = e_.(ConditionalExpr).getAChild() or
child = e_.(NullCoalescingExpr).getAChild() or
child = e_.(SwitchExpr).getACase() or
child = e_.(SwitchCaseExpr).getBody() or
child = e_.(LocalVariableDeclAndInitExpr).getInitializer() or
child = e_.(RefExpr).getExpr() or
child = e_.(CastExpr).getExpr()
)
}
Expr getARead(Ssa::Definition v) { result = v.getARead() }
ExprNode getARead(Ssa::Definition v) { exists(v.getAReadAtNode(result)) }
Field getField(FieldAccess fa) { result = fa.getTarget() }
Field getField(ExprNode fa) { result = fa.getExpr().(FieldAccess).getTarget() }
Expr getAnExpression(SsaReadPositionBlock bb) { result = bb.getBlock().getANode().getElement() }
ExprNode getAnExpression(SsaReadPositionBlock bb) { result = bb.getBlock().getANode() }
Guard getComparisonGuard(ComparisonExpr ce) { result = ce.getExpr() }
private newtype TComparisonExpr =
MkComparisonExpr(ComparisonTest ct, ExprNode e) { e = ct.getExpr().getAControlFlowNode() }
/** A relational comparison */
class ComparisonExpr extends ComparisonTest {
class ComparisonExpr extends MkComparisonExpr {
private ComparisonTest ct;
private ExprNode e;
private boolean strict;
ComparisonExpr() {
this.getComparisonKind() =
this = MkComparisonExpr(ct, e) and
ct.getComparisonKind() =
any(ComparisonKind ck |
ck.isLessThan() and strict = true
or
@@ -317,13 +264,22 @@ private module Impl {
)
}
/** Gets the underlying expression. */
Expr getExpr() { result = ct.getExpr() }
/** Gets a textual representation of this comparison test. */
string toString() { result = ct.toString() }
/** Gets the location of this comparison test. */
Location getLocation() { result = ct.getLocation() }
/**
* Gets the operand on the "greater" (or "greater-or-equal") side
* of this relational expression, that is, the side that is larger
* if the overall expression evaluates to `true`; for example on
* `x <= 20` this is the `20`, and on `y > 0` it is `y`.
*/
Expr getGreaterOperand() { result = this.getSecondArgument() }
ExprNode getGreaterOperand() { hasChild(ct.getExpr(), ct.getSecondArgument(), e, result) }
/**
* Gets the operand on the "lesser" (or "lesser-or-equal") side
@@ -331,7 +287,7 @@ private module Impl {
* if the overall expression evaluates to `true`; for example on
* `x <= 20` this is `x`, and on `y > 0` it is the `0`.
*/
Expr getLesserOperand() { result = this.getFirstArgument() }
ExprNode getLesserOperand() { hasChild(ct.getExpr(), ct.getFirstArgument(), e, result) }
/** Holds if this comparison is strict, i.e. `<` or `>`. */
predicate isStrict() { strict = true }

View File

@@ -4,15 +4,32 @@
private import csharp
private import Ssa
private import RangeUtils
private import ConstantUtils
private class ExprNode = ControlFlow::Nodes::ExprNode;
/** An SSA variable. */
class SsaVariable extends Definition {
/** Gets a read of this SSA variable. */
ExprNode getAUse() { exists(this.getAReadAtNode(result)) }
}
/** Gets a node that reads `src` via an SSA explicit definition. */
ExprNode getAnExplicitDefinitionRead(ExprNode src) {
exists(ExplicitDefinition def |
exists(def.getAReadAtNode(result)) and
hasChild(def.getElement(), def.getADefinition().getSource(), def.getControlFlowNode(), src)
)
}
/**
* Gets an expression that equals `v - delta`.
*/
Expr ssaRead(Definition v, int delta) {
result = v.getARead() and delta = 0
ExprNode ssaRead(Definition v, int delta) {
exists(v.getAReadAtNode(result)) and delta = 0
or
exists(AddExpr add, int d1, ConstantIntegerExpr c |
exists(ExprNode::AddExpr add, int d1, ConstantIntegerExpr c |
result = add and
delta = d1 - c.getIntValue()
|
@@ -21,22 +38,22 @@ Expr ssaRead(Definition v, int delta) {
add.getRightOperand() = ssaRead(v, d1) and add.getLeftOperand() = c
)
or
exists(SubExpr sub, int d1, ConstantIntegerExpr c |
exists(ExprNode::SubExpr sub, int d1, ConstantIntegerExpr c |
result = sub and
sub.getLeftOperand() = ssaRead(v, d1) and
sub.getRightOperand() = c and
delta = d1 + c.getIntValue()
)
or
v.(ExplicitDefinition).getADefinition().getExpr().(PreIncrExpr) = result and delta = 0
v.(ExplicitDefinition).getControlFlowNode().(ExprNode::PreIncrExpr) = result and delta = 0
or
v.(ExplicitDefinition).getADefinition().getExpr().(PreDecrExpr) = result and delta = 0
v.(ExplicitDefinition).getControlFlowNode().(ExprNode::PreDecrExpr) = result and delta = 0
or
v.(ExplicitDefinition).getADefinition().getExpr().(PostIncrExpr) = result and delta = 1 // x++ === ++x - 1
v.(ExplicitDefinition).getControlFlowNode().(ExprNode::PostIncrExpr) = result and delta = 1 // x++ === ++x - 1
or
v.(ExplicitDefinition).getADefinition().getExpr().(PostDecrExpr) = result and delta = -1 // x-- === --x + 1
v.(ExplicitDefinition).getControlFlowNode().(ExprNode::PostDecrExpr) = result and delta = -1 // x-- === --x + 1
or
v.(ExplicitDefinition).getADefinition().getExpr().(Assignment) = result and delta = 0
v.(ExplicitDefinition).getControlFlowNode().(ExprNode::Assignment) = result and delta = 0
or
result.(AssignExpr).getRValue() = ssaRead(v, delta)
result.(ExprNode::AssignExpr).getRValue() = ssaRead(v, delta)
}

View File

@@ -48,13 +48,6 @@ module LogForging {
HtmlSanitizer() { this.asExpr() instanceof HtmlSanitizedExpr }
}
/**
* A logger type that extends from an ILogger type.
*/
private class LoggerType extends RefType {
LoggerType() { getABaseType*().hasName("ILogger") }
}
/**
* An argument to a call to a method on a logger class.
*/

View File

@@ -422,6 +422,7 @@ callableFlow
| System.IO.TextReader.Read(Span<Char>) | qualifier -> return | false |
| System.IO.TextReader.ReadAsync(Char[], int, int) | qualifier -> return | false |
| System.IO.TextReader.ReadAsync(Memory<Char>, CancellationToken) | qualifier -> return | false |
| System.IO.TextReader.ReadAsyncInternal(Memory<Char>, CancellationToken) | qualifier -> return | false |
| System.IO.TextReader.ReadBlock(Char[], int, int) | qualifier -> return | false |
| System.IO.TextReader.ReadBlock(Span<Char>) | qualifier -> return | false |
| System.IO.TextReader.ReadBlockAsync(Char[], int, int) | qualifier -> return | false |
@@ -592,6 +593,7 @@ callableFlow
| System.String.TrimStart(params Char[]) | qualifier -> return | false |
| System.Text.Encoding.GetBytes(ReadOnlySpan<Char>, Span<Byte>) | argument 0 -> return | false |
| System.Text.Encoding.GetBytes(char*, int, byte*, int) | argument 0 -> return | false |
| System.Text.Encoding.GetBytes(char*, int, byte*, int, EncoderNLS) | argument 0 -> return | false |
| System.Text.Encoding.GetBytes(string) | argument 0 -> return | false |
| System.Text.Encoding.GetBytes(string, int, int) | argument 0 -> return | false |
| System.Text.Encoding.GetBytes(string, int, int, Byte[], int) | argument 0 -> return | false |
@@ -696,6 +698,98 @@ callableFlow
| System.Web.HttpUtility.UrlEncode(string) | argument 0 -> return | false |
| System.Web.UI.WebControls.TextBox.get_Text() | qualifier -> return | false |
callableFlowAccessPath
| System.().Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1, T2, T3, T4, T5, T6, T7, T8) | argument 0 [<empty>] -> return [Item1] | true |
| System.().Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1, T2, T3, T4, T5, T6, T7, T8) | argument 1 [<empty>] -> return [Item2] | true |
| System.().Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1, T2, T3, T4, T5, T6, T7, T8) | argument 2 [<empty>] -> return [Item3] | true |
| System.().Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1, T2, T3, T4, T5, T6, T7, T8) | argument 3 [<empty>] -> return [Item4] | true |
| System.().Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1, T2, T3, T4, T5, T6, T7, T8) | argument 4 [<empty>] -> return [Item5] | true |
| System.().Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1, T2, T3, T4, T5, T6, T7, T8) | argument 5 [<empty>] -> return [Item6] | true |
| System.().Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1, T2, T3, T4, T5, T6, T7, T8) | argument 6 [<empty>] -> return [Item7] | true |
| System.().Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1, T2, T3, T4, T5, T6, T7, T8) | argument 7 [<empty>] -> return [Item8] | true |
| System.().Create<T1, T2, T3, T4, T5, T6, T7>(T1, T2, T3, T4, T5, T6, T7) | argument 0 [<empty>] -> return [Item1] | true |
| System.().Create<T1, T2, T3, T4, T5, T6, T7>(T1, T2, T3, T4, T5, T6, T7) | argument 1 [<empty>] -> return [Item2] | true |
| System.().Create<T1, T2, T3, T4, T5, T6, T7>(T1, T2, T3, T4, T5, T6, T7) | argument 2 [<empty>] -> return [Item3] | true |
| System.().Create<T1, T2, T3, T4, T5, T6, T7>(T1, T2, T3, T4, T5, T6, T7) | argument 3 [<empty>] -> return [Item4] | true |
| System.().Create<T1, T2, T3, T4, T5, T6, T7>(T1, T2, T3, T4, T5, T6, T7) | argument 4 [<empty>] -> return [Item5] | true |
| System.().Create<T1, T2, T3, T4, T5, T6, T7>(T1, T2, T3, T4, T5, T6, T7) | argument 5 [<empty>] -> return [Item6] | true |
| System.().Create<T1, T2, T3, T4, T5, T6, T7>(T1, T2, T3, T4, T5, T6, T7) | argument 6 [<empty>] -> return [Item7] | true |
| System.().Create<T1, T2, T3, T4, T5, T6>(T1, T2, T3, T4, T5, T6) | argument 0 [<empty>] -> return [Item1] | true |
| System.().Create<T1, T2, T3, T4, T5, T6>(T1, T2, T3, T4, T5, T6) | argument 1 [<empty>] -> return [Item2] | true |
| System.().Create<T1, T2, T3, T4, T5, T6>(T1, T2, T3, T4, T5, T6) | argument 2 [<empty>] -> return [Item3] | true |
| System.().Create<T1, T2, T3, T4, T5, T6>(T1, T2, T3, T4, T5, T6) | argument 3 [<empty>] -> return [Item4] | true |
| System.().Create<T1, T2, T3, T4, T5, T6>(T1, T2, T3, T4, T5, T6) | argument 4 [<empty>] -> return [Item5] | true |
| System.().Create<T1, T2, T3, T4, T5, T6>(T1, T2, T3, T4, T5, T6) | argument 5 [<empty>] -> return [Item6] | true |
| System.().Create<T1, T2, T3, T4, T5>(T1, T2, T3, T4, T5) | argument 0 [<empty>] -> return [Item1] | true |
| System.().Create<T1, T2, T3, T4, T5>(T1, T2, T3, T4, T5) | argument 1 [<empty>] -> return [Item2] | true |
| System.().Create<T1, T2, T3, T4, T5>(T1, T2, T3, T4, T5) | argument 2 [<empty>] -> return [Item3] | true |
| System.().Create<T1, T2, T3, T4, T5>(T1, T2, T3, T4, T5) | argument 3 [<empty>] -> return [Item4] | true |
| System.().Create<T1, T2, T3, T4, T5>(T1, T2, T3, T4, T5) | argument 4 [<empty>] -> return [Item5] | true |
| System.().Create<T1, T2, T3, T4>(T1, T2, T3, T4) | argument 0 [<empty>] -> return [Item1] | true |
| System.().Create<T1, T2, T3, T4>(T1, T2, T3, T4) | argument 1 [<empty>] -> return [Item2] | true |
| System.().Create<T1, T2, T3, T4>(T1, T2, T3, T4) | argument 2 [<empty>] -> return [Item3] | true |
| System.().Create<T1, T2, T3, T4>(T1, T2, T3, T4) | argument 3 [<empty>] -> return [Item4] | true |
| System.().Create<T1, T2, T3>(T1, T2, T3) | argument 0 [<empty>] -> return [Item1] | true |
| System.().Create<T1, T2, T3>(T1, T2, T3) | argument 1 [<empty>] -> return [Item2] | true |
| System.().Create<T1, T2, T3>(T1, T2, T3) | argument 2 [<empty>] -> return [Item3] | true |
| System.().Create<T1, T2>(T1, T2) | argument 0 [<empty>] -> return [Item1] | true |
| System.().Create<T1, T2>(T1, T2) | argument 1 [<empty>] -> return [Item2] | true |
| System.().Create<T1>(T1) | argument 0 [<empty>] -> return [Item1] | true |
| System.(T1).ValueTuple(T1) | argument 0 [<empty>] -> return [Item1] | true |
| System.(T1).get_Item(int) | qualifier [Item1] -> return [<empty>] | true |
| System.(T1,T2).ValueTuple(T1, T2) | argument 0 [<empty>] -> return [Item1] | true |
| System.(T1,T2).ValueTuple(T1, T2) | argument 1 [<empty>] -> return [Item2] | true |
| System.(T1,T2).get_Item(int) | qualifier [Item1] -> return [<empty>] | true |
| System.(T1,T2).get_Item(int) | qualifier [Item2] -> return [<empty>] | true |
| System.(T1,T2,T3).ValueTuple(T1, T2, T3) | argument 0 [<empty>] -> return [Item1] | true |
| System.(T1,T2,T3).ValueTuple(T1, T2, T3) | argument 1 [<empty>] -> return [Item2] | true |
| System.(T1,T2,T3).ValueTuple(T1, T2, T3) | argument 2 [<empty>] -> return [Item3] | true |
| System.(T1,T2,T3).get_Item(int) | qualifier [Item1] -> return [<empty>] | true |
| System.(T1,T2,T3).get_Item(int) | qualifier [Item2] -> return [<empty>] | true |
| System.(T1,T2,T3).get_Item(int) | qualifier [Item3] -> return [<empty>] | true |
| System.(T1,T2,T3,T4).ValueTuple(T1, T2, T3, T4) | argument 0 [<empty>] -> return [Item1] | true |
| System.(T1,T2,T3,T4).ValueTuple(T1, T2, T3, T4) | argument 1 [<empty>] -> return [Item2] | true |
| System.(T1,T2,T3,T4).ValueTuple(T1, T2, T3, T4) | argument 2 [<empty>] -> return [Item3] | true |
| System.(T1,T2,T3,T4).ValueTuple(T1, T2, T3, T4) | argument 3 [<empty>] -> return [Item4] | true |
| System.(T1,T2,T3,T4).get_Item(int) | qualifier [Item1] -> return [<empty>] | true |
| System.(T1,T2,T3,T4).get_Item(int) | qualifier [Item2] -> return [<empty>] | true |
| System.(T1,T2,T3,T4).get_Item(int) | qualifier [Item3] -> return [<empty>] | true |
| System.(T1,T2,T3,T4).get_Item(int) | qualifier [Item4] -> return [<empty>] | true |
| System.(T1,T2,T3,T4,T5).ValueTuple(T1, T2, T3, T4, T5) | argument 0 [<empty>] -> return [Item1] | true |
| System.(T1,T2,T3,T4,T5).ValueTuple(T1, T2, T3, T4, T5) | argument 1 [<empty>] -> return [Item2] | true |
| System.(T1,T2,T3,T4,T5).ValueTuple(T1, T2, T3, T4, T5) | argument 2 [<empty>] -> return [Item3] | true |
| System.(T1,T2,T3,T4,T5).ValueTuple(T1, T2, T3, T4, T5) | argument 3 [<empty>] -> return [Item4] | true |
| System.(T1,T2,T3,T4,T5).ValueTuple(T1, T2, T3, T4, T5) | argument 4 [<empty>] -> return [Item5] | true |
| System.(T1,T2,T3,T4,T5).get_Item(int) | qualifier [Item1] -> return [<empty>] | true |
| System.(T1,T2,T3,T4,T5).get_Item(int) | qualifier [Item2] -> return [<empty>] | true |
| System.(T1,T2,T3,T4,T5).get_Item(int) | qualifier [Item3] -> return [<empty>] | true |
| System.(T1,T2,T3,T4,T5).get_Item(int) | qualifier [Item4] -> return [<empty>] | true |
| System.(T1,T2,T3,T4,T5).get_Item(int) | qualifier [Item5] -> return [<empty>] | true |
| System.(T1,T2,T3,T4,T5,T6).ValueTuple(T1, T2, T3, T4, T5, T6) | argument 0 [<empty>] -> return [Item1] | true |
| System.(T1,T2,T3,T4,T5,T6).ValueTuple(T1, T2, T3, T4, T5, T6) | argument 1 [<empty>] -> return [Item2] | true |
| System.(T1,T2,T3,T4,T5,T6).ValueTuple(T1, T2, T3, T4, T5, T6) | argument 2 [<empty>] -> return [Item3] | true |
| System.(T1,T2,T3,T4,T5,T6).ValueTuple(T1, T2, T3, T4, T5, T6) | argument 3 [<empty>] -> return [Item4] | true |
| System.(T1,T2,T3,T4,T5,T6).ValueTuple(T1, T2, T3, T4, T5, T6) | argument 4 [<empty>] -> return [Item5] | true |
| System.(T1,T2,T3,T4,T5,T6).ValueTuple(T1, T2, T3, T4, T5, T6) | argument 5 [<empty>] -> return [Item6] | true |
| System.(T1,T2,T3,T4,T5,T6).get_Item(int) | qualifier [Item1] -> return [<empty>] | true |
| System.(T1,T2,T3,T4,T5,T6).get_Item(int) | qualifier [Item2] -> return [<empty>] | true |
| System.(T1,T2,T3,T4,T5,T6).get_Item(int) | qualifier [Item3] -> return [<empty>] | true |
| System.(T1,T2,T3,T4,T5,T6).get_Item(int) | qualifier [Item4] -> return [<empty>] | true |
| System.(T1,T2,T3,T4,T5,T6).get_Item(int) | qualifier [Item5] -> return [<empty>] | true |
| System.(T1,T2,T3,T4,T5,T6).get_Item(int) | qualifier [Item6] -> return [<empty>] | true |
| System.(T1,T2,T3,T4,T5,T6,T7).ValueTuple(T1, T2, T3, T4, T5, T6, T7) | argument 0 [<empty>] -> return [Item1] | true |
| System.(T1,T2,T3,T4,T5,T6,T7).ValueTuple(T1, T2, T3, T4, T5, T6, T7) | argument 1 [<empty>] -> return [Item2] | true |
| System.(T1,T2,T3,T4,T5,T6,T7).ValueTuple(T1, T2, T3, T4, T5, T6, T7) | argument 2 [<empty>] -> return [Item3] | true |
| System.(T1,T2,T3,T4,T5,T6,T7).ValueTuple(T1, T2, T3, T4, T5, T6, T7) | argument 3 [<empty>] -> return [Item4] | true |
| System.(T1,T2,T3,T4,T5,T6,T7).ValueTuple(T1, T2, T3, T4, T5, T6, T7) | argument 4 [<empty>] -> return [Item5] | true |
| System.(T1,T2,T3,T4,T5,T6,T7).ValueTuple(T1, T2, T3, T4, T5, T6, T7) | argument 5 [<empty>] -> return [Item6] | true |
| System.(T1,T2,T3,T4,T5,T6,T7).ValueTuple(T1, T2, T3, T4, T5, T6, T7) | argument 6 [<empty>] -> return [Item7] | true |
| System.(T1,T2,T3,T4,T5,T6,T7).get_Item(int) | qualifier [Item1] -> return [<empty>] | true |
| System.(T1,T2,T3,T4,T5,T6,T7).get_Item(int) | qualifier [Item2] -> return [<empty>] | true |
| System.(T1,T2,T3,T4,T5,T6,T7).get_Item(int) | qualifier [Item3] -> return [<empty>] | true |
| System.(T1,T2,T3,T4,T5,T6,T7).get_Item(int) | qualifier [Item4] -> return [<empty>] | true |
| System.(T1,T2,T3,T4,T5,T6,T7).get_Item(int) | qualifier [Item5] -> return [<empty>] | true |
| System.(T1,T2,T3,T4,T5,T6,T7).get_Item(int) | qualifier [Item6] -> return [<empty>] | true |
| System.(T1,T2,T3,T4,T5,T6,T7).get_Item(int) | qualifier [Item7] -> return [<empty>] | true |
| System.Array.Add(object) | argument 0 [<empty>] -> qualifier [[]] | true |
| System.Array.AsReadOnly<T>(T[]) | argument 0 [[]] -> return [[]] | true |
| System.Array.Clone() | argument 0 [[]] -> return [[]] | true |
@@ -713,6 +807,8 @@ callableFlowAccessPath
| System.Array.Reverse(Array, int, int) | argument 0 [[]] -> return [[]] | true |
| System.Array.Reverse<T>(T[]) | argument 0 [[]] -> return [[]] | true |
| System.Array.Reverse<T>(T[], int, int) | argument 0 [[]] -> return [[]] | true |
| System.Array.get_Item(int) | qualifier [[]] -> return [<empty>] | true |
| System.Array.set_Item(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Collections.ArrayList.Add(object) | argument 0 [<empty>] -> qualifier [[]] | true |
| System.Collections.ArrayList.AddRange(ICollection) | argument 0 [[]] -> qualifier [[]] | true |
| System.Collections.ArrayList.Clone() | argument 0 [[]] -> return [[]] | true |
@@ -736,6 +832,8 @@ callableFlowAccessPath
| System.Collections.CollectionBase.CopyTo(Array, int) | qualifier [[]] -> argument 0 [[]] | true |
| System.Collections.CollectionBase.GetEnumerator() | qualifier [[]] -> return [Current] | true |
| System.Collections.CollectionBase.Insert(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Collections.CollectionBase.get_Item(int) | qualifier [[]] -> return [<empty>] | true |
| System.Collections.CollectionBase.set_Item(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Collections.Concurrent.BlockingCollection<>.Add(T) | argument 0 [<empty>] -> qualifier [[]] | true |
| System.Collections.Concurrent.BlockingCollection<>.CopyTo(Array, int) | qualifier [[]] -> argument 0 [[]] | true |
| System.Collections.Concurrent.BlockingCollection<>.CopyTo(T[], int) | qualifier [[]] -> argument 0 [[]] | true |
@@ -761,10 +859,13 @@ callableFlowAccessPath
| System.Collections.Concurrent.ConcurrentDictionary<,>.CopyTo(KeyValuePair<TKey,TValue>[], int) | qualifier [[]] -> argument 0 [[]] | true |
| System.Collections.Concurrent.ConcurrentDictionary<,>.GetEnumerator() | qualifier [[]] -> return [Current] | true |
| System.Collections.Concurrent.ConcurrentDictionary<,>.get_Item(TKey) | qualifier [[], Value] -> return [<empty>] | true |
| System.Collections.Concurrent.ConcurrentDictionary<,>.get_Item(object) | qualifier [[], Value] -> return [<empty>] | true |
| System.Collections.Concurrent.ConcurrentDictionary<,>.get_Keys() | qualifier [[], Key] -> return [[]] | true |
| System.Collections.Concurrent.ConcurrentDictionary<,>.get_Values() | qualifier [[], Value] -> return [[]] | true |
| System.Collections.Concurrent.ConcurrentDictionary<,>.set_Item(TKey, TValue) | argument 0 [<empty>] -> qualifier [[], Key] | true |
| System.Collections.Concurrent.ConcurrentDictionary<,>.set_Item(TKey, TValue) | argument 1 [<empty>] -> qualifier [[], Value] | true |
| System.Collections.Concurrent.ConcurrentDictionary<,>.set_Item(object, object) | argument 0 [<empty>] -> qualifier [[], Key] | true |
| System.Collections.Concurrent.ConcurrentDictionary<,>.set_Item(object, object) | argument 1 [<empty>] -> qualifier [[], Value] | true |
| System.Collections.Concurrent.ConcurrentQueue<>.CopyTo(Array, int) | qualifier [[]] -> argument 0 [[]] | true |
| System.Collections.Concurrent.ConcurrentQueue<>.CopyTo(T[], int) | qualifier [[]] -> argument 0 [[]] | true |
| System.Collections.Concurrent.ConcurrentQueue<>.GetEnumerator() | qualifier [[]] -> return [Current] | true |
@@ -776,6 +877,11 @@ callableFlowAccessPath
| System.Collections.DictionaryBase.Add(object, object) | argument 1 [<empty>] -> qualifier [[], Value] | true |
| System.Collections.DictionaryBase.CopyTo(Array, int) | qualifier [[]] -> argument 0 [[]] | true |
| System.Collections.DictionaryBase.GetEnumerator() | qualifier [[]] -> return [Current] | true |
| System.Collections.DictionaryBase.get_Item(object) | qualifier [[], Value] -> return [<empty>] | true |
| System.Collections.DictionaryBase.get_Keys() | qualifier [[], Key] -> return [[]] | true |
| System.Collections.DictionaryBase.get_Values() | qualifier [[], Value] -> return [[]] | true |
| System.Collections.DictionaryBase.set_Item(object, object) | argument 0 [<empty>] -> qualifier [[], Key] | true |
| System.Collections.DictionaryBase.set_Item(object, object) | argument 1 [<empty>] -> qualifier [[], Value] | true |
| System.Collections.Generic.Dictionary<,>.Add(KeyValuePair<TKey, TValue>) | argument 0 [<empty>] -> qualifier [[]] | true |
| System.Collections.Generic.Dictionary<,>.Add(KeyValuePair<TKey, TValue>) | argument 0 [Key] -> qualifier [[], Key] | true |
| System.Collections.Generic.Dictionary<,>.Add(KeyValuePair<TKey, TValue>) | argument 0 [Value] -> qualifier [[], Value] | true |
@@ -803,10 +909,13 @@ callableFlowAccessPath
| System.Collections.Generic.Dictionary<,>.ValueCollection.CopyTo(TValue[], int) | qualifier [[]] -> argument 0 [[]] | true |
| System.Collections.Generic.Dictionary<,>.ValueCollection.GetEnumerator() | qualifier [[]] -> return [Current] | true |
| System.Collections.Generic.Dictionary<,>.get_Item(TKey) | qualifier [[], Value] -> return [<empty>] | true |
| System.Collections.Generic.Dictionary<,>.get_Item(object) | qualifier [[], Value] -> return [<empty>] | true |
| System.Collections.Generic.Dictionary<,>.get_Keys() | qualifier [[], Key] -> return [[]] | true |
| System.Collections.Generic.Dictionary<,>.get_Values() | qualifier [[], Value] -> return [[]] | true |
| System.Collections.Generic.Dictionary<,>.set_Item(TKey, TValue) | argument 0 [<empty>] -> qualifier [[], Key] | true |
| System.Collections.Generic.Dictionary<,>.set_Item(TKey, TValue) | argument 1 [<empty>] -> qualifier [[], Value] | true |
| System.Collections.Generic.Dictionary<,>.set_Item(object, object) | argument 0 [<empty>] -> qualifier [[], Key] | true |
| System.Collections.Generic.Dictionary<,>.set_Item(object, object) | argument 1 [<empty>] -> qualifier [[], Value] | true |
| System.Collections.Generic.HashSet<>.Add(T) | argument 0 [<empty>] -> qualifier [[]] | true |
| System.Collections.Generic.HashSet<>.CopyTo(T[], int) | qualifier [[]] -> argument 0 [[]] | true |
| System.Collections.Generic.HashSet<>.GetEnumerator() | qualifier [[]] -> return [Current] | true |
@@ -854,6 +963,7 @@ callableFlowAccessPath
| System.Collections.Generic.List<>.Reverse(int, int) | argument 0 [[]] -> return [[]] | true |
| System.Collections.Generic.List<>.get_Item(int) | qualifier [[]] -> return [<empty>] | true |
| System.Collections.Generic.List<>.set_Item(int, T) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Collections.Generic.List<>.set_Item(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Collections.Generic.Queue<>.CopyTo(Array, int) | qualifier [[]] -> argument 0 [[]] | true |
| System.Collections.Generic.Queue<>.CopyTo(T[], int) | qualifier [[]] -> argument 0 [[]] | true |
| System.Collections.Generic.Queue<>.GetEnumerator() | qualifier [[]] -> return [Current] | true |
@@ -881,10 +991,13 @@ callableFlowAccessPath
| System.Collections.Generic.SortedDictionary<,>.ValueCollection.CopyTo(TValue[], int) | qualifier [[]] -> argument 0 [[]] | true |
| System.Collections.Generic.SortedDictionary<,>.ValueCollection.GetEnumerator() | qualifier [[]] -> return [Current] | true |
| System.Collections.Generic.SortedDictionary<,>.get_Item(TKey) | qualifier [[], Value] -> return [<empty>] | true |
| System.Collections.Generic.SortedDictionary<,>.get_Item(object) | qualifier [[], Value] -> return [<empty>] | true |
| System.Collections.Generic.SortedDictionary<,>.get_Keys() | qualifier [[], Key] -> return [[]] | true |
| System.Collections.Generic.SortedDictionary<,>.get_Values() | qualifier [[], Value] -> return [[]] | true |
| System.Collections.Generic.SortedDictionary<,>.set_Item(TKey, TValue) | argument 0 [<empty>] -> qualifier [[], Key] | true |
| System.Collections.Generic.SortedDictionary<,>.set_Item(TKey, TValue) | argument 1 [<empty>] -> qualifier [[], Value] | true |
| System.Collections.Generic.SortedDictionary<,>.set_Item(object, object) | argument 0 [<empty>] -> qualifier [[], Key] | true |
| System.Collections.Generic.SortedDictionary<,>.set_Item(object, object) | argument 1 [<empty>] -> qualifier [[], Value] | true |
| System.Collections.Generic.SortedList<,>.Add(KeyValuePair<TKey, TValue>) | argument 0 [<empty>] -> qualifier [[]] | true |
| System.Collections.Generic.SortedList<,>.Add(KeyValuePair<TKey, TValue>) | argument 0 [Key] -> qualifier [[], Key] | true |
| System.Collections.Generic.SortedList<,>.Add(KeyValuePair<TKey, TValue>) | argument 0 [Value] -> qualifier [[], Value] | true |
@@ -914,10 +1027,13 @@ callableFlowAccessPath
| System.Collections.Generic.SortedList<,>.ValueList.get_Item(int) | qualifier [[]] -> return [<empty>] | true |
| System.Collections.Generic.SortedList<,>.ValueList.set_Item(int, TValue) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Collections.Generic.SortedList<,>.get_Item(TKey) | qualifier [[], Value] -> return [<empty>] | true |
| System.Collections.Generic.SortedList<,>.get_Item(object) | qualifier [[], Value] -> return [<empty>] | true |
| System.Collections.Generic.SortedList<,>.get_Keys() | qualifier [[], Key] -> return [[]] | true |
| System.Collections.Generic.SortedList<,>.get_Values() | qualifier [[], Value] -> return [[]] | true |
| System.Collections.Generic.SortedList<,>.set_Item(TKey, TValue) | argument 0 [<empty>] -> qualifier [[], Key] | true |
| System.Collections.Generic.SortedList<,>.set_Item(TKey, TValue) | argument 1 [<empty>] -> qualifier [[], Value] | true |
| System.Collections.Generic.SortedList<,>.set_Item(object, object) | argument 0 [<empty>] -> qualifier [[], Key] | true |
| System.Collections.Generic.SortedList<,>.set_Item(object, object) | argument 1 [<empty>] -> qualifier [[], Value] | true |
| System.Collections.Generic.SortedSet<>.Add(T) | argument 0 [<empty>] -> qualifier [[]] | true |
| System.Collections.Generic.SortedSet<>.CopyTo(Array, int) | qualifier [[]] -> argument 0 [[]] | true |
| System.Collections.Generic.SortedSet<>.CopyTo(T[], int) | qualifier [[]] -> argument 0 [[]] | true |
@@ -981,6 +1097,7 @@ callableFlowAccessPath
| System.Collections.ObjectModel.Collection<>.Insert(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Collections.ObjectModel.Collection<>.get_Item(int) | qualifier [[]] -> return [<empty>] | true |
| System.Collections.ObjectModel.Collection<>.set_Item(int, T) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Collections.ObjectModel.Collection<>.set_Item(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Collections.ObjectModel.KeyedCollection<,>.get_Item(TKey) | qualifier [[]] -> return [<empty>] | true |
| System.Collections.ObjectModel.ReadOnlyCollection<>.Add(T) | argument 0 [<empty>] -> qualifier [[]] | true |
| System.Collections.ObjectModel.ReadOnlyCollection<>.Add(object) | argument 0 [<empty>] -> qualifier [[]] | true |
@@ -990,6 +1107,8 @@ callableFlowAccessPath
| System.Collections.ObjectModel.ReadOnlyCollection<>.Insert(int, T) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Collections.ObjectModel.ReadOnlyCollection<>.Insert(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Collections.ObjectModel.ReadOnlyCollection<>.get_Item(int) | qualifier [[]] -> return [<empty>] | true |
| System.Collections.ObjectModel.ReadOnlyCollection<>.set_Item(int, T) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Collections.ObjectModel.ReadOnlyCollection<>.set_Item(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Collections.ObjectModel.ReadOnlyDictionary<,>.Add(KeyValuePair<TKey, TValue>) | argument 0 [<empty>] -> qualifier [[]] | true |
| System.Collections.ObjectModel.ReadOnlyDictionary<,>.Add(KeyValuePair<TKey, TValue>) | argument 0 [Key] -> qualifier [[], Key] | true |
| System.Collections.ObjectModel.ReadOnlyDictionary<,>.Add(KeyValuePair<TKey, TValue>) | argument 0 [Value] -> qualifier [[], Value] | true |
@@ -1011,8 +1130,13 @@ callableFlowAccessPath
| System.Collections.ObjectModel.ReadOnlyDictionary<,>.ValueCollection.CopyTo(TValue[], int) | qualifier [[]] -> argument 0 [[]] | true |
| System.Collections.ObjectModel.ReadOnlyDictionary<,>.ValueCollection.GetEnumerator() | qualifier [[]] -> return [Current] | true |
| System.Collections.ObjectModel.ReadOnlyDictionary<,>.get_Item(TKey) | qualifier [[], Value] -> return [<empty>] | true |
| System.Collections.ObjectModel.ReadOnlyDictionary<,>.get_Item(object) | qualifier [[], Value] -> return [<empty>] | true |
| System.Collections.ObjectModel.ReadOnlyDictionary<,>.get_Keys() | qualifier [[], Key] -> return [[]] | true |
| System.Collections.ObjectModel.ReadOnlyDictionary<,>.get_Values() | qualifier [[], Value] -> return [[]] | true |
| System.Collections.ObjectModel.ReadOnlyDictionary<,>.set_Item(TKey, TValue) | argument 0 [<empty>] -> qualifier [[], Key] | true |
| System.Collections.ObjectModel.ReadOnlyDictionary<,>.set_Item(TKey, TValue) | argument 1 [<empty>] -> qualifier [[], Value] | true |
| System.Collections.ObjectModel.ReadOnlyDictionary<,>.set_Item(object, object) | argument 0 [<empty>] -> qualifier [[], Key] | true |
| System.Collections.ObjectModel.ReadOnlyDictionary<,>.set_Item(object, object) | argument 1 [<empty>] -> qualifier [[], Value] | true |
| System.Collections.Queue.Clone() | argument 0 [[]] -> return [[]] | true |
| System.Collections.Queue.CopyTo(Array, int) | qualifier [[]] -> argument 0 [[]] | true |
| System.Collections.Queue.GetEnumerator() | qualifier [[]] -> return [Current] | true |
@@ -1084,6 +1208,7 @@ callableFlowAccessPath
| System.Collections.Specialized.StringCollection.Insert(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Collections.Specialized.StringCollection.Insert(int, string) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Collections.Specialized.StringCollection.get_Item(int) | qualifier [[]] -> return [<empty>] | true |
| System.Collections.Specialized.StringCollection.set_Item(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Collections.Specialized.StringCollection.set_Item(int, string) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Collections.Specialized.StringDictionary.GetEnumerator() | qualifier [[]] -> return [Current] | true |
| System.Collections.Stack.Clone() | argument 0 [[]] -> return [[]] | true |
@@ -1102,6 +1227,7 @@ callableFlowAccessPath
| System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection.Insert(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection.get_Item(int) | qualifier [[]] -> return [<empty>] | true |
| System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection.get_Item(string) | qualifier [[]] -> return [<empty>] | true |
| System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection.set_Item(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.ComponentModel.Design.DesignerVerbCollection.Add(DesignerVerb) | argument 0 [<empty>] -> qualifier [[]] | true |
| System.ComponentModel.Design.DesignerVerbCollection.AddRange(DesignerVerbCollection) | argument 0 [[]] -> qualifier [[]] | true |
| System.ComponentModel.Design.DesignerVerbCollection.AddRange(DesignerVerb[]) | argument 0 [[]] -> qualifier [[]] | true |
@@ -1118,6 +1244,7 @@ callableFlowAccessPath
| System.ComponentModel.EventDescriptorCollection.Insert(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.ComponentModel.EventDescriptorCollection.get_Item(int) | qualifier [[]] -> return [<empty>] | true |
| System.ComponentModel.EventDescriptorCollection.get_Item(string) | qualifier [[]] -> return [<empty>] | true |
| System.ComponentModel.EventDescriptorCollection.set_Item(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.ComponentModel.IBindingList.Find(PropertyDescriptor, object) | qualifier [[]] -> return [<empty>] | true |
| System.ComponentModel.ListSortDescriptionCollection.Add(object) | argument 0 [<empty>] -> qualifier [[]] | true |
| System.ComponentModel.ListSortDescriptionCollection.CopyTo(Array, int) | qualifier [[]] -> argument 0 [[]] | true |
@@ -1125,6 +1252,7 @@ callableFlowAccessPath
| System.ComponentModel.ListSortDescriptionCollection.Insert(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.ComponentModel.ListSortDescriptionCollection.get_Item(int) | qualifier [[]] -> return [<empty>] | true |
| System.ComponentModel.ListSortDescriptionCollection.set_Item(int, ListSortDescription) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.ComponentModel.ListSortDescriptionCollection.set_Item(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.ComponentModel.PropertyDescriptorCollection.Add(PropertyDescriptor) | argument 0 [<empty>] -> qualifier [[]] | true |
| System.ComponentModel.PropertyDescriptorCollection.Add(PropertyDescriptor) | argument 0 [Key] -> qualifier [[], Key] | true |
| System.ComponentModel.PropertyDescriptorCollection.Add(PropertyDescriptor) | argument 0 [Value] -> qualifier [[], Value] | true |
@@ -1144,8 +1272,18 @@ callableFlowAccessPath
| System.ComponentModel.PropertyDescriptorCollection.PropertyDescriptorCollection(PropertyDescriptor[], bool) | argument 0 [[], Value] -> return [[], Value] | true |
| System.ComponentModel.PropertyDescriptorCollection.get_Item(int) | qualifier [[], Value] -> return [<empty>] | true |
| System.ComponentModel.PropertyDescriptorCollection.get_Item(int) | qualifier [[]] -> return [<empty>] | true |
| System.ComponentModel.PropertyDescriptorCollection.get_Item(object) | qualifier [[], Value] -> return [<empty>] | true |
| System.ComponentModel.PropertyDescriptorCollection.get_Item(object) | qualifier [[]] -> return [<empty>] | true |
| System.ComponentModel.PropertyDescriptorCollection.get_Item(string) | qualifier [[], Value] -> return [<empty>] | true |
| System.ComponentModel.PropertyDescriptorCollection.get_Item(string) | qualifier [[]] -> return [<empty>] | true |
| System.ComponentModel.PropertyDescriptorCollection.get_Keys() | qualifier [[], Key] -> return [[]] | true |
| System.ComponentModel.PropertyDescriptorCollection.get_Values() | qualifier [[], Value] -> return [[]] | true |
| System.ComponentModel.PropertyDescriptorCollection.set_Item(int, object) | argument 0 [<empty>] -> qualifier [[], Key] | true |
| System.ComponentModel.PropertyDescriptorCollection.set_Item(int, object) | argument 1 [<empty>] -> qualifier [[], Value] | true |
| System.ComponentModel.PropertyDescriptorCollection.set_Item(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.ComponentModel.PropertyDescriptorCollection.set_Item(object, object) | argument 0 [<empty>] -> qualifier [[], Key] | true |
| System.ComponentModel.PropertyDescriptorCollection.set_Item(object, object) | argument 1 [<empty>] -> qualifier [[], Value] | true |
| System.ComponentModel.PropertyDescriptorCollection.set_Item(object, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.ComponentModel.TypeConverter.StandardValuesCollection.CopyTo(Array, int) | qualifier [[]] -> argument 0 [[]] | true |
| System.ComponentModel.TypeConverter.StandardValuesCollection.GetEnumerator() | qualifier [[]] -> return [Current] | true |
| System.Dynamic.ExpandoObject.Add(KeyValuePair<String, Object>) | argument 0 [<empty>] -> qualifier [[]] | true |
@@ -1155,6 +1293,11 @@ callableFlowAccessPath
| System.Dynamic.ExpandoObject.Add(string, object) | argument 1 [<empty>] -> qualifier [[], Value] | true |
| System.Dynamic.ExpandoObject.CopyTo(KeyValuePair<String,Object>[], int) | qualifier [[]] -> argument 0 [[]] | true |
| System.Dynamic.ExpandoObject.GetEnumerator() | qualifier [[]] -> return [Current] | true |
| System.Dynamic.ExpandoObject.get_Item(string) | qualifier [[], Value] -> return [<empty>] | true |
| System.Dynamic.ExpandoObject.get_Keys() | qualifier [[], Key] -> return [[]] | true |
| System.Dynamic.ExpandoObject.get_Values() | qualifier [[], Value] -> return [[]] | true |
| System.Dynamic.ExpandoObject.set_Item(string, object) | argument 0 [<empty>] -> qualifier [[], Key] | true |
| System.Dynamic.ExpandoObject.set_Item(string, object) | argument 1 [<empty>] -> qualifier [[], Value] | true |
| System.IO.Path.Combine(params String[]) | argument 0 [[]] -> return [<empty>] | false |
| System.Lazy<>.Lazy(Func<T>) | output from argument 0 [<empty>] -> return [Value] | true |
| System.Lazy<>.Lazy(Func<T>, LazyThreadSafetyMode) | output from argument 0 [<empty>] -> return [Value] | true |
@@ -1363,6 +1506,8 @@ callableFlowAccessPath
| System.Linq.Grouping<,>.CopyTo(TElement[], int) | qualifier [[]] -> argument 0 [[]] | true |
| System.Linq.Grouping<,>.GetEnumerator() | qualifier [[]] -> return [Current] | true |
| System.Linq.Grouping<,>.Insert(int, TElement) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Linq.Grouping<,>.get_Item(int) | qualifier [[]] -> return [<empty>] | true |
| System.Linq.Grouping<,>.set_Item(int, TElement) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Linq.Lookup<,>.GetEnumerator() | qualifier [[]] -> return [Current] | true |
| System.Linq.ParallelEnumerable.Aggregate<TSource, TAccumulate, TResult>(ParallelQuery<TSource>, TAccumulate, Func<TAccumulate, TSource, TAccumulate>, Func<TAccumulate, TResult>) | argument 0 [[]] -> parameter 1 of argument 2 [<empty>] | true |
| System.Linq.ParallelEnumerable.Aggregate<TSource, TAccumulate>(ParallelQuery<TSource>, TAccumulate, Func<TAccumulate, TSource, TAccumulate>) | argument 0 [[]] -> parameter 1 of argument 2 [<empty>] | true |
@@ -1787,6 +1932,7 @@ callableFlowAccessPath
| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.Reverse(int, int) | argument 0 [[]] -> return [[]] | true |
| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.get_Item(int) | qualifier [[]] -> return [<empty>] | true |
| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.set_Item(int, T) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Runtime.CompilerServices.ReadOnlyCollectionBuilder<>.set_Item(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Runtime.CompilerServices.TaskAwaiter<>.GetResult() | qualifier [m_task, Result] -> return [<empty>] | true |
| System.Security.PermissionSet.CopyTo(Array, int) | qualifier [[]] -> argument 0 [[]] | true |
| System.Security.PermissionSet.GetEnumerator() | qualifier [[]] -> return [Current] | true |
@@ -1826,6 +1972,7 @@ callableFlowAccessPath
| System.Text.Encoding.GetChars(Byte[], int, int, Char[], int) | argument 0 [[]] -> return [<empty>] | false |
| System.Text.Encoding.GetChars(ReadOnlySpan<Byte>, Span<Char>) | argument 0 [[]] -> return [<empty>] | false |
| System.Text.Encoding.GetChars(byte*, int, char*, int) | argument 0 [[]] -> return [<empty>] | false |
| System.Text.Encoding.GetChars(byte*, int, char*, int, DecoderNLS) | argument 0 [[]] -> return [<empty>] | false |
| System.Text.Encoding.GetString(Byte[]) | argument 0 [[]] -> return [<empty>] | false |
| System.Text.Encoding.GetString(Byte[], int, int) | argument 0 [[]] -> return [<empty>] | false |
| System.Text.Encoding.GetString(ReadOnlySpan<Byte>) | argument 0 [[]] -> return [<empty>] | false |
@@ -1838,6 +1985,8 @@ callableFlowAccessPath
| System.Text.RegularExpressions.CaptureCollection.Insert(int, Capture) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Text.RegularExpressions.CaptureCollection.Insert(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Text.RegularExpressions.CaptureCollection.get_Item(int) | qualifier [[]] -> return [<empty>] | true |
| System.Text.RegularExpressions.CaptureCollection.set_Item(int, Capture) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Text.RegularExpressions.CaptureCollection.set_Item(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Text.RegularExpressions.GroupCollection.Add(Group) | argument 0 [<empty>] -> qualifier [[]] | true |
| System.Text.RegularExpressions.GroupCollection.Add(object) | argument 0 [<empty>] -> qualifier [[]] | true |
| System.Text.RegularExpressions.GroupCollection.CopyTo(Array, int) | qualifier [[]] -> argument 0 [[]] | true |
@@ -1847,6 +1996,8 @@ callableFlowAccessPath
| System.Text.RegularExpressions.GroupCollection.Insert(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Text.RegularExpressions.GroupCollection.get_Item(int) | qualifier [[]] -> return [<empty>] | true |
| System.Text.RegularExpressions.GroupCollection.get_Item(string) | qualifier [[]] -> return [<empty>] | true |
| System.Text.RegularExpressions.GroupCollection.set_Item(int, Group) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Text.RegularExpressions.GroupCollection.set_Item(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Text.RegularExpressions.MatchCollection.Add(Match) | argument 0 [<empty>] -> qualifier [[]] | true |
| System.Text.RegularExpressions.MatchCollection.Add(object) | argument 0 [<empty>] -> qualifier [[]] | true |
| System.Text.RegularExpressions.MatchCollection.CopyTo(Array, int) | qualifier [[]] -> argument 0 [[]] | true |
@@ -1855,6 +2006,8 @@ callableFlowAccessPath
| System.Text.RegularExpressions.MatchCollection.Insert(int, Match) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Text.RegularExpressions.MatchCollection.Insert(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Text.RegularExpressions.MatchCollection.get_Item(int) | qualifier [[]] -> return [<empty>] | true |
| System.Text.RegularExpressions.MatchCollection.set_Item(int, Match) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Text.RegularExpressions.MatchCollection.set_Item(int, object) | argument 1 [<empty>] -> qualifier [[]] | true |
| System.Text.StringBuilder.Append(object) | argument 0 [<empty>] -> qualifier [[]] | true |
| System.Text.StringBuilder.Append(object) | argument 0 [<empty>] -> return [[]] | true |
| System.Text.StringBuilder.Append(string) | argument 0 [<empty>] -> qualifier [[]] | true |
@@ -1994,6 +2147,251 @@ callableFlowAccessPath
| System.Threading.Tasks.TaskFactory<>.StartNew(Func<TResult>, CancellationToken) | output from argument 0 [<empty>] -> return [Result] | true |
| System.Threading.Tasks.TaskFactory<>.StartNew(Func<TResult>, CancellationToken, TaskCreationOptions, TaskScheduler) | output from argument 0 [<empty>] -> return [Result] | true |
| System.Threading.Tasks.TaskFactory<>.StartNew(Func<TResult>, TaskCreationOptions) | output from argument 0 [<empty>] -> return [Result] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1, T2, T3, T4, T5, T6, T7, T8) | argument 0 [<empty>] -> return [Item1] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1, T2, T3, T4, T5, T6, T7, T8) | argument 1 [<empty>] -> return [Item2] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1, T2, T3, T4, T5, T6, T7, T8) | argument 2 [<empty>] -> return [Item3] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1, T2, T3, T4, T5, T6, T7, T8) | argument 3 [<empty>] -> return [Item4] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1, T2, T3, T4, T5, T6, T7, T8) | argument 4 [<empty>] -> return [Item5] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1, T2, T3, T4, T5, T6, T7, T8) | argument 5 [<empty>] -> return [Item6] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1, T2, T3, T4, T5, T6, T7, T8) | argument 6 [<empty>] -> return [Item7] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5, T6, T7>(T1, T2, T3, T4, T5, T6, T7) | argument 0 [<empty>] -> return [Item1] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5, T6, T7>(T1, T2, T3, T4, T5, T6, T7) | argument 1 [<empty>] -> return [Item2] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5, T6, T7>(T1, T2, T3, T4, T5, T6, T7) | argument 2 [<empty>] -> return [Item3] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5, T6, T7>(T1, T2, T3, T4, T5, T6, T7) | argument 3 [<empty>] -> return [Item4] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5, T6, T7>(T1, T2, T3, T4, T5, T6, T7) | argument 4 [<empty>] -> return [Item5] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5, T6, T7>(T1, T2, T3, T4, T5, T6, T7) | argument 5 [<empty>] -> return [Item6] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5, T6, T7>(T1, T2, T3, T4, T5, T6, T7) | argument 6 [<empty>] -> return [Item7] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5, T6>(T1, T2, T3, T4, T5, T6) | argument 0 [<empty>] -> return [Item1] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5, T6>(T1, T2, T3, T4, T5, T6) | argument 1 [<empty>] -> return [Item2] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5, T6>(T1, T2, T3, T4, T5, T6) | argument 2 [<empty>] -> return [Item3] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5, T6>(T1, T2, T3, T4, T5, T6) | argument 3 [<empty>] -> return [Item4] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5, T6>(T1, T2, T3, T4, T5, T6) | argument 4 [<empty>] -> return [Item5] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5, T6>(T1, T2, T3, T4, T5, T6) | argument 5 [<empty>] -> return [Item6] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5>(T1, T2, T3, T4, T5) | argument 0 [<empty>] -> return [Item1] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5>(T1, T2, T3, T4, T5) | argument 1 [<empty>] -> return [Item2] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5>(T1, T2, T3, T4, T5) | argument 2 [<empty>] -> return [Item3] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5>(T1, T2, T3, T4, T5) | argument 3 [<empty>] -> return [Item4] | true |
| System.Tuple.Create<T1, T2, T3, T4, T5>(T1, T2, T3, T4, T5) | argument 4 [<empty>] -> return [Item5] | true |
| System.Tuple.Create<T1, T2, T3, T4>(T1, T2, T3, T4) | argument 0 [<empty>] -> return [Item1] | true |
| System.Tuple.Create<T1, T2, T3, T4>(T1, T2, T3, T4) | argument 1 [<empty>] -> return [Item2] | true |
| System.Tuple.Create<T1, T2, T3, T4>(T1, T2, T3, T4) | argument 2 [<empty>] -> return [Item3] | true |
| System.Tuple.Create<T1, T2, T3, T4>(T1, T2, T3, T4) | argument 3 [<empty>] -> return [Item4] | true |
| System.Tuple.Create<T1, T2, T3>(T1, T2, T3) | argument 0 [<empty>] -> return [Item1] | true |
| System.Tuple.Create<T1, T2, T3>(T1, T2, T3) | argument 1 [<empty>] -> return [Item2] | true |
| System.Tuple.Create<T1, T2, T3>(T1, T2, T3) | argument 2 [<empty>] -> return [Item3] | true |
| System.Tuple.Create<T1, T2>(T1, T2) | argument 0 [<empty>] -> return [Item1] | true |
| System.Tuple.Create<T1, T2>(T1, T2) | argument 1 [<empty>] -> return [Item2] | true |
| System.Tuple.Create<T1>(T1) | argument 0 [<empty>] -> return [Item1] | true |
| System.Tuple<,,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 0 [<empty>] -> return [Item1] | true |
| System.Tuple<,,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 1 [<empty>] -> return [Item2] | true |
| System.Tuple<,,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 2 [<empty>] -> return [Item3] | true |
| System.Tuple<,,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 3 [<empty>] -> return [Item4] | true |
| System.Tuple<,,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 4 [<empty>] -> return [Item5] | true |
| System.Tuple<,,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 5 [<empty>] -> return [Item6] | true |
| System.Tuple<,,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 6 [<empty>] -> return [Item7] | true |
| System.Tuple<,,,,,,,>.get_Item(int) | qualifier [Item1] -> return [<empty>] | true |
| System.Tuple<,,,,,,,>.get_Item(int) | qualifier [Item2] -> return [<empty>] | true |
| System.Tuple<,,,,,,,>.get_Item(int) | qualifier [Item3] -> return [<empty>] | true |
| System.Tuple<,,,,,,,>.get_Item(int) | qualifier [Item4] -> return [<empty>] | true |
| System.Tuple<,,,,,,,>.get_Item(int) | qualifier [Item5] -> return [<empty>] | true |
| System.Tuple<,,,,,,,>.get_Item(int) | qualifier [Item6] -> return [<empty>] | true |
| System.Tuple<,,,,,,,>.get_Item(int) | qualifier [Item7] -> return [<empty>] | true |
| System.Tuple<,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7) | argument 0 [<empty>] -> return [Item1] | true |
| System.Tuple<,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7) | argument 1 [<empty>] -> return [Item2] | true |
| System.Tuple<,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7) | argument 2 [<empty>] -> return [Item3] | true |
| System.Tuple<,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7) | argument 3 [<empty>] -> return [Item4] | true |
| System.Tuple<,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7) | argument 4 [<empty>] -> return [Item5] | true |
| System.Tuple<,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7) | argument 5 [<empty>] -> return [Item6] | true |
| System.Tuple<,,,,,,>.Tuple(T1, T2, T3, T4, T5, T6, T7) | argument 6 [<empty>] -> return [Item7] | true |
| System.Tuple<,,,,,,>.get_Item(int) | qualifier [Item1] -> return [<empty>] | true |
| System.Tuple<,,,,,,>.get_Item(int) | qualifier [Item2] -> return [<empty>] | true |
| System.Tuple<,,,,,,>.get_Item(int) | qualifier [Item3] -> return [<empty>] | true |
| System.Tuple<,,,,,,>.get_Item(int) | qualifier [Item4] -> return [<empty>] | true |
| System.Tuple<,,,,,,>.get_Item(int) | qualifier [Item5] -> return [<empty>] | true |
| System.Tuple<,,,,,,>.get_Item(int) | qualifier [Item6] -> return [<empty>] | true |
| System.Tuple<,,,,,,>.get_Item(int) | qualifier [Item7] -> return [<empty>] | true |
| System.Tuple<,,,,,>.Tuple(T1, T2, T3, T4, T5, T6) | argument 0 [<empty>] -> return [Item1] | true |
| System.Tuple<,,,,,>.Tuple(T1, T2, T3, T4, T5, T6) | argument 1 [<empty>] -> return [Item2] | true |
| System.Tuple<,,,,,>.Tuple(T1, T2, T3, T4, T5, T6) | argument 2 [<empty>] -> return [Item3] | true |
| System.Tuple<,,,,,>.Tuple(T1, T2, T3, T4, T5, T6) | argument 3 [<empty>] -> return [Item4] | true |
| System.Tuple<,,,,,>.Tuple(T1, T2, T3, T4, T5, T6) | argument 4 [<empty>] -> return [Item5] | true |
| System.Tuple<,,,,,>.Tuple(T1, T2, T3, T4, T5, T6) | argument 5 [<empty>] -> return [Item6] | true |
| System.Tuple<,,,,,>.get_Item(int) | qualifier [Item1] -> return [<empty>] | true |
| System.Tuple<,,,,,>.get_Item(int) | qualifier [Item2] -> return [<empty>] | true |
| System.Tuple<,,,,,>.get_Item(int) | qualifier [Item3] -> return [<empty>] | true |
| System.Tuple<,,,,,>.get_Item(int) | qualifier [Item4] -> return [<empty>] | true |
| System.Tuple<,,,,,>.get_Item(int) | qualifier [Item5] -> return [<empty>] | true |
| System.Tuple<,,,,,>.get_Item(int) | qualifier [Item6] -> return [<empty>] | true |
| System.Tuple<,,,,>.Tuple(T1, T2, T3, T4, T5) | argument 0 [<empty>] -> return [Item1] | true |
| System.Tuple<,,,,>.Tuple(T1, T2, T3, T4, T5) | argument 1 [<empty>] -> return [Item2] | true |
| System.Tuple<,,,,>.Tuple(T1, T2, T3, T4, T5) | argument 2 [<empty>] -> return [Item3] | true |
| System.Tuple<,,,,>.Tuple(T1, T2, T3, T4, T5) | argument 3 [<empty>] -> return [Item4] | true |
| System.Tuple<,,,,>.Tuple(T1, T2, T3, T4, T5) | argument 4 [<empty>] -> return [Item5] | true |
| System.Tuple<,,,,>.get_Item(int) | qualifier [Item1] -> return [<empty>] | true |
| System.Tuple<,,,,>.get_Item(int) | qualifier [Item2] -> return [<empty>] | true |
| System.Tuple<,,,,>.get_Item(int) | qualifier [Item3] -> return [<empty>] | true |
| System.Tuple<,,,,>.get_Item(int) | qualifier [Item4] -> return [<empty>] | true |
| System.Tuple<,,,,>.get_Item(int) | qualifier [Item5] -> return [<empty>] | true |
| System.Tuple<,,,>.Tuple(T1, T2, T3, T4) | argument 0 [<empty>] -> return [Item1] | true |
| System.Tuple<,,,>.Tuple(T1, T2, T3, T4) | argument 1 [<empty>] -> return [Item2] | true |
| System.Tuple<,,,>.Tuple(T1, T2, T3, T4) | argument 2 [<empty>] -> return [Item3] | true |
| System.Tuple<,,,>.Tuple(T1, T2, T3, T4) | argument 3 [<empty>] -> return [Item4] | true |
| System.Tuple<,,,>.get_Item(int) | qualifier [Item1] -> return [<empty>] | true |
| System.Tuple<,,,>.get_Item(int) | qualifier [Item2] -> return [<empty>] | true |
| System.Tuple<,,,>.get_Item(int) | qualifier [Item3] -> return [<empty>] | true |
| System.Tuple<,,,>.get_Item(int) | qualifier [Item4] -> return [<empty>] | true |
| System.Tuple<,,>.Tuple(T1, T2, T3) | argument 0 [<empty>] -> return [Item1] | true |
| System.Tuple<,,>.Tuple(T1, T2, T3) | argument 1 [<empty>] -> return [Item2] | true |
| System.Tuple<,,>.Tuple(T1, T2, T3) | argument 2 [<empty>] -> return [Item3] | true |
| System.Tuple<,,>.get_Item(int) | qualifier [Item1] -> return [<empty>] | true |
| System.Tuple<,,>.get_Item(int) | qualifier [Item2] -> return [<empty>] | true |
| System.Tuple<,,>.get_Item(int) | qualifier [Item3] -> return [<empty>] | true |
| System.Tuple<,>.Tuple(T1, T2) | argument 0 [<empty>] -> return [Item1] | true |
| System.Tuple<,>.Tuple(T1, T2) | argument 1 [<empty>] -> return [Item2] | true |
| System.Tuple<,>.get_Item(int) | qualifier [Item1] -> return [<empty>] | true |
| System.Tuple<,>.get_Item(int) | qualifier [Item2] -> return [<empty>] | true |
| System.Tuple<>.Tuple(T1) | argument 0 [<empty>] -> return [Item1] | true |
| System.Tuple<>.get_Item(int) | qualifier [Item1] -> return [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18,T19,T20,T21>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20, out T21) | argument 0 [Item1] -> argument 1 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18,T19,T20,T21>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20, out T21) | argument 0 [Item2] -> argument 2 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18,T19,T20,T21>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20, out T21) | argument 0 [Item3] -> argument 3 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18,T19,T20,T21>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20, out T21) | argument 0 [Item4] -> argument 4 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18,T19,T20,T21>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20, out T21) | argument 0 [Item5] -> argument 5 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18,T19,T20,T21>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20, out T21) | argument 0 [Item6] -> argument 6 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18,T19,T20,T21>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20, out T21) | argument 0 [Item7] -> argument 7 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18,T19,T20>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20) | argument 0 [Item1] -> argument 1 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18,T19,T20>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20) | argument 0 [Item2] -> argument 2 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18,T19,T20>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20) | argument 0 [Item3] -> argument 3 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18,T19,T20>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20) | argument 0 [Item4] -> argument 4 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18,T19,T20>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20) | argument 0 [Item5] -> argument 5 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18,T19,T20>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20) | argument 0 [Item6] -> argument 6 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18,T19,T20>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19, out T20) | argument 0 [Item7] -> argument 7 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18,T19>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19) | argument 0 [Item1] -> argument 1 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18,T19>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19) | argument 0 [Item2] -> argument 2 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18,T19>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19) | argument 0 [Item3] -> argument 3 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18,T19>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19) | argument 0 [Item4] -> argument 4 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18,T19>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19) | argument 0 [Item5] -> argument 5 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18,T19>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19) | argument 0 [Item6] -> argument 6 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18,T19>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18, out T19) | argument 0 [Item7] -> argument 7 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18) | argument 0 [Item1] -> argument 1 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18) | argument 0 [Item2] -> argument 2 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18) | argument 0 [Item3] -> argument 3 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18) | argument 0 [Item4] -> argument 4 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18) | argument 0 [Item5] -> argument 5 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18) | argument 0 [Item6] -> argument 6 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17,T18>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17, out T18) | argument 0 [Item7] -> argument 7 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17) | argument 0 [Item1] -> argument 1 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17) | argument 0 [Item2] -> argument 2 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17) | argument 0 [Item3] -> argument 3 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17) | argument 0 [Item4] -> argument 4 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17) | argument 0 [Item5] -> argument 5 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17) | argument 0 [Item6] -> argument 6 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16,T17>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16, out T17) | argument 0 [Item7] -> argument 7 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16) | argument 0 [Item1] -> argument 1 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16) | argument 0 [Item2] -> argument 2 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16) | argument 0 [Item3] -> argument 3 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16) | argument 0 [Item4] -> argument 4 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16) | argument 0 [Item5] -> argument 5 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16) | argument 0 [Item6] -> argument 6 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15,T16>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15, out T16) | argument 0 [Item7] -> argument 7 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15) | argument 0 [Item1] -> argument 1 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15) | argument 0 [Item2] -> argument 2 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15) | argument 0 [Item3] -> argument 3 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15) | argument 0 [Item4] -> argument 4 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15) | argument 0 [Item5] -> argument 5 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15) | argument 0 [Item6] -> argument 6 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14,Tuple<T15>>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14, out T15) | argument 0 [Item7] -> argument 7 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14) | argument 0 [Item1] -> argument 1 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14) | argument 0 [Item2] -> argument 2 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14) | argument 0 [Item3] -> argument 3 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14) | argument 0 [Item4] -> argument 4 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14) | argument 0 [Item5] -> argument 5 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14) | argument 0 [Item6] -> argument 6 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13,T14>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13, out T14) | argument 0 [Item7] -> argument 7 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13) | argument 0 [Item1] -> argument 1 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13) | argument 0 [Item2] -> argument 2 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13) | argument 0 [Item3] -> argument 3 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13) | argument 0 [Item4] -> argument 4 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13) | argument 0 [Item5] -> argument 5 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13) | argument 0 [Item6] -> argument 6 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12,T13>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12, out T13) | argument 0 [Item7] -> argument 7 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12) | argument 0 [Item1] -> argument 1 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12) | argument 0 [Item2] -> argument 2 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12) | argument 0 [Item3] -> argument 3 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12) | argument 0 [Item4] -> argument 4 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12) | argument 0 [Item5] -> argument 5 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12) | argument 0 [Item6] -> argument 6 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11,T12>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11, out T12) | argument 0 [Item7] -> argument 7 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11) | argument 0 [Item1] -> argument 1 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11) | argument 0 [Item2] -> argument 2 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11) | argument 0 [Item3] -> argument 3 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11) | argument 0 [Item4] -> argument 4 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11) | argument 0 [Item5] -> argument 5 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11) | argument 0 [Item6] -> argument 6 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10,T11>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10, out T11) | argument 0 [Item7] -> argument 7 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10) | argument 0 [Item1] -> argument 1 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10) | argument 0 [Item2] -> argument 2 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10) | argument 0 [Item3] -> argument 3 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10) | argument 0 [Item4] -> argument 4 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10) | argument 0 [Item5] -> argument 5 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10) | argument 0 [Item6] -> argument 6 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9,T10>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9, out T10) | argument 0 [Item7] -> argument 7 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9) | argument 0 [Item1] -> argument 1 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9) | argument 0 [Item2] -> argument 2 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9) | argument 0 [Item3] -> argument 3 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9) | argument 0 [Item4] -> argument 4 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9) | argument 0 [Item5] -> argument 5 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9) | argument 0 [Item6] -> argument 6 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8,T9>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8, out T9) | argument 0 [Item7] -> argument 7 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8) | argument 0 [Item1] -> argument 1 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8) | argument 0 [Item2] -> argument 2 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8) | argument 0 [Item3] -> argument 3 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8) | argument 0 [Item4] -> argument 4 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8) | argument 0 [Item5] -> argument 5 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8) | argument 0 [Item6] -> argument 6 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7, T8>(Tuple<T1, T2, T3, T4, T5, T6, T7, Tuple<T8>>, out T1, out T2, out T3, out T4, out T5, out T6, out T7, out T8) | argument 0 [Item7] -> argument 7 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7>(Tuple<T1, T2, T3, T4, T5, T6, T7>, out T1, out T2, out T3, out T4, out T5, out T6, out T7) | argument 0 [Item1] -> argument 1 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7>(Tuple<T1, T2, T3, T4, T5, T6, T7>, out T1, out T2, out T3, out T4, out T5, out T6, out T7) | argument 0 [Item2] -> argument 2 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7>(Tuple<T1, T2, T3, T4, T5, T6, T7>, out T1, out T2, out T3, out T4, out T5, out T6, out T7) | argument 0 [Item3] -> argument 3 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7>(Tuple<T1, T2, T3, T4, T5, T6, T7>, out T1, out T2, out T3, out T4, out T5, out T6, out T7) | argument 0 [Item4] -> argument 4 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7>(Tuple<T1, T2, T3, T4, T5, T6, T7>, out T1, out T2, out T3, out T4, out T5, out T6, out T7) | argument 0 [Item5] -> argument 5 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7>(Tuple<T1, T2, T3, T4, T5, T6, T7>, out T1, out T2, out T3, out T4, out T5, out T6, out T7) | argument 0 [Item6] -> argument 6 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6, T7>(Tuple<T1, T2, T3, T4, T5, T6, T7>, out T1, out T2, out T3, out T4, out T5, out T6, out T7) | argument 0 [Item7] -> argument 7 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6>(Tuple<T1, T2, T3, T4, T5, T6>, out T1, out T2, out T3, out T4, out T5, out T6) | argument 0 [Item1] -> argument 1 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6>(Tuple<T1, T2, T3, T4, T5, T6>, out T1, out T2, out T3, out T4, out T5, out T6) | argument 0 [Item2] -> argument 2 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6>(Tuple<T1, T2, T3, T4, T5, T6>, out T1, out T2, out T3, out T4, out T5, out T6) | argument 0 [Item3] -> argument 3 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6>(Tuple<T1, T2, T3, T4, T5, T6>, out T1, out T2, out T3, out T4, out T5, out T6) | argument 0 [Item4] -> argument 4 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6>(Tuple<T1, T2, T3, T4, T5, T6>, out T1, out T2, out T3, out T4, out T5, out T6) | argument 0 [Item5] -> argument 5 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5, T6>(Tuple<T1, T2, T3, T4, T5, T6>, out T1, out T2, out T3, out T4, out T5, out T6) | argument 0 [Item6] -> argument 6 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5>(Tuple<T1, T2, T3, T4, T5>, out T1, out T2, out T3, out T4, out T5) | argument 0 [Item1] -> argument 1 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5>(Tuple<T1, T2, T3, T4, T5>, out T1, out T2, out T3, out T4, out T5) | argument 0 [Item2] -> argument 2 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5>(Tuple<T1, T2, T3, T4, T5>, out T1, out T2, out T3, out T4, out T5) | argument 0 [Item3] -> argument 3 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5>(Tuple<T1, T2, T3, T4, T5>, out T1, out T2, out T3, out T4, out T5) | argument 0 [Item4] -> argument 4 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4, T5>(Tuple<T1, T2, T3, T4, T5>, out T1, out T2, out T3, out T4, out T5) | argument 0 [Item5] -> argument 5 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4>(Tuple<T1, T2, T3, T4>, out T1, out T2, out T3, out T4) | argument 0 [Item1] -> argument 1 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4>(Tuple<T1, T2, T3, T4>, out T1, out T2, out T3, out T4) | argument 0 [Item2] -> argument 2 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4>(Tuple<T1, T2, T3, T4>, out T1, out T2, out T3, out T4) | argument 0 [Item3] -> argument 3 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3, T4>(Tuple<T1, T2, T3, T4>, out T1, out T2, out T3, out T4) | argument 0 [Item4] -> argument 4 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3>(Tuple<T1, T2, T3>, out T1, out T2, out T3) | argument 0 [Item1] -> argument 1 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3>(Tuple<T1, T2, T3>, out T1, out T2, out T3) | argument 0 [Item2] -> argument 2 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2, T3>(Tuple<T1, T2, T3>, out T1, out T2, out T3) | argument 0 [Item3] -> argument 3 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2>(Tuple<T1, T2>, out T1, out T2) | argument 0 [Item1] -> argument 1 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1, T2>(Tuple<T1, T2>, out T1, out T2) | argument 0 [Item2] -> argument 2 [<empty>] | true |
| System.TupleExtensions.Deconstruct<T1>(Tuple<T1>, out T1) | argument 0 [Item1] -> argument 1 [<empty>] | true |
| System.ValueTuple<,,,,,,,>.ValueTuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 0 [<empty>] -> return [Item1] | true |
| System.ValueTuple<,,,,,,,>.ValueTuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 1 [<empty>] -> return [Item2] | true |
| System.ValueTuple<,,,,,,,>.ValueTuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 2 [<empty>] -> return [Item3] | true |
| System.ValueTuple<,,,,,,,>.ValueTuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 3 [<empty>] -> return [Item4] | true |
| System.ValueTuple<,,,,,,,>.ValueTuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 4 [<empty>] -> return [Item5] | true |
| System.ValueTuple<,,,,,,,>.ValueTuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 5 [<empty>] -> return [Item6] | true |
| System.ValueTuple<,,,,,,,>.ValueTuple(T1, T2, T3, T4, T5, T6, T7, TRest) | argument 6 [<empty>] -> return [Item7] | true |
| System.ValueTuple<,,,,,,,>.get_Item(int) | qualifier [Item1] -> return [<empty>] | true |
| System.ValueTuple<,,,,,,,>.get_Item(int) | qualifier [Item2] -> return [<empty>] | true |
| System.ValueTuple<,,,,,,,>.get_Item(int) | qualifier [Item3] -> return [<empty>] | true |
| System.ValueTuple<,,,,,,,>.get_Item(int) | qualifier [Item4] -> return [<empty>] | true |
| System.ValueTuple<,,,,,,,>.get_Item(int) | qualifier [Item5] -> return [<empty>] | true |
| System.ValueTuple<,,,,,,,>.get_Item(int) | qualifier [Item6] -> return [<empty>] | true |
| System.ValueTuple<,,,,,,,>.get_Item(int) | qualifier [Item7] -> return [<empty>] | true |
clearsContent
| System.Array.Clear() | qualifier | [] |
| System.Array.Clear(Array, int, int) | qualifier | [] |

View File

@@ -3,7 +3,6 @@ import semmle.code.csharp.dataflow.LibraryTypeDataFlow
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
callable = c.getQualifiedNameWithTypes() and
flow = source + " -> " + sink and
@@ -22,7 +21,6 @@ query predicate callableFlowAccessPath(string callable, string flow, boolean pre
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, preservesValue) and
callable = c.getQualifiedNameWithTypes() and

View File

@@ -55,7 +55,7 @@ class ModulusAnalysis
{
j = i * 8 + 7;
}
System.Console.WriteLine(j); // congruent 3 mod 4 or 7 mod 8
System.Console.WriteLine(j); // congruent 3 mod 4 (cond = true) or 7 mod 8 (cond = false)
if (cond)
{
@@ -78,7 +78,18 @@ class ModulusAnalysis
}
}
void For(int cap)
{
for (var i = 0; i < cap; i++)
System.Console.WriteLine(i);
for (var j = 0; j < cap; j += 1)
System.Console.WriteLine(j);
for (var k = 0; k < cap; k += 3)
System.Console.WriteLine(k); // congruent 0 mod 3
}
int[] GetArray(){ return new int[42]; }
int[] GetArray() { return new int[42]; }
}

View File

@@ -33,82 +33,106 @@
| ModulusAnalysis.cs:25:42:25:44 | access to local variable mul | 0 | 3 | 42 |
| ModulusAnalysis.cs:25:42:25:44 | access to local variable mul | SSA def(mul) | 0 | 0 |
| ModulusAnalysis.cs:29:17:31:23 | ... ? ... : ... | 0 | 3 | 4 |
| ModulusAnalysis.cs:30:15:30:15 | access to parameter i | SSA param(i) | 0 | 0 |
| ModulusAnalysis.cs:30:15:30:19 | ... * ... | 0 | 0 | 4 |
| ModulusAnalysis.cs:30:15:30:23 | ... + ... | 0 | 3 | 4 |
| ModulusAnalysis.cs:30:19:30:19 | 4 | 0 | 4 | 0 |
| ModulusAnalysis.cs:30:23:30:23 | 3 | 0 | 3 | 0 |
| ModulusAnalysis.cs:31:15:31:15 | access to parameter i | SSA param(i) | 0 | 0 |
| ModulusAnalysis.cs:31:15:31:19 | ... * ... | 0 | 0 | 8 |
| ModulusAnalysis.cs:31:15:31:23 | ... + ... | 0 | 7 | 8 |
| ModulusAnalysis.cs:31:19:31:19 | 8 | 0 | 8 | 0 |
| ModulusAnalysis.cs:31:23:31:23 | 7 | 0 | 7 | 0 |
| ModulusAnalysis.cs:32:34:32:34 | access to local variable j | 0 | 3 | 4 |
| ModulusAnalysis.cs:32:34:32:34 | access to local variable j | [cond (line 9): false] SSA def(j) | 0 | 0 |
| ModulusAnalysis.cs:32:34:32:34 | access to local variable j | [cond (line 9): true] SSA def(j) | 0 | 0 |
| ModulusAnalysis.cs:34:13:34:13 | access to parameter x | SSA param(x) | 0 | 0 |
| ModulusAnalysis.cs:34:17:34:18 | access to constant c1 | 0 | 42 | 0 |
| ModulusAnalysis.cs:34:17:34:18 | access to constant c1 | SSA entry def(ModulusAnalysis.c1) | 0 | 0 |
| ModulusAnalysis.cs:34:23:34:23 | 3 | 0 | 3 | 0 |
| ModulusAnalysis.cs:34:28:34:28 | access to parameter y | SSA param(y) | 0 | 0 |
| ModulusAnalysis.cs:34:32:34:33 | access to constant c1 | 0 | 42 | 0 |
| ModulusAnalysis.cs:34:32:34:33 | access to constant c1 | SSA entry def(ModulusAnalysis.c1) | 0 | 0 |
| ModulusAnalysis.cs:34:38:34:38 | 7 | 0 | 7 | 0 |
| ModulusAnalysis.cs:36:38:36:38 | access to parameter x | 0 | 3 | 42 |
| ModulusAnalysis.cs:36:38:36:38 | access to parameter x | SSA param(x) | 0 | 0 |
| ModulusAnalysis.cs:36:38:36:42 | ... + ... | 0 | 10 | 42 |
| ModulusAnalysis.cs:36:38:36:42 | ... + ... | SSA param(x) | 7 | 42 |
| ModulusAnalysis.cs:36:38:36:42 | ... + ... | SSA param(y) | 3 | 42 |
| ModulusAnalysis.cs:36:42:36:42 | access to parameter y | 0 | 7 | 42 |
| ModulusAnalysis.cs:36:42:36:42 | access to parameter y | SSA param(y) | 0 | 0 |
| ModulusAnalysis.cs:39:13:39:13 | access to parameter x | SSA param(x) | 0 | 0 |
| ModulusAnalysis.cs:39:17:39:18 | access to constant c1 | 0 | 42 | 0 |
| ModulusAnalysis.cs:39:17:39:18 | access to constant c1 | SSA entry def(ModulusAnalysis.c1) | 0 | 0 |
| ModulusAnalysis.cs:39:23:39:23 | 3 | 0 | 3 | 0 |
| ModulusAnalysis.cs:39:28:39:28 | access to parameter y | SSA param(y) | 0 | 0 |
| ModulusAnalysis.cs:39:32:39:33 | access to constant c1 | 0 | 42 | 0 |
| ModulusAnalysis.cs:39:32:39:33 | access to constant c1 | SSA entry def(ModulusAnalysis.c1) | 0 | 0 |
| ModulusAnalysis.cs:39:38:39:38 | 7 | 0 | 7 | 0 |
| ModulusAnalysis.cs:41:38:41:38 | access to parameter x | 0 | 3 | 42 |
| ModulusAnalysis.cs:41:38:41:38 | access to parameter x | SSA param(x) | 0 | 0 |
| ModulusAnalysis.cs:41:38:41:42 | ... - ... | 0 | 38 | 42 |
| ModulusAnalysis.cs:41:38:41:42 | ... - ... | SSA param(x) | 35 | 42 |
| ModulusAnalysis.cs:41:42:41:42 | access to parameter y | 0 | 7 | 42 |
| ModulusAnalysis.cs:41:42:41:42 | access to parameter y | SSA param(y) | 0 | 0 |
| ModulusAnalysis.cs:44:17:44:26 | access to property Length | [cond (line 9): false] SSA untracked def(arr.Length) | 0 | 0 |
| ModulusAnalysis.cs:44:17:44:26 | access to property Length | [cond (line 9): true] SSA untracked def(arr.Length) | 0 | 0 |
| ModulusAnalysis.cs:44:17:44:30 | ... * ... | 0 | 0 | 4 |
| ModulusAnalysis.cs:44:17:44:35 | ... - ... | 0 | 1 | 4 |
| ModulusAnalysis.cs:44:30:44:30 | 4 | 0 | 4 | 0 |
| ModulusAnalysis.cs:44:34:44:35 | 11 | 0 | 11 | 0 |
| ModulusAnalysis.cs:45:34:45:34 | access to local variable l | 0 | 1 | 4 |
| ModulusAnalysis.cs:45:34:45:34 | access to local variable l | [cond (line 9): false] SSA def(l) | 0 | 0 |
| ModulusAnalysis.cs:45:34:45:34 | access to local variable l | [cond (line 9): true] SSA def(l) | 0 | 0 |
| ModulusAnalysis.cs:47:9:47:38 | ... = ... | 0 | 1 | 4 |
| ModulusAnalysis.cs:47:13:47:29 | access to property Length | access to property Length | 0 | 0 |
| ModulusAnalysis.cs:47:13:47:33 | ... * ... | 0 | 0 | 4 |
| ModulusAnalysis.cs:47:13:47:38 | ... - ... | 0 | 1 | 4 |
| ModulusAnalysis.cs:47:33:47:33 | 4 | 0 | 4 | 0 |
| ModulusAnalysis.cs:47:37:47:38 | 11 | 0 | 11 | 0 |
| ModulusAnalysis.cs:48:34:48:34 | access to local variable l | 0 | 1 | 4 |
| ModulusAnalysis.cs:48:34:48:34 | access to local variable l | [cond (line 9): false] SSA def(l) | 0 | 0 |
| ModulusAnalysis.cs:48:34:48:34 | access to local variable l | [cond (line 9): true] SSA def(l) | 0 | 0 |
| ModulusAnalysis.cs:52:13:52:25 | ... = ... | 0 | 3 | 4 |
| ModulusAnalysis.cs:52:17:52:17 | access to parameter i | SSA param(i) | 0 | 0 |
| ModulusAnalysis.cs:52:17:52:21 | ... * ... | 0 | 0 | 4 |
| ModulusAnalysis.cs:52:17:52:25 | ... + ... | 0 | 3 | 4 |
| ModulusAnalysis.cs:52:21:52:21 | 4 | 0 | 4 | 0 |
| ModulusAnalysis.cs:52:25:52:25 | 3 | 0 | 3 | 0 |
| ModulusAnalysis.cs:56:13:56:25 | ... = ... | 0 | 7 | 8 |
| ModulusAnalysis.cs:56:17:56:17 | access to parameter i | SSA param(i) | 0 | 0 |
| ModulusAnalysis.cs:56:17:56:21 | ... * ... | 0 | 0 | 8 |
| ModulusAnalysis.cs:56:17:56:25 | ... + ... | 0 | 7 | 8 |
| ModulusAnalysis.cs:56:21:56:21 | 8 | 0 | 8 | 0 |
| ModulusAnalysis.cs:56:25:56:25 | 7 | 0 | 7 | 0 |
| ModulusAnalysis.cs:58:34:58:34 | access to local variable j | 0 | 3 | 4 |
| ModulusAnalysis.cs:58:34:58:34 | access to local variable j | 0 | 7 | 8 |
| ModulusAnalysis.cs:58:34:58:34 | access to local variable j | [cond (line 9): false] SSA def(j) | 0 | 0 |
| ModulusAnalysis.cs:58:34:58:34 | access to local variable j | [cond (line 9): true] SSA def(j) | 0 | 0 |
| ModulusAnalysis.cs:30:15:30:15 | [cond (line 9): true] access to parameter i | SSA param(i) | 0 | 0 |
| ModulusAnalysis.cs:30:15:30:19 | [cond (line 9): true] ... * ... | 0 | 0 | 4 |
| ModulusAnalysis.cs:30:15:30:23 | [cond (line 9): true] ... + ... | 0 | 3 | 4 |
| ModulusAnalysis.cs:30:19:30:19 | [cond (line 9): true] 4 | 0 | 4 | 0 |
| ModulusAnalysis.cs:30:23:30:23 | [cond (line 9): true] 3 | 0 | 3 | 0 |
| ModulusAnalysis.cs:31:15:31:15 | [cond (line 9): false] access to parameter i | SSA param(i) | 0 | 0 |
| ModulusAnalysis.cs:31:15:31:19 | [cond (line 9): false] ... * ... | 0 | 0 | 8 |
| ModulusAnalysis.cs:31:15:31:23 | [cond (line 9): false] ... + ... | 0 | 7 | 8 |
| ModulusAnalysis.cs:31:19:31:19 | [cond (line 9): false] 8 | 0 | 8 | 0 |
| ModulusAnalysis.cs:31:23:31:23 | [cond (line 9): false] 7 | 0 | 7 | 0 |
| ModulusAnalysis.cs:32:34:32:34 | [cond (line 9): false] access to local variable j | 0 | 3 | 4 |
| ModulusAnalysis.cs:32:34:32:34 | [cond (line 9): false] access to local variable j | [cond (line 9): false] SSA def(j) | 0 | 0 |
| ModulusAnalysis.cs:32:34:32:34 | [cond (line 9): true] access to local variable j | 0 | 3 | 4 |
| ModulusAnalysis.cs:32:34:32:34 | [cond (line 9): true] access to local variable j | [cond (line 9): true] SSA def(j) | 0 | 0 |
| ModulusAnalysis.cs:34:13:34:13 | [cond (line 9): false] access to parameter x | SSA param(x) | 0 | 0 |
| ModulusAnalysis.cs:34:13:34:13 | [cond (line 9): true] access to parameter x | SSA param(x) | 0 | 0 |
| ModulusAnalysis.cs:34:17:34:18 | [cond (line 9): false] access to constant c1 | 0 | 42 | 0 |
| ModulusAnalysis.cs:34:17:34:18 | [cond (line 9): false] access to constant c1 | SSA entry def(ModulusAnalysis.c1) | 0 | 0 |
| ModulusAnalysis.cs:34:17:34:18 | [cond (line 9): true] access to constant c1 | 0 | 42 | 0 |
| ModulusAnalysis.cs:34:17:34:18 | [cond (line 9): true] access to constant c1 | SSA entry def(ModulusAnalysis.c1) | 0 | 0 |
| ModulusAnalysis.cs:34:23:34:23 | [cond (line 9): false] 3 | 0 | 3 | 0 |
| ModulusAnalysis.cs:34:23:34:23 | [cond (line 9): true] 3 | 0 | 3 | 0 |
| ModulusAnalysis.cs:34:28:34:28 | [cond (line 9): false] access to parameter y | SSA param(y) | 0 | 0 |
| ModulusAnalysis.cs:34:28:34:28 | [cond (line 9): true] access to parameter y | SSA param(y) | 0 | 0 |
| ModulusAnalysis.cs:34:32:34:33 | [cond (line 9): false] access to constant c1 | 0 | 42 | 0 |
| ModulusAnalysis.cs:34:32:34:33 | [cond (line 9): false] access to constant c1 | SSA entry def(ModulusAnalysis.c1) | 0 | 0 |
| ModulusAnalysis.cs:34:32:34:33 | [cond (line 9): true] access to constant c1 | 0 | 42 | 0 |
| ModulusAnalysis.cs:34:32:34:33 | [cond (line 9): true] access to constant c1 | SSA entry def(ModulusAnalysis.c1) | 0 | 0 |
| ModulusAnalysis.cs:34:38:34:38 | [cond (line 9): false] 7 | 0 | 7 | 0 |
| ModulusAnalysis.cs:34:38:34:38 | [cond (line 9): true] 7 | 0 | 7 | 0 |
| ModulusAnalysis.cs:36:38:36:38 | [cond (line 9): false] access to parameter x | SSA param(x) | 0 | 0 |
| ModulusAnalysis.cs:36:38:36:38 | [cond (line 9): true] access to parameter x | SSA param(x) | 0 | 0 |
| ModulusAnalysis.cs:36:42:36:42 | [cond (line 9): false] access to parameter y | SSA param(y) | 0 | 0 |
| ModulusAnalysis.cs:36:42:36:42 | [cond (line 9): true] access to parameter y | SSA param(y) | 0 | 0 |
| ModulusAnalysis.cs:39:13:39:13 | [cond (line 9): false] access to parameter x | SSA param(x) | 0 | 0 |
| ModulusAnalysis.cs:39:13:39:13 | [cond (line 9): true] access to parameter x | SSA param(x) | 0 | 0 |
| ModulusAnalysis.cs:39:17:39:18 | [cond (line 9): false] access to constant c1 | 0 | 42 | 0 |
| ModulusAnalysis.cs:39:17:39:18 | [cond (line 9): false] access to constant c1 | SSA entry def(ModulusAnalysis.c1) | 0 | 0 |
| ModulusAnalysis.cs:39:17:39:18 | [cond (line 9): true] access to constant c1 | 0 | 42 | 0 |
| ModulusAnalysis.cs:39:17:39:18 | [cond (line 9): true] access to constant c1 | SSA entry def(ModulusAnalysis.c1) | 0 | 0 |
| ModulusAnalysis.cs:39:23:39:23 | [cond (line 9): false] 3 | 0 | 3 | 0 |
| ModulusAnalysis.cs:39:23:39:23 | [cond (line 9): true] 3 | 0 | 3 | 0 |
| ModulusAnalysis.cs:39:28:39:28 | [cond (line 9): false] access to parameter y | SSA param(y) | 0 | 0 |
| ModulusAnalysis.cs:39:28:39:28 | [cond (line 9): true] access to parameter y | SSA param(y) | 0 | 0 |
| ModulusAnalysis.cs:39:32:39:33 | [cond (line 9): false] access to constant c1 | 0 | 42 | 0 |
| ModulusAnalysis.cs:39:32:39:33 | [cond (line 9): false] access to constant c1 | SSA entry def(ModulusAnalysis.c1) | 0 | 0 |
| ModulusAnalysis.cs:39:32:39:33 | [cond (line 9): true] access to constant c1 | 0 | 42 | 0 |
| ModulusAnalysis.cs:39:32:39:33 | [cond (line 9): true] access to constant c1 | SSA entry def(ModulusAnalysis.c1) | 0 | 0 |
| ModulusAnalysis.cs:39:38:39:38 | [cond (line 9): false] 7 | 0 | 7 | 0 |
| ModulusAnalysis.cs:39:38:39:38 | [cond (line 9): true] 7 | 0 | 7 | 0 |
| ModulusAnalysis.cs:41:38:41:38 | [cond (line 9): false] access to parameter x | SSA param(x) | 0 | 0 |
| ModulusAnalysis.cs:41:38:41:38 | [cond (line 9): true] access to parameter x | SSA param(x) | 0 | 0 |
| ModulusAnalysis.cs:41:42:41:42 | [cond (line 9): false] access to parameter y | SSA param(y) | 0 | 0 |
| ModulusAnalysis.cs:41:42:41:42 | [cond (line 9): true] access to parameter y | SSA param(y) | 0 | 0 |
| ModulusAnalysis.cs:44:17:44:26 | [cond (line 9): false] access to property Length | [cond (line 9): false] access to property Length | 0 | 0 |
| ModulusAnalysis.cs:44:17:44:26 | [cond (line 9): true] access to property Length | [cond (line 9): true] access to property Length | 0 | 0 |
| ModulusAnalysis.cs:44:17:44:30 | [cond (line 9): false] ... * ... | 0 | 0 | 4 |
| ModulusAnalysis.cs:44:17:44:30 | [cond (line 9): true] ... * ... | 0 | 0 | 4 |
| ModulusAnalysis.cs:44:17:44:35 | [cond (line 9): false] ... - ... | 0 | 1 | 4 |
| ModulusAnalysis.cs:44:17:44:35 | [cond (line 9): true] ... - ... | 0 | 1 | 4 |
| ModulusAnalysis.cs:44:30:44:30 | [cond (line 9): false] 4 | 0 | 4 | 0 |
| ModulusAnalysis.cs:44:30:44:30 | [cond (line 9): true] 4 | 0 | 4 | 0 |
| ModulusAnalysis.cs:44:34:44:35 | [cond (line 9): false] 11 | 0 | 11 | 0 |
| ModulusAnalysis.cs:44:34:44:35 | [cond (line 9): true] 11 | 0 | 11 | 0 |
| ModulusAnalysis.cs:45:34:45:34 | [cond (line 9): false] access to local variable l | 0 | 1 | 4 |
| ModulusAnalysis.cs:45:34:45:34 | [cond (line 9): false] access to local variable l | [cond (line 9): false] SSA def(l) | 0 | 0 |
| ModulusAnalysis.cs:45:34:45:34 | [cond (line 9): true] access to local variable l | 0 | 1 | 4 |
| ModulusAnalysis.cs:45:34:45:34 | [cond (line 9): true] access to local variable l | [cond (line 9): true] SSA def(l) | 0 | 0 |
| ModulusAnalysis.cs:47:9:47:38 | [cond (line 9): false] ... = ... | 0 | 1 | 4 |
| ModulusAnalysis.cs:47:9:47:38 | [cond (line 9): true] ... = ... | 0 | 1 | 4 |
| ModulusAnalysis.cs:47:13:47:29 | [cond (line 9): false] access to property Length | [cond (line 9): false] access to property Length | 0 | 0 |
| ModulusAnalysis.cs:47:13:47:29 | [cond (line 9): true] access to property Length | [cond (line 9): true] access to property Length | 0 | 0 |
| ModulusAnalysis.cs:47:13:47:33 | [cond (line 9): false] ... * ... | 0 | 0 | 4 |
| ModulusAnalysis.cs:47:13:47:33 | [cond (line 9): true] ... * ... | 0 | 0 | 4 |
| ModulusAnalysis.cs:47:13:47:38 | [cond (line 9): false] ... - ... | 0 | 1 | 4 |
| ModulusAnalysis.cs:47:13:47:38 | [cond (line 9): true] ... - ... | 0 | 1 | 4 |
| ModulusAnalysis.cs:47:33:47:33 | [cond (line 9): false] 4 | 0 | 4 | 0 |
| ModulusAnalysis.cs:47:33:47:33 | [cond (line 9): true] 4 | 0 | 4 | 0 |
| ModulusAnalysis.cs:47:37:47:38 | [cond (line 9): false] 11 | 0 | 11 | 0 |
| ModulusAnalysis.cs:47:37:47:38 | [cond (line 9): true] 11 | 0 | 11 | 0 |
| ModulusAnalysis.cs:48:34:48:34 | [cond (line 9): false] access to local variable l | 0 | 1 | 4 |
| ModulusAnalysis.cs:48:34:48:34 | [cond (line 9): false] access to local variable l | [cond (line 9): false] SSA def(l) | 0 | 0 |
| ModulusAnalysis.cs:48:34:48:34 | [cond (line 9): true] access to local variable l | 0 | 1 | 4 |
| ModulusAnalysis.cs:48:34:48:34 | [cond (line 9): true] access to local variable l | [cond (line 9): true] SSA def(l) | 0 | 0 |
| ModulusAnalysis.cs:52:13:52:25 | [cond (line 9): true] ... = ... | 0 | 3 | 4 |
| ModulusAnalysis.cs:52:17:52:17 | [cond (line 9): true] access to parameter i | SSA param(i) | 0 | 0 |
| ModulusAnalysis.cs:52:17:52:21 | [cond (line 9): true] ... * ... | 0 | 0 | 4 |
| ModulusAnalysis.cs:52:17:52:25 | [cond (line 9): true] ... + ... | 0 | 3 | 4 |
| ModulusAnalysis.cs:52:21:52:21 | [cond (line 9): true] 4 | 0 | 4 | 0 |
| ModulusAnalysis.cs:52:25:52:25 | [cond (line 9): true] 3 | 0 | 3 | 0 |
| ModulusAnalysis.cs:56:13:56:25 | [cond (line 9): false] ... = ... | 0 | 7 | 8 |
| ModulusAnalysis.cs:56:17:56:17 | [cond (line 9): false] access to parameter i | SSA param(i) | 0 | 0 |
| ModulusAnalysis.cs:56:17:56:21 | [cond (line 9): false] ... * ... | 0 | 0 | 8 |
| ModulusAnalysis.cs:56:17:56:25 | [cond (line 9): false] ... + ... | 0 | 7 | 8 |
| ModulusAnalysis.cs:56:21:56:21 | [cond (line 9): false] 8 | 0 | 8 | 0 |
| ModulusAnalysis.cs:56:25:56:25 | [cond (line 9): false] 7 | 0 | 7 | 0 |
| ModulusAnalysis.cs:58:34:58:34 | [cond (line 9): false] access to local variable j | 0 | 7 | 8 |
| ModulusAnalysis.cs:58:34:58:34 | [cond (line 9): false] access to local variable j | [cond (line 9): false] SSA def(j) | 0 | 0 |
| ModulusAnalysis.cs:58:34:58:34 | [cond (line 9): true] access to local variable j | 0 | 3 | 4 |
| ModulusAnalysis.cs:58:34:58:34 | [cond (line 9): true] access to local variable j | [cond (line 9): true] SSA def(j) | 0 | 0 |
| ModulusAnalysis.cs:62:38:62:38 | access to local variable j | 0 | 3 | 4 |
| ModulusAnalysis.cs:62:38:62:38 | access to local variable j | [cond (line 9): true] SSA def(j) | 0 | 0 |
| ModulusAnalysis.cs:66:38:66:38 | access to local variable j | 0 | 7 | 8 |
@@ -135,4 +159,36 @@
| ModulusAnalysis.cs:75:25:75:25 | 3 | 0 | 3 | 0 |
| ModulusAnalysis.cs:77:38:77:38 | access to parameter x | 0 | 3 | 16 |
| ModulusAnalysis.cs:77:38:77:38 | access to parameter x | SSA param(x) | 0 | 0 |
| ModulusAnalysis.cs:83:38:83:39 | 42 | 0 | 42 | 0 |
| ModulusAnalysis.cs:83:22:83:22 | 0 | 0 | 0 | 0 |
| ModulusAnalysis.cs:83:25:83:25 | access to local variable i | SSA phi(i) | 0 | 0 |
| ModulusAnalysis.cs:83:29:83:31 | access to parameter cap | SSA param(cap) | 0 | 0 |
| ModulusAnalysis.cs:83:34:83:34 | access to local variable i | SSA phi(i) | 0 | 0 |
| ModulusAnalysis.cs:83:34:83:36 | ...++ | SSA phi(i) | 0 | 0 |
| ModulusAnalysis.cs:84:38:84:38 | access to local variable i | SSA phi(i) | 0 | 0 |
| ModulusAnalysis.cs:86:22:86:22 | 0 | 0 | 0 | 0 |
| ModulusAnalysis.cs:86:25:86:25 | access to local variable j | SSA phi(j) | 0 | 0 |
| ModulusAnalysis.cs:86:29:86:31 | access to parameter cap | SSA param(cap) | 0 | 0 |
| ModulusAnalysis.cs:86:34:86:34 | access to local variable j | SSA phi(j) | 0 | 0 |
| ModulusAnalysis.cs:86:34:86:39 | ... + ... | SSA phi(j) | 1 | 0 |
| ModulusAnalysis.cs:86:34:86:39 | ... = ... | SSA phi(j) | 1 | 0 |
| ModulusAnalysis.cs:86:39:86:39 | 1 | 0 | 1 | 0 |
| ModulusAnalysis.cs:87:38:87:38 | access to local variable j | SSA phi(j) | 0 | 0 |
| ModulusAnalysis.cs:89:22:89:22 | 0 | 0 | 0 | 0 |
| ModulusAnalysis.cs:89:25:89:25 | access to local variable k | 0 | 0 | 3 |
| ModulusAnalysis.cs:89:25:89:25 | access to local variable k | SSA def(k) | 0 | 3 |
| ModulusAnalysis.cs:89:25:89:25 | access to local variable k | SSA phi(k) | 0 | 0 |
| ModulusAnalysis.cs:89:29:89:31 | access to parameter cap | SSA param(cap) | 0 | 0 |
| ModulusAnalysis.cs:89:34:89:34 | access to local variable k | 0 | 0 | 3 |
| ModulusAnalysis.cs:89:34:89:34 | access to local variable k | SSA def(k) | 0 | 3 |
| ModulusAnalysis.cs:89:34:89:34 | access to local variable k | SSA phi(k) | 0 | 0 |
| ModulusAnalysis.cs:89:34:89:39 | ... + ... | 0 | 0 | 3 |
| ModulusAnalysis.cs:89:34:89:39 | ... + ... | SSA def(k) | 0 | 3 |
| ModulusAnalysis.cs:89:34:89:39 | ... + ... | SSA phi(k) | 3 | 0 |
| ModulusAnalysis.cs:89:34:89:39 | ... = ... | 0 | 0 | 3 |
| ModulusAnalysis.cs:89:34:89:39 | ... = ... | SSA def(k) | 0 | 3 |
| ModulusAnalysis.cs:89:34:89:39 | ... = ... | SSA phi(k) | 3 | 0 |
| ModulusAnalysis.cs:89:39:89:39 | 3 | 0 | 3 | 0 |
| ModulusAnalysis.cs:90:38:90:38 | access to local variable k | 0 | 0 | 3 |
| ModulusAnalysis.cs:90:38:90:38 | access to local variable k | SSA def(k) | 0 | 3 |
| ModulusAnalysis.cs:90:38:90:38 | access to local variable k | SSA phi(k) | 0 | 0 |
| ModulusAnalysis.cs:94:39:94:40 | 42 | 0 | 42 | 0 |

View File

@@ -1,7 +1,8 @@
import csharp
import semmle.code.csharp.dataflow.internal.rangeanalysis.RangeUtils
import semmle.code.csharp.dataflow.ModulusAnalysis
import semmle.code.csharp.dataflow.Bound
from Expr e, Bound b, int delta, int mod
from ControlFlow::Nodes::ExprNode e, Bound b, int delta, int mod
where exprModulus(e, b, delta, mod)
select e, b.toString(), delta, mod

View File

@@ -1,10 +1,10 @@
import csharp
import semmle.code.csharp.dataflow.SignAnalysis
import semmle.code.csharp.dataflow.internal.rangeanalysis.SignAnalysisCommon
from Expr e
from ControlFlow::Nodes::ExprNode e
where
not exists(exprSign(e)) and
not e instanceof TypeAccess and
not e.getExpr() instanceof TypeAccess and
(
e.getType() instanceof CharType or
e.getType() instanceof IntegralType or

View File

@@ -464,6 +464,28 @@ class SignAnalysis
x++;
System.Console.WriteLine(x); // strictly positive
}
void Splitting1(bool b)
{
var x = b ? 1 : -1;
if (b)
System.Console.WriteLine(x); // strictly positive [MISSING]
else
System.Console.WriteLine(x); // strictly negative [MISSING]
}
void Splitting2(bool b)
{
int x;
if (b) x = 1; else x = -1;
System.Console.WriteLine(x); // strictly positive (b = true) or strictly negative (b = false)
if (b)
System.Console.WriteLine(x); // strictly positive
else
System.Console.WriteLine(x); // strictly negative
}
}
// semmle-extractor-options: /r:System.Linq.dll

View File

@@ -53,7 +53,6 @@
| SignAnalysis.cs:80:17:80:17 | access to parameter i | strictlyNegative |
| SignAnalysis.cs:81:13:81:13 | access to local variable x | strictlyNegative |
| SignAnalysis.cs:81:13:81:18 | ... + ... | strictlyNegative |
| SignAnalysis.cs:81:13:81:18 | ... += ... | strictlyNegative |
| SignAnalysis.cs:81:13:81:18 | ... = ... | strictlyNegative |
| SignAnalysis.cs:81:18:81:18 | access to parameter i | strictlyNegative |
| SignAnalysis.cs:82:38:82:38 | access to local variable x | strictlyNegative |
@@ -90,14 +89,12 @@
| SignAnalysis.cs:108:13:108:21 | Decimal de = ... | strictlyPositive |
| SignAnalysis.cs:108:18:108:21 | 4.2 | strictlyPositive |
| SignAnalysis.cs:109:34:109:35 | access to local variable de | strictlyPositive |
| SignAnalysis.cs:110:13:110:13 | access to local variable c | positive |
| SignAnalysis.cs:110:13:110:19 | Char c = ... | strictlyPositive |
| SignAnalysis.cs:110:17:110:19 | a | strictlyPositive |
| SignAnalysis.cs:111:34:111:34 | access to local variable c | strictlyPositive |
| SignAnalysis.cs:120:9:120:10 | access to field f0 | positive |
| SignAnalysis.cs:120:9:120:12 | ...++ | positive |
| SignAnalysis.cs:121:34:121:35 | access to field f0 | strictlyPositive |
| SignAnalysis.cs:122:9:122:10 | access to field f0 | positive |
| SignAnalysis.cs:129:9:129:16 | ... = ... | strictlyNegative |
| SignAnalysis.cs:129:14:129:16 | -... | strictlyNegative |
| SignAnalysis.cs:129:15:129:16 | 10 | strictlyPositive |
@@ -164,8 +161,6 @@
| SignAnalysis.cs:306:21:306:22 | -... | strictlyNegative |
| SignAnalysis.cs:306:22:306:22 | 1 | strictlyPositive |
| SignAnalysis.cs:309:38:309:38 | access to local variable x | strictlyNegative |
| SignAnalysis.cs:315:13:315:15 | access to local variable min | positive |
| SignAnalysis.cs:316:13:316:15 | access to local variable max | positive |
| SignAnalysis.cs:316:13:316:31 | Char max = ... | strictlyPositive |
| SignAnalysis.cs:316:19:316:31 | access to constant MaxValue | strictlyPositive |
| SignAnalysis.cs:317:13:317:23 | Int32 c = ... | strictlyPositive |
@@ -200,7 +195,6 @@
| SignAnalysis.cs:357:13:357:13 | access to parameter i | positive |
| SignAnalysis.cs:359:38:359:38 | access to parameter i | strictlyPositive |
| SignAnalysis.cs:371:38:371:38 | access to local variable y | strictlyNegative |
| SignAnalysis.cs:377:16:377:17 | access to local variable dp | positive |
| SignAnalysis.cs:377:16:377:22 | Single* dp = ... | positive |
| SignAnalysis.cs:377:21:377:22 | &... | positive |
| SignAnalysis.cs:378:18:378:19 | access to local variable dp | positive |
@@ -221,7 +215,6 @@
| SignAnalysis.cs:414:13:414:13 | access to local variable i | strictlyPositive |
| SignAnalysis.cs:415:31:415:31 | access to local variable i | strictlyPositive |
| SignAnalysis.cs:424:31:424:31 | access to local variable x | strictlyNegative |
| SignAnalysis.cs:428:19:428:19 | access to constant A | strictlyPositive |
| SignAnalysis.cs:428:19:428:24 | ... = ... | strictlyPositive |
| SignAnalysis.cs:428:23:428:24 | 12 | strictlyPositive |
| SignAnalysis.cs:434:38:434:38 | access to local variable i | strictlyNegative |
@@ -229,7 +222,6 @@
| SignAnalysis.cs:440:29:440:31 | access to parameter dst | positive |
| SignAnalysis.cs:443:38:443:38 | access to local variable x | strictlyNegative |
| SignAnalysis.cs:446:31:446:32 | 10 | strictlyPositive |
| SignAnalysis.cs:448:22:448:23 | access to local variable to | positive |
| SignAnalysis.cs:448:22:448:29 | Byte* to = ... | positive |
| SignAnalysis.cs:448:27:448:29 | (...) ... | positive |
| SignAnalysis.cs:450:38:450:44 | (...) ... | positive |
@@ -241,9 +233,20 @@
| SignAnalysis.cs:457:18:457:27 | call to method Unsigned | positive |
| SignAnalysis.cs:458:13:458:13 | access to local variable l | positive |
| SignAnalysis.cs:460:38:460:38 | access to local variable l | strictlyPositive |
| SignAnalysis.cs:463:14:463:14 | access to local variable x | positive |
| SignAnalysis.cs:463:14:463:24 | UInt32 x = ... | positive |
| SignAnalysis.cs:463:18:463:24 | (...) ... | positive |
| SignAnalysis.cs:464:9:464:9 | access to local variable x | positive |
| SignAnalysis.cs:464:9:464:11 | ...++ | positive |
| SignAnalysis.cs:465:34:465:34 | access to local variable x | strictlyPositive |
| SignAnalysis.cs:470:21:470:21 | [b (line 468): true] 1 | strictlyPositive |
| SignAnalysis.cs:470:25:470:26 | [b (line 468): false] -... | strictlyNegative |
| SignAnalysis.cs:470:26:470:26 | [b (line 468): false] 1 | strictlyPositive |
| SignAnalysis.cs:480:16:480:20 | [b (line 477): true] ... = ... | strictlyPositive |
| SignAnalysis.cs:480:20:480:20 | [b (line 477): true] 1 | strictlyPositive |
| SignAnalysis.cs:480:28:480:33 | [b (line 477): false] ... = ... | strictlyNegative |
| SignAnalysis.cs:480:32:480:33 | [b (line 477): false] -... | strictlyNegative |
| SignAnalysis.cs:480:33:480:33 | [b (line 477): false] 1 | strictlyPositive |
| SignAnalysis.cs:482:34:482:34 | [b (line 477): false] access to local variable x | strictlyNegative |
| SignAnalysis.cs:482:34:482:34 | [b (line 477): true] access to local variable x | strictlyPositive |
| SignAnalysis.cs:485:38:485:38 | access to local variable x | strictlyPositive |
| SignAnalysis.cs:487:38:487:38 | access to local variable x | strictlyNegative |

View File

@@ -1,7 +1,7 @@
import csharp
import semmle.code.csharp.dataflow.SignAnalysis
string getASignString(Expr e) {
string getASignString(ControlFlow::Nodes::ExprNode e) {
positive(e) and
not strictlyPositive(e) and
result = "positive"
@@ -17,5 +17,5 @@ string getASignString(Expr e) {
result = "strictlyNegative"
}
from Expr e
from ControlFlow::Nodes::ExprNode e
select e, strictconcat(string s | s = getASignString(e) | s, " ")

View File

@@ -0,0 +1,101 @@
# Query classification and display
## Attributable Queries
The results of some queries are unsuitable for attribution to individual
developers. Most of them have a threshold value on which they trigger,
for example all metric violations and statistics based queries. The
results of such queries would all be attributed to the person pushing
the value over (or under) the threshold. Some queries only trigger when
another one doesn't. An example of this is the MaybeNull query which
only triggers if the AlwaysNull query doesn't. A small change in the
data flow could make an alert switch from AlwaysNull to MaybeNull (or
vice versa). As a result we attribute both a fix and an introduction to
the developer that changed the data flow. For this particular example
the funny attribution results are more a nuisance than a real problem;
the overall alert count remains unchanged. However, for the duplicate
and similar code queries the effects can be much more severe, as they
come in versions for "duplicate file" and "duplicate function" among
many others, where "duplicate function" only triggers if "duplicate
file" didn't. As a result adding some code to a duplicate file might
result in a "fix" of a "duplicate file" alert and an introduction of
many "duplicate function" alerts. This would be highly unfair.
Currently, only the duplicate and similar code queries exhibit this
"exchanging one for many" alerts when trying to attribute their results.
Therefore we currently exclude all duplicate code related alerts from
attribution.
The following queries are excluded from attribution:
- Metric violations, i.e. the ones with metadata properties like
 `@(error|warning|recommendation)-(to|from)`
- Queries with tag `non-attributable`
This check is applied when the results of a single attribution are
loaded into the datastore. This means that any change to this behaviour
will only take effect on newly attributed revisions but the historical
data remains unchanged.
## Query severity and precision
We currently classify queries on two axes, with some additional tags.
Those axes are severity and precision, and are defined using the
query-metadata properties `@problem.severity` and `@precision`.
For severity, we have the following categories:
- Error
- Warning
- Recommendation
These categories may change in the future.
For precision, we have the following categories:
- very-high
- high
- medium
- low
As [usual](https://en.wikipedia.org/wiki/Precision_and_recall),
precision is defined as the percentage of query results that are true
positives, i.e., precision = number of true positives / (number of true
positives + number of false positives). There is no hard-and-fast rule
for which precision ranges correspond to which categories.
We expect these categories to remain unchanged for the foreseeable
future.
### A note on precision
Intuitively, precision measures how well the query performs at finding the
results it is supposed to find, i.e., how well it implements its
(informal, unwritten) rule. So how precise a query is depends very much
on what we consider that rule to be. We generally try to sharpen our
rules to focus on results that a developer might actually be interested
in.
## Which queries to run and display on LGTM
The following queries are run:
Precision: | very-high | high | medium | low
---------------|-----------|---------|---------|----
Error | **Yes** | **Yes** | **Yes** | No
Warning | **Yes** | **Yes** | **Yes** | No
Recommendation | **Yes** | **Yes** | No | No
The following queries have their results displayed by default:
Precision: | very-high | high | medium | low
---------------|-----------|---------|--------|----
Error | **Yes** | **Yes** | No | No
Warning | **Yes** | **Yes** | No | No
Recommendation | **Yes** | No | No | No
Results for queries that are run but not displayed by default can be
made visible by editing the project configuration.
Queries from custom query packs (in-repo or site-wide) are always run
and displayed by default. They can be hidden by editing the project
config, and "disabled" by removing them from the query pack.

View File

@@ -0,0 +1,2 @@
lgtm,codescanning
* Some methods of the [Guava](https://guava.dev/) framework have been added as flow steps (specifically those of the [Splitter](https://guava.dev/releases/30.0-jre/api/docs/com/google/common/base/Splitter.html), [Joiner](https://guava.dev/releases/30.0-jre/api/docs/com/google/common/base/Joiner.html), and [Strings](https://guava.dev/releases/30.0-jre/api/docs/com/google/common/base/Strings.html) classes), which may lead to more results from the security queries.

View File

@@ -15,6 +15,7 @@ module Frameworks {
private import semmle.code.java.frameworks.android.SQLite
private import semmle.code.java.frameworks.Guice
private import semmle.code.java.frameworks.Protobuf
private import semmle.code.java.frameworks.guava.Guava
}
/**

View File

@@ -111,18 +111,6 @@ private predicate evenlyDivisibleExpr(Expr e, int factor) {
)
}
/**
* Holds if `inp` is an input to `phi` along `edge` and this input has index `r`
* in an arbitrary 1-based numbering of the input edges to `phi`.
*/
private predicate rankedPhiInput(
SsaPhiNode phi, SsaVariable inp, SsaReadPositionPhiInputEdge edge, int r
) {
edge.phiInput(phi, inp) and
edge =
rank[r](SsaReadPositionPhiInputEdge e | e.phiInput(phi, _) | e order by getId(e.getOrigBlock()))
}
/**
* Holds if `rix` is the number of input edges to `phi`.
*/

View File

@@ -79,6 +79,11 @@ Expr clearlyNotNullExpr(Expr reason) {
)
or
exists(SsaVariable v | clearlyNotNull(v, reason) and result = v.getAUse())
or
exists(Method m | m = result.(MethodAccess).getMethod() and reason = result |
m.getDeclaringType().hasQualifiedName("com.google.common.base", "Strings") and
m.hasName("nullToEmpty")
)
}
/** Holds if `v` is an SSA variable that is provably not `null`. */
@@ -146,6 +151,11 @@ predicate nullCheckMethod(Method m, boolean branch, boolean isnull) {
m.hasName("isNotEmpty") and
branch = true and
isnull = false
or
m.getDeclaringType().hasQualifiedName("com.google.common.base", "Strings") and
m.hasName("isNullOrEmpty") and
branch = false and
isnull = false
}
/**

View File

@@ -4,6 +4,7 @@ module Private {
private import semmle.code.java.dataflow.RangeUtils as RU
private import semmle.code.java.controlflow.Guards as G
private import semmle.code.java.controlflow.BasicBlocks as BB
private import SsaReadPositionCommon
class BasicBlock = BB::BasicBlock;
@@ -115,5 +116,19 @@ module Private {
private predicate idOf(BasicBlock x, int y) = equivalenceRelation(id/2)(x, y)
int getId(BasicBlock bb) { idOf(bb, result) }
private int getId(BasicBlock bb) { idOf(bb, result) }
/**
* Holds if `inp` is an input to `phi` along `edge` and this input has index `r`
* in an arbitrary 1-based numbering of the input edges to `phi`.
*/
predicate rankedPhiInput(SsaPhiNode phi, SsaVariable inp, SsaReadPositionPhiInputEdge edge, int r) {
edge.phiInput(phi, inp) and
edge =
rank[r](SsaReadPositionPhiInputEdge e |
e.phiInput(phi, _)
|
e order by getId(e.getOrigBlock())
)
}
}

View File

@@ -51,7 +51,7 @@ private predicate unknownSign(Expr e) {
or
exists(CastExpr cast, Type fromtyp |
cast = e and
fromtyp = cast.getExpr().getType() and
fromtyp = cast.getSourceType() and
not fromtyp instanceof NumericOrCharType
)
or

View File

@@ -27,7 +27,10 @@ module Private {
class LongLiteral = J::LongLiteral;
class CastExpr = J::CastExpr;
class CastExpr extends J::CastExpr {
/** Gets the source type of this cast. */
J::Type getSourceType() { result = this.getExpr().getType() }
}
class Type = J::Type;

View File

@@ -0,0 +1,6 @@
/**
* Definitions for tracking taint steps through the Guava framework.
*/
import java
import StringUtils

View File

@@ -0,0 +1,169 @@
/** Definitions of flow steps through the various string utility functions in the Guava framework. */
import java
private import semmle.code.java.dataflow.FlowSteps
/**
* The class `com.google.common.base.Strings`.
*/
class TypeGuavaStrings extends Class {
TypeGuavaStrings() { this.hasQualifiedName("com.google.common.base", "Strings") }
}
/**
* The class `com.google.common.base.Joiner`.
*/
class TypeGuavaJoiner extends Class {
TypeGuavaJoiner() { this.hasQualifiedName("com.google.common.base", "Joiner") }
}
/**
* The nested class `Joiner.MapJoiner`.
*/
class TypeGuavaMapJoiner extends NestedClass {
TypeGuavaMapJoiner() {
this.getEnclosingType() instanceof TypeGuavaJoiner and
this.hasName("MapJoiner")
}
}
/**
* The class `com.google.common.base.Splitter`.
*/
class TypeGuavaSplitter extends Class {
TypeGuavaSplitter() { this.hasQualifiedName("com.google.common.base", "Splitter") }
}
/**
* The nested class `Splitter.MapSplitter`.
*/
class TypeGuavaMapSplitter extends NestedClass {
TypeGuavaMapSplitter() {
this.getEnclosingType() instanceof TypeGuavaSplitter and
this.hasName("MapSplitter")
}
}
/**
* A taint preserving method on `com.google.common.base.Strings`.
*/
private class GuavaStringsTaintPreservingMethod extends TaintPreservingCallable {
GuavaStringsTaintPreservingMethod() {
this.getDeclaringType() instanceof TypeGuavaStrings and
// static String emptyToNull(String string)
// static String nullToEmpty(String string)
// static String padStart(String string, int minLength, char padChar)
// static String padEnd(String string, int minLength, char padChar)
// static String repeat(String string, int count)
// static String lenientFormat(String template, Object ... args)
this.hasName(["emptyToNull", "nullToEmpty", "padStart", "padEnd", "repeat", "lenientFormat"])
}
override predicate returnsTaintFrom(int src) {
src = 0
or
this.hasName("lenientFormat") and
src = [0 .. getNumberOfParameters()]
}
}
/**
* A method of `Joiner` or `MapJoiner`.
*/
private class GuavaJoinerMethod extends Method {
GuavaJoinerMethod() {
this.getDeclaringType().getASourceSupertype*() instanceof TypeGuavaJoiner or
this.getDeclaringType().getASourceSupertype*() instanceof TypeGuavaMapJoiner
}
}
/**
* A method that builds a `Joiner` or `MapJoiner`.
*/
private class GuavaJoinerBuilderMethod extends GuavaJoinerMethod, TaintPreservingCallable {
GuavaJoinerBuilderMethod() {
// static Joiner on(char separator)
// static Joiner on(String separator)
// Joiner skipNulls()
// Joiner useForNull(String nullText)
// Joiner.MapJoiner withKeyValueSeparator(char keyValueSeparator)
// Joiner.MapJoiner withKeyValueSeparator(String keyValueSeparator)
// Joiner.MapJoiner useForNull(String nullText) [on MapJoiner]
this.hasName(["on", "skipNulls", "useForNull", "withKeyValueSeparator"])
}
override predicate returnsTaintFrom(int src) {
src = 0
or
src = -1 and not isStatic()
}
}
/**
* An `appendTo` method on `Joiner` or `MapJoiner`.
*/
private class GuavaJoinerAppendToMethod extends GuavaJoinerMethod, TaintPreservingCallable {
GuavaJoinerAppendToMethod() {
// <A extends Appendable> A appendTo(A appendable, Iterable<?> parts)
// <A extends Appendable> A appendTo(A appendable, Iterator<?> parts)
// <A extends Appendable> A appendTo(A appendable, Object[] parts)
// <A extends Appendable> A appendTo(A appendable, Object first, Object second, Object... rest)
// StringBuilder appendTo(StringBuilder builder, Iterable<?> parts)
// StringBuilder appendTo(StringBuilder builder, Iterator<?> parts)
// StringBuilder appendTo(StringBuilder builder, Object[] parts)
// StringBuilder appendTo(StringBuilder builder, Object first, Object second, Object... rest)
// <A extends Appendable> A appendTo(A appendable, Iterable<? extends Map.Entry<?,?>> entries) [on MapJoiner]
// <A extends Appendable> A appendTo(A appendable, Iterator<? extends Map.Entry<?,?>> parts)
// <A extends Appendable> A appendTo(A appendable, Map<?,?> map)
// StringBuilder appendTo(StringBuilder builder, Iterable<? extends Map.Entry<?,?>> entries)
// StringBuilder appendTo(StringBuilder builder, Iterator<? extends Map.Entry<?,?>> entries)
// StringBuilder appendTo(StringBuilder builder, Map<?,?> map)
this.hasName("appendTo")
}
override predicate transfersTaint(int src, int sink) {
src = [-1 .. getNumberOfParameters()] and
src != sink and
sink = 0
}
override predicate returnsTaintFrom(int src) { src = [-1 .. getNumberOfParameters()] }
}
/**
* A `join` method on `Joiner` or `MapJoiner`.
*/
private class GuavaJoinMethod extends GuavaJoinerMethod, TaintPreservingCallable {
GuavaJoinMethod() {
// String join(Iterable<?> parts)
// String join(Iterator<?> parts)
// String join(Object[] parts)
// String join(Object first, Object second, Object... rest)
// String join(Iterable<? extends Map.Entry<?,?>> entries) [on MapJoiner]
// String join(Iterator<? extends Map.Entry<?,?>> entries)
// String join(Map<?,?> map)
this.hasName("join")
}
override predicate returnsTaintFrom(int src) { src = [-1 .. getNumberOfParameters()] }
}
/**
* A method of `Splitter` or `MapSplitter` that splits its input string.
*/
private class GuavaSplitMethod extends TaintPreservingCallable {
GuavaSplitMethod() {
(
this.getDeclaringType() instanceof TypeGuavaSplitter
or
this.getDeclaringType() instanceof TypeGuavaMapSplitter
) and
// Iterable<String> split(CharSequence sequence)
// List<String> splitToList(CharSequence sequence)
// Stream<String> splitToStream(CharSequence sequence)
// Map<String,String> split(CharSequence sequence) [on MapSplitter]
this.hasName(["split", "splitToList", "splitToStream"])
}
override predicate returnsTaintFrom(int src) { src = 0 }
}

View File

@@ -104,4 +104,32 @@
| ModulusAnalysis.java:49:25:49:25 | 3 | 0 | 3 | 0 |
| ModulusAnalysis.java:50:32:50:32 | x | 0 | 3 | 16 |
| ModulusAnalysis.java:50:32:50:32 | x | SSA init(x) | 0 | 0 |
| ModulusAnalysis.java:54:38:54:39 | 42 | 0 | 42 | 0 |
| ModulusAnalysis.java:56:22:56:22 | 0 | 0 | 0 | 0 |
| ModulusAnalysis.java:56:25:56:25 | i | SSA phi(i) | 0 | 0 |
| ModulusAnalysis.java:56:29:56:31 | cap | SSA init(cap) | 0 | 0 |
| ModulusAnalysis.java:56:34:56:34 | i | SSA phi(i) | 0 | 0 |
| ModulusAnalysis.java:56:34:56:36 | ...++ | SSA phi(i) | 0 | 0 |
| ModulusAnalysis.java:57:32:57:32 | i | SSA phi(i) | 0 | 0 |
| ModulusAnalysis.java:59:22:59:22 | 0 | 0 | 0 | 0 |
| ModulusAnalysis.java:59:25:59:25 | j | SSA phi(j) | 0 | 0 |
| ModulusAnalysis.java:59:29:59:31 | cap | SSA init(cap) | 0 | 0 |
| ModulusAnalysis.java:59:34:59:34 | j | SSA phi(j) | 0 | 0 |
| ModulusAnalysis.java:59:34:59:39 | ...+=... | SSA phi(j) | 1 | 0 |
| ModulusAnalysis.java:59:39:59:39 | 1 | 0 | 1 | 0 |
| ModulusAnalysis.java:60:32:60:32 | j | SSA phi(j) | 0 | 0 |
| ModulusAnalysis.java:62:22:62:22 | 0 | 0 | 0 | 0 |
| ModulusAnalysis.java:62:25:62:25 | k | 0 | 0 | 3 |
| ModulusAnalysis.java:62:25:62:25 | k | SSA def(k) | 0 | 3 |
| ModulusAnalysis.java:62:25:62:25 | k | SSA phi(k) | 0 | 0 |
| ModulusAnalysis.java:62:29:62:31 | cap | SSA init(cap) | 0 | 0 |
| ModulusAnalysis.java:62:34:62:34 | k | 0 | 0 | 3 |
| ModulusAnalysis.java:62:34:62:34 | k | SSA def(k) | 0 | 3 |
| ModulusAnalysis.java:62:34:62:34 | k | SSA phi(k) | 0 | 0 |
| ModulusAnalysis.java:62:34:62:39 | ...+=... | 0 | 0 | 3 |
| ModulusAnalysis.java:62:34:62:39 | ...+=... | SSA def(k) | 0 | 3 |
| ModulusAnalysis.java:62:34:62:39 | ...+=... | SSA phi(k) | 3 | 0 |
| ModulusAnalysis.java:62:39:62:39 | 3 | 0 | 3 | 0 |
| ModulusAnalysis.java:63:32:63:32 | k | 0 | 0 | 3 |
| ModulusAnalysis.java:63:32:63:32 | k | SSA def(k) | 0 | 3 |
| ModulusAnalysis.java:63:32:63:32 | k | SSA phi(k) | 0 | 0 |
| ModulusAnalysis.java:66:38:66:39 | 42 | 0 | 42 | 0 |

View File

@@ -51,5 +51,17 @@ class ModulusAnalysis
}
}
void loops(int cap)
{
for (int i = 0; i < cap; i++)
System.out.println(i);
for (int j = 0; j < cap; j += 1)
System.out.println(j);
for (int k = 0; k < cap; k += 3)
System.out.println(k); // congruent 0 mod 3
}
int[] getArray(){ return new int[42]; }
}

View File

@@ -0,0 +1,62 @@
import com.google.common.base.Strings;
import com.google.common.base.Splitter;
import com.google.common.base.Joiner;
import java.util.Map;
import java.util.HashMap;
class Test {
String taint() { return "tainted"; }
void sink(Object o) {}
void test1() {
String x = taint();
sink(Strings.padStart(x, 10, ' '));
sink(Strings.padEnd(x, 10, ' '));
sink(Strings.repeat(x, 3));
sink(Strings.emptyToNull(Strings.nullToEmpty(x)));
sink(Strings.lenientFormat(x, 3));
sink(Strings.commonPrefix(x, "abc"));
sink(Strings.commonSuffix(x, "cde"));
sink(Strings.lenientFormat("%s = %s", x, 3));
}
void test2() {
String x = taint();
Splitter s = Splitter.on(x).omitEmptyStrings();
sink(s.split("x y z"));
sink(s.split(x));
sink(s.splitToList(x));
sink(s.withKeyValueSeparator("=").split("a=b"));
sink(s.withKeyValueSeparator("=").split(x));
}
void test3() {
String x = taint();
Joiner taintedJoiner = Joiner.on(x);
Joiner safeJoiner = Joiner.on(", ");
StringBuilder sb = new StringBuilder();
sink(safeJoiner.appendTo(sb, "a", "b", "c"));
sink(sb.toString());
sink(taintedJoiner.appendTo(sb, "a", "b", "c"));
sink(sb.toString());
sink(safeJoiner.appendTo(sb, "a", "b", "c"));
sink(sb.toString());
sb = new StringBuilder();
sink(safeJoiner.appendTo(sb, x, x));
Map<String, String> m = new HashMap<String, String>();
m.put("k", "v");
sink(safeJoiner.withKeyValueSeparator("=").join(m));
sink(safeJoiner.withKeyValueSeparator(x).join(m));
sink(taintedJoiner.useForNull("(null)").withKeyValueSeparator("=").join(m));
m.put("k2", x);
sink(safeJoiner.withKeyValueSeparator("=").join(m));
}
}

View File

@@ -0,0 +1,17 @@
| Test.java:15:20:15:26 | taint(...) | Test.java:17:14:17:41 | padStart(...) |
| Test.java:15:20:15:26 | taint(...) | Test.java:18:14:18:39 | padEnd(...) |
| Test.java:15:20:15:26 | taint(...) | Test.java:19:14:19:33 | repeat(...) |
| Test.java:15:20:15:26 | taint(...) | Test.java:20:14:20:56 | emptyToNull(...) |
| Test.java:15:20:15:26 | taint(...) | Test.java:21:14:21:40 | lenientFormat(...) |
| Test.java:15:20:15:26 | taint(...) | Test.java:24:14:24:51 | lenientFormat(...) |
| Test.java:28:20:28:26 | taint(...) | Test.java:32:14:32:23 | split(...) |
| Test.java:28:20:28:26 | taint(...) | Test.java:33:14:33:29 | splitToList(...) |
| Test.java:28:20:28:26 | taint(...) | Test.java:35:14:35:50 | split(...) |
| Test.java:39:20:39:26 | taint(...) | Test.java:46:14:46:54 | appendTo(...) |
| Test.java:39:20:39:26 | taint(...) | Test.java:47:14:47:26 | toString(...) |
| Test.java:39:20:39:26 | taint(...) | Test.java:48:14:48:51 | appendTo(...) |
| Test.java:39:20:39:26 | taint(...) | Test.java:49:14:49:26 | toString(...) |
| Test.java:39:20:39:26 | taint(...) | Test.java:52:14:52:42 | appendTo(...) |
| Test.java:39:20:39:26 | taint(...) | Test.java:57:14:57:56 | join(...) |
| Test.java:39:20:39:26 | taint(...) | Test.java:58:14:58:82 | join(...) |
| Test.java:39:20:39:26 | taint(...) | Test.java:60:14:60:58 | join(...) |

View File

@@ -0,0 +1,18 @@
import java
import semmle.code.java.dataflow.TaintTracking
class Conf extends TaintTracking::Configuration {
Conf() { this = "qltest:frameworks:guava" }
override predicate isSource(DataFlow::Node n) {
n.asExpr().(MethodAccess).getMethod().hasName("taint")
}
override predicate isSink(DataFlow::Node n) {
exists(MethodAccess ma | ma.getMethod().hasName("sink") | n.asExpr() = ma.getAnArgument())
}
}
from DataFlow::Node src, DataFlow::Node sink, Conf conf
where conf.hasFlow(src, sink)
select src, sink

View File

@@ -0,0 +1 @@
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/guava-30.0

View File

@@ -0,0 +1,58 @@
/*
* Copyright (C) 2008 The Guava 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.
*/
package com.google.common.base;
import java.util.Iterator;
import java.util.Map;
public class Joiner {
public static Joiner on(String separator) {
return null;
}
public final StringBuilder appendTo(StringBuilder builder, Object first, Object second, Object... rest) {
return null;
}
public final String join(Object first, Object second, Object... rest) {
return null;
}
public Joiner useForNull(final String nullText) {
return null;
}
public Joiner skipNulls() {
return null;
}
public MapJoiner withKeyValueSeparator(String keyValueSeparator) {
return null;
}
public static final class MapJoiner {
public StringBuilder appendTo(StringBuilder builder, Map<?, ?> map) {
return null;
}
public String join(Map<?, ?> map) {
return null;
}
public MapJoiner useForNull(String nullText) {
return null;
}
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (C) 2009 The Guava 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.
*/
package com.google.common.base;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public final class Splitter {
public static Splitter on(final String separator) {
return null;
}
public Splitter omitEmptyStrings() {
return null;;
}
public Iterable<String> split(final CharSequence sequence) {
return null;
}
public List<String> splitToList(CharSequence sequence) {
return null;
}
public MapSplitter withKeyValueSeparator(String separator) {
return null;
}
public static final class MapSplitter {
public Map<String, String> split(CharSequence sequence) {
return null;
}
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2010 The Guava 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.
*/
package com.google.common.base;
public final class Strings {
public static String nullToEmpty(String string) {
return null;
}
public static String emptyToNull(String string) {
return null;
}
public static boolean isNullOrEmpty(String string) {
return true;
}
public static String padStart(String string, int minLength, char padChar) {
return null;
}
public static String padEnd(String string, int minLength, char padChar) {
return null;
}
public static String repeat(String string, int count) {
return null;
}
public static String commonPrefix(CharSequence a, CharSequence b) {
return null;
}
public static String commonSuffix(CharSequence a, CharSequence b) {
return null;
}
public static String lenientFormat(String template, Object ... args) {
return null;
}
}

View File

@@ -19,6 +19,8 @@ import java.util.List;
import java.util.regex.Pattern;
import com.google.gson.Gson;
import com.google.gson.JsonParseException;
import com.semmle.js.dependencies.packument.Packument;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
@@ -84,7 +86,13 @@ public class Fetcher {
}
System.out.println("Fetching package metadata for " + packageName);
try (Reader reader = new BufferedReader(new InputStreamReader(fetch("https://registry.npmjs.org/" + packageName)))) {
return new Gson().fromJson(reader, Packument.class);
Packument packument = new Gson().fromJson(reader, Packument.class);
if (packument == null) {
throw new IOException("Malformed packument for " + packageName);
}
return packument;
} catch (JsonParseException ex) {
throw new IOException("Malformed packument for " + packageName, ex);
}
}

View File

@@ -117,7 +117,7 @@ import com.semmle.util.trap.TrapWriter;
* or "metadata" becomes an exclude path. Note that there are no implicit exclude paths.
*
* <p>The walking phase starts at each include path in turn and recursively traverses folders and
* files. Symlinks and hidden folders are skipped, but not hidden files. If it encounters a
* files. Symlinks and most hidden folders are skipped, but not hidden files. If it encounters a
* sub-folder whose path is excluded, traversal stops. If it encounters a file, that file becomes a
* candidate, unless its path is excluded. If the path of a file is both an include path and an
* exclude path, the inclusion takes precedence, and the file becomes a candidate after all.
@@ -746,6 +746,9 @@ protected DependencyInstallationResult preparePackagesAndDependencies(Set<Path>
if (file.getFileName().toString().equals("package.json")) {
try {
PackageJson packageJson = new Gson().fromJson(new WholeIO().read(file), PackageJson.class);
if (packageJson == null) {
continue;
}
file = file.toAbsolutePath();
if (tryRelativize(sourceRoot, file) == null) {
continue; // Ignore package.json files outside the source root.
@@ -1010,10 +1013,19 @@ protected DependencyInstallationResult preparePackagesAndDependencies(Set<Path>
return super.visitFile(file, attrs);
}
/**
* Returns {@code true} if {@code dir} is a hidden directory
* that should be skipped by default.
*/
private boolean isSkippedHiddenDirectory(Path dir) {
// Allow .github folders as they may contain YAML files relevant to GitHub repositories.
return dir.toFile().isHidden() && !dir.getFileName().toString().equals(".github");
}
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
throws IOException {
if (!dir.equals(currentRoot[0]) && (excludes.contains(dir) || dir.toFile().isHidden()))
if (!dir.equals(currentRoot[0]) && (excludes.contains(dir) || isSkippedHiddenDirectory(dir)))
return FileVisitResult.SKIP_SUBTREE;
if (Files.exists(dir.resolve("codeql-database.yml"))) {
return FileVisitResult.SKIP_SUBTREE;

View File

@@ -608,4 +608,19 @@ public class AutoBuildTests {
addFile(false, LGTM_SRC, "db/foo.js");
runTest();
}
@Test
public void hiddenGitHubFoldersAreIncluded() throws IOException {
Path tst_yml = addFile(true, LGTM_SRC, ".github", "workflows", "test.yml");
hide(tst_yml.getParent().getParent());
runTest();
}
@Test
public void hiddenGitHubFoldersCanBeExcluded() throws IOException {
envVars.put("LGTM_INDEX_FILTERS", "exclude:**/.github");
Path tst_yml = addFile(false, LGTM_SRC, ".github", "workflows", "test.yml");
hide(tst_yml.getParent().getParent());
runTest();
}
}

View File

@@ -0,0 +1,4 @@
files
| nullContents/package.json:0:0:0:0 | nullContents/package.json |
| tst.js:0:0:0:0 | tst.js |
packageJsons

View File

@@ -0,0 +1,5 @@
import javascript
query File files() { any() }
query PackageJSON packageJsons() { any() }

View File

@@ -0,0 +1,2 @@
// This file is just here to ensure some JS code is extracted
let x = 'hey';

Some files were not shown because too many files have changed in this diff Show More