mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Merge branch 'main' of github.com:github/codeql into python-port-path-injection
This commit is contained in:
@@ -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"
|
||||
|
||||
2
cpp/change-notes/2020-10-21-erroneous-types.md
Normal file
2
cpp/change-notes/2020-10-21-erroneous-types.md
Normal 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`).
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>.
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -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>.
|
||||
|
||||
@@ -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>.
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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() + "'"
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>).
|
||||
|
||||
@@ -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)."
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 | |
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 ---
|
||||
|
||||
@@ -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 ---
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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() }
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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`.
|
||||
*/
|
||||
|
||||
@@ -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) }
|
||||
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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()) }
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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 | [] |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]; }
|
||||
}
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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 |
|
||||
|
||||
@@ -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, " ")
|
||||
|
||||
101
docs/query-classification-and-display.md
Normal file
101
docs/query-classification-and-display.md
Normal 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.
|
||||
2
java/change-notes/2020-10-16-guava-flow-steps.md
Normal file
2
java/change-notes/2020-10-16-guava-flow-steps.md
Normal 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.
|
||||
@@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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`.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
6
java/ql/src/semmle/code/java/frameworks/guava/Guava.qll
Normal file
6
java/ql/src/semmle/code/java/frameworks/guava/Guava.qll
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Definitions for tracking taint steps through the Guava framework.
|
||||
*/
|
||||
|
||||
import java
|
||||
import StringUtils
|
||||
169
java/ql/src/semmle/code/java/frameworks/guava/StringUtils.qll
Normal file
169
java/ql/src/semmle/code/java/frameworks/guava/StringUtils.qll
Normal 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 }
|
||||
}
|
||||
@@ -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 |
|
||||
|
||||
@@ -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]; }
|
||||
}
|
||||
62
java/ql/test/library-tests/frameworks/guava/Test.java
Normal file
62
java/ql/test/library-tests/frameworks/guava/Test.java
Normal 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));
|
||||
}
|
||||
}
|
||||
17
java/ql/test/library-tests/frameworks/guava/flow.expected
Normal file
17
java/ql/test/library-tests/frameworks/guava/flow.expected
Normal 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(...) |
|
||||
18
java/ql/test/library-tests/frameworks/guava/flow.ql
Normal file
18
java/ql/test/library-tests/frameworks/guava/flow.ql
Normal 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
|
||||
1
java/ql/test/library-tests/frameworks/guava/options
Normal file
1
java/ql/test/library-tests/frameworks/guava/options
Normal file
@@ -0,0 +1 @@
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/guava-30.0
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
files
|
||||
| nullContents/package.json:0:0:0:0 | nullContents/package.json |
|
||||
| tst.js:0:0:0:0 | tst.js |
|
||||
packageJsons
|
||||
@@ -0,0 +1,5 @@
|
||||
import javascript
|
||||
|
||||
query File files() { any() }
|
||||
|
||||
query PackageJSON packageJsons() { any() }
|
||||
@@ -0,0 +1 @@
|
||||
null
|
||||
@@ -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
Reference in New Issue
Block a user