зеркало из https://github.com/github/codeql.git
Merge branch 'master' into taintedallocfp
This commit is contained in:
Коммит
ad337de6ce
|
@ -6,37 +6,36 @@
|
|||
|
||||
| **Query** | **Tags** | **Purpose** |
|
||||
|-----------------------------|-----------|--------------------------------------------------------------------|
|
||||
| `()`-declared function called with too few arguments (`cpp/too-few-arguments`) | Correctness | Find all cases where the number of arguments is less than the number of parameters of the function, provided the function is also properly declared/defined elsewhere. |
|
||||
| `()`-declared function called with mismatched arguments (`cpp/mismatched-function-arguments`) | Correctness | Find all cases where the types of arguments do not match the types of parameters of the function, provided the function is also properly declared/defined elsewhere. |
|
||||
| Call to alloca in a loop (`cpp/alloca-in-loop`) | reliability, correctness, external/cwe/cwe-770 | Finds calls to `alloca` in loops, which can lead to stack overflow if the number of iterations is large. Newly displayed on LGTM. |
|
||||
| Use of dangerous function (`dangerous-function-overflow`) | reliability, security, external/cwe/cwe-242 | Finds calls to `gets`, which does not guard against buffer overflow. These results were previously detected by the `cpp/potentially-dangerous-function` query. |
|
||||
| Call to alloca in a loop (`cpp/alloca-in-loop`) | reliability, correctness, external/cwe/cwe-770 | Finds calls to `alloca` in loops, which can lead to stack overflow if the number of iterations is large. Newly displayed [on LGTM](https://lgtm.com/rules/1508831665988/). |
|
||||
| Call to function with fewer arguments than declared parameters (`cpp/too-few-arguments`) | correctness, maintainability, security | Finds all cases where the number of arguments is fewer than the number of parameters of the function, provided the function is also properly declared/defined elsewhere. Results are displayed by default [on LGTM](https://lgtm.com/rules/1508860726279/). |
|
||||
| Call to a function with one or more incompatible arguments (`cpp/mistyped-function-arguments`) | correctness, maintainability | Finds all cases where the types of arguments do not match the types of parameters of the function, provided the function is also properly declared/defined elsewhere. Results are not displayed by default [on LGTM](https://lgtm.com/rules/1508849286093/). |
|
||||
| Use of dangerous function (`cpp/dangerous-function-overflow`) | reliability, security, external/cwe/cwe-242 | Finds calls to `gets`, which does not guard against buffer overflow. These results were previously detected by the `cpp/potentially-dangerous-function` query. Results for both queries are displayed by default on LGTM. |
|
||||
|
||||
## Changes to existing queries
|
||||
|
||||
| **Query** | **Expected impact** | **Change** |
|
||||
|----------------------------|------------------------|------------------------------------------------------------------|
|
||||
| Buffer not sufficient for string (`cpp/overflow-calculated`) | Fewer results | This query no longer reports results that would be found by the 'No space for zero terminator' (`cpp/no-space-for-terminator`) query. |
|
||||
| No space for zero terminator (`cpp/no-space-for-terminator`) | More correct results | This query now detects calls to `std::malloc`. |
|
||||
| Commented-out code (`cpp/commented-out-code`) | More correct results | Commented out preprocessor code is now detected by this query. |
|
||||
| Call to function with extraneous arguments (`cpp/futile-params`) | Improved coverage | Query has been generalized to find all cases where the number of arguments exceeds the number of parameters of the function, provided the function is also properly declared/defined elsewhere. |
|
||||
| Commented-out code (`cpp/commented-out-code`) | More correct results | Commented-out preprocessor code is now detected by this query. |
|
||||
| Comparison result is always the same | Fewer false positive results | The range analysis library is now more conservative about floating point values being possibly `NaN`. |
|
||||
| Constructor with default arguments will be used as a copy constructor (`cpp/constructor-used-as-copy-constructor`) | Lowered severity and precision | The severity and precision of this query have been reduced to "warning" and "low", respectively. This coding pattern is used intentionally and safely in a number of real-world projects. Results are no longer displayed on LGTM unless you choose to display them. |
|
||||
| Dead code due to goto or break statement (`cpp/dead-code-goto`) | Fewer false positive results | Functions containing preprocessor logic are now excluded from this analysis. |
|
||||
| Mismatching new/free or malloc/delete (`cpp/new-free-mismatch`) | Fewer false positive results | Fixed an issue where functions were being identified as allocation functions inappropriately. Also affects `cpp/new-array-delete-mismatch` and `cpp/new-delete-array-mismatch`. |
|
||||
| Overflow in uncontrolled allocation size (`cpp/uncontrolled-allocation-size`) | More correct results | This query has been reworked so that it can find a wider variety of results. |
|
||||
| Memory may not be freed (`cpp/memory-may-not-be-freed`) | More correct results | Support added for more Microsoft-specific allocation functions, including `LocalAlloc`, `GlobalAlloc`, `HeapAlloc` and `CoTaskMemAlloc`. |
|
||||
| Memory is never freed (`cpp/memory-never-freed`) | More correct results | Support added for more Microsoft-specific allocation functions, including `LocalAlloc`, `GlobalAlloc`, `HeapAlloc` and `CoTaskMemAlloc`. |
|
||||
| Memory may not be freed (`cpp/memory-may-not-be-freed`) | More correct results | Support added for more Microsoft-specific allocation functions, including `LocalAlloc`, `GlobalAlloc`, `HeapAlloc` and `CoTaskMemAlloc`. |
|
||||
| Mismatching new/free or malloc/delete (`cpp/new-free-mismatch`) | Fewer false positive results | Fixed an issue where functions were being identified as allocation functions inappropriately. This correction also affects `cpp/new-array-delete-mismatch` and `cpp/new-delete-array-mismatch`. |
|
||||
| No space for zero terminator (`cpp/no-space-for-terminator`) | More correct results | This query now detects calls to `std::malloc`. |
|
||||
| Overflow in uncontrolled allocation size (`cpp/uncontrolled-allocation-size`) | More correct results | This query has been reworked so that it can find a wider variety of results. |
|
||||
| Resource not released in destructor (`cpp/resource-not-released-in-destructor`) | Fewer false positive results | Resource allocation and deallocation functions are now determined more accurately. |
|
||||
| Comparison result is always the same | Fewer false positive results | The range analysis library is now more conservative about floating point values being possibly `NaN` |
|
||||
| Use of potentially dangerous function | More correct results | Calls to `localtime`, `ctime` and `asctime` are now detected by this query. |
|
||||
| Wrong type of arguments to formatting function (`cpp/wrong-type-format-argument`) | More correct results and fewer false positive results | This query now more accurately identifies wide and non-wide string/character format arguments on different platforms. Platform detection has also been made more accurate for the purposes of this query. |
|
||||
| Wrong type of arguments to formatting function (`cpp/wrong-type-format-argument`) | Fewer false positive results | Non-standard uses of %L are now understood. |
|
||||
| `()`-declared function called with too many arguments (`cpp/futile-params`) | Improved coverage | Query has been generalized to find all cases where the number of arguments exceedes the number of parameters of the function, provided the function is also properly declared/defined elsewhere. |
|
||||
| Use of potentially dangerous function (`cpp/potentially-dangerous-function`) | Fewer results | Results relating to the standard library `gets` function have been moved into a new query (`dangerous-function-overflow`). |
|
||||
| Constructor with default arguments will be used as a copy constructor (`cpp/constructor-used-as-copy-constructor`) | Lowered severity and precision | The severity and precision of this query have been reduced to "warning" and "low", respectively, due to this coding pattern being used intentionally and safely in a number of real-world projects. |
|
||||
| Wrong type of arguments to formatting function (`cpp/wrong-type-format-argument`) | More correct results and fewer false positive results | This query now understands non-standard uses of `%L`. In addition, it more accurately identifies wide and non-wide string/character format arguments on different platforms. |
|
||||
| Use of potentially dangerous function (`cpp/potentially-dangerous-function`) | Fewer results | Results relating to the standard library `gets` function have been moved into a new query (`cpp/dangerous-function-overflow`). |
|
||||
|
||||
## Changes to QL libraries
|
||||
- The predicate `Declaration.hasGlobalName` now only holds for declarations that are not nested in a class. For example, it no longer holds for a member function `MyClass::myFunction` or a constructor `MyClass::MyClass`, whereas previously it would classify those two declarations as global names.
|
||||
- In class `Declaration`, predicates `getQualifiedName/0` and `hasQualifiedName/1` are no longer recommended for finding functions by name. Instead, use `hasGlobalName/1` and the new `hasQualifiedName/2` and `hasQualifiedName/3` predicates. This improves performance and makes it more reliable to identify names involving templates and inline namespaces.
|
||||
- Additional support for definition by reference has been added to the `semmle.code.cpp.dataflow.TaintTracking` library.
|
||||
- The taint tracking library now includes taint-specific edges for functions modeled in `semmle.code.cpp.models.interfaces.DataFlow`.
|
||||
- The taint tracking library adds flow through library functions that are modeled in `semmle.code.cpp.models.interfaces.Taint`. Queries can add subclasses of `TaintFunction` to specify additional flow.
|
||||
- In class `Declaration`, predicates `getQualifiedName/0` and `hasQualifiedName/1` are no longer recommended for finding functions by name. Instead, use `hasGlobalName/1` and the new `hasQualifiedName/2` and `hasQualifiedName/3` predicates. This improves performance and identifies names involving templates and inline namespaces more reliably.
|
||||
- Additional support for definition by reference has been added to the `semmle.code.cpp.dataflow.TaintTracking` library, including:
|
||||
- Taint-specific edges for functions modeled in `semmle.code.cpp.models.interfaces.DataFlow`.
|
||||
- Flow through library functions that are modeled in `semmle.code.cpp.models.interfaces.Taint`. Queries can add subclasses of `TaintFunction` to specify additional flow.
|
||||
- There is a new `FoldExpr` class, representing C++17 fold expressions.
|
||||
- The member predicates `DeclarationEntry.getUnspecifiedType`, `Expr.getUnspecifiedType`, and `Variable.getUnspecifiedType` have been added. These should be preferred over the existing `getUnderlyingType` predicates.
|
|
@ -1,12 +1,16 @@
|
|||
# Improvements to C# analysis
|
||||
|
||||
## General improvements
|
||||
|
||||
C# analysis now supports the extraction and analysis of many C# 8 features. For details see [Changes to code extraction](#changes-to-code-extraction) and [Changes to QL libraries](#changes-to-ql-libraries) below.
|
||||
|
||||
## Changes to existing queries
|
||||
|
||||
| **Query** | **Expected impact** | **Change** |
|
||||
|------------------------------|------------------------|-----------------------------------|
|
||||
| Class defines a field that uses an ICryptoTransform class in a way that would be unsafe for concurrent threads (`cs/thread-unsafe-icryptotransform-field-in-class`) | Fewer false positive results | The criteria for a result has changed to include nested properties, nested fields and collections. The format of the alert message has changed to highlight the static field. |
|
||||
| Constant condition (`cs/constant-condition`) | Fewer false positive results | Results have been removed where the `null` value is in a conditional expression on the left hand side of a null-coalescing expression. For example, in `(a ? b : null) ?? c`, `null` is not considered to be a constant condition. |
|
||||
| Useless upcast (`cs/useless-upcast`) | Fewer false positive results | Results have been removed where the upcast is used to disambiguate the target of a constructor call. |
|
||||
| Class defines a field that uses an ICryptoTransform class in a way that would be unsafe for concurrent threads (`cs/thread-unsafe-icryptotransform-field-in-class`) | Fewer false positive results | The criteria for a result has changed to include nested properties, nested fields, and collections. The format of the alert message has changed to highlight the static field. |
|
||||
| Constant condition (`cs/constant-condition`) | Fewer false positive results | The query now ignores code where the `null` value is in a conditional expression on the left hand side of a null-coalescing expression. For example, in `(a ? b : null) ?? c`, `null` is not considered to be a constant condition. |
|
||||
| Useless upcast (`cs/useless-upcast`) | Fewer false positive results | The query now ignores code where the upcast is used to disambiguate the target of a constructor call. |
|
||||
|
||||
## Changes to code extraction
|
||||
|
||||
|
@ -17,12 +21,12 @@
|
|||
- `static` modifiers on local functions
|
||||
- Null-coalescing assignment expressions
|
||||
|
||||
* The `unmanaged` type parameter constraint is now extracted.
|
||||
* The `unmanaged` type parameter constraint is also now extracted.
|
||||
|
||||
## Changes to QL libraries
|
||||
|
||||
* The class `Attribute` has two new predicates: `getConstructorArgument()` and `getNamedArgument()`. The first predicate returns arguments to the underlying constructor call and the latter returns named arguments for initializing fields and properties.
|
||||
* The class `TypeParameterConstraints` has a new predicate `hasUnmanagedTypeConstraint()`, indicating that the type parameter has the `unmanaged` constraint.
|
||||
* The class `Attribute` has two new predicates: `getConstructorArgument()` and `getNamedArgument()`. The first predicate returns arguments to the underlying constructor call and the second returns named arguments for initializing fields and properties.
|
||||
* The class `TypeParameterConstraints` has a new predicate `hasUnmanagedTypeConstraint()`. This shows whether the type parameter has the `unmanaged` constraint.
|
||||
* The following QL classes have been added to model C# 8 features:
|
||||
- Class `AssignCoalesceExpr` models null-coalescing assignment, for example `x ??= y`
|
||||
- Class `IndexExpr` models from-end index expressions, for example `^1`
|
||||
|
@ -37,5 +41,3 @@
|
|||
- Class `Switch` models both `SwitchExpr` and `SwitchStmt`
|
||||
- Class `Case` models both `CaseStmt` and `SwitchCaseExpr`
|
||||
- Class `UsingStmt` models both `UsingBlockStmt` and `UsingDeclStmt`
|
||||
|
||||
## Changes to autobuilder
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
# Improvements to Java analysis
|
||||
|
||||
## New queries
|
||||
|
||||
| **Query** | **Tags** | **Purpose** |
|
||||
|-----------------------------|-----------|--------------------------------------------------------------------|
|
||||
|
||||
## Changes to existing queries
|
||||
|
||||
| **Query** | **Expected impact** | **Change** |
|
||||
|
@ -19,14 +14,13 @@
|
|||
`checkArgument` and `checkState` methods in
|
||||
`com.google.common.base.Preconditions`, the `isTrue` and `validState` methods
|
||||
in `org.apache.commons.lang3.Validate`, as well as any similar custom
|
||||
methods. This means that more guards are recognized yielding precision
|
||||
improvements in a number of queries including `java/index-out-of-bounds`,
|
||||
methods. This means that more guards are recognized which improves the precision of a number of queries including `java/index-out-of-bounds`,
|
||||
`java/dereferenced-value-may-be-null`, and `java/useless-null-check`.
|
||||
* The default sanitizer in taint tracking has been made more precise. The
|
||||
sanitizer works by looking for guards that inspect tainted strings, and it
|
||||
used to work at the level of individual variables. This has been changed to
|
||||
use the `Guards` library, such that only guarded variable accesses are
|
||||
sanitized. This may give additional results in the security queries.
|
||||
* Spring framework support is enhanced by taking into account additional
|
||||
sanitizer works by looking for guards that inspect tainted strings. It
|
||||
previously worked at the level of individual variables. Now it
|
||||
uses the `Guards` library, such that only guarded variable accesses are
|
||||
sanitized. This may give additional results for security queries.
|
||||
* Spring framework support now takes into account additional
|
||||
annotations that indicate remote user input. This affects all security
|
||||
queries, which may yield additional results.
|
||||
queries, which may give additional results.
|
||||
|
|
|
@ -31,22 +31,18 @@ The increased precision in tracking of values through `*` arguments may remove f
|
|||
Overall the number of true positive results should increase and the number false negative results should decline.
|
||||
We welcome feedback on the new implementation, particularly any surprising changes in results.
|
||||
|
||||
|
||||
## New queries
|
||||
| **Query** | **Tags** | **Purpose** |
|
||||
|-----------|----------|-------------|
|
||||
| Accepting unknown SSH host keys when using Paramiko (`py/paramiko-missing-host-key-validation`) | security, external/cwe/cwe-295 | Finds instances where Paramiko is configured to accept unknown host keys. Results are shown on LGTM by default. |
|
||||
| Use of 'return' or 'yield' outside a function (`py/return-or-yield-outside-function`) | reliability, correctness | Finds instances where `return`, `yield`, and `yield from` are used outside a function. Results are not shown on LGTM by default. |
|
||||
|
||||
## Changes to existing queries
|
||||
|
||||
| **Query** | **Expected impact** | **Change** |
|
||||
|-----------|---------------------|------------|
|
||||
| **Query** | **Tags** | **Purpose** |
|
||||
|-----------|----------|-------------|
|
||||
| Accepting unknown SSH host keys when using Paramiko (`py/paramiko-missing-host-key-validation`) | security, external/cwe/cwe-295 | Finds instances where Paramiko is configured to accept unknown host keys. Results are shown [on LGTM](https://lgtm.com/rules/1508297729270/) by default. |
|
||||
| Use of 'return' or 'yield' outside a function (`py/return-or-yield-outside-function`) | reliability, correctness | Finds instances where `return`, `yield`, and `yield from` are used outside a function. Results are not shown on LGTM by default. |
|
||||
|
||||
## Changes to code extraction
|
||||
|
||||
* *Series of bullet points*
|
||||
* String literals as expressions within literal string interpolation (f-strings) are now handled correctly.
|
||||
|
||||
## Changes to QL libraries
|
||||
* The Python extractor now handles invalid input more robustly. In particular, it exits gracefully when:
|
||||
|
||||
* *Series of bullet points*
|
||||
* A non-existent file or directory is specified using the `--path` option, or as a file name.
|
||||
* An invalid number is specified for the `--max-procs` option.
|
||||
|
|
|
@ -15,5 +15,7 @@
|
|||
|
||||
## Changes to QL libraries
|
||||
|
||||
- The predicate `Variable.getAnAssignedValue()` now reports assignments to fields resulting from aggregate initialization (` = {...}`).
|
||||
- The predicate `TypeMention.toString()` has been simplified to always return the string "`type mention`". This may improve performance when using `Element.toString()` or its descendants.
|
||||
- The `semmle.code.cpp.security.TaintTracking` library now considers a pointer difference calculation as blocking taint flow.
|
||||
- Fixed the `LocalScopeVariableReachability.qll` library's handling of loops with an entry condition is both always true upon first entry, and where there is more than one control flow path through the loop condition. This change increases the accuracy of the `LocalScopeVariableReachability.qll` library and queries which depend on it.
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# Improvements to C# analysis
|
||||
|
||||
## Changes to existing queries
|
||||
|
||||
| **Query** | **Expected impact** | **Change** |
|
||||
|------------------------------|------------------------|-----------------------------------|
|
||||
| Dispose may not be called if an exception is thrown during execution (`cs/dispose-not-called-on-throw`) | Fewer false positive results | Results have been removed where an object is disposed both by a `using` statement and a `Dispose` call. |
|
||||
|
||||
## Changes to code extraction
|
||||
|
||||
## Changes to QL libraries
|
||||
|
||||
## Changes to autobuilder
|
|
@ -0,0 +1,10 @@
|
|||
# Improvements to Java analysis
|
||||
|
||||
## Changes to existing queries
|
||||
|
||||
| **Query** | **Expected impact** | **Change** |
|
||||
|----------------------------|------------------------|------------------------------------------------------------------|
|
||||
| Equals method does not inspect argument type (`java/unchecked-cast-in-equals`) | Fewer false positive and more true positive results | Precision has been improved by doing a bit of inter-procedural analysis and relying less on ad-hoc method names. |
|
||||
|
||||
## Changes to QL libraries
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
# Improvements to JavaScript analysis
|
||||
|
||||
## General improvements
|
||||
|
||||
* Support for the following frameworks and libraries has been improved:
|
||||
- [cross-spawn](https://www.npmjs.com/package/cross-spawn)
|
||||
- [cross-spawn-async](https://www.npmjs.com/package/cross-spawn-async)
|
||||
- [exec](https://www.npmjs.com/package/exec)
|
||||
- [execa](https://www.npmjs.com/package/execa)
|
||||
- [exec-async](https://www.npmjs.com/package/exec-async)
|
||||
- [express](https://www.npmjs.com/package/express)
|
||||
- [remote-exec](https://www.npmjs.com/package/remote-exec)
|
||||
|
||||
## New queries
|
||||
|
||||
| **Query** | **Tags** | **Purpose** |
|
||||
|-----------|----------|-------------|
|
||||
| | | |
|
||||
|
||||
## Changes to existing queries
|
||||
|
||||
| **Query** | **Expected impact** | **Change** |
|
||||
|--------------------------------|------------------------------|---------------------------------------------------------------------------|
|
||||
|
||||
|
||||
## Changes to QL libraries
|
||||
|
|
@ -13,7 +13,9 @@ Note that where there are several versions or dialects of a language, the suppor
|
|||
|
||||
.. container:: footnote-group
|
||||
|
||||
.. [1] The best results are achieved with COBOL code that stays close to the ANSI 85 standard.
|
||||
.. [2] Builds that execute on Java 6 to 11 can be analyzed. The analysis understands Java 11 language features.
|
||||
.. [3] JSX and Flow code, YAML, JSON, and HTML files may also be analyzed with JavaScript files.
|
||||
.. [4] TypeScript analysis is performed by running the JavaScript extractor with TypeScript enabled. This is the default for LGTM.
|
||||
.. [1] Support for the Arm Compiler (armcc) is preliminary.
|
||||
.. [2] In addition, support is included for the preview features of C# 8.0 and .NET Core 3.0.
|
||||
.. [3] The best results are achieved with COBOL code that stays close to the ANSI 85 standard.
|
||||
.. [4] Builds that execute on Java 6 to 12 can be analyzed. The analysis understands Java 12 language features.
|
||||
.. [5] JSX and Flow code, YAML, JSON, HTML, and XML files may also be analyzed with JavaScript files.
|
||||
.. [6] TypeScript analysis is performed by running the JavaScript extractor with TypeScript enabled. This is the default for LGTM.
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
Language,Variants,Compilers,Extensions
|
||||
C/C++,"C89, C99, C11, C++98, C++03, C++11, C++14, C++17","Clang extensions (up to Clang 6.0)
|
||||
C/C++,"C89, C99, C11, C++98, C++03, C++11, C++14, C++17","Clang extensions (up to Clang 8.0)
|
||||
|
||||
GNU extensions (up to GCC 7.3),
|
||||
GNU extensions (up to GCC 8.3),
|
||||
|
||||
Microsoft extensions (up to VS 2017)","``.cpp``, ``.c++``, ``.cxx``, ``.hpp``, ``.hh``, ``.h++``, ``.hxx``, ``.c``, ``.cc``, ``.h``"
|
||||
C#,C# up to 7.2 together with .NET versions up to 4.7.1,"Microsoft Visual Studio up to 2017,
|
||||
Microsoft extensions (up to VS 2019),
|
||||
|
||||
.NET Core up to 2.1","``.sln``, ``.csproj``, ``.cs``, ``.cshtml``, ``.xaml``"
|
||||
COBOL,ANSI 85 or newer [1]_.,Not applicable,"``.cbl``, ``.CBL``, ``.cpy``, ``.CPY``, ``.copy``, ``.COPY``"
|
||||
Java,"Java 6 to 11 [2]_.","javac (OpenJDK and Oracle JDK)
|
||||
Arm Compiler 5.0 [1]_.","``.cpp``, ``.c++``, ``.cxx``, ``.hpp``, ``.hh``, ``.h++``, ``.hxx``, ``.c``, ``.cc``, ``.h``"
|
||||
C#,C# up to 7.3. with .NET up to 4.8 [2]_.,"Microsoft Visual Studio up to 2019,
|
||||
|
||||
.NET Core up to 2.2","``.sln``, ``.csproj``, ``.cs``, ``.cshtml``, ``.xaml``"
|
||||
COBOL,ANSI 85 or newer [3]_.,Not applicable,"``.cbl``, ``.CBL``, ``.cpy``, ``.CPY``, ``.copy``, ``.COPY``"
|
||||
Java,"Java 6 to 12 [4]_.","javac (OpenJDK and Oracle JDK)
|
||||
|
||||
Eclipse compiler for Java (ECJ) batch compiler",``.java``
|
||||
JavaScript,ECMAScript 2019 or lower,Not applicable,"``.js``, ``.jsx``, ``.mjs``, ``.es``, ``.es6``, ``.htm``, ``.html``, ``.xhm``, ``.xhtml``, ``.vue``, ``.json``, ``.yaml``, ``.yml``, ``.raml`` [3]_."
|
||||
JavaScript,ECMAScript 2019 or lower,Not applicable,"``.js``, ``.jsx``, ``.mjs``, ``.es``, ``.es6``, ``.htm``, ``.html``, ``.xhm``, ``.xhtml``, ``.vue``, ``.json``, ``.yaml``, ``.yml``, ``.raml``, ``.xml`` [5]_."
|
||||
Python,"2.7, 3.5, 3.6, 3.7",Not applicable,``.py``
|
||||
TypeScript [4]_.,"2.6-3.5",Standard TypeScript compiler,"``.ts``, ``.tsx``"
|
||||
TypeScript [6]_.,"2.6-3.5",Standard TypeScript compiler,"``.ts``, ``.tsx``"
|
||||
|
|
|
|
@ -43,11 +43,15 @@ class CastToPointerArithFlow extends DataFlow::Configuration {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `derived` has a (possibly indirect) base class of `base`, and at least one new
|
||||
* field has been introduced in the inheritance chain after `base`.
|
||||
*/
|
||||
predicate introducesNewField(Class derived, Class base) {
|
||||
derived.getABaseClass+() = base and
|
||||
(
|
||||
exists(Field f |
|
||||
f.getDeclaringType() = derived
|
||||
f.getDeclaringType() = derived and
|
||||
derived.getABaseClass+() = base
|
||||
) or
|
||||
introducesNewField(derived.getABaseClass(), base)
|
||||
)
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
When eras change, date and time conversions that rely on a hard-coded era start date need to be reviewed. Conversions relying on Japanese dates in the current era can produce an ambiguous date.
|
||||
The values for the current Japanese era dates should be read from a source that will be updated, such as the Windows registry.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
<a href="https://blogs.msdn.microsoft.com/shawnste/2018/04/12/the-japanese-calendars-y2k-moment/">The Japanese Calendar's Y2K Moment</a>.
|
||||
</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* @name Hard-coded Japanese era start date
|
||||
* @description Japanese era changes can lead to code behaving differently. Avoid hard-coding Japanese era start dates.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @id cpp/japanese-era/constructor-or-method-with-exact-era-date
|
||||
* @precision medium
|
||||
* @tags reliability
|
||||
* japanese-era
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
from Call cc, int i
|
||||
where
|
||||
cc.getArgument(i).getValue().toInt() = 1989 and
|
||||
cc.getArgument(i + 1).getValue().toInt() = 1 and
|
||||
cc.getArgument(i + 2).getValue().toInt() = 8
|
||||
select cc, "Call that appears to have hard-coded Japanese era start date as parameter."
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
When eras change, date and time conversions that rely on a hard-coded era start date need to be reviewed. Conversions relying on Japanese dates in the current era can produce an ambiguous date.
|
||||
The values for the current Japanese era dates should be read from a source that will be updated, such as the Windows registry.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
<a href="https://blogs.msdn.microsoft.com/shawnste/2018/04/12/the-japanese-calendars-y2k-moment/">The Japanese Calendar's Y2K Moment</a>.
|
||||
</li>
|
||||
</references>
|
||||
</qhelp>
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* @name Hard-coded Japanese era start date
|
||||
* @description Japanese era changes can lead to code behaving differently. Avoid hard-coding Japanese era start dates.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @id cpp/japanese-era/struct-with-exact-era-date
|
||||
* @tags reliability
|
||||
* japanese-era
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.commons.DateTime
|
||||
|
||||
from
|
||||
StructLikeClass s, YearFieldAccess year, MonthFieldAccess month, DayFieldAccess day,
|
||||
Operation yearAssignment, Operation monthAssignment, Operation dayAssignment
|
||||
where
|
||||
s.getAField().getAnAccess() = year and
|
||||
yearAssignment.getAnOperand() = year and
|
||||
yearAssignment.getAnOperand().getValue().toInt() = 1989 and
|
||||
s.getAField().getAnAccess() = month and
|
||||
monthAssignment.getAnOperand() = month and
|
||||
monthAssignment.getAnOperand().getValue().toInt() = 1 and
|
||||
s.getAField().getAnAccess() = day and
|
||||
dayAssignment.getAnOperand() = day and
|
||||
dayAssignment.getAnOperand().getValue().toInt() = 8
|
||||
select year, "A time struct that is initialized with exact Japanese calendar era start date."
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<include src="LeapYear.qhelp" />
|
||||
|
||||
<p>When performing arithmetic operations on a variable that represents a date, leap years must be taken into account.
|
||||
It is not safe to assume that a year is 365 days long.</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>Determine whether the time span in question contains a leap day, then perform the calculation using the correct number
|
||||
of days. Alternatively, use an established library routine that already contains correct leap year logic.</p>
|
||||
</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>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>
|
||||
</qhelp>
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* @name Year field changed using an arithmetic operation is used on an unchecked time conversion function
|
||||
* @description A year field changed using an arithmetic operation is used on a time conversion function, but the return value of the function is not checked for success or failure.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @id cpp/leap-year/adding-365-days-per-year
|
||||
* @precision medium
|
||||
* @tags security
|
||||
* leap-year
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import LeapYear
|
||||
import semmle.code.cpp.dataflow.DataFlow
|
||||
|
||||
from Expr source, Expr sink, PossibleYearArithmeticOperationCheckConfiguration config
|
||||
where config.hasFlow(DataFlow::exprNode(source), DataFlow::exprNode(sink))
|
||||
select sink,
|
||||
"This arithmetic operation $@ uses a constant value of 365 ends up modifying the date/time located at $@, without considering leap year scenarios.",
|
||||
source, source.toString(), sink, sink.toString()
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<fragment>
|
||||
<p>The leap year rule for the Gregorian calendar, which has become the internationally accepted civil calendar, is: every year that is exactly divisible by four is a leap year, except for years that are exactly divisible by 100, but these centurial years are leap years if they are exactly divisible by 400.</p>
|
||||
<p>A leap year bug occurs when software (in any language) is written without consideration of leap year logic, or with flawed logic to calculate leap years; which typically results in incorrect results.</p>
|
||||
<p>The impact of these bugs may range from almost unnoticeable bugs such as an incorrect date, to severe bugs that affect reliability, availability or even the security of the affected system.</p>
|
||||
</fragment>
|
||||
</qhelp>
|
|
@ -0,0 +1,276 @@
|
|||
/**
|
||||
* Provides a library for helping create leap year related queries
|
||||
*/
|
||||
import cpp
|
||||
import semmle.code.cpp.dataflow.DataFlow
|
||||
import semmle.code.cpp.controlflow.Guards
|
||||
import semmle.code.cpp.commons.DateTime
|
||||
|
||||
/**
|
||||
* Get the top-level BinaryOperation enclosing the expression e
|
||||
*/
|
||||
BinaryOperation getATopLevelBinaryOperationExpression(Expr e)
|
||||
{
|
||||
result = e.getEnclosingElement().(BinaryOperation)
|
||||
or
|
||||
result = getATopLevelBinaryOperationExpression( e.getEnclosingElement())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the top-level binary operation for expression `e` includes the operator specified in `operator` with an operand specified by `valueToCheck`
|
||||
*/
|
||||
predicate additionalLogicalCheck( Expr e, string operation, int valueToCheck) {
|
||||
exists(BinaryLogicalOperation bo |
|
||||
bo = getATopLevelBinaryOperationExpression(e) |
|
||||
exists( BinaryArithmeticOperation bao |
|
||||
bao = bo.getAChild*() |
|
||||
bao.getAnOperand().getValue().toInt() = valueToCheck
|
||||
and bao.getOperator() = operation
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Operation that seems to be checking for leap year
|
||||
*/
|
||||
class CheckForLeapYearOperation extends Operation {
|
||||
CheckForLeapYearOperation() {
|
||||
exists( BinaryArithmeticOperation bo |
|
||||
bo = this |
|
||||
bo.getAnOperand().getValue().toInt() = 4
|
||||
and bo.getOperator().toString() = "%"
|
||||
and additionalLogicalCheck( this.getEnclosingElement(), "%", 100)
|
||||
and additionalLogicalCheck( this.getEnclosingElement(), "%", 400)
|
||||
)
|
||||
}
|
||||
|
||||
override string getOperator() { result = "LeapYearCheck" }
|
||||
}
|
||||
|
||||
/**
|
||||
* abstract class of type YearFieldAccess that would represent an access to a year field on a struct and is used for arguing about leap year calculations
|
||||
*/
|
||||
abstract class LeapYearFieldAccess extends YearFieldAccess {
|
||||
/**
|
||||
* Holds if the field access is a modification,
|
||||
* and it involves an arithmetic operation
|
||||
*/
|
||||
predicate isModifiedByArithmeticOperation() {
|
||||
this.isModified()
|
||||
and exists( Operation op |
|
||||
op.getAnOperand() = this
|
||||
and ( op instanceof AssignArithmeticOperation
|
||||
or exists( BinaryArithmeticOperation bao |
|
||||
bao = op.getAnOperand())
|
||||
or op instanceof PostfixCrementOperation
|
||||
or op instanceof PrefixCrementOperation
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the field access is a modification,
|
||||
* and it involves an arithmetic operation.
|
||||
* In order to avoid false positives, the operation does not includes values that are normal for year normalization.
|
||||
*
|
||||
* 1900 - struct tm counts years since 1900
|
||||
* 1980/80 - FAT32 epoch
|
||||
*/
|
||||
predicate isModifiedByArithmeticOperationNotForNormalization() {
|
||||
this.isModified()
|
||||
and exists( Operation op |
|
||||
op.getAnOperand() = this
|
||||
and ( (op instanceof AssignArithmeticOperation
|
||||
and not ( op.getAChild().getValue().toInt() = 1900
|
||||
or op.getAChild().getValue().toInt() = 2000
|
||||
or op.getAChild().getValue().toInt() = 1980
|
||||
or op.getAChild().getValue().toInt() = 80
|
||||
// Special case for transforming marshaled 2-digit year date:
|
||||
// theTime.wYear += 100*value;
|
||||
or exists( MulExpr mulBy100 | mulBy100 = op.getAChild() |
|
||||
mulBy100.getAChild().getValue().toInt() = 100 )))
|
||||
or exists( BinaryArithmeticOperation bao |
|
||||
bao = op.getAnOperand()
|
||||
and not ( bao.getAChild().getValue().toInt() = 1900
|
||||
or bao.getAChild().getValue().toInt() = 2000
|
||||
or bao.getAChild().getValue().toInt() = 1980
|
||||
or bao.getAChild().getValue().toInt() = 80
|
||||
// Special case for transforming marshaled 2-digit year date:
|
||||
// theTime.wYear += 100*value;
|
||||
or exists( MulExpr mulBy100 | mulBy100 = op.getAChild() |
|
||||
mulBy100.getAChild().getValue().toInt() = 100 ))
|
||||
)
|
||||
or op instanceof PostfixCrementOperation
|
||||
or op instanceof PrefixCrementOperation
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Holds if the top-level binary operation includes a modulus operator with an operand specified by `valueToCheck`
|
||||
*/
|
||||
predicate additionalModulusCheckForLeapYear( int valueToCheck) {
|
||||
additionalLogicalCheck(this, "%", valueToCheck)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the top-level binary operation includes an addition or subtraction operator with an operand specified by `valueToCheck`
|
||||
*/
|
||||
predicate additionalAdditionOrSubstractionCheckForLeapYear( int valueToCheck) {
|
||||
additionalLogicalCheck(this, "+", valueToCheck)
|
||||
or additionalLogicalCheck(this, "-", valueToCheck)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds true if this object is used on a modulus 4 operation, which would likely indicate the start of a leap year check
|
||||
*/
|
||||
predicate isUsedInMod4Operation()
|
||||
{
|
||||
not this.isModified() and
|
||||
exists( BinaryArithmeticOperation bo |
|
||||
bo.getAnOperand() = this
|
||||
and bo.getAnOperand().getValue().toInt() = 4
|
||||
and bo.getOperator().toString() = "%"
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds true if this object seems to be used in a valid gregorian calendar leap year check
|
||||
*/
|
||||
predicate isUsedInCorrectLeapYearCheck()
|
||||
{
|
||||
// The Gregorian leap year rule is:
|
||||
// Every year that is exactly divisible by four is a leap year,
|
||||
// except for years that are exactly divisible by 100,
|
||||
// but these centurial years are leap years if they are exactly divisible by 400
|
||||
//
|
||||
// https://aa.usno.navy.mil/faq/docs/calendars.php
|
||||
this.isUsedInMod4Operation()
|
||||
and additionalModulusCheckForLeapYear(400)
|
||||
and additionalModulusCheckForLeapYear(100)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* YearFieldAccess for SYSTEMTIME struct
|
||||
*/
|
||||
class StructSystemTimeLeapYearFieldAccess extends LeapYearFieldAccess {
|
||||
StructSystemTimeLeapYearFieldAccess() {
|
||||
this.toString().matches("wYear")
|
||||
}
|
||||
}
|
||||
/**
|
||||
* YearFieldAccess for struct tm
|
||||
*/
|
||||
class StructTmLeapYearFieldAccess extends LeapYearFieldAccess {
|
||||
StructTmLeapYearFieldAccess() {
|
||||
this.toString().matches("tm_year")
|
||||
}
|
||||
|
||||
override predicate isUsedInCorrectLeapYearCheck()
|
||||
{
|
||||
this.isUsedInMod4Operation()
|
||||
and additionalModulusCheckForLeapYear(400)
|
||||
and additionalModulusCheckForLeapYear(100)
|
||||
// tm_year represents years since 1900
|
||||
and ( additionalAdditionOrSubstractionCheckForLeapYear(1900)
|
||||
// some systems may use 2000 for 2-digit year conversions
|
||||
or additionalAdditionOrSubstractionCheckForLeapYear(2000)
|
||||
// converting from/to Unix epoch
|
||||
or additionalAdditionOrSubstractionCheckForLeapYear(1970)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* FunctionCall that includes an operation that is checking for leap year
|
||||
*/
|
||||
class ChecksForLeapYearFunctionCall extends FunctionCall {
|
||||
ChecksForLeapYearFunctionCall() {
|
||||
exists( Function f, CheckForLeapYearOperation clyo |
|
||||
f.getACallToThisFunction() = this |
|
||||
clyo.getEnclosingFunction() = f
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DataFlow::Configuration for finding a variable access that would flow into
|
||||
* a function call that includes an operation to check for leap year
|
||||
*/
|
||||
class LeapYearCheckConfiguration extends DataFlow::Configuration {
|
||||
LeapYearCheckConfiguration() {
|
||||
this = "LeapYearCheckConfiguration"
|
||||
}
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
exists( VariableAccess va |
|
||||
va = source.asExpr()
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists( ChecksForLeapYearFunctionCall fc |
|
||||
sink.asExpr() = fc.getAnArgument()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* DataFlow::Configuration for finding an operation w/hardcoded 365 that will flow into a FILEINFO field
|
||||
*/
|
||||
class FiletimeYearArithmeticOperationCheckConfiguration extends DataFlow::Configuration {
|
||||
FiletimeYearArithmeticOperationCheckConfiguration() {
|
||||
this = "FiletimeYearArithmeticOperationCheckConfiguration"
|
||||
}
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
exists( Expr e, Operation op |
|
||||
e = source.asExpr() |
|
||||
op.getAChild*().getValue().toInt()=365
|
||||
and op.getAChild*() = e
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists( StructLikeClass dds, FieldAccess fa, AssignExpr aexpr, Expr e |
|
||||
e = sink.asExpr() |
|
||||
dds instanceof FileTimeStruct
|
||||
and fa.getQualifier().getUnderlyingType() = dds
|
||||
and fa.isModified()
|
||||
and aexpr.getAChild() = fa
|
||||
and aexpr.getChild(1).getAChild*() = e
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DataFlow::Configuration for finding an operation w/hardcoded 365 that will flow into any known date/time field
|
||||
*/
|
||||
class PossibleYearArithmeticOperationCheckConfiguration extends DataFlow::Configuration {
|
||||
PossibleYearArithmeticOperationCheckConfiguration() {
|
||||
this = "PossibleYearArithmeticOperationCheckConfiguration"
|
||||
}
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
exists( Expr e, Operation op |
|
||||
e = source.asExpr() |
|
||||
op.getAChild*().getValue().toInt()=365
|
||||
and op.getAChild*() = e
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists( StructLikeClass dds, FieldAccess fa, AssignExpr aexpr, Expr e |
|
||||
e = sink.asExpr() |
|
||||
(dds instanceof FileTimeStruct
|
||||
or dds instanceof DateDataStruct)
|
||||
and fa.getQualifier().getUnderlyingType() = dds
|
||||
and fa.isModified()
|
||||
and aexpr.getAChild() = fa
|
||||
and aexpr.getChild(1).getAChild*() = e
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<include src="LeapYear.qhelp" />
|
||||
|
||||
<p>When performing arithmetic operations on a variable that represents a year, it is important to consider that the resulting value may not be a valid date.</p>
|
||||
<p>The typical example is doing simple year arithmetic (i.e. <code>date.year++</code>) without considering if the resulting value will be a valid date or not.</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
<p>When modifying a year field on a date structure, verify if the resulting year is a leap year.</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
<p>In this example, we are adding 1 year to the current date. This may work most of the time, but on any given February 29th, the resulting value will be invalid.</p>
|
||||
<sample src="UncheckedLeapYearAfterYearModificationBad.c" />
|
||||
|
||||
<p>To fix this bug, check the result for leap year.</p>
|
||||
<sample src="UncheckedLeapYearAfterYearModificationGood.c" />
|
||||
</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>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>
|
||||
</qhelp>
|
|
@ -0,0 +1,64 @@
|
|||
/**
|
||||
* @name Year field changed using an arithmetic operation without checking for leap year
|
||||
* @description A field that represents a year is being modified by an arithmetic operation, but no proper check for leap years can be detected afterwards.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @id cpp/leap-year/unchecked-after-arithmetic-year-modification
|
||||
* @precision medium
|
||||
* @tags security
|
||||
* leap-year
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import LeapYear
|
||||
|
||||
from Variable var, LeapYearFieldAccess yfa
|
||||
where
|
||||
exists(VariableAccess va |
|
||||
yfa.getQualifier() = va and
|
||||
var.getAnAccess() = va and
|
||||
// The year is modified with an arithmetic operation. Avoid values that are likely false positives
|
||||
yfa.isModifiedByArithmeticOperationNotForNormalization() and
|
||||
// Avoid false positives
|
||||
not (
|
||||
// If there is a local check for leap year after the modification
|
||||
exists(LeapYearFieldAccess yfacheck |
|
||||
yfacheck.getQualifier() = var.getAnAccess() and
|
||||
yfacheck.isUsedInCorrectLeapYearCheck() and
|
||||
yfacheck = yfa.getASuccessor*()
|
||||
)
|
||||
or
|
||||
// If there is a data flow from the variable that was modified to a function that seems to check for leap year
|
||||
exists(
|
||||
VariableAccess source, ChecksForLeapYearFunctionCall fc, LeapYearCheckConfiguration config
|
||||
|
|
||||
source = var.getAnAccess() and
|
||||
config.hasFlow(DataFlow::exprNode(source), DataFlow::exprNode(fc.getAnArgument()))
|
||||
)
|
||||
or
|
||||
// If there is a data flow from the field that was modified to a function that seems to check for leap year
|
||||
exists(
|
||||
VariableAccess vacheck, YearFieldAccess yfacheck, ChecksForLeapYearFunctionCall fc,
|
||||
LeapYearCheckConfiguration config
|
||||
|
|
||||
vacheck = var.getAnAccess() and
|
||||
yfacheck.getQualifier() = vacheck and
|
||||
config.hasFlow(DataFlow::exprNode(yfacheck), DataFlow::exprNode(fc.getAnArgument()))
|
||||
)
|
||||
or
|
||||
// If there is a successor or predecessor that sets the month = 1
|
||||
exists(MonthFieldAccess mfa, AssignExpr ae |
|
||||
mfa.getQualifier() = var.getAnAccess() and
|
||||
mfa.isModified() and
|
||||
(
|
||||
mfa = yfa.getASuccessor*() or
|
||||
yfa = mfa.getASuccessor*()
|
||||
) and
|
||||
ae = mfa.getEnclosingElement() and
|
||||
ae.getAnOperand().getValue().toInt() = 1
|
||||
)
|
||||
)
|
||||
)
|
||||
select yfa,
|
||||
"Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found.",
|
||||
yfa.getTarget(), yfa.getTarget().toString(), var, var.toString()
|
|
@ -0,0 +1,9 @@
|
|||
SYSTEMTIME st;
|
||||
FILETIME ft;
|
||||
GetSystemTime(&st);
|
||||
|
||||
// Flawed logic may result in invalid date
|
||||
st.wYear++;
|
||||
|
||||
// The following code may fail
|
||||
SystemTimeToFileTime(&st, &ft);
|
|
@ -0,0 +1,15 @@
|
|||
SYSTEMTIME st;
|
||||
FILETIME ft;
|
||||
GetSystemTime(&st);
|
||||
|
||||
// Flawed logic will result in invalid date
|
||||
st.wYear++;
|
||||
|
||||
// Check for leap year, and adjust the date accordingly
|
||||
bool isLeapYear = st.wYear % 4 == 0 && (st.wYear % 100 != 0 || st.wYear % 400 == 0);
|
||||
st.wDay = st.wMonth == 2 && st.wDay == 29 && !isLeapYear ? 28 : st.wDay;
|
||||
|
||||
if (!SystemTimeToFileTime(&st, &ft))
|
||||
{
|
||||
// handle error
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<include src="LeapYear.qhelp" />
|
||||
|
||||
<p>When using a function that transforms a date structure, and the year on the input argument for the API has been manipulated, it is important to check for the return value of the function to make sure it succeeded.</p>
|
||||
<p>Otherwise, the function may have failed, and the output parameter may contain invalid data that can cause any number of problems on the affected system.</p>
|
||||
<p>The following is a list of the functions that this query covers:</p>
|
||||
<ul>
|
||||
<li><code>FileTimeToSystemTime</code></li>
|
||||
<li><code>SystemTimeToFileTime</code></li>
|
||||
<li><code>SystemTimeToTzSpecificLocalTime</code></li>
|
||||
<li><code>SystemTimeToTzSpecificLocalTimeEx</code></li>
|
||||
<li><code>TzSpecificLocalTimeToSystemTime</code></li>
|
||||
<li><code>TzSpecificLocalTimeToSystemTimeEx</code></li>
|
||||
<li><code>RtlLocalTimeToSystemTime</code></li>
|
||||
<li><code>RtlTimeToSecondsSince1970</code></li>
|
||||
<li><code>_mkgmtime</code></li>
|
||||
</ul>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
<p>When calling an API that transforms a date variable that was manipulated, always check for the return value to verify that the API call succeeded.</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
<p>In this example, we are adding 1 year to the current date. This may work most of the time, but on any given February 29th, the resulting value will be invalid.</p>
|
||||
<sample src="UncheckedLeapYearAfterYearModificationBad.c" />
|
||||
|
||||
<p>To fix this bug, you must verify the return value for <code>SystemTimeToFileTime</code> and handle any potential error accordingly.</p>
|
||||
<sample src="UncheckedLeapYearAfterYearModificationGood.c" />
|
||||
</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>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>
|
||||
</qhelp>
|
|
@ -0,0 +1,110 @@
|
|||
/**
|
||||
* @name Year field changed using an arithmetic operation is used on an unchecked time conversion function
|
||||
* @description A year field changed using an arithmetic operation is used on a time conversion function, but the return value of the function is not checked for success or failure
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @id cpp/leap-year/unchecked-return-value-for-time-conversion-function
|
||||
* @precision medium
|
||||
* @tags security
|
||||
* leap-year
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import LeapYear
|
||||
|
||||
/**
|
||||
* A YearFieldAccess that is modifying the year by any arithmetic operation
|
||||
*
|
||||
* NOTE:
|
||||
* To change this class to work for general purpose date transformations that do not check the return value,
|
||||
* make the following changes:
|
||||
* -> extends FieldAccess (line 27)
|
||||
* -> this.isModified (line 33)
|
||||
* Expect a lower precision for a general purpose version.
|
||||
*/
|
||||
class DateStructModifiedFieldAccess extends LeapYearFieldAccess {
|
||||
DateStructModifiedFieldAccess() {
|
||||
exists(Field f, StructLikeClass struct |
|
||||
f.getAnAccess() = this and
|
||||
struct.getAField() = f and
|
||||
struct.getUnderlyingType() instanceof DateDataStruct and
|
||||
this.isModifiedByArithmeticOperation()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a list of APIs that will get the system time, and therefore guarantee that the value is valid
|
||||
*/
|
||||
class SafeTimeGatheringFunction extends Function {
|
||||
SafeTimeGatheringFunction() {
|
||||
this.getQualifiedName().matches("GetFileTime") or
|
||||
this.getQualifiedName().matches("GetSystemTime") or
|
||||
this.getQualifiedName().matches("NtQuerySystemTime")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This list of APIs should check for the return value to detect problems during the conversion
|
||||
*/
|
||||
class TimeConversionFunction extends Function {
|
||||
TimeConversionFunction() {
|
||||
this.getQualifiedName().matches("FileTimeToSystemTime") or
|
||||
this.getQualifiedName().matches("SystemTimeToFileTime") or
|
||||
this.getQualifiedName().matches("SystemTimeToTzSpecificLocalTime") or
|
||||
this.getQualifiedName().matches("SystemTimeToTzSpecificLocalTimeEx") or
|
||||
this.getQualifiedName().matches("TzSpecificLocalTimeToSystemTime") or
|
||||
this.getQualifiedName().matches("TzSpecificLocalTimeToSystemTimeEx") or
|
||||
this.getQualifiedName().matches("RtlLocalTimeToSystemTime") or
|
||||
this.getQualifiedName().matches("RtlTimeToSecondsSince1970") or
|
||||
this.getQualifiedName().matches("_mkgmtime")
|
||||
}
|
||||
}
|
||||
|
||||
from FunctionCall fcall, TimeConversionFunction trf, Variable var
|
||||
where
|
||||
fcall = trf.getACallToThisFunction() and
|
||||
fcall instanceof ExprInVoidContext and
|
||||
var.getUnderlyingType() instanceof DateDataStruct and
|
||||
(
|
||||
exists(AddressOfExpr aoe |
|
||||
aoe = fcall.getAnArgument() and
|
||||
aoe.getAddressable() = var
|
||||
)
|
||||
or
|
||||
exists(VariableAccess va |
|
||||
fcall.getAnArgument() = va and
|
||||
var.getAnAccess() = va
|
||||
)
|
||||
) and
|
||||
exists(DateStructModifiedFieldAccess dsmfa, VariableAccess modifiedVarAccess |
|
||||
modifiedVarAccess = var.getAnAccess() and
|
||||
modifiedVarAccess = dsmfa.getQualifier() and
|
||||
modifiedVarAccess = fcall.getAPredecessor*()
|
||||
) and
|
||||
// Remove false positives
|
||||
not (
|
||||
// Remove any instance where the predecessor is a SafeTimeGatheringFunction and no change to the data happened in between
|
||||
exists(FunctionCall pred |
|
||||
pred = fcall.getAPredecessor*() and
|
||||
exists(SafeTimeGatheringFunction stgf | pred = stgf.getACallToThisFunction()) and
|
||||
not exists(DateStructModifiedFieldAccess dsmfa, VariableAccess modifiedVarAccess |
|
||||
modifiedVarAccess = var.getAnAccess() and
|
||||
modifiedVarAccess = dsmfa.getQualifier() and
|
||||
modifiedVarAccess = fcall.getAPredecessor*() and
|
||||
modifiedVarAccess = pred.getASuccessor*()
|
||||
)
|
||||
)
|
||||
or
|
||||
// Remove any instance where the year is changed, but the month is set to 1 (year wrapping)
|
||||
exists(MonthFieldAccess mfa, AssignExpr ae |
|
||||
mfa.getQualifier() = var.getAnAccess() and
|
||||
mfa.isModified() and
|
||||
mfa = fcall.getAPredecessor*() and
|
||||
ae = mfa.getEnclosingElement() and
|
||||
ae.getAnOperand().getValue().toInt() = 1
|
||||
)
|
||||
)
|
||||
select fcall,
|
||||
"Return value of $@ function should be verified to check for any error because variable $@ is not guaranteed to be safe.",
|
||||
trf, trf.getQualifiedName().toString(), var, var.getName()
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<include src="LeapYear.qhelp" />
|
||||
|
||||
<p>This query helps to detect when a developer allocates an array or other fixed-length data structure such as <code>std::vector</code> with 365 elements – one for each day of the year.</p>
|
||||
<p>Since leap years have 366 days, there will be no allocated element on December 31st at the end of a leap year; which will lead to a buffer overflow on a leap year.</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
<p>When allocating memory for storing elements for each day of the year, ensure that the correct number of elements are allocated.</p>
|
||||
<p>It is also highly recommended to compile the code with array-bounds checking enabled whenever possible.</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
<p>In this example, we are allocating 365 integers, one for each day of the year. This code will fail on a leap year, when there are 366 days.</p>
|
||||
<sample src="UnsafeArrayForDaysOfYearBad.c" />
|
||||
|
||||
<p>When using arrays, allocate the correct number of elements to match the year.</p>
|
||||
<sample src="UnsafeArrayForDaysOfYearGood.c" />
|
||||
</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>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>
|
||||
</qhelp>
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* @name Unsafe array for days of the year
|
||||
* @description An array of 365 items typically indicates one entry per day of the year, but without considering leap years, which would be 366 days.
|
||||
* An access on a leap year could result in buffer overflow bugs.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @id cpp/leap-year/unsafe-array-for-days-of-the-year
|
||||
* @precision medium
|
||||
* @tags security
|
||||
* leap-year
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
class LeapYearUnsafeDaysOfTheYearArrayType extends ArrayType {
|
||||
LeapYearUnsafeDaysOfTheYearArrayType() { this.getArraySize() = 365 }
|
||||
}
|
||||
|
||||
from Element element
|
||||
where
|
||||
exists(NewArrayExpr nae |
|
||||
element = nae and
|
||||
nae.getAllocatedType() instanceof LeapYearUnsafeDaysOfTheYearArrayType
|
||||
)
|
||||
or
|
||||
exists(Variable var |
|
||||
var = element and
|
||||
var.getType() instanceof LeapYearUnsafeDaysOfTheYearArrayType
|
||||
)
|
||||
or
|
||||
exists(ConstructorCall cc |
|
||||
element = cc and
|
||||
cc.getTarget().hasName("vector") and
|
||||
cc.getArgument(0).getValue().toInt() = 365
|
||||
)
|
||||
select element,
|
||||
"There is an array or std::vector allocation with a hard-coded set of 365 elements, which may indicate the number of days in a year without considering leap year scenarios."
|
|
@ -0,0 +1,2 @@
|
|||
int items[365];
|
||||
items[dayOfYear - 1] = x; // buffer overflow on December 31st of any leap year
|
|
@ -0,0 +1,4 @@
|
|||
bool isLeapYear = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
|
||||
int *items = new int[isLeapYear ? 366 : 365];
|
||||
// ...
|
||||
delete[] items;
|
|
@ -55,6 +55,7 @@ predicate memberDirectlyInitialisesVariable(MemberFunction mf, Class c, MemberVa
|
|||
predicate memberInitialisesVariable(MemberFunction mf, Class c, MemberVariable mv) {
|
||||
memberDirectlyInitialisesVariable(mf, c, mv) or
|
||||
exists(MemberFunction mf2 |
|
||||
memberDirectlyInitialisesVariable(_, c, mv) and // (optimizer hint)
|
||||
memberInitialisesVariable(mf2, c, mv) and
|
||||
mf.getDeclaringType() = c and
|
||||
mf.calls(mf2)
|
||||
|
|
|
@ -9,20 +9,27 @@
|
|||
* readability
|
||||
* external/jsf
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
from Parameter p, Parameter superP, MemberFunction subF, MemberFunction superF, int i, string subValue, string superValue
|
||||
where p.hasInitializer()
|
||||
and subF.getParameter(i) = p
|
||||
and superP.hasInitializer()
|
||||
and subF.overrides(superF)
|
||||
and superF.getParameter(i) = superP
|
||||
and subValue = p.getInitializer().getExpr().getValue()
|
||||
and superValue = superP.getInitializer().getExpr().getValue()
|
||||
and subValue != superValue
|
||||
select p.getInitializer().getExpr(),
|
||||
"Parameter " + p.getName() +
|
||||
" redefines its default value to " + subValue +
|
||||
" from the inherited default value " + superValue +
|
||||
" (in " + superF.getDeclaringType().getName() +
|
||||
").\nThe default value will be resolved statically, not by dispatch, so this can cause confusion."
|
||||
predicate memberParameterWithDefault(
|
||||
MemberFunction f, int ix, Parameter p, Expr initExpr, string initValue
|
||||
) {
|
||||
f.getParameter(ix) = p and
|
||||
initExpr = p.getInitializer().getExpr() and
|
||||
initValue = initExpr.getValue()
|
||||
}
|
||||
|
||||
from
|
||||
Parameter p, Parameter superP, MemberFunction subF, MemberFunction superF, int i, Expr subExpr,
|
||||
string subValue, string superValue
|
||||
where
|
||||
memberParameterWithDefault(subF, i, p, subExpr, subValue) and
|
||||
subF.overrides(superF) and
|
||||
memberParameterWithDefault(superF, i, superP, _, superValue) and
|
||||
subValue != superValue
|
||||
select subExpr,
|
||||
"Parameter " + p.getName() + " redefines its default value to " + subValue +
|
||||
" from the inherited default value " + superValue + " (in " +
|
||||
superF.getDeclaringType().getName() +
|
||||
").\nThe default value will be resolved statically, not by dispatch, so this can cause confusion."
|
||||
|
|
|
@ -54,7 +54,7 @@ class Field extends MemberVariable {
|
|||
* which the field will be initialized, whether by an initializer list or in a
|
||||
* constructor.
|
||||
*/
|
||||
final int getInitializationOrder() {
|
||||
final pragma[nomagic] int getInitializationOrder() {
|
||||
exists(Class cls, int memberIndex |
|
||||
this = cls.getCanonicalMember(memberIndex) and
|
||||
memberIndex = rank[result + 1](int index |
|
||||
|
|
|
@ -117,6 +117,11 @@ class Variable extends Declaration, @variable {
|
|||
or
|
||||
exists (AssignExpr ae
|
||||
| ae.getLValue().(Access).getTarget() = this and result = ae.getRValue())
|
||||
or
|
||||
exists(AggregateLiteral l |
|
||||
this.getDeclaringType() = l.getType() and
|
||||
result = l.getChild(this.(Field).getInitializationOrder())
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
/**
|
||||
* Provides a library for helping working with a set of known data structures representing dates in C++
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
class FileTimeStruct extends Type {
|
||||
FileTimeStruct() {
|
||||
this.toString().matches("_FILETIME")
|
||||
or this.toString().matches("_FILETIME %")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Type of known data structures that are used for date representation.
|
||||
*/
|
||||
class DateDataStruct extends Type {
|
||||
DateDataStruct() {
|
||||
this.toString().matches("_SYSTEMTIME")
|
||||
or this.toString().matches("SYSTEMTIME")
|
||||
or this.toString().matches("tm")
|
||||
or this.toString().matches("_SYSTEMTIME %")
|
||||
or this.toString().matches("SYSTEMTIME %")
|
||||
or this.toString().matches("tm %")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* abstract class of type FieldAccess that would represent an access to a field on a struct
|
||||
*/
|
||||
abstract class StructFieldAccess extends FieldAccess {
|
||||
StructFieldAccess () {
|
||||
exists(Field f, StructLikeClass struct |
|
||||
f.getAnAccess() = this
|
||||
and struct.getAField() = f
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* abstract class of type FieldAccess where access is to a day of the month field of the struct
|
||||
* This is to be derived from for a specific struct's day of the month field access
|
||||
*/
|
||||
abstract class DayFieldAccess extends StructFieldAccess { }
|
||||
|
||||
/**
|
||||
* abstract class of type FieldAccess where access is to a month field of the struct
|
||||
* This is to be derived from for a specific struct's month field access
|
||||
*/
|
||||
abstract class MonthFieldAccess extends StructFieldAccess {}
|
||||
|
||||
/**
|
||||
* abstract class of type FieldAccess where access is to a year field of the struct
|
||||
* This is to be derived from for a specific struct's year field access
|
||||
*/
|
||||
abstract class YearFieldAccess extends StructFieldAccess {}
|
||||
|
||||
/**
|
||||
* DayFieldAccess for SYSTEMTIME struct
|
||||
*/
|
||||
class SystemTimeDayFieldAccess extends DayFieldAccess {
|
||||
SystemTimeDayFieldAccess () {
|
||||
this.toString().matches("wDay")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MonthFieldAccess for SYSTEMTIME struct
|
||||
*/
|
||||
class SystemTimeMonthFieldAccess extends MonthFieldAccess {
|
||||
SystemTimeMonthFieldAccess () {
|
||||
this.toString().matches("wMonth")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* YearFieldAccess for SYSTEMTIME struct
|
||||
*/
|
||||
class StructSystemTimeYearFieldAccess extends YearFieldAccess {
|
||||
StructSystemTimeYearFieldAccess() {
|
||||
this.toString().matches("wYear")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DayFieldAccess for struct tm
|
||||
*/
|
||||
class StructTmDayFieldAccess extends DayFieldAccess {
|
||||
StructTmDayFieldAccess() {
|
||||
this.toString().matches("tm_mday")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MonthFieldAccess for struct tm
|
||||
*/
|
||||
class StructTmMonthFieldAccess extends MonthFieldAccess {
|
||||
StructTmMonthFieldAccess() {
|
||||
this.toString().matches("tm_mon")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* YearFieldAccess for struct tm
|
||||
*/
|
||||
class StructTmYearFieldAccess extends YearFieldAccess {
|
||||
StructTmYearFieldAccess() {
|
||||
this.toString().matches("tm_year")
|
||||
}
|
||||
}
|
|
@ -131,20 +131,28 @@ private predicate bbLoopEntryConditionAlwaysTrueAt(BasicBlock bb, int i, Control
|
|||
}
|
||||
|
||||
/**
|
||||
* Basic block `pred` ends with a condition belonging to a loop, and that
|
||||
* condition is provably true upon entry. Basic block `succ` is a successor
|
||||
* of `pred`, and `skipsLoop` indicates whether `succ` is the false-successor
|
||||
* of `pred`.
|
||||
* Basic block `pred` contains all or part of the condition belonging to a loop,
|
||||
* and there is an edge from `pred` to `succ` that concludes the condition.
|
||||
* If the edge corrseponds with the loop condition being found to be `true`, then
|
||||
* `skipsLoop` is `false`. Otherwise the edge corresponds with the loop condition
|
||||
* being found to be `false` and `skipsLoop` is `true`. Non-concluding edges
|
||||
* within a complex loop condition are not matched by this predicate.
|
||||
*/
|
||||
private predicate bbLoopConditionAlwaysTrueUponEntrySuccessor(BasicBlock pred, BasicBlock succ, boolean skipsLoop) {
|
||||
succ = pred.getASuccessor() and
|
||||
exists(ControlFlowNode last |
|
||||
last = pred.getEnd() and
|
||||
loopConditionAlwaysTrueUponEntry(_, last) and
|
||||
if succ = pred.getAFalseSuccessor() then
|
||||
skipsLoop = true
|
||||
else
|
||||
skipsLoop = false
|
||||
exists(Expr cond |
|
||||
loopConditionAlwaysTrueUponEntry(_, cond) and
|
||||
cond.getAChild*() = pred.getEnd() and
|
||||
succ = pred.getASuccessor() and
|
||||
not cond.getAChild*() = succ.getStart() and
|
||||
(
|
||||
(
|
||||
succ = pred.getAFalseSuccessor() and
|
||||
skipsLoop = true
|
||||
) or (
|
||||
succ = pred.getATrueSuccessor() and
|
||||
skipsLoop = false
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -176,7 +184,7 @@ predicate bbSuccessorEntryReachesLoopInvariant(BasicBlock pred, BasicBlock succ,
|
|||
// The edge from `pred` to `succ` is _not_ from a loop condition provably
|
||||
// true upon entry, so the values of `predSkipsFirstLoopAlwaysTrueUponEntry`
|
||||
// and `succSkipsFirstLoopAlwaysTrueUponEntry` must be the same.
|
||||
not bbLoopConditionAlwaysTrueUponEntrySuccessor(pred, _, _) and
|
||||
not bbLoopConditionAlwaysTrueUponEntrySuccessor(pred, succ, _) and
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry = predSkipsFirstLoopAlwaysTrueUponEntry and
|
||||
// Moreover, if `pred` contains the entry point of a loop where the
|
||||
// condition is provably true upon entry, then `succ` is not allowed
|
||||
|
|
|
@ -60,27 +60,14 @@ private cached module Cached {
|
|||
not n2 instanceof PrimitiveBasicBlock
|
||||
}
|
||||
|
||||
/** Returns the index of `node` in its `PrimitiveBasicBlock`. */
|
||||
private int getMemberIndex(Node node) {
|
||||
primitive_basic_block_entry_node(node) and
|
||||
result = 0
|
||||
or
|
||||
exists(Node prev |
|
||||
member_step(prev, node) and
|
||||
result = getMemberIndex(prev) + 1
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `node` is the `pos`th control-flow node in primitive basic block `bb`. */
|
||||
cached
|
||||
predicate primitive_basic_block_member(Node node, PrimitiveBasicBlock bb, int pos) {
|
||||
primitive_basic_block_entry_node(bb) and
|
||||
(
|
||||
pos = 0 and
|
||||
node = bb
|
||||
or
|
||||
pos = getMemberIndex(node) and
|
||||
member_step+(bb, node)
|
||||
primitive_basic_block_entry_node(bb) and node = bb and pos = 0
|
||||
or
|
||||
exists(Node prev |
|
||||
member_step(prev, node) and
|
||||
primitive_basic_block_member(prev, bb, pos - 1)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,10 @@ class Stmt extends StmtParent, @stmt {
|
|||
|
||||
/**
|
||||
* Gets the statement following this statement in the same block, if any.
|
||||
*
|
||||
* Note that this is not widely useful, because this doesn't have a result for
|
||||
* the last statement of a block. Consider using the `ControlFlowNode` class
|
||||
* to trace the flow of control instead.
|
||||
*/
|
||||
Stmt getFollowingStmt() {
|
||||
exists(Block b, int i | this = b.getStmt(i) and
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
| file://:0:0:0:0 | abc | test.cpp:53:6:53:11 | chars1 |
|
||||
| file://:0:0:0:0 | {...} | test.cpp:38:22:38:22 | v |
|
||||
| test.cpp:4:9:4:11 | 10 | test.cpp:4:6:4:6 | v |
|
||||
| test.cpp:5:15:5:16 | & ... | test.cpp:5:7:5:11 | ptr_v |
|
||||
| test.cpp:6:15:6:15 | v | test.cpp:6:7:6:11 | ref_v |
|
||||
| test.cpp:8:6:8:7 | 11 | test.cpp:4:6:4:6 | v |
|
||||
| test.cpp:10:10:10:11 | 13 | test.cpp:6:7:6:11 | ref_v |
|
||||
| test.cpp:11:6:11:10 | ... + ... | test.cpp:4:6:4:6 | v |
|
||||
| test.cpp:19:32:19:35 | 0.0 | test.cpp:19:27:19:28 | _y |
|
||||
| test.cpp:19:42:19:43 | _x | test.cpp:24:8:24:8 | x |
|
||||
| test.cpp:19:49:19:50 | _y | test.cpp:24:11:24:11 | y |
|
||||
| test.cpp:19:54:19:60 | 0.0 | test.cpp:24:14:24:14 | z |
|
||||
| test.cpp:35:16:35:25 | {...} | test.cpp:35:11:35:12 | v1 |
|
||||
| test.cpp:35:17:35:17 | 1 | test.cpp:31:6:31:8 | num |
|
||||
| test.cpp:35:20:35:24 | One | test.cpp:32:14:32:16 | str |
|
||||
| test.cpp:36:16:36:39 | {...} | test.cpp:36:11:36:12 | v2 |
|
||||
| test.cpp:36:24:36:24 | 2 | test.cpp:31:6:31:8 | num |
|
||||
| test.cpp:36:34:36:38 | Two | test.cpp:32:14:32:16 | str |
|
||||
| test.cpp:38:27:38:27 | 3 | test.cpp:31:6:31:8 | num |
|
||||
| test.cpp:38:30:38:36 | Three | test.cpp:32:14:32:16 | str |
|
||||
| test.cpp:48:16:48:28 | {...} | test.cpp:48:11:48:12 | v3 |
|
||||
| test.cpp:48:17:48:27 | {...} | test.cpp:45:12:45:14 | ms2 |
|
||||
| test.cpp:48:18:48:18 | 4 | test.cpp:31:6:31:8 | num |
|
||||
| test.cpp:48:21:48:26 | Four | test.cpp:32:14:32:16 | str |
|
||||
| test.cpp:52:19:52:27 | {...} | test.cpp:52:5:52:11 | myArray |
|
||||
| test.cpp:54:17:54:31 | {...} | test.cpp:54:6:54:11 | chars2 |
|
||||
| test.cpp:55:16:55:20 | abc | test.cpp:55:7:55:12 | chars3 |
|
|
@ -0,0 +1,4 @@
|
|||
import cpp
|
||||
|
||||
from Variable v
|
||||
select v.getAnAssignedValue(), v
|
|
@ -0,0 +1,55 @@
|
|||
|
||||
void test1()
|
||||
{
|
||||
int v = 10; // assignment to `v`
|
||||
int *ptr_v = &v; // assignment to `ptr_v`
|
||||
int &ref_v = v; // assignment to `ref_v`
|
||||
|
||||
v = 11; // assignment to `v`
|
||||
*ptr_v = 12;
|
||||
ref_v = 13; // assignment to `ref_v`
|
||||
v = v + 1; // assignment to `v`
|
||||
v += 1;
|
||||
v++;
|
||||
}
|
||||
|
||||
class myClass1
|
||||
{
|
||||
public:
|
||||
myClass1(float _x, float _y = 0.0f) : x(_x), y(_y), z(0.0f) { // assignments to `_y`, `x`, `y`, `z`
|
||||
// ...
|
||||
}
|
||||
|
||||
private:
|
||||
float x, y, z;
|
||||
};
|
||||
|
||||
// ---
|
||||
|
||||
struct myStruct1
|
||||
{
|
||||
int num;
|
||||
const char *str;
|
||||
};
|
||||
|
||||
myStruct1 v1 = {1, "One"}; // assigments to `v1`, `num`, `str`
|
||||
myStruct1 v2 = {.num = 2, .str = "Two"}; // assigments to `v2`, `num`, `str`
|
||||
|
||||
void test2(myStruct1 v = {3, "Three"}) // assignments to `v` (literal `{...}` has no location), `num`, `str`
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
struct myStruct2
|
||||
{
|
||||
myStruct1 ms2;
|
||||
};
|
||||
|
||||
myStruct2 v3 = {{4, "Four"}}; // assigments to `v3`, `ms2`, `num`, `str`
|
||||
|
||||
// ---
|
||||
|
||||
int myArray[10] = {1, 2, 3}; // assigment to `myArray`
|
||||
char chars1[] = "abc"; // assignment to `chars1` (literal "abc" has no location)
|
||||
char chars2[] = {'a', 'b', 'c'}; // assigment to `chars2`
|
||||
char *chars3 = "abc"; // assigment to `chars3`
|
|
@ -0,0 +1,40 @@
|
|||
class EraInfo
|
||||
{
|
||||
public:
|
||||
EraInfo() {
|
||||
|
||||
};
|
||||
|
||||
EraInfo(int year, int month, int day) {
|
||||
|
||||
};
|
||||
|
||||
EraInfo(int Era, int foo, int year, int month, int day, const wchar_t * eraName)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static EraInfo * EraInfoFromDate(int Era, int foo, int year, int month, int day, wchar_t * eraName)
|
||||
{
|
||||
return new EraInfo(Era, foo, year, month, day, eraName);
|
||||
}
|
||||
};
|
||||
|
||||
int Main()
|
||||
{
|
||||
|
||||
// BAD: constructor creating a EraInfo with exact Heisei era start date
|
||||
EraInfo * pDateTimeUtil = new EraInfo(1989, 1, 8);
|
||||
|
||||
// BAD: constructor creating a EraInfo with exact Heisei era start date
|
||||
EraInfo * pDateTimeUtil1 = new EraInfo(1, 2, 1989, 1, 8, L"\u5e73\u6210");
|
||||
|
||||
// Good: constructor creating a EraInfo with another date
|
||||
EraInfo * pDateTimeUtil2 = new EraInfo(1, 2, 1900, 1, 1, L"foo");
|
||||
|
||||
// BAD: method call passing exact Haisei era start date as parameters
|
||||
EraInfo * pDateTimeUtil3 = EraInfo::EraInfoFromDate(1, 2, 1989, 1, 8, L"\u5e73\u6210");
|
||||
|
||||
// GOOD: method call with the same parameters in a different order (we only track year, month, day)
|
||||
EraInfo * pDateTimeUtil4 = EraInfo::EraInfoFromDate(1, 2, 8, 1, 1989, L"\u5e73\u6210");
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
| ConstructorOrMethodWithExactDate.cpp:27:31:27:53 | call to EraInfo | Call that appears to have hard-coded Japanese era start date as parameter. |
|
||||
| ConstructorOrMethodWithExactDate.cpp:30:32:30:77 | call to EraInfo | Call that appears to have hard-coded Japanese era start date as parameter. |
|
||||
| ConstructorOrMethodWithExactDate.cpp:36:32:36:55 | call to EraInfoFromDate | Call that appears to have hard-coded Japanese era start date as parameter. |
|
|
@ -0,0 +1 @@
|
|||
Likely Bugs/JapaneseEra/ConstructorOrMethodWithExactEraDate.ql
|
|
@ -0,0 +1,57 @@
|
|||
typedef unsigned short WORD;
|
||||
|
||||
struct tm
|
||||
{
|
||||
int tm_sec; // seconds after the minute - [0, 60] including leap second
|
||||
int tm_min; // minutes after the hour - [0, 59]
|
||||
int tm_hour; // hours since midnight - [0, 23]
|
||||
int tm_mday; // day of the month - [1, 31]
|
||||
int tm_mon; // months since January - [0, 11]
|
||||
int tm_year; // years since 1900
|
||||
int tm_wday; // days since Sunday - [0, 6]
|
||||
int tm_yday; // days since January 1 - [0, 365]
|
||||
int tm_isdst; // daylight savings time flag
|
||||
};
|
||||
|
||||
typedef struct _SYSTEMTIME {
|
||||
WORD wYear;
|
||||
WORD wMonth;
|
||||
WORD wDayOfWeek;
|
||||
WORD wDay;
|
||||
WORD wHour;
|
||||
WORD wMinute;
|
||||
WORD wSecond;
|
||||
WORD wMilliseconds;
|
||||
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;
|
||||
|
||||
int main()
|
||||
{
|
||||
// BAD: Creation of tm stuct corresponding to the beginning of Heisei era
|
||||
tm *timeTm = new tm();
|
||||
timeTm->tm_year = 1989;
|
||||
timeTm->tm_mon = 1;
|
||||
timeTm->tm_mday = 8;
|
||||
|
||||
|
||||
// GOOD: Creation of tm stuct with different date
|
||||
tm *timeTm1 = new tm();
|
||||
timeTm1->tm_year = 1988;
|
||||
timeTm1->tm_mon = 1;
|
||||
timeTm1->tm_mday = 1;
|
||||
|
||||
// BAD: Creation of SYSTEMTIME stuct corresponding to the beginning of Heisei era
|
||||
SYSTEMTIME st;
|
||||
st.wDay = 8;
|
||||
st.wMonth = 1;
|
||||
st.wYear = 1989;
|
||||
|
||||
|
||||
// GOOD: Creation of SYSTEMTIME stuct with a different date
|
||||
SYSTEMTIME st1;
|
||||
st1.wDay = 1;
|
||||
st1.wMonth = 1;
|
||||
st1.wYear = 1990;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
| StructWithExactDate.cpp:31:13:31:19 | tm_year | A time struct that is initialized with exact Japanese calendar era start date. |
|
||||
| StructWithExactDate.cpp:46:8:46:12 | wYear | A time struct that is initialized with exact Japanese calendar era start date. |
|
|
@ -0,0 +1 @@
|
|||
Likely Bugs/JapaneseEra/StructWithExactEraDate.ql
|
|
@ -0,0 +1,11 @@
|
|||
| test.cpp:314:5:314:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:309:13:309:14 | st | st |
|
||||
| test.cpp:327:5:327:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:322:13:322:14 | st | st |
|
||||
| test.cpp:338:6:338:10 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:333:62:333:63 | st | st |
|
||||
| test.cpp:484:5:484:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:480:13:480:14 | st | st |
|
||||
| test.cpp:497:5:497:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:492:13:492:14 | st | st |
|
||||
| test.cpp:509:5:509:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:505:13:505:14 | st | st |
|
||||
| test.cpp:606:11:606:17 | tm_year | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:56:6:56:12 | tm_year | tm_year | test.cpp:602:12:602:19 | timeinfo | timeinfo |
|
||||
| test.cpp:634:11:634:17 | tm_year | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:56:6:56:12 | tm_year | tm_year | test.cpp:628:12:628:19 | timeinfo | timeinfo |
|
||||
| test.cpp:636:11:636:17 | tm_year | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:56:6:56:12 | tm_year | tm_year | test.cpp:628:12:628:19 | timeinfo | timeinfo |
|
||||
| test.cpp:640:5:640:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:629:13:629:14 | st | st |
|
||||
| test.cpp:642:5:642:9 | wYear | Field $@ on variable $@ has been modified, but no appropriate check for LeapYear was found. | test.cpp:12:7:12:11 | wYear | wYear | test.cpp:629:13:629:14 | st | st |
|
|
@ -0,0 +1 @@
|
|||
Likely Bugs/Leap Year/UncheckedLeapYearAfterYearModification.ql
|
|
@ -0,0 +1,3 @@
|
|||
| test.cpp:317:2:317:21 | call to SystemTimeToFileTime | Return value of $@ function should be verified to check for any error because variable $@ is not guaranteed to be safe. | test.cpp:63:1:63:20 | SystemTimeToFileTime | SystemTimeToFileTime | test.cpp:309:13:309:14 | st | st |
|
||||
| test.cpp:330:2:330:21 | call to SystemTimeToFileTime | Return value of $@ function should be verified to check for any error because variable $@ is not guaranteed to be safe. | test.cpp:63:1:63:20 | SystemTimeToFileTime | SystemTimeToFileTime | test.cpp:322:13:322:14 | st | st |
|
||||
| test.cpp:341:2:341:21 | call to SystemTimeToFileTime | Return value of $@ function should be verified to check for any error because variable $@ is not guaranteed to be safe. | test.cpp:63:1:63:20 | SystemTimeToFileTime | SystemTimeToFileTime | test.cpp:333:62:333:63 | st | st |
|
|
@ -0,0 +1 @@
|
|||
Likely Bugs/Leap Year/UncheckedReturnValueForTimeFunctions.ql
|
|
@ -0,0 +1,658 @@
|
|||
typedef unsigned short WORD;
|
||||
typedef unsigned long DWORD, HANDLE;
|
||||
typedef int BOOL, BOOLEAN, errno_t;
|
||||
typedef char CHAR;
|
||||
typedef short SHORT;
|
||||
typedef long LONG;
|
||||
typedef unsigned short WCHAR; // wc, 16-bit UNICODE character
|
||||
typedef long __time64_t, time_t;
|
||||
#define NULL 0
|
||||
|
||||
typedef struct _SYSTEMTIME {
|
||||
WORD wYear;
|
||||
WORD wMonth;
|
||||
WORD wDayOfWeek;
|
||||
WORD wDay;
|
||||
WORD wHour;
|
||||
WORD wMinute;
|
||||
WORD wSecond;
|
||||
WORD wMilliseconds;
|
||||
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;
|
||||
|
||||
typedef struct _FILETIME {
|
||||
DWORD dwLowDateTime;
|
||||
DWORD dwHighDateTime;
|
||||
} FILETIME, *PFILETIME, *LPFILETIME;
|
||||
|
||||
typedef struct _TIME_ZONE_INFORMATION {
|
||||
LONG Bias;
|
||||
WCHAR StandardName[32];
|
||||
SYSTEMTIME StandardDate;
|
||||
LONG StandardBias;
|
||||
WCHAR DaylightName[32];
|
||||
SYSTEMTIME DaylightDate;
|
||||
LONG DaylightBias;
|
||||
} TIME_ZONE_INFORMATION, *PTIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
|
||||
|
||||
typedef struct _TIME_DYNAMIC_ZONE_INFORMATION {
|
||||
LONG Bias;
|
||||
WCHAR StandardName[32];
|
||||
SYSTEMTIME StandardDate;
|
||||
LONG StandardBias;
|
||||
WCHAR DaylightName[32];
|
||||
SYSTEMTIME DaylightDate;
|
||||
LONG DaylightBias;
|
||||
WCHAR TimeZoneKeyName[128];
|
||||
BOOLEAN DynamicDaylightTimeDisabled;
|
||||
} DYNAMIC_TIME_ZONE_INFORMATION, *PDYNAMIC_TIME_ZONE_INFORMATION;
|
||||
|
||||
struct tm
|
||||
{
|
||||
int tm_sec; // seconds after the minute - [0, 60] including leap second
|
||||
int tm_min; // minutes after the hour - [0, 59]
|
||||
int tm_hour; // hours since midnight - [0, 23]
|
||||
int tm_mday; // day of the month - [1, 31]
|
||||
int tm_mon; // months since January - [0, 11]
|
||||
int tm_year; // years since 1900
|
||||
int tm_wday; // days since Sunday - [0, 6]
|
||||
int tm_yday; // days since January 1 - [0, 365]
|
||||
int tm_isdst; // daylight savings time flag
|
||||
};
|
||||
|
||||
BOOL
|
||||
SystemTimeToFileTime(
|
||||
const SYSTEMTIME* lpSystemTime,
|
||||
LPFILETIME lpFileTime
|
||||
);
|
||||
|
||||
BOOL
|
||||
FileTimeToSystemTime(
|
||||
const FILETIME* lpFileTime,
|
||||
LPSYSTEMTIME lpSystemTime
|
||||
);
|
||||
|
||||
BOOL
|
||||
SystemTimeToTzSpecificLocalTime(
|
||||
const TIME_ZONE_INFORMATION* lpTimeZoneInformation,
|
||||
const SYSTEMTIME* lpUniversalTime,
|
||||
LPSYSTEMTIME lpLocalTime
|
||||
);
|
||||
|
||||
BOOL
|
||||
SystemTimeToTzSpecificLocalTimeEx(
|
||||
const DYNAMIC_TIME_ZONE_INFORMATION* lpTimeZoneInformation,
|
||||
const SYSTEMTIME* lpUniversalTime,
|
||||
LPSYSTEMTIME lpLocalTime
|
||||
);
|
||||
|
||||
BOOL
|
||||
TzSpecificLocalTimeToSystemTime(
|
||||
const TIME_ZONE_INFORMATION* lpTimeZoneInformation,
|
||||
const SYSTEMTIME* lpLocalTime,
|
||||
LPSYSTEMTIME lpUniversalTime
|
||||
);
|
||||
|
||||
BOOL
|
||||
TzSpecificLocalTimeToSystemTimeEx(
|
||||
const DYNAMIC_TIME_ZONE_INFORMATION* lpTimeZoneInformation,
|
||||
const SYSTEMTIME* lpLocalTime,
|
||||
LPSYSTEMTIME lpUniversalTime
|
||||
);
|
||||
|
||||
void GetSystemTime(
|
||||
LPSYSTEMTIME lpSystemTime
|
||||
);
|
||||
|
||||
void GetSystemTimeAsFileTime(
|
||||
LPFILETIME lpSystemTimeAsFileTime
|
||||
);
|
||||
|
||||
__time64_t _mkgmtime64(
|
||||
struct tm* _Tm
|
||||
);
|
||||
|
||||
__time64_t _mkgmtime(
|
||||
struct tm* const _Tm
|
||||
)
|
||||
{
|
||||
return _mkgmtime64(_Tm);
|
||||
}
|
||||
|
||||
__time64_t mktime(
|
||||
struct tm* const _Tm
|
||||
)
|
||||
{
|
||||
return _mkgmtime64(_Tm);
|
||||
}
|
||||
|
||||
__time64_t _time64(
|
||||
__time64_t* _Time
|
||||
);
|
||||
|
||||
__time64_t time(
|
||||
time_t* const _Time
|
||||
)
|
||||
{
|
||||
return _time64(_Time);
|
||||
}
|
||||
|
||||
int gmtime_s(
|
||||
struct tm* _Tm,
|
||||
__time64_t const* _Time
|
||||
);
|
||||
|
||||
BOOL
|
||||
GetFileTime(
|
||||
HANDLE hFile,
|
||||
LPFILETIME lpCreationTime,
|
||||
LPFILETIME lpLastAccessTime,
|
||||
LPFILETIME lpLastWriteTime
|
||||
);
|
||||
|
||||
void Correct_FileTimeToSystemTime(const FILETIME* lpFileTime)
|
||||
{
|
||||
SYSTEMTIME systemTime;
|
||||
|
||||
if (!FileTimeToSystemTime(lpFileTime, &systemTime))
|
||||
{
|
||||
/// handle error
|
||||
return;
|
||||
}
|
||||
|
||||
/// Normal usage
|
||||
}
|
||||
|
||||
void AntiPattern_FileTimeToSystemTime(const FILETIME* lpFileTime)
|
||||
{
|
||||
SYSTEMTIME systemTime;
|
||||
|
||||
// (out-of-scope) GeneralBug
|
||||
FileTimeToSystemTime(lpFileTime, &systemTime);
|
||||
}
|
||||
|
||||
void Correct_SystemTimeToTzSpecificLocalTime(const TIME_ZONE_INFORMATION *lpTimeZoneInformation, const SYSTEMTIME *lpUniversalTime)
|
||||
{
|
||||
SYSTEMTIME localTime;
|
||||
|
||||
if (!SystemTimeToTzSpecificLocalTime(lpTimeZoneInformation, lpUniversalTime, &localTime))
|
||||
{
|
||||
/// handle error
|
||||
return;
|
||||
}
|
||||
|
||||
/// Normal usage
|
||||
}
|
||||
|
||||
void AntiPattern_SystemTimeToTzSpecificLocalTime(const TIME_ZONE_INFORMATION *lpTimeZoneInformation, const SYSTEMTIME *lpUniversalTime)
|
||||
{
|
||||
SYSTEMTIME localTime;
|
||||
|
||||
// (out-of-scope) GeneralBug
|
||||
SystemTimeToTzSpecificLocalTime(lpTimeZoneInformation, lpUniversalTime, &localTime);
|
||||
}
|
||||
|
||||
void Correct_SystemTimeToTzSpecificLocalTimeEx(const DYNAMIC_TIME_ZONE_INFORMATION *lpTimeZoneInformation, const SYSTEMTIME *lpUniversalTime)
|
||||
{
|
||||
SYSTEMTIME localTime;
|
||||
|
||||
if (!SystemTimeToTzSpecificLocalTimeEx(lpTimeZoneInformation, lpUniversalTime, &localTime))
|
||||
{
|
||||
/// handle error
|
||||
return;
|
||||
}
|
||||
|
||||
/// Normal usage
|
||||
}
|
||||
|
||||
void AntiPattern_SystemTimeToTzSpecificLocalTimeEx(const DYNAMIC_TIME_ZONE_INFORMATION *lpTimeZoneInformation, const SYSTEMTIME *lpUniversalTime)
|
||||
{
|
||||
SYSTEMTIME localTime;
|
||||
|
||||
// (out-of-scope) GeneralBug
|
||||
SystemTimeToTzSpecificLocalTimeEx(lpTimeZoneInformation, lpUniversalTime, &localTime);
|
||||
}
|
||||
|
||||
void Correct_TzSpecificLocalTimeToSystemTime(const TIME_ZONE_INFORMATION *lpTimeZoneInformation, const SYSTEMTIME *lpLocalTime)
|
||||
{
|
||||
SYSTEMTIME universalTime;
|
||||
|
||||
if (!TzSpecificLocalTimeToSystemTime(lpTimeZoneInformation, lpLocalTime, &universalTime))
|
||||
{
|
||||
/// handle error
|
||||
return;
|
||||
}
|
||||
|
||||
/// Normal usage
|
||||
}
|
||||
|
||||
void AntiPattern_TzSpecificLocalTimeToSystemTime(const TIME_ZONE_INFORMATION *lpTimeZoneInformation, const SYSTEMTIME *lpLocalTime)
|
||||
{
|
||||
SYSTEMTIME universalTime;
|
||||
|
||||
// (out-of-scope) GeneralBug
|
||||
TzSpecificLocalTimeToSystemTime(lpTimeZoneInformation, lpLocalTime, &universalTime);
|
||||
}
|
||||
|
||||
void Correct_TzSpecificLocalTimeToSystemTimeEx(const DYNAMIC_TIME_ZONE_INFORMATION *lpTimeZoneInformation, const SYSTEMTIME *lpLocalTime)
|
||||
{
|
||||
SYSTEMTIME universalTime;
|
||||
|
||||
if (!TzSpecificLocalTimeToSystemTimeEx(lpTimeZoneInformation, lpLocalTime, &universalTime))
|
||||
{
|
||||
/// handle error
|
||||
return;
|
||||
}
|
||||
|
||||
/// Normal usage
|
||||
}
|
||||
|
||||
void AntiPattern_TzSpecificLocalTimeToSystemTimeEx(const DYNAMIC_TIME_ZONE_INFORMATION *lpTimeZoneInformation, const SYSTEMTIME *lpLocalTime)
|
||||
{
|
||||
SYSTEMTIME universalTime;
|
||||
|
||||
// (out-of-scope) GeneralBug
|
||||
TzSpecificLocalTimeToSystemTimeEx(lpTimeZoneInformation, lpLocalTime, &universalTime);
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
SYSTEMTIME Cases
|
||||
*************************************************/
|
||||
|
||||
void Correct_filetime_conversion_check(SYSTEMTIME& st)
|
||||
{
|
||||
FILETIME ft;
|
||||
|
||||
if (!SystemTimeToFileTime(&st, &ft))
|
||||
{
|
||||
/// Something failed, handle error
|
||||
return;
|
||||
}
|
||||
|
||||
/// SystemTimeToFileTime succeeded
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
|
||||
void AntiPattern_unchecked_filetime_conversion(SYSTEMTIME& st)
|
||||
{
|
||||
FILETIME ft;
|
||||
|
||||
// (out-of-scope) GeneralBug: Unchecked call to SystemTimeToFileTime. this may have failed, but we didn't check the return value!
|
||||
SystemTimeToFileTime(&st, &ft);
|
||||
}
|
||||
|
||||
void AntiPattern_unchecked_filetime_conversion2(SYSTEMTIME* st)
|
||||
{
|
||||
FILETIME ft;
|
||||
|
||||
if (st != NULL)
|
||||
{
|
||||
// (out-of-scope) GeneralBug: Unchecked call to SystemTimeToFileTime. this may have failed, but we didn't check the return value!
|
||||
SystemTimeToFileTime(st, &ft);
|
||||
}
|
||||
}
|
||||
|
||||
void AntiPattern_unchecked_filetime_conversion2()
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
FILETIME ft;
|
||||
GetSystemTime(&st);
|
||||
|
||||
st.wDay++;
|
||||
|
||||
// (out-of-scope) GeneralBug: Not checking is OK, no struct manipulation
|
||||
SystemTimeToFileTime(&st, &ft);
|
||||
}
|
||||
|
||||
void AntiPattern_unchecked_filetime_conversion2a()
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
FILETIME ft;
|
||||
GetSystemTime(&st);
|
||||
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
st.wYear += 2;
|
||||
|
||||
// BUG - UncheckedReturnValueForTimeFunctions
|
||||
SystemTimeToFileTime(&st, &ft);
|
||||
}
|
||||
|
||||
void AntiPattern_unchecked_filetime_conversion2b()
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
FILETIME ft;
|
||||
GetSystemTime(&st);
|
||||
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
st.wYear++;
|
||||
|
||||
// BUG - UncheckedReturnValueForTimeFunctions
|
||||
SystemTimeToFileTime(&st, &ft);
|
||||
}
|
||||
|
||||
void AntiPattern_unchecked_filetime_conversion2b(SYSTEMTIME* st)
|
||||
{
|
||||
FILETIME ft;
|
||||
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
st->wYear++;
|
||||
|
||||
// BUG - UncheckedReturnValueForTimeFunctions
|
||||
SystemTimeToFileTime(st, &ft);
|
||||
}
|
||||
|
||||
void AntiPattern_unchecked_filetime_conversion3()
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
FILETIME ft;
|
||||
GetSystemTime(&st);
|
||||
|
||||
if (st.wMonth < 12)
|
||||
{
|
||||
st.wMonth++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check for leap year, but...
|
||||
st.wMonth = 1;
|
||||
st.wYear++;
|
||||
}
|
||||
|
||||
// (out-of-scope) GeneralBug: Not checking if newly generated date is valid for conversion
|
||||
SystemTimeToFileTime(&st, &ft);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
void CorrectPattern_check1()
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime(&st);
|
||||
|
||||
st.wYear++;
|
||||
|
||||
// Guard
|
||||
if (st.wMonth == 2 && st.wDay == 29)
|
||||
{
|
||||
// move back a day when landing on Feb 29 in an non-leap year
|
||||
bool isLeapYear = st.wYear % 4 == 0 && (st.wYear % 100 != 0 || st.wYear % 400 == 0);
|
||||
if (!isLeapYear)
|
||||
{
|
||||
st.wDay = 28;
|
||||
}
|
||||
}
|
||||
|
||||
// Safe to use
|
||||
AntiPattern_unchecked_filetime_conversion(st);
|
||||
}
|
||||
|
||||
void CorrectPattern_check2(int yearsToAdd)
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime(&st);
|
||||
|
||||
st.wYear += yearsToAdd;
|
||||
|
||||
// Guard
|
||||
bool isLeapYear = st.wYear % 4 == 0 && (st.wYear % 100 != 0 || st.wYear % 400 == 0);
|
||||
st.wDay = st.wMonth == 2 && st.wDay == 29 && !isLeapYear ? 28 : st.wDay;
|
||||
|
||||
// Safe to use
|
||||
AntiPattern_unchecked_filetime_conversion(st);
|
||||
}
|
||||
|
||||
bool isLeapYear(SYSTEMTIME& st)
|
||||
{
|
||||
return st.wYear % 4 == 0 && (st.wYear % 100 != 0 || st.wYear % 400 == 0);
|
||||
}
|
||||
|
||||
void CorrectPattern_check3()
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime(&st);
|
||||
|
||||
st.wYear++;
|
||||
|
||||
// Guard
|
||||
if (st.wMonth == 2 && st.wDay == 29 && isLeapYear(st))
|
||||
{
|
||||
// move back a day when landing on Feb 29 in an non-leap year
|
||||
st.wDay = 28;
|
||||
}
|
||||
|
||||
// Safe to use
|
||||
AntiPattern_unchecked_filetime_conversion(st);
|
||||
}
|
||||
|
||||
bool isLeapYear2(int year)
|
||||
{
|
||||
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
|
||||
}
|
||||
|
||||
bool fixDate(int day, int month, int year)
|
||||
{
|
||||
return (month == 2 && day == 29 && isLeapYear2(year));
|
||||
}
|
||||
|
||||
void CorrectPattern_check4()
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime(&st);
|
||||
|
||||
///// FP
|
||||
st.wYear++;
|
||||
|
||||
// Guard
|
||||
if (fixDate(st.wDay, st.wMonth, st.wYear))
|
||||
{
|
||||
// move back a day when landing on Feb 29 in an non-leap year
|
||||
st.wDay = 28;
|
||||
}
|
||||
|
||||
// Safe to use
|
||||
AntiPattern_unchecked_filetime_conversion(st);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CorrectPattern_NotManipulated_DateFromAPI_0()
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime(&st);
|
||||
FILETIME ft;
|
||||
|
||||
// Not checking is OK, no struct manipulation
|
||||
SystemTimeToFileTime(&st, &ft);
|
||||
}
|
||||
|
||||
void CorrectPattern_NotManipulated_DateFromAPI_1(HANDLE hWatchdog)
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
FILETIME ft;
|
||||
|
||||
GetFileTime(hWatchdog, NULL, NULL, &ft);
|
||||
FileTimeToSystemTime(&ft, &st);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
void AntiPattern_1_year_addition()
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime(&st);
|
||||
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
st.wYear++;
|
||||
|
||||
// Usage of potentially invalid date
|
||||
Correct_filetime_conversion_check(st);
|
||||
}
|
||||
|
||||
void AntiPattern_simple_addition(int yearAddition)
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
|
||||
GetSystemTime(&st);
|
||||
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
st.wYear += yearAddition;
|
||||
|
||||
// Usage of potentially invalid date
|
||||
Correct_filetime_conversion_check(st);
|
||||
}
|
||||
|
||||
void AntiPattern_IncorrectGuard(int yearsToAdd)
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
GetSystemTime(&st);
|
||||
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
st.wYear += yearsToAdd;
|
||||
|
||||
// Incorrect Guard
|
||||
if (st.wMonth == 2 && st.wDay == 29)
|
||||
{
|
||||
// Part of a different anti-pattern.
|
||||
// Make sure the guard includes the proper check
|
||||
bool isLeapYear = st.wYear % 4 == 0;
|
||||
if (!isLeapYear)
|
||||
{
|
||||
st.wDay = 28;
|
||||
}
|
||||
}
|
||||
|
||||
// Potentially Unsafe to use
|
||||
Correct_filetime_conversion_check(st);
|
||||
}
|
||||
|
||||
/*************************************************
|
||||
struct tm Cases
|
||||
*************************************************/
|
||||
|
||||
void CorrectUsageOf_mkgmtime(struct tm& timeinfo)
|
||||
{
|
||||
if (_mkgmtime(&timeinfo) == -1)
|
||||
{
|
||||
/// Something failed, handle error
|
||||
return;
|
||||
}
|
||||
|
||||
/// _mkgmtime succeeded
|
||||
}
|
||||
|
||||
void AntiPattern_uncheckedUsageOf_mkgmtime(struct tm& timeinfo)
|
||||
{
|
||||
// (out-of-scope) GeneralBug: Must check return value for _mkgmtime
|
||||
// QLNOTE: Include other related _mkgmtime* functions in the function name pattern
|
||||
_mkgmtime(&timeinfo);
|
||||
// _mktime64(&timeinfo);
|
||||
// _mktime32(&timeinfo);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////
|
||||
|
||||
void Correct_year_addition_struct_tm()
|
||||
{
|
||||
time_t rawtime;
|
||||
struct tm timeinfo;
|
||||
time(&rawtime);
|
||||
// NOTE: Should ideally check return value for this function (not in scope)
|
||||
errno_t err = gmtime_s(&timeinfo, &rawtime);
|
||||
if (err)
|
||||
{
|
||||
/// handle error
|
||||
return;
|
||||
}
|
||||
|
||||
// this is the potentially dangerous part, when not followed up with leap year checks
|
||||
timeinfo.tm_year++;
|
||||
|
||||
// Guard
|
||||
// move back a day when landing on Feb 29 in an non-leap year
|
||||
bool isLeapYear = timeinfo.tm_year % 4 == 0 && (timeinfo.tm_year % 100 != 0 || (timeinfo.tm_year + 1900) % 400 == 0);
|
||||
timeinfo.tm_mday = timeinfo.tm_mon == 1 && timeinfo.tm_mday == 29 && !isLeapYear ? 28 : timeinfo.tm_mday;
|
||||
|
||||
// safe to use
|
||||
AntiPattern_uncheckedUsageOf_mkgmtime(timeinfo);
|
||||
}
|
||||
|
||||
void Correct_LinuxPattern()
|
||||
{
|
||||
time_t rawtime;
|
||||
struct tm timeinfo;
|
||||
time(&rawtime);
|
||||
// NOTE: Should ideally check return value for this function (not in scope)
|
||||
errno_t err = gmtime_s(&timeinfo, &rawtime);
|
||||
|
||||
/* from 1900 -> from 1980 */
|
||||
timeinfo.tm_year -= 80;
|
||||
/* 0~11 -> 1~12 */
|
||||
timeinfo.tm_mon++;
|
||||
/* 0~59 -> 0~29(2sec counts) */
|
||||
timeinfo.tm_sec >>= 1;
|
||||
|
||||
// safe to use
|
||||
AntiPattern_uncheckedUsageOf_mkgmtime(timeinfo);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////
|
||||
|
||||
void AntiPattern_year_addition_struct_tm()
|
||||
{
|
||||
time_t rawtime;
|
||||
struct tm timeinfo;
|
||||
time(&rawtime);
|
||||
gmtime_s(&timeinfo, &rawtime);
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
timeinfo.tm_year++;
|
||||
|
||||
// Usage of potentially invalid date
|
||||
CorrectUsageOf_mkgmtime(timeinfo);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
void FalsePositiveTests(int x)
|
||||
{
|
||||
struct tm timeinfo;
|
||||
SYSTEMTIME st;
|
||||
|
||||
timeinfo.tm_year = x;
|
||||
timeinfo.tm_year = 1970;
|
||||
|
||||
st.wYear = x;
|
||||
st.wYear = 1900 + x;
|
||||
}
|
||||
|
||||
void FalseNegativeTests(int x)
|
||||
{
|
||||
struct tm timeinfo;
|
||||
SYSTEMTIME st;
|
||||
|
||||
timeinfo.tm_year = x;
|
||||
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
timeinfo.tm_year = x + timeinfo.tm_year;
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
timeinfo.tm_year = 1970 + timeinfo.tm_year;
|
||||
|
||||
st.wYear = x;
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
st.wYear = x + st.wYear;
|
||||
// BUG - UncheckedLeapYearAfterYearModification
|
||||
st.wYear = (1986 + st.wYear) - 1;
|
||||
}
|
||||
|
||||
// False positive
|
||||
inline void
|
||||
IncrementMonth(LPSYSTEMTIME pst)
|
||||
{
|
||||
if (pst->wMonth < 12)
|
||||
{
|
||||
pst->wMonth++;
|
||||
}
|
||||
else
|
||||
{
|
||||
pst->wMonth = 1;
|
||||
pst->wYear++;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
| test.cpp:173:29:173:38 | qwLongTime | This arithmetic operation $@ uses a constant value of 365 ends up modifying the date/time located at $@, without considering leap year scenarios. | test.cpp:170:2:170:47 | ... += ... | ... += ... | test.cpp:173:29:173:38 | qwLongTime | qwLongTime |
|
||||
| test.cpp:174:30:174:39 | qwLongTime | This arithmetic operation $@ uses a constant value of 365 ends up modifying the date/time located at $@, without considering leap year scenarios. | test.cpp:170:2:170:47 | ... += ... | ... += ... | test.cpp:174:30:174:39 | qwLongTime | qwLongTime |
|
|
@ -0,0 +1 @@
|
|||
Likely Bugs/Leap Year/Adding365daysPerYear.ql
|
|
@ -0,0 +1,178 @@
|
|||
typedef unsigned short WORD;
|
||||
typedef unsigned long DWORD, HANDLE;
|
||||
typedef int BOOL, BOOLEAN, errno_t;
|
||||
typedef char CHAR;
|
||||
typedef short SHORT;
|
||||
typedef long LONG;
|
||||
typedef unsigned short WCHAR; // wc, 16-bit UNICODE character
|
||||
typedef long __time64_t, time_t;
|
||||
#define NULL 0
|
||||
|
||||
typedef long long LONGLONG;
|
||||
typedef unsigned long long ULONGLONG;
|
||||
|
||||
|
||||
typedef struct _SYSTEMTIME {
|
||||
WORD wYear;
|
||||
WORD wMonth;
|
||||
WORD wDayOfWeek;
|
||||
WORD wDay;
|
||||
WORD wHour;
|
||||
WORD wMinute;
|
||||
WORD wSecond;
|
||||
WORD wMilliseconds;
|
||||
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;
|
||||
|
||||
typedef struct _FILETIME {
|
||||
DWORD dwLowDateTime;
|
||||
DWORD dwHighDateTime;
|
||||
} FILETIME, *PFILETIME, *LPFILETIME;
|
||||
|
||||
typedef struct _TIME_ZONE_INFORMATION {
|
||||
LONG Bias;
|
||||
WCHAR StandardName[32];
|
||||
SYSTEMTIME StandardDate;
|
||||
LONG StandardBias;
|
||||
WCHAR DaylightName[32];
|
||||
SYSTEMTIME DaylightDate;
|
||||
LONG DaylightBias;
|
||||
} TIME_ZONE_INFORMATION, *PTIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
|
||||
|
||||
typedef struct _TIME_DYNAMIC_ZONE_INFORMATION {
|
||||
LONG Bias;
|
||||
WCHAR StandardName[32];
|
||||
SYSTEMTIME StandardDate;
|
||||
LONG StandardBias;
|
||||
WCHAR DaylightName[32];
|
||||
SYSTEMTIME DaylightDate;
|
||||
LONG DaylightBias;
|
||||
WCHAR TimeZoneKeyName[128];
|
||||
BOOLEAN DynamicDaylightTimeDisabled;
|
||||
} DYNAMIC_TIME_ZONE_INFORMATION, *PDYNAMIC_TIME_ZONE_INFORMATION;
|
||||
|
||||
struct tm
|
||||
{
|
||||
int tm_sec; // seconds after the minute - [0, 60] including leap second
|
||||
int tm_min; // minutes after the hour - [0, 59]
|
||||
int tm_hour; // hours since midnight - [0, 23]
|
||||
int tm_mday; // day of the month - [1, 31]
|
||||
int tm_mon; // months since January - [0, 11]
|
||||
int tm_year; // years since 1900
|
||||
int tm_wday; // days since Sunday - [0, 6]
|
||||
int tm_yday; // days since January 1 - [0, 365]
|
||||
int tm_isdst; // daylight savings time flag
|
||||
};
|
||||
|
||||
BOOL
|
||||
SystemTimeToFileTime(
|
||||
const SYSTEMTIME* lpSystemTime,
|
||||
LPFILETIME lpFileTime
|
||||
);
|
||||
|
||||
BOOL
|
||||
FileTimeToSystemTime(
|
||||
const FILETIME* lpFileTime,
|
||||
LPSYSTEMTIME lpSystemTime
|
||||
);
|
||||
|
||||
BOOL
|
||||
SystemTimeToTzSpecificLocalTime(
|
||||
const TIME_ZONE_INFORMATION* lpTimeZoneInformation,
|
||||
const SYSTEMTIME* lpUniversalTime,
|
||||
LPSYSTEMTIME lpLocalTime
|
||||
);
|
||||
|
||||
BOOL
|
||||
SystemTimeToTzSpecificLocalTimeEx(
|
||||
const DYNAMIC_TIME_ZONE_INFORMATION* lpTimeZoneInformation,
|
||||
const SYSTEMTIME* lpUniversalTime,
|
||||
LPSYSTEMTIME lpLocalTime
|
||||
);
|
||||
|
||||
BOOL
|
||||
TzSpecificLocalTimeToSystemTime(
|
||||
const TIME_ZONE_INFORMATION* lpTimeZoneInformation,
|
||||
const SYSTEMTIME* lpLocalTime,
|
||||
LPSYSTEMTIME lpUniversalTime
|
||||
);
|
||||
|
||||
BOOL
|
||||
TzSpecificLocalTimeToSystemTimeEx(
|
||||
const DYNAMIC_TIME_ZONE_INFORMATION* lpTimeZoneInformation,
|
||||
const SYSTEMTIME* lpLocalTime,
|
||||
LPSYSTEMTIME lpUniversalTime
|
||||
);
|
||||
|
||||
void GetSystemTime(
|
||||
LPSYSTEMTIME lpSystemTime
|
||||
);
|
||||
|
||||
void GetSystemTimeAsFileTime(
|
||||
LPFILETIME lpSystemTimeAsFileTime
|
||||
);
|
||||
|
||||
__time64_t _mkgmtime64(
|
||||
struct tm* _Tm
|
||||
);
|
||||
|
||||
__time64_t _mkgmtime(
|
||||
struct tm* const _Tm
|
||||
)
|
||||
{
|
||||
return _mkgmtime64(_Tm);
|
||||
}
|
||||
|
||||
__time64_t mktime(
|
||||
struct tm* const _Tm
|
||||
)
|
||||
{
|
||||
return _mkgmtime64(_Tm);
|
||||
}
|
||||
|
||||
__time64_t _time64(
|
||||
__time64_t* _Time
|
||||
);
|
||||
|
||||
__time64_t time(
|
||||
time_t* const _Time
|
||||
)
|
||||
{
|
||||
return _time64(_Time);
|
||||
}
|
||||
|
||||
int gmtime_s(
|
||||
struct tm* _Tm,
|
||||
__time64_t const* _Time
|
||||
);
|
||||
|
||||
BOOL
|
||||
GetFileTime(
|
||||
HANDLE hFile,
|
||||
LPFILETIME lpCreationTime,
|
||||
LPFILETIME lpLastAccessTime,
|
||||
LPFILETIME lpLastWriteTime
|
||||
);
|
||||
|
||||
|
||||
void antipattern2()
|
||||
{
|
||||
// get the current time as a FILETIME
|
||||
SYSTEMTIME st; FILETIME ft;
|
||||
GetSystemTime(&st);
|
||||
SystemTimeToFileTime(&st, &ft);
|
||||
|
||||
// convert to a quadword (64-bit integer) to do arithmetic
|
||||
ULONGLONG qwLongTime;
|
||||
qwLongTime = (((ULONGLONG)ft.dwHighDateTime) << 32) + ft.dwLowDateTime;
|
||||
|
||||
// add a year by calculating the ticks in 365 days
|
||||
// (which may be incorrect when crossing a leap day)
|
||||
qwLongTime += 365 * 24 * 60 * 60 * 10000000LLU;
|
||||
|
||||
// copy back to a FILETIME
|
||||
ft.dwLowDateTime = (DWORD)(qwLongTime & 0xFFFFFFFF);
|
||||
ft.dwHighDateTime = (DWORD)(qwLongTime >> 32);
|
||||
|
||||
// convert back to SYSTEMTIME for display or other usage
|
||||
FileTimeToSystemTime(&ft, &st);
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
| test.cpp:17:6:17:10 | items | There is an array or std::vector allocation with a hard-coded set of 365 elements, which may indicate the number of days in a year without considering leap year scenarios. |
|
||||
| test.cpp:25:15:25:26 | new[] | There is an array or std::vector allocation with a hard-coded set of 365 elements, which may indicate the number of days in a year without considering leap year scenarios. |
|
||||
| test.cpp:52:20:52:23 | call to vector | There is an array or std::vector allocation with a hard-coded set of 365 elements, which may indicate the number of days in a year without considering leap year scenarios. |
|
|
@ -0,0 +1 @@
|
|||
Likely Bugs/Leap Year/UnsafeArrayForDaysOfYear.ql
|
|
@ -0,0 +1,70 @@
|
|||
template <class T>
|
||||
class vector {
|
||||
private:
|
||||
T _x;
|
||||
public:
|
||||
vector(int size)
|
||||
{
|
||||
}
|
||||
|
||||
T& operator[](int idx) { return _x; }
|
||||
const T& operator[](int idx) const { return _x; }
|
||||
};
|
||||
|
||||
void ArrayOfDays_Bug(int dayOfYear, int x)
|
||||
{
|
||||
// BUG
|
||||
int items[365];
|
||||
|
||||
items[dayOfYear - 1] = x;
|
||||
}
|
||||
|
||||
void ArrayOfDays_Bug2(int dayOfYear, int x)
|
||||
{
|
||||
// BUG
|
||||
int *items = new int[365];
|
||||
|
||||
items[dayOfYear - 1] = x;
|
||||
delete items;
|
||||
}
|
||||
|
||||
|
||||
void ArrayOfDays_Correct(unsigned long year, int dayOfYear, int x)
|
||||
{
|
||||
bool isLeapYear = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
|
||||
int *items = new int[isLeapYear ? 366 : 365];
|
||||
|
||||
items[dayOfYear - 1] = x;
|
||||
|
||||
delete[] items;
|
||||
}
|
||||
|
||||
void ArrayOfDays_FalsePositive(int dayOfYear, int x)
|
||||
{
|
||||
int items[366];
|
||||
|
||||
items[dayOfYear - 1] = x;
|
||||
}
|
||||
|
||||
void VectorOfDays_Bug(int dayOfYear, int x)
|
||||
{
|
||||
// BUG
|
||||
vector<int> items(365);
|
||||
|
||||
items[dayOfYear - 1] = x;
|
||||
}
|
||||
|
||||
void VectorOfDays_Correct(unsigned long year, int dayOfYear, int x)
|
||||
{
|
||||
bool isLeapYear = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
|
||||
vector<int> items(isLeapYear ? 366 : 365);
|
||||
|
||||
items[dayOfYear - 1] = x;
|
||||
}
|
||||
|
||||
void VectorOfDays_FalsePositive(int dayOfYear, int x)
|
||||
{
|
||||
vector<int> items(366);
|
||||
|
||||
items[dayOfYear - 1] = x;
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
| test.cpp:35:2:37:2 | for(...;...;...) ... | test.cpp:35:18:35:23 | ... < ... | 1 | i | { ... } | i | ExprStmt |
|
||||
| test.cpp:43:2:45:2 | for(...;...;...) ... | test.cpp:43:18:43:26 | ... < ... | | i | { ... } | i | ExprStmt |
|
||||
| test.cpp:74:2:77:2 | while (...) ... | test.cpp:74:9:74:17 | ... > ... | 1 | count | { ... } | count | ExprStmt |
|
||||
| test.cpp:84:2:88:2 | while (...) ... | test.cpp:84:9:84:17 | ... > ... | | count | { ... } | count | if (...) ... |
|
||||
| test.cpp:171:3:173:3 | while (...) ... | test.cpp:171:10:171:43 | ... != ... | 0 | | { ... } | 0 | return ... |
|
||||
| test.cpp:251:2:255:2 | while (...) ... | test.cpp:251:9:251:12 | loop | 1 | loop | { ... } | loop | return ... |
|
||||
| test.cpp:263:2:267:2 | while (...) ... | test.cpp:263:9:263:20 | ... && ... | 1 | 1 | { ... } | ... && ... | return ... |
|
||||
| test.cpp:275:2:279:2 | while (...) ... | test.cpp:275:9:275:13 | ! ... | 1 | stop | { ... } | stop | return ... |
|
||||
| test.cpp:287:2:291:2 | while (...) ... | test.cpp:287:9:287:20 | ... && ... | 1 | loop | { ... } | loop | return ... |
|
||||
| test.cpp:299:2:303:2 | while (...) ... | test.cpp:299:9:299:20 | ... && ... | 1 | loop | { ... } | ... && ..., loop | return ... |
|
||||
| test.cpp:311:2:315:2 | while (...) ... | test.cpp:311:9:311:21 | ... \|\| ... | 1 | ... \|\| ... | { ... } | 0 | return ... |
|
||||
| test.cpp:323:2:328:2 | while (...) ... | test.cpp:323:9:323:17 | ... ? ... : ... | | b, c | { ... } | c | return ... |
|
||||
| test.cpp:336:2:341:2 | while (...) ... | test.cpp:336:9:336:21 | ... \|\| ... | 1 | b, c | { ... } | c | return ... |
|
||||
| test.cpp:348:2:351:17 | do (...) ... | test.cpp:351:11:351:15 | 0 | | { ... } | { ... } | { ... } | return ... |
|
||||
| test.cpp:361:2:364:2 | while (...) ... | test.cpp:361:9:361:21 | ... \|\| ... | 1 | ... \|\| ... | { ... } | 0 | while (...) ... |
|
||||
| test.cpp:365:2:368:2 | while (...) ... | test.cpp:365:9:365:13 | ! ... | 1 | stop | { ... } | stop | while (...) ... |
|
||||
| test.cpp:369:2:373:2 | while (...) ... | test.cpp:369:9:369:21 | ... \|\| ... | 1 | b, c | { ... } | c | do (...) ... |
|
||||
| test.cpp:374:2:376:17 | do (...) ... | test.cpp:376:11:376:15 | 0 | | do (...) ... | { ... } | { ... } | return ... |
|
||||
| test.cpp:384:2:386:2 | while (...) ... | test.cpp:384:9:384:12 | 1 | 1 | 1 | { ... } | | return ... |
|
||||
| test.cpp:394:2:396:2 | while (...) ... | test.cpp:394:9:394:21 | ... , ... | | { ... } | { ... } | | |
|
||||
| test.cpp:404:3:408:3 | while (...) ... | test.cpp:404:10:404:13 | loop | 1 | loop | { ... } | | |
|
||||
| test.cpp:416:2:418:2 | for(...;...;...) ... | test.cpp:416:18:416:23 | ... < ... | 1 | i | { ... } | i | return ... |
|
||||
| test.cpp:424:2:425:2 | for(...;...;...) ... | test.cpp:424:18:424:23 | ... < ... | 1 | i | { ... } | i | return ... |
|
||||
| test.cpp:433:2:434:2 | for(...;...;...) ... | test.cpp:433:18:433:22 | 0 | 0 | | { ... } | 0 | return ... |
|
|
@ -0,0 +1,13 @@
|
|||
import cpp
|
||||
import LoopConditionsConst
|
||||
|
||||
from Loop l, Expr condition
|
||||
where
|
||||
l.getCondition() = condition
|
||||
select
|
||||
l, condition,
|
||||
concat(int val | loopEntryConst(condition, val) | val.toString(), ", "),
|
||||
concat(BasicBlock bb | bb.getASuccessor() = l.getStmt() | bb.toString(), ", "),
|
||||
concat(l.getStmt().toString(), ", "),
|
||||
concat(BasicBlock bb | bb.getASuccessor() = l.getFollowingStmt() | bb.toString(), ", "),
|
||||
concat(l.getFollowingStmt().toString(), ", ")
|
|
@ -0,0 +1,10 @@
|
|||
import cpp
|
||||
import semmle.code.cpp.controlflow.internal.ConstantExprs
|
||||
|
||||
predicate loopEntryConst(Expr condition, int val)
|
||||
{
|
||||
exists(LoopEntryConditionEvaluator x, ControlFlowNode loop |
|
||||
x.isLoopEntry(condition, loop) and
|
||||
val = x.getValue(condition)
|
||||
)
|
||||
}
|
|
@ -8,3 +8,9 @@
|
|||
| test.cpp:132:9:132:9 | j | The variable $@ may not be initialized here. | test.cpp:126:6:126:6 | j | j |
|
||||
| test.cpp:219:3:219:3 | x | The variable $@ may not be initialized here. | test.cpp:218:7:218:7 | x | x |
|
||||
| test.cpp:243:13:243:13 | i | The variable $@ may not be initialized here. | test.cpp:241:6:241:6 | i | i |
|
||||
| test.cpp:329:9:329:11 | val | The variable $@ may not be initialized here. | test.cpp:321:6:321:8 | val | val |
|
||||
| test.cpp:336:10:336:10 | a | The variable $@ may not be initialized here. | test.cpp:333:7:333:7 | a | a |
|
||||
| test.cpp:369:10:369:10 | a | The variable $@ may not be initialized here. | test.cpp:358:7:358:7 | a | a |
|
||||
| test.cpp:378:9:378:11 | val | The variable $@ may not be initialized here. | test.cpp:359:6:359:8 | val | val |
|
||||
| test.cpp:417:10:417:10 | j | The variable $@ may not be initialized here. | test.cpp:414:9:414:9 | j | j |
|
||||
| test.cpp:436:9:436:9 | j | The variable $@ may not be initialized here. | test.cpp:431:9:431:9 | j | j |
|
||||
|
|
|
@ -242,4 +242,196 @@ void test21()
|
|||
|
||||
v3 = v1 >> i; // BAD: i is not initialized
|
||||
v3 = v2 >> 1; // BAD: v2 is not initialized [NOT DETECTED]
|
||||
}
|
||||
}
|
||||
|
||||
int test22() {
|
||||
bool loop = true;
|
||||
int val;
|
||||
|
||||
while (loop)
|
||||
{
|
||||
val = 1;
|
||||
loop = false;
|
||||
}
|
||||
return val; // GOOD
|
||||
}
|
||||
|
||||
int test23() {
|
||||
bool loop = true, stop = false;
|
||||
int val;
|
||||
|
||||
while (loop && true)
|
||||
{
|
||||
val = 1;
|
||||
loop = false;
|
||||
}
|
||||
return val; // GOOD
|
||||
}
|
||||
|
||||
int test24() {
|
||||
bool stop = false;
|
||||
int val;
|
||||
|
||||
while (!stop)
|
||||
{
|
||||
val = 1;
|
||||
stop = true;
|
||||
}
|
||||
return val; // GOOD
|
||||
}
|
||||
|
||||
int test25() {
|
||||
bool loop = true, stop = false;
|
||||
int val;
|
||||
|
||||
while (true && loop)
|
||||
{
|
||||
val = 1;
|
||||
loop = false;
|
||||
}
|
||||
return val; // GOOD
|
||||
}
|
||||
|
||||
int test26() {
|
||||
bool loop = true, stop = false;
|
||||
int val;
|
||||
|
||||
while (loop && loop)
|
||||
{
|
||||
val = 1;
|
||||
loop = false;
|
||||
}
|
||||
return val; // GOOD
|
||||
}
|
||||
|
||||
int test27() {
|
||||
bool loop = true, stop = false;
|
||||
int val;
|
||||
|
||||
while (loop || false)
|
||||
{
|
||||
val = 1;
|
||||
loop = false;
|
||||
}
|
||||
return val; // GOOD
|
||||
}
|
||||
|
||||
int test28() {
|
||||
bool a = true, b = true, c = true;
|
||||
int val;
|
||||
|
||||
while (a ? b : c)
|
||||
{
|
||||
val = 1;
|
||||
a = false;
|
||||
c = false;
|
||||
}
|
||||
return val; // GOOD [FALSE POSITIVE]
|
||||
}
|
||||
|
||||
int test29() {
|
||||
bool a, b = true, c = true;
|
||||
int val;
|
||||
|
||||
while ((a && b) || c) // BAD (a is uninitialized)
|
||||
{
|
||||
val = 1;
|
||||
b = false;
|
||||
c = false;
|
||||
}
|
||||
return val; // GOOD
|
||||
}
|
||||
|
||||
int test30() {
|
||||
int val;
|
||||
|
||||
do
|
||||
{
|
||||
val = 1;
|
||||
} while (false);
|
||||
return val; // GOOD
|
||||
}
|
||||
|
||||
int test31() {
|
||||
bool loop = true;
|
||||
bool stop = false;
|
||||
bool a, b = true, c = true;
|
||||
int val;
|
||||
|
||||
while (loop || false)
|
||||
{
|
||||
loop = false;
|
||||
}
|
||||
while (!stop)
|
||||
{
|
||||
stop = true;
|
||||
}
|
||||
while ((a && b) || c) // BAD (a is uninitialized)
|
||||
{
|
||||
b = false;
|
||||
c = false;
|
||||
}
|
||||
do
|
||||
{
|
||||
} while (false);
|
||||
|
||||
return val; // BAD
|
||||
}
|
||||
|
||||
int test32() {
|
||||
int val;
|
||||
|
||||
while (true)
|
||||
{
|
||||
}
|
||||
|
||||
return val; // GOOD (never reached)
|
||||
}
|
||||
|
||||
int test33() {
|
||||
int val;
|
||||
|
||||
while (val = 1, true) {
|
||||
return val; // GOOD
|
||||
}
|
||||
}
|
||||
|
||||
int test34() {
|
||||
bool loop = true;
|
||||
int val;
|
||||
|
||||
{
|
||||
while (loop)
|
||||
{
|
||||
val = 1;
|
||||
loop = false;
|
||||
}
|
||||
}
|
||||
return val; // GOOD
|
||||
}
|
||||
|
||||
int test35() {
|
||||
int i, j;
|
||||
|
||||
for (int i = 0; i < 10; i++, j = 1) {
|
||||
return j; // BAD
|
||||
}
|
||||
}
|
||||
|
||||
int test36() {
|
||||
int i, j;
|
||||
|
||||
for (int i = 0; i < 10; i++, j = 1) {
|
||||
}
|
||||
|
||||
return j; // GOOD
|
||||
}
|
||||
|
||||
int test38() {
|
||||
int i, j;
|
||||
|
||||
for (int i = 0; false; i++, j = 1) {
|
||||
}
|
||||
|
||||
return j; // BAD
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<AssemblyName>Semmle.Autobuild</AssemblyName>
|
||||
<RootNamespace>Semmle.Autobuild</RootNamespace>
|
||||
<ApplicationIcon />
|
||||
|
@ -15,7 +15,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Build" Version="15.8.166" />
|
||||
<PackageReference Include="Microsoft.Build" Version="16.0.461" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -1,310 +1,3 @@
|
|||
# Auto-generated by:
|
||||
# ./build target/general/lgtm-query-suites/output/csharp-alerts-lgtm
|
||||
+ semmlecode-csharp-queries/API Abuse/CallToGCCollect.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/API Abuse/CallToObsoleteMethod.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/API Abuse/ClassDoesNotImplementEquals.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/API Abuse/ClassImplementsICloneable.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/API Abuse/DisposeNotCalledOnException.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/API Abuse/FormatInvalid.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/API Abuse/FormatMissingArgument.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/API Abuse/FormatUnusedArgument.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/API Abuse/InconsistentEqualsGetHashCode.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/API Abuse/IncorrectCompareToSignature.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/API Abuse/IncorrectEqualsSignature.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/API Abuse/NoDisposeCallOnLocalIDisposable.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/API Abuse/NullArgumentToEquals.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/ASP/BlockCodeResponseWrite.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Architecture/Refactoring Opportunities/InappropriateIntimacy.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Bad Practices/CallsUnmanagedCode.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Bad Practices/CatchOfNullReferenceException.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Bad Practices/Control-Flow/ConstantCondition.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Bad Practices/Declarations/LocalScopeVariableShadowsMember.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Bad Practices/Declarations/TooManyRefParameters.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Bad Practices/EmptyCatchBlock.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Bad Practices/ErroneousClassCompare.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Bad Practices/Implementation Hiding/AbstractToConcreteCollection.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Bad Practices/Implementation Hiding/ExposeRepresentation.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Bad Practices/Naming Conventions/FieldMasksSuperField.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Bad Practices/Naming Conventions/SameNameAsSuper.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Bad Practices/UnmanagedCodeCheck.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Bad Practices/VirtualCallInConstructorOrDestructor.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/CSI/CompareIdenticalValues.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/CSI/NullAlways.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/CSI/NullMaybe.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Complexity/BlockWithTooManyStatements.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Complexity/ComplexCondition.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Concurrency/FutileSyncOnField.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Concurrency/LockOrder.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Concurrency/LockThis.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Concurrency/LockedWait.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Concurrency/SynchSetUnsynchGet.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Concurrency/UnsafeLazyInitialization.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Concurrency/UnsynchronizedStaticAccess.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Configuration/EmptyPasswordInConfigurationFile.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Configuration/PasswordInConfigurationFile.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Dead Code/DeadStoreOfLocal.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Documentation/XmldocMissingSummary.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Input Validation/UseOfFileUpload.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Input Validation/ValueShadowing.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Input Validation/ValueShadowingServerVariable.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Language Abuse/CastThisToTypeParameter.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Language Abuse/CatchOfGenericException.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Language Abuse/ChainedIs.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Language Abuse/DubiousDowncastOfThis.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Language Abuse/DubiousTypeTestOfThis.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Language Abuse/MissedReadonlyOpportunity.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Language Abuse/MissedTernaryOpportunity.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Language Abuse/MissedUsingOpportunity.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Language Abuse/NestedIf.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Language Abuse/RethrowException.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Language Abuse/SimplifyBoolExpr.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Language Abuse/UnusedPropertyValue.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Language Abuse/UselessCastToSelf.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Language Abuse/UselessNullCoalescingExpression.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Language Abuse/UselessTypeTest.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Language Abuse/UselessUpcast.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/Collections/ContainerLengthCmpOffByOne.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/Collections/ContainerSizeCmpZero.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/Collections/ReadOnlyContainer.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/Collections/WriteOnlyContainer.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/ConstantComparison.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/DangerousNonShortCircuitLogic.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/Dynamic/BadDynamicCall.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/EqualityCheckOnFloats.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/EqualsArray.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/EqualsUsesAs.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/EqualsUsesIs.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/HashedButNoHash.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/ImpossibleArrayCast.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/IncomparableEquals.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/InconsistentCompareTo.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/NestedLoopsSameVariable.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/ObjectComparison.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/PossibleLossOfPrecision.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/RecursiveEquals.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/RecursiveOperatorEquals.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/ReferenceEqualsOnValueTypes.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/SelfAssignment.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/Statements/EmptyBlock.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/Statements/EmptyLockStatement.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/Statements/UseBraces.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/StaticFieldWrittenByInstance.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/StringBuilderCharInit.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Likely Bugs/UncheckedCastInEquals.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Linq/BadMultipleIteration.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Linq/MissedAllOpportunity.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Linq/MissedCastOpportunity.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Linq/MissedOfTypeOpportunity.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Linq/MissedSelectOpportunity.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Linq/MissedWhereOpportunity.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Linq/RedundantSelect.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Performance/StringBuilderInLoop.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Performance/StringConcatenationInLoop.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Performance/UseTryGetValue.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-011/ASPNetDebug.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-022/TaintedPath.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-078/CommandInjection.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-078/StoredCommandInjection.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-079/StoredXSS.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-079/XSS.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-089/SecondOrderSqlInjection.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-089/SqlInjection.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-090/LDAPInjection.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-090/StoredLDAPInjection.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-094/CodeInjection.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-099/ResourceInjection.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-112/MissingXMLValidation.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-117/LogForging.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-119/LocalUnvalidatedArithmetic.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-201/ExposureInTransmittedData.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-209/ExceptionInformationExposure.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-248/MissingASPNETGlobalErrorHandler.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-312/CleartextStorage.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-352/MissingAntiForgeryTokenValidation.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-359/ExposureOfPrivateInformation.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-384/AbandonSession.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-451/MissingXFrameOptions.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-548/ASPNetDirectoryListing.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-601/UrlRedirect.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-611/UntrustedDataInsecureXml.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-614/RequireSSL.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-643/StoredXPathInjection.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-643/XPathInjection.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-730/ReDoS.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-730/RegexInjection.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-798/HardcodedConnectionString.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-798/HardcodedCredentials.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CWE-807/ConditionalBypass.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CookieWithOverlyBroadDomain.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/CookieWithOverlyBroadPath.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/Encryption using ECB.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/HeaderCheckingDisabled.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/InadequateRSAPadding.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/InsecureRandomness.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/InsufficientKeySize.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/PersistentCookie.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Security Features/WeakEncryption.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Useless code/DefaultToString.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Useless code/FutileConditional.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Useless code/IntGetHashCode.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Useless code/RedundantToStringCall.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/Useless code/UnusedLabel.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/external/DuplicateMethod.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/external/MostlyDuplicateClass.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/external/MostlyDuplicateFile.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/external/MostlyDuplicateMethod.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
+ semmlecode-csharp-queries/external/MostlySimilarFile.ql
|
||||
@_namespace com.lgtm/csharp-queries
|
||||
# DO NOT EDIT
|
||||
# This is a stub file. The actual suite of queries to run is generated
|
||||
# automatically based on query precision and severity.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<AssemblyName>Semmle.Extraction.CIL.Driver</AssemblyName>
|
||||
<RootNamespace>Semmle.Extraction.CIL.Driver</RootNamespace>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<AssemblyName>Semmle.Extraction.CIL</AssemblyName>
|
||||
<RootNamespace>Semmle.Extraction.CIL</RootNamespace>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<AssemblyName>Semmle.Extraction.CSharp.Driver</AssemblyName>
|
||||
<RootNamespace>Semmle.Extraction.CSharp.Driver</RootNamespace>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<AssemblyName>Semmle.Extraction.CSharp.Standalone</AssemblyName>
|
||||
<RootNamespace>Semmle.Extraction.CSharp.Standalone</RootNamespace>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
|
@ -20,9 +20,9 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Build" Version="15.8.166" />
|
||||
<PackageReference Include="Microsoft.Build" Version="16.0.461" />
|
||||
<PackageReference Include="Microsoft.Win32.Primitives" Version="4.3.0" />
|
||||
<PackageReference Include="System.Net.Primitives" Version="4.3.0" />
|
||||
<PackageReference Include="System.Net.Primitives" Version="4.3.1" />
|
||||
<PackageReference Include="System.Security.Principal" Version="4.3.0" />
|
||||
<PackageReference Include="System.Threading.ThreadPool" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -242,6 +242,9 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
|||
case SyntaxKind.SwitchExpression:
|
||||
return Switch.Create(info);
|
||||
|
||||
case SyntaxKind.SuppressNullableWarningExpression:
|
||||
return PostfixUnary.Create(info.SetKind(ExprKind.SUPPRESS_NULLABLE_WARNING), ((PostfixUnaryExpressionSyntax)info.Node).Operand);
|
||||
|
||||
default:
|
||||
info.Context.ModelError(info.Node, $"Unhandled expression '{info.Node}' of kind '{info.Node.Kind()}'");
|
||||
return new Unknown(info);
|
||||
|
|
|
@ -113,6 +113,7 @@ namespace Semmle.Extraction.Kinds
|
|||
PROPERTY_PATTERN = 116,
|
||||
POSITIONAL_PATTERN = 117,
|
||||
SWITCH_CASE = 118,
|
||||
ASSIGN_COALESCE = 119
|
||||
ASSIGN_COALESCE = 119,
|
||||
SUPPRESS_NULLABLE_WARNING = 120
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<AssemblyName>Semmle.Extraction.CSharp</AssemblyName>
|
||||
<RootNamespace>Semmle.Extraction.CSharp</RootNamespace>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<AssemblyName>Semmle.Extraction</AssemblyName>
|
||||
<RootNamespace>Semmle.Extraction</RootNamespace>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
|
@ -13,7 +13,9 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis" Version="3.1.0" />
|
||||
<PackageReference Include="GitInfo" Version="2.0.18" />
|
||||
<PackageReference Include="GitInfo" Version="2.0.20"><IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
</PropertyGroup>
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<AssemblyName>Semmle.Util</AssemblyName>
|
||||
<RootNamespace>Semmle.Util</RootNamespace>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
|
|
|
@ -52,11 +52,19 @@ private class DisposeCall extends MethodCall {
|
|||
DisposeCall() { this.getTarget() instanceof DisposeMethod }
|
||||
}
|
||||
|
||||
private predicate localFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||
DataFlow::localFlowStep(nodeFrom, nodeTo) and
|
||||
not exists(AssignableDefinition def, UsingStmt us |
|
||||
nodeTo.asExpr() = def.getAReachableRead() and
|
||||
def.getTargetAccess() = us.getAVariableDeclExpr().getAccess()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate reachesDisposeCall(DisposeCall disposeCall, DataFlow::Node node) {
|
||||
DataFlow::localFlowStep(node, DataFlow::exprNode(disposeCall.getQualifier()))
|
||||
localFlowStep(node, DataFlow::exprNode(disposeCall.getQualifier()))
|
||||
or
|
||||
exists(DataFlow::Node mid | reachesDisposeCall(disposeCall, mid) |
|
||||
DataFlow::localFlowStep(node, mid)
|
||||
localFlowStep(node, mid)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -89,8 +89,8 @@ abstract private class GeneratedType extends ValueOrRefType, GeneratedElement {
|
|||
else
|
||||
result = this.stubComment() + this.stubAttributes() + this.stubAbstractModifier() +
|
||||
this.stubStaticModifier() + this.stubAccessibilityModifier() + this.stubKeyword() + " " +
|
||||
this.getUndecoratedName() + stubGenericArguments(this) + stubBaseTypesString() + "\n{\n" +
|
||||
stubMembers() + "}\n\n"
|
||||
this.getUndecoratedName() + stubGenericArguments(this) + stubBaseTypesString() +
|
||||
stubTypeParametersConstraints(this) + "\n{\n" + stubMembers() + "}\n\n"
|
||||
}
|
||||
|
||||
private ValueOrRefType getAnInterestingBaseType() {
|
||||
|
@ -270,11 +270,16 @@ private string stubAccessibility(Member m) {
|
|||
}
|
||||
|
||||
private string stubModifiers(Member m) {
|
||||
result = stubAccessibility(m) + stubStatic(m) + stubOverride(m)
|
||||
result = stubAccessibility(m) + stubStaticOrConst(m) + stubOverride(m)
|
||||
}
|
||||
|
||||
private string stubStatic(Member m) {
|
||||
if m.(Modifiable).isStatic() then result = "static " else result = ""
|
||||
private string stubStaticOrConst(Member m) {
|
||||
if m.(Modifiable).isStatic()
|
||||
then result = "static "
|
||||
else
|
||||
if m.(Modifiable).isConst()
|
||||
then result = "const "
|
||||
else result = ""
|
||||
}
|
||||
|
||||
private string stubOverride(Member m) {
|
||||
|
@ -386,18 +391,135 @@ private string stubGenericMethodParams(Method m) {
|
|||
else result = ""
|
||||
}
|
||||
|
||||
private string stubConstraints(TypeParameterConstraints tpc) {
|
||||
tpc.hasConstructorConstraint() and result = "new()"
|
||||
or
|
||||
tpc.hasUnmanagedTypeConstraint() and result = "unmanaged"
|
||||
or
|
||||
tpc.hasValueTypeConstraint() and result = "struct"
|
||||
or
|
||||
tpc.hasRefTypeConstraint() and result = "class"
|
||||
or
|
||||
result = tpc.getATypeParameterConstraint().getName()
|
||||
or
|
||||
result = stubClassName(tpc.getAnInterfaceConstraint())
|
||||
or
|
||||
result = stubClassName(tpc.getClassConstraint())
|
||||
}
|
||||
|
||||
private string stubTypeParameterConstraints(TypeParameter tp) {
|
||||
exists(TypeParameterConstraints tpc | tpc = tp.getConstraints() |
|
||||
result = " where " + tp.getName() + ": " +
|
||||
strictconcat(string s | s = stubConstraints(tpc) | s, ", ")
|
||||
)
|
||||
}
|
||||
|
||||
private string stubTypeParametersConstraints(Declaration d) {
|
||||
if d instanceof UnboundGeneric
|
||||
then
|
||||
result = concat(TypeParameter tp |
|
||||
tp = d.(UnboundGeneric).getATypeParameter()
|
||||
|
|
||||
stubTypeParameterConstraints(tp), " "
|
||||
)
|
||||
else result = ""
|
||||
}
|
||||
|
||||
private string stubImplementation(Virtualizable c) {
|
||||
if c.isAbstract() or c.getDeclaringType() instanceof Interface
|
||||
then result = ""
|
||||
else result = " => throw null"
|
||||
}
|
||||
|
||||
private predicate isKeyword(string s) {
|
||||
s = "abstract" or
|
||||
s = "as" or
|
||||
s = "base" or
|
||||
s = "bool" or
|
||||
s = "break" or
|
||||
s = "byte" or
|
||||
s = "case" or
|
||||
s = "catch" or
|
||||
s = "char" or
|
||||
s = "checked" or
|
||||
s = "class" or
|
||||
s = "const" or
|
||||
s = "continue" or
|
||||
s = "decimal" or
|
||||
s = "default" or
|
||||
s = "delegate" or
|
||||
s = "do" or
|
||||
s = "double" or
|
||||
s = "else" or
|
||||
s = "enum" or
|
||||
s = "event" or
|
||||
s = "explicit" or
|
||||
s = "extern" or
|
||||
s = "false" or
|
||||
s = "finally" or
|
||||
s = "fixed" or
|
||||
s = "float" or
|
||||
s = "for" or
|
||||
s = "foreach" or
|
||||
s = "goto" or
|
||||
s = "if" or
|
||||
s = "implicit" or
|
||||
s = "in" or
|
||||
s = "int" or
|
||||
s = "interface" or
|
||||
s = "internal" or
|
||||
s = "is" or
|
||||
s = "lock" or
|
||||
s = "long" or
|
||||
s = "namespace" or
|
||||
s = "new" or
|
||||
s = "null" or
|
||||
s = "object" or
|
||||
s = "operator" or
|
||||
s = "out" or
|
||||
s = "override" or
|
||||
s = "params" or
|
||||
s = "private" or
|
||||
s = "protected" or
|
||||
s = "public" or
|
||||
s = "readonly" or
|
||||
s = "ref" or
|
||||
s = "return" or
|
||||
s = "sbyte" or
|
||||
s = "sealed" or
|
||||
s = "short" or
|
||||
s = "sizeof" or
|
||||
s = "stackalloc" or
|
||||
s = "static" or
|
||||
s = "string" or
|
||||
s = "struct" or
|
||||
s = "switch" or
|
||||
s = "this" or
|
||||
s = "throw" or
|
||||
s = "true" or
|
||||
s = "try" or
|
||||
s = "typeof" or
|
||||
s = "uint" or
|
||||
s = "ulong" or
|
||||
s = "unchecked" or
|
||||
s = "unsafe" or
|
||||
s = "ushort" or
|
||||
s = "using" or
|
||||
s = "virtual" or
|
||||
s = "void" or
|
||||
s = "volatile" or
|
||||
s = "while"
|
||||
}
|
||||
|
||||
bindingset[s]
|
||||
private string escapeIfKeyword(string s) { if isKeyword(s) then result = "@" + s else result = s }
|
||||
|
||||
private string stubParameters(Parameterizable p) {
|
||||
result = concat(int i, Parameter param |
|
||||
param = p.getParameter(i) and not param.getType() instanceof ArglistType
|
||||
|
|
||||
stubParameterModifiers(param) + stubClassName(param.getType()) + " " + param.getName() +
|
||||
stubDefaultValue(param), ", "
|
||||
stubParameterModifiers(param) + stubClassName(param.getType()) + " " +
|
||||
escapeIfKeyword(param.getName()) + stubDefaultValue(param), ", "
|
||||
order by
|
||||
i
|
||||
)
|
||||
|
@ -437,7 +559,7 @@ private string stubMember(Member m) {
|
|||
exists(Method c | m = c and not m.getDeclaringType() instanceof Enum |
|
||||
result = " " + stubModifiers(c) + stubClassName(c.getReturnType()) + " " +
|
||||
stubExplicitImplementation(c) + c.getName() + stubGenericMethodParams(c) + "(" +
|
||||
stubParameters(c) + ")" + stubImplementation(c) + ";\n"
|
||||
stubParameters(c) + ")" + stubTypeParametersConstraints(c) + stubImplementation(c) + ";\n"
|
||||
)
|
||||
or
|
||||
exists(Operator op |
|
||||
|
@ -469,8 +591,10 @@ private string stubMember(Member m) {
|
|||
"] { " + stubGetter(i) + stubSetter(i) + "}\n"
|
||||
)
|
||||
or
|
||||
exists(Field f | f = m and not f instanceof EnumConstant |
|
||||
result = " " + stubModifiers(m) + stubClassName(f.getType()) + " " + f.getName() + ";\n"
|
||||
exists(Field f, string impl | f = m and not f instanceof EnumConstant |
|
||||
(if f.isConst() then impl = " = throw null" else impl = "") and
|
||||
result = " " + stubModifiers(m) + stubClassName(f.getType()) + " " + f.getName() + impl +
|
||||
";\n"
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -27,10 +27,6 @@ class Element extends DotNet::Element, @element {
|
|||
/** Gets a location of this element, including sources and assemblies. */
|
||||
override Location getALocation() { none() }
|
||||
|
||||
override File getFile() { result = getLocation().getFile() }
|
||||
|
||||
override predicate fromSource() { this.getFile().fromSource() }
|
||||
|
||||
/** Holds if this element is from an assembly. */
|
||||
predicate fromLibrary() { this.getFile().fromLibrary() }
|
||||
|
||||
|
|
|
@ -673,6 +673,8 @@ module Internal {
|
|||
or
|
||||
e.(Call).getTarget().getSourceDeclaration() instanceof NonNullCallable and
|
||||
not e.(QualifiableExpr).isConditional()
|
||||
or
|
||||
e instanceof SuppressNullableWarningExpr
|
||||
}
|
||||
|
||||
/** Holds if expression `e2` is a non-`null` value whenever `e1` is. */
|
||||
|
|
|
@ -370,6 +370,12 @@ private predicate inBooleanContext(Expr e, boolean isBooleanCompletionForParent)
|
|||
inBooleanContext(nce, _) and
|
||||
isBooleanCompletionForParent = true
|
||||
)
|
||||
or
|
||||
exists(SwitchExpr se |
|
||||
inBooleanContext(se, _) and
|
||||
e = se.getACase().getBody() and
|
||||
isBooleanCompletionForParent = true
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -406,6 +412,12 @@ private predicate inNullnessContext(Expr e, boolean isNullnessCompletionForParen
|
|||
e = nce.getRightOperand() and
|
||||
isNullnessCompletionForParent = true
|
||||
)
|
||||
or
|
||||
exists(SwitchExpr se |
|
||||
inNullnessContext(se, _) and
|
||||
e = se.getACase().getBody() and
|
||||
isNullnessCompletionForParent = true
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -83,6 +83,10 @@ module LocalFlow {
|
|||
scope = e2 and
|
||||
isSuccessor = true
|
||||
or
|
||||
e1 = e2.(SuppressNullableWarningExpr).getExpr() and
|
||||
scope = e2 and
|
||||
isSuccessor = true
|
||||
or
|
||||
e2 = any(ConditionalExpr ce |
|
||||
e1 = ce.getThen() or
|
||||
e1 = ce.getElse()
|
||||
|
|
|
@ -511,6 +511,8 @@ class SwitchExpr extends Expr, Switch, @switch_expr {
|
|||
override Expr getExpr() { result = this.getChild(-1) }
|
||||
|
||||
override SwitchCaseExpr getCase(int n) { result = this.getChild(n) }
|
||||
|
||||
override SwitchCaseExpr getACase() { result = this.getCase(_) }
|
||||
}
|
||||
|
||||
/** A `case` expression or statement. */
|
||||
|
@ -990,3 +992,20 @@ class IndexExpr extends Expr, @index_expr {
|
|||
|
||||
override string toString() { result = "^..." }
|
||||
}
|
||||
|
||||
/**
|
||||
* A nullable warning suppression expression, for example `x!` in
|
||||
* ```
|
||||
* string GetName()
|
||||
* {
|
||||
* string? x = ...;
|
||||
* return x!;
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class SuppressNullableWarningExpr extends Expr, @suppress_nullable_warning_expr {
|
||||
/** Gets the expression, for example `x` in `x!`. */
|
||||
Expr getExpr() { result.getParent() = this }
|
||||
|
||||
override string toString() { result = "...!" }
|
||||
}
|
||||
|
|
|
@ -22,10 +22,10 @@ class Element extends @dotnet_element {
|
|||
Location getALocation() { none() }
|
||||
|
||||
/** Gets the file containing this element. */
|
||||
File getFile() { result = getLocation().getFile() }
|
||||
final File getFile() { result = this.getLocation().getFile() }
|
||||
|
||||
/** Holds if this element is from source code. */
|
||||
predicate fromSource() { none() }
|
||||
predicate fromSource() { this.getFile().fromSource() }
|
||||
|
||||
/**
|
||||
* Gets the "language" of this program element, as defined by the extension of the filename.
|
||||
|
|
|
@ -987,6 +987,7 @@ case @expr.kind of
|
|||
| 117 = @positional_pattern_expr
|
||||
| 118 = @switch_case_expr
|
||||
| 119 = @assign_coalesce_expr
|
||||
| 120 = @suppress_nullable_warning_expr
|
||||
;
|
||||
|
||||
@switch = @switch_stmt | @switch_expr;
|
||||
|
|
|
@ -836,6 +836,10 @@
|
|||
<v>0</v>
|
||||
</e>
|
||||
<e>
|
||||
<k>@suppress_nullable_warning_expr</k>
|
||||
<v>500</v>
|
||||
</e>
|
||||
<e>
|
||||
<k>@xmldtd</k>
|
||||
<v>2</v>
|
||||
</e>
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
| System.Guid System.Guid.ParseExact(System.String,System.String): 11: throw, 0: ldarg.0 [push: 1, pop: 0]; 1: brtrue.s 5: [push: 0, pop: 1]; 2: ldstr "input" [push: 1, pop: 0]; 3: newobj System.ArgumentNullException..ctor [push: 1, pop: 1]; 4: throw [push: 0, pop: 1]; 5: ldarg.0 [push: 1, pop: 0]; 6: call System.String.op_Implicit [push: 1, pop: 1]; 7: ldarg.1 [push: 1, pop: 0]; 8: brtrue.s 12: [push: 0, pop: 1]; 9: ldstr "format" [push: 1, pop: 0]; 10: newobj System.ArgumentNullException..ctor [push: 1, pop: 1]; 11: throw [push: 0, pop: 1] | Throw has invalid stack size |
|
||||
| System.Threading.CancellationTokenRegistration System.Threading.CancellationToken.Register(System.Action): 8: throw, 0: ldarg.0 [push: 1, pop: 0]; 1: ldsfld s_actionToActionObjShunt [push: 1, pop: 0]; 2: ldarg.1 [push: 1, pop: 0]; 3: dup [push: 2, pop: 1]; 4: brtrue.s 9: [push: 0, pop: 1]; 5: pop [push: 0, pop: 1]; 6: ldstr "callback" [push: 1, pop: 0]; 7: newobj System.ArgumentNullException..ctor [push: 1, pop: 1]; 8: throw [push: 0, pop: 1] | Throw has invalid stack size |
|
||||
| System.Threading.CancellationTokenRegistration System.Threading.CancellationToken.Register(System.Action,System.Boolean): 8: throw, 0: ldarg.0 [push: 1, pop: 0]; 1: ldsfld s_actionToActionObjShunt [push: 1, pop: 0]; 2: ldarg.1 [push: 1, pop: 0]; 3: dup [push: 2, pop: 1]; 4: brtrue.s 9: [push: 0, pop: 1]; 5: pop [push: 0, pop: 1]; 6: ldstr "callback" [push: 1, pop: 0]; 7: newobj System.ArgumentNullException..ctor [push: 1, pop: 1]; 8: throw [push: 0, pop: 1] | Throw has invalid stack size |
|
||||
| System.Void System.Guid..ctor(System.Byte[]): 7: throw, 0: ldarg.0 [push: 1, pop: 0]; 1: ldarg.1 [push: 1, pop: 0]; 2: dup [push: 2, pop: 1]; 3: brtrue.s 8: [push: 0, pop: 1]; 4: pop [push: 0, pop: 1]; 5: ldstr "b" [push: 1, pop: 0]; 6: newobj System.ArgumentNullException..ctor [push: 1, pop: 1]; 7: throw [push: 0, pop: 1] | Throw has invalid stack size |
|
||||
| System.Void System.TermInfo.Database..ctor(System.String,System.Byte[]): 33: throw, 0: ldarg.0 [push: 1, pop: 0]; 1: call System.Object..ctor [push: 0, pop: 1]; 2: ldarg.0 [push: 1, pop: 0]; 3: ldarg.1 [push: 1, pop: 0]; 4: stfld _term [push: 0, pop: 2]; 5: ldarg.0 [push: 1, pop: 0]; 6: ldarg.2 [push: 1, pop: 0]; 7: stfld _data [push: 0, pop: 2]; 8: ldarg.2 [push: 1, pop: 0]; 9: ldc.i4.0 [push: 1, pop: 0]; 10: call System.TermInfo.Database.ReadInt16 [push: 1, pop: 2]; 11: stloc.0 L0 [push: 0, pop: 1]; 12: ldarg.0 [push: 1, pop: 0]; 13: ldloc.0 [push: 1, pop: 0]; 14: ldc.i4 72224 [push: 1, pop: 0]; 15: beq.s 36: [push: 0, pop: 2]; 16: ldloc.0 [push: 1, pop: 0]; 17: ldc.i4 138784 [push: 1, pop: 0]; 18: beq.s 34: [push: 0, pop: 2]; 19: call System.SR.get_IO_TermInfoInvalidMagicNumber [push: 1, pop: 0]; 20: ldc.i4.1 [push: 1, pop: 0]; 21: newarr System.String [push: 1, pop: 1]; 22: dup [push: 2, pop: 1]; 23: ldc.i4.0 [push: 1, pop: 0]; 24: ldstr "O" [push: 1, pop: 0]; 25: ldloc.0 [push: 1, pop: 0]; 26: ldc.i4.8 [push: 1, pop: 0]; 27: call System.Convert.ToString [push: 1, pop: 2]; 28: call System.String.Concat [push: 1, pop: 2]; 29: stelem.ref [push: 0, pop: 3]; 30: call System.String.Concat [push: 1, pop: 1]; 31: call System.SR.Format [push: 1, pop: 2]; 32: newobj System.InvalidOperationException..ctor [push: 1, pop: 1]; 33: throw [push: 0, pop: 1] | Throw has invalid stack size |
|
|
@ -0,0 +1,5 @@
|
|||
| System.Guid System.Guid.ParseExact(System.String,System.String): 11: throw, 0: ldarg.0 [push: 1, pop: 0]; 1: brtrue.s 5: [push: 0, pop: 1]; 2: ldstr "input" [push: 1, pop: 0]; 3: newobj System.ArgumentNullException..ctor [push: 1, pop: 1]; 4: throw [push: 0, pop: 1]; 5: ldarg.0 [push: 1, pop: 0]; 6: call System.String.op_Implicit [push: 1, pop: 1]; 7: ldarg.1 [push: 1, pop: 0]; 8: brtrue.s 12: [push: 0, pop: 1]; 9: ldstr "format" [push: 1, pop: 0]; 10: newobj System.ArgumentNullException..ctor [push: 1, pop: 1]; 11: throw [push: 0, pop: 1] | Throw has invalid stack size |
|
||||
| System.Threading.CancellationTokenRegistration System.Threading.CancellationToken.Register(System.Action): 8: throw, 0: ldarg.0 [push: 1, pop: 0]; 1: ldsfld s_actionToActionObjShunt [push: 1, pop: 0]; 2: ldarg.1 [push: 1, pop: 0]; 3: dup [push: 2, pop: 1]; 4: brtrue.s 9: [push: 0, pop: 1]; 5: pop [push: 0, pop: 1]; 6: ldstr "callback" [push: 1, pop: 0]; 7: newobj System.ArgumentNullException..ctor [push: 1, pop: 1]; 8: throw [push: 0, pop: 1] | Throw has invalid stack size |
|
||||
| System.Threading.CancellationTokenRegistration System.Threading.CancellationToken.Register(System.Action,System.Boolean): 8: throw, 0: ldarg.0 [push: 1, pop: 0]; 1: ldsfld s_actionToActionObjShunt [push: 1, pop: 0]; 2: ldarg.1 [push: 1, pop: 0]; 3: dup [push: 2, pop: 1]; 4: brtrue.s 9: [push: 0, pop: 1]; 5: pop [push: 0, pop: 1]; 6: ldstr "callback" [push: 1, pop: 0]; 7: newobj System.ArgumentNullException..ctor [push: 1, pop: 1]; 8: throw [push: 0, pop: 1] | Throw has invalid stack size |
|
||||
| System.Void System.Guid..ctor(System.Byte[]): 7: throw, 0: ldarg.0 [push: 1, pop: 0]; 1: ldarg.1 [push: 1, pop: 0]; 2: dup [push: 2, pop: 1]; 3: brtrue.s 8: [push: 0, pop: 1]; 4: pop [push: 0, pop: 1]; 5: ldstr "b" [push: 1, pop: 0]; 6: newobj System.ArgumentNullException..ctor [push: 1, pop: 1]; 7: throw [push: 0, pop: 1] | Throw has invalid stack size |
|
||||
| System.Void System.TermInfo.Database..ctor(System.String,System.Byte[]): 33: throw, 0: ldarg.0 [push: 1, pop: 0]; 1: call System.Object..ctor [push: 0, pop: 1]; 2: ldarg.0 [push: 1, pop: 0]; 3: ldarg.1 [push: 1, pop: 0]; 4: stfld _term [push: 0, pop: 2]; 5: ldarg.0 [push: 1, pop: 0]; 6: ldarg.2 [push: 1, pop: 0]; 7: stfld _data [push: 0, pop: 2]; 8: ldarg.2 [push: 1, pop: 0]; 9: ldc.i4.0 [push: 1, pop: 0]; 10: call System.TermInfo.Database.ReadInt16 [push: 1, pop: 2]; 11: stloc.0 L0 [push: 0, pop: 1]; 12: ldarg.0 [push: 1, pop: 0]; 13: ldloc.0 [push: 1, pop: 0]; 14: ldc.i4 72224 [push: 1, pop: 0]; 15: beq.s 36: [push: 0, pop: 2]; 16: ldloc.0 [push: 1, pop: 0]; 17: ldc.i4 138784 [push: 1, pop: 0]; 18: beq.s 34: [push: 0, pop: 2]; 19: call System.SR.get_IO_TermInfoInvalidMagicNumber [push: 1, pop: 0]; 20: ldc.i4.1 [push: 1, pop: 0]; 21: newarr System.String [push: 1, pop: 1]; 22: dup [push: 2, pop: 1]; 23: ldc.i4.0 [push: 1, pop: 0]; 24: ldstr "O" [push: 1, pop: 0]; 25: ldloc.0 [push: 1, pop: 0]; 26: ldc.i4.8 [push: 1, pop: 0]; 27: call System.Convert.ToString [push: 1, pop: 2]; 28: call System.String.Concat [push: 1, pop: 2]; 29: stelem.ref [push: 0, pop: 3]; 30: call System.String.Concat [push: 1, pop: 1]; 31: call System.SR.Format [push: 1, pop: 2]; 32: newobj System.InvalidOperationException..ctor [push: 1, pop: 1]; 33: throw [push: 0, pop: 1] | Throw has invalid stack size |
|
|
@ -16,8 +16,10 @@ alwaysNonNull
|
|||
| System.ArgumentNullException System.ThrowHelper.GetArgumentNullException(System.ExceptionArgument) |
|
||||
| System.ArgumentOutOfRangeException System.ThrowHelper.GetArgumentOutOfRangeException(System.ExceptionArgument,System.ExceptionResource) |
|
||||
| System.ArgumentOutOfRangeException System.ThrowHelper.GetArgumentOutOfRangeException(System.ExceptionArgument,System.Int32,System.ExceptionResource) |
|
||||
| System.Collections.Generic.KeyNotFoundException System.ThrowHelper.GetKeyNotFoundException(System.Object) |
|
||||
| System.Exception System.ThrowHelper.GetArraySegmentCtorValidationFailedException(System.Array,System.Int32,System.Int32) |
|
||||
| System.InvalidOperationException System.ThrowHelper.GetInvalidOperationException(System.ExceptionResource) |
|
||||
| System.InvalidOperationException System.ThrowHelper.GetInvalidOperationException_EnumCurrent(System.Int32) |
|
||||
| System.Object Dataflow.NonNullMethods.ReturnsNonNull2() |
|
||||
| System.Object Dataflow.NonNullMethods.ReturnsNonNull() |
|
||||
| System.Object Dataflow.NonNullMethods.ReturnsNonNullIndirect() |
|
||||
|
@ -37,15 +39,15 @@ alwaysThrows
|
|||
| System.Object Dataflow.ThrowingMethods.get_ThrowProperty() | System.Exception | 0: newobj System.Exception..ctor, 1: throw |
|
||||
| System.Object Dataflow.ThrowingMethods.get_VirtualThrowProperty() | System.Exception | 0: newobj System.Exception..ctor, 1: throw |
|
||||
| System.Object System.ValueTuple.get_Item(System.Int32) | System.IndexOutOfRangeException | 0: newobj System.IndexOutOfRangeException..ctor, 1: throw |
|
||||
| System.Void System.ThrowHelper.ThrowAddingDuplicateWithKeyArgumentException(System.Object) | System.ArgumentException | 0: ldarg.0, 1: call System.ThrowHelper.GetAddingDuplicateWithKeyArgumentException, 2: throw |
|
||||
| System.Void System.ThrowHelper.ThrowAddingDuplicateWithKeyArgumentException`1(!0) | System.ArgumentException | 0: ldarg.0, 1: box, 2: call System.ThrowHelper.GetAddingDuplicateWithKeyArgumentException, 3: throw |
|
||||
| System.Void System.ThrowHelper.ThrowAggregateException(System.Collections.Generic.List<System.Exception>) | System.AggregateException | 0: ldarg.0, 1: newobj System.AggregateException..ctor, 2: throw |
|
||||
| System.Void System.ThrowHelper.ThrowArgumentException(System.ExceptionResource) | System.ArgumentException | 0: ldarg.0, 1: call System.ThrowHelper.GetArgumentException, 2: throw |
|
||||
| System.Void System.ThrowHelper.ThrowArgumentException(System.ExceptionResource,System.ExceptionArgument) | System.ArgumentException | 0: ldarg.0, 1: ldarg.1, 2: call System.ThrowHelper.GetArgumentException, 3: throw |
|
||||
| System.Void System.ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType() | System.ArgumentException | 0: ldc.i4.s 31, 1: call System.ThrowHelper.GetArgumentException, 2: throw |
|
||||
| System.Void System.ThrowHelper.ThrowArgumentException_DestinationTooShort() | System.ArgumentException | 0: call System.SR.get_Argument_DestinationTooShort, 1: newobj System.ArgumentException..ctor, 2: throw |
|
||||
| System.Void System.ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch() | System.ArgumentException | 0: call System.SR.get_Argument_OverlapAlignmentMismatch, 1: newobj System.ArgumentException..ctor, 2: throw |
|
||||
| System.Void System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument) | System.ArgumentNullException | 0: ldarg.0, 1: call System.ThrowHelper.GetArgumentNullException, 2: throw |
|
||||
| System.Void System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument,System.ExceptionResource) | System.ArgumentNullException | 0: ldarg.0, 1: call System.ThrowHelper.GetArgumentName, 2: ldarg.1, 3: call System.ThrowHelper.GetResourceString, 4: newobj System.ArgumentNullException..ctor, 5: throw |
|
||||
| System.Void System.ThrowHelper.ThrowArgumentNullException(System.ExceptionResource) | System.ArgumentNullException | 0: ldarg.0, 1: call System.ThrowHelper.GetResourceString, 2: newobj System.ArgumentNullException..ctor, 3: throw |
|
||||
| System.Void System.ThrowHelper.ThrowArgumentOutOfRangeException() | System.ArgumentOutOfRangeException | 0: newobj System.ArgumentOutOfRangeException..ctor, 1: throw |
|
||||
| System.Void System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument) | System.ArgumentOutOfRangeException | 0: ldarg.0, 1: call System.ThrowHelper.GetArgumentName, 2: newobj System.ArgumentOutOfRangeException..ctor, 3: throw |
|
||||
| System.Void System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument,System.ExceptionResource) | System.ArgumentOutOfRangeException | 0: ldarg.0, 1: ldarg.1, 2: call System.ThrowHelper.GetArgumentOutOfRangeException, 3: throw |
|
||||
|
@ -58,21 +60,22 @@ alwaysThrows
|
|||
| System.Void System.ThrowHelper.ThrowIndexOutOfRangeException() | System.IndexOutOfRangeException | 0: newobj System.IndexOutOfRangeException..ctor, 1: throw |
|
||||
| System.Void System.ThrowHelper.ThrowInvalidOperationException(System.ExceptionResource) | System.InvalidOperationException | 0: ldarg.0, 1: call System.ThrowHelper.GetInvalidOperationException, 2: throw |
|
||||
| System.Void System.ThrowHelper.ThrowInvalidOperationException(System.ExceptionResource,System.Exception) | System.InvalidOperationException | 0: ldarg.0, 1: call System.ThrowHelper.GetResourceString, 2: ldarg.1, 3: newobj System.InvalidOperationException..ctor, 4: throw |
|
||||
| System.Void System.ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported() | System.InvalidOperationException | 0: ldc.i4.s 31, 1: call System.ThrowHelper.GetInvalidOperationException, 2: throw |
|
||||
| System.Void System.ThrowHelper.ThrowInvalidOperationException_EnumCurrent(System.Int32) | System.InvalidOperationException | 0: ldarg.0, 1: call System.ThrowHelper.GetInvalidOperationException_EnumCurrent, 2: throw |
|
||||
| System.Void System.ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumEnded() | System.InvalidOperationException | 0: ldc.i4.s 31, 1: call System.ThrowHelper.GetInvalidOperationException, 2: throw |
|
||||
| System.Void System.ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion() | System.InvalidOperationException | 0: ldc.i4.s 31, 1: call System.ThrowHelper.GetInvalidOperationException, 2: throw |
|
||||
| System.Void System.ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumNotStarted() | System.InvalidOperationException | 0: ldc.i4.s 31, 1: call System.ThrowHelper.GetInvalidOperationException, 2: throw |
|
||||
| System.Void System.ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen() | System.InvalidOperationException | 0: ldc.i4.s 31, 1: call System.ThrowHelper.GetInvalidOperationException, 2: throw |
|
||||
| System.Void System.ThrowHelper.ThrowInvalidOperationException_InvalidOperation_NoValue() | System.InvalidOperationException | 0: ldc.i4.s 31, 1: call System.ThrowHelper.GetInvalidOperationException, 2: throw |
|
||||
| System.Void System.ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(System.Type) | System.ArgumentException | 0: call System.SR.get_Argument_InvalidTypeWithPointersNotSupported, 1: ldarg.0, 2: call System.SR.Format, 3: newobj System.ArgumentException..ctor, 4: throw |
|
||||
| System.Void System.ThrowHelper.ThrowKeyNotFoundException() | System.Collections.Generic.KeyNotFoundException | 0: newobj System.Collections.Generic.KeyNotFoundException..ctor, 1: throw |
|
||||
| System.Void System.ThrowHelper.ThrowKeyNotFoundException`1(!0) | System.Collections.Generic.KeyNotFoundException | 0: ldarg.0, 1: box, 2: call System.ThrowHelper.GetKeyNotFoundException, 3: throw |
|
||||
| System.Void System.ThrowHelper.ThrowLengthArgumentOutOfRange_ArgumentOutOfRange_NeedNonNegNum() | System.ArgumentOutOfRangeException | 0: ldc.i4.s 31, 1: ldc.i4.4, 2: call System.ThrowHelper.GetArgumentOutOfRangeException, 3: throw |
|
||||
| System.Void System.ThrowHelper.ThrowNotSupportedException() | System.NotSupportedException | 0: newobj System.NotSupportedException..ctor, 1: throw |
|
||||
| System.Void System.ThrowHelper.ThrowNotSupportedException(System.ExceptionResource) | System.NotSupportedException | 0: ldarg.0, 1: call System.ThrowHelper.GetResourceString, 2: newobj System.NotSupportedException..ctor, 3: throw |
|
||||
| System.Void System.ThrowHelper.ThrowObjectDisposedException(System.ExceptionResource) | System.ObjectDisposedException | 0: ldnull, 1: ldarg.0, 2: call System.ThrowHelper.GetResourceString, 3: newobj System.ObjectDisposedException..ctor, 4: throw |
|
||||
| System.Void System.ThrowHelper.ThrowObjectDisposedException(System.String,System.ExceptionResource) | System.ObjectDisposedException | 0: ldarg.0, 1: ldarg.1, 2: call System.ThrowHelper.GetResourceString, 3: newobj System.ObjectDisposedException..ctor, 4: throw |
|
||||
| System.Void System.ThrowHelper.ThrowOutOfMemoryException() | System.OutOfMemoryException | 0: newobj System.OutOfMemoryException..ctor, 1: throw |
|
||||
| System.Void System.ThrowHelper.ThrowRankException(System.ExceptionResource) | System.RankException | 0: ldarg.0, 1: call System.ThrowHelper.GetResourceString, 2: newobj System.RankException..ctor, 3: throw |
|
||||
| System.Void System.ThrowHelper.ThrowSecurityException(System.ExceptionResource) | System.Security.SecurityException | 0: ldarg.0, 1: call System.ThrowHelper.GetResourceString, 2: newobj System.Security.SecurityException..ctor, 3: throw |
|
||||
| System.Void System.ThrowHelper.ThrowSerializationException(System.ExceptionResource) | System.Runtime.Serialization.SerializationException | 0: ldarg.0, 1: call System.ThrowHelper.GetResourceString, 2: newobj System.Runtime.Serialization.SerializationException..ctor, 3: throw |
|
||||
| System.Void System.ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index() | System.ArgumentOutOfRangeException | 0: ldc.i4.s 31, 1: ldc.i4.s 31, 2: call System.ThrowHelper.GetArgumentOutOfRangeException, 3: throw |
|
||||
| System.Void System.ThrowHelper.ThrowUnauthorizedAccessException(System.ExceptionResource) | System.UnauthorizedAccessException | 0: ldarg.0, 1: call System.ThrowHelper.GetResourceString, 2: newobj System.UnauthorizedAccessException..ctor, 3: throw |
|
||||
| System.Void System.ThrowHelper.ThrowWrongKeyTypeArgumentException(System.Object,System.Type) | System.ArgumentException | 0: ldarg.0, 1: ldarg.1, 2: call System.ThrowHelper.GetWrongKeyTypeArgumentException, 3: throw |
|
||||
| System.Void System.ThrowHelper.ThrowWrongValueTypeArgumentException(System.Object,System.Type) | System.ArgumentException | 0: ldarg.0, 1: ldarg.1, 2: call System.ThrowHelper.GetWrongValueTypeArgumentException, 3: throw |
|
||||
| System.Void System.ThrowHelper.ThrowWrongKeyTypeArgumentException`1(!0,System.Type) | System.ArgumentException | 0: ldarg.0, 1: box, 2: ldarg.1, 3: call System.ThrowHelper.GetWrongKeyTypeArgumentException, 4: throw |
|
||||
| System.Void System.ThrowHelper.ThrowWrongValueTypeArgumentException`1(!0,System.Type) | System.ArgumentException | 0: ldarg.0, 1: box, 2: ldarg.1, 3: call System.ThrowHelper.GetWrongValueTypeArgumentException, 4: throw |
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
| dataflow.cs:18:18:18:26 | "tainted" | dataflow.cs:18:18:18:37 | call to method ToString |
|
||||
| dataflow.cs:19:27:19:28 | 12 | dataflow.cs:19:18:19:29 | call to method Abs |
|
||||
| dataflow.cs:20:27:20:27 | 2 | dataflow.cs:20:18:20:31 | call to method Max |
|
||||
| dataflow.cs:20:30:20:30 | 3 | dataflow.cs:20:18:20:31 | call to method Max |
|
||||
| dataflow.cs:21:29:21:31 | 0.5 | dataflow.cs:21:18:21:32 | call to method Round |
|
||||
| dataflow.cs:22:45:22:53 | "tainted" | dataflow.cs:22:18:22:54 | call to method GetFullPath |
|
||||
| dataflow.cs:29:44:29:46 | 1 | dataflow.cs:29:18:29:52 | call to method IEEERemainder |
|
||||
| dataflow.cs:29:49:29:51 | 2 | dataflow.cs:29:18:29:52 | call to method IEEERemainder |
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
| dataflow.cs:11:18:11:22 | "123" | dataflow.cs:11:18:11:37 | call to method CompareTo |
|
||||
| dataflow.cs:11:34:11:36 | "b" | dataflow.cs:11:18:11:37 | call to method CompareTo |
|
||||
| dataflow.cs:18:18:18:26 | "tainted" | dataflow.cs:18:18:18:37 | call to method ToString |
|
||||
| dataflow.cs:19:27:19:28 | 12 | dataflow.cs:19:18:19:29 | call to method Abs |
|
||||
| dataflow.cs:20:27:20:27 | 2 | dataflow.cs:20:18:20:31 | call to method Max |
|
||||
| dataflow.cs:20:30:20:30 | 3 | dataflow.cs:20:18:20:31 | call to method Max |
|
||||
| dataflow.cs:21:29:21:31 | 0.5 | dataflow.cs:21:18:21:32 | call to method Round |
|
||||
| dataflow.cs:22:45:22:53 | "tainted" | dataflow.cs:22:18:22:54 | call to method GetFullPath |
|
||||
| dataflow.cs:26:37:26:37 | 1 | dataflow.cs:26:18:26:56 | call to method DivRem |
|
||||
| dataflow.cs:26:40:26:40 | 2 | dataflow.cs:26:18:26:56 | call to method DivRem |
|
||||
|
|
|
@ -3,19 +3,37 @@
|
|||
| System.IO.SyncTextReader._in |
|
||||
| System.IO.SyncTextWriter._out |
|
||||
| System.IO.UnmanagedMemoryStreamWrapper._unmanagedStream |
|
||||
| System.Net.Http.DecompressionHandler.DecompressedContent._originalContent |
|
||||
| System.Net.Http.DecompressionHandler._innerHandler |
|
||||
| System.Net.Http.DelegatingHandler._innerHandler |
|
||||
| System.Net.Http.DelegatingStream._innerStream |
|
||||
| System.Net.Http.HttpAuthenticatedConnectionHandler._poolManager |
|
||||
| System.Net.Http.HttpClient._pendingRequestsCts |
|
||||
| System.Net.Http.HttpConnection.HttpConnectionResponseContent._stream |
|
||||
| System.Net.Http.HttpConnection._stream |
|
||||
| System.Net.Http.HttpConnectionHandler._poolManager |
|
||||
| System.Net.Http.HttpConnectionPool.CachedConnection._connection |
|
||||
| System.Net.Http.HttpConnectionPool.ConnectionWaiter._cancellationTokenRegistration |
|
||||
| System.Net.Http.HttpConnectionPoolManager._cleaningTimer |
|
||||
| System.Net.Http.HttpContent._bufferedContent |
|
||||
| System.Net.Http.HttpContentStream._connection |
|
||||
| System.Net.Http.HttpMessageInvoker._handler |
|
||||
| System.Net.Http.HttpRequestMessage._content |
|
||||
| System.Net.Http.HttpResponseMessage._content |
|
||||
| System.Net.Http.NoWriteNoSeekStreamContent._content |
|
||||
| System.Net.Http.RedirectHandler._initialInnerHandler |
|
||||
| System.Net.Http.RedirectHandler._redirectInnerHandler |
|
||||
| System.Net.Http.SocketsHttpHandler._handler |
|
||||
| System.Net.Http.StreamContent._content |
|
||||
| System.Net.NTAuthentication._credentialsHandle |
|
||||
| System.Net.NTAuthentication._securityContext |
|
||||
| System.Net.Security.SafeDeleteNegoContext._context |
|
||||
| System.Net.Security.SafeDeleteNegoContext._targetName |
|
||||
| System.Security.SecureString._buffer |
|
||||
| System.Threading.CancellationTokenSource.Linked1CancellationTokenSource._reg1 |
|
||||
| System.Threading.CancellationTokenSource.Linked2CancellationTokenSource._reg1 |
|
||||
| System.Threading.CancellationTokenSource.Linked2CancellationTokenSource._reg2 |
|
||||
| System.Threading.CancellationTokenSource._timer |
|
||||
| System.Threading.ReaderWriterLockSlim._readEvent |
|
||||
| System.Threading.ReaderWriterLockSlim._upgradeEvent |
|
||||
| System.Threading.ReaderWriterLockSlim._waitUpgradeEvent |
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
| BufferedStream(Stream) | 0 |
|
||||
| BufferedStream(Stream, int) | 0 |
|
||||
| CachedConnection(HttpConnection) | 0 |
|
||||
| ChunkedEncodingReadStream(HttpConnection) | 0 |
|
||||
| ChunkedEncodingWriteStream(HttpConnection) | 0 |
|
||||
| ConnectionCloseReadStream(HttpConnection) | 0 |
|
||||
| ContentLengthReadStream(HttpConnection, ulong) | 0 |
|
||||
| ContentLengthWriteStream(HttpConnection) | 0 |
|
||||
| CopyAsync(Stream, Stream, int, bool, CancellationToken) | 0 |
|
||||
| CopyToWriter(XmlWriter) | 0 |
|
||||
| Create(Stream) | 0 |
|
||||
|
@ -17,6 +23,8 @@
|
|||
| Create(XmlWriter, XmlWriterSettings) | 0 |
|
||||
| CreateAsyncCheckWrapper(XmlReader) | 0 |
|
||||
| CreateReader(Stream, string) | 0 |
|
||||
| DecompressedContent(HttpContent) | 0 |
|
||||
| DeflateDecompressedContent(HttpContent) | 0 |
|
||||
| DelegatingHandler(HttpMessageHandler) | 0 |
|
||||
| DelegatingStream(Stream) | 0 |
|
||||
| Deserialize(Stream) | 0 |
|
||||
|
@ -29,8 +37,10 @@
|
|||
| Disposal(IDisposable, object, TextWriter) | 0 |
|
||||
| Disposal(IDisposable, object, TextWriter) | 1 |
|
||||
| Disposal(IDisposable, object, TextWriter) | 2 |
|
||||
| DrainResponseAsync(HttpResponseMessage) | 0 |
|
||||
| EventsToWriter(XmlWriter) | 0 |
|
||||
| Execute(object, XmlResolver, XsltArgumentList, XmlWriter) | 3 |
|
||||
| GZipDecompressedContent(HttpContent) | 0 |
|
||||
| GetSynchronizedTextReader(TextReader) | 0 |
|
||||
| HtmlEncodedRawTextWriter(Stream, XmlWriterSettings) | 0 |
|
||||
| HtmlEncodedRawTextWriter(TextWriter, XmlWriterSettings) | 0 |
|
||||
|
@ -38,33 +48,49 @@
|
|||
| HtmlEncodedRawTextWriterIndent(TextWriter, XmlWriterSettings) | 0 |
|
||||
| HtmlUtf8RawTextWriter(Stream, XmlWriterSettings) | 0 |
|
||||
| HtmlUtf8RawTextWriterIndent(Stream, XmlWriterSettings) | 0 |
|
||||
| HttpAuthenticatedConnectionHandler(HttpConnectionPoolManager) | 0 |
|
||||
| HttpClient(HttpMessageHandler) | 0 |
|
||||
| HttpClient(HttpMessageHandler, bool) | 0 |
|
||||
| HttpConnectionHandler(HttpConnectionPoolManager) | 0 |
|
||||
| HttpContentDuplexStream(HttpConnection) | 0 |
|
||||
| HttpContentReadStream(HttpConnection) | 0 |
|
||||
| HttpContentStream(HttpConnection) | 0 |
|
||||
| HttpContentWriteStream(HttpConnection) | 0 |
|
||||
| HttpMessageInvoker(HttpMessageHandler) | 0 |
|
||||
| HttpMessageInvoker(HttpMessageHandler, bool) | 0 |
|
||||
| Load(Stream) | 0 |
|
||||
| Load(TextReader) | 0 |
|
||||
| MessageProcessingHandler(HttpMessageHandler) | 0 |
|
||||
| PatchAsync(string, HttpContent) | 1 |
|
||||
| PatchAsync(string, HttpContent, CancellationToken) | 1 |
|
||||
| PostAsync(string, HttpContent) | 1 |
|
||||
| PostAsync(string, HttpContent, CancellationToken) | 1 |
|
||||
| PutAsync(string, HttpContent) | 1 |
|
||||
| PutAsync(string, HttpContent, CancellationToken) | 1 |
|
||||
| RawConnectionStream(HttpConnection) | 0 |
|
||||
| Read(Stream, ValidationEventHandler) | 0 |
|
||||
| Read(TextReader, ValidationEventHandler) | 0 |
|
||||
| ReadOnlyStream(Stream) | 0 |
|
||||
| RedirectHandler(int, HttpMessageHandler, HttpMessageHandler) | 1 |
|
||||
| RedirectHandler(int, HttpMessageHandler, HttpMessageHandler) | 2 |
|
||||
| ReflectionXmlSerializationReader(XmlMapping, XmlReader, XmlDeserializationEvents, string) | 1 |
|
||||
| ReturnConnection(HttpConnection) | 0 |
|
||||
| Save(TextWriter) | 0 |
|
||||
| SendWithNtProxyAuthAsync(HttpConnection, HttpRequestMessage, CancellationToken) | 0 |
|
||||
| Serialize(TextWriter, object) | 0 |
|
||||
| Serialize(TextWriter, object, XmlSerializerNamespaces) | 0 |
|
||||
| SetError(TextWriter) | 0 |
|
||||
| SetGssContext(SafeGssContextHandle) | 0 |
|
||||
| SetIn(TextReader) | 0 |
|
||||
| SetOut(TextWriter) | 0 |
|
||||
| SetStream(HttpContentStream) | 0 |
|
||||
| StreamContent(Stream) | 0 |
|
||||
| StreamContent(Stream, int) | 0 |
|
||||
| Synchronized(Stream) | 0 |
|
||||
| System.IO.Stream System.IO.Stream.Synchronized(System.IO.Stream) | 0 |
|
||||
| System.IO.SyncTextReader System.IO.SyncTextReader.GetSynchronizedTextReader(System.IO.TextReader) | 0 |
|
||||
| System.IO.SyncTextWriter System.IO.SyncTextWriter.GetSynchronizedTextWriter(System.IO.TextWriter) | 0 |
|
||||
| System.Int32 System.Net.Http.HttpConnection.ChunkedEncodingReadStream.ReadChunksFromConnectionBuffer(System.Span<System.Byte>,System.Threading.CancellationTokenRegistration) | 1 |
|
||||
| System.Object System.Xml.Serialization.TempAssembly.InvokeReader(System.Xml.Serialization.XmlMapping,System.Xml.XmlReader,System.Xml.Serialization.XmlDeserializationEvents,System.String) | 1 |
|
||||
| System.Object System.Xml.Serialization.XmlSerializer.Deserialize(System.IO.Stream) | 0 |
|
||||
| System.Object System.Xml.Serialization.XmlSerializer.Deserialize(System.IO.TextReader) | 0 |
|
||||
|
@ -73,6 +99,10 @@
|
|||
| System.Object System.Xml.Serialization.XmlSerializer.Deserialize(System.Xml.XmlReader,System.String,System.Xml.Serialization.XmlDeserializationEvents) | 0 |
|
||||
| System.Object System.Xml.Serialization.XmlSerializer.Deserialize(System.Xml.XmlReader,System.Xml.Serialization.XmlDeserializationEvents) | 0 |
|
||||
| System.Object System.Xml.Serialization.XmlSerializer.DeserializePrimitive(System.Xml.XmlReader,System.Xml.Serialization.XmlDeserializationEvents) | 0 |
|
||||
| System.Object System.Xml.Serialization.XmlSerializer.DeserializeUsingReflection(System.Xml.XmlReader,System.String,System.Xml.Serialization.XmlDeserializationEvents) | 0 |
|
||||
| System.ReadOnlyMemory<System.Byte> System.Net.Http.HttpConnection.ChunkedEncodingReadStream.ReadChunkFromConnectionBuffer(System.Int32,System.Threading.CancellationTokenRegistration) | 1 |
|
||||
| System.Threading.Tasks.Task System.Net.Http.HttpConnection.DrainResponseAsync(System.Net.Http.HttpResponseMessage) | 0 |
|
||||
| System.Threading.Tasks.Task System.Net.Http.HttpConnection.SendRequestContentWithExpect100ContinueAsync(System.Net.Http.HttpRequestMessage,System.Threading.Tasks.Task<System.Boolean>,System.Net.Http.HttpConnection.HttpContentWriteStream,System.Threading.Timer,System.Threading.CancellationToken) | 3 |
|
||||
| System.Threading.Tasks.Task System.Net.Http.HttpContent.LoadIntoBufferAsyncCore(System.Threading.Tasks.Task,System.IO.MemoryStream) | 1 |
|
||||
| System.Threading.Tasks.Task System.Net.Http.StreamToStreamCopy.CopyAsync(System.IO.Stream,System.IO.Stream,System.Int32,System.Boolean,System.Threading.CancellationToken) | 0 |
|
||||
| System.Threading.Tasks.Task System.Net.Http.StreamToStreamCopy.DisposeSourceWhenCompleteAsync(System.Threading.Tasks.Task,System.IO.Stream) | 1 |
|
||||
|
@ -80,8 +110,16 @@
|
|||
| System.Threading.Tasks.Task System.Xml.XmlTextReaderImpl.InitStreamInputAsync(System.Uri,System.String,System.IO.Stream,System.Byte[],System.Int32,System.Text.Encoding) | 2 |
|
||||
| System.Threading.Tasks.Task System.Xml.XmlTextReaderImpl.InitTextReaderInputAsync(System.String,System.IO.TextReader) | 1 |
|
||||
| System.Threading.Tasks.Task System.Xml.XmlTextReaderImpl.InitTextReaderInputAsync(System.String,System.Uri,System.IO.TextReader) | 2 |
|
||||
| System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> System.Net.Http.AuthenticationHelper.InnerSendAsync(System.Net.Http.HttpRequestMessage,System.Boolean,System.Net.Http.HttpConnectionPool,System.Net.Http.HttpConnection,System.Threading.CancellationToken) | 3 |
|
||||
| System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> System.Net.Http.AuthenticationHelper.SendWithNtAuthAsync(System.Net.Http.HttpRequestMessage,System.Uri,System.Net.ICredentials,System.Boolean,System.Net.Http.HttpConnection,System.Net.Http.HttpConnectionPool,System.Threading.CancellationToken) | 4 |
|
||||
| System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> System.Net.Http.AuthenticationHelper.SendWithNtConnectionAuthAsync(System.Net.Http.HttpRequestMessage,System.Net.ICredentials,System.Net.Http.HttpConnection,System.Net.Http.HttpConnectionPool,System.Threading.CancellationToken) | 2 |
|
||||
| System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> System.Net.Http.AuthenticationHelper.SendWithNtProxyAuthAsync(System.Net.Http.HttpRequestMessage,System.Uri,System.Net.ICredentials,System.Net.Http.HttpConnection,System.Net.Http.HttpConnectionPool,System.Threading.CancellationToken) | 3 |
|
||||
| System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> System.Net.Http.HttpClient.FinishSendAsyncBuffered(System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage>,System.Net.Http.HttpRequestMessage,System.Threading.CancellationTokenSource,System.Boolean) | 2 |
|
||||
| System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage>,System.Net.Http.HttpRequestMessage,System.Threading.CancellationTokenSource,System.Boolean) | 2 |
|
||||
| System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> System.Net.Http.HttpClient.PatchAsync(System.String,System.Net.Http.HttpContent) | 1 |
|
||||
| System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> System.Net.Http.HttpClient.PatchAsync(System.String,System.Net.Http.HttpContent,System.Threading.CancellationToken) | 1 |
|
||||
| System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> System.Net.Http.HttpClient.PatchAsync(System.Uri,System.Net.Http.HttpContent) | 1 |
|
||||
| System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> System.Net.Http.HttpClient.PatchAsync(System.Uri,System.Net.Http.HttpContent,System.Threading.CancellationToken) | 1 |
|
||||
| System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> System.Net.Http.HttpClient.PostAsync(System.String,System.Net.Http.HttpContent) | 1 |
|
||||
| System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> System.Net.Http.HttpClient.PostAsync(System.String,System.Net.Http.HttpContent,System.Threading.CancellationToken) | 1 |
|
||||
| System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> System.Net.Http.HttpClient.PostAsync(System.Uri,System.Net.Http.HttpContent) | 1 |
|
||||
|
@ -90,6 +128,8 @@
|
|||
| System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> System.Net.Http.HttpClient.PutAsync(System.String,System.Net.Http.HttpContent,System.Threading.CancellationToken) | 1 |
|
||||
| System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> System.Net.Http.HttpClient.PutAsync(System.Uri,System.Net.Http.HttpContent) | 1 |
|
||||
| System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> System.Net.Http.HttpClient.PutAsync(System.Uri,System.Net.Http.HttpContent,System.Threading.CancellationToken) | 1 |
|
||||
| System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> System.Net.Http.HttpConnectionPool.SendWithNtConnectionAuthAsync(System.Net.Http.HttpConnection,System.Net.Http.HttpRequestMessage,System.Boolean,System.Threading.CancellationToken) | 0 |
|
||||
| System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage> System.Net.Http.HttpConnectionPool.SendWithNtProxyAuthAsync(System.Net.Http.HttpConnection,System.Net.Http.HttpRequestMessage,System.Threading.CancellationToken) | 0 |
|
||||
| System.Void System.Console.SetError(System.IO.TextWriter) | 0 |
|
||||
| System.Void System.Console.SetIn(System.IO.TextReader) | 0 |
|
||||
| System.Void System.Console.SetOut(System.IO.TextWriter) | 0 |
|
||||
|
@ -99,25 +139,49 @@
|
|||
| System.Void System.IO.SyncTextReader..ctor(System.IO.TextReader) | 0 |
|
||||
| System.Void System.IO.SyncTextWriter..ctor(System.IO.TextWriter) | 0 |
|
||||
| System.Void System.IO.UnmanagedMemoryStreamWrapper..ctor(System.IO.UnmanagedMemoryStream) | 0 |
|
||||
| System.Void System.Net.Http.DecompressionHandler..ctor(System.Net.DecompressionMethods,System.Net.Http.HttpMessageHandler) | 1 |
|
||||
| System.Void System.Net.Http.DecompressionHandler.DecompressedContent..ctor(System.Net.Http.HttpContent) | 0 |
|
||||
| System.Void System.Net.Http.DecompressionHandler.DeflateDecompressedContent..ctor(System.Net.Http.HttpContent) | 0 |
|
||||
| System.Void System.Net.Http.DecompressionHandler.GZipDecompressedContent..ctor(System.Net.Http.HttpContent) | 0 |
|
||||
| System.Void System.Net.Http.DelegatingHandler..ctor(System.Net.Http.HttpMessageHandler) | 0 |
|
||||
| System.Void System.Net.Http.DelegatingHandler.set_InnerHandler(System.Net.Http.HttpMessageHandler) | 0 |
|
||||
| System.Void System.Net.Http.DelegatingStream..ctor(System.IO.Stream) | 0 |
|
||||
| System.Void System.Net.Http.DiagnosticsHandler..ctor(System.Net.Http.HttpMessageHandler) | 0 |
|
||||
| System.Void System.Net.Http.HttpAuthenticatedConnectionHandler..ctor(System.Net.Http.HttpConnectionPoolManager) | 0 |
|
||||
| System.Void System.Net.Http.HttpClient..ctor(System.Net.Http.HttpMessageHandler) | 0 |
|
||||
| System.Void System.Net.Http.HttpClient..ctor(System.Net.Http.HttpMessageHandler,System.Boolean) | 0 |
|
||||
| System.Void System.Net.Http.HttpClient.HandleFinishSendAsyncCleanup(System.Threading.CancellationTokenSource,System.Boolean) | 0 |
|
||||
| System.Void System.Net.Http.HttpConnection..ctor(System.Net.Http.HttpConnectionPool,System.Net.Sockets.Socket,System.IO.Stream,System.Net.TransportContext) | 2 |
|
||||
| System.Void System.Net.Http.HttpConnection.ChunkedEncodingReadStream..ctor(System.Net.Http.HttpConnection) | 0 |
|
||||
| System.Void System.Net.Http.HttpConnection.ChunkedEncodingWriteStream..ctor(System.Net.Http.HttpConnection) | 0 |
|
||||
| System.Void System.Net.Http.HttpConnection.ConnectionCloseReadStream..ctor(System.Net.Http.HttpConnection) | 0 |
|
||||
| System.Void System.Net.Http.HttpConnection.ContentLengthReadStream..ctor(System.Net.Http.HttpConnection,System.UInt64) | 0 |
|
||||
| System.Void System.Net.Http.HttpConnection.ContentLengthWriteStream..ctor(System.Net.Http.HttpConnection) | 0 |
|
||||
| System.Void System.Net.Http.HttpConnection.HttpConnectionResponseContent.SetStream(System.Net.Http.HttpContentStream) | 0 |
|
||||
| System.Void System.Net.Http.HttpConnection.HttpContentReadStream..ctor(System.Net.Http.HttpConnection) | 0 |
|
||||
| System.Void System.Net.Http.HttpConnection.HttpContentWriteStream..ctor(System.Net.Http.HttpConnection) | 0 |
|
||||
| System.Void System.Net.Http.HttpConnection.RawConnectionStream..ctor(System.Net.Http.HttpConnection) | 0 |
|
||||
| System.Void System.Net.Http.HttpConnectionHandler..ctor(System.Net.Http.HttpConnectionPoolManager) | 0 |
|
||||
| System.Void System.Net.Http.HttpConnectionPool.<>c.<CleanCacheAndDisposeIfUnused>b__55_0(System.Net.Http.HttpConnection) | 0 |
|
||||
| System.Void System.Net.Http.HttpConnectionPool.CachedConnection..ctor(System.Net.Http.HttpConnection) | 0 |
|
||||
| System.Void System.Net.Http.HttpConnectionPool.ReturnConnection(System.Net.Http.HttpConnection) | 0 |
|
||||
| System.Void System.Net.Http.HttpConnectionWithFinalizer..ctor(System.Net.Http.HttpConnectionPool,System.Net.Sockets.Socket,System.IO.Stream,System.Net.TransportContext) | 2 |
|
||||
| System.Void System.Net.Http.HttpContentDuplexStream..ctor(System.Net.Http.HttpConnection) | 0 |
|
||||
| System.Void System.Net.Http.HttpContentStream..ctor(System.Net.Http.HttpConnection) | 0 |
|
||||
| System.Void System.Net.Http.HttpMessageInvoker..ctor(System.Net.Http.HttpMessageHandler) | 0 |
|
||||
| System.Void System.Net.Http.HttpMessageInvoker..ctor(System.Net.Http.HttpMessageHandler,System.Boolean) | 0 |
|
||||
| System.Void System.Net.Http.HttpRequestMessage.set_Content(System.Net.Http.HttpContent) | 0 |
|
||||
| System.Void System.Net.Http.HttpResponseMessage.set_Content(System.Net.Http.HttpContent) | 0 |
|
||||
| System.Void System.Net.Http.MessageProcessingHandler..ctor(System.Net.Http.HttpMessageHandler) | 0 |
|
||||
| System.Void System.Net.Http.NoWriteNoSeekStreamContent..ctor(System.IO.Stream,System.Threading.CancellationToken) | 0 |
|
||||
| System.Void System.Net.Http.NoWriteNoSeekStreamContent..ctor(System.IO.Stream) | 0 |
|
||||
| System.Void System.Net.Http.RedirectHandler..ctor(System.Int32,System.Net.Http.HttpMessageHandler,System.Net.Http.HttpMessageHandler) | 1 |
|
||||
| System.Void System.Net.Http.RedirectHandler..ctor(System.Int32,System.Net.Http.HttpMessageHandler,System.Net.Http.HttpMessageHandler) | 2 |
|
||||
| System.Void System.Net.Http.StreamContent..ctor(System.IO.Stream) | 0 |
|
||||
| System.Void System.Net.Http.StreamContent..ctor(System.IO.Stream,System.Int32) | 0 |
|
||||
| System.Void System.Net.Http.StreamContent..ctor(System.IO.Stream,System.Int32,System.Threading.CancellationToken) | 0 |
|
||||
| System.Void System.Net.Http.StreamContent.InitializeContent(System.IO.Stream,System.Int32) | 0 |
|
||||
| System.Void System.Net.Http.StreamContent.ReadOnlyStream..ctor(System.IO.Stream) | 0 |
|
||||
| System.Void System.Net.Http.StreamToStreamCopy.DisposeSource(System.IO.Stream) | 0 |
|
||||
| System.Void System.Threading.Mutex.MutexCleanupInfo..ctor(Microsoft.Win32.SafeHandles.SafeWaitHandle,System.Boolean) | 0 |
|
||||
| System.Void System.Net.Security.SafeDeleteNegoContext.SetGssContext(Microsoft.Win32.SafeHandles.SafeGssContextHandle) | 0 |
|
||||
| System.Void System.TypeNameParser..ctor(System.SafeTypeNameParserHandle) | 0 |
|
||||
| System.Void System.Xml.HtmlEncodedRawTextWriter..ctor(System.IO.Stream,System.Xml.XmlWriterSettings) | 0 |
|
||||
| System.Void System.Xml.HtmlEncodedRawTextWriter..ctor(System.IO.TextWriter,System.Xml.XmlWriterSettings) | 0 |
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
| System.IO.TextWriter System.Console.EnsureInitialized<System.IO.TextWriter>(System.IO.TextWriter,System.Func<System.IO.TextWriter>) | 0 |
|
||||
| System.IO.TextWriter System.IO.TextWriter.Synchronized(System.IO.TextWriter) | 0 |
|
||||
| System.IO.TextWriter System.Threading.Volatile.Read<System.IO.TextWriter>(System.IO.TextWriter) | 0 |
|
||||
| System.Tuple<System.IO.TextWriter,System.ReadOnlyMemory<System.Char>> System.Tuple.Create<System.IO.TextWriter,System.ReadOnlyMemory<System.Char>>(System.IO.TextWriter,System.ReadOnlyMemory<System.Char>) | 0 |
|
||||
| System.Void System.CodeDom.Compiler.IndentedTextWriter..ctor(System.IO.TextWriter) | 0 |
|
||||
| System.Void System.CodeDom.Compiler.IndentedTextWriter..ctor(System.IO.TextWriter,System.String) | 0 |
|
||||
| System.Void System.IO.TextWriter.SyncTextWriter..ctor(System.IO.TextWriter) | 0 |
|
||||
|
@ -17,6 +18,7 @@
|
|||
| System.Void System.Tuple<System.Char,System.IO.TextWriter>..ctor(System.IO.TextWriter,System.Char) | 0 |
|
||||
| System.Void System.Tuple<System.Char[],System.IO.TextWriter,System.Int32,System.Int32>..ctor(System.IO.TextWriter,System.Char[],System.Int32,System.Int32) | 0 |
|
||||
| System.Void System.Tuple<System.IO.TextWriter,System.String>..ctor(System.IO.TextWriter,System.String) | 0 |
|
||||
| System.Void System.Xml.Serialization.IndentedWriter..ctor(System.IO.TextWriter,System.Boolean) | 0 |
|
||||
| System.Void System.Xml.XmlTextEncoder..ctor(System.IO.TextWriter) | 0 |
|
||||
| System.Void System.Xml.Xsl.XslTransform.Transform(System.Xml.XPath.IXPathNavigable,System.Xml.Xsl.XsltArgumentList,System.IO.TextWriter) | 2 |
|
||||
| System.Void System.Xml.Xsl.XslTransform.Transform(System.Xml.XPath.IXPathNavigable,System.Xml.Xsl.XsltArgumentList,System.IO.TextWriter,System.Xml.XmlResolver) | 2 |
|
||||
|
|
|
@ -365,6 +365,16 @@
|
|||
| Switch.cs:118:25:118:25 | access to parameter s | Switch.cs:118:25:118:31 | ... == ... | 3 |
|
||||
| Switch.cs:118:42:118:42 | 2 | Switch.cs:118:35:118:43 | return ...; | 2 |
|
||||
| Switch.cs:120:17:120:17 | 1 | Switch.cs:120:9:120:18 | return ...; | 3 |
|
||||
| Switch.cs:123:10:123:12 | enter M11 | Switch.cs:125:24:125:29 | Boolean b | 7 |
|
||||
| Switch.cs:123:10:123:12 | exit M11 | Switch.cs:123:10:123:12 | exit M11 | 1 |
|
||||
| Switch.cs:125:34:125:34 | access to local variable b | Switch.cs:125:34:125:34 | access to local variable b | 1 |
|
||||
| Switch.cs:125:37:125:46 | ... => ... | Switch.cs:125:42:125:46 | false | 3 |
|
||||
| Switch.cs:126:13:126:19 | return ...; | Switch.cs:126:13:126:19 | return ...; | 1 |
|
||||
| Switch.cs:129:12:129:14 | enter M12 | Switch.cs:131:28:131:35 | String s | 6 |
|
||||
| Switch.cs:131:9:131:67 | return ...; | Switch.cs:129:12:129:14 | exit M12 | 2 |
|
||||
| Switch.cs:131:40:131:40 | access to local variable s | Switch.cs:131:40:131:40 | access to local variable s | 1 |
|
||||
| Switch.cs:131:43:131:51 | ... => ... | Switch.cs:131:48:131:51 | null | 3 |
|
||||
| Switch.cs:131:56:131:66 | call to method ToString | Switch.cs:131:56:131:66 | call to method ToString | 1 |
|
||||
| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:7:13:7:22 | ... is ... | 14 |
|
||||
| TypeAccesses.cs:7:25:7:25 | ; | TypeAccesses.cs:7:25:7:25 | ; | 1 |
|
||||
| TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:3:10:3:10 | exit M | 4 |
|
||||
|
|
|
@ -722,6 +722,24 @@
|
|||
| post | Switch.cs:118:25:118:25 | access to parameter s | Switch.cs:118:25:118:25 | access to parameter s |
|
||||
| post | Switch.cs:118:42:118:42 | 2 | Switch.cs:118:42:118:42 | 2 |
|
||||
| post | Switch.cs:120:17:120:17 | 1 | Switch.cs:120:17:120:17 | 1 |
|
||||
| post | Switch.cs:123:10:123:12 | enter M11 | Switch.cs:123:10:123:12 | enter M11 |
|
||||
| post | Switch.cs:123:10:123:12 | exit M11 | Switch.cs:123:10:123:12 | enter M11 |
|
||||
| post | Switch.cs:123:10:123:12 | exit M11 | Switch.cs:123:10:123:12 | exit M11 |
|
||||
| post | Switch.cs:123:10:123:12 | exit M11 | Switch.cs:125:34:125:34 | access to local variable b |
|
||||
| post | Switch.cs:123:10:123:12 | exit M11 | Switch.cs:125:37:125:46 | ... => ... |
|
||||
| post | Switch.cs:123:10:123:12 | exit M11 | Switch.cs:126:13:126:19 | return ...; |
|
||||
| post | Switch.cs:125:34:125:34 | access to local variable b | Switch.cs:125:34:125:34 | access to local variable b |
|
||||
| post | Switch.cs:125:37:125:46 | ... => ... | Switch.cs:125:37:125:46 | ... => ... |
|
||||
| post | Switch.cs:126:13:126:19 | return ...; | Switch.cs:126:13:126:19 | return ...; |
|
||||
| post | Switch.cs:129:12:129:14 | enter M12 | Switch.cs:129:12:129:14 | enter M12 |
|
||||
| post | Switch.cs:131:9:131:67 | return ...; | Switch.cs:129:12:129:14 | enter M12 |
|
||||
| post | Switch.cs:131:9:131:67 | return ...; | Switch.cs:131:9:131:67 | return ...; |
|
||||
| post | Switch.cs:131:9:131:67 | return ...; | Switch.cs:131:40:131:40 | access to local variable s |
|
||||
| post | Switch.cs:131:9:131:67 | return ...; | Switch.cs:131:43:131:51 | ... => ... |
|
||||
| post | Switch.cs:131:9:131:67 | return ...; | Switch.cs:131:56:131:66 | call to method ToString |
|
||||
| post | Switch.cs:131:40:131:40 | access to local variable s | Switch.cs:131:40:131:40 | access to local variable s |
|
||||
| post | Switch.cs:131:43:131:51 | ... => ... | Switch.cs:131:43:131:51 | ... => ... |
|
||||
| post | Switch.cs:131:56:131:66 | call to method ToString | Switch.cs:131:56:131:66 | call to method ToString |
|
||||
| post | TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:3:10:3:10 | enter M |
|
||||
| post | TypeAccesses.cs:7:25:7:25 | ; | TypeAccesses.cs:7:25:7:25 | ; |
|
||||
| post | TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:3:10:3:10 | enter M |
|
||||
|
@ -2244,6 +2262,26 @@
|
|||
| pre | Switch.cs:118:25:118:25 | access to parameter s | Switch.cs:118:42:118:42 | 2 |
|
||||
| pre | Switch.cs:118:42:118:42 | 2 | Switch.cs:118:42:118:42 | 2 |
|
||||
| pre | Switch.cs:120:17:120:17 | 1 | Switch.cs:120:17:120:17 | 1 |
|
||||
| pre | Switch.cs:123:10:123:12 | enter M11 | Switch.cs:123:10:123:12 | enter M11 |
|
||||
| pre | Switch.cs:123:10:123:12 | enter M11 | Switch.cs:123:10:123:12 | exit M11 |
|
||||
| pre | Switch.cs:123:10:123:12 | enter M11 | Switch.cs:125:34:125:34 | access to local variable b |
|
||||
| pre | Switch.cs:123:10:123:12 | enter M11 | Switch.cs:125:37:125:46 | ... => ... |
|
||||
| pre | Switch.cs:123:10:123:12 | enter M11 | Switch.cs:126:13:126:19 | return ...; |
|
||||
| pre | Switch.cs:123:10:123:12 | exit M11 | Switch.cs:123:10:123:12 | exit M11 |
|
||||
| pre | Switch.cs:125:34:125:34 | access to local variable b | Switch.cs:125:34:125:34 | access to local variable b |
|
||||
| pre | Switch.cs:125:34:125:34 | access to local variable b | Switch.cs:126:13:126:19 | return ...; |
|
||||
| pre | Switch.cs:125:37:125:46 | ... => ... | Switch.cs:125:37:125:46 | ... => ... |
|
||||
| pre | Switch.cs:126:13:126:19 | return ...; | Switch.cs:126:13:126:19 | return ...; |
|
||||
| pre | Switch.cs:129:12:129:14 | enter M12 | Switch.cs:129:12:129:14 | enter M12 |
|
||||
| pre | Switch.cs:129:12:129:14 | enter M12 | Switch.cs:131:9:131:67 | return ...; |
|
||||
| pre | Switch.cs:129:12:129:14 | enter M12 | Switch.cs:131:40:131:40 | access to local variable s |
|
||||
| pre | Switch.cs:129:12:129:14 | enter M12 | Switch.cs:131:43:131:51 | ... => ... |
|
||||
| pre | Switch.cs:129:12:129:14 | enter M12 | Switch.cs:131:56:131:66 | call to method ToString |
|
||||
| pre | Switch.cs:131:9:131:67 | return ...; | Switch.cs:131:9:131:67 | return ...; |
|
||||
| pre | Switch.cs:131:40:131:40 | access to local variable s | Switch.cs:131:40:131:40 | access to local variable s |
|
||||
| pre | Switch.cs:131:40:131:40 | access to local variable s | Switch.cs:131:56:131:66 | call to method ToString |
|
||||
| pre | Switch.cs:131:43:131:51 | ... => ... | Switch.cs:131:43:131:51 | ... => ... |
|
||||
| pre | Switch.cs:131:56:131:66 | call to method ToString | Switch.cs:131:56:131:66 | call to method ToString |
|
||||
| pre | TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:3:10:3:10 | enter M |
|
||||
| pre | TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:7:25:7:25 | ; |
|
||||
| pre | TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:8:9:8:28 | ... ...; |
|
||||
|
|
|
@ -327,6 +327,14 @@
|
|||
| Switch.cs:118:18:118:18 | 2 | Switch.cs:118:25:118:25 | access to parameter s | true |
|
||||
| Switch.cs:118:18:118:18 | 2 | Switch.cs:118:42:118:42 | 2 | true |
|
||||
| Switch.cs:118:25:118:31 | ... == ... | Switch.cs:118:42:118:42 | 2 | true |
|
||||
| Switch.cs:125:24:125:29 | Boolean b | Switch.cs:125:34:125:34 | access to local variable b | true |
|
||||
| Switch.cs:125:24:125:29 | Boolean b | Switch.cs:125:37:125:46 | ... => ... | false |
|
||||
| Switch.cs:125:24:125:29 | Boolean b | Switch.cs:126:13:126:19 | return ...; | true |
|
||||
| Switch.cs:125:34:125:34 | access to local variable b | Switch.cs:126:13:126:19 | return ...; | true |
|
||||
| Switch.cs:131:28:131:35 | String s | Switch.cs:131:40:131:40 | access to local variable s | true |
|
||||
| Switch.cs:131:28:131:35 | String s | Switch.cs:131:43:131:51 | ... => ... | false |
|
||||
| Switch.cs:131:28:131:35 | String s | Switch.cs:131:56:131:66 | call to method ToString | true |
|
||||
| Switch.cs:131:40:131:40 | access to local variable s | Switch.cs:131:56:131:66 | call to method ToString | false |
|
||||
| TypeAccesses.cs:7:13:7:22 | ... is ... | TypeAccesses.cs:7:25:7:25 | ; | true |
|
||||
| VarDecls.cs:25:20:25:20 | access to parameter b | VarDecls.cs:25:24:25:24 | access to local variable x | true |
|
||||
| VarDecls.cs:25:20:25:20 | access to parameter b | VarDecls.cs:25:28:25:28 | access to local variable y | false |
|
||||
|
|
|
@ -197,6 +197,9 @@
|
|||
| 119 | 18 | Conditions.cs:119:18:119:21 | access to local variable last | true | 121 | 13 | Conditions.cs:121:13:122:25 | [last (line 118): true] if (...) ... |
|
||||
| 121 | 17 | Conditions.cs:121:17:121:20 | [last (line 118): false] access to local variable last | false | 116 | 41 | Conditions.cs:116:41:116:41 | access to local variable i |
|
||||
| 121 | 17 | Conditions.cs:121:17:121:20 | [last (line 118): true] access to local variable last | true | 122 | 17 | Conditions.cs:122:17:122:25 | ...; |
|
||||
| 125 | 34 | Switch.cs:125:34:125:34 | access to local variable b | false | 123 | 10 | Switch.cs:123:10:123:12 | exit M11 |
|
||||
| 125 | 34 | Switch.cs:125:34:125:34 | access to local variable b | true | 126 | 13 | Switch.cs:126:13:126:19 | return ...; |
|
||||
| 125 | 42 | Switch.cs:125:42:125:46 | false | false | 123 | 10 | Switch.cs:123:10:123:12 | exit M11 |
|
||||
| 127 | 32 | cflow.cs:127:32:127:44 | ... == ... | false | 127 | 53 | cflow.cs:127:53:127:57 | this access |
|
||||
| 127 | 32 | cflow.cs:127:32:127:44 | ... == ... | true | 127 | 48 | cflow.cs:127:48:127:49 | "" |
|
||||
| 131 | 16 | Conditions.cs:131:16:131:19 | [Field1 (line 129): false] true | true | 132 | 9 | Conditions.cs:132:9:140:9 | [Field1 (line 129): false] {...} |
|
||||
|
|
|
@ -1485,6 +1485,28 @@
|
|||
| post | Switch.cs:118:35:118:43 | return ...; | Switch.cs:118:42:118:42 | 2 |
|
||||
| post | Switch.cs:120:9:120:18 | return ...; | Switch.cs:120:16:120:17 | -... |
|
||||
| post | Switch.cs:120:16:120:17 | -... | Switch.cs:120:17:120:17 | 1 |
|
||||
| post | Switch.cs:123:10:123:12 | exit M11 | Switch.cs:125:34:125:34 | access to local variable b |
|
||||
| post | Switch.cs:123:10:123:12 | exit M11 | Switch.cs:125:42:125:46 | false |
|
||||
| post | Switch.cs:123:10:123:12 | exit M11 | Switch.cs:126:13:126:19 | return ...; |
|
||||
| post | Switch.cs:124:5:127:5 | {...} | Switch.cs:123:10:123:12 | enter M11 |
|
||||
| post | Switch.cs:125:9:126:19 | if (...) ... | Switch.cs:124:5:127:5 | {...} |
|
||||
| post | Switch.cs:125:13:125:13 | access to parameter o | Switch.cs:125:13:125:48 | ... switch { ... } |
|
||||
| post | Switch.cs:125:13:125:48 | ... switch { ... } | Switch.cs:125:9:126:19 | if (...) ... |
|
||||
| post | Switch.cs:125:24:125:29 | Boolean b | Switch.cs:125:24:125:34 | ... => ... |
|
||||
| post | Switch.cs:125:24:125:34 | ... => ... | Switch.cs:125:13:125:13 | access to parameter o |
|
||||
| post | Switch.cs:125:37:125:37 | _ | Switch.cs:125:37:125:46 | ... => ... |
|
||||
| post | Switch.cs:125:42:125:46 | false | Switch.cs:125:37:125:37 | _ |
|
||||
| post | Switch.cs:129:12:129:14 | exit M12 | Switch.cs:131:9:131:67 | return ...; |
|
||||
| post | Switch.cs:130:5:132:5 | {...} | Switch.cs:129:12:129:14 | enter M12 |
|
||||
| post | Switch.cs:131:9:131:67 | return ...; | Switch.cs:131:40:131:40 | access to local variable s |
|
||||
| post | Switch.cs:131:9:131:67 | return ...; | Switch.cs:131:48:131:51 | null |
|
||||
| post | Switch.cs:131:9:131:67 | return ...; | Switch.cs:131:56:131:66 | call to method ToString |
|
||||
| post | Switch.cs:131:17:131:17 | access to parameter o | Switch.cs:131:17:131:53 | ... switch { ... } |
|
||||
| post | Switch.cs:131:17:131:53 | ... switch { ... } | Switch.cs:130:5:132:5 | {...} |
|
||||
| post | Switch.cs:131:28:131:35 | String s | Switch.cs:131:28:131:40 | ... => ... |
|
||||
| post | Switch.cs:131:28:131:40 | ... => ... | Switch.cs:131:17:131:17 | access to parameter o |
|
||||
| post | Switch.cs:131:43:131:43 | _ | Switch.cs:131:43:131:51 | ... => ... |
|
||||
| post | Switch.cs:131:48:131:51 | null | Switch.cs:131:43:131:43 | _ |
|
||||
| post | TypeAccesses.cs:3:10:3:10 | exit M | TypeAccesses.cs:8:13:8:27 | Type t = ... |
|
||||
| post | TypeAccesses.cs:4:5:9:5 | {...} | TypeAccesses.cs:3:10:3:10 | enter M |
|
||||
| post | TypeAccesses.cs:5:9:5:26 | ... ...; | TypeAccesses.cs:4:5:9:5 | {...} |
|
||||
|
@ -3964,6 +3986,28 @@
|
|||
| pre | Switch.cs:118:42:118:42 | 2 | Switch.cs:118:35:118:43 | return ...; |
|
||||
| pre | Switch.cs:120:16:120:17 | -... | Switch.cs:120:9:120:18 | return ...; |
|
||||
| pre | Switch.cs:120:17:120:17 | 1 | Switch.cs:120:16:120:17 | -... |
|
||||
| pre | Switch.cs:123:10:123:12 | enter M11 | Switch.cs:124:5:127:5 | {...} |
|
||||
| pre | Switch.cs:124:5:127:5 | {...} | Switch.cs:125:9:126:19 | if (...) ... |
|
||||
| pre | Switch.cs:125:9:126:19 | if (...) ... | Switch.cs:125:13:125:48 | ... switch { ... } |
|
||||
| pre | Switch.cs:125:13:125:13 | access to parameter o | Switch.cs:125:24:125:34 | ... => ... |
|
||||
| pre | Switch.cs:125:13:125:48 | ... switch { ... } | Switch.cs:125:13:125:13 | access to parameter o |
|
||||
| pre | Switch.cs:125:24:125:29 | Boolean b | Switch.cs:125:34:125:34 | access to local variable b |
|
||||
| pre | Switch.cs:125:24:125:29 | Boolean b | Switch.cs:125:37:125:46 | ... => ... |
|
||||
| pre | Switch.cs:125:24:125:34 | ... => ... | Switch.cs:125:24:125:29 | Boolean b |
|
||||
| pre | Switch.cs:125:34:125:34 | access to local variable b | Switch.cs:126:13:126:19 | return ...; |
|
||||
| pre | Switch.cs:125:37:125:37 | _ | Switch.cs:125:42:125:46 | false |
|
||||
| pre | Switch.cs:125:37:125:46 | ... => ... | Switch.cs:125:37:125:37 | _ |
|
||||
| pre | Switch.cs:129:12:129:14 | enter M12 | Switch.cs:130:5:132:5 | {...} |
|
||||
| pre | Switch.cs:130:5:132:5 | {...} | Switch.cs:131:17:131:53 | ... switch { ... } |
|
||||
| pre | Switch.cs:131:9:131:67 | return ...; | Switch.cs:129:12:129:14 | exit M12 |
|
||||
| pre | Switch.cs:131:17:131:17 | access to parameter o | Switch.cs:131:28:131:40 | ... => ... |
|
||||
| pre | Switch.cs:131:17:131:53 | ... switch { ... } | Switch.cs:131:17:131:17 | access to parameter o |
|
||||
| pre | Switch.cs:131:28:131:35 | String s | Switch.cs:131:40:131:40 | access to local variable s |
|
||||
| pre | Switch.cs:131:28:131:35 | String s | Switch.cs:131:43:131:51 | ... => ... |
|
||||
| pre | Switch.cs:131:28:131:40 | ... => ... | Switch.cs:131:28:131:35 | String s |
|
||||
| pre | Switch.cs:131:40:131:40 | access to local variable s | Switch.cs:131:56:131:66 | call to method ToString |
|
||||
| pre | Switch.cs:131:43:131:43 | _ | Switch.cs:131:48:131:51 | null |
|
||||
| pre | Switch.cs:131:43:131:51 | ... => ... | Switch.cs:131:43:131:43 | _ |
|
||||
| pre | TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:4:5:9:5 | {...} |
|
||||
| pre | TypeAccesses.cs:4:5:9:5 | {...} | TypeAccesses.cs:5:9:5:26 | ... ...; |
|
||||
| pre | TypeAccesses.cs:5:9:5:26 | ... ...; | TypeAccesses.cs:5:25:5:25 | access to parameter o |
|
||||
|
|
|
@ -1257,6 +1257,28 @@
|
|||
| Switch.cs:118:42:118:42 | 2 | Switch.cs:118:35:118:43 | return ...; | semmle.label | successor |
|
||||
| Switch.cs:120:16:120:17 | -... | Switch.cs:120:9:120:18 | return ...; | semmle.label | successor |
|
||||
| Switch.cs:120:17:120:17 | 1 | Switch.cs:120:16:120:17 | -... | semmle.label | successor |
|
||||
| Switch.cs:124:5:127:5 | {...} | Switch.cs:125:9:126:19 | if (...) ... | semmle.label | successor |
|
||||
| Switch.cs:125:9:126:19 | if (...) ... | Switch.cs:125:13:125:48 | ... switch { ... } | semmle.label | successor |
|
||||
| Switch.cs:125:13:125:13 | access to parameter o | Switch.cs:125:24:125:34 | ... => ... | semmle.label | successor |
|
||||
| Switch.cs:125:13:125:48 | ... switch { ... } | Switch.cs:125:13:125:13 | access to parameter o | semmle.label | successor |
|
||||
| Switch.cs:125:24:125:29 | Boolean b | Switch.cs:125:34:125:34 | access to local variable b | semmle.label | match |
|
||||
| Switch.cs:125:24:125:29 | Boolean b | Switch.cs:125:37:125:46 | ... => ... | semmle.label | no-match |
|
||||
| Switch.cs:125:24:125:34 | ... => ... | Switch.cs:125:24:125:29 | Boolean b | semmle.label | successor |
|
||||
| Switch.cs:125:34:125:34 | access to local variable b | Switch.cs:126:13:126:19 | return ...; | semmle.label | true |
|
||||
| Switch.cs:125:37:125:37 | _ | Switch.cs:125:42:125:46 | false | semmle.label | match |
|
||||
| Switch.cs:125:37:125:46 | ... => ... | Switch.cs:125:37:125:37 | _ | semmle.label | successor |
|
||||
| Switch.cs:130:5:132:5 | {...} | Switch.cs:131:17:131:53 | ... switch { ... } | semmle.label | successor |
|
||||
| Switch.cs:131:17:131:17 | access to parameter o | Switch.cs:131:28:131:40 | ... => ... | semmle.label | successor |
|
||||
| Switch.cs:131:17:131:53 | ... switch { ... } | Switch.cs:131:17:131:17 | access to parameter o | semmle.label | successor |
|
||||
| Switch.cs:131:28:131:35 | String s | Switch.cs:131:40:131:40 | access to local variable s | semmle.label | match |
|
||||
| Switch.cs:131:28:131:35 | String s | Switch.cs:131:43:131:51 | ... => ... | semmle.label | no-match |
|
||||
| Switch.cs:131:28:131:40 | ... => ... | Switch.cs:131:28:131:35 | String s | semmle.label | successor |
|
||||
| Switch.cs:131:40:131:40 | access to local variable s | Switch.cs:131:9:131:67 | return ...; | semmle.label | null |
|
||||
| Switch.cs:131:40:131:40 | access to local variable s | Switch.cs:131:56:131:66 | call to method ToString | semmle.label | non-null |
|
||||
| Switch.cs:131:43:131:43 | _ | Switch.cs:131:48:131:51 | null | semmle.label | match |
|
||||
| Switch.cs:131:43:131:51 | ... => ... | Switch.cs:131:43:131:43 | _ | semmle.label | successor |
|
||||
| Switch.cs:131:48:131:51 | null | Switch.cs:131:9:131:67 | return ...; | semmle.label | null |
|
||||
| Switch.cs:131:56:131:66 | call to method ToString | Switch.cs:131:9:131:67 | return ...; | semmle.label | successor |
|
||||
| TypeAccesses.cs:4:5:9:5 | {...} | TypeAccesses.cs:5:9:5:26 | ... ...; | semmle.label | successor |
|
||||
| TypeAccesses.cs:5:9:5:26 | ... ...; | TypeAccesses.cs:5:25:5:25 | access to parameter o | semmle.label | successor |
|
||||
| TypeAccesses.cs:5:13:5:25 | String s = ... | TypeAccesses.cs:6:9:6:24 | ...; | semmle.label | successor |
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче