mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Merge rc/1.18 into next.
This commit is contained in:
@@ -1,40 +1,28 @@
|
||||
# Improvements to C/C++ analysis
|
||||
|
||||
## General improvements
|
||||
|
||||
> Changes that affect alerts in many files or from many queries
|
||||
> For example, changes to file classification
|
||||
|
||||
## New queries
|
||||
|
||||
| **Query** | **Tags** | **Purpose** |
|
||||
|-----------------------------|-----------|--------------------------------------------------------------------|
|
||||
| Upcast array used in pointer arithmetic | reliability, correctness, external/cwe/cwe-119 | Finds undefined behavior caused by doing pointer arithmetic on an array of objects that has been cast to an array of a supertype. |
|
||||
| Upcast array used in pointer arithmetic (`cpp/upcast-array-pointer-arithmetic`) | reliability, correctness, external/cwe/cwe-119 | Finds undefined behavior caused by doing pointer arithmetic on an array of objects that has been cast to an array of a supertype. |
|
||||
|
||||
## Changes to existing queries
|
||||
|
||||
| **Query** | **Expected impact** | **Change** |
|
||||
|----------------------------|------------------------|------------------------------------------------------------------|
|
||||
| Self comparison | Fewer false positive results | Range checks of the form `x == (T)x` are no longer flagged unless they are guaranteed to have the same result on all platforms. |
|
||||
| [Nested loops with same variable] | Fewer false positive results | Results where the loop variable is a member of a class or struct now account for the object. |
|
||||
| [For loop variable changed in body] | Fewer false positive results | Results where the loop variable is a member of a class or struct now account for the object. |
|
||||
| [Local variable hides global variable] | Fewer false positive results | Results for parameters are now only reported if the name of the global variable is the same as the name of the parameter as used in the function definition (not just a function declaration). |
|
||||
| [Memory may not be freed] | More correct results | This query now models calls to `realloc` more accurately. |
|
||||
| Wrong number of arguments to formatting function | Fewer false positive results | Some false positives related to custom printf-like functions have been fixed. |
|
||||
| Wrong number of arguments to formatting function | Clear separation between results of high and low severity | This query has been split into two queries: a high-severity query named [Too few arguments to formatting function] and a low-severity query named [Too many arguments to formatting function]. |
|
||||
| [Too few arguments to formatting function] | More correct and fewer false positives results | This query now understands positional format arguments as supported by some libraries. |
|
||||
| [Too many arguments to formatting function] | More correct and fewer false positives results | This query now understands positional format arguments as supported by some libraries. |
|
||||
| [Variable used in its own initializer] | Fewer false positive results | Results where a macro is used to indicate deliberate uninitialization are now excluded |
|
||||
| [Assignment where comparison was intended] | Fewer false positive results | Results are no longer reported if the variable is not yet defined. |
|
||||
| [Comparison where assignment was intended] | More correct results | "This query now includes results where an overloaded `operator==` is used in the wrong context. |
|
||||
| [User-controlled data in arithmetic expression] | More correct results | Increment / decrement / addition assignment / subtraction assignment operations are now understood as arithmetic operations in this query. |
|
||||
| [Uncontrolled data in arithmetic expression] | More correct results | Increment / decrement / addition assignment / subtraction assignment operations are now understood as arithmetic operations in this query. |
|
||||
| [Use of extreme values in arithmetic expression] | More correct results | Increment / decrement / addition assignment / subtraction assignment operations are now understood as arithmetic operations in this query. |
|
||||
| [Use of extreme values in arithmetic expression] | Fewer false positives | The query now considers whether a particular expression might cause an overflow of minimum or maximum values only. |
|
||||
| Assignment where comparison was intended (`cpp/assign-where-compare-meant`) | Fewer false positive results | Results are no longer reported if the variable is not yet defined. |
|
||||
| Comparison where assignment was intended (`cpp/compare-where-assign-meant`) | More results | This query now includes results where an overloaded `operator==` is used in the wrong context. |
|
||||
| For loop variable changed in body (`cpp/loop-variable-changed`) | Fewer false positive results | Results where the loop variable is a member of a class or struct now account for the object. |
|
||||
| Local variable hides global variable (`cpp/local-variable-hides-global-variable`) | Fewer false positive results | Results for parameters are now only reported if the name of the global variable is the same as the name of the parameter as used in the function definition (not just a function declaration). |
|
||||
| Nested loops with same variable (`cpp/nested-loops-with-same-variable`) | Fewer false positive results | Results where the loop variable is a member of a class or struct now account for the object. |
|
||||
| Self comparison (`cpp/comparison-of-identical-expressions`) | Fewer false positive results | Range checks of the form `x == (T)x` are no longer flagged unless they are guaranteed to have the same result on all platforms. |
|
||||
| Too few arguments to formatting function (`cpp/wrong-number-format-arguments`) | More precise results | This was previously known as "Wrong number of arguments to formatting function". It now focuses only on functions calls that are missing arguments, which tend to be more severe. See the next row for the new query that reports lower-severity alerts for calls with too many arguments. In addition, both queries now understand positional format arguments as supported by some libraries, and some false positive results for custom printf-like functions have been fixed.|
|
||||
| Too many arguments to formatting function (`cpp/too-many-format-arguments`) | More precise results | This new query was created by splitting the old "Wrong number of arguments to formatting function" query (see row above). It reports function calls with too many arguments. |
|
||||
| User-controlled data in arithmetic expression (`cpp/tainted-arithmetic`) | More results | The query is extended to analyze increment, decrement, addition-assignment, and subtraction-assignment operations. |
|
||||
| Variable used in its own initializer (`cpp/use-in-own-initializer`) | Fewer false positive results | Results where a macro is used to indicate deliberate uninitialization are now excluded. |
|
||||
|Uncontrolled data in arithmetic expression (`cpp/uncontrolled-arithmetic`) | More results | The query is extended to analyze increment, decrement, addition-assignment, and subtraction-assignment operations. |
|
||||
|
||||
## Changes to QL libraries
|
||||
|
||||
* Fixes for aggregate initializers using designators:
|
||||
* `ClassAggregateLiteral.getFieldExpr()` previously assumed initializer expressions appeared in the same order as the declaration order of the fields, causing it to associate the expressions with the wrong fields when using designated initializers. This has been fixed.
|
||||
* `ArrayAggregateLiteral.getElementExpr()` previously assumed initializer expressions appeared in the same order as the corresponding array elements, causing it to associate the expressions with the wrong array elements when using designated initializers. This has been fixed.
|
||||
* `Element.getEnclosingElement()` no longer includes macro accesses in its results. To explore parents and children of macro accesses, use the relevant member predicates on `MacroAccess` or `MacroInvocation`.
|
||||
* The `ClassAggregateLiteral.getFieldExpr()` and `ArrayAggregateLiteral.getElementExpr()` predicates incorrectly assumed that initializer expressions appeared in the same order as the declaration order of the elements. This resulted in the association of the expressions with the wrong elements when designated initializers were used. This has been fixed.
|
||||
* Results for the `Element.getEnclosingElement()` predicate no longer included macro accesses. To explore parents and children of macro accesses, use the relevant member predicates on `MacroAccess` or `MacroInvocation`.
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
# Improvements to C# analysis
|
||||
|
||||
> NOTES
|
||||
>
|
||||
> Please describe your changes in terms that are suitable for
|
||||
> customers to read. These notes will have only minor tidying up
|
||||
> before they are published as part of the release notes.
|
||||
|
||||
## General improvements
|
||||
|
||||
* Control flow analysis has been improved for `catch` clauses with filters.
|
||||
@@ -14,30 +8,53 @@
|
||||
|
||||
| **Query** | **Tags** | **Purpose** |
|
||||
|-----------------------------|-----------|--------------------------------------------------------------------|
|
||||
| Arbitrary file write during zip extraction ("Zip Slip") (`cs/zipslip`) | security, external/cwe/cwe-022 | Identifies zip extraction routines which allow arbitrary file overwrite vulnerabilities.
|
||||
| Arbitrary file write during zip extraction ("Zip Slip") (`cs/zipslip`) | security, external/cwe/cwe-022 | Identifies zip extraction routines which allow arbitrary file overwrite vulnerabilities. |
|
||||
| Local scope variable shadows member (`cs/local-shadows-member`) | maintainability, readability | Replaces the existing queries Local variable shadows class member (`cs/local-shadows-class-member`), Local variable shadows struct member (`cs/local-shadows-struct-member`), Parameter shadows class member (`cs/parameter-shadows-class-member`), and Parameter shadows struct member (`cs/parameter-shadows-struct-member`). |
|
||||
|
||||
## Changes to existing queries
|
||||
|
||||
| **Query** | **Expected impact** | **Change** |
|
||||
|----------------------------|------------------------|------------------------------------------------------------------|
|
||||
| [Constant condition](https://help.semmle.com/wiki/display/CSHARP/Constant+condition) (`cs/constant-condition`) | More results | The query has been generalized to cover both Null-coalescing left operand is constant (`cs/constant-null-coalescing`) and Switch selector is constant (`cs/constant-switch-selector`). |
|
||||
| Constant condition (`cs/constant-condition`) | More results | The query has been generalized to report alerts for the old queries Null-coalescing left operand is constant (`cs/constant-null-coalescing`) and Switch selector is constant (`cs/constant-switch-selector`). |
|
||||
| Exposing internal representation (`cs/expose-implementation`) | Different results | The query has been rewritten, based on the [equivalent Java query](https://help.semmle.com/wiki/display/JAVA/Exposing+internal+representation). |
|
||||
| Local variable shadows class member(`cs/local-shadows-class-member`) | No results | The query has been replaced by Local scope variable shadows member (`cs/local-shadows-member`). |
|
||||
| Local variable shadows struct member (`cs/local-shadows-struct-member`) | No results | The query has been replaced by Local scope variable shadows member (`cs/local-shadows-member`). |
|
||||
| [Missing Dispose call on local IDisposable](https://help.semmle.com/wiki/display/CSHARP/Missing+Dispose+call+on+local+IDisposable) (`cs/local-not-disposed`) | Fewer results | The query identifies more cases where the local variable may be disposed by a library call. |
|
||||
| [Nested loops with same variable](https://help.semmle.com/wiki/display/CSHARP/Nested+loops+with+same+variable) (`cs/nested-loops-with-same-variable`) | Fewer results | Results are no longer highlighted in nested loops that share the same condition, and do not use the variable after the inner loop. |
|
||||
| Null-coalescing left operand is constant (`cs/constant-null-coalescing`) | No results | The query has been removed, as it is now covered by Constant condition (`cs/constant-condition`). |
|
||||
| Parameter shadows class member (`cs/parameter-shadows-class-member`) | No results | The query has been replaced by Local scope variable shadows member (`cs/local-shadows-member`). |
|
||||
| Parameter shadows struct member (`cs/parameter-shadows-struct-member`) | No results | The query has been replaced by Local scope variable shadows member (`cs/local-shadows-member`). |
|
||||
| [Potentially incorrect CompareTo(...) signature](https://help.semmle.com/wiki/display/CSHARP/Potentially+incorrect+CompareTo%28...%29+signature) (`cs/wrong-compareto-signature`) | Fewer results | Results are no longer highlighted in constructed types. |
|
||||
| Switch selector is constant (`cs/constant-switch-selector`) | No results | The query has been removed, as it is now covered by Constant condition (`cs/constant-condition`). |
|
||||
| [Useless upcast](https://help.semmle.com/wiki/display/CSHARP/Useless+upcast) (`cs/useless-upcast`) | Fewer results | The query has been improved to cover more cases where upcasts may be needed. |
|
||||
| Local variable shadows class member (`cs/local-shadows-class-member`) | No results | The query has been replaced by the new query: Local scope variable shadows member (`cs/local-shadows-member`). |
|
||||
| Local variable shadows struct member (`cs/local-shadows-struct-member`) | No results | The query has been replaced by the new query: Local scope variable shadows member (`cs/local-shadows-member`). |
|
||||
| Missing Dispose call on local IDisposable (`cs/local-not-disposed`) | Fewer false positive results | The query identifies more cases where the local variable may be disposed by a library call. |
|
||||
| Nested loops with same variable (`cs/nested-loops-with-same-variable`) | Fewer false positive results | Results are no longer highlighted in nested loops that share the same condition, and do not use the variable after the inner loop. |
|
||||
| Null-coalescing left operand is constant (`cs/constant-null-coalescing`) | No results | The query has been removed, as alerts for this problem are now reported by the new query: Constant condition (`cs/constant-condition`). |
|
||||
| Parameter shadows class member (`cs/parameter-shadows-class-member`) | No results | The query has been replaced by the new query: Local scope variable shadows member (`cs/local-shadows-member`). |
|
||||
| Parameter shadows struct member (`cs/parameter-shadows-struct-member`) | No results | The query has been replaced by the new query: Local scope variable shadows member (`cs/local-shadows-member`). |
|
||||
| Potentially incorrect CompareTo(...) signature (`cs/wrong-compareto-signature`) | Fewer false positive results | Results are no longer highlighted in constructed types. |
|
||||
| Switch selector is constant (`cs/constant-switch-selector`) | No results | The query has been removed, as alerts for this problem are now reported by the new query: Constant condition (`cs/constant-condition`). |
|
||||
| Useless upcast (`cs/useless-upcast`) | Fewer false positive results | The query has been improved to cover more cases where upcasts may be needed. |
|
||||
|
||||
## Changes to code extraction
|
||||
|
||||
* *Series of bullet points*
|
||||
* The `into` part of `join` clauses is now extracted.
|
||||
* The `when` part of constant cases is now extracted.
|
||||
* Fixed a bug where `while(x is T y) ...` was not extracted correctly.
|
||||
|
||||
## Changes to QL libraries
|
||||
|
||||
* A new non-member predicate `mayBeDisposed()` can be used to determine if a variable is potentially disposed inside a library. It will analyse the CIL code in the library to determine this.
|
||||
* A new non-member predicate `mayBeDisposed()` can be used to determine if a variable is potentially disposed inside a library. It will analyze the CIL code in the library to determine this.
|
||||
* The predicate `getCondition()` has been moved from `TypeCase` to `CaseStmt`. It is now possible to get the condition of a `ConstCase` using its `getCondition()` predicate.
|
||||
* Several control flow graph entities have been renamed (the old names are deprecated but are still available in this release for backwards compatibility):
|
||||
- `ControlFlowNode` has been renamed to `ControlFlow::Node`.
|
||||
- `CallableEntryNode` has been renamed to `ControlFlow::Nodes::EntryNode`.
|
||||
- `CallableExitNode` has been renamed to `ControlFlow::Nodes::ExitNode`.
|
||||
- `ControlFlowEdgeType` has been renamed to `ControlFlow::SuccessorType`.
|
||||
- `ControlFlowEdgeSuccessor` has been renamed to `ControlFlow::SuccessorTypes::NormalSuccessor`.
|
||||
- `ControlFlowEdgeConditional` has been renamed to `ControlFlow::SuccessorTypes::ConditionalSuccessor`.
|
||||
- `ControlFlowEdgeBoolean` has been renamed to `ControlFlow::SuccessorTypes::BooleanSuccessor`.
|
||||
- `ControlFlowEdgeNullness` has been renamed to `ControlFlow::SuccessorTypes::NullnessSuccessor`.
|
||||
- `ControlFlowEdgeMatching` has been renamed to `ControlFlow::SuccessorTypes::MatchingSuccessor`.
|
||||
- `ControlFlowEdgeEmptiness` has been renamed to `ControlFlow::SuccessorTypes::EmptinessSuccessor`.
|
||||
- `ControlFlowEdgeReturn` has been renamed to `ControlFlow::SuccessorTypes::ReturnSuccessor`.
|
||||
- `ControlFlowEdgeBreak` has been renamed to `ControlFlow::SuccessorTypes::BreakSuccessor`.
|
||||
- `ControlFlowEdgeContinue` has been renamed to `ControlFlow::SuccessorTypes::ContinueSuccessor`.
|
||||
- `ControlFlowEdgeGotoLabel` has been renamed to `ControlFlow::SuccessorTypes::GotoLabelSuccessor`.
|
||||
- `ControlFlowEdgeGotoCase` has been renamed to `ControlFlow::SuccessorTypes::GotoCaseSuccessor`.
|
||||
- `ControlFlowEdgeGotoDefault` has been renamed to `ControlFlow::SuccessorTypes::GotoDefaultSuccessor`.
|
||||
- `ControlFlowEdgeException` has been renamed to `ControlFlow::SuccessorTypes::ExceptionSuccessor`.
|
||||
|
||||
> You should update any custom queries that use these entities to ensure that they continue working when the old names are removed in a future release.
|
||||
|
||||
@@ -2,15 +2,13 @@
|
||||
|
||||
## General improvements
|
||||
|
||||
* Additional heuristics have been added to `semmle.javascript.heuristics`. Add `import semmle.javascript.heuristics.all` to a query in order to activate all of the heuristics at once.
|
||||
* Improved modeling of data flow through destructuring assignments may give additional results for the security queries and other queries that rely on data flow.
|
||||
|
||||
* Modelling of data flow through destructuring assignments has been improved. This may give additional results for the security queries and other queries that rely on data flow.
|
||||
* Improved modeling of global variables may give more true-positive results and fewer false-positive results for a variety of queries.
|
||||
|
||||
* Modelling of global variables has been improved. This may give more true-positive results and fewer false-positive results for a variety of queries.
|
||||
* Improved modeling of re-export declarations may result in fewer false-positive results for a variety of queries.
|
||||
|
||||
* Modelling of re-export declarations has been improved. This may result in fewer false-positive results for a variety of queries.
|
||||
|
||||
* Modelling of taint flow through array operations has been improved. This may give additional results for the security queries.
|
||||
* Improved modeling of taint flow through array operations may give additional results for the security queries.
|
||||
|
||||
* The taint tracking library recognizes more ways in which taint propagates. In particular, some flow through string formatters is now recognized. This may give additional results for the security queries.
|
||||
|
||||
@@ -18,74 +16,86 @@
|
||||
|
||||
* Type inference for simple function calls has been improved. This may give additional results for queries that rely on type inference.
|
||||
|
||||
* Support for popular libraries has been improved. Consequently, queries may produce more results on code bases that use the following libraries:
|
||||
- [bluebird](https://bluebirdjs.com)
|
||||
- [browserid-crypto](https://github.com/mozilla/browserid-crypto)
|
||||
- [compose-function](https://github.com/stoeffel/compose-function)
|
||||
- [cookie-parser](https://github.com/expressjs/cookie-parser)
|
||||
- [cookie-session](https://github.com/expressjs/cookie-session)
|
||||
- [crypto-js](https://github.com/https://github.com/brix/crypto-js)
|
||||
- [deep-assign](https://github.com/sindresorhus/deep-assign)
|
||||
- [deep-extend](https://github.com/unclechu/node-deep-extend)
|
||||
- [deep-merge](https://github.com/Raynos/deep-merge)
|
||||
- [deep](https://github.com/jeffomatic/deep)
|
||||
- [deepmerge](https://github.com/KyleAMathews/deepmerge)
|
||||
- [defaults-deep](https://github.com/jonschlinkert/defaults-deep)
|
||||
- [defaults](https://github.com/tmpvar/defaults)
|
||||
- [dottie](https://github.com/mickhansen/dottie.js)
|
||||
- [dotty](https://github.com/deoxxa/dotty)
|
||||
- [ent](https://github.com/substack/node-ent)
|
||||
- [entities](https://github.com/fb55/node-entities)
|
||||
- [escape-goat](https://github.com/sindresorhus/escape-goat)
|
||||
- [express-jwt](https://github.com/auth0/express-jwt)
|
||||
- [express-session](https://github.com/expressjs/session)
|
||||
- [extend-shallow](https://github.com/jonschlinkert/extend-shallow)
|
||||
- [extend](https://github.com/justmoon/node-extend)
|
||||
- [extend2](https://github.com/eggjs/extend2)
|
||||
- [fast-json-parse](https://github.com/mcollina/fast-json-parse)
|
||||
- [forge](https://github.com/digitalbazaar/forge)
|
||||
- [format-util](https://github.com/tmpfs/format-util)
|
||||
- [global](https://github.com/Raynos/global)
|
||||
- [he](https://github.com/mathiasbynens/he)
|
||||
- [html-entities](https://github.com/mdevils/node-html-entities)
|
||||
- [jquery](https://jquery.com)
|
||||
- [js-extend](https://github.com/vmattos/js-extend)
|
||||
- [json-parse-better-errors](https://github.com/zkat/json-parse-better-errors)
|
||||
- [json-parse-safe](https://github.com/joaquimserafim/json-parse-safe)
|
||||
- [json-safe-parse](https://github.com/bahamas10/node-json-safe-parse)
|
||||
- [just-compose](https://github.com/angus-c/just)
|
||||
- [just-extend](https://github.com/angus-c/just)
|
||||
- [lodash](https://lodash.com)
|
||||
- [merge-deep](https://github.com/jonschlinkert/merge-deep)
|
||||
- [merge-options](https://github.com/schnittstabil/merge-options)
|
||||
- [merge](https://github.com/yeikos/js.merge)
|
||||
- [mixin-deep](https://github.com/jonschlinkert/mixin-deep)
|
||||
- [mixin-object](https://github.com/jonschlinkert/mixin-object)
|
||||
- [MySQL2](https://github.com/sidorares/node-mysql2)
|
||||
- [node.extend](https://github.com/dreamerslab/node.extend)
|
||||
- [object-assign](https://github.com/sindresorhus/object-assign)
|
||||
- [object.assign](https://github.com/ljharb/object.assign)
|
||||
- [object.defaults](https://github.com/jonschlinkert/object.defaults)
|
||||
- [parse-json](https://github.com/sindresorhus/parse-json)
|
||||
- [printf](https://github.com/adaltas/node-printf)
|
||||
- [printj](https://github.com/SheetJS/printj)
|
||||
- [q](https://documentup.com/kriskowal/q/)
|
||||
- [ramda](https://ramdajs.com)
|
||||
- [React Native](https://facebook.github.io/react-native/)
|
||||
- [safe-json-parse](https://github.com/Raynos/safe-json-parse)
|
||||
- [sanitize](https://github.com/pocketly/node-sanitize)
|
||||
- [sanitizer](https://github.com/theSmaw/Caja-HTML-Sanitizer)
|
||||
- [smart-extend](https://github.com/danielkalen/smart-extend)
|
||||
- [sprintf.js](https://github.com/alexei/sprintf.js)
|
||||
- [string-template](https://github.com/Matt-Esch/string-template)
|
||||
- [underscore](https://underscorejs.org)
|
||||
- [util-extend](https://github.com/isaacs/util-extend)
|
||||
- [utils-merge](https://github.com/jaredhanson/utils-merge)
|
||||
- [validator](https://github.com/chriso/validator.js)
|
||||
- [xss](https://github.com/leizongmin/js-xss)
|
||||
- [xtend](https://github.com/Raynos/xtend)
|
||||
* Additional heuristics have been added to `semmle.javascript.heuristics`. Add `import semmle.javascript.heuristics.all` to a query in order to activate all of the heuristics at once.
|
||||
|
||||
* Handling of ambient TypeScript code has been improved. As a result, fewer false positives will be reported in `.d.ts` files.
|
||||
* Handling of ambient TypeScript code has been improved. As a result, fewer false-positive results will be reported in `.d.ts` files.
|
||||
|
||||
* Support for popular libraries has been improved. Consequently, queries may produce more results on code bases that use the following libraries:
|
||||
[axios](https://github.com/axios/axios),
|
||||
[bluebird](https://bluebirdjs.com),
|
||||
[browserid-crypto](https://github.com/mozilla/browserid-crypto),
|
||||
[compose-function](https://github.com/stoeffel/compose-function),
|
||||
[cookie-parser](https://github.com/expressjs/cookie-parser),
|
||||
[cookie-session](https://github.com/expressjs/cookie-session),
|
||||
[cross-fetch](https://github.com/lquixada/cross-fetch),
|
||||
[crypto-js](https://github.com/https://github.com/brix/crypto-js),
|
||||
[deep-assign](https://github.com/sindresorhus/deep-assign),
|
||||
[deep-extend](https://github.com/unclechu/node-deep-extend),
|
||||
[deep-merge](https://github.com/Raynos/deep-merge),
|
||||
[deep](https://github.com/jeffomatic/deep),
|
||||
[deepmerge](https://github.com/KyleAMathews/deepmerge),
|
||||
[defaults-deep](https://github.com/jonschlinkert/defaults-deep),
|
||||
[defaults](https://github.com/tmpvar/defaults),
|
||||
[dottie](https://github.com/mickhansen/dottie.js),
|
||||
[dotty](https://github.com/deoxxa/dotty),
|
||||
[ent](https://github.com/substack/node-ent),
|
||||
[entities](https://github.com/fb55/node-entities),
|
||||
[escape-goat](https://github.com/sindresorhus/escape-goat),
|
||||
[express-jwt](https://github.com/auth0/express-jwt),
|
||||
[express-session](https://github.com/expressjs/session),
|
||||
[extend-shallow](https://github.com/jonschlinkert/extend-shallow),
|
||||
[extend](https://github.com/justmoon/node-extend),
|
||||
[extend2](https://github.com/eggjs/extend2),
|
||||
[fast-json-parse](https://github.com/mcollina/fast-json-parse),
|
||||
[forge](https://github.com/digitalbazaar/forge),
|
||||
[format-util](https://github.com/tmpfs/format-util),
|
||||
[got](https://github.com/sindresorhus/got),
|
||||
[global](https://github.com/Raynos/global),
|
||||
[he](https://github.com/mathiasbynens/he),
|
||||
[html-entities](https://github.com/mdevils/node-html-entities),
|
||||
[isomorphic-fetch](https://github.com/matthew-andrews/isomorphic-fetch),
|
||||
[jquery](https://jquery.com),
|
||||
[js-extend](https://github.com/vmattos/js-extend),
|
||||
[json-parse-better-errors](https://github.com/zkat/json-parse-better-errors),
|
||||
[json-parse-safe](https://github.com/joaquimserafim/json-parse-safe),
|
||||
[json-safe-parse](https://github.com/bahamas10/node-json-safe-parse),
|
||||
[just-compose](https://github.com/angus-c/just),
|
||||
[just-extend](https://github.com/angus-c/just),
|
||||
[lodash](https://lodash.com),
|
||||
[merge-deep](https://github.com/jonschlinkert/merge-deep),
|
||||
[merge-options](https://github.com/schnittstabil/merge-options),
|
||||
[merge](https://github.com/yeikos/js.merge),
|
||||
[mixin-deep](https://github.com/jonschlinkert/mixin-deep),
|
||||
[mixin-object](https://github.com/jonschlinkert/mixin-object),
|
||||
[MySQL2](https://github.com/sidorares/node-mysql2),
|
||||
[node.extend](https://github.com/dreamerslab/node.extend),
|
||||
[node-fetch](https://github.com/bitinn/node-fetch),
|
||||
[object-assign](https://github.com/sindresorhus/object-assign),
|
||||
[object.assign](https://github.com/ljharb/object.assign),
|
||||
[object.defaults](https://github.com/jonschlinkert/object.defaults),
|
||||
[parse-json](https://github.com/sindresorhus/parse-json),
|
||||
[printf](https://github.com/adaltas/node-printf),
|
||||
[printj](https://github.com/SheetJS/printj),
|
||||
[q](https://documentup.com/kriskowal/q/),
|
||||
[ramda](https://ramdajs.com),
|
||||
[request](https://github.com/request/request),
|
||||
[request-promise](https://github.com/request/request-promise),
|
||||
[request-promise-any](https://github.com/request/request-promise-any),
|
||||
[request-promise-native](https://github.com/request/request-promise-native),
|
||||
[React Native](https://facebook.github.io/react-native/),
|
||||
[safe-json-parse](https://github.com/Raynos/safe-json-parse),
|
||||
[sanitize](https://github.com/pocketly/node-sanitize),
|
||||
[sanitizer](https://github.com/theSmaw/Caja-HTML-Sanitizer),
|
||||
[smart-extend](https://github.com/danielkalen/smart-extend),
|
||||
[sprintf.js](https://github.com/alexei/sprintf.js),
|
||||
[string-template](https://github.com/Matt-Esch/string-template),
|
||||
[superagent](https://github.com/visionmedia/superagent),
|
||||
[underscore](https://underscorejs.org),
|
||||
[util-extend](https://github.com/isaacs/util-extend),
|
||||
[utils-merge](https://github.com/jaredhanson/utils-merge),
|
||||
[validator](https://github.com/chriso/validator.js),
|
||||
[xss](https://github.com/leizongmin/js-xss),
|
||||
[xtend](https://github.com/Raynos/xtend).
|
||||
|
||||
## New queries
|
||||
|
||||
@@ -94,36 +104,36 @@
|
||||
| Clear-text logging of sensitive information (`js/clear-text-logging`) | security, external/cwe/cwe-312, external/cwe/cwe-315, external/cwe/cwe-359 | Highlights logging of sensitive information, indicating a violation of [CWE-312](https://cwe.mitre.org/data/definitions/312.html). Results shown on LGTM by default. |
|
||||
| Disabling Electron webSecurity (`js/disabling-electron-websecurity`) | security, frameworks/electron | Highlights Electron browser objects that are created with the `webSecurity` property set to false. Results shown on LGTM by default. |
|
||||
| Enabling Electron allowRunningInsecureContent (`js/enabling-electron-insecure-content`) | security, frameworks/electron | Highlights Electron browser objects that are created with the `allowRunningInsecureContent` property set to true. Results shown on LGTM by default. |
|
||||
| Uncontrolled data used in remote request (`js/request-forgery`) | security, external/cwe/cwe-918 | Highlights remote requests that are built from unsanitized user input, indicating a violation of [CWE-918](https://cwe.mitre.org/data/definitions/918.html). Results are hidden on LGTM by default. |
|
||||
| Use of externally-controlled format string (`js/tainted-format-string`) | security, external/cwe/cwe-134 | Highlights format strings containing user-provided data, indicating a violation of [CWE-134](https://cwe.mitre.org/data/definitions/134.html). Results shown on LGTM by default. |
|
||||
|
||||
## Changes to existing queries
|
||||
|
||||
| **Query** | **Expected impact** | **Change** |
|
||||
|----------------------------|------------------------|------------------------------------------------------------------|
|
||||
| Arguments redefined | Fewer results | This rule previously also flagged redefinitions of `eval`. This was an oversight that is now fixed. |
|
||||
| Comparison between inconvertible types | Fewer results | This rule now flags fewer comparisons involving parameters. |
|
||||
| Comparison between inconvertible types | Lower severity | The severity of this rule has been revised to "warning". |
|
||||
| CORS misconfiguration for credentials transfer | More true-positive results | This rule now treats header names case-insensitively. |
|
||||
| Hard-coded credentials | More true-positive results | This rule now recognizes secret cryptographic keys. |
|
||||
| Incomplete string escaping or encoding | Better name, more true-positive results | This rule has been renamed to more clearly reflect its purpose. Also, it now recognizes incomplete URL encoding and decoding. |
|
||||
| Insecure randomness | More true-positive results | This rule now recognizes secret cryptographic keys. |
|
||||
| Missing rate limiting | More true-positive results, fewer false-positive results | This rule now recognizes additional rate limiters and expensive route handlers. |
|
||||
| Missing X-Frame-Options HTTP header | Fewer false-positive results | This rule now treats header names case-insensitively. |
|
||||
| Reflected cross-site scripting | Fewer false-positive results | This rule now treats header names case-insensitively. |
|
||||
| Server-side URL redirect | More true-positive results | This rule now treats header names case-insensitively. |
|
||||
| Superfluous trailing arguments | Fewer false-positive results | This rule now ignores calls to some empty functions. |
|
||||
| Type confusion through parameter tampering | Fewer false-positive results | This rule no longer flags emptiness checks. |
|
||||
| Uncontrolled command line | More true-positive results | This rule now recognizes indirect command injection through `sh -c` and similar. |
|
||||
| Unused variable | Fewer results | This rule no longer flags class expressions that could be made anonymous. While technically true, these results are not interesting. |
|
||||
| Unused variable | Renamed | This rule has been renamed to "Unused variable, import, function or class" to reflect the fact that it flags different kinds of unused program elements. |
|
||||
| Use of incompletely initialized object| Fewer results | This rule now flags the constructor instead its errorneous `this` or `super` expressions. |
|
||||
| Useless conditional | Fewer results | This rule no longer flags uses of boolean return values. |
|
||||
| Useless conditional | Fewer results | This rule now flags fewer comparisons involving parameters. |
|
||||
| Arguments redefined (`js/arguments-redefinition`) | Fewer results | This query previously also flagged redefinitions of `eval`. This was an oversight that is now fixed. |
|
||||
| Comparison between inconvertible types (`js/comparison-between-incompatible-types`) | Fewer results | This query now flags fewer comparisons involving parameters. The severity of this query has been revised to "warning". |
|
||||
| CORS misconfiguration for credentials transfer (`js/cors-misconfiguration-for-credentials`) | More true-positive results | This query now treats header names case-insensitively. |
|
||||
| Hard-coded credentials (`js/hardcoded-credentials`) | More true-positive results | This query now recognizes secret cryptographic keys. |
|
||||
| Incomplete string escaping or encoding (`js/incomplete-sanitization`) | New name, more true-positive results | The "Incomplete sanitization" query has been renamed to more clearly reflect its purpose. It now recognizes incomplete URL encoding and decoding. |
|
||||
| Insecure randomness (`js/insecure-randomness`) | More true-positive results | This query now recognizes secret cryptographic keys. |
|
||||
| Misleading indentation after control statement (`js/misleading-indentation-after-control-statement`) | Fewer results | This query temporarily ignores TypeScript files. |
|
||||
| Missing rate limiting (`js/missing-rate-limiting`) | More true-positive results, fewer false-positive results | This query now recognizes additional rate limiters and expensive route handlers. |
|
||||
| Omitted array element (`js/omitted-array-element`)| Fewer results | This query temporarily ignores TypeScript files. |
|
||||
| Reflected cross-site scripting (`js/reflected-xss`) | Fewer false-positive results | This query now treats header names case-insensitively. |
|
||||
| Semicolon insertion (`js/automatic-semicolon-insertion`) | Fewer results | This query temporarily ignores TypeScript files. |
|
||||
| Server-side URL redirect (`js/server-side-unvalidated-url-redirection`) | More true-positive results | This query now treats header names case-insensitively. |
|
||||
| Superfluous trailing arguments (`js/superfluous-trailing-arguments`) | Fewer false-positive results | This query now ignores calls to some empty functions. |
|
||||
| Type confusion through parameter tampering (`js/type-confusion-through-parameter-tampering`) | Fewer false-positive results | This query no longer flags emptiness checks. |
|
||||
| Uncontrolled command line (`js/command-line-injection`) | More true-positive results | This query now recognizes indirect command injection through `sh -c` and similar. |
|
||||
| Unused variable, import, function or class (`js/unused-local-variable`) | New name, fewer results | The "Unused variable" query has been renamed to reflect the fact that it highlights different kinds of unused program elements. In addition, the query no longer highlights class expressions that could be made anonymous. While technically true, these results are not interesting. |
|
||||
| Use of incompletely initialized object (`js/incomplete-object-initialization`) | Fewer results | This query now highlights the constructor instead of its erroneous `this` or `super` expressions. |
|
||||
| Useless conditional (`js/trivial-conditional`) | Fewer results | This query no longer flags uses of boolean return values and highlights fewer comparisons involving parameters. |
|
||||
|
||||
## Changes to QL libraries
|
||||
|
||||
* HTTP and HTTPS requests made using the Node.js `http.request` and `https.request` APIs and the Electron `Electron.net.request` and `Electron.ClientRequest` APIs are modeled as `RemoteFlowSources`.
|
||||
* HTTP header names are now always normalized to lower case to reflect the fact that they are case insensitive. In particular, the result of `HeaderDefinition.getAHeaderName`, and the first parameter of `HeaderDefinition.defines`, `ExplicitHeaderDefinition.definesExplicitly` and `RouteHandler.getAResponseHeader` is now always a lower-case string.
|
||||
* HTTP and HTTPS requests made using the Node.js `http.request` and `https.request` APIs, and the Electron `Electron.net.request` and `Electron.ClientRequest` APIs, are modeled as `RemoteFlowSources`.
|
||||
* HTTP header names are now always normalized to lower case to reflect the fact that they are case insensitive. In particular, the result of `HeaderDefinition.getAHeaderName`, and the first parameter of `HeaderDefinition.defines`, `ExplicitHeaderDefinition.definesExplicitly`, and `RouteHandler.getAResponseHeader` are now always a lower-case string.
|
||||
* New AST nodes have been added for TypeScript 2.9 and 3.0 features.
|
||||
* The class `JsonParseCall` has been deprecated. Use `JsonParserCall` instead.
|
||||
* The class `JsonParseCall` has been deprecated. Update your queries to use `JsonParserCall` instead.
|
||||
* The handling of spread arguments in the data flow library has been changed: `DataFlow::InvokeNode.getArgument(i)` is now only defined when there is no spread argument at or before argument position `i`, and similarly `InvokeNode.getNumArgument` is only defined for invocations without spread arguments.
|
||||
|
||||
@@ -602,7 +602,7 @@ class ReturnValueInstruction extends ReturnInstruction {
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
|
||||
tag instanceof ReturnValueOperand and
|
||||
exists(this.getOperand(tag.(ReturnValueOperand))) and
|
||||
result instanceof IndirectMemoryAccess
|
||||
}
|
||||
}
|
||||
@@ -629,7 +629,7 @@ class LoadInstruction extends CopyInstruction {
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
|
||||
tag instanceof CopySourceOperand and
|
||||
exists(this.getOperand(tag.(CopySourceOperand))) and
|
||||
result instanceof IndirectMemoryAccess
|
||||
}
|
||||
|
||||
@@ -1015,7 +1015,7 @@ class ThrowValueInstruction extends ThrowInstruction {
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
|
||||
tag instanceof ExceptionOperand and
|
||||
exists(this.getOperand(tag.(ExceptionOperand))) and
|
||||
result instanceof IndirectMemoryAccess
|
||||
}
|
||||
|
||||
@@ -1114,7 +1114,7 @@ class UnmodeledUseInstruction extends Instruction {
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
|
||||
tag instanceof UnmodeledUseOperand and
|
||||
exists(this.getOperand(tag.(UnmodeledUseOperand))) and
|
||||
result instanceof UnmodeledMemoryAccess
|
||||
}
|
||||
}
|
||||
@@ -1125,7 +1125,7 @@ class PhiInstruction extends Instruction {
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
|
||||
tag instanceof PhiOperand and
|
||||
exists(this.getOperand(tag.(PhiOperand))) and
|
||||
result instanceof PhiMemoryAccess
|
||||
}
|
||||
|
||||
|
||||
@@ -602,7 +602,7 @@ class ReturnValueInstruction extends ReturnInstruction {
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
|
||||
tag instanceof ReturnValueOperand and
|
||||
exists(this.getOperand(tag.(ReturnValueOperand))) and
|
||||
result instanceof IndirectMemoryAccess
|
||||
}
|
||||
}
|
||||
@@ -629,7 +629,7 @@ class LoadInstruction extends CopyInstruction {
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
|
||||
tag instanceof CopySourceOperand and
|
||||
exists(this.getOperand(tag.(CopySourceOperand))) and
|
||||
result instanceof IndirectMemoryAccess
|
||||
}
|
||||
|
||||
@@ -1015,7 +1015,7 @@ class ThrowValueInstruction extends ThrowInstruction {
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
|
||||
tag instanceof ExceptionOperand and
|
||||
exists(this.getOperand(tag.(ExceptionOperand))) and
|
||||
result instanceof IndirectMemoryAccess
|
||||
}
|
||||
|
||||
@@ -1114,7 +1114,7 @@ class UnmodeledUseInstruction extends Instruction {
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
|
||||
tag instanceof UnmodeledUseOperand and
|
||||
exists(this.getOperand(tag.(UnmodeledUseOperand))) and
|
||||
result instanceof UnmodeledMemoryAccess
|
||||
}
|
||||
}
|
||||
@@ -1125,7 +1125,7 @@ class PhiInstruction extends Instruction {
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
|
||||
tag instanceof PhiOperand and
|
||||
exists(this.getOperand(tag.(PhiOperand))) and
|
||||
result instanceof PhiMemoryAccess
|
||||
}
|
||||
|
||||
|
||||
@@ -602,7 +602,7 @@ class ReturnValueInstruction extends ReturnInstruction {
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
|
||||
tag instanceof ReturnValueOperand and
|
||||
exists(this.getOperand(tag.(ReturnValueOperand))) and
|
||||
result instanceof IndirectMemoryAccess
|
||||
}
|
||||
}
|
||||
@@ -629,7 +629,7 @@ class LoadInstruction extends CopyInstruction {
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
|
||||
tag instanceof CopySourceOperand and
|
||||
exists(this.getOperand(tag.(CopySourceOperand))) and
|
||||
result instanceof IndirectMemoryAccess
|
||||
}
|
||||
|
||||
@@ -1015,7 +1015,7 @@ class ThrowValueInstruction extends ThrowInstruction {
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
|
||||
tag instanceof ExceptionOperand and
|
||||
exists(this.getOperand(tag.(ExceptionOperand))) and
|
||||
result instanceof IndirectMemoryAccess
|
||||
}
|
||||
|
||||
@@ -1114,7 +1114,7 @@ class UnmodeledUseInstruction extends Instruction {
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
|
||||
tag instanceof UnmodeledUseOperand and
|
||||
exists(this.getOperand(tag.(UnmodeledUseOperand))) and
|
||||
result instanceof UnmodeledMemoryAccess
|
||||
}
|
||||
}
|
||||
@@ -1125,7 +1125,7 @@ class PhiInstruction extends Instruction {
|
||||
}
|
||||
|
||||
override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
|
||||
tag instanceof PhiOperand and
|
||||
exists(this.getOperand(tag.(PhiOperand))) and
|
||||
result instanceof PhiMemoryAccess
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ private import semmle.code.csharp.frameworks.system.web.UI
|
||||
|
||||
class DisposableType extends RefType {
|
||||
DisposableType() {
|
||||
this.getABaseType+() = getSystemIDisposableInterface()
|
||||
this.getABaseType+() instanceof SystemIDisposableInterface
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,13 +17,13 @@ class DisposableField extends Field {
|
||||
|
||||
class WebControl extends RefType {
|
||||
WebControl() {
|
||||
this.getBaseClass*() = getSystemWebUIControlClass()
|
||||
this.getBaseClass*() instanceof SystemWebUIControlClass
|
||||
}
|
||||
}
|
||||
|
||||
class WebPage extends RefType {
|
||||
WebPage() {
|
||||
this.getBaseClass*() = getSystemWebUIPageClass()
|
||||
this.getBaseClass*() instanceof SystemWebUIPageClass
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.commons.Assertions
|
||||
import semmle.code.csharp.commons.Constants
|
||||
import ControlFlowGraph
|
||||
|
||||
/** A constant condition. */
|
||||
abstract class ConstantCondition extends Expr {
|
||||
@@ -76,13 +75,13 @@ class ConstantNullnessCondition extends ConstantCondition {
|
||||
boolean b;
|
||||
|
||||
ConstantNullnessCondition() {
|
||||
forex(ControlFlowNode cfn |
|
||||
forex(ControlFlow::Node cfn |
|
||||
cfn = this.getAControlFlowNode() |
|
||||
exists(ControlFlowEdgeNullness t |
|
||||
exists(ControlFlow::SuccessorTypes::NullnessSuccessor t |
|
||||
exists(cfn.getASuccessorByType(t)) |
|
||||
if t.isNull() then b = true else b = false
|
||||
) and
|
||||
strictcount(ControlFlowEdgeType t | exists(cfn.getASuccessorByType(t))) = 1
|
||||
strictcount(ControlFlow::SuccessorType t | exists(cfn.getASuccessorByType(t))) = 1
|
||||
)
|
||||
}
|
||||
|
||||
@@ -99,13 +98,13 @@ class ConstantMatchingCondition extends ConstantCondition {
|
||||
boolean b;
|
||||
|
||||
ConstantMatchingCondition() {
|
||||
forex(ControlFlowNode cfn |
|
||||
forex(ControlFlow::Node cfn |
|
||||
cfn = this.getAControlFlowNode() |
|
||||
exists(ControlFlowEdgeMatching t |
|
||||
exists(ControlFlow::SuccessorTypes::MatchingSuccessor t |
|
||||
exists(cfn.getASuccessorByType(t)) |
|
||||
if t.isMatch() then b = true else b = false
|
||||
) and
|
||||
strictcount(ControlFlowEdgeType t | exists(cfn.getASuccessorByType(t))) = 1
|
||||
strictcount(ControlFlow::SuccessorType t | exists(cfn.getASuccessorByType(t))) = 1
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -35,5 +35,5 @@ class StringComparison extends Expr {
|
||||
from StringComparison sc, PropertyAccess pa
|
||||
where sc.getAnOperand() instanceof StringLiteral
|
||||
and sc.getAnOperand() = pa
|
||||
and pa.getTarget() = getSystemTypeClass().getFullNameProperty()
|
||||
and pa.getTarget() = any(SystemTypeClass c).getFullNameProperty()
|
||||
select sc, "Erroneous class compare."
|
||||
|
||||
@@ -102,17 +102,17 @@ class LockStmtBlock extends LockedBlock
|
||||
exists( LockStmt s | this=s.getBlock() )
|
||||
}
|
||||
|
||||
predicate isLockThis()
|
||||
override predicate isLockThis()
|
||||
{
|
||||
exists( LockStmt s | this=s.getBlock() and s.isLockThis() )
|
||||
}
|
||||
|
||||
Variable getLockVariable()
|
||||
override Variable getLockVariable()
|
||||
{
|
||||
exists( LockStmt s | this=s.getBlock() and result=s.getLockVariable() )
|
||||
}
|
||||
|
||||
Type getLockTypeObject()
|
||||
override Type getLockTypeObject()
|
||||
{
|
||||
exists( LockStmt s | this=s.getBlock() and result=s.getLockTypeObject() )
|
||||
}
|
||||
@@ -138,17 +138,17 @@ class SynchronizedMethodBlock extends LockedBlock
|
||||
{
|
||||
exists( SynchronizedMethod m | this=m.getStatementBody() )
|
||||
}
|
||||
predicate isLockThis()
|
||||
override predicate isLockThis()
|
||||
{
|
||||
exists( SynchronizedMethod m | this=m.getStatementBody() and m.isLockThis() )
|
||||
}
|
||||
|
||||
Variable getLockVariable()
|
||||
override Variable getLockVariable()
|
||||
{
|
||||
none()
|
||||
}
|
||||
|
||||
Type getLockTypeObject()
|
||||
override Type getLockTypeObject()
|
||||
{
|
||||
exists( SynchronizedMethod m | this=m.getStatementBody() and result=m.getLockTypeObject() )
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
import csharp
|
||||
import DataMembers
|
||||
import ThreadCreation
|
||||
import ControlFlowGraph
|
||||
|
||||
predicate correctlySynchronized(CollectionMember c, Expr access) {
|
||||
access = c.getAReadOrWrite() and
|
||||
@@ -24,9 +23,9 @@ predicate correctlySynchronized(CollectionMember c, Expr access) {
|
||||
)
|
||||
}
|
||||
|
||||
ControlFlowNode unlockedReachable(Callable a) {
|
||||
ControlFlow::Node unlockedReachable(Callable a) {
|
||||
result = a.getEntryPoint() or
|
||||
exists(ControlFlowNode mid | mid = unlockedReachable(a) |
|
||||
exists(ControlFlow::Node mid | mid = unlockedReachable(a) |
|
||||
not mid.getElement() instanceof LockingCall and
|
||||
result = mid.getASuccessor()
|
||||
)
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
|
||||
import csharp
|
||||
import semmle.code.csharp.commons.ComparisonTest
|
||||
import semmle.code.csharp.controlflow.ControlFlowGraph::ControlFlowGraph
|
||||
import semmle.code.csharp.commons.StructuralComparison as SC
|
||||
|
||||
/** A structural comparison configuration for comparing the conditions of nested `for` loops. */
|
||||
@@ -87,13 +86,13 @@ class NestedForLoopSameVariable extends ForStmt {
|
||||
}
|
||||
|
||||
/** Finds elements inside the outer loop that are no longer guarded by the loop invariant. */
|
||||
private ControlFlowNode getAnUnguardedNode()
|
||||
private ControlFlow::Node getAnUnguardedNode()
|
||||
{
|
||||
result.getElement().getParent+() = getOuterForStmt().getBody() and
|
||||
(
|
||||
result = this.getCondition().(ControlFlowElement).getAControlFlowExitNode().getAFalseSuccessor()
|
||||
or
|
||||
exists(ControlFlowNode mid | mid = getAnUnguardedNode() |
|
||||
exists(ControlFlow::Node mid | mid = getAnUnguardedNode() |
|
||||
mid.getASuccessor() = result and
|
||||
not exists(getAComparisonTest(result.getElement()))
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
import csharp
|
||||
|
||||
// Iterate the control flow until we reach a Stmt
|
||||
Stmt findSuccessorStmt(ControlFlowGraph::ControlFlowNode n)
|
||||
Stmt findSuccessorStmt(ControlFlow::Node n)
|
||||
{
|
||||
result=n.getElement() or
|
||||
not n.getElement() instanceof Stmt and result=findSuccessorStmt(n.getASuccessor())
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.frameworks.System
|
||||
|
||||
predicate nodeBeforeParameterAccess(ControlFlowGraph::ControlFlowNode node)
|
||||
predicate nodeBeforeParameterAccess(ControlFlow::Node node)
|
||||
{
|
||||
exists(EqualsMethod equals | equals.getBody() = node.getElement())
|
||||
or
|
||||
exists(EqualsMethod equals, Parameter param, ControlFlowGraph::ControlFlowNode mid |
|
||||
exists(EqualsMethod equals, Parameter param, ControlFlow::Node mid |
|
||||
equals.getParameter(0) = param and
|
||||
equals.getAChild*() = mid.getElement() and
|
||||
nodeBeforeParameterAccess(mid) and
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.frameworks.system.Text
|
||||
|
||||
from ObjectCreation creation, LoopStmt loop, ControlFlowGraph::ControlFlowNode loopEntryNode
|
||||
from ObjectCreation creation, LoopStmt loop, ControlFlow::Node loopEntryNode
|
||||
where creation.getType() instanceof SystemTextStringBuilderClass
|
||||
and loopEntryNode = loop.getBody().getAControlFlowEntryNode()
|
||||
and loop.getBody().getAChild*() = creation
|
||||
|
||||
@@ -12,10 +12,9 @@
|
||||
*/
|
||||
|
||||
import csharp
|
||||
import ControlFlowGraph
|
||||
import semmle.code.csharp.frameworks.system.web.Security
|
||||
|
||||
predicate loginMethod(Method m, ControlFlowEdgeType flowFrom)
|
||||
predicate loginMethod(Method m, ControlFlow::SuccessorType flowFrom)
|
||||
{
|
||||
(
|
||||
m = any(SystemWebSecurityMembershipClass c).getValidateUserMethod()
|
||||
@@ -23,11 +22,11 @@ predicate loginMethod(Method m, ControlFlowEdgeType flowFrom)
|
||||
m = any(SystemWebSecurityFormsAuthenticationClass c).getAuthenticateMethod()
|
||||
)
|
||||
and
|
||||
flowFrom.(ControlFlowEdgeBoolean).getValue()=true
|
||||
flowFrom.(ControlFlow::SuccessorTypes::BooleanSuccessor).getValue()=true
|
||||
or
|
||||
m = any(SystemWebSecurityFormsAuthenticationClass c).getSignOutMethod()
|
||||
and
|
||||
flowFrom instanceof ControlFlowEdgeSuccessor
|
||||
flowFrom instanceof ControlFlow::SuccessorTypes::NormalSuccessor
|
||||
}
|
||||
|
||||
/** The `System.Web.SessionState.HttpSessionState` class. */
|
||||
@@ -62,14 +61,14 @@ predicate sessionUse(MemberAccess ma)
|
||||
}
|
||||
|
||||
/** A control flow step that is not sanitised by a call to clear the session. */
|
||||
predicate controlStep(ControlFlowNode s1, ControlFlowNode s2)
|
||||
predicate controlStep(ControlFlow::Node s1, ControlFlow::Node s2)
|
||||
{
|
||||
s2 = s1.getASuccessor()
|
||||
and
|
||||
not sessionEndMethod(s2.getElement().(MethodCall).getTarget())
|
||||
}
|
||||
|
||||
from ControlFlowNode loginCall, Method loginMethod, ControlFlowNode sessionUse, ControlFlowEdgeType fromLoginFlow
|
||||
from ControlFlow::Node loginCall, Method loginMethod, ControlFlow::Node sessionUse, ControlFlow::SuccessorType fromLoginFlow
|
||||
where loginMethod = loginCall.getElement().(MethodCall).getTarget()
|
||||
and loginMethod(loginMethod, fromLoginFlow)
|
||||
and sessionUse(sessionUse.getElement())
|
||||
|
||||
@@ -29,11 +29,18 @@ import semmle.code.csharp.exprs.Dynamic
|
||||
import semmle.code.csharp.exprs.Expr
|
||||
import semmle.code.csharp.exprs.Literal
|
||||
import semmle.code.csharp.exprs.LogicalOperation
|
||||
import semmle.code.csharp.controlflow.ControlFlowGraph as ControlFlowGraph
|
||||
import semmle.code.csharp.controlflow.ControlFlowGraph
|
||||
import semmle.code.csharp.dataflow.DataFlow
|
||||
import semmle.code.csharp.dataflow.TaintTracking
|
||||
import semmle.code.csharp.dataflow.SSA
|
||||
|
||||
/** DEPRECATED: Use `ControlFlow` instead. */
|
||||
deprecated
|
||||
module ControlFlowGraph {
|
||||
import semmle.code.csharp.controlflow.ControlFlowGraph
|
||||
import ControlFlow
|
||||
}
|
||||
|
||||
/** Whether the source was extracted without a build command. */
|
||||
predicate extractionIsStandalone() {
|
||||
exists(SourceFile f | f.extractedStandalone())
|
||||
|
||||
4
csharp/ql/src/external/ExternalArtifact.qll
vendored
4
csharp/ql/src/external/ExternalArtifact.qll
vendored
@@ -9,7 +9,7 @@ class ExternalDefect extends @externalDefect, Element {
|
||||
|
||||
float getSeverity() { externalDefects(this, _, _, _, result) }
|
||||
|
||||
Location getLocation() { externalDefects(this,_,result,_,_) }
|
||||
override Location getLocation() { externalDefects(this,_,result,_,_) }
|
||||
|
||||
override string toString() {
|
||||
result = getQueryPath() + ": " + getLocation() + " - " + getMessage()
|
||||
@@ -22,7 +22,7 @@ class ExternalMetric extends @externalMetric, Element {
|
||||
|
||||
float getValue() { externalMetrics(this, _, _, result) }
|
||||
|
||||
Location getLocation() { externalMetrics(this,_,result,_) }
|
||||
override Location getLocation() { externalMetrics(this,_,result,_) }
|
||||
|
||||
override string toString() {
|
||||
result = getQueryPath() + ": " + getLocation() + " - " + getValue()
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
*/
|
||||
|
||||
import csharp
|
||||
private import ControlFlowGraph
|
||||
|
||||
/**
|
||||
* An assignable, that is, an element that can be assigned to. Either a
|
||||
@@ -348,7 +347,7 @@ private cached module AssignableDefinitionImpl {
|
||||
cached predicate isUncertainRefCall(Call c, AssignableAccess aa) {
|
||||
isRelevantRefCall(c, aa)
|
||||
and
|
||||
exists(ControlFlowGraph::BasicBlock bb, Parameter p |
|
||||
exists(ControlFlow::BasicBlock bb, Parameter p |
|
||||
isAnalyzableRefCall(c, aa, p) |
|
||||
parameterReachesWithoutDef(p, bb) and
|
||||
bb.getLastNode() = p.getCallable().getExitPoint()
|
||||
@@ -360,14 +359,14 @@ private cached module AssignableDefinitionImpl {
|
||||
* entry point of `p`'s callable to basic block `bb` without passing through
|
||||
* any assignments to `p`.
|
||||
*/
|
||||
private predicate parameterReachesWithoutDef(Parameter p, BasicBlock bb) {
|
||||
private predicate parameterReachesWithoutDef(Parameter p, ControlFlow::BasicBlock bb) {
|
||||
not basicBlockRefParamDef(bb, p)
|
||||
and
|
||||
(
|
||||
isAnalyzableRefCall(_, _, p) and
|
||||
p.getCallable().getEntryPoint() = bb.getFirstNode()
|
||||
or
|
||||
exists(BasicBlock mid |
|
||||
exists(ControlFlow::BasicBlock mid |
|
||||
parameterReachesWithoutDef(p, mid) |
|
||||
bb = mid.getASuccessor()
|
||||
)
|
||||
@@ -375,7 +374,7 @@ private cached module AssignableDefinitionImpl {
|
||||
}
|
||||
|
||||
/** Holds if a node in basic block `bb` assigns to `ref` parameter `p`. */
|
||||
private predicate basicBlockRefParamDef(BasicBlock bb, Parameter p) {
|
||||
private predicate basicBlockRefParamDef(ControlFlow::BasicBlock bb, Parameter p) {
|
||||
bb.getANode() = getAnAnalyzableRefDef(_, _, p).getAControlFlowNode()
|
||||
}
|
||||
|
||||
@@ -447,11 +446,11 @@ class AssignableDefinition extends TAssignableDefinition {
|
||||
* the definitions of `x` and `y` in `M(out x, out y)` and `(x, y) = (0, 1)`
|
||||
* relate to the same call to `M` and assignment node, respectively.
|
||||
*/
|
||||
ControlFlowNode getAControlFlowNode() { none() }
|
||||
ControlFlow::Node getAControlFlowNode() { none() }
|
||||
|
||||
/** DEPRECATED: Use `getAControlFlowNode()` instead. */
|
||||
deprecated
|
||||
ControlFlowNode getControlFlowNode() { result = this.getAControlFlowNode() }
|
||||
ControlFlow::Node getControlFlowNode() { result = this.getAControlFlowNode() }
|
||||
|
||||
/** Gets the enclosing callable of this definition. */
|
||||
Callable getEnclosingCallable() {
|
||||
@@ -603,7 +602,7 @@ module AssignableDefinitions {
|
||||
result = a
|
||||
}
|
||||
|
||||
override ControlFlowNode getAControlFlowNode() {
|
||||
override ControlFlow::Node getAControlFlowNode() {
|
||||
result = a.getAControlFlowNode()
|
||||
}
|
||||
|
||||
@@ -644,7 +643,7 @@ module AssignableDefinitions {
|
||||
* orders of the definitions of `x`, `y`, and `z` are 0, 1, and 2, respectively.
|
||||
*/
|
||||
int getEvaluationOrder() {
|
||||
exists(BasicBlock bb, int i |
|
||||
exists(ControlFlow::BasicBlock bb, int i |
|
||||
bb.getNode(i).getElement() = leaf |
|
||||
i = rank[result + 1](int j, TupleAssignmentDefinition def |
|
||||
bb.getNode(j).getElement() = def.getLeaf() and
|
||||
@@ -655,7 +654,7 @@ module AssignableDefinitions {
|
||||
)
|
||||
}
|
||||
|
||||
override ControlFlowNode getAControlFlowNode() {
|
||||
override ControlFlow::Node getAControlFlowNode() {
|
||||
result = ae.getAControlFlowNode()
|
||||
}
|
||||
|
||||
@@ -690,7 +689,7 @@ module AssignableDefinitions {
|
||||
* the definitions of `x` and `y` are 0 and 1, respectively.
|
||||
*/
|
||||
int getIndex() {
|
||||
exists(BasicBlock bb, int i |
|
||||
exists(ControlFlow::BasicBlock bb, int i |
|
||||
bb.getNode(i).getElement() = aa |
|
||||
i = rank[result + 1](int j, OutRefDefinition def |
|
||||
bb.getNode(j).getElement() = def.getTargetAccess() and
|
||||
@@ -701,7 +700,7 @@ module AssignableDefinitions {
|
||||
)
|
||||
}
|
||||
|
||||
override ControlFlowNode getAControlFlowNode() {
|
||||
override ControlFlow::Node getAControlFlowNode() {
|
||||
result = this.getCall().getAControlFlowNode()
|
||||
}
|
||||
|
||||
@@ -733,7 +732,7 @@ module AssignableDefinitions {
|
||||
result = mo
|
||||
}
|
||||
|
||||
override ControlFlowNode getAControlFlowNode() {
|
||||
override ControlFlow::Node getAControlFlowNode() {
|
||||
result = mo.getAControlFlowNode()
|
||||
}
|
||||
|
||||
@@ -757,7 +756,7 @@ module AssignableDefinitions {
|
||||
result = lvde
|
||||
}
|
||||
|
||||
override ControlFlowNode getAControlFlowNode() {
|
||||
override ControlFlow::Node getAControlFlowNode() {
|
||||
result = lvde.getAControlFlowNode()
|
||||
}
|
||||
|
||||
@@ -782,7 +781,7 @@ module AssignableDefinitions {
|
||||
result = p
|
||||
}
|
||||
|
||||
override ControlFlowNode getAControlFlowNode() {
|
||||
override ControlFlow::Node getAControlFlowNode() {
|
||||
result = p.getCallable().getEntryPoint()
|
||||
}
|
||||
|
||||
@@ -810,7 +809,7 @@ module AssignableDefinitions {
|
||||
result = aoe
|
||||
}
|
||||
|
||||
override ControlFlowNode getAControlFlowNode() {
|
||||
override ControlFlow::Node getAControlFlowNode() {
|
||||
result = aoe.getAControlFlowNode()
|
||||
}
|
||||
|
||||
@@ -834,7 +833,7 @@ module AssignableDefinitions {
|
||||
result = ipe.getVariableDeclExpr()
|
||||
}
|
||||
|
||||
override ControlFlowNode getAControlFlowNode() {
|
||||
override ControlFlow::Node getAControlFlowNode() {
|
||||
result = this.getDeclaration().getAControlFlowNode()
|
||||
}
|
||||
|
||||
@@ -871,7 +870,7 @@ module AssignableDefinitions {
|
||||
result = tc.getVariableDeclExpr()
|
||||
}
|
||||
|
||||
override ControlFlowNode getAControlFlowNode() {
|
||||
override ControlFlow::Node getAControlFlowNode() {
|
||||
result = this.getDeclaration().getAControlFlowNode()
|
||||
}
|
||||
|
||||
@@ -907,7 +906,7 @@ module AssignableDefinitions {
|
||||
result = a
|
||||
}
|
||||
|
||||
override ControlFlowNode getAControlFlowNode() {
|
||||
override ControlFlow::Node getAControlFlowNode() {
|
||||
none() // initializers are currently not part of the CFG
|
||||
}
|
||||
|
||||
|
||||
@@ -167,12 +167,12 @@ class Callable extends DotNet::Callable, Parameterizable, ExprOrStmtParent, @cal
|
||||
final predicate hasExpressionBody() { exists(getExpressionBody()) }
|
||||
|
||||
/** Gets the entry point in the control graph for this callable. */
|
||||
ControlFlowGraph::CallableEntryNode getEntryPoint() {
|
||||
ControlFlow::Nodes::EntryNode getEntryPoint() {
|
||||
result.getCallable() = this
|
||||
}
|
||||
|
||||
/** Gets the exit point in the control graph for this callable. */
|
||||
ControlFlowGraph::CallableExitNode getExitPoint() {
|
||||
ControlFlow::Nodes::ExitNode getExitPoint() {
|
||||
result.getCallable() = this
|
||||
}
|
||||
|
||||
|
||||
@@ -92,8 +92,7 @@ class EventAccessor extends Accessor, @event_accessor {
|
||||
result instanceof VoidType
|
||||
}
|
||||
|
||||
/** Gets the assembly name of this event accessor. */
|
||||
string getAssemblyName() { event_accessors(this,_,result,_,_) }
|
||||
override string getAssemblyName() { event_accessors(this,_,result,_,_) }
|
||||
|
||||
override EventAccessor getSourceDeclaration() { event_accessors(this,_,_,_,result) }
|
||||
|
||||
|
||||
@@ -250,7 +250,25 @@ class SwitchStmt extends SelectionStmt, @switch_stmt {
|
||||
* A `case` statement. Either a constant case (`ConstCase`), a type matching
|
||||
* case (`TypeCase`), or a `default` case (`DefaultCase`).
|
||||
*/
|
||||
class CaseStmt extends Stmt, @case { }
|
||||
class CaseStmt extends Stmt, @case {
|
||||
/**
|
||||
* Gets the condition on this case, if any. For example, the type case on line 3
|
||||
* has no condition, and the type case on line 4 has condition `s.Length > 0`, in
|
||||
*
|
||||
* ```
|
||||
* switch(p)
|
||||
* {
|
||||
* case int i:
|
||||
* case string s when s.Length > 0:
|
||||
* break;
|
||||
* ...
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
Expr getCondition() {
|
||||
result = this.getChild(2)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A constant case of a `switch` statement, for example `case OpCode.Nop:`
|
||||
@@ -280,15 +298,16 @@ class ConstCase extends LabeledStmt, CaseStmt {
|
||||
}
|
||||
|
||||
/**
|
||||
* A type matching case in a `switch` statement, for example `case int i:` on line 2 or
|
||||
* `case string s when s.Length>0:` on line 3 in
|
||||
* A type matching case in a `switch` statement, for example `case int i:` on line 3 or
|
||||
* `case string s when s.Length > 0:` on line 4 in
|
||||
*
|
||||
* ```
|
||||
* switch(p) {
|
||||
* case int i:
|
||||
* case string s when s.Length>0:
|
||||
* break;
|
||||
* ...
|
||||
* switch(p)
|
||||
* {
|
||||
* case int i:
|
||||
* case string s when s.Length > 0:
|
||||
* break;
|
||||
* ...
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
@@ -350,23 +369,6 @@ class TypeCase extends LabeledStmt, CaseStmt {
|
||||
result = getTypeAccess().getType()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the condition on this case, if any. For example, the type case on line 2
|
||||
* has no condition, and the type case on line 3 has condition `s.Length>0`, in
|
||||
*
|
||||
* ```
|
||||
* switch(p) {
|
||||
* case int i:
|
||||
* case string s when s.Length>0:
|
||||
* break;
|
||||
* ...
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
Expr getCondition() {
|
||||
result = getChild(2)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
exists(string var |
|
||||
if exists(this.getVariableDeclExpr()) then
|
||||
|
||||
@@ -29,7 +29,7 @@ abstract class AssertNonNullMethod extends AssertMethod {
|
||||
*/
|
||||
class SystemDiagnosticsDebugAssertTrueMethod extends AssertTrueMethod {
|
||||
SystemDiagnosticsDebugAssertTrueMethod() {
|
||||
this = getSystemDiagnosticsDebugClass().getAssertMethod()
|
||||
this = any(SystemDiagnosticsDebugClass c).getAssertMethod()
|
||||
}
|
||||
|
||||
override int getAssertionIndex() { result = 0 }
|
||||
@@ -38,7 +38,7 @@ class SystemDiagnosticsDebugAssertTrueMethod extends AssertTrueMethod {
|
||||
/** A Visual Studio assertion method. */
|
||||
class VSTestAssertTrueMethod extends AssertTrueMethod {
|
||||
VSTestAssertTrueMethod() {
|
||||
this = getVSTestAssertClass().getIsTrueMethod()
|
||||
this = any(VSTestAssertClass c).getIsTrueMethod()
|
||||
}
|
||||
|
||||
override int getAssertionIndex() { result = 0 }
|
||||
@@ -47,7 +47,7 @@ class VSTestAssertTrueMethod extends AssertTrueMethod {
|
||||
/** A Visual Studio negated assertion method. */
|
||||
class VSTestAssertFalseMethod extends AssertFalseMethod {
|
||||
VSTestAssertFalseMethod() {
|
||||
this = getVSTestAssertClass().getIsFalseMethod()
|
||||
this = any(VSTestAssertClass c).getIsFalseMethod()
|
||||
}
|
||||
|
||||
override int getAssertionIndex() { result = 0 }
|
||||
@@ -56,7 +56,7 @@ class VSTestAssertFalseMethod extends AssertFalseMethod {
|
||||
/** A Visual Studio `null` assertion method. */
|
||||
class VSTestAssertNullMethod extends AssertNullMethod {
|
||||
VSTestAssertNullMethod() {
|
||||
this = getVSTestAssertClass().getIsNullMethod()
|
||||
this = any(VSTestAssertClass c).getIsNullMethod()
|
||||
}
|
||||
|
||||
override int getAssertionIndex() { result = 0 }
|
||||
@@ -65,7 +65,7 @@ class VSTestAssertNullMethod extends AssertNullMethod {
|
||||
/** A Visual Studio non-`null` assertion method. */
|
||||
class VSTestAssertNonNullMethod extends AssertNonNullMethod {
|
||||
VSTestAssertNonNullMethod() {
|
||||
this = getVSTestAssertClass().getIsNotNullMethod()
|
||||
this = any(VSTestAssertClass c).getIsNotNullMethod()
|
||||
}
|
||||
|
||||
override int getAssertionIndex() { result = 0 }
|
||||
|
||||
@@ -40,7 +40,7 @@ module SsaChecks {
|
||||
import Ssa
|
||||
|
||||
predicate nonUniqueSsaDef(AssignableRead read, string m) {
|
||||
exists(ControlFlowNode cfn |
|
||||
exists(ControlFlow::Node cfn |
|
||||
strictcount(Definition def | def.getAReadAtNode(cfn) = read) > 1
|
||||
)
|
||||
and
|
||||
@@ -48,7 +48,7 @@ module SsaChecks {
|
||||
}
|
||||
|
||||
predicate notDominatedByDef(AssignableRead read, string m) {
|
||||
exists(Definition def, BasicBlock bb, ControlFlowNode rnode, ControlFlowNode dnode, int i |
|
||||
exists(Definition def, BasicBlock bb, ControlFlow::Node rnode, ControlFlow::Node dnode, int i |
|
||||
def.getAReadAtNode(rnode) = read |
|
||||
def.definesAt(bb, i) and
|
||||
dnode = bb.getNode(max(int j | j = i or j = 0)) and
|
||||
@@ -82,12 +82,10 @@ module SsaChecks {
|
||||
}
|
||||
|
||||
module CfgChecks {
|
||||
import ControlFlowGraph
|
||||
|
||||
predicate multipleSuccessors(ControlFlowElement cfe, string m) {
|
||||
exists(ControlFlowNode cfn |
|
||||
exists(ControlFlow::Node cfn |
|
||||
cfn = cfe.getAControlFlowNode() |
|
||||
strictcount(cfn.getASuccessorByType(any(ControlFlowEdgeSuccessor e))) > 1 and
|
||||
strictcount(cfn.getASuccessorByType(any(ControlFlow::SuccessorTypes::NormalSuccessor e))) > 1 and
|
||||
m = "Multiple (non-conditional/exceptional) successors"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/** Provides logic for determining constant expressions. */
|
||||
import csharp
|
||||
private import ControlFlowGraph
|
||||
private import semmle.code.csharp.commons.ComparisonTest
|
||||
private import semmle.code.csharp.commons.StructuralComparison as StructuralComparison
|
||||
|
||||
@@ -8,10 +7,10 @@ private import semmle.code.csharp.commons.StructuralComparison as StructuralComp
|
||||
* Holds if `e` is a condition that always evaluates to Boolean value `b`.
|
||||
*/
|
||||
predicate isConstantCondition(Expr e, boolean b) {
|
||||
forex(ControlFlowNode cfn |
|
||||
forex(ControlFlow::Node cfn |
|
||||
cfn = e.getAControlFlowNode() |
|
||||
exists(cfn.getASuccessorByType(any(ControlFlowEdgeBoolean t | t.getValue() = b))) and
|
||||
strictcount(ControlFlowEdgeType t | exists(cfn.getASuccessorByType(t))) = 1
|
||||
exists(cfn.getASuccessorByType(any(ControlFlow::SuccessorTypes::BooleanSuccessor t | t.getValue() = b))) and
|
||||
strictcount(ControlFlow::SuccessorType t | exists(cfn.getASuccessorByType(t))) = 1
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -99,20 +99,20 @@ class BasicBlock extends TBasicBlockStart {
|
||||
}
|
||||
|
||||
/** Gets the control flow node at a specific (zero-indexed) position in this basic block. */
|
||||
ControlFlowGraph::ControlFlowNode getNode(int pos) { bbIndex(getFirstNode(), result, pos) }
|
||||
ControlFlow::Node getNode(int pos) { bbIndex(getFirstNode(), result, pos) }
|
||||
|
||||
/** Gets a control flow node in this basic block. */
|
||||
ControlFlowGraph::ControlFlowNode getANode() {
|
||||
ControlFlow::Node getANode() {
|
||||
result = getNode(_)
|
||||
}
|
||||
|
||||
/** Gets the first control flow node in this basic block. */
|
||||
ControlFlowGraph::ControlFlowNode getFirstNode() {
|
||||
ControlFlow::Node getFirstNode() {
|
||||
this = TBasicBlockStart(result)
|
||||
}
|
||||
|
||||
/** Gets the last control flow node in this basic block. */
|
||||
ControlFlowGraph::ControlFlowNode getLastNode() {
|
||||
ControlFlow::Node getLastNode() {
|
||||
result = getNode(length() - 1)
|
||||
}
|
||||
|
||||
@@ -326,22 +326,22 @@ class BasicBlock extends TBasicBlockStart {
|
||||
private cached module Internal {
|
||||
/** Internal representation of basic blocks. */
|
||||
cached newtype TBasicBlock =
|
||||
TBasicBlockStart(ControlFlowGraph::ControlFlowNode cfn) { startsBB(cfn) }
|
||||
TBasicBlockStart(ControlFlow::Node cfn) { startsBB(cfn) }
|
||||
|
||||
/** Holds if `cfn` starts a new basic block. */
|
||||
private predicate startsBB(ControlFlowGraph::ControlFlowNode cfn) {
|
||||
private predicate startsBB(ControlFlow::Node cfn) {
|
||||
not exists(cfn.getAPredecessor()) and exists(cfn.getASuccessor())
|
||||
or
|
||||
cfn.isJoin()
|
||||
or
|
||||
exists(ControlFlowGraph::ControlFlowNode pred | pred = cfn.getAPredecessor() | strictcount(pred.getASuccessor()) > 1)
|
||||
exists(ControlFlow::Node pred | pred = cfn.getAPredecessor() | strictcount(pred.getASuccessor()) > 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `succ` is a control flow successor of `pred` within
|
||||
* the same basic block.
|
||||
*/
|
||||
private predicate intraBBSucc(ControlFlowGraph::ControlFlowNode pred, ControlFlowGraph::ControlFlowNode succ) {
|
||||
private predicate intraBBSucc(ControlFlow::Node pred, ControlFlow::Node succ) {
|
||||
succ = pred.getASuccessor() and
|
||||
not startsBB(succ)
|
||||
}
|
||||
@@ -353,7 +353,7 @@ private cached module Internal {
|
||||
* that starts a basic block to `cfn` along the `intraBBSucc` relation.
|
||||
*/
|
||||
cached
|
||||
predicate bbIndex(ControlFlowGraph::ControlFlowNode bbStart, ControlFlowGraph::ControlFlowNode cfn, int i) =
|
||||
predicate bbIndex(ControlFlow::Node bbStart, ControlFlow::Node cfn, int i) =
|
||||
shortestDistances(startsBB/1, intraBBSucc/2)(bbStart, cfn, i)
|
||||
|
||||
/**
|
||||
@@ -395,7 +395,7 @@ class EntryBasicBlock extends BasicBlock {
|
||||
|
||||
/** Holds if `bb` is an entry basic block. */
|
||||
private predicate entryBB(BasicBlock bb) {
|
||||
bb.getFirstNode() instanceof ControlFlowGraph::CallableEntryNode
|
||||
bb.getFirstNode() instanceof ControlFlow::Nodes::EntryNode
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -408,7 +408,7 @@ class ExitBasicBlock extends BasicBlock {
|
||||
|
||||
/** Holds if `bb` is an exit basic block. */
|
||||
private predicate exitBB(BasicBlock bb) {
|
||||
bb.getLastNode() instanceof ControlFlowGraph::CallableExitNode
|
||||
bb.getLastNode() instanceof ControlFlow::Nodes::ExitNode
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -309,8 +309,8 @@ private predicate inBooleanContext(Expr e, boolean isBooleanCompletionForParent)
|
||||
isBooleanCompletionForParent = false
|
||||
)
|
||||
or
|
||||
exists(TypeCase tc |
|
||||
tc.getCondition() = e |
|
||||
exists(CaseStmt cs |
|
||||
cs.getCondition() = e |
|
||||
isBooleanCompletionForParent = false
|
||||
)
|
||||
or
|
||||
|
||||
@@ -7,12 +7,10 @@ private import semmle.code.csharp.ExprOrStmtParent
|
||||
* A program element that can possess control flow. That is, either a statement or
|
||||
* an expression.
|
||||
*
|
||||
* A control flow element can be mapped to a control flow node (`ControlFlowNode`)
|
||||
* A control flow element can be mapped to a control flow node (`ControlFlow::Node`)
|
||||
* via `getAControlFlowNode()`. There is a one-to-many relationship between
|
||||
* `ControlFlowElement`s and `ControlFlowNode`s. This allows control flow
|
||||
* control flow elements and control flow nodes. This allows control flow
|
||||
* splitting, for example modeling the control flow through `finally` blocks.
|
||||
*
|
||||
* `ControlFlowNode`s are nodes in the control flow graph.
|
||||
*/
|
||||
class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
|
||||
/** Gets the enclosing callable of this element, if any. */
|
||||
@@ -22,26 +20,26 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
|
||||
* Gets a control flow node for this element. That is, a node in the
|
||||
* control flow graph that corresponds to this element.
|
||||
*
|
||||
* Typically, there is exactly one `ControlFlowNode` associated with a
|
||||
* Typically, there is exactly one `ControlFlow::Node` associated with a
|
||||
* `ControlFlowElement`, but a `ControlFlowElement` may be split into
|
||||
* several `ControlFlowNode`s, for example to represent the continuation
|
||||
* several `ControlFlow::Node`s, for example to represent the continuation
|
||||
* flow in a `try/catch/finally` construction.
|
||||
*/
|
||||
ControlFlowGraph::ControlFlowNode getAControlFlowNode() {
|
||||
ControlFlow::Node getAControlFlowNode() {
|
||||
result.getElement() = this
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a first control flow node executed within this element.
|
||||
*/
|
||||
ControlFlowGraph::ControlFlowNode getAControlFlowEntryNode() {
|
||||
ControlFlow::Node getAControlFlowEntryNode() {
|
||||
result = ControlFlowGraph::Internal::getAControlFlowEntryNode(this).getAControlFlowNode()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a potential last control flow node executed within this element.
|
||||
*/
|
||||
ControlFlowGraph::ControlFlowNode getAControlFlowExitNode() {
|
||||
ControlFlow::Node getAControlFlowExitNode() {
|
||||
result = ControlFlowGraph::Internal::getAControlFlowExitNode(this).getAControlFlowNode()
|
||||
}
|
||||
|
||||
@@ -61,7 +59,7 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
|
||||
/** Gets an element that is reachable from this element. */
|
||||
ControlFlowElement getAReachableElement() {
|
||||
// Reachable in same basic block
|
||||
exists(ControlFlowGraph::BasicBlock bb, int i, int j |
|
||||
exists(ControlFlow::BasicBlock bb, int i, int j |
|
||||
bb.getNode(i) = getAControlFlowNode() and
|
||||
bb.getNode(j) = result.getAControlFlowNode() and
|
||||
i < j
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -184,7 +184,7 @@ class NullGuardedExpr extends AccessOrCallExpr {
|
||||
// Call to `string.IsNullOrEmpty()`
|
||||
exists(MethodCall mc |
|
||||
mc = cond and
|
||||
mc.getTarget() = getSystemStringClass().getIsNullOrEmptyMethod() and
|
||||
mc.getTarget() = any(SystemStringClass c).getIsNullOrEmptyMethod() and
|
||||
mc.getArgument(0) = sub and
|
||||
b = false
|
||||
)
|
||||
|
||||
@@ -18,12 +18,10 @@
|
||||
*/
|
||||
|
||||
import csharp
|
||||
private import ControlFlowGraph
|
||||
private import semmle.code.csharp.commons.Assertions
|
||||
private import semmle.code.csharp.commons.ComparisonTest
|
||||
private import semmle.code.csharp.controlflow.Guards
|
||||
private import semmle.code.csharp.dataflow.SSA
|
||||
private import semmle.code.csharp.controlflow.ControlFlowGraph
|
||||
private import semmle.code.csharp.frameworks.System
|
||||
|
||||
/** An expression that may be `null`. */
|
||||
@@ -412,7 +410,7 @@ private Expr failureIsNonNullTest(LocalScopeVariable var) {
|
||||
* Gets an immediate successor node of the conditional node `cfgnode` where
|
||||
* the condition implies that the variable `var` is `null`.
|
||||
*/
|
||||
private ControlFlowNode nullBranchKill(LocalScopeVariable var, ControlFlowNode cfgnode) {
|
||||
private ControlFlow::Node nullBranchKill(LocalScopeVariable var, ControlFlow::Node cfgnode) {
|
||||
(cfgnode.getElement() = nullTest(var) and result = cfgnode.getATrueSuccessor())
|
||||
or
|
||||
(cfgnode.getElement() = failureIsNullTest(var) and result = cfgnode.getAFalseSuccessor())
|
||||
@@ -422,17 +420,17 @@ private ControlFlowNode nullBranchKill(LocalScopeVariable var, ControlFlowNode c
|
||||
* Gets an immediate successor node of the conditional node `cfgnode` where
|
||||
* the condition implies that the variable `var` is non-`null`.
|
||||
*/
|
||||
private ControlFlowNode nonNullBranchKill(LocalScopeVariable var, ControlFlowNode cfgnode) {
|
||||
private ControlFlow::Node nonNullBranchKill(LocalScopeVariable var, ControlFlow::Node cfgnode) {
|
||||
(cfgnode.getElement() = nonNullTest(var) and result = cfgnode.getATrueSuccessor())
|
||||
or
|
||||
(cfgnode.getElement() = failureIsNonNullTest(var) and result = cfgnode.getAFalseSuccessor())
|
||||
}
|
||||
|
||||
/** Gets a node where the variable `var` may be `null`. */
|
||||
ControlFlowNode maybeNullNode(LocalScopeVariable var) {
|
||||
ControlFlow::Node maybeNullNode(LocalScopeVariable var) {
|
||||
result = nullDef(var).getAControlFlowNode().getASuccessor()
|
||||
or
|
||||
exists(ControlFlowNode mid |
|
||||
exists(ControlFlow::Node mid |
|
||||
mid = maybeNullNode(var) and
|
||||
not mid.getElement() = nonNullDef(var) and
|
||||
mid.getASuccessor() = result and
|
||||
@@ -441,10 +439,10 @@ ControlFlowNode maybeNullNode(LocalScopeVariable var) {
|
||||
}
|
||||
|
||||
/** Gets a node where the variable `var` may be non-`null`. */
|
||||
ControlFlowNode maybeNonNullNode(LocalScopeVariable var) {
|
||||
ControlFlow::Node maybeNonNullNode(LocalScopeVariable var) {
|
||||
result = nonNullDef(var).getAControlFlowNode().getASuccessor()
|
||||
or
|
||||
exists(ControlFlowNode mid |
|
||||
exists(ControlFlow::Node mid |
|
||||
mid = maybeNonNullNode(var) and
|
||||
not mid.getElement() = nullDef(var) and
|
||||
mid.getASuccessor() = result and
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
import csharp
|
||||
|
||||
module Ssa {
|
||||
class BasicBlock = ControlFlowGraph::BasicBlock;
|
||||
class ControlFlowNode = ControlFlowGraph::ControlFlowNode;
|
||||
class BasicBlock = ControlFlow::BasicBlock;
|
||||
|
||||
private module SourceVariableImpl {
|
||||
private import AssignableDefinitions
|
||||
@@ -207,7 +206,7 @@ module Ssa {
|
||||
* Holds if the `i`th node `node` of basic block `bb` reads source variable `v`.
|
||||
* The read at `node` is of kind `rk`.
|
||||
*/
|
||||
predicate variableRead(BasicBlock bb, int i, SourceVariable v, ControlFlowNode node, ReadKind rk) {
|
||||
predicate variableRead(BasicBlock bb, int i, SourceVariable v, ControlFlow::Node node, ReadKind rk) {
|
||||
v.getAnAccess().(AssignableRead) = node.getElement() and
|
||||
node = bb.getNode(i) and
|
||||
rk = ActualRead()
|
||||
@@ -222,7 +221,7 @@ module Ssa {
|
||||
rk = RefReadBeforeWrite()
|
||||
}
|
||||
|
||||
private predicate outRefExitRead(ControlFlowGraph::ExitBasicBlock ebb, int i, LocalScopeSourceVariable v, ControlFlowGraph::CallableExitNode node) {
|
||||
private predicate outRefExitRead(ControlFlow::BasicBlocks::ExitBlock ebb, int i, LocalScopeSourceVariable v, ControlFlow::Nodes::ExitNode node) {
|
||||
exists(LocalScopeVariable lsv |
|
||||
lsv = v.getAssignable() and
|
||||
ebb.getNode(i) = node and
|
||||
@@ -231,7 +230,7 @@ module Ssa {
|
||||
)
|
||||
}
|
||||
|
||||
private predicate capturedVarExitRead(ControlFlowGraph::ExitBasicBlock ebb, int i, LocalScopeSourceVariable v, ControlFlowGraph::CallableExitNode node) {
|
||||
private predicate capturedVarExitRead(ControlFlow::BasicBlocks::ExitBlock ebb, int i, LocalScopeSourceVariable v, ControlFlow::Nodes::ExitNode node) {
|
||||
exists(BasicBlock bb |
|
||||
variableDefinition(bb, _, v, _) |
|
||||
ebb.getNode(i) = node and
|
||||
@@ -240,7 +239,7 @@ module Ssa {
|
||||
)
|
||||
}
|
||||
|
||||
private predicate refReadBeforeWrite(BasicBlock bb, int i, LocalScopeSourceVariable v, ControlFlowNode node) {
|
||||
private predicate refReadBeforeWrite(BasicBlock bb, int i, LocalScopeSourceVariable v, ControlFlow::Node node) {
|
||||
exists(AssignableDefinitions::AssignmentDefinition def, LocalVariable lv |
|
||||
def.getTarget() = lv and
|
||||
lv.isRef() and
|
||||
@@ -692,7 +691,7 @@ module Ssa {
|
||||
* same basic block without crossing another SSA definition of `v`.
|
||||
* The read at `node` is of kind `rk`.
|
||||
*/
|
||||
private predicate ssaDefReachesReadWithinBlock(TrackedVar v, TrackedDefinition def, ControlFlowNode read, ReadKind rk) {
|
||||
private predicate ssaDefReachesReadWithinBlock(TrackedVar v, TrackedDefinition def, ControlFlow::Node read, ReadKind rk) {
|
||||
exists(BasicBlock bb, int rankix, int i |
|
||||
ssaDefReachesRank(bb, def, rankix, v) and
|
||||
rankix = ssaRefRank(bb, i, v, SsaRead()) and
|
||||
@@ -873,7 +872,7 @@ module Ssa {
|
||||
* The read at `node` is of kind `rk`.
|
||||
*/
|
||||
cached
|
||||
predicate ssaDefReachesRead(TrackedVar v, TrackedDefinition def, ControlFlowNode read, ReadKind rk) {
|
||||
predicate ssaDefReachesRead(TrackedVar v, TrackedDefinition def, ControlFlow::Node read, ReadKind rk) {
|
||||
ssaDefReachesReadWithinBlock(v, def, read, rk)
|
||||
or
|
||||
exists(BasicBlock bb |
|
||||
@@ -1615,7 +1614,7 @@ module Ssa {
|
||||
* `c` may read the value of the captured variable.
|
||||
*/
|
||||
private predicate capturerReads(Callable c, LocalScopeVariable v) {
|
||||
exists(ControlFlowGraph::EntryBasicBlock ebb, LocalScopeSourceVariable lssv |
|
||||
exists(ControlFlow::BasicBlocks::EntryBlock ebb, LocalScopeSourceVariable lssv |
|
||||
liveAtEntry(ebb, lssv, _) |
|
||||
v = lssv.getAssignable() and
|
||||
c = ebb.getCallable() and
|
||||
@@ -1873,7 +1872,7 @@ module Ssa {
|
||||
)
|
||||
}
|
||||
or
|
||||
TSsaImplicitEntryDef(TrackedVar v, ControlFlowGraph::EntryBasicBlock ebb) {
|
||||
TSsaImplicitEntryDef(TrackedVar v, ControlFlow::BasicBlocks::EntryBlock ebb) {
|
||||
liveAtEntry(ebb, v, _)
|
||||
and
|
||||
exists(Callable c |
|
||||
@@ -1921,7 +1920,7 @@ module Ssa {
|
||||
bb.getNode(i + 1) = v.getAnAccess().(AssignableRead).getAControlFlowNode()
|
||||
}
|
||||
or
|
||||
TPhiNode(TrackedVar v, ControlFlowGraph::JoinBlock bb) {
|
||||
TPhiNode(TrackedVar v, ControlFlow::BasicBlocks::JoinBlock bb) {
|
||||
liveAtEntry(bb, v, _)
|
||||
and
|
||||
exists(BasicBlock bb1, Definition def |
|
||||
@@ -2067,7 +2066,7 @@ module Ssa {
|
||||
* - The reads of `this.Field` on lines 10 and 11 can be reached from the phi
|
||||
* node between lines 9 and 10.
|
||||
*/
|
||||
AssignableRead getAReadAtNode(ControlFlowNode cfn) {
|
||||
AssignableRead getAReadAtNode(ControlFlow::Node cfn) {
|
||||
ssaDefReachesRead(_, this, cfn, _) and
|
||||
result.getAControlFlowNode() = cfn
|
||||
}
|
||||
@@ -2250,7 +2249,7 @@ module Ssa {
|
||||
* parameter may remain unchanged throughout the rest of the enclosing callable.
|
||||
*/
|
||||
predicate isLiveOutRefParameterDefinition(Parameter p) {
|
||||
exists(Definition def, ControlFlowNode read, SourceVariable v |
|
||||
exists(Definition def, ControlFlow::Node read, SourceVariable v |
|
||||
this = def.getAnUltimateDefinition() |
|
||||
ssaDefReachesRead(v, def, read, OutRefExitRead()) and
|
||||
v.getAssignable() = p
|
||||
@@ -2371,7 +2370,7 @@ module Ssa {
|
||||
class ImplicitEntryDefinition extends ImplicitDefinition, TSsaImplicitEntryDef {
|
||||
/** Gets the callable that this entry definition belongs to. */
|
||||
Callable getCallable() {
|
||||
exists(ControlFlowGraph::EntryBasicBlock ebb |
|
||||
exists(ControlFlow::BasicBlocks::EntryBlock ebb |
|
||||
this = TSsaImplicitEntryDef(_, ebb) and
|
||||
result = ebb.getCallable()
|
||||
)
|
||||
@@ -2533,7 +2532,7 @@ module Ssa {
|
||||
* does not exist in the source program.
|
||||
*/
|
||||
override Location getLocation() {
|
||||
exists(ControlFlowGraph::JoinBlock bb |
|
||||
exists(ControlFlow::BasicBlocks::JoinBlock bb |
|
||||
this = TPhiNode(_, bb) and
|
||||
result = bb.getFirstNode().getLocation()
|
||||
)
|
||||
|
||||
@@ -6,7 +6,7 @@ import csharp
|
||||
* Provides a simple SSA implementation for local scope variables.
|
||||
*/
|
||||
module BaseSsa {
|
||||
private import ControlFlowGraph
|
||||
private import ControlFlow
|
||||
private import AssignableDefinitions
|
||||
|
||||
private class SimpleLocalScopeVariable extends LocalScopeVariable {
|
||||
|
||||
@@ -11,7 +11,7 @@ import Expr
|
||||
* (`BinaryArithmeticOperation`).
|
||||
*/
|
||||
class ArithmeticOperation extends Operation, @arith_op_expr {
|
||||
string getOperator() { none() }
|
||||
override string getOperator() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,10 +38,9 @@ class Call extends DotNet::Call, Expr, @call {
|
||||
* Use `getARuntimeTarget()` instead to get a potential run-time target (will
|
||||
* include `B.M` in the example above).
|
||||
*/
|
||||
Callable getTarget() { none() }
|
||||
override Callable getTarget() { none() }
|
||||
|
||||
/** Gets the `i`th argument of this call. */
|
||||
Expr getArgument(int i) {
|
||||
override Expr getArgument(int i) {
|
||||
result = this.getChild(i) and i >= 0
|
||||
}
|
||||
|
||||
@@ -49,8 +48,7 @@ class Call extends DotNet::Call, Expr, @call {
|
||||
result = this.getArgument(i)
|
||||
}
|
||||
|
||||
/** Gets an argument of this call. */
|
||||
Expr getAnArgument() {
|
||||
override Expr getAnArgument() {
|
||||
result = getArgument(_)
|
||||
}
|
||||
|
||||
@@ -189,7 +187,7 @@ class Call extends DotNet::Call, Expr, @call {
|
||||
* - Line 16: There is no static target (delegate call) but the delegate `i => { }` (line
|
||||
* 20) is a run-time target.
|
||||
*/
|
||||
Callable getARuntimeTarget() {
|
||||
override Callable getARuntimeTarget() {
|
||||
exists(DispatchCall dc | dc.getCall() = this | result = dc.getADynamicTarget())
|
||||
}
|
||||
|
||||
|
||||
@@ -189,11 +189,11 @@ private module FormatFlow {
|
||||
private class FormatConfiguration extends DataFlow::Configuration {
|
||||
FormatConfiguration() { this = "format" }
|
||||
|
||||
predicate isSource(DataFlow::Node n) {
|
||||
override predicate isSource(DataFlow::Node n) {
|
||||
n.asExpr() instanceof StringLiteral
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node n) {
|
||||
override predicate isSink(DataFlow::Node n) {
|
||||
exists(FormatCall c | n.asExpr() = c.getFormatExpr())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ class SystemWebHttpRequestClass extends SystemWebClass {
|
||||
and
|
||||
result.hasName("Url")
|
||||
and
|
||||
result.getType() = getSystemUriClass()
|
||||
result.getType() instanceof SystemUriClass
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ private import semmle.code.csharp.frameworks.system.Runtime
|
||||
/** The `System.Runtime.InteropServices` namespace. */
|
||||
class SystemRuntimeInteropServicesNamespace extends Namespace {
|
||||
SystemRuntimeInteropServicesNamespace() {
|
||||
this.getParentNamespace() = getSystemRuntimeNamespace() and
|
||||
this.getParentNamespace() instanceof SystemRuntimeNamespace and
|
||||
this.hasName("InteropServices")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ module MissingXMLValidation {
|
||||
this.getExpr() = createCall.getArgumentForName("input")
|
||||
}
|
||||
|
||||
string getReason() {
|
||||
override string getReason() {
|
||||
// No settings = no Schema validation
|
||||
result = "there is no 'XmlReaderSettings' instance specifying schema validation." and not exists(createCall.getSettings()) or
|
||||
/*
|
||||
|
||||
@@ -50,7 +50,7 @@ module XMLEntityInjection {
|
||||
).getAnArgument()
|
||||
}
|
||||
|
||||
string getReason() {
|
||||
override string getReason() {
|
||||
exists(InsecureXML::InsecureXmlProcessing r | r.isUnsafe(result) | this.getExpr() = r.getAnArgument())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,7 +451,7 @@ module XSS {
|
||||
this.getExpr() = aspWrittenValue(inline)
|
||||
}
|
||||
|
||||
string explanation() {
|
||||
override string explanation() {
|
||||
result = "member is [[\"accessed inline\"|\"" +makeUrl(inline.getLocation())+ "\"]] in an ASPX page"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,6 +245,14 @@
|
||||
| Switch.cs:106:29:106:29 | 1 | Switch.cs:106:22:106:30 | return ...; | 2 |
|
||||
| Switch.cs:108:17:108:17 | 1 | Switch.cs:108:9:108:18 | return ...; | 3 |
|
||||
| Switch.cs:111:17:111:21 | enter Throw | Switch.cs:111:17:111:21 | exit Throw | 4 |
|
||||
| Switch.cs:113:9:113:11 | enter M10 | Switch.cs:117:18:117:18 | 3 | 7 |
|
||||
| Switch.cs:113:9:113:11 | exit M10 | Switch.cs:113:9:113:11 | exit M10 | 1 |
|
||||
| Switch.cs:117:25:117:25 | access to parameter s | Switch.cs:117:25:117:32 | ... == ... | 3 |
|
||||
| Switch.cs:117:43:117:43 | 1 | Switch.cs:117:36:117:44 | return ...; | 2 |
|
||||
| Switch.cs:118:13:118:33 | case ...: | Switch.cs:118:18:118:18 | 2 | 2 |
|
||||
| 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 |
|
||||
| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:7:13:7:22 | ... is ... | 16 |
|
||||
| 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 | 5 |
|
||||
|
||||
@@ -470,6 +470,21 @@
|
||||
| post | Switch.cs:106:29:106:29 | 1 | Switch.cs:106:29:106:29 | 1 |
|
||||
| post | Switch.cs:108:17:108:17 | 1 | Switch.cs:108:17:108:17 | 1 |
|
||||
| post | Switch.cs:111:17:111:21 | enter Throw | Switch.cs:111:17:111:21 | enter Throw |
|
||||
| post | Switch.cs:113:9:113:11 | enter M10 | Switch.cs:113:9:113:11 | enter M10 |
|
||||
| post | Switch.cs:113:9:113:11 | exit M10 | Switch.cs:113:9:113:11 | enter M10 |
|
||||
| post | Switch.cs:113:9:113:11 | exit M10 | Switch.cs:113:9:113:11 | exit M10 |
|
||||
| post | Switch.cs:113:9:113:11 | exit M10 | Switch.cs:117:25:117:25 | access to parameter s |
|
||||
| post | Switch.cs:113:9:113:11 | exit M10 | Switch.cs:117:43:117:43 | 1 |
|
||||
| post | Switch.cs:113:9:113:11 | exit M10 | Switch.cs:118:13:118:33 | case ...: |
|
||||
| post | Switch.cs:113:9:113:11 | exit M10 | Switch.cs:118:25:118:25 | access to parameter s |
|
||||
| post | Switch.cs:113:9:113:11 | exit M10 | Switch.cs:118:42:118:42 | 2 |
|
||||
| post | Switch.cs:113:9:113:11 | exit M10 | Switch.cs:120:17:120:17 | 1 |
|
||||
| post | Switch.cs:117:25:117:25 | access to parameter s | Switch.cs:117:25:117:25 | access to parameter s |
|
||||
| post | Switch.cs:117:43:117:43 | 1 | Switch.cs:117:43:117:43 | 1 |
|
||||
| post | Switch.cs:118:13:118:33 | case ...: | Switch.cs:118:13:118:33 | case ...: |
|
||||
| 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 | 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 |
|
||||
@@ -1709,6 +1724,26 @@
|
||||
| pre | Switch.cs:106:29:106:29 | 1 | Switch.cs:106:29:106:29 | 1 |
|
||||
| pre | Switch.cs:108:17:108:17 | 1 | Switch.cs:108:17:108:17 | 1 |
|
||||
| pre | Switch.cs:111:17:111:21 | enter Throw | Switch.cs:111:17:111:21 | enter Throw |
|
||||
| pre | Switch.cs:113:9:113:11 | enter M10 | Switch.cs:113:9:113:11 | enter M10 |
|
||||
| pre | Switch.cs:113:9:113:11 | enter M10 | Switch.cs:113:9:113:11 | exit M10 |
|
||||
| pre | Switch.cs:113:9:113:11 | enter M10 | Switch.cs:117:25:117:25 | access to parameter s |
|
||||
| pre | Switch.cs:113:9:113:11 | enter M10 | Switch.cs:117:43:117:43 | 1 |
|
||||
| pre | Switch.cs:113:9:113:11 | enter M10 | Switch.cs:118:13:118:33 | case ...: |
|
||||
| pre | Switch.cs:113:9:113:11 | enter M10 | Switch.cs:118:25:118:25 | access to parameter s |
|
||||
| pre | Switch.cs:113:9:113:11 | enter M10 | Switch.cs:118:42:118:42 | 2 |
|
||||
| pre | Switch.cs:113:9:113:11 | enter M10 | Switch.cs:120:17:120:17 | 1 |
|
||||
| pre | Switch.cs:113:9:113:11 | exit M10 | Switch.cs:113:9:113:11 | exit M10 |
|
||||
| pre | Switch.cs:117:25:117:25 | access to parameter s | Switch.cs:117:25:117:25 | access to parameter s |
|
||||
| pre | Switch.cs:117:25:117:25 | access to parameter s | Switch.cs:117:43:117:43 | 1 |
|
||||
| pre | Switch.cs:117:43:117:43 | 1 | Switch.cs:117:43:117:43 | 1 |
|
||||
| pre | Switch.cs:118:13:118:33 | case ...: | Switch.cs:118:13:118:33 | case ...: |
|
||||
| pre | Switch.cs:118:13:118:33 | case ...: | Switch.cs:118:25:118:25 | access to parameter s |
|
||||
| pre | Switch.cs:118:13:118:33 | case ...: | Switch.cs:118:42:118:42 | 2 |
|
||||
| pre | Switch.cs:118:13:118:33 | case ...: | Switch.cs:120:17:120:17 | 1 |
|
||||
| pre | Switch.cs:118:25:118:25 | access to parameter s | Switch.cs:118:25:118:25 | access to parameter s |
|
||||
| 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 | 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 | ... ...; |
|
||||
|
||||
@@ -89,6 +89,8 @@
|
||||
| Switch.cs:50:30:50:38 | ... != ... | Switch.cs:51:17:51:22 | break; | true |
|
||||
| Switch.cs:84:19:84:23 | ... > ... | Switch.cs:85:17:85:22 | break; | true |
|
||||
| Switch.cs:84:19:84:23 | ... > ... | Switch.cs:86:22:86:25 | true | false |
|
||||
| Switch.cs:117:25:117:32 | ... == ... | Switch.cs:117:43:117:43 | 1 | true |
|
||||
| Switch.cs:118:25:118:31 | ... == ... | Switch.cs:118:42:118:42 | 2 | true |
|
||||
| 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 |
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.controlflow.ControlFlowGraph
|
||||
|
||||
from ConditionBlock cb, BasicBlock controlled, boolean testIsTrue
|
||||
from ControlFlow::BasicBlocks::ConditionBlock cb, ControlFlow::BasicBlock controlled, boolean testIsTrue
|
||||
where cb.controls(controlled, testIsTrue)
|
||||
select cb.getLastNode(), controlled.getFirstNode(), testIsTrue
|
||||
|
||||
@@ -117,6 +117,10 @@
|
||||
| 108 | 13 | cflow.cs:108:13:108:21 | ... != ... | false | 116 | 9 | cflow.cs:116:9:116:29 | ...; |
|
||||
| 108 | 13 | cflow.cs:108:13:108:21 | ... != ... | true | 109 | 9 | cflow.cs:109:9:115:9 | {...} |
|
||||
| 110 | 20 | cflow.cs:110:20:110:23 | true | true | 111 | 13 | cflow.cs:111:13:113:13 | {...} |
|
||||
| 117 | 25 | Switch.cs:117:25:117:32 | ... == ... | false | 118 | 13 | Switch.cs:118:13:118:33 | case ...: |
|
||||
| 117 | 25 | Switch.cs:117:25:117:32 | ... == ... | true | 117 | 43 | Switch.cs:117:43:117:43 | 1 |
|
||||
| 118 | 25 | Switch.cs:118:25:118:31 | ... == ... | false | 120 | 17 | Switch.cs:120:17:120:17 | 1 |
|
||||
| 118 | 25 | Switch.cs:118:25:118:31 | ... == ... | true | 118 | 42 | Switch.cs:118:42:118:42 | 2 |
|
||||
| 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 | "" |
|
||||
| 162 | 48 | cflow.cs:162:48:162:51 | [exception: Exception] true | true | 163 | 9 | cflow.cs:163:9:165:9 | {...} |
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.controlflow.ControlFlowGraph
|
||||
|
||||
ControlFlowNode successor(ControlFlowNode node, boolean kind) {
|
||||
ControlFlow::Node successor(ControlFlow::Node node, boolean kind) {
|
||||
(kind = true and result = node.getATrueSuccessor()) or
|
||||
(kind = false and result = node.getAFalseSuccessor())
|
||||
}
|
||||
|
||||
from ControlFlowNode node, ControlFlowNode successor, Location nl, Location sl, boolean kind
|
||||
from ControlFlow::Node node, ControlFlow::Node successor, Location nl, Location sl, boolean kind
|
||||
where successor = successor(node, kind)
|
||||
and nl = node.getLocation()
|
||||
and sl = successor.getLocation()
|
||||
|
||||
@@ -819,6 +819,24 @@
|
||||
| post | Switch.cs:111:17:111:21 | exit Throw | Switch.cs:111:28:111:48 | throw ... |
|
||||
| post | Switch.cs:111:28:111:48 | throw ... | Switch.cs:111:34:111:48 | object creation of type Exception |
|
||||
| post | Switch.cs:111:34:111:48 | object creation of type Exception | Switch.cs:111:17:111:21 | enter Throw |
|
||||
| post | Switch.cs:113:9:113:11 | exit M10 | Switch.cs:117:36:117:44 | return ...; |
|
||||
| post | Switch.cs:113:9:113:11 | exit M10 | Switch.cs:118:35:118:43 | return ...; |
|
||||
| post | Switch.cs:113:9:113:11 | exit M10 | Switch.cs:120:9:120:18 | return ...; |
|
||||
| post | Switch.cs:114:5:121:5 | {...} | Switch.cs:113:9:113:11 | enter M10 |
|
||||
| post | Switch.cs:115:9:119:9 | switch (...) {...} | Switch.cs:114:5:121:5 | {...} |
|
||||
| post | Switch.cs:115:17:115:17 | access to parameter s | Switch.cs:115:9:119:9 | switch (...) {...} |
|
||||
| post | Switch.cs:115:17:115:24 | access to property Length | Switch.cs:115:17:115:17 | access to parameter s |
|
||||
| post | Switch.cs:117:13:117:34 | case ...: | Switch.cs:115:17:115:24 | access to property Length |
|
||||
| post | Switch.cs:117:18:117:18 | 3 | Switch.cs:117:13:117:34 | case ...: |
|
||||
| post | Switch.cs:117:25:117:32 | ... == ... | Switch.cs:117:28:117:32 | "foo" |
|
||||
| post | Switch.cs:117:28:117:32 | "foo" | Switch.cs:117:25:117:25 | access to parameter s |
|
||||
| post | Switch.cs:117:36:117:44 | return ...; | Switch.cs:117:43:117:43 | 1 |
|
||||
| post | Switch.cs:118:18:118:18 | 2 | Switch.cs:118:13:118:33 | case ...: |
|
||||
| post | Switch.cs:118:25:118:31 | ... == ... | Switch.cs:118:28:118:31 | "fu" |
|
||||
| post | Switch.cs:118:28:118:31 | "fu" | Switch.cs:118:25:118:25 | access to parameter s |
|
||||
| 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 | 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 | {...} |
|
||||
@@ -2643,6 +2661,27 @@
|
||||
| pre | Switch.cs:111:17:111:21 | enter Throw | Switch.cs:111:34:111:48 | object creation of type Exception |
|
||||
| pre | Switch.cs:111:28:111:48 | throw ... | Switch.cs:111:17:111:21 | exit Throw |
|
||||
| pre | Switch.cs:111:34:111:48 | object creation of type Exception | Switch.cs:111:28:111:48 | throw ... |
|
||||
| pre | Switch.cs:113:9:113:11 | enter M10 | Switch.cs:114:5:121:5 | {...} |
|
||||
| pre | Switch.cs:114:5:121:5 | {...} | Switch.cs:115:9:119:9 | switch (...) {...} |
|
||||
| pre | Switch.cs:115:9:119:9 | switch (...) {...} | Switch.cs:115:17:115:17 | access to parameter s |
|
||||
| pre | Switch.cs:115:17:115:17 | access to parameter s | Switch.cs:115:17:115:24 | access to property Length |
|
||||
| pre | Switch.cs:115:17:115:24 | access to property Length | Switch.cs:117:13:117:34 | case ...: |
|
||||
| pre | Switch.cs:117:13:117:34 | case ...: | Switch.cs:117:18:117:18 | 3 |
|
||||
| pre | Switch.cs:117:18:117:18 | 3 | Switch.cs:117:25:117:25 | access to parameter s |
|
||||
| pre | Switch.cs:117:18:117:18 | 3 | Switch.cs:118:13:118:33 | case ...: |
|
||||
| pre | Switch.cs:117:25:117:25 | access to parameter s | Switch.cs:117:28:117:32 | "foo" |
|
||||
| pre | Switch.cs:117:25:117:32 | ... == ... | Switch.cs:117:43:117:43 | 1 |
|
||||
| pre | Switch.cs:117:28:117:32 | "foo" | Switch.cs:117:25:117:32 | ... == ... |
|
||||
| pre | Switch.cs:117:43:117:43 | 1 | Switch.cs:117:36:117:44 | return ...; |
|
||||
| pre | Switch.cs:118:13:118:33 | case ...: | Switch.cs:118:18:118:18 | 2 |
|
||||
| pre | Switch.cs:118:18:118:18 | 2 | Switch.cs:118:25:118:25 | access to parameter s |
|
||||
| pre | Switch.cs:118:18:118:18 | 2 | Switch.cs:120:17:120:17 | 1 |
|
||||
| pre | Switch.cs:118:25:118:25 | access to parameter s | Switch.cs:118:28:118:31 | "fu" |
|
||||
| pre | Switch.cs:118:25:118:31 | ... == ... | Switch.cs:118:42:118:42 | 2 |
|
||||
| pre | Switch.cs:118:28:118:31 | "fu" | Switch.cs:118:25:118:31 | ... == ... |
|
||||
| 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 | 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:13:5:13 | access to local variable s |
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.controlflow.ControlFlowGraph
|
||||
|
||||
from ControlFlowNode dom, ControlFlowNode node, string s
|
||||
from ControlFlow::Node dom, ControlFlow::Node node, string s
|
||||
where
|
||||
dom.strictlyDominates(node) and dom.getASuccessor() = node and s = "pre"
|
||||
or
|
||||
|
||||
@@ -688,6 +688,28 @@
|
||||
| Switch.cs:108:16:108:17 | -... | Switch.cs:108:9:108:18 | return ...; | semmle.label | successor |
|
||||
| Switch.cs:108:17:108:17 | 1 | Switch.cs:108:16:108:17 | -... | semmle.label | successor |
|
||||
| Switch.cs:111:34:111:48 | object creation of type Exception | Switch.cs:111:28:111:48 | throw ... | semmle.label | successor |
|
||||
| Switch.cs:114:5:121:5 | {...} | Switch.cs:115:9:119:9 | switch (...) {...} | semmle.label | successor |
|
||||
| Switch.cs:115:9:119:9 | switch (...) {...} | Switch.cs:115:17:115:17 | access to parameter s | semmle.label | successor |
|
||||
| Switch.cs:115:17:115:17 | access to parameter s | Switch.cs:115:17:115:24 | access to property Length | semmle.label | successor |
|
||||
| Switch.cs:115:17:115:24 | access to property Length | Switch.cs:117:13:117:34 | case ...: | semmle.label | successor |
|
||||
| Switch.cs:117:13:117:34 | case ...: | Switch.cs:117:18:117:18 | 3 | semmle.label | successor |
|
||||
| Switch.cs:117:18:117:18 | 3 | Switch.cs:117:25:117:25 | access to parameter s | semmle.label | match |
|
||||
| Switch.cs:117:18:117:18 | 3 | Switch.cs:118:13:118:33 | case ...: | semmle.label | no-match |
|
||||
| Switch.cs:117:25:117:25 | access to parameter s | Switch.cs:117:28:117:32 | "foo" | semmle.label | successor |
|
||||
| Switch.cs:117:25:117:32 | ... == ... | Switch.cs:117:43:117:43 | 1 | semmle.label | true |
|
||||
| Switch.cs:117:25:117:32 | ... == ... | Switch.cs:118:13:118:33 | case ...: | semmle.label | false |
|
||||
| Switch.cs:117:28:117:32 | "foo" | Switch.cs:117:25:117:32 | ... == ... | semmle.label | successor |
|
||||
| Switch.cs:117:43:117:43 | 1 | Switch.cs:117:36:117:44 | return ...; | semmle.label | successor |
|
||||
| Switch.cs:118:13:118:33 | case ...: | Switch.cs:118:18:118:18 | 2 | semmle.label | successor |
|
||||
| Switch.cs:118:18:118:18 | 2 | Switch.cs:118:25:118:25 | access to parameter s | semmle.label | match |
|
||||
| Switch.cs:118:18:118:18 | 2 | Switch.cs:120:17:120:17 | 1 | semmle.label | no-match |
|
||||
| Switch.cs:118:25:118:25 | access to parameter s | Switch.cs:118:28:118:31 | "fu" | semmle.label | successor |
|
||||
| Switch.cs:118:25:118:31 | ... == ... | Switch.cs:118:42:118:42 | 2 | semmle.label | true |
|
||||
| Switch.cs:118:25:118:31 | ... == ... | Switch.cs:120:17:120:17 | 1 | semmle.label | false |
|
||||
| Switch.cs:118:28:118:31 | "fu" | Switch.cs:118:25:118:31 | ... == ... | semmle.label | successor |
|
||||
| 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 |
|
||||
| TypeAccesses.cs:4:5:9:5 | {...} | TypeAccesses.cs:5:9:5:26 | ... ...; | semmle.label | successor |
|
||||
| TypeAccesses.cs:5:9:5:26 | ... ...; | TypeAccesses.cs:5:13:5:13 | access to local variable s | semmle.label | successor |
|
||||
| TypeAccesses.cs:5:13:5:13 | access to local variable s | TypeAccesses.cs:5:25:5:25 | access to parameter o | semmle.label | successor |
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.controlflow.ControlFlowGraph
|
||||
|
||||
query predicate edges(ControlFlowElement node, ControlFlowElement successor, string attr, string val) {
|
||||
exists(ControlFlowEdgeType t |
|
||||
exists(ControlFlow::SuccessorType t |
|
||||
successor = node.getAControlFlowNode().getASuccessorByType(t).getElement() |
|
||||
attr = "semmle.label" and
|
||||
val = t.toString()
|
||||
|
||||
@@ -722,6 +722,27 @@
|
||||
| Switch.cs:108:17:108:17 | 1 | Switch.cs:108:17:108:17 | 1 |
|
||||
| Switch.cs:111:28:111:48 | throw ... | Switch.cs:111:34:111:48 | object creation of type Exception |
|
||||
| Switch.cs:111:34:111:48 | object creation of type Exception | Switch.cs:111:34:111:48 | object creation of type Exception |
|
||||
| Switch.cs:114:5:121:5 | {...} | Switch.cs:114:5:121:5 | {...} |
|
||||
| Switch.cs:115:9:119:9 | switch (...) {...} | Switch.cs:115:9:119:9 | switch (...) {...} |
|
||||
| Switch.cs:115:17:115:17 | access to parameter s | Switch.cs:115:17:115:17 | access to parameter s |
|
||||
| Switch.cs:115:17:115:24 | access to property Length | Switch.cs:115:17:115:17 | access to parameter s |
|
||||
| Switch.cs:117:13:117:34 | case ...: | Switch.cs:117:13:117:34 | case ...: |
|
||||
| Switch.cs:117:18:117:18 | 3 | Switch.cs:117:18:117:18 | 3 |
|
||||
| Switch.cs:117:25:117:25 | access to parameter s | Switch.cs:117:25:117:25 | access to parameter s |
|
||||
| Switch.cs:117:25:117:32 | ... == ... | Switch.cs:117:25:117:25 | access to parameter s |
|
||||
| Switch.cs:117:28:117:32 | "foo" | Switch.cs:117:28:117:32 | "foo" |
|
||||
| Switch.cs:117:36:117:44 | return ...; | Switch.cs:117:43:117:43 | 1 |
|
||||
| Switch.cs:117:43:117:43 | 1 | Switch.cs:117:43:117:43 | 1 |
|
||||
| Switch.cs:118:13:118:33 | case ...: | Switch.cs:118:13:118:33 | case ...: |
|
||||
| Switch.cs:118:18:118:18 | 2 | Switch.cs:118:18:118:18 | 2 |
|
||||
| Switch.cs:118:25:118:25 | access to parameter s | Switch.cs:118:25:118:25 | access to parameter s |
|
||||
| Switch.cs:118:25:118:31 | ... == ... | Switch.cs:118:25:118:25 | access to parameter s |
|
||||
| Switch.cs:118:28:118:31 | "fu" | Switch.cs:118:28:118:31 | "fu" |
|
||||
| Switch.cs:118:35:118:43 | return ...; | Switch.cs:118:42:118:42 | 2 |
|
||||
| Switch.cs:118:42:118:42 | 2 | Switch.cs:118:42:118:42 | 2 |
|
||||
| Switch.cs:120:9:120:18 | return ...; | Switch.cs:120:17:120:17 | 1 |
|
||||
| Switch.cs:120:16:120:17 | -... | Switch.cs:120:17:120:17 | 1 |
|
||||
| Switch.cs:120:17:120:17 | 1 | Switch.cs:120:17:120:17 | 1 |
|
||||
| TypeAccesses.cs:4:5:9:5 | {...} | TypeAccesses.cs:4:5:9:5 | {...} |
|
||||
| TypeAccesses.cs:5:9:5:26 | ... ...; | TypeAccesses.cs:5:9:5:26 | ... ...; |
|
||||
| TypeAccesses.cs:5:13:5:13 | access to local variable s | TypeAccesses.cs:5:13:5:13 | access to local variable s |
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import csharp
|
||||
import ControlFlowGraph::Internal
|
||||
import ControlFlow::Internal
|
||||
|
||||
from ControlFlowElement cfe
|
||||
select cfe, first(cfe)
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
| Switch.cs:91:10:91:11 | M8 | Switch.cs:92:5:99:5 | {...} |
|
||||
| Switch.cs:101:9:101:10 | M9 | Switch.cs:102:5:109:5 | {...} |
|
||||
| Switch.cs:111:17:111:21 | Throw | Switch.cs:111:34:111:48 | object creation of type Exception |
|
||||
| Switch.cs:113:9:113:11 | M10 | Switch.cs:114:5:121:5 | {...} |
|
||||
| TypeAccesses.cs:3:10:3:10 | M | TypeAccesses.cs:4:5:9:5 | {...} |
|
||||
| VarDecls.cs:5:18:5:19 | M1 | VarDecls.cs:6:5:11:5 | {...} |
|
||||
| VarDecls.cs:13:12:13:13 | M2 | VarDecls.cs:14:5:17:5 | {...} |
|
||||
|
||||
@@ -1020,6 +1020,40 @@
|
||||
| Switch.cs:108:17:108:17 | 1 | Switch.cs:108:17:108:17 | 1 | normal |
|
||||
| Switch.cs:111:28:111:48 | throw ... | Switch.cs:111:28:111:48 | throw ... | throw(Exception) |
|
||||
| Switch.cs:111:34:111:48 | object creation of type Exception | Switch.cs:111:34:111:48 | object creation of type Exception | normal |
|
||||
| Switch.cs:114:5:121:5 | {...} | Switch.cs:117:36:117:44 | return ...; | return |
|
||||
| Switch.cs:114:5:121:5 | {...} | Switch.cs:118:35:118:43 | return ...; | return |
|
||||
| Switch.cs:114:5:121:5 | {...} | Switch.cs:120:9:120:18 | return ...; | return |
|
||||
| Switch.cs:115:9:119:9 | switch (...) {...} | Switch.cs:117:36:117:44 | return ...; | return |
|
||||
| Switch.cs:115:9:119:9 | switch (...) {...} | Switch.cs:118:18:118:18 | 2 | no-match |
|
||||
| Switch.cs:115:9:119:9 | switch (...) {...} | Switch.cs:118:25:118:31 | ... == ... | false/false |
|
||||
| Switch.cs:115:9:119:9 | switch (...) {...} | Switch.cs:118:35:118:43 | return ...; | return |
|
||||
| Switch.cs:115:17:115:17 | access to parameter s | Switch.cs:115:17:115:17 | access to parameter s | normal |
|
||||
| Switch.cs:115:17:115:24 | access to property Length | Switch.cs:115:17:115:24 | access to property Length | normal |
|
||||
| Switch.cs:117:13:117:34 | case ...: | Switch.cs:117:18:117:18 | 3 | no-match |
|
||||
| Switch.cs:117:13:117:34 | case ...: | Switch.cs:117:25:117:32 | ... == ... | false/false |
|
||||
| Switch.cs:117:13:117:34 | case ...: | Switch.cs:117:36:117:44 | return ...; | return |
|
||||
| Switch.cs:117:18:117:18 | 3 | Switch.cs:117:18:117:18 | 3 | match |
|
||||
| Switch.cs:117:18:117:18 | 3 | Switch.cs:117:18:117:18 | 3 | no-match |
|
||||
| Switch.cs:117:25:117:25 | access to parameter s | Switch.cs:117:25:117:25 | access to parameter s | normal |
|
||||
| Switch.cs:117:25:117:32 | ... == ... | Switch.cs:117:25:117:32 | ... == ... | false/false |
|
||||
| Switch.cs:117:25:117:32 | ... == ... | Switch.cs:117:25:117:32 | ... == ... | true/true |
|
||||
| Switch.cs:117:28:117:32 | "foo" | Switch.cs:117:28:117:32 | "foo" | normal |
|
||||
| Switch.cs:117:36:117:44 | return ...; | Switch.cs:117:36:117:44 | return ...; | return |
|
||||
| Switch.cs:117:43:117:43 | 1 | Switch.cs:117:43:117:43 | 1 | normal |
|
||||
| Switch.cs:118:13:118:33 | case ...: | Switch.cs:118:18:118:18 | 2 | no-match |
|
||||
| Switch.cs:118:13:118:33 | case ...: | Switch.cs:118:25:118:31 | ... == ... | false/false |
|
||||
| Switch.cs:118:13:118:33 | case ...: | Switch.cs:118:35:118:43 | return ...; | return |
|
||||
| Switch.cs:118:18:118:18 | 2 | Switch.cs:118:18:118:18 | 2 | match |
|
||||
| Switch.cs:118:18:118:18 | 2 | Switch.cs:118:18:118:18 | 2 | no-match |
|
||||
| Switch.cs:118:25:118:25 | access to parameter s | Switch.cs:118:25:118:25 | access to parameter s | normal |
|
||||
| Switch.cs:118:25:118:31 | ... == ... | Switch.cs:118:25:118:31 | ... == ... | false/false |
|
||||
| Switch.cs:118:25:118:31 | ... == ... | Switch.cs:118:25:118:31 | ... == ... | true/true |
|
||||
| Switch.cs:118:28:118:31 | "fu" | Switch.cs:118:28:118:31 | "fu" | normal |
|
||||
| Switch.cs:118:35:118:43 | return ...; | Switch.cs:118:35:118:43 | return ...; | return |
|
||||
| Switch.cs:118:42:118:42 | 2 | Switch.cs:118:42:118:42 | 2 | normal |
|
||||
| Switch.cs:120:9:120:18 | return ...; | Switch.cs:120:9:120:18 | return ...; | return |
|
||||
| Switch.cs:120:16:120:17 | -... | Switch.cs:120:16:120:17 | -... | normal |
|
||||
| Switch.cs:120:17:120:17 | 1 | Switch.cs:120:17:120:17 | 1 | normal |
|
||||
| TypeAccesses.cs:4:5:9:5 | {...} | TypeAccesses.cs:8:13:8:27 | Type t = ... | normal |
|
||||
| TypeAccesses.cs:5:9:5:26 | ... ...; | TypeAccesses.cs:5:13:5:25 | String s = ... | normal |
|
||||
| TypeAccesses.cs:5:13:5:13 | access to local variable s | TypeAccesses.cs:5:13:5:13 | access to local variable s | normal |
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import csharp
|
||||
import ControlFlowGraph::Internal
|
||||
import ControlFlow::Internal
|
||||
private import semmle.code.csharp.controlflow.Completion
|
||||
|
||||
from ControlFlowElement cfe, Completion c
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.controlflow.ControlFlowGraph
|
||||
import ControlFlow
|
||||
import Internal
|
||||
import Nodes
|
||||
|
||||
class MyFinallySplitControlFlowNode extends ControlFlowElementNode {
|
||||
class MyFinallySplitControlFlowNode extends ElementNode {
|
||||
MyFinallySplitControlFlowNode() {
|
||||
exists(FinallySplitting::FinallySplitType type |
|
||||
type = this.getASplit().(FinallySplit).getType() |
|
||||
not type instanceof ControlFlowEdgeSuccessor
|
||||
not type instanceof SuccessorTypes::NormalSuccessor
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -976,6 +976,32 @@
|
||||
| Switch.cs:111:17:111:21 | enter Throw | Switch.cs:111:34:111:48 | object creation of type Exception | semmle.label | successor |
|
||||
| Switch.cs:111:28:111:48 | throw ... | Switch.cs:111:17:111:21 | exit Throw | semmle.label | exception(Exception) |
|
||||
| Switch.cs:111:34:111:48 | object creation of type Exception | Switch.cs:111:28:111:48 | throw ... | semmle.label | successor |
|
||||
| Switch.cs:113:9:113:11 | enter M10 | Switch.cs:114:5:121:5 | {...} | semmle.label | successor |
|
||||
| Switch.cs:114:5:121:5 | {...} | Switch.cs:115:9:119:9 | switch (...) {...} | semmle.label | successor |
|
||||
| Switch.cs:115:9:119:9 | switch (...) {...} | Switch.cs:115:17:115:17 | access to parameter s | semmle.label | successor |
|
||||
| Switch.cs:115:17:115:17 | access to parameter s | Switch.cs:115:17:115:24 | access to property Length | semmle.label | successor |
|
||||
| Switch.cs:115:17:115:24 | access to property Length | Switch.cs:117:13:117:34 | case ...: | semmle.label | successor |
|
||||
| Switch.cs:117:13:117:34 | case ...: | Switch.cs:117:18:117:18 | 3 | semmle.label | successor |
|
||||
| Switch.cs:117:18:117:18 | 3 | Switch.cs:117:25:117:25 | access to parameter s | semmle.label | match |
|
||||
| Switch.cs:117:18:117:18 | 3 | Switch.cs:118:13:118:33 | case ...: | semmle.label | no-match |
|
||||
| Switch.cs:117:25:117:25 | access to parameter s | Switch.cs:117:28:117:32 | "foo" | semmle.label | successor |
|
||||
| Switch.cs:117:25:117:32 | ... == ... | Switch.cs:117:43:117:43 | 1 | semmle.label | true |
|
||||
| Switch.cs:117:25:117:32 | ... == ... | Switch.cs:118:13:118:33 | case ...: | semmle.label | false |
|
||||
| Switch.cs:117:28:117:32 | "foo" | Switch.cs:117:25:117:32 | ... == ... | semmle.label | successor |
|
||||
| Switch.cs:117:36:117:44 | return ...; | Switch.cs:113:9:113:11 | exit M10 | semmle.label | return |
|
||||
| Switch.cs:117:43:117:43 | 1 | Switch.cs:117:36:117:44 | return ...; | semmle.label | successor |
|
||||
| Switch.cs:118:13:118:33 | case ...: | Switch.cs:118:18:118:18 | 2 | semmle.label | successor |
|
||||
| Switch.cs:118:18:118:18 | 2 | Switch.cs:118:25:118:25 | access to parameter s | semmle.label | match |
|
||||
| Switch.cs:118:18:118:18 | 2 | Switch.cs:120:17:120:17 | 1 | semmle.label | no-match |
|
||||
| Switch.cs:118:25:118:25 | access to parameter s | Switch.cs:118:28:118:31 | "fu" | semmle.label | successor |
|
||||
| Switch.cs:118:25:118:31 | ... == ... | Switch.cs:118:42:118:42 | 2 | semmle.label | true |
|
||||
| Switch.cs:118:25:118:31 | ... == ... | Switch.cs:120:17:120:17 | 1 | semmle.label | false |
|
||||
| Switch.cs:118:28:118:31 | "fu" | Switch.cs:118:25:118:31 | ... == ... | semmle.label | successor |
|
||||
| Switch.cs:118:35:118:43 | return ...; | Switch.cs:113:9:113:11 | exit M10 | semmle.label | return |
|
||||
| Switch.cs:118:42:118:42 | 2 | Switch.cs:118:35:118:43 | return ...; | semmle.label | successor |
|
||||
| Switch.cs:120:9:120:18 | return ...; | Switch.cs:113:9:113:11 | exit M10 | semmle.label | return |
|
||||
| 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 |
|
||||
| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:4:5:9:5 | {...} | 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:13:5:13 | access to local variable s | semmle.label | successor |
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.controlflow.ControlFlowGraph
|
||||
|
||||
query predicate edges(ControlFlowNode node, ControlFlowNode successor, string attr, string val) {
|
||||
exists(ControlFlowEdgeType t |
|
||||
query predicate edges(ControlFlow::Node node, ControlFlow::Node successor, string attr, string val) {
|
||||
exists(ControlFlow::SuccessorType t |
|
||||
successor = node.getASuccessorByType(t) |
|
||||
attr = "semmle.label" and
|
||||
val = t.toString()
|
||||
|
||||
@@ -109,4 +109,14 @@ class Switch
|
||||
}
|
||||
|
||||
static bool Throw() => throw new Exception();
|
||||
|
||||
int M10(string s)
|
||||
{
|
||||
switch (s.Length)
|
||||
{
|
||||
case 3 when s=="foo" : return 1;
|
||||
case 2 when s=="fu" : return 2;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,6 +250,11 @@ class Patterns
|
||||
{
|
||||
case "xyz":
|
||||
break;
|
||||
case "" when 1 < 2:
|
||||
break;
|
||||
case "x" when o is string s4:
|
||||
Console.WriteLine($"x {s4}");
|
||||
break;
|
||||
case int i2 when i2 > 0:
|
||||
Console.WriteLine($"positive {i2}");
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
| CSharp7.cs:253:13:253:31 | case ...: | CSharp7.cs:253:26:253:30 | ... < ... |
|
||||
| CSharp7.cs:255:13:255:41 | case ...: | CSharp7.cs:255:27:255:40 | ... is ... |
|
||||
| CSharp7.cs:258:13:258:36 | case Int32 i2: | CSharp7.cs:258:30:258:35 | ... > ... |
|
||||
4
csharp/ql/test/library-tests/csharp7/CaseCondition.ql
Normal file
4
csharp/ql/test/library-tests/csharp7/CaseCondition.ql
Normal file
@@ -0,0 +1,4 @@
|
||||
import csharp
|
||||
|
||||
from CaseStmt stmt
|
||||
select stmt, stmt.getCondition()
|
||||
@@ -51,16 +51,18 @@
|
||||
| CSharp7.cs:233:16:233:23 | Object o = ... | CSharp7.cs:242:18:242:18 | access to local variable o |
|
||||
| CSharp7.cs:233:16:233:23 | Object o = ... | CSharp7.cs:245:18:245:18 | access to local variable o |
|
||||
| CSharp7.cs:233:16:233:23 | Object o = ... | CSharp7.cs:249:17:249:17 | access to local variable o |
|
||||
| CSharp7.cs:233:16:233:23 | Object o = ... | CSharp7.cs:255:27:255:27 | access to local variable o |
|
||||
| CSharp7.cs:234:18:234:23 | Int32 i1 | CSharp7.cs:234:28:234:29 | access to local variable i1 |
|
||||
| CSharp7.cs:234:18:234:23 | Int32 i1 | CSharp7.cs:236:38:236:39 | access to local variable i1 |
|
||||
| CSharp7.cs:238:23:238:31 | String s1 | CSharp7.cs:240:41:240:42 | access to local variable s1 |
|
||||
| CSharp7.cs:253:18:253:23 | Int32 i2 | CSharp7.cs:253:30:253:31 | access to local variable i2 |
|
||||
| CSharp7.cs:253:18:253:23 | Int32 i2 | CSharp7.cs:254:47:254:48 | access to local variable i2 |
|
||||
| CSharp7.cs:256:18:256:23 | Int32 i3 | CSharp7.cs:257:42:257:43 | access to local variable i3 |
|
||||
| CSharp7.cs:259:18:259:26 | String s2 | CSharp7.cs:260:45:260:46 | access to local variable s2 |
|
||||
| CSharp7.cs:278:13:278:48 | Dictionary<Int32,String> dict = ... | CSharp7.cs:279:20:279:23 | access to local variable dict |
|
||||
| CSharp7.cs:279:13:279:62 | IEnumerable<(Int32,String)> list = ... | CSharp7.cs:281:39:281:42 | access to local variable list |
|
||||
| CSharp7.cs:279:13:279:62 | IEnumerable<(Int32,String)> list = ... | CSharp7.cs:283:36:283:39 | access to local variable list |
|
||||
| CSharp7.cs:279:13:279:62 | IEnumerable<(Int32,String)> list = ... | CSharp7.cs:285:32:285:35 | access to local variable list |
|
||||
| CSharp7.cs:279:32:279:35 | item | CSharp7.cs:279:41:279:44 | access to parameter item |
|
||||
| CSharp7.cs:279:32:279:35 | item | CSharp7.cs:279:51:279:54 | access to parameter item |
|
||||
| CSharp7.cs:255:32:255:40 | String s4 | CSharp7.cs:256:40:256:41 | access to local variable s4 |
|
||||
| CSharp7.cs:258:18:258:23 | Int32 i2 | CSharp7.cs:258:30:258:31 | access to local variable i2 |
|
||||
| CSharp7.cs:258:18:258:23 | Int32 i2 | CSharp7.cs:259:47:259:48 | access to local variable i2 |
|
||||
| CSharp7.cs:261:18:261:23 | Int32 i3 | CSharp7.cs:262:42:262:43 | access to local variable i3 |
|
||||
| CSharp7.cs:264:18:264:26 | String s2 | CSharp7.cs:265:45:265:46 | access to local variable s2 |
|
||||
| CSharp7.cs:283:13:283:48 | Dictionary<Int32,String> dict = ... | CSharp7.cs:284:20:284:23 | access to local variable dict |
|
||||
| CSharp7.cs:284:13:284:62 | IEnumerable<(Int32,String)> list = ... | CSharp7.cs:286:39:286:42 | access to local variable list |
|
||||
| CSharp7.cs:284:13:284:62 | IEnumerable<(Int32,String)> list = ... | CSharp7.cs:288:36:288:39 | access to local variable list |
|
||||
| CSharp7.cs:284:13:284:62 | IEnumerable<(Int32,String)> list = ... | CSharp7.cs:290:32:290:35 | access to local variable list |
|
||||
| CSharp7.cs:284:32:284:35 | item | CSharp7.cs:284:41:284:44 | access to parameter item |
|
||||
| CSharp7.cs:284:32:284:35 | item | CSharp7.cs:284:51:284:54 | access to parameter item |
|
||||
|
||||
@@ -15,4 +15,4 @@
|
||||
| CSharp7.cs:165:13:165:31 | f2 | CSharp7.cs:165:25:165:30 | call to local function f |
|
||||
| CSharp7.cs:177:9:177:40 | f | CSharp7.cs:177:31:177:39 | ... + ... |
|
||||
| CSharp7.cs:178:9:178:32 | g | CSharp7.cs:178:31:178:31 | access to parameter s |
|
||||
| CSharp7.cs:279:32:279:61 | (...) => ... | CSharp7.cs:279:40:279:61 | (..., ...) |
|
||||
| CSharp7.cs:284:32:284:61 | (...) => ... | CSharp7.cs:284:40:284:61 | (..., ...) |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
| CSharp7.cs:281:9:281:47 | foreach (... ... in ...) ... | 0 | CSharp7.cs:281:23:281:23 | Int32 a | CSharp7.cs:281:23:281:23 | a | CSharp7.cs:281:39:281:42 | access to local variable list | CSharp7.cs:281:45:281:47 | {...} |
|
||||
| CSharp7.cs:281:9:281:47 | foreach (... ... in ...) ... | 1 | CSharp7.cs:281:33:281:33 | String b | CSharp7.cs:281:33:281:33 | b | CSharp7.cs:281:39:281:42 | access to local variable list | CSharp7.cs:281:45:281:47 | {...} |
|
||||
| CSharp7.cs:283:9:283:44 | foreach (... ... in ...) ... | 0 | CSharp7.cs:283:23:283:23 | Int32 a | CSharp7.cs:283:23:283:23 | a | CSharp7.cs:283:36:283:39 | access to local variable list | CSharp7.cs:283:42:283:44 | {...} |
|
||||
| CSharp7.cs:283:9:283:44 | foreach (... ... in ...) ... | 1 | CSharp7.cs:283:30:283:30 | String b | CSharp7.cs:283:30:283:30 | b | CSharp7.cs:283:36:283:39 | access to local variable list | CSharp7.cs:283:42:283:44 | {...} |
|
||||
| CSharp7.cs:285:9:285:40 | foreach (... ... in ...) ... | 0 | CSharp7.cs:285:23:285:23 | Int32 a | CSharp7.cs:285:23:285:23 | a | CSharp7.cs:285:32:285:35 | access to local variable list | CSharp7.cs:285:38:285:40 | {...} |
|
||||
| CSharp7.cs:285:9:285:40 | foreach (... ... in ...) ... | 1 | CSharp7.cs:285:26:285:26 | String b | CSharp7.cs:285:26:285:26 | b | CSharp7.cs:285:32:285:35 | access to local variable list | CSharp7.cs:285:38:285:40 | {...} |
|
||||
| CSharp7.cs:286:9:286:47 | foreach (... ... in ...) ... | 0 | CSharp7.cs:286:23:286:23 | Int32 a | CSharp7.cs:286:23:286:23 | a | CSharp7.cs:286:39:286:42 | access to local variable list | CSharp7.cs:286:45:286:47 | {...} |
|
||||
| CSharp7.cs:286:9:286:47 | foreach (... ... in ...) ... | 1 | CSharp7.cs:286:33:286:33 | String b | CSharp7.cs:286:33:286:33 | b | CSharp7.cs:286:39:286:42 | access to local variable list | CSharp7.cs:286:45:286:47 | {...} |
|
||||
| CSharp7.cs:288:9:288:44 | foreach (... ... in ...) ... | 0 | CSharp7.cs:288:23:288:23 | Int32 a | CSharp7.cs:288:23:288:23 | a | CSharp7.cs:288:36:288:39 | access to local variable list | CSharp7.cs:288:42:288:44 | {...} |
|
||||
| CSharp7.cs:288:9:288:44 | foreach (... ... in ...) ... | 1 | CSharp7.cs:288:30:288:30 | String b | CSharp7.cs:288:30:288:30 | b | CSharp7.cs:288:36:288:39 | access to local variable list | CSharp7.cs:288:42:288:44 | {...} |
|
||||
| CSharp7.cs:290:9:290:40 | foreach (... ... in ...) ... | 0 | CSharp7.cs:290:23:290:23 | Int32 a | CSharp7.cs:290:23:290:23 | a | CSharp7.cs:290:32:290:35 | access to local variable list | CSharp7.cs:290:38:290:40 | {...} |
|
||||
| CSharp7.cs:290:9:290:40 | foreach (... ... in ...) ... | 1 | CSharp7.cs:290:26:290:26 | String b | CSharp7.cs:290:26:290:26 | b | CSharp7.cs:290:32:290:35 | access to local variable list | CSharp7.cs:290:38:290:40 | {...} |
|
||||
|
||||
@@ -1,57 +1,77 @@
|
||||
| CSharp7.cs:249:9:270:9 | switch (...) {...} | CSharp7.cs:249:17:249:17 | access to local variable o | semmle.label | successor |
|
||||
| CSharp7.cs:249:9:275:9 | switch (...) {...} | CSharp7.cs:249:17:249:17 | access to local variable o | semmle.label | successor |
|
||||
| CSharp7.cs:249:17:249:17 | access to local variable o | CSharp7.cs:251:13:251:23 | case ...: | semmle.label | successor |
|
||||
| CSharp7.cs:251:13:251:23 | case ...: | CSharp7.cs:251:18:251:22 | "xyz" | semmle.label | successor |
|
||||
| CSharp7.cs:251:18:251:22 | "xyz" | CSharp7.cs:252:17:252:22 | break; | semmle.label | match |
|
||||
| CSharp7.cs:251:18:251:22 | "xyz" | CSharp7.cs:253:13:253:36 | case Int32 i2: | semmle.label | no-match |
|
||||
| CSharp7.cs:251:18:251:22 | "xyz" | CSharp7.cs:253:13:253:31 | case ...: | semmle.label | no-match |
|
||||
| CSharp7.cs:252:17:252:22 | break; | CSharp7.cs:231:10:231:13 | exit Test | semmle.label | break |
|
||||
| CSharp7.cs:253:13:253:36 | case Int32 i2: | CSharp7.cs:253:18:253:20 | access to type Int32 | semmle.label | successor |
|
||||
| CSharp7.cs:253:18:253:20 | access to type Int32 | CSharp7.cs:253:18:253:23 | Int32 i2 | semmle.label | match |
|
||||
| CSharp7.cs:253:18:253:20 | access to type Int32 | CSharp7.cs:256:13:256:24 | case Int32 i3: | semmle.label | no-match |
|
||||
| CSharp7.cs:253:18:253:23 | Int32 i2 | CSharp7.cs:253:30:253:31 | access to local variable i2 | semmle.label | successor |
|
||||
| CSharp7.cs:253:30:253:31 | access to local variable i2 | CSharp7.cs:253:35:253:35 | 0 | semmle.label | successor |
|
||||
| CSharp7.cs:253:30:253:35 | ... > ... | CSharp7.cs:254:17:254:52 | ...; | semmle.label | true |
|
||||
| CSharp7.cs:253:30:253:35 | ... > ... | CSharp7.cs:256:13:256:24 | case Int32 i3: | semmle.label | false |
|
||||
| CSharp7.cs:253:35:253:35 | 0 | CSharp7.cs:253:30:253:35 | ... > ... | semmle.label | successor |
|
||||
| CSharp7.cs:254:17:254:51 | call to method WriteLine | CSharp7.cs:255:17:255:22 | break; | semmle.label | successor |
|
||||
| CSharp7.cs:254:17:254:52 | ...; | CSharp7.cs:254:37:254:45 | "positive " | semmle.label | successor |
|
||||
| CSharp7.cs:254:35:254:50 | $"..." | CSharp7.cs:254:17:254:51 | call to method WriteLine | semmle.label | successor |
|
||||
| CSharp7.cs:254:37:254:45 | "positive " | CSharp7.cs:254:47:254:48 | access to local variable i2 | semmle.label | successor |
|
||||
| CSharp7.cs:254:47:254:48 | access to local variable i2 | CSharp7.cs:254:35:254:50 | $"..." | semmle.label | successor |
|
||||
| CSharp7.cs:255:17:255:22 | break; | CSharp7.cs:231:10:231:13 | exit Test | semmle.label | break |
|
||||
| CSharp7.cs:256:13:256:24 | case Int32 i3: | CSharp7.cs:256:18:256:20 | access to type Int32 | semmle.label | successor |
|
||||
| CSharp7.cs:256:18:256:20 | access to type Int32 | CSharp7.cs:256:18:256:23 | Int32 i3 | semmle.label | match |
|
||||
| CSharp7.cs:256:18:256:20 | access to type Int32 | CSharp7.cs:259:13:259:27 | case String s2: | semmle.label | no-match |
|
||||
| CSharp7.cs:256:18:256:23 | Int32 i3 | CSharp7.cs:257:17:257:47 | ...; | semmle.label | successor |
|
||||
| CSharp7.cs:257:17:257:46 | call to method WriteLine | CSharp7.cs:258:17:258:22 | break; | semmle.label | successor |
|
||||
| CSharp7.cs:257:17:257:47 | ...; | CSharp7.cs:257:37:257:40 | "int " | semmle.label | successor |
|
||||
| CSharp7.cs:257:35:257:45 | $"..." | CSharp7.cs:257:17:257:46 | call to method WriteLine | semmle.label | successor |
|
||||
| CSharp7.cs:257:37:257:40 | "int " | CSharp7.cs:257:42:257:43 | access to local variable i3 | semmle.label | successor |
|
||||
| CSharp7.cs:257:42:257:43 | access to local variable i3 | CSharp7.cs:257:35:257:45 | $"..." | semmle.label | successor |
|
||||
| CSharp7.cs:258:17:258:22 | break; | CSharp7.cs:231:10:231:13 | exit Test | semmle.label | break |
|
||||
| CSharp7.cs:259:13:259:27 | case String s2: | CSharp7.cs:259:18:259:23 | access to type String | semmle.label | successor |
|
||||
| CSharp7.cs:259:18:259:23 | access to type String | CSharp7.cs:259:18:259:26 | String s2 | semmle.label | match |
|
||||
| CSharp7.cs:259:18:259:23 | access to type String | CSharp7.cs:262:13:262:26 | case Double: | semmle.label | no-match |
|
||||
| CSharp7.cs:259:18:259:26 | String s2 | CSharp7.cs:260:17:260:50 | ...; | semmle.label | successor |
|
||||
| CSharp7.cs:260:17:260:49 | call to method WriteLine | CSharp7.cs:261:17:261:22 | break; | semmle.label | successor |
|
||||
| CSharp7.cs:260:17:260:50 | ...; | CSharp7.cs:260:37:260:43 | "string " | semmle.label | successor |
|
||||
| CSharp7.cs:260:35:260:48 | $"..." | CSharp7.cs:260:17:260:49 | call to method WriteLine | semmle.label | successor |
|
||||
| CSharp7.cs:260:37:260:43 | "string " | CSharp7.cs:260:45:260:46 | access to local variable s2 | semmle.label | successor |
|
||||
| CSharp7.cs:260:45:260:46 | access to local variable s2 | CSharp7.cs:260:35:260:48 | $"..." | semmle.label | successor |
|
||||
| CSharp7.cs:261:17:261:22 | break; | CSharp7.cs:231:10:231:13 | exit Test | semmle.label | break |
|
||||
| CSharp7.cs:262:13:262:26 | case Double: | CSharp7.cs:262:18:262:23 | access to type Double | semmle.label | successor |
|
||||
| CSharp7.cs:262:18:262:23 | access to type Double | CSharp7.cs:263:17:263:44 | ...; | semmle.label | match |
|
||||
| CSharp7.cs:262:18:262:23 | access to type Double | CSharp7.cs:265:13:265:24 | case Object v2: | semmle.label | no-match |
|
||||
| CSharp7.cs:263:17:263:43 | call to method WriteLine | CSharp7.cs:264:17:264:22 | break; | semmle.label | successor |
|
||||
| CSharp7.cs:263:17:263:44 | ...; | CSharp7.cs:263:35:263:42 | "Double" | semmle.label | successor |
|
||||
| CSharp7.cs:263:35:263:42 | "Double" | CSharp7.cs:263:17:263:43 | call to method WriteLine | semmle.label | successor |
|
||||
| CSharp7.cs:264:17:264:22 | break; | CSharp7.cs:231:10:231:13 | exit Test | semmle.label | break |
|
||||
| CSharp7.cs:265:13:265:24 | case Object v2: | CSharp7.cs:265:18:265:20 | access to type Object | semmle.label | successor |
|
||||
| CSharp7.cs:265:18:265:20 | access to type Object | CSharp7.cs:265:18:265:23 | Object v2 | semmle.label | match |
|
||||
| CSharp7.cs:265:18:265:20 | access to type Object | CSharp7.cs:267:13:267:20 | default: | semmle.label | no-match |
|
||||
| CSharp7.cs:265:18:265:23 | Object v2 | CSharp7.cs:266:17:266:22 | break; | semmle.label | successor |
|
||||
| CSharp7.cs:253:13:253:31 | case ...: | CSharp7.cs:253:18:253:19 | "" | semmle.label | successor |
|
||||
| CSharp7.cs:253:18:253:19 | "" | CSharp7.cs:253:26:253:26 | 1 | semmle.label | match |
|
||||
| CSharp7.cs:253:18:253:19 | "" | CSharp7.cs:255:13:255:41 | case ...: | semmle.label | no-match |
|
||||
| CSharp7.cs:253:26:253:26 | 1 | CSharp7.cs:253:30:253:30 | 2 | semmle.label | successor |
|
||||
| CSharp7.cs:253:26:253:30 | ... < ... | CSharp7.cs:254:17:254:22 | break; | semmle.label | true |
|
||||
| CSharp7.cs:253:30:253:30 | 2 | CSharp7.cs:253:26:253:30 | ... < ... | semmle.label | successor |
|
||||
| CSharp7.cs:254:17:254:22 | break; | CSharp7.cs:231:10:231:13 | exit Test | semmle.label | break |
|
||||
| CSharp7.cs:255:13:255:41 | case ...: | CSharp7.cs:255:18:255:20 | "x" | semmle.label | successor |
|
||||
| CSharp7.cs:255:18:255:20 | "x" | CSharp7.cs:255:27:255:27 | access to local variable o | semmle.label | match |
|
||||
| CSharp7.cs:255:18:255:20 | "x" | CSharp7.cs:258:13:258:36 | case Int32 i2: | semmle.label | no-match |
|
||||
| CSharp7.cs:255:27:255:27 | access to local variable o | CSharp7.cs:255:32:255:40 | String s4 | semmle.label | successor |
|
||||
| CSharp7.cs:255:27:255:40 | ... is ... | CSharp7.cs:256:17:256:45 | ...; | semmle.label | true |
|
||||
| CSharp7.cs:255:27:255:40 | ... is ... | CSharp7.cs:258:13:258:36 | case Int32 i2: | semmle.label | false |
|
||||
| CSharp7.cs:255:32:255:40 | String s4 | CSharp7.cs:255:27:255:40 | ... is ... | semmle.label | successor |
|
||||
| CSharp7.cs:256:17:256:44 | call to method WriteLine | CSharp7.cs:257:17:257:22 | break; | semmle.label | successor |
|
||||
| CSharp7.cs:256:17:256:45 | ...; | CSharp7.cs:256:37:256:38 | "x " | semmle.label | successor |
|
||||
| CSharp7.cs:256:35:256:43 | $"..." | CSharp7.cs:256:17:256:44 | call to method WriteLine | semmle.label | successor |
|
||||
| CSharp7.cs:256:37:256:38 | "x " | CSharp7.cs:256:40:256:41 | access to local variable s4 | semmle.label | successor |
|
||||
| CSharp7.cs:256:40:256:41 | access to local variable s4 | CSharp7.cs:256:35:256:43 | $"..." | semmle.label | successor |
|
||||
| CSharp7.cs:257:17:257:22 | break; | CSharp7.cs:231:10:231:13 | exit Test | semmle.label | break |
|
||||
| CSharp7.cs:258:13:258:36 | case Int32 i2: | CSharp7.cs:258:18:258:20 | access to type Int32 | semmle.label | successor |
|
||||
| CSharp7.cs:258:18:258:20 | access to type Int32 | CSharp7.cs:258:18:258:23 | Int32 i2 | semmle.label | match |
|
||||
| CSharp7.cs:258:18:258:20 | access to type Int32 | CSharp7.cs:261:13:261:24 | case Int32 i3: | semmle.label | no-match |
|
||||
| CSharp7.cs:258:18:258:23 | Int32 i2 | CSharp7.cs:258:30:258:31 | access to local variable i2 | semmle.label | successor |
|
||||
| CSharp7.cs:258:30:258:31 | access to local variable i2 | CSharp7.cs:258:35:258:35 | 0 | semmle.label | successor |
|
||||
| CSharp7.cs:258:30:258:35 | ... > ... | CSharp7.cs:259:17:259:52 | ...; | semmle.label | true |
|
||||
| CSharp7.cs:258:30:258:35 | ... > ... | CSharp7.cs:261:13:261:24 | case Int32 i3: | semmle.label | false |
|
||||
| CSharp7.cs:258:35:258:35 | 0 | CSharp7.cs:258:30:258:35 | ... > ... | semmle.label | successor |
|
||||
| CSharp7.cs:259:17:259:51 | call to method WriteLine | CSharp7.cs:260:17:260:22 | break; | semmle.label | successor |
|
||||
| CSharp7.cs:259:17:259:52 | ...; | CSharp7.cs:259:37:259:45 | "positive " | semmle.label | successor |
|
||||
| CSharp7.cs:259:35:259:50 | $"..." | CSharp7.cs:259:17:259:51 | call to method WriteLine | semmle.label | successor |
|
||||
| CSharp7.cs:259:37:259:45 | "positive " | CSharp7.cs:259:47:259:48 | access to local variable i2 | semmle.label | successor |
|
||||
| CSharp7.cs:259:47:259:48 | access to local variable i2 | CSharp7.cs:259:35:259:50 | $"..." | semmle.label | successor |
|
||||
| CSharp7.cs:260:17:260:22 | break; | CSharp7.cs:231:10:231:13 | exit Test | semmle.label | break |
|
||||
| CSharp7.cs:261:13:261:24 | case Int32 i3: | CSharp7.cs:261:18:261:20 | access to type Int32 | semmle.label | successor |
|
||||
| CSharp7.cs:261:18:261:20 | access to type Int32 | CSharp7.cs:261:18:261:23 | Int32 i3 | semmle.label | match |
|
||||
| CSharp7.cs:261:18:261:20 | access to type Int32 | CSharp7.cs:264:13:264:27 | case String s2: | semmle.label | no-match |
|
||||
| CSharp7.cs:261:18:261:23 | Int32 i3 | CSharp7.cs:262:17:262:47 | ...; | semmle.label | successor |
|
||||
| CSharp7.cs:262:17:262:46 | call to method WriteLine | CSharp7.cs:263:17:263:22 | break; | semmle.label | successor |
|
||||
| CSharp7.cs:262:17:262:47 | ...; | CSharp7.cs:262:37:262:40 | "int " | semmle.label | successor |
|
||||
| CSharp7.cs:262:35:262:45 | $"..." | CSharp7.cs:262:17:262:46 | call to method WriteLine | semmle.label | successor |
|
||||
| CSharp7.cs:262:37:262:40 | "int " | CSharp7.cs:262:42:262:43 | access to local variable i3 | semmle.label | successor |
|
||||
| CSharp7.cs:262:42:262:43 | access to local variable i3 | CSharp7.cs:262:35:262:45 | $"..." | semmle.label | successor |
|
||||
| CSharp7.cs:263:17:263:22 | break; | CSharp7.cs:231:10:231:13 | exit Test | semmle.label | break |
|
||||
| CSharp7.cs:264:13:264:27 | case String s2: | CSharp7.cs:264:18:264:23 | access to type String | semmle.label | successor |
|
||||
| CSharp7.cs:264:18:264:23 | access to type String | CSharp7.cs:264:18:264:26 | String s2 | semmle.label | match |
|
||||
| CSharp7.cs:264:18:264:23 | access to type String | CSharp7.cs:267:13:267:26 | case Double: | semmle.label | no-match |
|
||||
| CSharp7.cs:264:18:264:26 | String s2 | CSharp7.cs:265:17:265:50 | ...; | semmle.label | successor |
|
||||
| CSharp7.cs:265:17:265:49 | call to method WriteLine | CSharp7.cs:266:17:266:22 | break; | semmle.label | successor |
|
||||
| CSharp7.cs:265:17:265:50 | ...; | CSharp7.cs:265:37:265:43 | "string " | semmle.label | successor |
|
||||
| CSharp7.cs:265:35:265:48 | $"..." | CSharp7.cs:265:17:265:49 | call to method WriteLine | semmle.label | successor |
|
||||
| CSharp7.cs:265:37:265:43 | "string " | CSharp7.cs:265:45:265:46 | access to local variable s2 | semmle.label | successor |
|
||||
| CSharp7.cs:265:45:265:46 | access to local variable s2 | CSharp7.cs:265:35:265:48 | $"..." | semmle.label | successor |
|
||||
| CSharp7.cs:266:17:266:22 | break; | CSharp7.cs:231:10:231:13 | exit Test | semmle.label | break |
|
||||
| CSharp7.cs:267:13:267:20 | default: | CSharp7.cs:268:17:268:52 | ...; | semmle.label | successor |
|
||||
| CSharp7.cs:268:17:268:51 | call to method WriteLine | CSharp7.cs:269:17:269:22 | break; | semmle.label | successor |
|
||||
| CSharp7.cs:268:17:268:52 | ...; | CSharp7.cs:268:35:268:50 | "Something else" | semmle.label | successor |
|
||||
| CSharp7.cs:268:35:268:50 | "Something else" | CSharp7.cs:268:17:268:51 | call to method WriteLine | semmle.label | successor |
|
||||
| CSharp7.cs:267:13:267:26 | case Double: | CSharp7.cs:267:18:267:23 | access to type Double | semmle.label | successor |
|
||||
| CSharp7.cs:267:18:267:23 | access to type Double | CSharp7.cs:268:17:268:44 | ...; | semmle.label | match |
|
||||
| CSharp7.cs:267:18:267:23 | access to type Double | CSharp7.cs:270:13:270:24 | case Object v2: | semmle.label | no-match |
|
||||
| CSharp7.cs:268:17:268:43 | call to method WriteLine | CSharp7.cs:269:17:269:22 | break; | semmle.label | successor |
|
||||
| CSharp7.cs:268:17:268:44 | ...; | CSharp7.cs:268:35:268:42 | "Double" | semmle.label | successor |
|
||||
| CSharp7.cs:268:35:268:42 | "Double" | CSharp7.cs:268:17:268:43 | call to method WriteLine | semmle.label | successor |
|
||||
| CSharp7.cs:269:17:269:22 | break; | CSharp7.cs:231:10:231:13 | exit Test | semmle.label | break |
|
||||
| CSharp7.cs:270:13:270:24 | case Object v2: | CSharp7.cs:270:18:270:20 | access to type Object | semmle.label | successor |
|
||||
| CSharp7.cs:270:18:270:20 | access to type Object | CSharp7.cs:270:18:270:23 | Object v2 | semmle.label | match |
|
||||
| CSharp7.cs:270:18:270:20 | access to type Object | CSharp7.cs:272:13:272:20 | default: | semmle.label | no-match |
|
||||
| CSharp7.cs:270:18:270:23 | Object v2 | CSharp7.cs:271:17:271:22 | break; | semmle.label | successor |
|
||||
| CSharp7.cs:271:17:271:22 | break; | CSharp7.cs:231:10:231:13 | exit Test | semmle.label | break |
|
||||
| CSharp7.cs:272:13:272:20 | default: | CSharp7.cs:273:17:273:52 | ...; | semmle.label | successor |
|
||||
| CSharp7.cs:273:17:273:51 | call to method WriteLine | CSharp7.cs:274:17:274:22 | break; | semmle.label | successor |
|
||||
| CSharp7.cs:273:17:273:52 | ...; | CSharp7.cs:273:35:273:50 | "Something else" | semmle.label | successor |
|
||||
| CSharp7.cs:273:35:273:50 | "Something else" | CSharp7.cs:273:17:273:51 | call to method WriteLine | semmle.label | successor |
|
||||
| CSharp7.cs:274:17:274:22 | break; | CSharp7.cs:231:10:231:13 | exit Test | semmle.label | break |
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.controlflow.ControlFlowGraph
|
||||
|
||||
query predicate edges(ControlFlowNode n1, ControlFlowNode n2, string attr, string val) {
|
||||
exists(SwitchStmt switch, ControlFlowEdgeType t |
|
||||
query predicate edges(ControlFlow::Node n1, ControlFlow::Node n2, string attr, string val) {
|
||||
exists(SwitchStmt switch, ControlFlow::SuccessorType t |
|
||||
switch.getAControlFlowNode().getASuccessor*()=n1 |
|
||||
n2 = n1.getASuccessorByType(t) and
|
||||
attr = "semmle.label" and
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
| CSharp7.cs:234:13:234:23 | ... is ... | CSharp7.cs:234:18:234:20 | access to type Int32 | Int32 | CSharp7.cs:234:18:234:23 | Int32 i1 | false |
|
||||
| CSharp7.cs:238:18:238:31 | ... is ... | CSharp7.cs:238:23:238:28 | access to type String | String | CSharp7.cs:238:23:238:31 | String s1 | false |
|
||||
| CSharp7.cs:245:18:245:28 | ... is ... | CSharp7.cs:245:23:245:25 | access to type Object | Object | CSharp7.cs:245:23:245:28 | Object v1 | true |
|
||||
| CSharp7.cs:255:27:255:40 | ... is ... | CSharp7.cs:255:32:255:37 | access to type String | String | CSharp7.cs:255:32:255:40 | String s4 | false |
|
||||
|
||||
@@ -154,35 +154,42 @@
|
||||
| CSharp7.cs:242:18:242:18 | access to local variable o | CSharp7.cs:245:18:245:18 | access to local variable o |
|
||||
| CSharp7.cs:242:18:242:18 | access to local variable o | CSharp7.cs:249:17:249:17 | access to local variable o |
|
||||
| CSharp7.cs:245:18:245:18 | access to local variable o | CSharp7.cs:249:17:249:17 | access to local variable o |
|
||||
| CSharp7.cs:249:17:249:17 | access to local variable o | CSharp7.cs:253:18:253:23 | SSA def(i2) |
|
||||
| CSharp7.cs:249:17:249:17 | access to local variable o | CSharp7.cs:256:18:256:23 | SSA def(i3) |
|
||||
| CSharp7.cs:249:17:249:17 | access to local variable o | CSharp7.cs:259:18:259:26 | SSA def(s2) |
|
||||
| CSharp7.cs:253:18:253:23 | SSA def(i2) | CSharp7.cs:253:30:253:31 | access to local variable i2 |
|
||||
| CSharp7.cs:253:30:253:31 | access to local variable i2 | CSharp7.cs:253:30:253:35 | ... > ... |
|
||||
| CSharp7.cs:253:30:253:31 | access to local variable i2 | CSharp7.cs:254:47:254:48 | access to local variable i2 |
|
||||
| CSharp7.cs:254:37:254:45 | "positive " | CSharp7.cs:254:35:254:50 | $"..." |
|
||||
| CSharp7.cs:254:47:254:48 | access to local variable i2 | CSharp7.cs:254:35:254:50 | $"..." |
|
||||
| CSharp7.cs:256:18:256:23 | SSA def(i3) | CSharp7.cs:257:42:257:43 | access to local variable i3 |
|
||||
| CSharp7.cs:257:37:257:40 | "int " | CSharp7.cs:257:35:257:45 | $"..." |
|
||||
| CSharp7.cs:257:42:257:43 | access to local variable i3 | CSharp7.cs:257:35:257:45 | $"..." |
|
||||
| CSharp7.cs:259:18:259:26 | SSA def(s2) | CSharp7.cs:260:45:260:46 | access to local variable s2 |
|
||||
| CSharp7.cs:260:37:260:43 | "string " | CSharp7.cs:260:35:260:48 | $"..." |
|
||||
| CSharp7.cs:260:45:260:46 | access to local variable s2 | CSharp7.cs:260:35:260:48 | $"..." |
|
||||
| CSharp7.cs:278:13:278:48 | SSA def(dict) | CSharp7.cs:279:20:279:23 | access to local variable dict |
|
||||
| CSharp7.cs:278:20:278:48 | object creation of type Dictionary<Int32,String> | CSharp7.cs:278:13:278:48 | SSA def(dict) |
|
||||
| CSharp7.cs:279:13:279:62 | SSA def(list) | CSharp7.cs:281:39:281:42 | access to local variable list |
|
||||
| CSharp7.cs:279:20:279:62 | call to method Select | CSharp7.cs:279:13:279:62 | SSA def(list) |
|
||||
| CSharp7.cs:279:32:279:35 | item | CSharp7.cs:279:41:279:44 | access to parameter item |
|
||||
| CSharp7.cs:279:32:279:61 | [implicit call] (...) => ... | CSharp7.cs:279:20:279:62 | call to method Select |
|
||||
| CSharp7.cs:279:41:279:44 | access to parameter item | CSharp7.cs:279:51:279:54 | access to parameter item |
|
||||
| CSharp7.cs:279:41:279:48 | access to property Key | CSharp7.cs:279:40:279:61 | (..., ...) |
|
||||
| CSharp7.cs:279:51:279:54 | access to parameter item | CSharp7.cs:279:51:279:60 | access to property Value |
|
||||
| CSharp7.cs:279:51:279:60 | access to property Value | CSharp7.cs:279:40:279:61 | (..., ...) |
|
||||
| CSharp7.cs:281:23:281:23 | Int32 a | CSharp7.cs:281:18:281:34 | (..., ...) |
|
||||
| CSharp7.cs:281:33:281:33 | String b | CSharp7.cs:281:18:281:34 | (..., ...) |
|
||||
| CSharp7.cs:281:39:281:42 | access to local variable list | CSharp7.cs:283:36:283:39 | access to local variable list |
|
||||
| CSharp7.cs:283:23:283:23 | Int32 a | CSharp7.cs:283:18:283:31 | (..., ...) |
|
||||
| CSharp7.cs:283:30:283:30 | String b | CSharp7.cs:283:18:283:31 | (..., ...) |
|
||||
| CSharp7.cs:283:36:283:39 | access to local variable list | CSharp7.cs:285:32:285:35 | access to local variable list |
|
||||
| CSharp7.cs:285:23:285:23 | Int32 a | CSharp7.cs:285:18:285:27 | (..., ...) |
|
||||
| CSharp7.cs:285:26:285:26 | String b | CSharp7.cs:285:18:285:27 | (..., ...) |
|
||||
| CSharp7.cs:249:17:249:17 | access to local variable o | CSharp7.cs:255:27:255:27 | access to local variable o |
|
||||
| CSharp7.cs:249:17:249:17 | access to local variable o | CSharp7.cs:258:18:258:23 | SSA def(i2) |
|
||||
| CSharp7.cs:249:17:249:17 | access to local variable o | CSharp7.cs:261:18:261:23 | SSA def(i3) |
|
||||
| CSharp7.cs:249:17:249:17 | access to local variable o | CSharp7.cs:264:18:264:26 | SSA def(s2) |
|
||||
| CSharp7.cs:253:26:253:26 | 1 | CSharp7.cs:253:26:253:30 | ... < ... |
|
||||
| CSharp7.cs:253:30:253:30 | 2 | CSharp7.cs:253:26:253:30 | ... < ... |
|
||||
| CSharp7.cs:255:27:255:27 | access to local variable o | CSharp7.cs:255:32:255:40 | SSA def(s4) |
|
||||
| CSharp7.cs:255:32:255:40 | SSA def(s4) | CSharp7.cs:256:40:256:41 | access to local variable s4 |
|
||||
| CSharp7.cs:256:37:256:38 | "x " | CSharp7.cs:256:35:256:43 | $"..." |
|
||||
| CSharp7.cs:256:40:256:41 | access to local variable s4 | CSharp7.cs:256:35:256:43 | $"..." |
|
||||
| CSharp7.cs:258:18:258:23 | SSA def(i2) | CSharp7.cs:258:30:258:31 | access to local variable i2 |
|
||||
| CSharp7.cs:258:30:258:31 | access to local variable i2 | CSharp7.cs:258:30:258:35 | ... > ... |
|
||||
| CSharp7.cs:258:30:258:31 | access to local variable i2 | CSharp7.cs:259:47:259:48 | access to local variable i2 |
|
||||
| CSharp7.cs:259:37:259:45 | "positive " | CSharp7.cs:259:35:259:50 | $"..." |
|
||||
| CSharp7.cs:259:47:259:48 | access to local variable i2 | CSharp7.cs:259:35:259:50 | $"..." |
|
||||
| CSharp7.cs:261:18:261:23 | SSA def(i3) | CSharp7.cs:262:42:262:43 | access to local variable i3 |
|
||||
| CSharp7.cs:262:37:262:40 | "int " | CSharp7.cs:262:35:262:45 | $"..." |
|
||||
| CSharp7.cs:262:42:262:43 | access to local variable i3 | CSharp7.cs:262:35:262:45 | $"..." |
|
||||
| CSharp7.cs:264:18:264:26 | SSA def(s2) | CSharp7.cs:265:45:265:46 | access to local variable s2 |
|
||||
| CSharp7.cs:265:37:265:43 | "string " | CSharp7.cs:265:35:265:48 | $"..." |
|
||||
| CSharp7.cs:265:45:265:46 | access to local variable s2 | CSharp7.cs:265:35:265:48 | $"..." |
|
||||
| CSharp7.cs:283:13:283:48 | SSA def(dict) | CSharp7.cs:284:20:284:23 | access to local variable dict |
|
||||
| CSharp7.cs:283:20:283:48 | object creation of type Dictionary<Int32,String> | CSharp7.cs:283:13:283:48 | SSA def(dict) |
|
||||
| CSharp7.cs:284:13:284:62 | SSA def(list) | CSharp7.cs:286:39:286:42 | access to local variable list |
|
||||
| CSharp7.cs:284:20:284:62 | call to method Select | CSharp7.cs:284:13:284:62 | SSA def(list) |
|
||||
| CSharp7.cs:284:32:284:35 | item | CSharp7.cs:284:41:284:44 | access to parameter item |
|
||||
| CSharp7.cs:284:32:284:61 | [implicit call] (...) => ... | CSharp7.cs:284:20:284:62 | call to method Select |
|
||||
| CSharp7.cs:284:41:284:44 | access to parameter item | CSharp7.cs:284:51:284:54 | access to parameter item |
|
||||
| CSharp7.cs:284:41:284:48 | access to property Key | CSharp7.cs:284:40:284:61 | (..., ...) |
|
||||
| CSharp7.cs:284:51:284:54 | access to parameter item | CSharp7.cs:284:51:284:60 | access to property Value |
|
||||
| CSharp7.cs:284:51:284:60 | access to property Value | CSharp7.cs:284:40:284:61 | (..., ...) |
|
||||
| CSharp7.cs:286:23:286:23 | Int32 a | CSharp7.cs:286:18:286:34 | (..., ...) |
|
||||
| CSharp7.cs:286:33:286:33 | String b | CSharp7.cs:286:18:286:34 | (..., ...) |
|
||||
| CSharp7.cs:286:39:286:42 | access to local variable list | CSharp7.cs:288:36:288:39 | access to local variable list |
|
||||
| CSharp7.cs:288:23:288:23 | Int32 a | CSharp7.cs:288:18:288:31 | (..., ...) |
|
||||
| CSharp7.cs:288:30:288:30 | String b | CSharp7.cs:288:18:288:31 | (..., ...) |
|
||||
| CSharp7.cs:288:36:288:39 | access to local variable list | CSharp7.cs:290:32:290:35 | access to local variable list |
|
||||
| CSharp7.cs:290:23:290:23 | Int32 a | CSharp7.cs:290:18:290:27 | (..., ...) |
|
||||
| CSharp7.cs:290:26:290:26 | String b | CSharp7.cs:290:18:290:27 | (..., ...) |
|
||||
|
||||
@@ -52,15 +52,16 @@
|
||||
| CSharp7.cs:234:22:234:23 | i1 | int |
|
||||
| CSharp7.cs:238:30:238:31 | s1 | string |
|
||||
| CSharp7.cs:245:27:245:28 | v1 | object |
|
||||
| CSharp7.cs:253:22:253:23 | i2 | int |
|
||||
| CSharp7.cs:256:22:256:23 | i3 | int |
|
||||
| CSharp7.cs:259:25:259:26 | s2 | string |
|
||||
| CSharp7.cs:265:22:265:23 | v2 | object |
|
||||
| CSharp7.cs:278:13:278:16 | dict | Dictionary<int, string> |
|
||||
| CSharp7.cs:279:13:279:16 | list | IEnumerable<(int, string)> |
|
||||
| CSharp7.cs:281:23:281:23 | a | int |
|
||||
| CSharp7.cs:281:33:281:33 | b | string |
|
||||
| CSharp7.cs:283:23:283:23 | a | int |
|
||||
| CSharp7.cs:283:30:283:30 | b | string |
|
||||
| CSharp7.cs:285:23:285:23 | a | int |
|
||||
| CSharp7.cs:285:26:285:26 | b | string |
|
||||
| CSharp7.cs:255:39:255:40 | s4 | string |
|
||||
| CSharp7.cs:258:22:258:23 | i2 | int |
|
||||
| CSharp7.cs:261:22:261:23 | i3 | int |
|
||||
| CSharp7.cs:264:25:264:26 | s2 | string |
|
||||
| CSharp7.cs:270:22:270:23 | v2 | object |
|
||||
| CSharp7.cs:283:13:283:16 | dict | Dictionary<int, string> |
|
||||
| CSharp7.cs:284:13:284:16 | list | IEnumerable<(int, string)> |
|
||||
| CSharp7.cs:286:23:286:23 | a | int |
|
||||
| CSharp7.cs:286:33:286:33 | b | string |
|
||||
| CSharp7.cs:288:23:288:23 | a | int |
|
||||
| CSharp7.cs:288:30:288:30 | b | string |
|
||||
| CSharp7.cs:290:23:290:23 | a | int |
|
||||
| CSharp7.cs:290:26:290:26 | b | string |
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
| CSharp7.cs:177:38:177:39 | "" | CSharp7.cs:177:31:177:39 | ... + ... |
|
||||
| CSharp7.cs:236:33:236:36 | "int " | CSharp7.cs:236:31:236:41 | $"..." |
|
||||
| CSharp7.cs:240:33:240:39 | "string " | CSharp7.cs:240:31:240:44 | $"..." |
|
||||
| CSharp7.cs:254:37:254:45 | "positive " | CSharp7.cs:254:35:254:50 | $"..." |
|
||||
| CSharp7.cs:257:37:257:40 | "int " | CSharp7.cs:257:35:257:45 | $"..." |
|
||||
| CSharp7.cs:260:37:260:43 | "string " | CSharp7.cs:260:35:260:48 | $"..." |
|
||||
| CSharp7.cs:256:37:256:38 | "x " | CSharp7.cs:256:35:256:43 | $"..." |
|
||||
| CSharp7.cs:259:37:259:45 | "positive " | CSharp7.cs:259:35:259:50 | $"..." |
|
||||
| CSharp7.cs:262:37:262:40 | "int " | CSharp7.cs:262:35:262:45 | $"..." |
|
||||
| CSharp7.cs:265:37:265:43 | "string " | CSharp7.cs:265:35:265:48 | $"..." |
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
| CSharp7.cs:223:9:223:14 | (..., ...) | write |
|
||||
| CSharp7.cs:224:9:224:18 | (..., ...) | write |
|
||||
| CSharp7.cs:225:9:225:18 | (..., ...) | write |
|
||||
| CSharp7.cs:279:40:279:61 | (..., ...) | read |
|
||||
| CSharp7.cs:281:18:281:34 | (..., ...) | read |
|
||||
| CSharp7.cs:283:18:283:31 | (..., ...) | read |
|
||||
| CSharp7.cs:285:18:285:27 | (..., ...) | read |
|
||||
| CSharp7.cs:284:40:284:61 | (..., ...) | read |
|
||||
| CSharp7.cs:286:18:286:34 | (..., ...) | read |
|
||||
| CSharp7.cs:288:18:288:31 | (..., ...) | read |
|
||||
| CSharp7.cs:290:18:290:27 | (..., ...) | read |
|
||||
|
||||
@@ -82,11 +82,11 @@
|
||||
| CSharp7.cs:224:9:224:18 | (..., ...) | 1 | CSharp7.cs:224:17:224:17 | _ |
|
||||
| CSharp7.cs:225:9:225:18 | (..., ...) | 0 | CSharp7.cs:225:10:225:10 | _ |
|
||||
| CSharp7.cs:225:9:225:18 | (..., ...) | 1 | CSharp7.cs:225:17:225:17 | Double y |
|
||||
| CSharp7.cs:279:40:279:61 | (..., ...) | 0 | CSharp7.cs:279:41:279:48 | access to property Key |
|
||||
| CSharp7.cs:279:40:279:61 | (..., ...) | 1 | CSharp7.cs:279:51:279:60 | access to property Value |
|
||||
| CSharp7.cs:281:18:281:34 | (..., ...) | 0 | CSharp7.cs:281:23:281:23 | Int32 a |
|
||||
| CSharp7.cs:281:18:281:34 | (..., ...) | 1 | CSharp7.cs:281:33:281:33 | String b |
|
||||
| CSharp7.cs:283:18:283:31 | (..., ...) | 0 | CSharp7.cs:283:23:283:23 | Int32 a |
|
||||
| CSharp7.cs:283:18:283:31 | (..., ...) | 1 | CSharp7.cs:283:30:283:30 | String b |
|
||||
| CSharp7.cs:285:18:285:27 | (..., ...) | 0 | CSharp7.cs:285:23:285:23 | Int32 a |
|
||||
| CSharp7.cs:285:18:285:27 | (..., ...) | 1 | CSharp7.cs:285:26:285:26 | String b |
|
||||
| CSharp7.cs:284:40:284:61 | (..., ...) | 0 | CSharp7.cs:284:41:284:48 | access to property Key |
|
||||
| CSharp7.cs:284:40:284:61 | (..., ...) | 1 | CSharp7.cs:284:51:284:60 | access to property Value |
|
||||
| CSharp7.cs:286:18:286:34 | (..., ...) | 0 | CSharp7.cs:286:23:286:23 | Int32 a |
|
||||
| CSharp7.cs:286:18:286:34 | (..., ...) | 1 | CSharp7.cs:286:33:286:33 | String b |
|
||||
| CSharp7.cs:288:18:288:31 | (..., ...) | 0 | CSharp7.cs:288:23:288:23 | Int32 a |
|
||||
| CSharp7.cs:288:18:288:31 | (..., ...) | 1 | CSharp7.cs:288:30:288:30 | String b |
|
||||
| CSharp7.cs:290:18:290:27 | (..., ...) | 0 | CSharp7.cs:290:23:290:23 | Int32 a |
|
||||
| CSharp7.cs:290:18:290:27 | (..., ...) | 1 | CSharp7.cs:290:26:290:26 | String b |
|
||||
|
||||
@@ -31,11 +31,11 @@
|
||||
| (Int32,Int32,Int32) | (int, int, int) | ValueTuple<int, int, int> | 3 | 2 | CSharp7.cs:75:16:75:22 | Item3 |
|
||||
| (Int32,Int32,Int32) | (int, int, int) | ValueTuple<int, int, int> | 3 | 2 | CSharp7.cs:75:34:75:34 | Item3 |
|
||||
| (Int32,String) | (int, string) | ValueTuple<int, string> | 2 | 0 | CSharp7.cs:97:19:97:19 | Item1 |
|
||||
| (Int32,String) | (int, string) | ValueTuple<int, string> | 2 | 0 | CSharp7.cs:279:41:279:48 | Key |
|
||||
| (Int32,String) | (int, string) | ValueTuple<int, string> | 2 | 0 | CSharp7.cs:281:19:281:23 | a |
|
||||
| (Int32,String) | (int, string) | ValueTuple<int, string> | 2 | 0 | CSharp7.cs:284:41:284:48 | Key |
|
||||
| (Int32,String) | (int, string) | ValueTuple<int, string> | 2 | 0 | CSharp7.cs:286:19:286:23 | a |
|
||||
| (Int32,String) | (int, string) | ValueTuple<int, string> | 2 | 1 | CSharp7.cs:97:22:97:37 | Item2 |
|
||||
| (Int32,String) | (int, string) | ValueTuple<int, string> | 2 | 1 | CSharp7.cs:279:51:279:60 | Value |
|
||||
| (Int32,String) | (int, string) | ValueTuple<int, string> | 2 | 1 | CSharp7.cs:281:26:281:33 | b |
|
||||
| (Int32,String) | (int, string) | ValueTuple<int, string> | 2 | 1 | CSharp7.cs:284:51:284:60 | Value |
|
||||
| (Int32,String) | (int, string) | ValueTuple<int, string> | 2 | 1 | CSharp7.cs:286:26:286:33 | b |
|
||||
| (String,(Int32,Int32)) | (string, (int, int)) | ValueTuple<string, (int, int)> | 2 | 0 | CSharp7.cs:109:10:109:15 | m1 |
|
||||
| (String,(Int32,Int32)) | (string, (int, int)) | ValueTuple<string, (int, int)> | 2 | 0 | CSharp7.cs:109:29:109:37 | Item1 |
|
||||
| (String,(Int32,Int32)) | (string, (int, int)) | ValueTuple<string, (int, int)> | 2 | 0 | CSharp7.cs:112:10:112:11 | m3 |
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
| CSharp7.cs:251:13:251:23 | case ...: |
|
||||
| CSharp7.cs:253:13:253:36 | case Int32 i2: |
|
||||
| CSharp7.cs:256:13:256:24 | case Int32 i3: |
|
||||
| CSharp7.cs:259:13:259:27 | case String s2: |
|
||||
| CSharp7.cs:262:13:262:26 | case Double: |
|
||||
| CSharp7.cs:265:13:265:24 | case Object v2: |
|
||||
| CSharp7.cs:267:13:267:20 | default: |
|
||||
| CSharp7.cs:253:13:253:31 | case ...: |
|
||||
| CSharp7.cs:255:13:255:41 | case ...: |
|
||||
| CSharp7.cs:258:13:258:36 | case Int32 i2: |
|
||||
| CSharp7.cs:261:13:261:24 | case Int32 i3: |
|
||||
| CSharp7.cs:264:13:264:27 | case String s2: |
|
||||
| CSharp7.cs:267:13:267:26 | case Double: |
|
||||
| CSharp7.cs:270:13:270:24 | case Object v2: |
|
||||
| CSharp7.cs:272:13:272:20 | default: |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
| CSharp7.cs:253:13:253:36 | case Int32 i2: | CSharp7.cs:253:18:253:23 | Int32 i2 | CSharp7.cs:253:18:253:20 | access to type Int32 | Int32 | false |
|
||||
| CSharp7.cs:256:13:256:24 | case Int32 i3: | CSharp7.cs:256:18:256:23 | Int32 i3 | CSharp7.cs:256:18:256:20 | access to type Int32 | Int32 | false |
|
||||
| CSharp7.cs:259:13:259:27 | case String s2: | CSharp7.cs:259:18:259:26 | String s2 | CSharp7.cs:259:18:259:23 | access to type String | String | false |
|
||||
| CSharp7.cs:265:13:265:24 | case Object v2: | CSharp7.cs:265:18:265:23 | Object v2 | CSharp7.cs:265:18:265:20 | access to type Object | Object | true |
|
||||
| CSharp7.cs:258:13:258:36 | case Int32 i2: | CSharp7.cs:258:18:258:23 | Int32 i2 | CSharp7.cs:258:18:258:20 | access to type Int32 | Int32 | false |
|
||||
| CSharp7.cs:261:13:261:24 | case Int32 i3: | CSharp7.cs:261:18:261:23 | Int32 i3 | CSharp7.cs:261:18:261:20 | access to type Int32 | Int32 | false |
|
||||
| CSharp7.cs:264:13:264:27 | case String s2: | CSharp7.cs:264:18:264:26 | String s2 | CSharp7.cs:264:18:264:23 | access to type String | String | false |
|
||||
| CSharp7.cs:270:13:270:24 | case Object v2: | CSharp7.cs:270:18:270:23 | Object v2 | CSharp7.cs:270:18:270:20 | access to type Object | Object | true |
|
||||
|
||||
@@ -1 +1 @@
|
||||
| CSharp7.cs:253:13:253:36 | case Int32 i2: | CSharp7.cs:253:30:253:35 | ... > ... |
|
||||
| CSharp7.cs:258:13:258:36 | case Int32 i2: | CSharp7.cs:258:30:258:35 | ... > ... |
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.controlflow.ControlFlowGraph
|
||||
|
||||
/** "Naive" def-use implementation. */
|
||||
predicate defReaches(AssignableDefinition def, LocalScopeVariable v, ControlFlowNode cfn) {
|
||||
predicate defReaches(AssignableDefinition def, LocalScopeVariable v, ControlFlow::Node cfn) {
|
||||
def.getTarget() = v and cfn = def.getAControlFlowNode().getASuccessor()
|
||||
or
|
||||
exists(ControlFlowNode mid |
|
||||
exists(ControlFlow::Node mid |
|
||||
defReaches(def, v, mid) |
|
||||
not mid = any(AssignableDefinition ad | ad.getTarget() = v and ad.isCertain()).getAControlFlowNode() and
|
||||
cfn = mid.getASuccessor()
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.controlflow.ControlFlowGraph
|
||||
|
||||
/** "Naive" parameter-use implementation. */
|
||||
predicate parameterReaches(Parameter p, ControlFlowNode cfn) {
|
||||
predicate parameterReaches(Parameter p, ControlFlow::Node cfn) {
|
||||
cfn = p.getCallable().getEntryPoint().getASuccessor()
|
||||
or
|
||||
exists(ControlFlowNode mid |
|
||||
exists(ControlFlow::Node mid |
|
||||
parameterReaches(p, mid) |
|
||||
not mid = any(AssignableDefinition ad | ad.getTarget() = p and ad.isCertain()).getAControlFlowNode() and
|
||||
cfn = mid.getASuccessor()
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.controlflow.ControlFlowGraph
|
||||
|
||||
/** "Naive" use-use implementation. */
|
||||
predicate useReaches(LocalScopeVariableRead read, LocalScopeVariable v, ControlFlowNode cfn) {
|
||||
predicate useReaches(LocalScopeVariableRead read, LocalScopeVariable v, ControlFlow::Node cfn) {
|
||||
read.getTarget() = v and cfn = read.getAControlFlowNode().getASuccessor()
|
||||
or
|
||||
exists(ControlFlowNode mid |
|
||||
exists(ControlFlow::Node mid |
|
||||
useReaches(read, v, mid) |
|
||||
not mid = any(AssignableDefinition ad | ad.getTarget() = v and ad.isCertain()).getAControlFlowNode() and
|
||||
cfn = mid.getASuccessor()
|
||||
@@ -29,7 +28,7 @@ private TLocalScopeVariableReadOrSsaDef getANextReadOrDef(TLocalScopeVariableRea
|
||||
result = TLocalScopeVariableRead(read.getANextRead())
|
||||
or
|
||||
not exists(read.getANextRead()) and
|
||||
exists(Ssa::Definition ssaDef, Ssa::PseudoDefinition pseudoDef, ControlFlowNode cfn, BasicBlock bb, int i |
|
||||
exists(Ssa::Definition ssaDef, Ssa::PseudoDefinition pseudoDef, ControlFlow::Node cfn, ControlFlow::BasicBlock bb, int i |
|
||||
ssaDef.getARead() = read |
|
||||
pseudoDef.getAnInput() = ssaDef and
|
||||
pseudoDef.definesAt(bb, i) and
|
||||
|
||||
@@ -3,5 +3,5 @@ import csharp
|
||||
from int uses, int live
|
||||
where
|
||||
uses = strictcount(Ssa::ExplicitDefinition ssa, AssignableRead read | read = ssa.getARead()) and
|
||||
live = strictcount(Ssa::ExplicitDefinition ssa, ControlFlowGraph::BasicBlock bb | ssa.isLiveAtEndOfBlock(bb))
|
||||
live = strictcount(Ssa::ExplicitDefinition ssa, ControlFlow::BasicBlock bb | ssa.isLiveAtEndOfBlock(bb))
|
||||
select uses, live
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.controlflow.ControlFlowGraph
|
||||
|
||||
query predicate edges(ControlFlowNode node, ControlFlowNode successor, string attr, string val) {
|
||||
exists(ControlFlowEdgeType t |
|
||||
query predicate edges(ControlFlow::Node node, ControlFlow::Node successor, string attr, string val) {
|
||||
exists(ControlFlow::SuccessorType t |
|
||||
successor = node.getASuccessorByType(t) |
|
||||
attr = "semmle.label" and
|
||||
val = t.toString()
|
||||
|
||||
@@ -43,3 +43,9 @@
|
||||
| queries.cs:47:11:47:18 | call to method Select | 1 | queries.cs:47:18:47:18 | access to local variable a |
|
||||
| queries.cs:51:11:51:18 | call to method Select | 0 | queries.cs:50:11:50:32 | String a = ... |
|
||||
| queries.cs:51:11:51:18 | call to method Select | 1 | queries.cs:51:18:51:18 | access to local variable a |
|
||||
| queries.cs:55:11:55:49 | call to method GroupJoin | 0 | queries.cs:54:11:54:25 | Int32 a = ... |
|
||||
| queries.cs:55:11:55:49 | call to method GroupJoin | 1 | queries.cs:55:11:55:49 | IList<IList<Int32>> c = ... |
|
||||
| queries.cs:55:11:55:49 | call to method GroupJoin | 2 | queries.cs:55:21:55:25 | access to local variable list2 |
|
||||
| queries.cs:55:11:55:49 | call to method GroupJoin | 3 | queries.cs:55:30:55:30 | access to local variable a |
|
||||
| queries.cs:55:11:55:49 | call to method GroupJoin | 4 | queries.cs:55:39:55:42 | access to indexer |
|
||||
| queries.cs:55:11:55:49 | call to method GroupJoin | 5 | queries.cs:55:11:55:49 | IList<IList<Int32>> d = ... |
|
||||
|
||||
@@ -49,6 +49,11 @@ class Queries
|
||||
var list11 =
|
||||
from string a in list7
|
||||
select a;
|
||||
|
||||
var list12 =
|
||||
from a in list1
|
||||
join c in list2 on a equals c[0] into d
|
||||
select (a,d);
|
||||
}
|
||||
|
||||
class A : System.Collections.IEnumerable
|
||||
|
||||
@@ -81,3 +81,28 @@ class Designations
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
class WhileIs
|
||||
{
|
||||
void Test()
|
||||
{
|
||||
object x = null;
|
||||
while(x is string s)
|
||||
{
|
||||
var y = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ObjectInitializerType
|
||||
{
|
||||
struct Point
|
||||
{
|
||||
public object Name;
|
||||
}
|
||||
|
||||
void F()
|
||||
{
|
||||
new Point() { Name = "Bob" };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,3 +39,10 @@
|
||||
| Program.cs:69:5:69:8 | Boolean |
|
||||
| Program.cs:69:16:69:18 | Int32 |
|
||||
| Program.cs:75:5:75:7 | Int32 |
|
||||
| Program.cs:87:5:87:8 | Void |
|
||||
| Program.cs:89:9:89:14 | Object |
|
||||
| Program.cs:90:20:90:25 | String |
|
||||
| Program.cs:92:13:92:15 | String |
|
||||
| Program.cs:101:16:101:21 | Object |
|
||||
| Program.cs:104:5:104:8 | Void |
|
||||
| Program.cs:106:13:106:17 | Point |
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
| Program.cs:92:21:92:21 | access to local variable s |
|
||||
5
csharp/ql/test/library-tests/regressions/WhileIs.ql
Normal file
5
csharp/ql/test/library-tests/regressions/WhileIs.ql
Normal file
@@ -0,0 +1,5 @@
|
||||
import csharp
|
||||
|
||||
from LocalVariable decl
|
||||
where decl.getName() = "s"
|
||||
select decl.getAnAccess()
|
||||
@@ -0,0 +1,14 @@
|
||||
// semmle-extractor-options: --standalone
|
||||
|
||||
using System;
|
||||
|
||||
class Cfg
|
||||
{
|
||||
void F()
|
||||
{
|
||||
var v = new InvalidType();
|
||||
Debug.Assert(v.a.b, "This is true");
|
||||
|
||||
new CounterCreationData() { CounterHelp = string.Empty, CounterType = v.Type };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
| ControlFlow.cs:7:10:7:10 | enter F | ControlFlow.cs:8:5:13:5 | {...} |
|
||||
| ControlFlow.cs:8:5:13:5 | {...} | ControlFlow.cs:9:9:9:34 | ... ...; |
|
||||
| ControlFlow.cs:9:9:9:34 | ... ...; | ControlFlow.cs:9:13:9:13 | access to local variable v |
|
||||
| ControlFlow.cs:10:9:10:13 | Expression | ControlFlow.cs:10:22:10:22 | access to local variable v |
|
||||
| ControlFlow.cs:10:9:10:43 | Call to unknown method | ControlFlow.cs:12:9:12:87 | ...; |
|
||||
| ControlFlow.cs:10:9:10:44 | ...; | ControlFlow.cs:10:9:10:13 | Expression |
|
||||
| ControlFlow.cs:10:22:10:22 | access to local variable v | ControlFlow.cs:10:22:10:24 | Expression |
|
||||
| ControlFlow.cs:10:22:10:24 | Expression | ControlFlow.cs:10:22:10:26 | Expression |
|
||||
| ControlFlow.cs:10:22:10:26 | Expression | ControlFlow.cs:10:29:10:42 | "This is true" |
|
||||
| ControlFlow.cs:10:29:10:42 | "This is true" | ControlFlow.cs:10:9:10:43 | Call to unknown method |
|
||||
| ControlFlow.cs:12:35:12:86 | { ..., ... } | ControlFlow.cs:7:10:7:10 | exit F |
|
||||
| ControlFlow.cs:12:37:12:47 | Expression | ControlFlow.cs:12:51:12:62 | access to field Empty |
|
||||
| ControlFlow.cs:12:37:12:62 | ... = ... | ControlFlow.cs:12:65:12:75 | Expression |
|
||||
| ControlFlow.cs:12:51:12:62 | access to field Empty | ControlFlow.cs:12:37:12:62 | ... = ... |
|
||||
| ControlFlow.cs:12:65:12:75 | Expression | ControlFlow.cs:12:79:12:79 | access to local variable v |
|
||||
| ControlFlow.cs:12:65:12:84 | ... = ... | ControlFlow.cs:12:35:12:86 | { ..., ... } |
|
||||
| ControlFlow.cs:12:79:12:79 | access to local variable v | ControlFlow.cs:12:79:12:84 | Expression |
|
||||
| ControlFlow.cs:12:79:12:84 | Expression | ControlFlow.cs:12:65:12:84 | ... = ... |
|
||||
17
csharp/ql/test/library-tests/standalone/controlflow/cfg.ql
Normal file
17
csharp/ql/test/library-tests/standalone/controlflow/cfg.ql
Normal file
@@ -0,0 +1,17 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.controlflow.ControlFlowGraph
|
||||
|
||||
/**
|
||||
* A method call where the target is unknown.
|
||||
* The purpose of this is to ensure that all MethodCall expressions
|
||||
* have a valid `toString()`.
|
||||
*/
|
||||
class UnknownCall extends MethodCall {
|
||||
UnknownCall() { not exists(this.getTarget()) }
|
||||
|
||||
override string toString() { result = "Call to unknown method" }
|
||||
}
|
||||
|
||||
query predicate edges(ControlFlow::Node n1, ControlFlow::Node n2) {
|
||||
n2 = n1.getASuccessor()
|
||||
}
|
||||
@@ -397,7 +397,7 @@ class MockitoSettableField extends Field {
|
||||
class MockitoMockMethod extends Method {
|
||||
MockitoMockMethod() {
|
||||
this.getDeclaringType().hasQualifiedName("org.mockito", "Mockito") and
|
||||
this.hasName("mock")
|
||||
(this.hasName("mock") or this.hasName("verify"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,3 +29,4 @@
|
||||
+ semmlecode-javascript-queries/Security/CWE-807/DifferentKindsComparisonBypass.ql: /Security/CWE/CWE-807
|
||||
+ semmlecode-javascript-queries/Security/CWE-843/TypeConfusionThroughParameterTampering.ql: /Security/CWE/CWE-834
|
||||
+ semmlecode-javascript-queries/Security/CWE-916/InsufficientPasswordHash.ql: /Security/CWE/CWE-916
|
||||
+ semmlecode-javascript-queries/Security/CWE-918/RequestForgery.ql: /Security/CWE/CWE-918
|
||||
|
||||
@@ -45,4 +45,5 @@ class OmittedArrayElement extends ArrayExpr {
|
||||
}
|
||||
|
||||
from OmittedArrayElement ae
|
||||
where not ae.getFile().getFileType().isTypeScript() // ignore quirks in TypeScript tokenizer
|
||||
select ae, "Avoid omitted array elements."
|
||||
@@ -36,7 +36,8 @@ where s.hasSemicolonInserted() and
|
||||
asi = strictcount(Stmt ss | asi(sc, ss, true)) and
|
||||
nstmt = strictcount(Stmt ss | asi(sc, ss, _)) and
|
||||
perc = ((1-asi/nstmt)*100).floor() and
|
||||
perc >= 90
|
||||
perc >= 90 and
|
||||
not s.getFile().getFileType().isTypeScript() // ignore some quirks in the TypeScript tokenizer
|
||||
select (LastLineOf)s, "Avoid automated semicolon insertion " +
|
||||
"(" + perc + "% of all statements in $@ have an explicit semicolon).",
|
||||
sc, "the enclosing " + sctype
|
||||
79
javascript/ql/src/Security/CWE-918/RequestForgery.qhelp
Normal file
79
javascript/ql/src/Security/CWE-918/RequestForgery.qhelp
Normal file
@@ -0,0 +1,79 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>
|
||||
|
||||
Directly incorporating user input into an HTTP request
|
||||
without validating the input can facilitate different kinds of request
|
||||
forgery attacks, where the attacker essentially controls the request.
|
||||
|
||||
If the vulnerable request is in server-side code, then security
|
||||
mechanisms, such as external firewalls, can be bypassed.
|
||||
|
||||
If the vulnerable request is in client-side code, then unsuspecting
|
||||
users can send malicious requests to other servers, potentially
|
||||
resulting in a DDOS attack.
|
||||
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
|
||||
<p>
|
||||
|
||||
To guard against request forgery, it is advisable to avoid
|
||||
putting user input directly into a remote request. If a flexible
|
||||
remote request mechanism is required, it is recommended to maintain a
|
||||
list of authorized request targets and choose from that list based on
|
||||
the user input provided.
|
||||
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
|
||||
<p>
|
||||
|
||||
The following example shows an HTTP request parameter
|
||||
being used directly in a URL request without validating the input,
|
||||
which facilitates an SSRF attack. The request
|
||||
<code>http.get(...)</code> is vulnerable since attackers can choose
|
||||
the value of <code>target</code> to be anything they want. For
|
||||
instance, the attacker can choose
|
||||
<code>"internal.example.com/#"</code> as the target, causing the URL
|
||||
used in the request to be
|
||||
<code>"https://internal.example.com/#.example.com/data"</code>.
|
||||
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
||||
A request to <code>https://internal.example.com</code> may
|
||||
be problematic if that server is not meant to be
|
||||
directly accessible from the attacker's machine.
|
||||
|
||||
</p>
|
||||
|
||||
<sample src="examples/RequestForgeryBad.js"/>
|
||||
|
||||
<p>
|
||||
|
||||
One way to remedy the problem is to use the user input to
|
||||
select a known fixed string before performing the request:
|
||||
|
||||
</p>
|
||||
|
||||
<sample src="examples/RequestForgeryGood.js"/>
|
||||
|
||||
</example>
|
||||
|
||||
<references>
|
||||
|
||||
<li>OWASP: <a href="https://www.owasp.org/index.php/Server_Side_Request_Forgery">SSRF</a></li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
18
javascript/ql/src/Security/CWE-918/RequestForgery.ql
Normal file
18
javascript/ql/src/Security/CWE-918/RequestForgery.ql
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* @name Uncontrolled data used in remote request
|
||||
* @description Sending remote requests with user-controlled data allows for request forgery attacks.
|
||||
* @kind problem
|
||||
* @problem.severity error
|
||||
* @precision medium
|
||||
* @id js/request-forgery
|
||||
* @tags security
|
||||
* external/cwe/cwe-918
|
||||
*/
|
||||
|
||||
import javascript
|
||||
import semmle.javascript.security.dataflow.RequestForgery::RequestForgery
|
||||
|
||||
from Configuration cfg, DataFlow::Node source, Sink sink, DataFlow::Node request
|
||||
where cfg.hasFlow(source, sink) and
|
||||
request = sink.getARequest()
|
||||
select request, "The $@ of this request depends on $@.", sink, sink.getKind(), source, "a user-provided value"
|
||||
@@ -0,0 +1,12 @@
|
||||
import http from 'http';
|
||||
import url from 'url';
|
||||
|
||||
var server = http.createServer(function(req, res) {
|
||||
var target = url.parse(request.url, true).query.target;
|
||||
|
||||
// BAD: `target` is controlled by the attacker
|
||||
http.get('https://' + target + ".example.com/data/", res => {
|
||||
// process request response ...
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
import http from 'http';
|
||||
import url from 'url';
|
||||
|
||||
var server = http.createServer(function(req, res) {
|
||||
var target = url.parse(request.url, true).query.target;
|
||||
|
||||
var subdomain;
|
||||
if (target === 'EU') {
|
||||
subdomain = "europe"
|
||||
} else {
|
||||
subdomain = "world"
|
||||
}
|
||||
|
||||
// GOOD: `subdomain` is controlled by the server
|
||||
http.get('https://' + subdomain + ".example.com/data/", res => {
|
||||
// process request response ...
|
||||
});
|
||||
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user