diff --git a/.codeqlmanifest.json b/.codeqlmanifest.json index 58157b912c6..421284bc4b9 100644 --- a/.codeqlmanifest.json +++ b/.codeqlmanifest.json @@ -1,4 +1,6 @@ { "provide": [ "*/ql/src/qlpack.yml", + "*/ql/test/qlpack.yml", + "*/upgrades/qlpack.yml", "misc/legacy-support/*/qlpack.yml", "misc/suite-helpers/qlpack.yml", "codeql/.codeqlmanifest.json" ] } diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6c0714571fc..e074b1c2079 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# Contributing to QL +# Contributing to CodeQL We welcome contributions to our standard library and standard checks. Got an idea for a new check, or how to improve an existing query? Then please go ahead and open a pull request! @@ -9,13 +9,13 @@ Before we accept your pull request, we require that you have agreed to our Contr If you have an idea for a query that you would like to share with other Semmle users, please open a pull request to add it to this repository. Follow the steps below to help other users understand what your query does, and to ensure that your query is consistent with the other Semmle queries. -1. **Consult the QL documentation for query writers** +1. **Consult the documentation for query writers** - There is lots of useful documentation to help you write QL, ranging from information about query file structure to language-specific tutorials. For more information on the documentation available, see [Writing QL queries](https://help.semmle.com/QL/learn-ql/writing-queries/writing-queries.html) on [help.semmle.com](https://help.semmle.com). + There is lots of useful documentation to help you write queries, ranging from information about query file structure to tutorials for specific target languages. For more information on the documentation available, see [Writing CodeQL queries](https://help.semmle.com/QL/learn-ql/writing-queries/writing-queries.html) on [help.semmle.com](https://help.semmle.com). -2. **Format your QL correctly** +2. **Format your code correctly** - All of Semmle's standard QL queries and libraries are uniformly formatted for clarity and consistency, so we strongly recommend that all QL contributions follow the same formatting guidelines. If you use QL for Eclipse, you can auto-format your query in the [QL editor](https://help.semmle.com/ql-for-eclipse/Content/WebHelp/ql-editor.html). For more information, see the [QL style guide](https://github.com/Semmle/ql/blob/master/docs/ql-style-guide.md). + All of Semmle's standard queries and libraries are uniformly formatted for clarity and consistency, so we strongly recommend that all contributions follow the same formatting guidelines. If you use QL for Eclipse, you can auto-format your query in the [QL editor](https://help.semmle.com/ql-for-eclipse/Content/WebHelp/ql-editor.html). For more information, see the [CodeQL style guide](https://github.com/Semmle/ql/blob/master/docs/ql-style-guide.md). 3. **Make sure your query has the correct metadata** @@ -29,7 +29,7 @@ Follow the steps below to help other users understand what your query does, and The `select` statement of your query must be compatible with the query type (determined by the `@kind` metadata property) for alert or path results to be displayed correctly in LGTM and QL for Eclipse. For more information on `select` statement format, see [Introduction to query files](https://help.semmle.com/QL/learn-ql/writing-queries/introduction-to-queries.html#select-clause) on help.semmle.com. -5. **Save your query in a `.ql` file in correct language directory in this repository** +5. **Save your query in a `.ql` file in the correct language directory in this repository** There are five language-specific directories in this repository: @@ -54,7 +54,7 @@ repositories, which might be made public. We might also use this information to contact you in relation to your contributions, as well as in the normal course of software development. We also store records of your CLA agreements. Under GDPR legislation, we do this -on the basis of our legitimate interest in creating the QL product. +on the basis of our legitimate interest in creating the CodeQL product. Please do get in touch (privacy@semmle.com) if you have any questions about this or our data protection policies. diff --git a/README.md b/README.md index b483d29cae2..3c73253b6df 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ -# Semmle QL +# CodeQL -This open source repository contains the standard QL libraries and queries that power [LGTM](https://lgtm.com), and the other products that [Semmle](https://semmle.com) makes available to its customers worldwide. +This open source repository contains the standard CodeQL libraries and queries that power [LGTM](https://lgtm.com), and the other products that [Semmle](https://semmle.com) makes available to its customers worldwide. -## How do I learn QL and run queries? +## How do I learn CodeQL and run queries? -There is [extensive documentation](https://help.semmle.com/QL/learn-ql/) on getting started with writing QL. -You can use the [interactive query console](https://lgtm.com/help/lgtm/using-query-console) on LGTM.com or the [QL for Eclipse](https://lgtm.com/help/lgtm/running-queries-ide) plugin to try out your queries on any open-source project that's currently being analyzed. +There is [extensive documentation](https://help.semmle.com/QL/learn-ql/) on getting started with writing CodeQL. +You can use the [interactive query console](https://lgtm.com/help/lgtm/using-query-console) on LGTM.com or the [QL for Eclipse](https://lgtm.com/help/lgtm/running-queries-ide) plugin to try out your queries on any open source project that's currently being analyzed. ## Contributing -We welcome contributions to our standard library and standard checks. Do you have an idea for a new check, or how to improve an existing query? Then please go ahead and open a pull request! Before you do, though, please take the time to read our [contributing guidelines](CONTRIBUTING.md). You can also consult our [style guides](https://github.com/Semmle/ql/tree/master/docs) to learn how to format your QL for consistency and clarity, how to write query metadata, and how to write query help documentation for your query. +We welcome contributions to our standard library and standard checks. Do you have an idea for a new check, or how to improve an existing query? Then please go ahead and open a pull request! Before you do, though, please take the time to read our [contributing guidelines](CONTRIBUTING.md). You can also consult our [style guides](https://github.com/Semmle/ql/tree/master/docs) to learn how to format your code for consistency and clarity, how to write query metadata, and how to write query help documentation for your query. ## License -The QL queries in this repository are licensed under [Apache License 2.0](LICENSE) by [Semmle](https://semmle.com). +The code in this repository is licensed under [Apache License 2.0](LICENSE) by [Semmle](https://semmle.com). diff --git a/change-notes/1.23/analysis-cpp.md b/change-notes/1.23/analysis-cpp.md index 64e9b98fcfb..87910b0d6a5 100644 --- a/change-notes/1.23/analysis-cpp.md +++ b/change-notes/1.23/analysis-cpp.md @@ -9,6 +9,7 @@ The following changes in version 1.23 affect C/C++ analysis in all applications. | **Query** | **Tags** | **Purpose** | |-----------------------------|-----------|--------------------------------------------------------------------| | Hard-coded Japanese era start date (`cpp/japanese-era/exact-era-date`) | reliability, japanese-era | This query is a combination of two old queries that were identical in purpose but separate as an implementation detail. This new query replaces Hard-coded Japanese era start date in call (`cpp/japanese-era/constructor-or-method-with-exact-era-date`) and Hard-coded Japanese era start date in struct (`cpp/japanese-era/struct-with-exact-era-date`). | +| Signed overflow check (`cpp/signed-overflow-check`) | correctness, reliability | Finds overflow checks that rely on signed integer addition to overflow, which has undefined behavior. Example: `a + b < a`. | ## Changes to existing queries @@ -23,8 +24,10 @@ The following changes in version 1.23 affect C/C++ analysis in all applications. | Too many arguments to formatting function (`cpp/too-many-format-arguments`) | Fewer false positive results | Fixed false positives resulting from mistmatching declarations of a formatting function. | | Unclear comparison precedence (`cpp/comparison-precedence`) | Fewer false positive results | False positives involving template classes and functions have been fixed. | | Comparison of narrow type with wide type in loop condition (`cpp/comparison-with-wider-type`) | Higher precision | The precision of this query has been increased to "high" as the alerts from this query have proved to be valuable on real-world projects. With this precision, results are now displayed by default in LGTM. | +| Non-constant format string (`cpp/non-constant-format`) | Fewer false positive results | Fixed false positives resulting from mistmatching declarations of a formatting function. | +| Wrong type of arguments to formatting function (`cpp/wrong-type-format-argument`) | More correct results and fewer false positive results | This query now understands explicitly specified argument numbers in format strings, such as the `1$` in `%1$s`. | -## Changes to QL libraries +## Changes to libraries * The data-flow library has been extended with a new feature to aid debugging. Instead of specifying `isSink(Node n) { any() }` on a configuration to @@ -39,6 +42,10 @@ The following changes in version 1.23 affect C/C++ analysis in all applications. definition of `x` when `x` is a variable of pointer type. It no longer considers deep paths such as `f(&x.myField)` to be definitions of `x`. These changes are in line with the user expectations we've observed. +* The data-flow library now makes it easier to specify barriers/sanitizers + arising from guards by overriding the predicate + `isBarrierGuard`/`isSanitizerGuard` on data-flow and taint-tracking + configurations respectively. * There is now a `DataFlow::localExprFlow` predicate and a `TaintTracking::localExprTaint` predicate to make it easy to use the most common case of local data flow and taint: from one `Expr` to another. @@ -46,7 +53,14 @@ The following changes in version 1.23 affect C/C++ analysis in all applications. clarity (e.g. `isOutReturnPointer()` to `isReturnValueDeref()`). The existing member predicates have been deprecated, and will be removed in a future release. Code that uses the old member predicates should be updated to use the corresponding new member predicate. +* The predicates `Declaration.hasStdName()` and `Declaration.hasGlobalOrStdName` + have been added, simplifying handling of C++ standard library functions. * The control-flow graph is now computed in QL, not in the extractor. This can lead to regressions (or improvements) in how queries are optimized because optimization in QL relies on static size estimates, and the control-flow edge relations will now have different size estimates than before. +* Support has been added for non-type template arguments. This means that the + return type of `Declaration::getTemplateArgument()` and + `Declaration::getATemplateArgument` have changed to `Locatable`. See the + documentation for `Declaration::getTemplateArgument()` and + `Declaration::getTemplateArgumentKind()` for details. diff --git a/change-notes/1.23/analysis-csharp.md b/change-notes/1.23/analysis-csharp.md index 7ec412a0eb2..c5bdae38dcd 100644 --- a/change-notes/1.23/analysis-csharp.md +++ b/change-notes/1.23/analysis-csharp.md @@ -8,7 +8,10 @@ The following changes in version 1.23 affect C# analysis in all applications. | **Query** | **Tags** | **Purpose** | |-----------------------------|-----------|--------------------------------------------------------------------| +| Deserialized delegate (`cs/deserialized-delegate`) | security, external/cwe/cwe-502 | Finds unsafe deserialization of delegate types. | +| Deserialization of untrusted data (`cs/unsafe-deserialization-untrusted-input`) | security, external/cwe/cwe-502 | Finds flow of untrusted input to calls to unsafe deserializers. | | Unsafe year argument for 'DateTime' constructor (`cs/unsafe-year-construction`) | reliability, date-time | Finds incorrect manipulation of `DateTime` values, which could lead to invalid dates. | +| Unsafe deserializer (`cs/unsafe-deserialization`) | security, external/cwe/cwe-502 | Finds calls to unsafe deserializers. | | Mishandling the Japanese era start date (`cs/mishandling-japanese-era`) | reliability, date-time | Finds hard-coded Japanese era start dates that could be invalid. | ## Changes to existing queries @@ -24,7 +27,7 @@ The following changes in version 1.23 affect C# analysis in all applications. * `nameof` expressions are now extracted correctly when the name is a namespace. -## Changes to QL libraries +## Changes to libraries * The new class `NamespaceAccess` models accesses to namespaces, for example in `nameof` expressions. * The data-flow library now makes it easier to specify barriers/sanitizers @@ -43,5 +46,7 @@ The following changes in version 1.23 affect C# analysis in all applications. * There is now a `DataFlow::localExprFlow` predicate and a `TaintTracking::localExprTaint` predicate to make it easy to use the most common case of local data flow and taint: from one `Expr` to another. +* Data is now tracked through null-coalescing expressions (`??`). +* A new library `semmle.code.csharp.Unification` has been added. This library exposes two predicates `unifiable` and `subsumes` for calculating type unification and type subsumption, respectively. ## Changes to autobuilder diff --git a/change-notes/1.23/analysis-java.md b/change-notes/1.23/analysis-java.md index b81b681aac5..8c38f57e9d2 100644 --- a/change-notes/1.23/analysis-java.md +++ b/change-notes/1.23/analysis-java.md @@ -19,7 +19,7 @@ The following changes in version 1.23 affect Java analysis in all applications. | Query built without neutralizing special characters (`java/concatenated-sql-query`) | More results | The query now identifies arguments to `Statement.executeLargeUpdate` and `Connection.prepareCall` as SQL expressions sinks. | | Useless comparison test (`java/constant-comparison`) | Fewer false positives | Additional overflow check patterns are now recognized and no longer reported. | -## Changes to QL libraries +## Changes to libraries * The data-flow library has been extended with a new feature to aid debugging. Instead of specifying `isSink(Node n) { any() }` on a configuration to diff --git a/change-notes/1.23/analysis-javascript.md b/change-notes/1.23/analysis-javascript.md index aa9d2086d14..b70ec5d47ba 100644 --- a/change-notes/1.23/analysis-javascript.md +++ b/change-notes/1.23/analysis-javascript.md @@ -2,7 +2,9 @@ ## General improvements -* Suppor for `globalThis` has been added. +* Automatic classification of generated and minified files has been improved, in particular files generated by Doxygen are now recognized. + +* Support for `globalThis` has been added. * Support for the following frameworks and libraries has been improved: - [firebase](https://www.npmjs.com/package/firebase) @@ -12,8 +14,7 @@ * The call graph has been improved to resolve method calls in more cases. This may produce more security alerts. -* TypeScript 3.6 features are supported. - +* TypeScript 3.6 and 3.7 features are now supported. ## New queries @@ -26,6 +27,7 @@ | Use of returnless function (`js/use-of-returnless-function`) | maintainability, correctness | Highlights calls where the return value is used, but the callee never returns a value. Results are shown on LGTM by default. | | Useless regular expression character escape (`js/useless-regexp-character-escape`) | correctness, security, external/cwe/cwe-20 | Highlights regular expression strings with useless character escapes, indicating a possible violation of [CWE-20](https://cwe.mitre.org/data/definitions/20.html). Results are shown on LGTM by default. | | Unreachable method overloads (`js/unreachable-method-overloads`) | correctness, typescript | Highlights method overloads that are impossible to use from client code. Results are shown on LGTM by default. | +| Ignoring result from pure array method (`js/ignore-array-result`) | maintainability, correctness | Highlights calls to array methods without side effects where the return value is ignored. Results are shown on LGTM by default. | ## Changes to existing queries @@ -44,8 +46,9 @@ | Stored cross-site scripting (`js/stored-xss`) | Fewer false-positive results | The query now recognizes more sanitizers. | | Uncontrolled command line (`js/command-line-injection`) | More results | This query now treats responses from servers as untrusted. | | Uncontrolled data used in path expression (`js/path-injection`) | Fewer false-positive results | This query now recognizes calls to Express `sendFile` as safe in some cases. | +| Unknown directive (`js/unknown-directive`) | Fewer false positive results | This query no longer flags uses of ":", which is sometimes used like a directive. | -## Changes to QL libraries +## Changes to libraries * `Expr.getDocumentation()` now handles chain assignments. diff --git a/change-notes/1.23/analysis-python.md b/change-notes/1.23/analysis-python.md index 00fab13e098..6cea1745284 100644 --- a/change-notes/1.23/analysis-python.md +++ b/change-notes/1.23/analysis-python.md @@ -20,3 +20,8 @@ |----------------------------|------------------------|------------| | Unreachable code | Fewer false positives | Analysis now accounts for uses of `contextlib.suppress` to suppress exceptions. | | `__iter__` method returns a non-iterator | Better alert message | Alert now highlights which class is expected to be an iterator. | + + +## Changes to QL libraries + +* Django library now recognizes positional arguments from a `django.conf.urls.url` regex (Django version 1.x) diff --git a/change-notes/support/README.md b/change-notes/support/README.md index 7813c69523d..f111a437183 100644 --- a/change-notes/support/README.md +++ b/change-notes/support/README.md @@ -1,6 +1,6 @@ # Files moved to ``docs`` directory -Now that all of the QL documentation is in this repository, +Now that all of the CodeQL documentation is in this repository, notes on the languages, compilers, and frameworks supported have moved. They're now stored as part of the Sphinx ``support`` project with the other documentation: ``docs/language/support``. diff --git a/cpp/ql/src/Best Practices/Unused Entities/UnusedStaticVariables.ql b/cpp/ql/src/Best Practices/Unused Entities/UnusedStaticVariables.ql index 26cf42521e5..3ad43998d18 100644 --- a/cpp/ql/src/Best Practices/Unused Entities/UnusedStaticVariables.ql +++ b/cpp/ql/src/Best Practices/Unused Entities/UnusedStaticVariables.ql @@ -21,6 +21,7 @@ from Variable v where v.isStatic() and v.hasDefinition() and + not v.isConstexpr() and not exists(VariableAccess a | a.getTarget() = v) and not v instanceof MemberVariable and not declarationHasSideEffects(v) and diff --git a/cpp/ql/src/Critical/DescriptorMayNotBeClosed.ql b/cpp/ql/src/Critical/DescriptorMayNotBeClosed.ql index 9c93e066119..47401c6eea5 100644 --- a/cpp/ql/src/Critical/DescriptorMayNotBeClosed.ql +++ b/cpp/ql/src/Critical/DescriptorMayNotBeClosed.ql @@ -13,7 +13,7 @@ import semmle.code.cpp.pointsto.PointsTo import Negativity predicate closeCall(FunctionCall fc, Variable v) { - fc.getTarget().hasGlobalName("close") and v.getAnAccess() = fc.getArgument(0) + fc.getTarget().hasGlobalOrStdName("close") and v.getAnAccess() = fc.getArgument(0) or exists(FunctionCall midcall, Function mid, int arg | fc.getArgument(arg) = v.getAnAccess() and diff --git a/cpp/ql/src/Critical/DescriptorNeverClosed.ql b/cpp/ql/src/Critical/DescriptorNeverClosed.ql index b52af1bf2a3..f06708f4ae3 100644 --- a/cpp/ql/src/Critical/DescriptorNeverClosed.ql +++ b/cpp/ql/src/Critical/DescriptorNeverClosed.ql @@ -13,7 +13,7 @@ import semmle.code.cpp.pointsto.PointsTo predicate closed(Expr e) { exists(FunctionCall fc | - fc.getTarget().hasGlobalName("close") and + fc.getTarget().hasGlobalOrStdName("close") and fc.getArgument(0) = e ) } diff --git a/cpp/ql/src/Critical/MemoryMayNotBeFreed.ql b/cpp/ql/src/Critical/MemoryMayNotBeFreed.ql index 9bba8e9896d..2bede681912 100644 --- a/cpp/ql/src/Critical/MemoryMayNotBeFreed.ql +++ b/cpp/ql/src/Critical/MemoryMayNotBeFreed.ql @@ -53,7 +53,7 @@ predicate allocCallOrIndirect(Expr e) { * can cause memory leaks. */ predicate verifiedRealloc(FunctionCall reallocCall, Variable v, ControlFlowNode verified) { - reallocCall.getTarget().hasGlobalName("realloc") and + reallocCall.getTarget().hasGlobalOrStdName("realloc") and reallocCall.getArgument(0) = v.getAnAccess() and ( exists(Variable newV, ControlFlowNode node | @@ -79,7 +79,7 @@ predicate verifiedRealloc(FunctionCall reallocCall, Variable v, ControlFlowNode predicate freeCallOrIndirect(ControlFlowNode n, Variable v) { // direct free call freeCall(n, v.getAnAccess()) and - not n.(FunctionCall).getTarget().hasGlobalName("realloc") + not n.(FunctionCall).getTarget().hasGlobalOrStdName("realloc") or // verified realloc call verifiedRealloc(_, v, n) diff --git a/cpp/ql/src/Critical/OverflowCalculated.ql b/cpp/ql/src/Critical/OverflowCalculated.ql index 36ee0140cf7..fbca4a20a8f 100644 --- a/cpp/ql/src/Critical/OverflowCalculated.ql +++ b/cpp/ql/src/Critical/OverflowCalculated.ql @@ -13,10 +13,7 @@ import cpp class MallocCall extends FunctionCall { - MallocCall() { - this.getTarget().hasGlobalName("malloc") or - this.getTarget().hasQualifiedName("std", "malloc") - } + MallocCall() { this.getTarget().hasGlobalOrStdName("malloc") } Expr getAllocatedSize() { if this.getArgument(0) instanceof VariableAccess @@ -36,12 +33,12 @@ predicate spaceProblem(FunctionCall append, string msg) { malloc.getAllocatedSize() = add and buffer.getAnAccess() = strlen.getStringExpr() and ( - insert.getTarget().hasGlobalName("strcpy") or - insert.getTarget().hasGlobalName("strncpy") + insert.getTarget().hasGlobalOrStdName("strcpy") or + insert.getTarget().hasGlobalOrStdName("strncpy") ) and ( - append.getTarget().hasGlobalName("strcat") or - append.getTarget().hasGlobalName("strncat") + append.getTarget().hasGlobalOrStdName("strcat") or + append.getTarget().hasGlobalOrStdName("strncat") ) and malloc.getASuccessor+() = insert and insert.getArgument(1) = buffer.getAnAccess() and diff --git a/cpp/ql/src/Critical/OverflowDestination.ql b/cpp/ql/src/Critical/OverflowDestination.ql index d7b02b5d8d5..ad925daed62 100644 --- a/cpp/ql/src/Critical/OverflowDestination.ql +++ b/cpp/ql/src/Critical/OverflowDestination.ql @@ -25,7 +25,7 @@ import semmle.code.cpp.security.TaintTracking predicate sourceSized(FunctionCall fc, Expr src) { exists(string name | (name = "strncpy" or name = "strncat" or name = "memcpy" or name = "memmove") and - fc.getTarget().hasGlobalName(name) + fc.getTarget().hasGlobalOrStdName(name) ) and exists(Expr dest, Expr size, Variable v | fc.getArgument(0) = dest and diff --git a/cpp/ql/src/Critical/OverflowStatic.ql b/cpp/ql/src/Critical/OverflowStatic.ql index 1892d5acff1..82ffc879331 100644 --- a/cpp/ql/src/Critical/OverflowStatic.ql +++ b/cpp/ql/src/Critical/OverflowStatic.ql @@ -60,19 +60,19 @@ predicate overflowOffsetInLoop(BufferAccess bufaccess, string msg) { predicate bufferAndSizeFunction(Function f, int buf, int size) { f.hasGlobalName("read") and buf = 1 and size = 2 or - f.hasGlobalName("fgets") and buf = 0 and size = 1 + f.hasGlobalOrStdName("fgets") and buf = 0 and size = 1 or - f.hasGlobalName("strncpy") and buf = 0 and size = 2 + f.hasGlobalOrStdName("strncpy") and buf = 0 and size = 2 or - f.hasGlobalName("strncat") and buf = 0 and size = 2 + f.hasGlobalOrStdName("strncat") and buf = 0 and size = 2 or - f.hasGlobalName("memcpy") and buf = 0 and size = 2 + f.hasGlobalOrStdName("memcpy") and buf = 0 and size = 2 or - f.hasGlobalName("memmove") and buf = 0 and size = 2 + f.hasGlobalOrStdName("memmove") and buf = 0 and size = 2 or - f.hasGlobalName("snprintf") and buf = 0 and size = 1 + f.hasGlobalOrStdName("snprintf") and buf = 0 and size = 1 or - f.hasGlobalName("vsnprintf") and buf = 0 and size = 1 + f.hasGlobalOrStdName("vsnprintf") and buf = 0 and size = 1 } class CallWithBufferSize extends FunctionCall { diff --git a/cpp/ql/src/Critical/SizeCheck.ql b/cpp/ql/src/Critical/SizeCheck.ql index da841b73c9b..313763ba56c 100644 --- a/cpp/ql/src/Critical/SizeCheck.ql +++ b/cpp/ql/src/Critical/SizeCheck.ql @@ -17,12 +17,12 @@ import cpp class Allocation extends FunctionCall { Allocation() { exists(string name | - this.getTarget().hasGlobalName(name) and + this.getTarget().hasGlobalOrStdName(name) and (name = "malloc" or name = "calloc" or name = "realloc") ) } - private string getName() { this.getTarget().hasGlobalName(result) } + private string getName() { this.getTarget().hasGlobalOrStdName(result) } int getSize() { this.getName() = "malloc" and diff --git a/cpp/ql/src/Critical/SizeCheck2.ql b/cpp/ql/src/Critical/SizeCheck2.ql index 3cb5d1d28b0..1b716d79d49 100644 --- a/cpp/ql/src/Critical/SizeCheck2.ql +++ b/cpp/ql/src/Critical/SizeCheck2.ql @@ -17,12 +17,12 @@ import cpp class Allocation extends FunctionCall { Allocation() { exists(string name | - this.getTarget().hasGlobalName(name) and + this.getTarget().hasGlobalOrStdName(name) and (name = "malloc" or name = "calloc" or name = "realloc") ) } - private string getName() { this.getTarget().hasGlobalName(result) } + private string getName() { this.getTarget().hasGlobalOrStdName(result) } int getSize() { this.getName() = "malloc" and diff --git a/cpp/ql/src/Critical/UseAfterFree.ql b/cpp/ql/src/Critical/UseAfterFree.ql index db78c206ea1..9efbb6c3b44 100644 --- a/cpp/ql/src/Critical/UseAfterFree.ql +++ b/cpp/ql/src/Critical/UseAfterFree.ql @@ -16,7 +16,7 @@ import semmle.code.cpp.controlflow.LocalScopeVariableReachability predicate isFreeExpr(Expr e, LocalScopeVariable v) { exists(VariableAccess va | va.getTarget() = v | exists(FunctionCall fc | fc = e | - fc.getTarget().hasGlobalName("free") and + fc.getTarget().hasGlobalOrStdName("free") and va = fc.getArgument(0) ) or diff --git a/cpp/ql/src/DefaultOptions.qll b/cpp/ql/src/DefaultOptions.qll index 27e5584369e..3e03ec9ee65 100644 --- a/cpp/ql/src/DefaultOptions.qll +++ b/cpp/ql/src/DefaultOptions.qll @@ -59,7 +59,7 @@ class Options extends string { predicate exits(Function f) { f.getAnAttribute().hasName("noreturn") or - exists(string name | f.hasGlobalName(name) | + exists(string name | f.hasGlobalOrStdName(name) | name = "exit" or name = "_exit" or name = "abort" or @@ -91,7 +91,7 @@ class Options extends string { * By default holds only for `fgets`. */ predicate alwaysCheckReturnValue(Function f) { - f.hasGlobalName("fgets") or + f.hasGlobalOrStdName("fgets") or CustomOptions::alwaysCheckReturnValue(f) // old Options.qll } diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql b/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql index afe49a1053b..c89ba211bbc 100644 --- a/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql +++ b/cpp/ql/src/Likely Bugs/Arithmetic/PointlessSelfComparison.ql @@ -19,6 +19,7 @@ where pointlessSelfComparison(cmp) and not nanTest(cmp) and not overflowTest(cmp) and + not cmp.isFromTemplateInstantiation(_) and not exists(MacroInvocation mi | // cmp is in mi mi.getAnExpandedElement() = cmp and diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-bad1.cpp b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-bad1.cpp new file mode 100644 index 00000000000..e50273aacde --- /dev/null +++ b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-bad1.cpp @@ -0,0 +1,3 @@ +bool foo(int n1, unsigned short delta) { + return n1 + delta < n1; // BAD +} diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-bad2.cpp b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-bad2.cpp new file mode 100644 index 00000000000..7f69e374ed1 --- /dev/null +++ b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-bad2.cpp @@ -0,0 +1,4 @@ +bool bar(unsigned short n1, unsigned short delta) { + // NB: Comparison is always false + return n1 + delta < n1; // GOOD (but misleading) +} diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-good1.cpp b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-good1.cpp new file mode 100644 index 00000000000..424684ee2ec --- /dev/null +++ b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-good1.cpp @@ -0,0 +1,4 @@ +#include +bool foo(int n1, unsigned short delta) { + return n1 > INT_MAX - delta; // GOOD +} diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-good2.cpp b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-good2.cpp new file mode 100644 index 00000000000..de8de2b9847 --- /dev/null +++ b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck-good2.cpp @@ -0,0 +1,3 @@ +bool bar(unsigned short n1, unsigned short delta) { + return (unsigned short)(n1 + delta) < n1; // GOOD +} diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.qhelp b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.qhelp new file mode 100644 index 00000000000..621ae3273fd --- /dev/null +++ b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.qhelp @@ -0,0 +1,115 @@ + + + +

+When checking for integer overflow, you may often write tests like +a + b < a. This works fine if a or +b are unsigned integers, since any overflow in the addition +will cause the value to simply "wrap around." However, using +signed integers is problematic because signed overflow has undefined +behavior according to the C and C++ standards. If the addition overflows +and has an undefined result, the comparison will likewise be undefined; +it may produce an unintended result, or may be deleted entirely by an +optimizing compiler. +

+
+ +

+Solutions to this problem can be thought of as falling into one of two +categories: (1) rewrite the signed expression so that overflow cannot occur +but the signedness remains, or (2) rewrite (or cast) the signed expression +into unsigned form. +

+ +

+Below we list examples of expressions where signed overflow may +occur, along with proposed solutions. The list should not be +considered exhaustive. +

+ +

+Given unsigned short i, delta and i + delta < i, +it is possible to rewrite it as (unsigned short)(i + delta) < i. +Note that i + deltadoes not actually overflow, due to int promotion +

+ +

+Given unsigned short i, delta and i + delta < i, +it is also possible to rewrite it as USHORT_MAX - delta. It must be true +that delta > 0 and the limits.h or climits +header has been included. +

+ +

+Given int i, delta and i + delta < i, +it is possible to rewrite it as INT_MAX - delta. It must be true +that delta > 0 and the limits.h or climits +header has been included. +

+ +

+Given int i, delta and i + delta < i, +it is also possible to rewrite it as (unsigned)i + delta < i. +Note that program semantics are affected by this change. +

+ +

+Given int i, delta and i + delta < i, +it is also possible to rewrite it as unsigned int i, delta and +i + delta < i. Note that program semantics are +affected by this change. +

+
+ + +

+In the following example, even though delta has been declared +unsigned short, C/C++ type promotion rules require that its +type is promoted to the larger type used in the addition and comparison, +namely a signed int. Addition is performed on +signed integers, and may have undefined behavior if an overflow occurs. +As a result, the entire (comparison) expression may also have an undefined +result. +

+ +

+The following example builds upon the previous one. Instead of +performing an addition (which could overflow), we have re-framed the +solution so that a subtraction is used instead. Since delta +is promoted to a signed int and INT_MAX denotes +the largest possible positive value for an signed int, +the expression INT_MAX - delta can never be less than zero +or more than INT_MAX. Hence, any overflow and underflow +are avoided. +

+ +

+In the following example, even though both n and delta +have been declared unsigned short, both are promoted to +signed int prior to addition. Because we started out with the +narrower short type, the addition is guaranteed not to overflow +and is therefore defined. But the fact that n1 + delta never +overflows means that the condition n1 + delta < n1 will never +hold true, which likely is not what the programmer intended. (see also the +cpp/bad-addition-overflow-check query). +

+ +

+The next example provides a solution to the previous one. Even though +i + delta does not overflow, casting it to an +unsigned short truncates the addition modulo 2^16, +so that unsigned short "wrap around" may now be observed. +Furthermore, since the left-hand side is now of type unsigned short, +the right-hand side does not need to be promoted to a signed int. +

+ + +
+ +
  • comp.lang.c FAQ list ยท Question 3.19 (Preserving rules)
  • +
  • INT31-C. Ensure that integer conversions do not result in lost or misinterpreted data
  • +
  • W. Dietz, P. Li, J. Regehr, V. Adve. Understanding Integer Overflow in C/C++
  • +
    +
    diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.ql b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.ql new file mode 100644 index 00000000000..648846a7dc1 --- /dev/null +++ b/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.ql @@ -0,0 +1,31 @@ +/** + * @name Undefined result of signed test for overflow + * @description Testing for overflow by adding a value to a variable + * to see if it "wraps around" works only for + * unsigned integer values. + * @kind problem + * @problem.severity warning + * @precision high + * @id cpp/signed-overflow-check + * @tags reliability + * security + */ + +import cpp +private import semmle.code.cpp.valuenumbering.GlobalValueNumbering +private import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis + +from RelationalOperation ro, AddExpr add, Expr expr1, Expr expr2 +where + ro.getAnOperand() = add and + add.getAnOperand() = expr1 and + ro.getAnOperand() = expr2 and + globalValueNumber(expr1) = globalValueNumber(expr2) and + add.getUnspecifiedType().(IntegralType).isSigned() and + not exists(MacroInvocation mi | mi.getAnAffectedElement() = add) and + exprMightOverflowPositively(add) and + exists(Compilation c | c.getAFileCompiled() = ro.getFile() | + not c.getAnArgument() = "-fwrapv" and + not c.getAnArgument() = "-fno-strict-overflow" + ) +select ro, "Testing for signed overflow may produce undefined results." diff --git a/cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayNoBound.qll b/cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayNoBound.qll deleted file mode 100644 index 3e1f74bfbed..00000000000 --- a/cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayNoBound.qll +++ /dev/null @@ -1,33 +0,0 @@ -import cpp -import semmle.code.cpp.dataflow.DataFlow -import semmle.code.cpp.controlflow.Guards -import BufferAccess -import semmle.code.cpp.valuenumbering.GlobalValueNumbering - -class NetworkFunctionCall extends FunctionCall { - NetworkFunctionCall() { - getTarget().hasName("ntohd") or - getTarget().hasName("ntohf") or - getTarget().hasName("ntohl") or - getTarget().hasName("ntohll") or - getTarget().hasName("ntohs") - } -} - -class NetworkToBufferSizeConfiguration extends DataFlow::Configuration { - NetworkToBufferSizeConfiguration() { this = "NetworkToBufferSizeConfiguration" } - - override predicate isSource(DataFlow::Node node) { node.asExpr() instanceof NetworkFunctionCall } - - override predicate isSink(DataFlow::Node node) { - node.asExpr() = any(BufferAccess ba).getAccessedLength() - } - - override predicate isBarrier(DataFlow::Node node) { - exists(GuardCondition gc, GVN gvn | - gc.getAChild*() = gvn.getAnExpr() and - globalValueNumber(node.asExpr()) = gvn and - gc.controls(node.asExpr().getBasicBlock(), _) - ) - } -} diff --git a/cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayBad.cpp b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound-bad.cpp similarity index 100% rename from cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayBad.cpp rename to cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound-bad.cpp diff --git a/cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayGood.cpp b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound-good.cpp similarity index 100% rename from cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayGood.cpp rename to cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound-good.cpp diff --git a/cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayNoBoundOpenSource.qhelp b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qhelp similarity index 90% rename from cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayNoBoundOpenSource.qhelp rename to cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qhelp index 522d6cde74c..3556df38c58 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayNoBoundOpenSource.qhelp +++ b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qhelp @@ -14,7 +14,7 @@ byte order function, such as ntohl. The use of a network-to-host byte order function is therefore a good indicator that the returned value is unvalidated data retrieved from the network, and should not be used without further validation. In particular, the returned value should not be used as an array index or array length -value without validation, which may result in a buffer overflow vulnerability. +value without validation, as this could result in a buffer overflow vulnerability.

    @@ -31,10 +31,10 @@ it to host byte order. The data is then used as an index in an array access expr there is no validation that the data returned by ntohl is within the bounds of the array, which could lead to reading outside the bounds of the buffer.

    - +

    In the corrected example, the returned data is validated against the known size of the buffer, before being used as an array index.

    - + diff --git a/cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayNoBoundOpenSource.ql b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.ql similarity index 100% rename from cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/NtohlArrayNoBoundOpenSource.ql rename to cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.ql diff --git a/cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/BufferAccess.qll b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qll similarity index 71% rename from cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/BufferAccess.qll rename to cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qll index 286db31020f..0871da2f92e 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/Buffer Overflow/BufferAccess.qll +++ b/cpp/ql/src/Likely Bugs/Memory Management/NtohlArrayNoBound.qll @@ -1,55 +1,7 @@ import cpp -import semmle.code.cpp.dataflow.TaintTracking -private import semmle.code.cpp.dataflow.RecursionPrevention - -/** - * A buffer which includes an allocation size. - */ -abstract class BufferWithSize extends DataFlow::Node { - abstract Expr getSizeExpr(); - - BufferAccess getAnAccess() { - any(BufferWithSizeConfig bsc).hasFlow(this, DataFlow::exprNode(result.getPointer())) - } -} - -/** An allocation function. */ -abstract class Alloc extends Function { } - -/** - * Allocation functions identified by the QL for C/C++ standard library. - */ -class DefaultAlloc extends Alloc { - DefaultAlloc() { allocationFunction(this) } -} - -/** A buffer created through a call to an allocation function. */ -class AllocBuffer extends BufferWithSize { - FunctionCall call; - - AllocBuffer() { - asExpr() = call and - call.getTarget() instanceof Alloc - } - - override Expr getSizeExpr() { result = call.getArgument(0) } -} - -/** - * Find accesses of buffers for which we have a size expression. - */ -private class BufferWithSizeConfig extends TaintTracking::Configuration { - BufferWithSizeConfig() { this = "BufferWithSize" } - - override predicate isSource(DataFlow::Node n) { n = any(BufferWithSize b) } - - override predicate isSink(DataFlow::Node n) { n.asExpr() = any(BufferAccess ae).getPointer() } - - override predicate isSanitizer(DataFlow::Node s) { - s = any(BufferWithSize b) and - s.asExpr().getControlFlowScope() instanceof Alloc - } -} +import semmle.code.cpp.dataflow.DataFlow +import semmle.code.cpp.controlflow.Guards +import semmle.code.cpp.valuenumbering.GlobalValueNumbering /** * An access (read or write) to a buffer, provided as a pair of @@ -172,3 +124,31 @@ class MallocSizeExpr extends BufferAccess, FunctionCall { override Expr getAccessedLength() { result = getArgument(1) } } + +class NetworkFunctionCall extends FunctionCall { + NetworkFunctionCall() { + getTarget().hasName("ntohd") or + getTarget().hasName("ntohf") or + getTarget().hasName("ntohl") or + getTarget().hasName("ntohll") or + getTarget().hasName("ntohs") + } +} + +class NetworkToBufferSizeConfiguration extends DataFlow::Configuration { + NetworkToBufferSizeConfiguration() { this = "NetworkToBufferSizeConfiguration" } + + override predicate isSource(DataFlow::Node node) { node.asExpr() instanceof NetworkFunctionCall } + + override predicate isSink(DataFlow::Node node) { + node.asExpr() = any(BufferAccess ba).getAccessedLength() + } + + override predicate isBarrier(DataFlow::Node node) { + exists(GuardCondition gc, GVN gvn | + gc.getAChild*() = gvn.getAnExpr() and + globalValueNumber(node.asExpr()) = gvn and + gc.controls(node.asExpr().getBasicBlock(), _) + ) + } +} diff --git a/cpp/ql/src/Likely Bugs/Protocols/boostorg/TlsSettingsMisconfiguration.qhelp b/cpp/ql/src/Likely Bugs/Protocols/TlsSettingsMisconfiguration.qhelp similarity index 100% rename from cpp/ql/src/Likely Bugs/Protocols/boostorg/TlsSettingsMisconfiguration.qhelp rename to cpp/ql/src/Likely Bugs/Protocols/TlsSettingsMisconfiguration.qhelp diff --git a/cpp/ql/src/Likely Bugs/Protocols/boostorg/TlsSettingsMisconfiguration.ql b/cpp/ql/src/Likely Bugs/Protocols/TlsSettingsMisconfiguration.ql similarity index 50% rename from cpp/ql/src/Likely Bugs/Protocols/boostorg/TlsSettingsMisconfiguration.ql rename to cpp/ql/src/Likely Bugs/Protocols/TlsSettingsMisconfiguration.ql index 83ed90bafab..53ad71cb22d 100644 --- a/cpp/ql/src/Likely Bugs/Protocols/boostorg/TlsSettingsMisconfiguration.ql +++ b/cpp/ql/src/Likely Bugs/Protocols/TlsSettingsMisconfiguration.ql @@ -13,32 +13,33 @@ import semmle.code.cpp.security.boostorg.asio.protocols class ExistsAnyFlowConfig extends DataFlow::Configuration { ExistsAnyFlowConfig() { this = "ExistsAnyFlowConfig" } - override predicate isSource(DataFlow::Node source) { any() } + override predicate isSource(DataFlow::Node source) { + exists(BoostorgAsio::SslContextClass c | c.getAContructorCall() = source.asExpr()) + } - override predicate isSink(DataFlow::Node sink) { any() } + override predicate isSink(DataFlow::Node sink) { + exists(BoostorgAsio::SslSetOptionsFunction f, FunctionCall fcSetOptions | + f.getACallToThisFunction() = fcSetOptions and + fcSetOptions.getQualifier() = sink.asExpr() + ) + } } bindingset[flag] predicate isOptionSet(ConstructorCall cc, int flag, FunctionCall fcSetOptions) { - exists( - BoostorgAsio::SslContextFlowsToSetOptionConfig config, ExistsAnyFlowConfig testConfig, - Expr optionsSink - | - config.hasFlow(DataFlow::exprNode(cc), DataFlow::exprNode(optionsSink)) and - exists(VariableAccess contextSetOptions | - testConfig.hasFlow(DataFlow::exprNode(cc), DataFlow::exprNode(contextSetOptions)) and - exists(BoostorgAsio::SslSetOptionsFunction f | f.getACallToThisFunction() = fcSetOptions | - contextSetOptions = fcSetOptions.getQualifier() and - forall( - Expr optionArgument, BoostorgAsio::SslOptionConfig optionArgConfig, - Expr optionArgumentSource - | - optionArgument = fcSetOptions.getArgument(0) and - optionArgConfig - .hasFlow(DataFlow::exprNode(optionArgumentSource), DataFlow::exprNode(optionArgument)) - | - optionArgument.getValue().toInt().bitShiftRight(16).bitAnd(flag) = flag - ) + exists(ExistsAnyFlowConfig anyFlowConfig, VariableAccess contextSetOptions | + anyFlowConfig.hasFlow(DataFlow::exprNode(cc), DataFlow::exprNode(contextSetOptions)) and + exists(BoostorgAsio::SslSetOptionsFunction f | f.getACallToThisFunction() = fcSetOptions | + contextSetOptions = fcSetOptions.getQualifier() and + forall( + Expr optionArgument, BoostorgAsio::SslOptionConfig optionArgConfig, + Expr optionArgumentSource + | + optionArgument = fcSetOptions.getArgument(0) and + optionArgConfig + .hasFlow(DataFlow::exprNode(optionArgumentSource), DataFlow::exprNode(optionArgument)) + | + optionArgument.getValue().toInt().bitShiftRight(16).bitAnd(flag) = flag ) ) ) @@ -46,43 +47,18 @@ predicate isOptionSet(ConstructorCall cc, int flag, FunctionCall fcSetOptions) { bindingset[flag] predicate isOptionNotSet(ConstructorCall cc, int flag) { - not exists( - BoostorgAsio::SslContextFlowsToSetOptionConfig config, ExistsAnyFlowConfig testConfig, - Expr optionsSink - | - config.hasFlow(DataFlow::exprNode(cc), DataFlow::exprNode(optionsSink)) and - exists(VariableAccess contextSetOptions | - testConfig.hasFlow(DataFlow::exprNode(cc), DataFlow::exprNode(contextSetOptions)) and - exists(FunctionCall fcSetOptions, BoostorgAsio::SslSetOptionsFunction f | - f.getACallToThisFunction() = fcSetOptions - | - contextSetOptions = fcSetOptions.getQualifier() and - forall( - Expr optionArgument, BoostorgAsio::SslOptionConfig optionArgConfig, - Expr optionArgumentSource - | - optionArgument = fcSetOptions.getArgument(0) and - optionArgConfig - .hasFlow(DataFlow::exprNode(optionArgumentSource), DataFlow::exprNode(optionArgument)) - | - optionArgument.getValue().toInt().bitShiftRight(16).bitAnd(flag) = flag - ) - ) - ) - ) + not exists(FunctionCall fcSetOptions | isOptionSet(cc, flag, fcSetOptions)) } from - BoostorgAsio::SslContextCallTlsProtocolConfig configConstructor, - BoostorgAsio::SslContextFlowsToSetOptionConfig config, Expr protocolSource, Expr protocolSink, - ConstructorCall cc, Expr e, string msg + BoostorgAsio::SslContextCallTlsProtocolConfig configConstructor, Expr protocolSource, + Expr protocolSink, ConstructorCall cc, Expr e, string msg where configConstructor.hasFlow(DataFlow::exprNode(protocolSource), DataFlow::exprNode(protocolSink)) and cc.getArgument(0) = protocolSink and ( BoostorgAsio::isExprSslV23BoostProtocol(protocolSource) and - not exists(Expr optionsSink | - config.hasFlow(DataFlow::exprNode(cc), DataFlow::exprNode(optionsSink)) and + not ( isOptionSet(cc, BoostorgAsio::getShiftedSslOptionsNoSsl3(), _) and isOptionSet(cc, BoostorgAsio::getShiftedSslOptionsNoTls1(), _) and isOptionSet(cc, BoostorgAsio::getShiftedSslOptionsNoTls1_1(), _) and @@ -91,8 +67,7 @@ where or BoostorgAsio::isExprTlsBoostProtocol(protocolSource) and not BoostorgAsio::isExprSslV23BoostProtocol(protocolSource) and - not exists(Expr optionsSink | - config.hasFlow(DataFlow::exprNode(cc), DataFlow::exprNode(optionsSink)) and + not ( isOptionSet(cc, BoostorgAsio::getShiftedSslOptionsNoTls1(), _) and isOptionSet(cc, BoostorgAsio::getShiftedSslOptionsNoTls1_1(), _) and isOptionNotSet(cc, BoostorgAsio::getShiftedSslOptionsNoTls1_2()) diff --git a/cpp/ql/src/Likely Bugs/Protocols/boostorg/UseOfDeprecatedHardcodedProtocol.qhelp b/cpp/ql/src/Likely Bugs/Protocols/UseOfDeprecatedHardcodedProtocol.qhelp similarity index 100% rename from cpp/ql/src/Likely Bugs/Protocols/boostorg/UseOfDeprecatedHardcodedProtocol.qhelp rename to cpp/ql/src/Likely Bugs/Protocols/UseOfDeprecatedHardcodedProtocol.qhelp diff --git a/cpp/ql/src/Likely Bugs/Protocols/boostorg/UseOfDeprecatedHardcodedProtocol.ql b/cpp/ql/src/Likely Bugs/Protocols/UseOfDeprecatedHardcodedProtocol.ql similarity index 100% rename from cpp/ql/src/Likely Bugs/Protocols/boostorg/UseOfDeprecatedHardcodedProtocol.ql rename to cpp/ql/src/Likely Bugs/Protocols/UseOfDeprecatedHardcodedProtocol.ql diff --git a/cpp/ql/src/Microsoft/IgnoreReturnValueSAL.ql b/cpp/ql/src/Microsoft/IgnoreReturnValueSAL.ql index 64f398fa855..fb25a93963d 100644 --- a/cpp/ql/src/Microsoft/IgnoreReturnValueSAL.ql +++ b/cpp/ql/src/Microsoft/IgnoreReturnValueSAL.ql @@ -7,6 +7,10 @@ * @id cpp/ignore-return-value-sal * @problem.severity warning * @tags reliability + * external/cwe/cwe-573 + * external/cwe/cwe-252 + * @opaque-id SM02344 + * @microsoft.severity Important */ import SAL diff --git a/cpp/ql/src/Microsoft/SAL.qll b/cpp/ql/src/Microsoft/SAL.qll index fe6b455fa9b..963a726ae54 100644 --- a/cpp/ql/src/Microsoft/SAL.qll +++ b/cpp/ql/src/Microsoft/SAL.qll @@ -126,7 +126,7 @@ class SALParameter extends Parameter { } /** - * A SAL element, i.e. a SAL annotation or a declaration entry + * A SAL element, that is, a SAL annotation or a declaration entry * that may have SAL annotations. */ library class SALElement extends Element { diff --git a/cpp/ql/src/Microsoft/SAL/IgnoreReturnValueSAL.ql b/cpp/ql/src/Microsoft/SAL/IgnoreReturnValueSAL.ql deleted file mode 100644 index 569f684a4c3..00000000000 --- a/cpp/ql/src/Microsoft/SAL/IgnoreReturnValueSAL.ql +++ /dev/null @@ -1,25 +0,0 @@ -/** - * @name SAL requires inspecting return value - * @description When a return value is discarded even though the SAL annotation - * requires inspecting it, a recoverable error may turn into a - * whole-program crash. - * @kind problem - * @problem.severity warning - * @tags reliability - * external/cwe/cwe-573 - * external/cwe/cwe-252 - * @opaque-id SM02344 - * @microsoft.severity Important - * @id cpp/ignorereturnvaluesal - */ - -import Microsoft.SAL - -from Function f, FunctionCall call -where - call.getTarget() = f and - call instanceof ExprInVoidContext and - any(SALCheckReturn a).getDeclaration() = f and - not any(Options o).okToIgnoreReturnValue(call) -select call, "Return value of $@ discarded although a SAL annotation " + "requires inspecting it.", - f, f.getName() diff --git a/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql b/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql index 096b1468bb9..42a29b96268 100644 --- a/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql +++ b/cpp/ql/src/Security/CWE/CWE-022/TaintedPath.ql @@ -34,8 +34,10 @@ class FileFunction extends FunctionWithWrappers { nme.matches("CreateFile%") ) or + this.hasQualifiedName("std", "fopen") + or // on any of the fstream classes, or filebuf - exists(string nme | this.getDeclaringType().getSimpleName() = nme | + exists(string nme | this.getDeclaringType().hasQualifiedName("std", nme) | nme = "basic_fstream" or nme = "basic_ifstream" or nme = "basic_ofstream" or diff --git a/cpp/ql/src/Security/CWE/CWE-079/CgiXss.qhelp b/cpp/ql/src/Security/CWE/CWE-079/CgiXss.qhelp index ccd297c3b36..4ad7a40fed6 100644 --- a/cpp/ql/src/Security/CWE/CWE-079/CgiXss.qhelp +++ b/cpp/ql/src/Security/CWE/CWE-079/CgiXss.qhelp @@ -34,7 +34,7 @@ characters before writing to the HTML page.

  • OWASP: -XSS +XSS (Cross Site Scripting) Prevention Cheat Sheet.
  • diff --git a/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql b/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql index 4469517c369..8b7fb83df81 100644 --- a/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql +++ b/cpp/ql/src/Security/CWE/CWE-079/CgiXss.ql @@ -17,8 +17,8 @@ import semmle.code.cpp.security.TaintTracking /** A call that prints its arguments to `stdout`. */ class PrintStdoutCall extends FunctionCall { PrintStdoutCall() { - getTarget().hasGlobalName("puts") or - getTarget().hasGlobalName("printf") + getTarget().hasGlobalOrStdName("puts") or + getTarget().hasGlobalOrStdName("printf") } } diff --git a/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql b/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql index 575752f0b74..ff17daca05c 100644 --- a/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql +++ b/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql @@ -19,10 +19,7 @@ import semmle.code.cpp.dataflow.DataFlow import semmle.code.cpp.models.implementations.Memcpy class MallocCall extends FunctionCall { - MallocCall() { - this.getTarget().hasGlobalName("malloc") or - this.getTarget().hasQualifiedName("std", "malloc") - } + MallocCall() { this.getTarget().hasGlobalOrStdName("malloc") } Expr getAllocatedSize() { if this.getArgument(0) instanceof VariableAccess diff --git a/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariable.qhelp b/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariable.qhelp index b9118edc736..8e6a8903483 100644 --- a/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariable.qhelp +++ b/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariable.qhelp @@ -37,7 +37,7 @@ which is then subsequently accessed to fetch properties of the device. However, check the return value from the function call to initDeviceConfig. If the device number passed to the notify function was invalid, the initDeviceConfig function will leave the config variable uninitialized, -which would result in the notify function accessing uninitialized memory.

    +which will result in the notify function accessing uninitialized memory.

    diff --git a/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariable.ql b/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariable.ql index eb00fb9ea10..f9eb2fe5400 100644 --- a/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariable.ql +++ b/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariable.ql @@ -2,7 +2,7 @@ * @name Conditionally uninitialized variable * @description When an initialization function is used to initialize a local variable, but the * returned status code is not checked, the variable may be left in an uninitialized - * state, and reading the variable may result in undefined behaviour. + * state, and reading the variable may result in undefined behavior. * @kind problem * @problem.severity warning * @opaque-id SM02313 diff --git a/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariableBad.c b/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariableBad.c index 1f281f3cfd9..73a01c2d900 100644 --- a/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariableBad.c +++ b/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariableBad.c @@ -19,7 +19,7 @@ int notify(int deviceNumber) { DeviceConfig config; initDeviceConfig(&config, deviceNumber); // BAD: Using config without checking the status code that is returned - if (config->isEnabled) { - notifyChannel(config->channel); + if (config.isEnabled) { + notifyChannel(config.channel); } -} \ No newline at end of file +} diff --git a/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariableGood.c b/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariableGood.c index a9dcc06c9a5..ced43a66cfc 100644 --- a/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariableGood.c +++ b/cpp/ql/src/Security/CWE/CWE-457/ConditionallyUninitializedVariableGood.c @@ -20,8 +20,8 @@ void notify(int deviceNumber) { int statusCode = initDeviceConfig(&config, deviceNumber); if (statusCode == 0) { // GOOD: Status code returned by initialization function is checked, so this is safe - if (config->isEnabled) { - notifyChannel(config->channel); + if (config.isEnabled) { + notifyChannel(config.channel); } } -} \ No newline at end of file +} diff --git a/cpp/ql/src/Security/CWE/CWE-457/InitializationFunctions.qll b/cpp/ql/src/Security/CWE/CWE-457/InitializationFunctions.qll index 240bd7aa25e..8f2950c9123 100644 --- a/cpp/ql/src/Security/CWE/CWE-457/InitializationFunctions.qll +++ b/cpp/ql/src/Security/CWE/CWE-457/InitializationFunctions.qll @@ -4,7 +4,7 @@ import cpp import external.ExternalArtifact -private import semmle.code.cpp.dispatch.VirtualDispatch +private import semmle.code.cpp.dispatch.VirtualDispatchPrototype import semmle.code.cpp.NestedFields import Microsoft.SAL import semmle.code.cpp.controlflow.Guards @@ -89,9 +89,9 @@ class ParameterNullCheck extends ParameterCheck { ( va = this.(NotExpr).getOperand() or va = any(EQExpr eq | eq = this and eq.getAnOperand().getValue() = "0").getAnOperand() or - va = getAssertedFalseCondition(this) or + va = getCheckedFalseCondition(this) or va = any(NEExpr eq | - eq = getAssertedFalseCondition(this) and eq.getAnOperand().getValue() = "0" + eq = getCheckedFalseCondition(this) and eq.getAnOperand().getValue() = "0" ).getAnOperand() ) or @@ -101,7 +101,7 @@ class ParameterNullCheck extends ParameterCheck { va = this or va = any(NEExpr eq | eq = this and eq.getAnOperand().getValue() = "0").getAnOperand() or va = any(EQExpr eq | - eq = getAssertedFalseCondition(this) and eq.getAnOperand().getValue() = "0" + eq = getCheckedFalseCondition(this) and eq.getAnOperand().getValue() = "0" ).getAnOperand() ) ) @@ -567,7 +567,7 @@ Expr getAnInitializedArgument(Call call) { result = call.getArgument(initialized * the call, under the given context and evidence. */ pragma[nomagic] -int conditionallyInitializedArgument( +private int conditionallyInitializedArgument( Call call, ConditionalInitializationFunction target, Context c, Evidence e ) { target = getTarget(call) and @@ -588,7 +588,7 @@ Expr getAConditionallyInitializedArgument( /** * Gets the type signature for the functions parameters. */ -string typeSig(Function f) { +private string typeSig(Function f) { result = concat(int i, Type pt | pt = f.getParameter(i).getType() | @@ -599,7 +599,7 @@ string typeSig(Function f) { /** * Holds where qualifiedName and typeSig make up the signature for the function. */ -predicate functionSignature(Function f, string qualifiedName, string typeSig) { +private predicate functionSignature(Function f, string qualifiedName, string typeSig) { qualifiedName = f.getQualifiedName() and typeSig = typeSig(f) } @@ -611,7 +611,7 @@ predicate functionSignature(Function f, string qualifiedName, string typeSig) { * This is useful for identifying call to target dependencies across libraries, where the libraries * are never statically linked together. */ -Function getAPossibleDefinition(Function undefinedFunction) { +private Function getAPossibleDefinition(Function undefinedFunction) { not undefinedFunction.isDefined() and exists(string qn, string typeSig | functionSignature(undefinedFunction, qn, typeSig) and functionSignature(result, qn, typeSig) @@ -620,32 +620,47 @@ Function getAPossibleDefinition(Function undefinedFunction) { } /** - * Gets a possible target for the Call, using the name and parameter matching if we did not associate + * Helper predicate for `getTarget`, that computes possible targets of a `Call`. + * + * If there is at least one defined target after performing some simple virtual dispatch + * resolution, then the result is all the defined targets. + */ +private Function getTarget1(Call c) { + result = VirtualDispatch::getAViableTarget(c) and + result.isDefined() +} + +/** + * Helper predicate for `getTarget`, that computes possible targets of a `Call`. + * + * If we can use the heuristic matching of functions to find definitions for some of the viable + * targets, return those. + */ +private Function getTarget2(Call c) { + not exists(getTarget1(c)) and + result = getAPossibleDefinition(VirtualDispatch::getAViableTarget(c)) +} + +/** + * Helper predicate for `getTarget`, that computes possible targets of a `Call`. + * + * Otherwise, the result is the undefined `Function` instances. + */ +private Function getTarget3(Call c) { + not exists(getTarget1(c)) and + not exists(getTarget2(c)) and + result = VirtualDispatch::getAViableTarget(c) +} + +/** + * Gets a possible target for the `Call`, using the name and parameter matching if we did not associate * this call with a specific definition at link or compile time, and performing simple virtual * dispatch resolution. */ Function getTarget(Call c) { - if VirtualDispatch::getAViableTarget(c).isDefined() - then - /* - * If there is at least one defined target after performing some simple virtual dispatch - * resolution, then the result is all the defined targets. - */ - - result = VirtualDispatch::getAViableTarget(c) and - result.isDefined() - else - if exists(getAPossibleDefinition(VirtualDispatch::getAViableTarget(c))) - then - /* - * If we can use the heuristic matching of functions to find definitions for some of the viable - * targets, return those. - */ - - result = getAPossibleDefinition(VirtualDispatch::getAViableTarget(c)) - else - // Otherwise, the result is the undefined `Function` instances - result = VirtualDispatch::getAViableTarget(c) + result = getTarget1(c) or + result = getTarget2(c) or + result = getTarget3(c) } /** @@ -669,7 +684,7 @@ FieldAccess getAFieldAccess(Variable v) { } /** - * Gets a condition which is asserted to be false by the given `ne` expression, according to this pattern: + * Gets a condition which is checked to be false by the given `ne` expression, according to this pattern: * ``` * int a = !!result; * if (!a) { // <- ne @@ -677,7 +692,7 @@ FieldAccess getAFieldAccess(Variable v) { * } * ``` */ -Expr getAssertedFalseCondition(NotExpr ne) { +private Expr getCheckedFalseCondition(NotExpr ne) { exists(LocalVariable v | result = v.getInitializer().getExpr().(NotExpr).getOperand().(NotExpr).getOperand() and ne.getOperand() = v.getAnAccess() and diff --git a/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql b/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql index fa74c85555d..63eca292297 100644 --- a/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql +++ b/cpp/ql/src/Security/CWE/CWE-497/ExposedSystemData.ql @@ -190,11 +190,11 @@ private predicate windowsSystemInfo(FunctionCall source, Element use) { // void WINAPI GetSystemInfo(_Out_ LPSYSTEM_INFO lpSystemInfo); // void WINAPI GetNativeSystemInfo(_Out_ LPSYSTEM_INFO lpSystemInfo); ( - source.getTarget().hasName("GetVersionEx") or - source.getTarget().hasName("GetVersionExA") or - source.getTarget().hasName("GetVersionExW") or - source.getTarget().hasName("GetSystemInfo") or - source.getTarget().hasName("GetNativeSystemInfo") + source.getTarget().hasGlobalName("GetVersionEx") or + source.getTarget().hasGlobalName("GetVersionExA") or + source.getTarget().hasGlobalName("GetVersionExW") or + source.getTarget().hasGlobalName("GetSystemInfo") or + source.getTarget().hasGlobalName("GetNativeSystemInfo") ) and use = source.getArgument(0) } @@ -216,9 +216,9 @@ private predicate windowsFolderPath(FunctionCall source, Element use) { // _In_ BOOL fCreate // ); ( - source.getTarget().hasName("SHGetSpecialFolderPath") or - source.getTarget().hasName("SHGetSpecialFolderPathA") or - source.getTarget().hasName("SHGetSpecialFolderPathW") + source.getTarget().hasGlobalName("SHGetSpecialFolderPath") or + source.getTarget().hasGlobalName("SHGetSpecialFolderPathA") or + source.getTarget().hasGlobalName("SHGetSpecialFolderPathW") ) and use = source.getArgument(1) or @@ -228,7 +228,7 @@ private predicate windowsFolderPath(FunctionCall source, Element use) { // _In_opt_ HANDLE hToken, // _Out_ PWSTR *ppszPath // ); - source.getTarget().hasName("SHGetKnownFolderPath") and + source.getTarget().hasGlobalName("SHGetKnownFolderPath") and use = source.getArgument(3) or // HRESULT SHGetFolderPath( @@ -239,9 +239,9 @@ private predicate windowsFolderPath(FunctionCall source, Element use) { // _Out_ LPTSTR pszPath // ); ( - source.getTarget().hasName("SHGetFolderPath") or - source.getTarget().hasName("SHGetFolderPathA") or - source.getTarget().hasName("SHGetFolderPathW") + source.getTarget().hasGlobalName("SHGetFolderPath") or + source.getTarget().hasGlobalName("SHGetFolderPathA") or + source.getTarget().hasGlobalName("SHGetFolderPathW") ) and use = source.getArgument(4) or @@ -254,9 +254,9 @@ private predicate windowsFolderPath(FunctionCall source, Element use) { // _Out_ LPTSTR pszPath // ); ( - source.getTarget().hasName("SHGetFolderPathAndSubDir") or - source.getTarget().hasName("SHGetFolderPathAndSubDirA") or - source.getTarget().hasName("SHGetFolderPathAndSubDirW") + source.getTarget().hasGlobalName("SHGetFolderPathAndSubDir") or + source.getTarget().hasGlobalName("SHGetFolderPathAndSubDirA") or + source.getTarget().hasGlobalName("SHGetFolderPathAndSubDirW") ) and use = source.getArgument(5) } @@ -273,9 +273,9 @@ class WindowsFolderPath extends SystemData { private predicate logonUser(FunctionCall source, VariableAccess use) { ( - source.getTarget().hasName("LogonUser") or - source.getTarget().hasName("LogonUserW") or - source.getTarget().hasName("LogonUserA") + source.getTarget().hasGlobalName("LogonUser") or + source.getTarget().hasGlobalName("LogonUserW") or + source.getTarget().hasGlobalName("LogonUserA") ) and use = source.getAnArgument() } @@ -297,9 +297,9 @@ private predicate regQuery(FunctionCall source, VariableAccess use) { // _Inout_opt_ PLONG lpcbValue // ); ( - source.getTarget().hasName("RegQueryValue") or - source.getTarget().hasName("RegQueryValueA") or - source.getTarget().hasName("RegQueryValueW") + source.getTarget().hasGlobalName("RegQueryValue") or + source.getTarget().hasGlobalName("RegQueryValueA") or + source.getTarget().hasGlobalName("RegQueryValueW") ) and use = source.getArgument(2) or @@ -311,9 +311,9 @@ private predicate regQuery(FunctionCall source, VariableAccess use) { // _Inout_opt_ LPDWORD ldwTotsize // ); ( - source.getTarget().hasName("RegQueryMultipleValues") or - source.getTarget().hasName("RegQueryMultipleValuesA") or - source.getTarget().hasName("RegQueryMultipleValuesW") + source.getTarget().hasGlobalName("RegQueryMultipleValues") or + source.getTarget().hasGlobalName("RegQueryMultipleValuesA") or + source.getTarget().hasGlobalName("RegQueryMultipleValuesW") ) and use = source.getArgument(3) or @@ -326,9 +326,9 @@ private predicate regQuery(FunctionCall source, VariableAccess use) { // _Inout_opt_ LPDWORD lpcbData // ); ( - source.getTarget().hasName("RegQueryValueEx") or - source.getTarget().hasName("RegQueryValueExA") or - source.getTarget().hasName("RegQueryValueExW") + source.getTarget().hasGlobalName("RegQueryValueEx") or + source.getTarget().hasGlobalName("RegQueryValueExA") or + source.getTarget().hasGlobalName("RegQueryValueExW") ) and use = source.getArgument(4) or @@ -342,9 +342,9 @@ private predicate regQuery(FunctionCall source, VariableAccess use) { // _Inout_opt_ LPDWORD pcbData // ); ( - source.getTarget().hasName("RegGetValue") or - source.getTarget().hasName("RegGetValueA") or - source.getTarget().hasName("RegGetValueW") + source.getTarget().hasGlobalName("RegGetValue") or + source.getTarget().hasGlobalName("RegGetValueA") or + source.getTarget().hasGlobalName("RegGetValueW") ) and use = source.getArgument(5) } diff --git a/cpp/ql/src/Security/CWE/CWE-676/DangerousFunctionOverflow.ql b/cpp/ql/src/Security/CWE/CWE-676/DangerousFunctionOverflow.ql index 84d7b48e265..fe9b56bd521 100644 --- a/cpp/ql/src/Security/CWE/CWE-676/DangerousFunctionOverflow.ql +++ b/cpp/ql/src/Security/CWE/CWE-676/DangerousFunctionOverflow.ql @@ -15,5 +15,5 @@ import cpp from FunctionCall call, Function target where call.getTarget() = target and - target.hasGlobalName("gets") + target.hasGlobalOrStdName("gets") select call, "gets does not guard against buffer overflow" diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql index 4b1f45185d1..f2512b93003 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 79.ql @@ -22,7 +22,7 @@ predicate acquireExpr(Expr acquire, string kind) { exists(FunctionCall fc, Function f, string name | fc = acquire and f = fc.getTarget() and - f.hasGlobalName(name) and + f.hasGlobalOrStdName(name) and ( name = "fopen" and kind = "file" @@ -46,7 +46,7 @@ predicate releaseExpr(Expr release, Expr resource, string kind) { exists(FunctionCall fc, Function f, string name | fc = release and f = fc.getTarget() and - f.hasGlobalName(name) and + f.hasGlobalOrStdName(name) and ( name = "fclose" and resource = fc.getArgument(0) and diff --git a/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.ql b/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.ql index 501101f706c..872a7443e6e 100644 --- a/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.ql +++ b/cpp/ql/src/jsf/4.10 Classes/AV Rule 97.ql @@ -22,8 +22,8 @@ predicate containsArray(Type t) { or containsArray(t.getUnderlyingType()) and not exists(TypedefType allowed | allowed = t | - allowed.hasGlobalName("jmp_buf") or - allowed.hasGlobalName("va_list") + allowed.hasGlobalOrStdName("jmp_buf") or + allowed.hasGlobalOrStdName("va_list") ) } diff --git a/cpp/ql/src/semmle/code/cpp/Class.qll b/cpp/ql/src/semmle/code/cpp/Class.qll index 5ac4f52392e..297654a1afa 100644 --- a/cpp/ql/src/semmle/code/cpp/Class.qll +++ b/cpp/ql/src/semmle/code/cpp/Class.qll @@ -605,15 +605,6 @@ class Class extends UserType { class_instantiation(underlyingElement(this), unresolveElement(c)) } - /** - * Gets the `i`th template argument used to instantiate this class from a - * class template. When called on a class template, this will return the - * `i`th template parameter. - */ - override Type getTemplateArgument(int i) { - class_template_argument(underlyingElement(this), i, unresolveElement(result)) - } - /** * Holds if this class/struct is polymorphic (has a virtual function, or * inherits one). @@ -623,7 +614,7 @@ class Class extends UserType { } override predicate involvesTemplateParameter() { - getATemplateArgument().involvesTemplateParameter() + getATemplateArgument().(Type).involvesTemplateParameter() } /** Holds if this class, struct or union was declared 'final'. */ diff --git a/cpp/ql/src/semmle/code/cpp/Declaration.qll b/cpp/ql/src/semmle/code/cpp/Declaration.qll index 5d13bf4883a..f2f31a51d29 100644 --- a/cpp/ql/src/semmle/code/cpp/Declaration.qll +++ b/cpp/ql/src/semmle/code/cpp/Declaration.qll @@ -123,6 +123,13 @@ abstract class Declaration extends Locatable, @declaration { /** Holds if this declaration has the given name in the global namespace. */ predicate hasGlobalName(string name) { this.hasQualifiedName("", "", name) } + /** Holds if this declaration has the given name in the global namespace or the `std` namespace. */ + predicate hasGlobalOrStdName(string name) { + this.hasGlobalName(name) + or + this.hasQualifiedName("std", "", name) + } + /** Gets a specifier of this declaration. */ abstract Specifier getASpecifier(); @@ -193,20 +200,83 @@ abstract class Declaration extends Locatable, @declaration { /** * Gets a template argument used to instantiate this declaration from a template. - * When called on a template, this will return a template parameter. + * When called on a template, this will return a template parameter type for + * both typed and non-typed parameters. */ - final Type getATemplateArgument() { result = getTemplateArgument(_) } + final Locatable getATemplateArgument() { result = getTemplateArgument(_) } + + /** + * Gets a template argument used to instantiate this declaration from a template. + * When called on a template, this will return a non-typed template + * parameter value. + */ + final Locatable getATemplateArgumentKind() { result = getTemplateArgumentKind(_) } /** * Gets the `i`th template argument used to instantiate this declaration from a - * template. When called on a template, this will return the `i`th template parameter. + * template. + * + * For example: + * + * `template class Foo;` + * + * Will have `getTemplateArgument(0)` return `T`, and + * `getTemplateArgument(1)` return `X`. + * + * `Foo bar; + * + * Will have `getTemplateArgument())` return `int`, and + * `getTemplateArgument(1)` return `1`. */ - Type getTemplateArgument(int index) { none() } + final Locatable getTemplateArgument(int index) { + if exists(getTemplateArgumentValue(index)) + then result = getTemplateArgumentValue(index) + else result = getTemplateArgumentType(index) + } + + /** + * Gets the `i`th template argument value used to instantiate this declaration + * from a template. When called on a template, this will return the `i`th template + * parameter value if it exists. + * + * For example: + * + * `template class Foo;` + * + * Will have `getTemplateArgumentKind(1)` return `T`, and no result for + * `getTemplateArgumentKind(0)`. + * + * `Foo bar; + * + * Will have `getTemplateArgumentKind(1)` return `int`, and no result for + * `getTemplateArgumentKind(0)`. + */ + final Locatable getTemplateArgumentKind(int index) { + if exists(getTemplateArgumentValue(index)) + then result = getTemplateArgumentType(index) + else none() + } /** Gets the number of template arguments for this declaration. */ final int getNumberOfTemplateArguments() { result = count(int i | exists(getTemplateArgument(i))) } + + private Type getTemplateArgumentType(int index) { + class_template_argument(underlyingElement(this), index, unresolveElement(result)) + or + function_template_argument(underlyingElement(this), index, unresolveElement(result)) + or + variable_template_argument(underlyingElement(this), index, unresolveElement(result)) + } + + private Expr getTemplateArgumentValue(int index) { + class_template_argument_value(underlyingElement(this), index, unresolveElement(result)) + or + function_template_argument_value(underlyingElement(this), index, unresolveElement(result)) + or + variable_template_argument_value(underlyingElement(this), index, unresolveElement(result)) + } } /** diff --git a/cpp/ql/src/semmle/code/cpp/Function.qll b/cpp/ql/src/semmle/code/cpp/Function.qll index 94d11d63575..85c277f945b 100644 --- a/cpp/ql/src/semmle/code/cpp/Function.qll +++ b/cpp/ql/src/semmle/code/cpp/Function.qll @@ -343,15 +343,6 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function { function_instantiation(underlyingElement(this), unresolveElement(f)) } - /** - * Gets the `i`th template argument used to instantiate this function from a - * function template. When called on a function template, this will return the - * `i`th template parameter. - */ - override Type getTemplateArgument(int index) { - function_template_argument(underlyingElement(this), index, unresolveElement(result)) - } - /** * Holds if this function is defined in several files. This is illegal in * C (though possible in some C++ compilers), and likely indicates that @@ -434,7 +425,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function { // ... and likewise for destructors. this.(Destructor).getADestruction().mayBeGloballyImpure() else - not exists(string name | this.hasGlobalName(name) | + not exists(string name | this.hasGlobalOrStdName(name) | // Unless it's a function that we know is side-effect-free, it may // have side-effects. name = "strcmp" or diff --git a/cpp/ql/src/semmle/code/cpp/NestedFields.qll b/cpp/ql/src/semmle/code/cpp/NestedFields.qll index 12109be8ece..c4be8b8b9ff 100644 --- a/cpp/ql/src/semmle/code/cpp/NestedFields.qll +++ b/cpp/ql/src/semmle/code/cpp/NestedFields.qll @@ -1,9 +1,8 @@ import cpp /** - * Gets a `Field` that is nested within the given `Struct`. - * - * This identifies `Field`s which are located in the same memory + * Gets a `Field` that is within the given `Struct`, either directly or nested + * inside one or more levels of member structs. */ private Field getANestedField(Struct s) { result = s.getAField() @@ -15,7 +14,7 @@ private Field getANestedField(Struct s) { } /** - * Unwraps a series of field accesses to determine the inner-most qualifier. + * Unwraps a series of field accesses to determine the outer-most qualifier. */ private Expr getUltimateQualifier(FieldAccess fa) { exists(Expr qualifier | qualifier = fa.getQualifier() | diff --git a/cpp/ql/src/semmle/code/cpp/Print.qll b/cpp/ql/src/semmle/code/cpp/Print.qll index ab979d89b03..e3ad19f6028 100644 --- a/cpp/ql/src/semmle/code/cpp/Print.qll +++ b/cpp/ql/src/semmle/code/cpp/Print.qll @@ -35,6 +35,14 @@ private string getParameterTypeString(Type parameterType) { else result = parameterType.(DumpType).getTypeIdentityString() } +private string getTemplateArgumentString(Declaration d, int i) { + if exists(d.getTemplateArgumentKind(i)) + then + result = d.getTemplateArgumentKind(i).(DumpType).getTypeIdentityString() + " " + + d.getTemplateArgument(i) + else result = d.getTemplateArgument(i).(DumpType).getTypeIdentityString() +} + /** * A `Declaration` extended to add methods for generating strings useful only for dumps and debugging. */ @@ -56,7 +64,7 @@ abstract private class DumpDeclaration extends Declaration { strictconcat(int i | exists(this.getTemplateArgument(i)) | - this.getTemplateArgument(i).(DumpType).getTypeIdentityString(), ", " order by i + getTemplateArgumentString(this, i), ", " order by i ) + ">" else result = "" } diff --git a/cpp/ql/src/semmle/code/cpp/PrintAST.ql b/cpp/ql/src/semmle/code/cpp/PrintAST.ql index 6fc40dd0525..e4c53030da5 100644 --- a/cpp/ql/src/semmle/code/cpp/PrintAST.ql +++ b/cpp/ql/src/semmle/code/cpp/PrintAST.ql @@ -7,3 +7,15 @@ import cpp import PrintAST + +/** + * Temporarily tweak this class or make a copy to control which functions are + * printed. + */ +class Cfg extends PrintASTConfiguration { + /** + * TWEAK THIS PREDICATE AS NEEDED. + * Holds if the AST for `func` should be printed. + */ + override predicate shouldPrintFunction(Function func) { any() } +} diff --git a/cpp/ql/src/semmle/code/cpp/Type.qll b/cpp/ql/src/semmle/code/cpp/Type.qll index 10a1b6b1724..ea1e7fd5026 100644 --- a/cpp/ql/src/semmle/code/cpp/Type.qll +++ b/cpp/ql/src/semmle/code/cpp/Type.qll @@ -210,7 +210,7 @@ class Type extends Locatable, @type { // A function call that provides an explicit template argument that refers to T uses T. // We exclude calls within instantiations, since they do not appear directly in the source. exists(FunctionCall c | - c.getAnExplicitTemplateArgument().refersTo(this) and + c.getAnExplicitTemplateArgument().(Type).refersTo(this) and result = c and not c.getEnclosingFunction().isConstructedFrom(_) ) diff --git a/cpp/ql/src/semmle/code/cpp/Variable.qll b/cpp/ql/src/semmle/code/cpp/Variable.qll index 6fd33d9a037..194cc5333c7 100644 --- a/cpp/ql/src/semmle/code/cpp/Variable.qll +++ b/cpp/ql/src/semmle/code/cpp/Variable.qll @@ -155,15 +155,6 @@ class Variable extends Declaration, @variable { variable_instantiation(underlyingElement(this), unresolveElement(v)) } - /** - * Gets the `i`th template argument used to instantiate this variable from a - * variable template. When called on a variable template, this will return the - * `i`th template parameter. - */ - override Type getTemplateArgument(int index) { - variable_template_argument(underlyingElement(this), index, unresolveElement(result)) - } - /** * Holds if this is a compiler-generated variable. For example, a * [range-based for loop](http://en.cppreference.com/w/cpp/language/range-for) diff --git a/cpp/ql/src/semmle/code/cpp/commons/Alloc.qll b/cpp/ql/src/semmle/code/cpp/commons/Alloc.qll index e90aea37781..8462cb13b1d 100644 --- a/cpp/ql/src/semmle/code/cpp/commons/Alloc.qll +++ b/cpp/ql/src/semmle/code/cpp/commons/Alloc.qll @@ -5,13 +5,17 @@ import cpp */ predicate allocationFunction(Function f) { exists(string name | - f.hasGlobalName(name) and + f.hasGlobalOrStdName(name) and ( name = "malloc" or name = "calloc" or name = "realloc" or name = "strdup" or - name = "wcsdup" or + name = "wcsdup" + ) + or + f.hasGlobalName(name) and + ( name = "_strdup" or name = "_wcsdup" or name = "_mbsdup" or @@ -59,7 +63,7 @@ predicate allocationCall(FunctionCall fc) { allocationFunction(fc.getTarget()) and ( // realloc(ptr, 0) only frees the pointer - fc.getTarget().hasGlobalName("realloc") implies not fc.getArgument(1).getValue() = "0" + fc.getTarget().hasGlobalOrStdName("realloc") implies not fc.getArgument(1).getValue() = "0" ) } @@ -73,7 +77,10 @@ predicate freeFunction(Function f, int argNum) { name = "free" and argNum = 0 or name = "realloc" and argNum = 0 - or + ) + or + f.hasGlobalOrStdName(name) and + ( name = "ExFreePoolWithTag" and argNum = 0 or name = "ExFreeToLookasideListEx" and argNum = 1 diff --git a/cpp/ql/src/semmle/code/cpp/commons/Environment.qll b/cpp/ql/src/semmle/code/cpp/commons/Environment.qll index e36244f4d5c..f3f1759dd5c 100644 --- a/cpp/ql/src/semmle/code/cpp/commons/Environment.qll +++ b/cpp/ql/src/semmle/code/cpp/commons/Environment.qll @@ -28,7 +28,7 @@ class EnvironmentRead extends Expr { private predicate readsEnvironment(Expr read, string sourceDescription) { exists(FunctionCall call, string name | read = call and - call.getTarget().hasGlobalName(name) and + call.getTarget().hasGlobalOrStdName(name) and (name = "getenv" or name = "secure_getenv" or name = "_wgetenv") and sourceDescription = name ) diff --git a/cpp/ql/src/semmle/code/cpp/commons/File.qll b/cpp/ql/src/semmle/code/cpp/commons/File.qll index 192918d25b3..5808d704e38 100644 --- a/cpp/ql/src/semmle/code/cpp/commons/File.qll +++ b/cpp/ql/src/semmle/code/cpp/commons/File.qll @@ -5,7 +5,7 @@ import cpp */ predicate fopenCall(FunctionCall fc) { exists(Function f | f = fc.getTarget() | - f.hasGlobalName("fopen") or + f.hasGlobalOrStdName("fopen") or f.hasGlobalName("open") or f.hasGlobalName("_open") or f.hasGlobalName("_wopen") or @@ -23,7 +23,7 @@ predicate fopenCall(FunctionCall fc) { */ predicate fcloseCall(FunctionCall fc, Expr closed) { exists(Function f | f = fc.getTarget() | - f.hasGlobalName("fclose") and + f.hasGlobalOrStdName("fclose") and closed = fc.getArgument(0) or f.hasGlobalName("close") and @@ -32,7 +32,7 @@ predicate fcloseCall(FunctionCall fc, Expr closed) { f.hasGlobalName("_close") and closed = fc.getArgument(0) or - f.hasGlobalName("CloseHandle") and + f.hasGlobalOrStdName("CloseHandle") and closed = fc.getArgument(0) ) } diff --git a/cpp/ql/src/semmle/code/cpp/commons/Printf.qll b/cpp/ql/src/semmle/code/cpp/commons/Printf.qll index bd179fe27cc..5bb60564c1b 100644 --- a/cpp/ql/src/semmle/code/cpp/commons/Printf.qll +++ b/cpp/ql/src/semmle/code/cpp/commons/Printf.qll @@ -8,25 +8,32 @@ import semmle.code.cpp.commons.StringAnalysis import semmle.code.cpp.models.interfaces.FormattingFunction import semmle.code.cpp.models.implementations.Printf +class PrintfFormatAttribute extends FormatAttribute { + PrintfFormatAttribute() { + getArchetype() = "printf" or + getArchetype() = "__printf__" + } +} + /** * A function that can be identified as a `printf` style formatting * function by its use of the GNU `format` attribute. */ class AttributeFormattingFunction extends FormattingFunction { - FormatAttribute printf_attrib; - override string getCanonicalQLClass() { result = "AttributeFormattingFunction" } AttributeFormattingFunction() { - printf_attrib = getAnAttribute() and - ( - printf_attrib.getArchetype() = "printf" or - printf_attrib.getArchetype() = "__printf__" - ) and - exists(printf_attrib.getFirstFormatArgIndex()) // exclude `vprintf` style format functions + exists(PrintfFormatAttribute printf_attrib | + printf_attrib = getAnAttribute() and + exists(printf_attrib.getFirstFormatArgIndex()) // exclude `vprintf` style format functions + ) } - override int getFormatParameterIndex() { result = printf_attrib.getFormatIndex() } + override int getFormatParameterIndex() { + forex(PrintfFormatAttribute printf_attrib | printf_attrib = getAnAttribute() | + result = printf_attrib.getFormatIndex() + ) + } } /** @@ -124,15 +131,17 @@ class FormattingFunctionCall extends Expr { } /** - * Gets the argument corresponding to the nth conversion specifier + * Gets the argument corresponding to the nth conversion specifier. */ Expr getConversionArgument(int n) { - exists(FormatLiteral fl, int b, int o | + exists(FormatLiteral fl | fl = this.getFormat() and - b = sum(int i, int toSum | i < n and toSum = fl.getNumArgNeeded(i) | toSum) and - o = fl.getNumArgNeeded(n) and - o > 0 and - result = this.getFormatArgument(b + o - 1) + ( + result = this.getFormatArgument(fl.getParameterFieldValue(n)) + or + result = this.getFormatArgument(fl.getFormatArgumentIndexFor(n, 2)) and + not exists(fl.getParameterFieldValue(n)) + ) ) } @@ -142,11 +151,14 @@ class FormattingFunctionCall extends Expr { * an explicit minimum field width). */ Expr getMinFieldWidthArgument(int n) { - exists(FormatLiteral fl, int b | + exists(FormatLiteral fl | fl = this.getFormat() and - b = sum(int i, int toSum | i < n and toSum = fl.getNumArgNeeded(i) | toSum) and - fl.hasImplicitMinFieldWidth(n) and - result = this.getFormatArgument(b) + ( + result = this.getFormatArgument(fl.getMinFieldWidthParameterFieldValue(n)) + or + result = this.getFormatArgument(fl.getFormatArgumentIndexFor(n, 0)) and + not exists(fl.getMinFieldWidthParameterFieldValue(n)) + ) ) } @@ -156,12 +168,14 @@ class FormattingFunctionCall extends Expr { * precision). */ Expr getPrecisionArgument(int n) { - exists(FormatLiteral fl, int b, int o | + exists(FormatLiteral fl | fl = this.getFormat() and - b = sum(int i, int toSum | i < n and toSum = fl.getNumArgNeeded(i) | toSum) and - (if fl.hasImplicitMinFieldWidth(n) then o = 1 else o = 0) and - fl.hasImplicitPrecision(n) and - result = this.getFormatArgument(b + o) + ( + result = this.getFormatArgument(fl.getPrecisionParameterFieldValue(n)) + or + result = this.getFormatArgument(fl.getFormatArgumentIndexFor(n, 1)) and + not exists(fl.getPrecisionParameterFieldValue(n)) + ) ) } @@ -361,6 +375,14 @@ class FormatLiteral extends Literal { */ string getParameterField(int n) { this.parseConvSpec(n, _, result, _, _, _, _, _) } + /** + * Gets the parameter field of the nth conversion specifier (if it has one) as a + * zero-based number. + */ + int getParameterFieldValue(int n) { + result = this.getParameterField(n).regexpCapture("([0-9]*)\\$", 1).toInt() - 1 + } + /** * Gets the flags of the nth conversion specifier. */ @@ -430,6 +452,14 @@ class FormatLiteral extends Literal { */ int getMinFieldWidth(int n) { result = this.getMinFieldWidthOpt(n).toInt() } + /** + * Gets the zero-based parameter number of the minimum field width of the nth + * conversion specifier, if it is implicit and uses a parameter field (such as `*1$`). + */ + int getMinFieldWidthParameterFieldValue(int n) { + result = this.getMinFieldWidthOpt(n).regexpCapture("\\*([0-9]*)\\$", 1).toInt() - 1 + } + /** * Gets the precision of the nth conversion specifier (empty string if none is given). */ @@ -460,6 +490,14 @@ class FormatLiteral extends Literal { else result = this.getPrecisionOpt(n).regexpCapture("\\.([0-9]*)", 1).toInt() } + /** + * Gets the zero-based parameter number of the precision of the nth conversion + * specifier, if it is implicit and uses a parameter field (such as `*1$`). + */ + int getPrecisionParameterFieldValue(int n) { + result = this.getPrecisionOpt(n).regexpCapture("\\.\\*([0-9]*)\\$", 1).toInt() - 1 + } + /** * Gets the length flag of the nth conversion specifier. */ @@ -777,19 +815,49 @@ class FormatLiteral extends Literal { ) } + /** + * Holds if the nth conversion specifier of this format string (if `mode = 2`), it's + * minimum field width (if `mode = 0`) or it's precision (if `mode = 1`) requires a + * format argument. + * + * Most conversion specifiers require a format argument, whereas minimum field width + * and precision only require a format argument if they are present and a `*` was + * used for it's value in the format string. + */ + private predicate hasFormatArgumentIndexFor(int n, int mode) { + mode = 0 and + this.hasImplicitMinFieldWidth(n) + or + mode = 1 and + this.hasImplicitPrecision(n) + or + mode = 2 and + exists(this.getConvSpecOffset(n)) and + not this.getConversionChar(n) = "m" + } + + /** + * Gets the computed format argument index for the nth conversion specifier of this + * format string (if `mode = 2`), it's minimum field width (if `mode = 0`) or it's + * precision (if `mode = 1`). Has no result if that element is not present. Does + * not account for positional arguments (`$`). + */ + int getFormatArgumentIndexFor(int n, int mode) { + hasFormatArgumentIndexFor(n, mode) and + (3 * n) + mode = rank[result + 1](int n2, int mode2 | + hasFormatArgumentIndexFor(n2, mode2) + | + (3 * n2) + mode2 + ) + } + /** * Gets the number of arguments required by the nth conversion specifier * of this format string. */ int getNumArgNeeded(int n) { exists(this.getConvSpecOffset(n)) and - not this.getConversionChar(n) = "%" and - exists(int n1, int n2, int n3 | - (if this.hasImplicitMinFieldWidth(n) then n1 = 1 else n1 = 0) and - (if this.hasImplicitPrecision(n) then n2 = 1 else n2 = 0) and - (if this.getConversionChar(n) = "m" then n3 = 0 else n3 = 1) and - result = n1 + n2 + n3 - ) + result = count(int mode | hasFormatArgumentIndexFor(n, mode)) } /** @@ -801,7 +869,7 @@ class FormatLiteral extends Literal { // At least one conversion specifier has a parameter field, in which case, // they all should have. result = max(string s | this.getParameterField(_) = s + "$" | s.toInt()) - else result = sum(int n, int toSum | toSum = this.getNumArgNeeded(n) | toSum) + else result = count(int n, int mode | hasFormatArgumentIndexFor(n, mode)) } /** diff --git a/cpp/ql/src/semmle/code/cpp/commons/StringAnalysis.qll b/cpp/ql/src/semmle/code/cpp/commons/StringAnalysis.qll index e10e52df07d..772bb42e319 100644 --- a/cpp/ql/src/semmle/code/cpp/commons/StringAnalysis.qll +++ b/cpp/ql/src/semmle/code/cpp/commons/StringAnalysis.qll @@ -53,8 +53,8 @@ class AnalysedString extends Expr { */ class StrlenCall extends FunctionCall { StrlenCall() { - this.getTarget().hasGlobalName("strlen") or - this.getTarget().hasGlobalName("wcslen") or + this.getTarget().hasGlobalOrStdName("strlen") or + this.getTarget().hasGlobalOrStdName("wcslen") or this.getTarget().hasGlobalName("_mbslen") or this.getTarget().hasGlobalName("_mbslen_l") or this.getTarget().hasGlobalName("_mbstrlen") or diff --git a/cpp/ql/src/semmle/code/cpp/controlflow/Dereferenced.qll b/cpp/ql/src/semmle/code/cpp/controlflow/Dereferenced.qll index cfd3efa91f3..69c5963af30 100644 --- a/cpp/ql/src/semmle/code/cpp/controlflow/Dereferenced.qll +++ b/cpp/ql/src/semmle/code/cpp/controlflow/Dereferenced.qll @@ -6,7 +6,7 @@ import Nullness */ predicate callDereferences(FunctionCall fc, int i) { exists(string name | - fc.getTarget().hasGlobalName(name) and + fc.getTarget().hasGlobalOrStdName(name) and ( name = "bcopy" and i in [0 .. 1] or diff --git a/cpp/ql/src/semmle/code/cpp/controlflow/Nullness.qll b/cpp/ql/src/semmle/code/cpp/controlflow/Nullness.qll index 54b14aadd9d..caaa5b54e8c 100644 --- a/cpp/ql/src/semmle/code/cpp/controlflow/Nullness.qll +++ b/cpp/ql/src/semmle/code/cpp/controlflow/Nullness.qll @@ -264,9 +264,9 @@ predicate callMayReturnNull(Call call) { * Holds if `f` may, directly or indirectly, return a null literal. */ predicate mayReturnNull(Function f) { - f.hasGlobalName("malloc") + f.hasGlobalOrStdName("malloc") or - f.hasGlobalName("calloc") + f.hasGlobalOrStdName("calloc") or // f.hasGlobalName("strchr") // or diff --git a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll index 0caa2ab05df..fc0b5a90882 100644 --- a/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll @@ -5,6 +5,8 @@ private import cpp private import semmle.code.cpp.dataflow.internal.FlowVar private import semmle.code.cpp.models.interfaces.DataFlow +private import semmle.code.cpp.controlflow.Guards +private import semmle.code.cpp.valuenumbering.GlobalValueNumbering cached private newtype TNode = @@ -680,12 +682,16 @@ VariableAccess getAnAccessToAssignedVariable(Expr assign) { * * It is important that all extending classes in scope are disjoint. */ -class BarrierGuard extends Expr { - /** NOT YET SUPPORTED. Holds if this guard validates `e` upon evaluating to `branch`. */ - abstract deprecated predicate checks(Expr e, boolean branch); +class BarrierGuard extends GuardCondition { + /** Override this predicate to hold if this guard validates `e` upon evaluating to `b`. */ + abstract predicate checks(Expr e, boolean b); /** Gets a node guarded by this guard. */ - final Node getAGuardedNode() { - none() // stub + final ExprNode getAGuardedNode() { + exists(GVN value, boolean branch | + result.getExpr() = value.getAnExpr() and + this.checks(value.getAnExpr(), branch) and + this.controls(result.getExpr().getBasicBlock(), branch) + ) } } diff --git a/cpp/ql/src/semmle/code/cpp/dispatch/VirtualDispatch.qll b/cpp/ql/src/semmle/code/cpp/dispatch/VirtualDispatchPrototype.qll similarity index 77% rename from cpp/ql/src/semmle/code/cpp/dispatch/VirtualDispatch.qll rename to cpp/ql/src/semmle/code/cpp/dispatch/VirtualDispatchPrototype.qll index 2fa9322843e..9992f88867b 100644 --- a/cpp/ql/src/semmle/code/cpp/dispatch/VirtualDispatch.qll +++ b/cpp/ql/src/semmle/code/cpp/dispatch/VirtualDispatchPrototype.qll @@ -28,6 +28,19 @@ module VirtualDispatch { not result.hasName("IUnknown") } + /** + * Helper predicate for `getAViableTarget`, which computes the viable targets for + * virtual calls based on the qualifier type. + */ + private Function getAViableVirtualCallTarget(Class qualifierType, MemberFunction staticTarget) { + exists(Class qualifierSubType | + result = getAPossibleImplementation(staticTarget) and + qualifierType = qualifierSubType.getABaseClass*() and + mayInherit(qualifierSubType, result) and + not cannotInherit(qualifierSubType, result) + ) + } + /** * Gets a viable target for the given function call. * @@ -42,18 +55,9 @@ module VirtualDispatch { * If `c` is not a virtual call, the result will be `c.getTarget()`. */ Function getAViableTarget(Call c) { - exists(Function staticTarget | staticTarget = c.getTarget() | - if c.(FunctionCall).isVirtual() and staticTarget instanceof MemberFunction - then - exists(Class qualifierType, Class qualifierSubType | - result = getAPossibleImplementation(staticTarget) and - qualifierType = getCallQualifierType(c) and - qualifierType = qualifierSubType.getABaseClass*() and - mayInherit(qualifierSubType, result) and - not cannotInherit(qualifierSubType, result) - ) - else result = staticTarget - ) + if c.(FunctionCall).isVirtual() and c.getTarget() instanceof MemberFunction + then result = getAViableVirtualCallTarget(getCallQualifierType(c), c.getTarget()) + else result = c.getTarget() } /** Holds if `f` is declared in `c` or a transitive base class of `c`. */ @@ -63,7 +67,7 @@ module VirtualDispatch { /** * Holds if `c` cannot inherit the member function `f`, - * i.e. `c` or one of its supertypes overrides `f`. + * that is, `c` or one of its supertypes overrides `f`. */ private predicate cannotInherit(Class c, MemberFunction f) { exists(Class overridingType, MemberFunction override | diff --git a/cpp/ql/src/semmle/code/cpp/exprs/Call.qll b/cpp/ql/src/semmle/code/cpp/exprs/Call.qll index 882918316f6..22a25969a8f 100644 --- a/cpp/ql/src/semmle/code/cpp/exprs/Call.qll +++ b/cpp/ql/src/semmle/code/cpp/exprs/Call.qll @@ -139,17 +139,29 @@ class FunctionCall extends Call, @funbindexpr { override string getCanonicalQLClass() { result = "FunctionCall" } /** Gets an explicit template argument for this call. */ - Type getAnExplicitTemplateArgument() { result = getExplicitTemplateArgument(_) } + Locatable getAnExplicitTemplateArgument() { result = getExplicitTemplateArgument(_) } + + /** Gets an explicit template argument value for this call. */ + Locatable getAnExplicitTemplateArgumentKind() { result = getExplicitTemplateArgumentKind(_) } /** Gets a template argument for this call. */ - Type getATemplateArgument() { result = getTarget().getATemplateArgument() } + Locatable getATemplateArgument() { result = getTarget().getATemplateArgument() } + + /** Gets a template argument value for this call. */ + Locatable getATemplateArgumentKind() { result = getTarget().getATemplateArgumentKind() } /** Gets the nth explicit template argument for this call. */ - Type getExplicitTemplateArgument(int n) { + Locatable getExplicitTemplateArgument(int n) { n < getNumberOfExplicitTemplateArguments() and result = getTemplateArgument(n) } + /** Gets the nth explicit template argument value for this call. */ + Locatable getExplicitTemplateArgumentKind(int n) { + n < getNumberOfExplicitTemplateArguments() and + result = getTemplateArgumentKind(n) + } + /** Gets the number of explicit template arguments for this call. */ int getNumberOfExplicitTemplateArguments() { if numtemplatearguments(underlyingElement(this), _) @@ -161,7 +173,10 @@ class FunctionCall extends Call, @funbindexpr { int getNumberOfTemplateArguments() { result = count(int i | exists(getTemplateArgument(i))) } /** Gets the nth template argument for this call (indexed from 0). */ - Type getTemplateArgument(int n) { result = getTarget().getTemplateArgument(n) } + Locatable getTemplateArgument(int n) { result = getTarget().getTemplateArgument(n) } + + /** Gets the nth template argument value for this call (indexed from 0). */ + Locatable getTemplateArgumentKind(int n) { result = getTarget().getTemplateArgumentKind(n) } /** Holds if any template arguments for this call are implicit / deduced. */ predicate hasImplicitTemplateArguments() { diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll index 08556a4af39..e0135e0ad2f 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll @@ -2,6 +2,7 @@ import cpp import semmle.code.cpp.security.Security private import semmle.code.cpp.ir.dataflow.DataFlow private import semmle.code.cpp.ir.IR +private import semmle.code.cpp.ir.dataflow.internal.DataFlowDispatch as Dispatch /** * A predictable instruction is one where an external user can predict @@ -37,7 +38,7 @@ private class DefaultTaintTrackingCfg extends DataFlow::Configuration { } private predicate accessesVariable(CopyInstruction copy, Variable var) { - exists(VariableAddressInstruction va | va.getVariable().getAST() = var | + exists(VariableAddressInstruction va | va.getASTVariable() = var | copy.(StoreInstruction).getDestinationAddress() = va or copy.(LoadInstruction).getSourceAddress() = va @@ -145,7 +146,8 @@ GlobalOrNamespaceVariable globalVarFromId(string id) { } Function resolveCall(Call call) { - // TODO: improve virtual dispatch. This will help in the test for - // `UncontrolledProcessOperation.ql`. - result = call.getTarget() + exists(CallInstruction callInstruction | + callInstruction.getAST() = call and + result = Dispatch::viableCallable(callInstruction) + ) } diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll index d0325a28d3e..9572639de59 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll @@ -1,5 +1,6 @@ private import cpp private import semmle.code.cpp.ir.IR +private import semmle.code.cpp.ir.dataflow.DataFlow Function viableImpl(CallInstruction call) { result = viableCallable(call) } @@ -20,6 +21,58 @@ Function viableCallable(CallInstruction call) { functionSignatureWithBody(qualifiedName, nparams, result) and strictcount(Function other | functionSignatureWithBody(qualifiedName, nparams, other)) = 1 ) + or + // Rudimentary virtual dispatch support. It's essentially local data flow + // where the source is a derived-to-base conversion and the target is the + // qualifier of a call. + exists(Class derived, DataFlow::Node thisArgument | + nodeMayHaveClass(derived, thisArgument) and + overrideMayAffectCall(derived, thisArgument, _, result, call) + ) +} + +/** + * Holds if `call` is a virtual function call with qualifier `thisArgument` in + * `enclosingFunction`, whose static target is overridden by + * `overridingFunction` in `overridingClass`. + */ +pragma[noinline] +private predicate overrideMayAffectCall( + Class overridingClass, DataFlow::Node thisArgument, Function enclosingFunction, + MemberFunction overridingFunction, CallInstruction call +) { + call.getEnclosingFunction() = enclosingFunction and + overridingFunction.getAnOverriddenFunction+() = call.getStaticCallTarget() and + overridingFunction.getDeclaringType() = overridingClass and + thisArgument = DataFlow::instructionNode(call.getThisArgument()) +} + +/** + * Holds if `node` may have dynamic class `derived`, where `derived` is a class + * that may affect virtual dispatch within the enclosing function. + * + * For the sake of performance, this recursion is written out manually to make + * it a relation on `Class x Node` rather than `Node x Node` or `MemberFunction + * x Node`, both of which would be larger. It's a forward search since there + * should usually be fewer classes than calls. + * + * If a value is cast several classes up in the hierarchy, that will be modeled + * as a chain of `ConvertToBaseInstruction`s and will cause the search to start + * from each of them and pass through subsequent ones. There might be + * performance to gain by stopping before a second upcast and reconstructing + * the full chain in a "big-step" recursion after this one. + */ +private predicate nodeMayHaveClass(Class derived, DataFlow::Node node) { + exists(ConvertToBaseInstruction toBase | + derived = toBase.getDerivedClass() and + overrideMayAffectCall(derived, _, toBase.getEnclosingFunction(), _, _) and + node.asInstruction() = toBase + ) + or + exists(DataFlow::Node prev | + nodeMayHaveClass(derived, prev) and + DataFlow::localFlowStep(prev, node) + ) } /** diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index 0476ea3c30a..4e84424fcb7 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -5,6 +5,7 @@ private import cpp private import semmle.code.cpp.ir.IR private import semmle.code.cpp.controlflow.IRGuards +private import semmle.code.cpp.ir.ValueNumbering /** * A newtype wrapper to prevent accidental casts between `Node` and @@ -204,7 +205,8 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction iTo.(CopyInstruction).getSourceValue() = iFrom or iTo.(PhiInstruction).getAnOperand().getDef() = iFrom or // Treat all conversions as flow, even conversions between different numeric types. - iTo.(ConvertInstruction).getUnary() = iFrom + iTo.(ConvertInstruction).getUnary() = iFrom or + iTo.(InheritanceConversionInstruction).getUnary() = iFrom } /** @@ -213,6 +215,14 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction */ predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) } +/** + * Holds if data can flow from `i1` to `i2` in zero or more + * local (intra-procedural) steps. + */ +predicate localInstructionFlow(Instruction e1, Instruction e2) { + localFlow(instructionNode(e1), instructionNode(e2)) +} + /** * Holds if data can flow from `e1` to `e2` in zero or more * local (intra-procedural) steps. @@ -220,7 +230,7 @@ predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) } predicate localExprFlow(Expr e1, Expr e2) { localFlow(exprNode(e1), exprNode(e2)) } /** - * A guard that validates some expression. + * A guard that validates some instruction. * * To use this in a configuration, extend the class and provide a * characteristic predicate precisely specifying the guard, and override @@ -229,11 +239,15 @@ predicate localExprFlow(Expr e1, Expr e2) { localFlow(exprNode(e1), exprNode(e2) * It is important that all extending classes in scope are disjoint. */ class BarrierGuard extends IRGuardCondition { - /** NOT YET SUPPORTED. Holds if this guard validates `e` upon evaluating to `b`. */ - abstract deprecated predicate checks(Instruction e, boolean b); + /** Override this predicate to hold if this guard validates `instr` upon evaluating to `b`. */ + abstract predicate checks(Instruction instr, boolean b); /** Gets a node guarded by this guard. */ final Node getAGuardedNode() { - none() // stub + exists(ValueNumber value, boolean edge | + result.asInstruction() = value.getAnInstruction() and + this.checks(value.getAnInstruction(), edge) and + this.controls(result.asInstruction().getBlock(), edge) + ) } } diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll index e34709e94ec..8d7c9194f4f 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll @@ -53,6 +53,14 @@ private predicate localInstructionTaintStep(Instruction nodeFrom, Instruction no */ predicate localTaint(DataFlow::Node source, DataFlow::Node sink) { localTaintStep*(source, sink) } +/** + * Holds if taint can flow from `i1` to `i2` in zero or more + * local (intra-procedural) steps. + */ +predicate localInstructionTaint(Instruction i1, Instruction i2) { + localTaint(DataFlow::instructionNode(i1), DataFlow::instructionNode(i2)) +} + /** * Holds if taint can flow from `e1` to `e2` in zero or more * local (intra-procedural) steps. diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/IRType.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/IRType.qll index 0abfa14023d..73cdbd20989 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/IRType.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/IRType.qll @@ -4,6 +4,7 @@ private import internal.IRTypeInternal +cached private newtype TIRType = TIRVoidType() or TIRUnknownType() or @@ -42,6 +43,10 @@ class IRType extends TIRType { * * This will hold for all `IRType` objects except `IRUnknownType`. */ + // This predicate is overridden with `pragma[noinline]` in every leaf subclass. + // This allows callers to ask for things like _the_ floating-point type of + // size 4 without getting a join that first finds all types of size 4 and + // _then_ restricts them to floating-point types. int getByteSize() { none() } /** @@ -104,8 +109,6 @@ private class IRSizedType extends IRType { this = TIRFunctionAddressType(byteSize) or this = TIROpaqueType(_, byteSize) } - - final override int getByteSize() { result = byteSize } } /** @@ -117,6 +120,9 @@ class IRBooleanType extends IRSizedType, TIRBooleanType { final override Language::LanguageType getCanonicalLanguageType() { result = Language::getCanonicalBooleanType(byteSize) } + + pragma[noinline] + final override int getByteSize() { result = byteSize } } /** @@ -141,6 +147,9 @@ class IRSignedIntegerType extends IRNumericType, TIRSignedIntegerType { final override Language::LanguageType getCanonicalLanguageType() { result = Language::getCanonicalSignedIntegerType(byteSize) } + + pragma[noinline] + final override int getByteSize() { result = byteSize } } /** @@ -153,6 +162,9 @@ class IRUnsignedIntegerType extends IRNumericType, TIRUnsignedIntegerType { final override Language::LanguageType getCanonicalLanguageType() { result = Language::getCanonicalUnsignedIntegerType(byteSize) } + + pragma[noinline] + final override int getByteSize() { result = byteSize } } /** @@ -164,6 +176,9 @@ class IRFloatingPointType extends IRNumericType, TIRFloatingPointType { final override Language::LanguageType getCanonicalLanguageType() { result = Language::getCanonicalFloatingPointType(byteSize) } + + pragma[noinline] + final override int getByteSize() { result = byteSize } } /** @@ -178,6 +193,9 @@ class IRAddressType extends IRSizedType, TIRAddressType { final override Language::LanguageType getCanonicalLanguageType() { result = Language::getCanonicalAddressType(byteSize) } + + pragma[noinline] + final override int getByteSize() { result = byteSize } } /** @@ -190,6 +208,9 @@ class IRFunctionAddressType extends IRSizedType, TIRFunctionAddressType { final override Language::LanguageType getCanonicalLanguageType() { result = Language::getCanonicalFunctionAddressType(byteSize) } + + pragma[noinline] + final override int getByteSize() { result = byteSize } } /** @@ -218,6 +239,9 @@ class IROpaqueType extends IRSizedType, TIROpaqueType { * same size. */ final Language::OpaqueTypeTag getTag() { result = tag } + + pragma[noinline] + final override int getByteSize() { result = byteSize } } module IRTypeSanity { diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/MemoryAccessKind.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/MemoryAccessKind.qll index d4f1599d78e..a71608ee855 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/MemoryAccessKind.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/MemoryAccessKind.qll @@ -5,6 +5,7 @@ private newtype TMemoryAccessKind = TBufferMayMemoryAccess() or TEscapedMemoryAccess() or TEscapedMayMemoryAccess() or + TNonLocalMayMemoryAccess() or TPhiMemoryAccess() or TUnmodeledMemoryAccess() or TChiTotalMemoryAccess() or @@ -80,6 +81,14 @@ class EscapedMayMemoryAccess extends MemoryAccessKind, TEscapedMayMemoryAccess { override string toString() { result = "escaped(may)" } } +/** + * The operand or result may access all memory whose address has escaped, other than data on the + * stack frame of the current function. + */ +class NonLocalMayMemoryAccess extends MemoryAccessKind, TNonLocalMayMemoryAccess { + override string toString() { result = "nonlocal(may)" } +} + /** * The operand is a Phi operand, which accesses the same memory as its * definition. diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll index 713893f52f7..edbec38d5b9 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll @@ -36,7 +36,7 @@ private newtype TOpcode = TPointerSub() or TPointerDiff() or TConvert() or - TConvertToBase() or + TConvertToNonVirtualBase() or TConvertToVirtualBase() or TConvertToDerived() or TCheckedConvertOrNull() or @@ -59,6 +59,7 @@ private newtype TOpcode = TUnmodeledDefinition() or TUnmodeledUse() or TAliasedDefinition() or + TAliasedUse() or TPhi() or TBuiltIn() or TVarArgsStart() or @@ -111,6 +112,8 @@ abstract class RelationalOpcode extends CompareOpcode { } abstract class CopyOpcode extends Opcode { } +abstract class ConvertToBaseOpcode extends UnaryOpcode { } + abstract class MemoryAccessOpcode extends Opcode { } abstract class ReturnOpcode extends Opcode { } @@ -311,11 +314,11 @@ module Opcode { final override string toString() { result = "Convert" } } - class ConvertToBase extends UnaryOpcode, TConvertToBase { - final override string toString() { result = "ConvertToBase" } + class ConvertToNonVirtualBase extends ConvertToBaseOpcode, TConvertToNonVirtualBase { + final override string toString() { result = "ConvertToNonVirtualBase" } } - class ConvertToVirtualBase extends UnaryOpcode, TConvertToVirtualBase { + class ConvertToVirtualBase extends ConvertToBaseOpcode, TConvertToVirtualBase { final override string toString() { result = "ConvertToVirtualBase" } } @@ -403,6 +406,10 @@ module Opcode { final override string toString() { result = "AliasedDefinition" } } + class AliasedUse extends Opcode, TAliasedUse { + final override string toString() { result = "AliasedUse" } + } + class Phi extends Opcode, TPhi { final override string toString() { result = "Phi" } } diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll index 1a607f82c29..e10e266b2ab 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/IRVariable.qll @@ -22,6 +22,12 @@ abstract class IRVariable extends TIRVariable { abstract string toString(); + /** + * Holds if this variable's value cannot be changed within a function. Currently used for string + * literals, but could also apply to `const` global and static variables. + */ + predicate isReadOnly() { none() } + /** * Gets the type of the variable. */ @@ -113,34 +119,43 @@ class IRStaticUserVariable extends IRUserVariable { final override Language::StaticVariable getVariable() { result = var } } +abstract class IRGeneratedVariable extends IRVariable { + Language::AST ast; + Language::LanguageType type; + + final override Language::LanguageType getLanguageType() { result = type } + + final override Language::AST getAST() { result = ast } + + override string toString() { result = getBaseString() + getLocationString() } + + override string getUniqueId() { none() } + + final string getLocationString() { + result = ast.getLocation().getStartLine().toString() + ":" + + ast.getLocation().getStartColumn().toString() + } + + string getBaseString() { none() } +} + IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) { result.getAST() = ast and result.getTag() = tag } -class IRTempVariable extends IRVariable, IRAutomaticVariable, TIRTempVariable { - Language::AST ast; +class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable { TempVariableTag tag; - Language::LanguageType type; IRTempVariable() { this = TIRTempVariable(func, ast, tag, type) } - final override Language::LanguageType getLanguageType() { result = type } - - final override Language::AST getAST() { result = ast } - final override string getUniqueId() { result = "Temp: " + Construction::getTempVariableUniqueId(this) } final TempVariableTag getTag() { result = tag } - override string toString() { - result = getBaseString() + ast.getLocation().getStartLine().toString() + ":" + - ast.getLocation().getStartColumn().toString() - } - - string getBaseString() { result = "#temp" } + override string getBaseString() { result = "#temp" } } class IRReturnVariable extends IRTempVariable { @@ -154,3 +169,19 @@ class IRThrowVariable extends IRTempVariable { override string getBaseString() { result = "#throw" } } + +class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { + Language::StringLiteral literal; + + IRStringLiteral() { this = TIRStringLiteral(func, ast, type, literal) } + + final override predicate isReadOnly() { any() } + + final override string getUniqueId() { + result = "String: " + getLocationString() + "=" + Language::getStringLiteralText(literal) + } + + override string getBaseString() { result = "#string" } + + final Language::StringLiteral getLiteral() { result = literal } +} diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll index a2a39e4d42e..8e785015828 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll @@ -51,7 +51,8 @@ module InstructionSanity { opcode instanceof ReadSideEffectOpcode or opcode instanceof Opcode::InlineAsm or opcode instanceof Opcode::CallSideEffect or - opcode instanceof Opcode::ReturnIndirection + opcode instanceof Opcode::ReturnIndirection or + opcode instanceof Opcode::AliasedUse ) and tag instanceof SideEffectOperandTag ) @@ -124,6 +125,16 @@ module InstructionSanity { ) } + query predicate duplicateChiOperand( + ChiInstruction chi, string message, IRFunction func, string funcText + ) { + chi.getTotal() = chi.getPartial() and + message = "Chi instruction for " + chi.getPartial().toString() + + " has duplicate operands in function $@" and + func = chi.getEnclosingIRFunction() and + funcText = Language::getIdentityString(func.getFunction()) + } + query predicate sideEffectWithoutPrimary( SideEffectInstruction instr, string message, IRFunction func, string funcText ) { @@ -264,6 +275,7 @@ module InstructionSanity { ) { exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex | not useOperand.getUse() instanceof UnmodeledUseInstruction and + not defInstr instanceof UnmodeledDefinitionInstruction and pointOfEvaluation(useOperand, useBlock, useIndex) and defInstr = useOperand.getAnyDef() and ( @@ -827,14 +839,12 @@ class FloatConstantInstruction extends ConstantInstruction { FloatConstantInstruction() { getResultType() instanceof Language::FloatingPointType } } -class StringConstantInstruction extends Instruction { - Language::StringLiteral value; +class StringConstantInstruction extends VariableInstruction { + override IRStringLiteral var; - StringConstantInstruction() { value = Construction::getInstructionStringLiteral(this) } + final override string getImmediateString() { result = Language::getStringLiteralText(getValue()) } - final override string getImmediateString() { result = Language::getStringLiteralText(value) } - - final Language::StringLiteral getValue() { result = value } + final Language::StringLiteral getValue() { result = var.getLiteral() } } class BinaryInstruction extends Instruction { @@ -1002,14 +1012,22 @@ class InheritanceConversionInstruction extends UnaryInstruction { * to the address of a direct non-virtual base class. */ class ConvertToBaseInstruction extends InheritanceConversionInstruction { - ConvertToBaseInstruction() { getOpcode() instanceof Opcode::ConvertToBase } + ConvertToBaseInstruction() { getOpcode() instanceof ConvertToBaseOpcode } +} + +/** + * Represents an instruction that converts from the address of a derived class + * to the address of a direct non-virtual base class. + */ +class ConvertToNonVirtualBaseInstruction extends ConvertToBaseInstruction { + ConvertToNonVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToNonVirtualBase } } /** * Represents an instruction that converts from the address of a derived class * to the address of a virtual base class. */ -class ConvertToVirtualBaseInstruction extends InheritanceConversionInstruction { +class ConvertToVirtualBaseInstruction extends ConvertToBaseInstruction { ConvertToVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToVirtualBase } } @@ -1442,6 +1460,13 @@ class AliasedDefinitionInstruction extends Instruction { final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess } } +/** + * An instruction that consumes all escaped memory on exit from the function. + */ +class AliasedUseInstruction extends Instruction { + AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse } +} + class UnmodeledUseInstruction extends Instruction { UnmodeledUseInstruction() { getOpcode() instanceof Opcode::UnmodeledUse } diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll index c85d609d200..8042dfa6a69 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll @@ -396,6 +396,9 @@ class SideEffectOperand extends TypedOperand { override SideEffectOperandTag tag; override MemoryAccessKind getMemoryAccess() { + useInstr instanceof AliasedUseInstruction and + result instanceof NonLocalMayMemoryAccess + or useInstr instanceof CallSideEffectInstruction and result instanceof EscapedMayMemoryAccess or diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll index 74c288d3468..2768f910120 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll @@ -110,7 +110,7 @@ private predicate operandIsPropagated(Operand operand, IntValue bitOffset) { instr = operand.getUse() and ( // Converting to a non-virtual base class adds the offset of the base class. - exists(ConvertToBaseInstruction convert | + exists(ConvertToNonVirtualBaseInstruction convert | convert = instr and bitOffset = Ints::mul(convert.getDerivation().getByteOffset(), 8) ) @@ -309,6 +309,10 @@ predicate resultPointsTo(Instruction instr, IRVariable var, IntValue bitOffset) instr.(VariableAddressInstruction).getIRVariable() = var and bitOffset = 0 or + // A string literal is just a special read-only global variable. + instr.(StringConstantInstruction).getIRVariable() = var and + bitOffset = 0 + or exists(Operand operand, IntValue originalBitOffset, IntValue propagatedBitOffset | operand = instr.getAnOperand() and // If an operand is propagated, then the result points to the same variable, diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll index e53a41e3f2a..0835ffb7da6 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasedSSA.qll @@ -45,6 +45,7 @@ private newtype TMemoryLocation = languageType = type.getCanonicalLanguageType() } or TUnknownMemoryLocation(IRFunction irFunc) or + TUnknownNonLocalMemoryLocation(IRFunction irFunc) or TUnknownVirtualVariable(IRFunction irFunc) /** @@ -162,6 +163,26 @@ class UnknownMemoryLocation extends TUnknownMemoryLocation, MemoryLocation { final override string getUniqueId() { result = "{Unknown}" } } +/** + * An access to memory that is not known to be confined to a specific `IRVariable`, but is known to + * not access memory on the current function's stack frame. + */ +class UnknownNonLocalMemoryLocation extends TUnknownNonLocalMemoryLocation, MemoryLocation { + IRFunction irFunc; + + UnknownNonLocalMemoryLocation() { this = TUnknownNonLocalMemoryLocation(irFunc) } + + final override string toString() { result = "{UnknownNonLocal}" } + + final override VirtualVariable getVirtualVariable() { result = TUnknownVirtualVariable(irFunc) } + + final override Language::LanguageType getType() { + result = any(IRUnknownType type).getCanonicalLanguageType() + } + + final override string getUniqueId() { result = "{UnknownNonLocal}" } +} + /** * An access to all aliased memory. */ @@ -189,10 +210,21 @@ Overlap getOverlap(MemoryLocation def, MemoryLocation use) { def instanceof UnknownVirtualVariable and result instanceof MustTotallyOverlap or - // An UnknownMemoryLocation may partially overlap any Location within the same virtual variable. + // An UnknownMemoryLocation may partially overlap any Location within the same virtual variable, + // unless the location is read-only. def.getVirtualVariable() = use.getVirtualVariable() and def instanceof UnknownMemoryLocation and - result instanceof MayPartiallyOverlap + result instanceof MayPartiallyOverlap and + not use.(VariableMemoryLocation).getVariable().isReadOnly() + or + // An UnknownNonLocalMemoryLocation may partially overlap any location within the same virtual + // variable, except a local variable or read-only variable. + def.getVirtualVariable() = use.getVirtualVariable() and + def instanceof UnknownNonLocalMemoryLocation and + result instanceof MayPartiallyOverlap and + not exists(IRVariable var | var = use.(VariableMemoryLocation).getVariable() | + var instanceof IRAutomaticVariable or var.isReadOnly() + ) or exists(VariableMemoryLocation defVariableLocation | defVariableLocation = def and @@ -202,6 +234,13 @@ Overlap getOverlap(MemoryLocation def, MemoryLocation use) { (use instanceof UnknownMemoryLocation or use instanceof UnknownVirtualVariable) and result instanceof MayPartiallyOverlap or + // A VariableMemoryLocation that is not a local variable may partially overlap an unknown + // non-local location within the same virtual variable. + def.getVirtualVariable() = use.getVirtualVariable() and + use instanceof UnknownNonLocalMemoryLocation and + result instanceof MayPartiallyOverlap and + not defVariableLocation.getVariable() instanceof IRAutomaticVariable + or // A VariableMemoryLocation overlaps another location within the same variable based on the relationship // of the two offset intervals. exists(Overlap intervalOverlap | @@ -327,6 +366,9 @@ MemoryLocation getResultMemoryLocation(Instruction instr) { or kind instanceof EscapedMayMemoryAccess and result = TUnknownMemoryLocation(instr.getEnclosingIRFunction()) + or + kind instanceof NonLocalMayMemoryAccess and + result = TUnknownNonLocalMemoryLocation(instr.getEnclosingIRFunction()) ) ) } @@ -351,6 +393,9 @@ MemoryLocation getOperandMemoryLocation(MemoryOperand operand) { or kind instanceof EscapedMayMemoryAccess and result = TUnknownMemoryLocation(operand.getEnclosingIRFunction()) + or + kind instanceof NonLocalMayMemoryAccess and + result = TUnknownNonLocalMemoryLocation(operand.getEnclosingIRFunction()) ) ) } diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll index 7152dec5c4a..a789edc7590 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll @@ -341,11 +341,6 @@ private module Cached { result = getOldInstruction(instruction).(OldIR::ConstantValueInstruction).getValue() } - cached - Language::StringLiteral getInstructionStringLiteral(Instruction instruction) { - result = getOldInstruction(instruction).(OldIR::StringConstantInstruction).getValue() - } - cached Language::BuiltInOperation getInstructionBuiltInOperation(Instruction instruction) { result = getOldInstruction(instruction) @@ -401,7 +396,11 @@ private predicate hasChiNode(Alias::VirtualVariable vvar, OldInstruction def) { defLocation.getVirtualVariable() = vvar and // If the definition totally (or exactly) overlaps the virtual variable, then there's no need for a `Chi` // instruction. - Alias::getOverlap(defLocation, vvar) instanceof MayPartiallyOverlap + ( + Alias::getOverlap(defLocation, vvar) instanceof MayPartiallyOverlap or + def.getResultMemoryAccess() instanceof IndirectMayMemoryAccess or + def.getResultMemoryAccess() instanceof BufferMayMemoryAccess + ) ) } @@ -714,7 +713,10 @@ module DefUse { defLocation = Alias::getResultMemoryLocation(def) and block.getInstruction(index) = def and overlap = Alias::getOverlap(defLocation, useLocation) and - if overlap instanceof MayPartiallyOverlap + if + overlap instanceof MayPartiallyOverlap or + def.getResultMemoryAccess() instanceof IndirectMayMemoryAccess or + def.getResultMemoryAccess() instanceof BufferMayMemoryAccess then offset = (index * 2) + 1 // The use will be connected to the definition on the `Chi` instruction. else offset = index * 2 // The use will be connected to the definition on the original instruction. ) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/internal/TIRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/internal/TIRVariable.qll index fea67ef5ecd..01c135abf13 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/internal/TIRVariable.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/internal/TIRVariable.qll @@ -9,4 +9,10 @@ newtype TIRVariable = Language::Function func, Language::AST ast, TempVariableTag tag, Language::LanguageType type ) { Construction::hasTempVariable(func, ast, tag, type) + } or + TIRStringLiteral( + Language::Function func, Language::AST ast, Language::LanguageType type, + Language::StringLiteral literal + ) { + Construction::hasStringLiteral(func, ast, type, literal) } diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll index 1a607f82c29..e10e266b2ab 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/IRVariable.qll @@ -22,6 +22,12 @@ abstract class IRVariable extends TIRVariable { abstract string toString(); + /** + * Holds if this variable's value cannot be changed within a function. Currently used for string + * literals, but could also apply to `const` global and static variables. + */ + predicate isReadOnly() { none() } + /** * Gets the type of the variable. */ @@ -113,34 +119,43 @@ class IRStaticUserVariable extends IRUserVariable { final override Language::StaticVariable getVariable() { result = var } } +abstract class IRGeneratedVariable extends IRVariable { + Language::AST ast; + Language::LanguageType type; + + final override Language::LanguageType getLanguageType() { result = type } + + final override Language::AST getAST() { result = ast } + + override string toString() { result = getBaseString() + getLocationString() } + + override string getUniqueId() { none() } + + final string getLocationString() { + result = ast.getLocation().getStartLine().toString() + ":" + + ast.getLocation().getStartColumn().toString() + } + + string getBaseString() { none() } +} + IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) { result.getAST() = ast and result.getTag() = tag } -class IRTempVariable extends IRVariable, IRAutomaticVariable, TIRTempVariable { - Language::AST ast; +class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable { TempVariableTag tag; - Language::LanguageType type; IRTempVariable() { this = TIRTempVariable(func, ast, tag, type) } - final override Language::LanguageType getLanguageType() { result = type } - - final override Language::AST getAST() { result = ast } - final override string getUniqueId() { result = "Temp: " + Construction::getTempVariableUniqueId(this) } final TempVariableTag getTag() { result = tag } - override string toString() { - result = getBaseString() + ast.getLocation().getStartLine().toString() + ":" + - ast.getLocation().getStartColumn().toString() - } - - string getBaseString() { result = "#temp" } + override string getBaseString() { result = "#temp" } } class IRReturnVariable extends IRTempVariable { @@ -154,3 +169,19 @@ class IRThrowVariable extends IRTempVariable { override string getBaseString() { result = "#throw" } } + +class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { + Language::StringLiteral literal; + + IRStringLiteral() { this = TIRStringLiteral(func, ast, type, literal) } + + final override predicate isReadOnly() { any() } + + final override string getUniqueId() { + result = "String: " + getLocationString() + "=" + Language::getStringLiteralText(literal) + } + + override string getBaseString() { result = "#string" } + + final Language::StringLiteral getLiteral() { result = literal } +} diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll index a2a39e4d42e..8e785015828 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll @@ -51,7 +51,8 @@ module InstructionSanity { opcode instanceof ReadSideEffectOpcode or opcode instanceof Opcode::InlineAsm or opcode instanceof Opcode::CallSideEffect or - opcode instanceof Opcode::ReturnIndirection + opcode instanceof Opcode::ReturnIndirection or + opcode instanceof Opcode::AliasedUse ) and tag instanceof SideEffectOperandTag ) @@ -124,6 +125,16 @@ module InstructionSanity { ) } + query predicate duplicateChiOperand( + ChiInstruction chi, string message, IRFunction func, string funcText + ) { + chi.getTotal() = chi.getPartial() and + message = "Chi instruction for " + chi.getPartial().toString() + + " has duplicate operands in function $@" and + func = chi.getEnclosingIRFunction() and + funcText = Language::getIdentityString(func.getFunction()) + } + query predicate sideEffectWithoutPrimary( SideEffectInstruction instr, string message, IRFunction func, string funcText ) { @@ -264,6 +275,7 @@ module InstructionSanity { ) { exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex | not useOperand.getUse() instanceof UnmodeledUseInstruction and + not defInstr instanceof UnmodeledDefinitionInstruction and pointOfEvaluation(useOperand, useBlock, useIndex) and defInstr = useOperand.getAnyDef() and ( @@ -827,14 +839,12 @@ class FloatConstantInstruction extends ConstantInstruction { FloatConstantInstruction() { getResultType() instanceof Language::FloatingPointType } } -class StringConstantInstruction extends Instruction { - Language::StringLiteral value; +class StringConstantInstruction extends VariableInstruction { + override IRStringLiteral var; - StringConstantInstruction() { value = Construction::getInstructionStringLiteral(this) } + final override string getImmediateString() { result = Language::getStringLiteralText(getValue()) } - final override string getImmediateString() { result = Language::getStringLiteralText(value) } - - final Language::StringLiteral getValue() { result = value } + final Language::StringLiteral getValue() { result = var.getLiteral() } } class BinaryInstruction extends Instruction { @@ -1002,14 +1012,22 @@ class InheritanceConversionInstruction extends UnaryInstruction { * to the address of a direct non-virtual base class. */ class ConvertToBaseInstruction extends InheritanceConversionInstruction { - ConvertToBaseInstruction() { getOpcode() instanceof Opcode::ConvertToBase } + ConvertToBaseInstruction() { getOpcode() instanceof ConvertToBaseOpcode } +} + +/** + * Represents an instruction that converts from the address of a derived class + * to the address of a direct non-virtual base class. + */ +class ConvertToNonVirtualBaseInstruction extends ConvertToBaseInstruction { + ConvertToNonVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToNonVirtualBase } } /** * Represents an instruction that converts from the address of a derived class * to the address of a virtual base class. */ -class ConvertToVirtualBaseInstruction extends InheritanceConversionInstruction { +class ConvertToVirtualBaseInstruction extends ConvertToBaseInstruction { ConvertToVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToVirtualBase } } @@ -1442,6 +1460,13 @@ class AliasedDefinitionInstruction extends Instruction { final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess } } +/** + * An instruction that consumes all escaped memory on exit from the function. + */ +class AliasedUseInstruction extends Instruction { + AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse } +} + class UnmodeledUseInstruction extends Instruction { UnmodeledUseInstruction() { getOpcode() instanceof Opcode::UnmodeledUse } diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Operand.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Operand.qll index c85d609d200..8042dfa6a69 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Operand.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Operand.qll @@ -396,6 +396,9 @@ class SideEffectOperand extends TypedOperand { override SideEffectOperandTag tag; override MemoryAccessKind getMemoryAccess() { + useInstr instanceof AliasedUseInstruction and + result instanceof NonLocalMayMemoryAccess + or useInstr instanceof CallSideEffectInstruction and result instanceof EscapedMayMemoryAccess or diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll index fbf6b7e3d08..628aae26995 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll @@ -44,6 +44,13 @@ private module Cached { ) } + cached + predicate hasStringLiteral(Function func, Locatable ast, CppType type, StringLiteral literal) { + literal = ast and + literal.getEnclosingFunction() = func and + getTypeForPRValue(literal.getType()) = type + } + cached predicate hasModeledMemoryResult(Instruction instruction) { none() } @@ -51,20 +58,23 @@ private module Cached { Expr getInstructionConvertedResultExpression(Instruction instruction) { exists(TranslatedExpr translatedExpr | translatedExpr = getTranslatedExpr(result) and - instruction = translatedExpr.getResult() + instruction = translatedExpr.getResult() and + // Only associate `instruction` with this expression if the translated + // expression actually produced the instruction; not if it merely + // forwarded the result of another translated expression. + instruction = translatedExpr.getInstruction(_) ) } cached Expr getInstructionUnconvertedResultExpression(Instruction instruction) { - exists(Expr converted, TranslatedExpr translatedExpr | + exists(Expr converted | result = converted.(Conversion).getExpr+() or result = converted | not result instanceof Conversion and - translatedExpr = getTranslatedExpr(converted) and - instruction = translatedExpr.getResult() + converted = getInstructionConvertedResultExpression(instruction) ) } @@ -231,8 +241,14 @@ private module Cached { cached IRVariable getInstructionVariable(Instruction instruction) { - result = getInstructionTranslatedElement(instruction) - .getInstructionVariable(getInstructionTag(instruction)) + exists(TranslatedElement element, InstructionTag tag | + element = getInstructionTranslatedElement(instruction) and + tag = getInstructionTag(instruction) and + ( + result = element.getInstructionVariable(tag) or + result.(IRStringLiteral).getAST() = element.getInstructionStringLiteral(tag) + ) + ) } cached @@ -263,12 +279,6 @@ private module Cached { ) } - cached - StringLiteral getInstructionStringLiteral(Instruction instruction) { - result = getInstructionTranslatedElement(instruction) - .getInstructionStringLiteral(getInstructionTag(instruction)) - } - cached BuiltInOperation getInstructionBuiltInOperation(Instruction instruction) { result = getInstructionTranslatedElement(instruction) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll index 228ceec4822..0a809be2dfa 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/InstructionTag.qll @@ -28,6 +28,7 @@ newtype TInstructionTag = UnmodeledDefinitionTag() or UnmodeledUseTag() or AliasedDefinitionTag() or + AliasedUseTag() or SwitchBranchTag() or CallTargetTag() or CallTag() or @@ -46,6 +47,7 @@ newtype TInstructionTag = ConditionValueResultLoadTag() or BoolConversionConstantTag() or BoolConversionCompareTag() or + ResultCopyTag() or LoadTag() or // Implicit load due to lvalue-to-rvalue conversion CatchTag() or ThrowTag() or @@ -124,6 +126,8 @@ string getInstructionTagId(TInstructionTag tag) { or tag = AliasedDefinitionTag() and result = "AliasedDef" or + tag = AliasedUseTag() and result = "AliasedUse" + or tag = SwitchBranchTag() and result = "SwitchBranch" or tag = CallTargetTag() and result = "CallTarget" diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll index 2b1d006d48c..ae9e6f1d3bd 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll @@ -352,6 +352,11 @@ class TranslatedSideEffects extends TranslatedElement, TTranslatedSideEffects { none() } + override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) { + tag = OnlyInstructionTag() and + result = getTranslatedExpr(expr).getInstruction(CallTag()) + } + /** * Gets the `TranslatedFunction` containing this expression. */ @@ -365,6 +370,39 @@ class TranslatedSideEffects extends TranslatedElement, TTranslatedSideEffects { override Function getFunction() { result = expr.getEnclosingFunction() } } +class TranslatedStructorCallSideEffects extends TranslatedSideEffects { + TranslatedStructorCallSideEffects() { getParent().(TranslatedStructorCall).hasQualifier() } + + override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType t) { + opcode instanceof Opcode::IndirectMayWriteSideEffect and + tag instanceof OnlyInstructionTag and + t = getTypeForPRValue(expr.getTarget().getDeclaringType()) + } + + override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { + ( + if exists(getChild(0)) + then result = getChild(0).getFirstInstruction() + else result = getParent().getChildSuccessor(this) + ) and + tag = OnlyInstructionTag() and + kind instanceof GotoEdge + } + + override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) } + + override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) { + tag instanceof OnlyInstructionTag and + operandTag instanceof AddressOperandTag and + result = getParent().(TranslatedStructorCall).getQualifierResult() + } + + final override int getInstructionIndex(InstructionTag tag) { + tag = OnlyInstructionTag() and + result = -1 + } +} + class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEffect { Call call; Expr arg; @@ -447,20 +485,26 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff } override CppType getInstructionOperandType(InstructionTag tag, TypedOperandTag operandTag) { - exists(Type operandType | + if hasSpecificReadSideEffect(any(Opcode::BufferReadSideEffect op)) + then + result = getUnknownType() and tag instanceof OnlyInstructionTag and - operandType = arg.getType().getUnspecifiedType().(DerivedType).getBaseType() and operandTag instanceof SideEffectOperandTag - or - tag instanceof OnlyInstructionTag and - operandType = arg.getType().getUnspecifiedType() and - not operandType instanceof DerivedType and - operandTag instanceof SideEffectOperandTag - | - // If the type we select is an incomplete type (e.g. a forward-declared `struct`), there will - // not be a `CppType` that represents that type. In that case, fall back to `UnknownCppType`. - result = getTypeForPRValueOrUnknown(operandType) - ) + else + exists(Type operandType | + tag instanceof OnlyInstructionTag and + operandType = arg.getType().getUnspecifiedType().(DerivedType).getBaseType() and + operandTag instanceof SideEffectOperandTag + or + tag instanceof OnlyInstructionTag and + operandType = arg.getType().getUnspecifiedType() and + not operandType instanceof DerivedType and + operandTag instanceof SideEffectOperandTag + | + // If the type we select is an incomplete type (e.g. a forward-declared `struct`), there will + // not be a `CppType` that represents that type. In that case, fall back to `UnknownCppType`. + result = getTypeForPRValueOrUnknown(operandType) + ) } predicate hasSpecificWriteSideEffect(Opcode op) { @@ -510,7 +554,7 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff ) or not call.getTarget() instanceof SideEffectFunction and - op instanceof Opcode::IndirectReadSideEffect + op instanceof Opcode::BufferReadSideEffect } override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) { diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll index 294a539ec31..87fd781fd95 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedDeclarationEntry.qll @@ -120,7 +120,9 @@ abstract class TranslatedVariableDeclaration extends TranslatedElement, Initiali private predicate hasUninitializedInstruction() { not exists(getInitialization()) or - getInitialization() instanceof TranslatedListInitialization + getInitialization() instanceof TranslatedListInitialization or + getInitialization() instanceof TranslatedConstructorInitialization or + getInitialization().(TranslatedStringLiteralInitialization).zeroInitRange(_, _) } } diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll index 3e29b1bad07..edca6e21039 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll @@ -9,6 +9,7 @@ private import InstructionTag private import TranslatedCondition private import TranslatedFunction private import TranslatedStmt +private import TranslatedExpr private import IRConstruction private import semmle.code.cpp.models.interfaces.SideEffect @@ -235,6 +236,15 @@ newtype TTranslatedElement = expr.hasLValueToRValueConversion() and not ignoreLoad(expr) } or + TTranslatedResultCopy(Expr expr) { + not ignoreExpr(expr) and + exprNeedsCopyIfNotLoaded(expr) and + // Doesn't have a TTranslatedLoad + not ( + expr.hasLValueToRValueConversion() and + not ignoreLoad(expr) + ) + } or // An expression most naturally translated as control flow. TTranslatedNativeCondition(Expr expr) { not ignoreExpr(expr) and @@ -380,8 +390,10 @@ newtype TTranslatedElement = TTranslatedAllocationSize(NewOrNewArrayExpr newExpr) { not ignoreExpr(newExpr) } or // The declaration/initialization part of a `ConditionDeclExpr` TTranslatedConditionDecl(ConditionDeclExpr expr) { not ignoreExpr(expr) } or - // The side effects of a `Call` { - TTranslatedSideEffects(Call expr) { exists(TTranslatedArgumentSideEffect(expr, _, _, _)) } or // A precise side effect of an argument to a `Call` { + // The side effects of a `Call` + TTranslatedSideEffects(Call expr) { + exists(TTranslatedArgumentSideEffect(expr, _, _, _)) or expr instanceof ConstructorCall + } or // A precise side effect of an argument to a `Call` TTranslatedArgumentSideEffect(Call call, Expr expr, int n, boolean isWrite) { ( expr = call.getArgument(n).getFullyConverted() diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll index 3fc73d66878..9db42c742ac 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll @@ -62,12 +62,11 @@ abstract class TranslatedExpr extends TranslatedElement { /** * Holds if the result of this `TranslatedExpr` is a glvalue. */ - private predicate isResultGLValue() { + predicate isResultGLValue() { + // This implementation is overridden in `TranslatedCoreExpr` to mark them + // as glvalues if they have loads on them. It's not overridden in + // `TranslatedResultCopy` since result copies never have loads. expr.isGLValueCategory() - or - // If this TranslatedExpr doesn't produce the result, then it must represent - // a glvalue that is then loaded by a TranslatedLoad. - not producesExprResult() } final override Locatable getAST() { result = expr } @@ -96,14 +95,28 @@ abstract class TranslatedExpr extends TranslatedElement { abstract class TranslatedCoreExpr extends TranslatedExpr { final override string toString() { result = expr.toString() } + /** + * Holds if the result of this `TranslatedExpr` is a glvalue. + */ + override predicate isResultGLValue() { + super.isResultGLValue() + or + // If this TranslatedExpr doesn't produce the result, then it must represent + // a glvalue that is then loaded by a TranslatedLoad. + hasLoad() + } + + final predicate hasLoad() { + expr.hasLValueToRValueConversion() and + not ignoreLoad(expr) + } + final override predicate producesExprResult() { // If there's no load, then this is the only TranslatedExpr for this // expression. - not expr.hasLValueToRValueConversion() - or - // If we're supposed to ignore the load on this expression, then this - // is the only TranslatedExpr. - ignoreLoad(expr) + not hasLoad() and + // If there's a result copy, then this expression's result is the copy. + not exprNeedsCopyIfNotLoaded(expr) } } @@ -288,6 +301,48 @@ class TranslatedLoad extends TranslatedExpr, TTranslatedLoad { private TranslatedCoreExpr getOperand() { result.getExpr() = expr } } +/** + * IR translation of an implicit lvalue-to-rvalue conversion on the result of + * an expression. + */ +class TranslatedResultCopy extends TranslatedExpr, TTranslatedResultCopy { + TranslatedResultCopy() { this = TTranslatedResultCopy(expr) } + + override string toString() { result = "Result of " + expr.toString() } + + override Instruction getFirstInstruction() { result = getOperand().getFirstInstruction() } + + override TranslatedElement getChild(int id) { id = 0 and result = getOperand() } + + override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { + tag = ResultCopyTag() and + opcode instanceof Opcode::CopyValue and + resultType = getOperand().getResultType() + } + + override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { + tag = ResultCopyTag() and + result = getParent().getChildSuccessor(this) and + kind instanceof GotoEdge + } + + override Instruction getChildSuccessor(TranslatedElement child) { + child = getOperand() and result = getInstruction(ResultCopyTag()) + } + + override Instruction getResult() { result = getInstruction(ResultCopyTag()) } + + override Instruction getInstructionOperand(InstructionTag tag, OperandTag operandTag) { + tag = ResultCopyTag() and + operandTag instanceof UnaryOperandTag and + result = getOperand().getResult() + } + + final override predicate producesExprResult() { any() } + + private TranslatedCoreExpr getOperand() { result.getExpr() = expr } +} + class TranslatedCommaExpr extends TranslatedNonConstantExpr { override CommaExpr expr; @@ -983,7 +1038,7 @@ class TranslatedInheritanceConversion extends TranslatedSingleInstructionConvers then if expr.(BaseClassConversion).isVirtual() then result instanceof Opcode::ConvertToVirtualBase - else result instanceof Opcode::ConvertToBase + else result instanceof Opcode::ConvertToNonVirtualBase else result instanceof Opcode::ConvertToDerived } } @@ -2403,6 +2458,58 @@ class TranslatedErrorExpr extends TranslatedSingleInstructionExpr { final override Opcode getOpcode() { result instanceof Opcode::Error } } +/** + * Holds if the translation of `expr` will not directly generate any + * `Instruction` for use as result. For such instructions we can synthesize a + * `CopyValue` instruction to ensure that there is a 1-to-1 mapping between + * expressions and result-bearing instructions. + */ +// This should ideally be a dispatch predicate on TranslatedNonConstantExpr, +// but it doesn't look monotonic to QL. +predicate exprNeedsCopyIfNotLoaded(Expr expr) { + ( + expr instanceof AssignExpr + or + expr instanceof AssignOperation and + not expr.isPRValueCategory() // is C++ + or + expr instanceof PrefixCrementOperation and + not expr.isPRValueCategory() // is C++ + or + expr instanceof PointerDereferenceExpr + or + expr instanceof AddressOfExpr + or + expr instanceof BuiltInOperationBuiltInAddressOf + or + // No case for ParenthesisExpr to avoid getting too many instructions + expr instanceof ReferenceDereferenceExpr + or + expr instanceof ReferenceToExpr + or + expr instanceof CommaExpr + or + expr instanceof ConditionDeclExpr + // TODO: simplify TranslatedStmtExpr too + ) and + not exprImmediatelyDiscarded(expr) +} + +/** + * Holds if `expr` is immediately discarded. Such expressions do not need a + * `CopyValue` because it's unlikely that anyone is interested in their value. + */ +private predicate exprImmediatelyDiscarded(Expr expr) { + exists(ExprStmt s | + s = expr.getParent() and + not exists(StmtExpr se | s = se.getStmt().(Block).getLastStmt()) + ) + or + exists(CommaExpr c | c.getLeftOperand() = expr) + or + exists(ForStmt for | for.getUpdate() = expr) +} + /** * The IR translation of an `__assume` expression. We currently translate these as `NoOp`. In the * future, we will probably want to do something better. At a minimum, we can model `__assume(0)` as diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll index fd8f4579e32..b0a3c153085 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedFunction.qll @@ -100,6 +100,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction { result = getInstruction(UnmodeledUseTag()) or tag = UnmodeledUseTag() and + result = getInstruction(AliasedUseTag()) + or + tag = AliasedUseTag() and result = getInstruction(ExitFunctionTag()) ) } @@ -172,6 +175,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction { opcode instanceof Opcode::UnmodeledUse and resultType = getVoidType() or + tag = AliasedUseTag() and + opcode instanceof Opcode::AliasedUse and + resultType = getVoidType() + or tag = ExitFunctionTag() and opcode instanceof Opcode::ExitFunction and resultType = getVoidType() @@ -192,6 +199,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction { operandTag instanceof UnmodeledUseOperandTag and result = getUnmodeledDefinitionInstruction() or + tag = AliasedUseTag() and + operandTag instanceof SideEffectOperandTag and + result = getUnmodeledDefinitionInstruction() + or tag = ReturnTag() and hasReturnValue() and ( @@ -208,6 +219,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction { hasReturnValue() and operandTag instanceof LoadOperandTag and result = getTypeForPRValue(getReturnType()) + or + tag = AliasedUseTag() and + operandTag instanceof SideEffectOperandTag and + result = getUnknownType() } final override IRVariable getInstructionVariable(InstructionTag tag) { diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll index 21ad11513bd..609f8276640 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll @@ -340,7 +340,7 @@ class TranslatedStringLiteralInitialization extends TranslatedDirectInitializati * Holds if the `elementCount` array elements starting at `startIndex` must be * zero initialized. */ - private predicate zeroInitRange(int startIndex, int elementCount) { + predicate zeroInitRange(int startIndex, int elementCount) { exists(int targetCount | startIndex = expr.getUnspecifiedType().(ArrayType).getArraySize() and targetCount = getContext().getTargetType().getUnspecifiedType().(ArrayType).getArraySize() and @@ -752,7 +752,7 @@ abstract class TranslatedBaseStructorCall extends TranslatedStructorCallFromStru final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { tag = OnlyInstructionTag() and - opcode instanceof Opcode::ConvertToBase and + opcode instanceof Opcode::ConvertToNonVirtualBase and resultType = getTypeForGLValue(call.getTarget().getDeclaringType()) } diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll index 1a607f82c29..e10e266b2ab 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/IRVariable.qll @@ -22,6 +22,12 @@ abstract class IRVariable extends TIRVariable { abstract string toString(); + /** + * Holds if this variable's value cannot be changed within a function. Currently used for string + * literals, but could also apply to `const` global and static variables. + */ + predicate isReadOnly() { none() } + /** * Gets the type of the variable. */ @@ -113,34 +119,43 @@ class IRStaticUserVariable extends IRUserVariable { final override Language::StaticVariable getVariable() { result = var } } +abstract class IRGeneratedVariable extends IRVariable { + Language::AST ast; + Language::LanguageType type; + + final override Language::LanguageType getLanguageType() { result = type } + + final override Language::AST getAST() { result = ast } + + override string toString() { result = getBaseString() + getLocationString() } + + override string getUniqueId() { none() } + + final string getLocationString() { + result = ast.getLocation().getStartLine().toString() + ":" + + ast.getLocation().getStartColumn().toString() + } + + string getBaseString() { none() } +} + IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) { result.getAST() = ast and result.getTag() = tag } -class IRTempVariable extends IRVariable, IRAutomaticVariable, TIRTempVariable { - Language::AST ast; +class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable { TempVariableTag tag; - Language::LanguageType type; IRTempVariable() { this = TIRTempVariable(func, ast, tag, type) } - final override Language::LanguageType getLanguageType() { result = type } - - final override Language::AST getAST() { result = ast } - final override string getUniqueId() { result = "Temp: " + Construction::getTempVariableUniqueId(this) } final TempVariableTag getTag() { result = tag } - override string toString() { - result = getBaseString() + ast.getLocation().getStartLine().toString() + ":" + - ast.getLocation().getStartColumn().toString() - } - - string getBaseString() { result = "#temp" } + override string getBaseString() { result = "#temp" } } class IRReturnVariable extends IRTempVariable { @@ -154,3 +169,19 @@ class IRThrowVariable extends IRTempVariable { override string getBaseString() { result = "#throw" } } + +class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { + Language::StringLiteral literal; + + IRStringLiteral() { this = TIRStringLiteral(func, ast, type, literal) } + + final override predicate isReadOnly() { any() } + + final override string getUniqueId() { + result = "String: " + getLocationString() + "=" + Language::getStringLiteralText(literal) + } + + override string getBaseString() { result = "#string" } + + final Language::StringLiteral getLiteral() { result = literal } +} diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll index a2a39e4d42e..8e785015828 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll @@ -51,7 +51,8 @@ module InstructionSanity { opcode instanceof ReadSideEffectOpcode or opcode instanceof Opcode::InlineAsm or opcode instanceof Opcode::CallSideEffect or - opcode instanceof Opcode::ReturnIndirection + opcode instanceof Opcode::ReturnIndirection or + opcode instanceof Opcode::AliasedUse ) and tag instanceof SideEffectOperandTag ) @@ -124,6 +125,16 @@ module InstructionSanity { ) } + query predicate duplicateChiOperand( + ChiInstruction chi, string message, IRFunction func, string funcText + ) { + chi.getTotal() = chi.getPartial() and + message = "Chi instruction for " + chi.getPartial().toString() + + " has duplicate operands in function $@" and + func = chi.getEnclosingIRFunction() and + funcText = Language::getIdentityString(func.getFunction()) + } + query predicate sideEffectWithoutPrimary( SideEffectInstruction instr, string message, IRFunction func, string funcText ) { @@ -264,6 +275,7 @@ module InstructionSanity { ) { exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex | not useOperand.getUse() instanceof UnmodeledUseInstruction and + not defInstr instanceof UnmodeledDefinitionInstruction and pointOfEvaluation(useOperand, useBlock, useIndex) and defInstr = useOperand.getAnyDef() and ( @@ -827,14 +839,12 @@ class FloatConstantInstruction extends ConstantInstruction { FloatConstantInstruction() { getResultType() instanceof Language::FloatingPointType } } -class StringConstantInstruction extends Instruction { - Language::StringLiteral value; +class StringConstantInstruction extends VariableInstruction { + override IRStringLiteral var; - StringConstantInstruction() { value = Construction::getInstructionStringLiteral(this) } + final override string getImmediateString() { result = Language::getStringLiteralText(getValue()) } - final override string getImmediateString() { result = Language::getStringLiteralText(value) } - - final Language::StringLiteral getValue() { result = value } + final Language::StringLiteral getValue() { result = var.getLiteral() } } class BinaryInstruction extends Instruction { @@ -1002,14 +1012,22 @@ class InheritanceConversionInstruction extends UnaryInstruction { * to the address of a direct non-virtual base class. */ class ConvertToBaseInstruction extends InheritanceConversionInstruction { - ConvertToBaseInstruction() { getOpcode() instanceof Opcode::ConvertToBase } + ConvertToBaseInstruction() { getOpcode() instanceof ConvertToBaseOpcode } +} + +/** + * Represents an instruction that converts from the address of a derived class + * to the address of a direct non-virtual base class. + */ +class ConvertToNonVirtualBaseInstruction extends ConvertToBaseInstruction { + ConvertToNonVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToNonVirtualBase } } /** * Represents an instruction that converts from the address of a derived class * to the address of a virtual base class. */ -class ConvertToVirtualBaseInstruction extends InheritanceConversionInstruction { +class ConvertToVirtualBaseInstruction extends ConvertToBaseInstruction { ConvertToVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToVirtualBase } } @@ -1442,6 +1460,13 @@ class AliasedDefinitionInstruction extends Instruction { final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess } } +/** + * An instruction that consumes all escaped memory on exit from the function. + */ +class AliasedUseInstruction extends Instruction { + AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse } +} + class UnmodeledUseInstruction extends Instruction { UnmodeledUseInstruction() { getOpcode() instanceof Opcode::UnmodeledUse } diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll index c85d609d200..8042dfa6a69 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll @@ -396,6 +396,9 @@ class SideEffectOperand extends TypedOperand { override SideEffectOperandTag tag; override MemoryAccessKind getMemoryAccess() { + useInstr instanceof AliasedUseInstruction and + result instanceof NonLocalMayMemoryAccess + or useInstr instanceof CallSideEffectInstruction and result instanceof EscapedMayMemoryAccess or diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll index 74c288d3468..2768f910120 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll @@ -110,7 +110,7 @@ private predicate operandIsPropagated(Operand operand, IntValue bitOffset) { instr = operand.getUse() and ( // Converting to a non-virtual base class adds the offset of the base class. - exists(ConvertToBaseInstruction convert | + exists(ConvertToNonVirtualBaseInstruction convert | convert = instr and bitOffset = Ints::mul(convert.getDerivation().getByteOffset(), 8) ) @@ -309,6 +309,10 @@ predicate resultPointsTo(Instruction instr, IRVariable var, IntValue bitOffset) instr.(VariableAddressInstruction).getIRVariable() = var and bitOffset = 0 or + // A string literal is just a special read-only global variable. + instr.(StringConstantInstruction).getIRVariable() = var and + bitOffset = 0 + or exists(Operand operand, IntValue originalBitOffset, IntValue propagatedBitOffset | operand = instr.getAnOperand() and // If an operand is propagated, then the result points to the same variable, diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll index 7152dec5c4a..a789edc7590 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll @@ -341,11 +341,6 @@ private module Cached { result = getOldInstruction(instruction).(OldIR::ConstantValueInstruction).getValue() } - cached - Language::StringLiteral getInstructionStringLiteral(Instruction instruction) { - result = getOldInstruction(instruction).(OldIR::StringConstantInstruction).getValue() - } - cached Language::BuiltInOperation getInstructionBuiltInOperation(Instruction instruction) { result = getOldInstruction(instruction) @@ -401,7 +396,11 @@ private predicate hasChiNode(Alias::VirtualVariable vvar, OldInstruction def) { defLocation.getVirtualVariable() = vvar and // If the definition totally (or exactly) overlaps the virtual variable, then there's no need for a `Chi` // instruction. - Alias::getOverlap(defLocation, vvar) instanceof MayPartiallyOverlap + ( + Alias::getOverlap(defLocation, vvar) instanceof MayPartiallyOverlap or + def.getResultMemoryAccess() instanceof IndirectMayMemoryAccess or + def.getResultMemoryAccess() instanceof BufferMayMemoryAccess + ) ) } @@ -714,7 +713,10 @@ module DefUse { defLocation = Alias::getResultMemoryLocation(def) and block.getInstruction(index) = def and overlap = Alias::getOverlap(defLocation, useLocation) and - if overlap instanceof MayPartiallyOverlap + if + overlap instanceof MayPartiallyOverlap or + def.getResultMemoryAccess() instanceof IndirectMayMemoryAccess or + def.getResultMemoryAccess() instanceof BufferMayMemoryAccess then offset = (index * 2) + 1 // The use will be connected to the definition on the `Chi` instruction. else offset = index * 2 // The use will be connected to the definition on the original instruction. ) diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll index 5925631b67c..49bb908265c 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll @@ -30,7 +30,11 @@ private predicate isVariableModeled(IRVariable var) { hasResultMemoryAccess(instr, var, type, bitOffset) | bitOffset = 0 and - type.getIRType() = var.getIRType() + type.getIRType() = var.getIRType() and + not ( + instr.getResultMemoryAccess() instanceof IndirectMayMemoryAccess or + instr.getResultMemoryAccess() instanceof BufferMayMemoryAccess + ) ) and forall(MemoryOperand operand, Language::LanguageType type, IntValue bitOffset | hasOperandMemoryAccess(operand, var, type, bitOffset) diff --git a/cpp/ql/src/semmle/code/cpp/ir/internal/CppType.qll b/cpp/ql/src/semmle/code/cpp/ir/internal/CppType.qll index 88184d90345..e967dc9920c 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/internal/CppType.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/internal/CppType.qll @@ -175,6 +175,7 @@ private IRType getIRTypeForPRValue(Type type) { ) } +cached private newtype TCppType = TPRValueType(Type type) { exists(getIRTypeForPRValue(type)) } or TFunctionGLValueType() or @@ -203,6 +204,7 @@ class CppType extends TCppType { * Gets the `IRType` that represents this `CppType`. Many different `CppType`s can map to a single * `IRType`. */ + cached IRType getIRType() { none() } /** diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Printf.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Printf.qll index 5654c1a9c99..58721897802 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/Printf.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Printf.qll @@ -7,9 +7,9 @@ class Printf extends FormattingFunction { Printf() { this instanceof TopLevelFunction and ( - hasGlobalName("printf") or + hasGlobalOrStdName("printf") or hasGlobalName("printf_s") or - hasGlobalName("wprintf") or + hasGlobalOrStdName("wprintf") or hasGlobalName("wprintf_s") or hasGlobalName("g_printf") ) and @@ -19,7 +19,7 @@ class Printf extends FormattingFunction { override int getFormatParameterIndex() { result = 0 } override predicate isWideCharDefault() { - hasGlobalName("wprintf") or + hasGlobalOrStdName("wprintf") or hasGlobalName("wprintf_s") } } @@ -31,8 +31,8 @@ class Fprintf extends FormattingFunction { Fprintf() { this instanceof TopLevelFunction and ( - hasGlobalName("fprintf") or - hasGlobalName("fwprintf") or + hasGlobalOrStdName("fprintf") or + hasGlobalOrStdName("fwprintf") or hasGlobalName("g_fprintf") ) and not exists(getDefinition().getFile().getRelativePath()) @@ -40,7 +40,7 @@ class Fprintf extends FormattingFunction { override int getFormatParameterIndex() { result = 1 } - override predicate isWideCharDefault() { hasGlobalName("fwprintf") } + override predicate isWideCharDefault() { hasGlobalOrStdName("fwprintf") } override int getOutputParameterIndex() { result = 0 } } @@ -52,10 +52,10 @@ class Sprintf extends FormattingFunction { Sprintf() { this instanceof TopLevelFunction and ( - hasGlobalName("sprintf") or + hasGlobalOrStdName("sprintf") or hasGlobalName("_sprintf_l") or hasGlobalName("__swprintf_l") or - hasGlobalName("wsprintf") or + hasGlobalOrStdName("wsprintf") or hasGlobalName("g_strdup_printf") or hasGlobalName("g_sprintf") or hasGlobalName("__builtin___sprintf_chk") @@ -99,8 +99,8 @@ class Snprintf extends FormattingFunction { Snprintf() { this instanceof TopLevelFunction and ( - hasGlobalName("snprintf") or // C99 defines snprintf - hasGlobalName("swprintf") or // The s version of wide-char printf is also always the n version + hasGlobalOrStdName("snprintf") or // C99 defines snprintf + hasGlobalOrStdName("swprintf") or // The s version of wide-char printf is also always the n version // Microsoft has _snprintf as well as several other variations hasGlobalName("sprintf_s") or hasGlobalName("snprintf_s") or @@ -160,7 +160,7 @@ class Snprintf extends FormattingFunction { */ predicate returnsFullFormatLength() { ( - hasGlobalName("snprintf") or + hasGlobalOrStdName("snprintf") or hasGlobalName("g_snprintf") or hasGlobalName("__builtin___snprintf_chk") or hasGlobalName("snprintf_s") diff --git a/cpp/ql/src/semmle/code/cpp/models/implementations/Pure.qll b/cpp/ql/src/semmle/code/cpp/models/implementations/Pure.qll index c5729c5d0f6..59b8c25700f 100644 --- a/cpp/ql/src/semmle/code/cpp/models/implementations/Pure.qll +++ b/cpp/ql/src/semmle/code/cpp/models/implementations/Pure.qll @@ -6,7 +6,7 @@ import semmle.code.cpp.models.interfaces.SideEffect class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunction, SideEffectFunction { PureStrFunction() { exists(string name | - hasGlobalName(name) and + hasGlobalOrStdName(name) and ( name = "atof" or name = "atoi" or @@ -75,7 +75,7 @@ class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunction, SideE class PureFunction extends TaintFunction, SideEffectFunction { PureFunction() { exists(string name | - hasGlobalName(name) and + hasGlobalOrStdName(name) and ( name = "abs" or name = "labs" diff --git a/cpp/ql/src/semmle/code/cpp/rangeanalysis/RangeAnalysis.qll b/cpp/ql/src/semmle/code/cpp/rangeanalysis/RangeAnalysis.qll index 50fe6ab9a55..b663f336d0a 100644 --- a/cpp/ql/src/semmle/code/cpp/rangeanalysis/RangeAnalysis.qll +++ b/cpp/ql/src/semmle/code/cpp/rangeanalysis/RangeAnalysis.qll @@ -80,7 +80,7 @@ private module RangeAnalysisCache { cached module RangeAnalysisPublic { /** - * Holds if `b + delta` is a valid bound for `i`. + * Holds if `b + delta` is a valid bound for `i` and this is the best such delta. * - `upper = true` : `i <= b + delta` * - `upper = false` : `i >= b + delta` * @@ -90,11 +90,12 @@ private module RangeAnalysisCache { */ cached predicate boundedInstruction(Instruction i, Bound b, int delta, boolean upper, Reason reason) { - boundedInstruction(i, b, delta, upper, _, _, reason) + boundedInstruction(i, b, delta, upper, _, _, reason) and + bestInstructionBound(i, b, delta, upper) } /** - * Holds if `b + delta` is a valid bound for `op`. + * Holds if `b + delta` is a valid bound for `op` and this is the best such delta. * - `upper = true` : `op <= b + delta` * - `upper = false` : `op >= b + delta` * @@ -104,9 +105,8 @@ private module RangeAnalysisCache { */ cached predicate boundedOperand(Operand op, Bound b, int delta, boolean upper, Reason reason) { - boundedNonPhiOperand(op, b, delta, upper, _, _, reason) - or - boundedPhiOperand(op, b, delta, upper, _, _, reason) + boundedOperandCand(op, b, delta, upper, reason) and + bestOperandBound(op, b, delta, upper) } } @@ -124,6 +124,43 @@ private module RangeAnalysisCache { private import RangeAnalysisCache import RangeAnalysisPublic +/** + * Holds if `b + delta` is a valid bound for `e` and this is the best such delta. + * - `upper = true` : `e <= b + delta` + * - `upper = false` : `e >= b + delta` + */ +private predicate bestInstructionBound(Instruction i, Bound b, int delta, boolean upper) { + delta = min(int d | boundedInstruction(i, b, d, upper, _, _, _)) and upper = true + or + delta = max(int d | boundedInstruction(i, b, d, upper, _, _, _)) and upper = false +} + +/** + * Holds if `b + delta` is a valid bound for `op`. + * - `upper = true` : `op <= b + delta` + * - `upper = false` : `op >= b + delta` + * + * The reason for the bound is given by `reason` and may be either a condition + * or `NoReason` if the bound was proven directly without the use of a bounding + * condition. + */ +private predicate boundedOperandCand(Operand op, Bound b, int delta, boolean upper, Reason reason) { + boundedNonPhiOperand(op, b, delta, upper, _, _, reason) + or + boundedPhiOperand(op, b, delta, upper, _, _, reason) +} + +/** + * Holds if `b + delta` is a valid bound for `op` and this is the best such delta. + * - `upper = true` : `op <= b + delta` + * - `upper = false` : `op >= b + delta` + */ +private predicate bestOperandBound(Operand op, Bound b, int delta, boolean upper) { + delta = min(int d | boundedOperandCand(op, b, d, upper, _)) and upper = true + or + delta = max(int d | boundedOperandCand(op, b, d, upper, _)) and upper = false +} + /** * Gets a condition that tests whether `vn` equals `bound + delta`. * diff --git a/cpp/ql/src/semmle/code/cpp/security/CommandExecution.qll b/cpp/ql/src/semmle/code/cpp/security/CommandExecution.qll index 9988e20290c..c7bea7eede7 100644 --- a/cpp/ql/src/semmle/code/cpp/security/CommandExecution.qll +++ b/cpp/ql/src/semmle/code/cpp/security/CommandExecution.qll @@ -8,7 +8,7 @@ import semmle.code.cpp.security.FunctionWithWrappers */ class SystemFunction extends FunctionWithWrappers { SystemFunction() { - hasGlobalName("system") or + hasGlobalOrStdName("system") or hasGlobalName("popen") or // Windows variants hasGlobalName("_popen") or diff --git a/cpp/ql/src/semmle/code/cpp/security/FileWrite.qll b/cpp/ql/src/semmle/code/cpp/security/FileWrite.qll index 6363e3a5d14..219f3d0a75b 100644 --- a/cpp/ql/src/semmle/code/cpp/security/FileWrite.qll +++ b/cpp/ql/src/semmle/code/cpp/security/FileWrite.qll @@ -125,7 +125,7 @@ private predicate fileWrite(Call write, Expr source, Expr dest) { exists(Function f, int s, int d | f = write.getTarget() and source = write.getArgument(s) and dest = write.getArgument(d) | - exists(string name | f.hasGlobalName(name) | + exists(string name | f.hasGlobalOrStdName(name) | // named functions name = "fwrite" and s = 0 and d = 3 or diff --git a/cpp/ql/src/semmle/code/cpp/security/OutputWrite.qll b/cpp/ql/src/semmle/code/cpp/security/OutputWrite.qll index 751a7a71ec7..06abfdb454d 100644 --- a/cpp/ql/src/semmle/code/cpp/security/OutputWrite.qll +++ b/cpp/ql/src/semmle/code/cpp/security/OutputWrite.qll @@ -63,8 +63,8 @@ private predicate outputWrite(Expr write, Expr source) { or // puts, putchar ( - f.hasGlobalName("puts") or - f.hasGlobalName("putchar") + f.hasGlobalOrStdName("puts") or + f.hasGlobalOrStdName("putchar") ) and arg = 0 or diff --git a/cpp/ql/src/semmle/code/cpp/security/Security.qll b/cpp/ql/src/semmle/code/cpp/security/Security.qll index 1a1c1d61ce8..c12a70b52c6 100644 --- a/cpp/ql/src/semmle/code/cpp/security/Security.qll +++ b/cpp/ql/src/semmle/code/cpp/security/Security.qll @@ -70,11 +70,9 @@ class SecurityOptions extends string { */ predicate userInputArgument(FunctionCall functionCall, int arg) { exists(string fname | - functionCall.getTarget().hasGlobalName(fname) and + functionCall.getTarget().hasGlobalOrStdName(fname) and exists(functionCall.getArgument(arg)) and ( - fname = "read" and arg = 1 - or fname = "fread" and arg = 0 or fname = "fgets" and arg = 0 @@ -83,6 +81,16 @@ class SecurityOptions extends string { or fname = "gets" and arg = 0 or + fname = "scanf" and arg >= 1 + or + fname = "fscanf" and arg >= 2 + ) + or + functionCall.getTarget().hasGlobalName(fname) and + exists(functionCall.getArgument(arg)) and + ( + fname = "read" and arg = 1 + or fname = "getaddrinfo" and arg = 3 or fname = "recv" and arg = 1 @@ -91,10 +99,6 @@ class SecurityOptions extends string { (arg = 1 or arg = 4 or arg = 5) or fname = "recvmsg" and arg = 1 - or - fname = "scanf" and arg >= 1 - or - fname = "fscanf" and arg >= 2 ) ) } diff --git a/cpp/ql/src/semmle/code/cpp/security/TaintTracking.qll b/cpp/ql/src/semmle/code/cpp/security/TaintTracking.qll index 1ef0a6f7092..31d8ad00f9c 100644 --- a/cpp/ql/src/semmle/code/cpp/security/TaintTracking.qll +++ b/cpp/ql/src/semmle/code/cpp/security/TaintTracking.qll @@ -425,41 +425,41 @@ private int maxArgIndex(Function f) { /** Functions that copy the value of one argument to another */ private predicate copyValueBetweenArguments(Function f, int sourceArg, int destArg) { - f.hasGlobalName("memcpy") and sourceArg = 1 and destArg = 0 + f.hasGlobalOrStdName("memcpy") and sourceArg = 1 and destArg = 0 or f.hasGlobalName("__builtin___memcpy_chk") and sourceArg = 1 and destArg = 0 or - f.hasGlobalName("memmove") and sourceArg = 1 and destArg = 0 + f.hasGlobalOrStdName("memmove") and sourceArg = 1 and destArg = 0 or - f.hasGlobalName("strcat") and sourceArg = 1 and destArg = 0 + f.hasGlobalOrStdName("strcat") and sourceArg = 1 and destArg = 0 or f.hasGlobalName("_mbscat") and sourceArg = 1 and destArg = 0 or - f.hasGlobalName("wcsncat") and sourceArg = 1 and destArg = 0 + f.hasGlobalOrStdName("wcscat") and sourceArg = 1 and destArg = 0 or - f.hasGlobalName("strncat") and sourceArg = 1 and destArg = 0 + f.hasGlobalOrStdName("strncat") and sourceArg = 1 and destArg = 0 or f.hasGlobalName("_mbsncat") and sourceArg = 1 and destArg = 0 or f.hasGlobalName("wcsncat") and sourceArg = 1 and destArg = 0 or - f.hasGlobalName("strcpy") and sourceArg = 1 and destArg = 0 + f.hasGlobalOrStdName("strcpy") and sourceArg = 1 and destArg = 0 or f.hasGlobalName("_mbscpy") and sourceArg = 1 and destArg = 0 or - f.hasGlobalName("wcscpy") and sourceArg = 1 and destArg = 0 + f.hasGlobalOrStdName("wcscpy") and sourceArg = 1 and destArg = 0 or - f.hasGlobalName("strncpy") and sourceArg = 1 and destArg = 0 + f.hasGlobalOrStdName("strncpy") and sourceArg = 1 and destArg = 0 or f.hasGlobalName("_mbsncpy") and sourceArg = 1 and destArg = 0 or - f.hasGlobalName("wcsncpy") and sourceArg = 1 and destArg = 0 + f.hasGlobalOrStdName("wcsncpy") and sourceArg = 1 and destArg = 0 or f.hasGlobalName("inet_aton") and sourceArg = 0 and destArg = 1 or f.hasGlobalName("inet_pton") and sourceArg = 1 and destArg = 2 or - f.hasGlobalName("strftime") and sourceArg in [2 .. maxArgIndex(f)] and destArg = 0 + f.hasGlobalOrStdName("strftime") and sourceArg in [2 .. maxArgIndex(f)] and destArg = 0 or exists(FormattingFunction ff | ff = f | sourceArg in [ff.getFormatParameterIndex() .. maxArgIndex(f)] and @@ -473,31 +473,31 @@ private predicate returnArgument(Function f, int sourceArg) { or f.hasGlobalName("__builtin___memcpy_chk") and sourceArg = 0 or - f.hasGlobalName("memmove") and sourceArg = 0 + f.hasGlobalOrStdName("memmove") and sourceArg = 0 or - f.hasGlobalName("strcat") and sourceArg = 0 + f.hasGlobalOrStdName("strcat") and sourceArg = 0 or f.hasGlobalName("_mbscat") and sourceArg = 0 or - f.hasGlobalName("wcsncat") and sourceArg = 0 + f.hasGlobalOrStdName("wcsncat") and sourceArg = 0 or - f.hasGlobalName("strncat") and sourceArg = 0 + f.hasGlobalOrStdName("strncat") and sourceArg = 0 or f.hasGlobalName("_mbsncat") and sourceArg = 0 or - f.hasGlobalName("wcsncat") and sourceArg = 0 + f.hasGlobalOrStdName("wcsncat") and sourceArg = 0 or - f.hasGlobalName("strcpy") and sourceArg = 0 + f.hasGlobalOrStdName("strcpy") and sourceArg = 0 or f.hasGlobalName("_mbscpy") and sourceArg = 0 or - f.hasGlobalName("wcscpy") and sourceArg = 0 + f.hasGlobalOrStdName("wcscpy") and sourceArg = 0 or - f.hasGlobalName("strncpy") and sourceArg = 0 + f.hasGlobalOrStdName("strncpy") and sourceArg = 0 or f.hasGlobalName("_mbsncpy") and sourceArg = 0 or - f.hasGlobalName("wcsncpy") and sourceArg = 0 + f.hasGlobalOrStdName("wcsncpy") and sourceArg = 0 or f.hasGlobalName("inet_ntoa") and sourceArg = 0 or diff --git a/cpp/ql/src/semmle/code/cpp/security/boostorg/asio/protocols.qll b/cpp/ql/src/semmle/code/cpp/security/boostorg/asio/protocols.qll index ae3733473ad..e113d5e5745 100644 --- a/cpp/ql/src/semmle/code/cpp/security/boostorg/asio/protocols.qll +++ b/cpp/ql/src/semmle/code/cpp/security/boostorg/asio/protocols.qll @@ -3,7 +3,7 @@ import semmle.code.cpp.dataflow.DataFlow module BoostorgAsio { /** - * Represents boost::asio::ssl::context enum + * Represents the `boost::asio::ssl::context` enum. */ class SslContextMethod extends Enum { SslContextMethod() { @@ -12,7 +12,7 @@ module BoostorgAsio { } /** - * returns the value for a banned protocol + * Gets an enumeration constant for a banned protocol. */ EnumConstant getABannedProtocolConstant() { result = this.getAnEnumConstant() and @@ -56,14 +56,15 @@ module BoostorgAsio { } /** - * returns the value for a approved protocols, but that are hard-coded (i.e. no protocol negotiation) + * Gets an enumeration constant for an approved protocol, that is hard-coded + * (no protocol negotiation). */ EnumConstant getAnApprovedButHardcodedProtocolConstant() { result = this.getATls12ProtocolConstant() } /** - * returns the value for a TLS v1.2 protocol + * Gets an enumeration constant for a TLS v1.2 protocol. */ EnumConstant getATls12ProtocolConstant() { result = this.getAnEnumConstant() and @@ -80,7 +81,7 @@ module BoostorgAsio { } /** - * returns the value for a TLS v1.3 protocol + * Gets an enumeration constant for a TLS v1.3 protocol. */ EnumConstant getATls13ProtocolConstant() { result = this.getAnEnumConstant() and @@ -97,7 +98,7 @@ module BoostorgAsio { } /** - * returns the value of a generic TLS or SSL/TLS protocol + * Gets an enumeration constant for a generic TLS or SSL/TLS protocol. */ EnumConstant getAGenericTlsProtocolConstant() { result = this.getAnEnumConstant() and @@ -116,7 +117,7 @@ module BoostorgAsio { } /** - * returns the value of a generic SSL/TLS protocol + * Gets an enumeration constant for a generic SSL/TLS protocol. */ EnumConstant getASslv23ProtocolConstant() { result = this.getAnEnumConstant() and @@ -135,7 +136,9 @@ module BoostorgAsio { } /** - * NOTE: ignore - Modern versions of OpenSSL do not support SSL v2 anymore, so this option is for backwards compatibility only + * Gets the value for the no_sslv2 constant, right shifted by 16 bits. + * + * Note that modern versions of OpelSSL do not support SSL v2, so this option is for backwards compatibility only. */ int getShiftedSslOptionsNoSsl2() { // SSL_OP_NO_SSLv2 was removed from modern OpenSSL versions @@ -143,7 +146,7 @@ module BoostorgAsio { } /** - * RightShift(16) value for no_sslv3 constant + * Gets the value for the no_sslv3 constant, right shifted by 16 bits. */ int getShiftedSslOptionsNoSsl3() { // SSL_OP_NO_SSLv3 == 0x02000000U @@ -151,7 +154,7 @@ module BoostorgAsio { } /** - * RightShift(16) value for no_tlsv1 constant + * Gets the value for the no_tlsv1 constant, right shifted by 16 bits. */ int getShiftedSslOptionsNoTls1() { // SSL_OP_NO_TLSv1 == 0x04000000U @@ -159,7 +162,7 @@ module BoostorgAsio { } /** - * RightShift(16) value for no_tlsv1_1 constant + * Gets the value for the no_tlsv1_1 constant, right shifted by 16 bits. */ int getShiftedSslOptionsNoTls1_1() { // SSL_OP_NO_TLSv1_1 == 0x10000000U @@ -167,7 +170,7 @@ module BoostorgAsio { } /** - * RightShift(16) value for no_tlsv1_2 constant + * Gets the value for the no_tlsv1_2 constant, right shifted by 16 bits. */ int getShiftedSslOptionsNoTls1_2() { // SSL_OP_NO_TLSv1_2 == 0x08000000U @@ -175,7 +178,7 @@ module BoostorgAsio { } /** - * RightShift(16) value for no_tlsv1_3 constant + * Gets the value for the no_tlsv1_3 constant, right shifted by 16 bits. */ int getShiftedSslOptionsNoTls1_3() { // SSL_OP_NO_TLSv1_2 == 0x20000000U @@ -183,7 +186,7 @@ module BoostorgAsio { } /** - * Represents boost::asio::ssl::context class + * Represents the `boost::asio::ssl::context` class. */ class SslContextClass extends Class { SslContextClass() { this.getQualifiedName() = "boost::asio::ssl::context" } @@ -196,7 +199,7 @@ module BoostorgAsio { } /** - * Represents boost::asio::ssl::context::set_options member function + * Represents `boost::asio::ssl::context::set_options` member function. */ class SslSetOptionsFunction extends Function { SslSetOptionsFunction() { @@ -205,7 +208,7 @@ module BoostorgAsio { } /** - * holds if the expression represents a banned protocol + * Holds if the expression represents a banned protocol. */ predicate isExprBannedBoostProtocol(Expr e) { exists(Literal va | va = e | @@ -244,7 +247,7 @@ module BoostorgAsio { } /** - * holds if the expression represents a TLS v1.2 protocol + * Holds if the expression represents a TLS v1.2 protocol. */ predicate isExprTls12BoostProtocol(Expr e) { exists(Literal va | va = e | @@ -269,7 +272,7 @@ module BoostorgAsio { } /** - * holds if the expression represents a protocol that requires Crypto Board approval + * Holds if the expression represents a protocol that requires Crypto Board approval. */ predicate isExprTls13BoostProtocol(Expr e) { exists(Literal va | va = e | @@ -294,7 +297,7 @@ module BoostorgAsio { } /** - * holds if the expression represents a generic TLS or SSL/TLS protocol + * Holds if the expression represents a generic TLS or SSL/TLS protocol. */ predicate isExprTlsBoostProtocol(Expr e) { exists(Literal va | va = e | @@ -325,7 +328,7 @@ module BoostorgAsio { } /** - * holds if the expression represents a generic SSl/TLS protocol + * Holds if the expression represents a generic SSl/TLS protocol. */ predicate isExprSslV23BoostProtocol(Expr e) { exists(Literal va | va = e | @@ -351,7 +354,8 @@ module BoostorgAsio { //////////////////////// Dataflow ///////////////////// /** - * Abstract - Protocol value Flows to the first argument of the context constructor + * Abstract class for flows of protocol values to the first argument of a context + * constructor. */ abstract class SslContextCallAbstractConfig extends DataFlow::Configuration { bindingset[this] @@ -366,7 +370,7 @@ module BoostorgAsio { } /** - * any Protocol value Flows to the first argument of the context constructor + * Any protocol value that flows to the first argument of a context constructor. */ class SslContextCallConfig extends SslContextCallAbstractConfig { SslContextCallConfig() { this = "SslContextCallConfig" } @@ -380,7 +384,7 @@ module BoostorgAsio { } /** - * a banned protocol value Flows to the first argument of the context constructor + * A banned protocol value that flows to the first argument of a context constructor. */ class SslContextCallBannedProtocolConfig extends SslContextCallAbstractConfig { SslContextCallBannedProtocolConfig() { this = "SslContextCallBannedProtocolConfig" } @@ -395,7 +399,7 @@ module BoostorgAsio { } /** - * a TLS 1.2 protocol value Flows to the first argument of the context constructor + * A TLS 1.2 protocol value that flows to the first argument of a context constructor. */ class SslContextCallTls12ProtocolConfig extends SslContextCallAbstractConfig { SslContextCallTls12ProtocolConfig() { this = "SslContextCallTls12ProtocolConfig" } @@ -410,7 +414,7 @@ module BoostorgAsio { } /** - * a TLS 1.3 protocol value Flows to the first argument of the context constructor + * A TLS 1.3 protocol value that flows to the first argument of a context constructor. */ class SslContextCallTls13ProtocolConfig extends SslContextCallAbstractConfig { SslContextCallTls13ProtocolConfig() { this = "SslContextCallTls12ProtocolConfig" } @@ -425,7 +429,7 @@ module BoostorgAsio { } /** - * a generic TLS protocol value Flows to the first argument of the context constructor + * A generic TLS protocol value that flows to the first argument of a context constructor. */ class SslContextCallTlsProtocolConfig extends SslContextCallAbstractConfig { SslContextCallTlsProtocolConfig() { this = "SslContextCallTlsProtocolConfig" } @@ -440,7 +444,7 @@ module BoostorgAsio { } /** - * a context constructor call flows to a call calling SetOptions() + * A context constructor call that flows to a call to `SetOptions()`. */ class SslContextFlowsToSetOptionConfig extends DataFlow::Configuration { SslContextFlowsToSetOptionConfig() { this = "SslContextFlowsToSetOptionConfig" } @@ -464,7 +468,7 @@ module BoostorgAsio { } /** - * an option value flows to the 1st parameter of SetOptions() + * An option value that flows to the first parameter of a call to `SetOptions()`. */ class SslOptionConfig extends DataFlow::Configuration { SslOptionConfig() { this = "SslOptionConfig" } diff --git a/cpp/ql/src/semmlecode.cpp.dbscheme b/cpp/ql/src/semmlecode.cpp.dbscheme index 98a075d5495..bd182f697bf 100644 --- a/cpp/ql/src/semmlecode.cpp.dbscheme +++ b/cpp/ql/src/semmlecode.cpp.dbscheme @@ -731,6 +731,11 @@ class_template_argument( int index: int ref, int arg_type: @type ref ); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); is_proxy_class_for( unique int id: @usertype ref, @@ -755,6 +760,11 @@ function_template_argument( int index: int ref, int arg_type: @type ref ); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); is_variable_template(unique int id: @variable ref); variable_instantiation( @@ -766,6 +776,11 @@ variable_template_argument( int index: int ref, int arg_type: @type ref ); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); /* Fixed point types diff --git a/cpp/ql/src/semmlecode.cpp.dbscheme.stats b/cpp/ql/src/semmlecode.cpp.dbscheme.stats index bd1964b0d4f..3a73724456a 100644 --- a/cpp/ql/src/semmlecode.cpp.dbscheme.stats +++ b/cpp/ql/src/semmlecode.cpp.dbscheme.stats @@ -1,15 +1,15 @@ @compilation -10588 +10177 @externalDataElement -72 +70 @duplication -185332 +185440 @similarity @@ -17,7 +17,7 @@ @external_package -133 +128 @svnentry @@ -25,67 +25,67 @@ @location_default -9664446 +9335283 @location_stmt -2176932 +2178211 @location_expr -9745314 +9746017 @diagnostic -76160 +73204 @file -66167 +63599 @folder -12107 +11637 @macroinvocation -40814994 +39320374 @function -3565918 +3552236 @fun_decl -3657006 +3635139 @var_decl -5579181 +5495954 @type_decl -1469165 +1413769 @namespace_decl -151627 +145743 @using -320601 +308161 @static_assert -132358 +131017 @parameter -4779409 +4724692 @membervariable -325099 +321201 @globalvariable @@ -93,47 +93,47 @@ @localvariable -527101 +521758 @enumconstant -94487 +94097 @builtintype -559 +537 @derivedtype -4572495 +4651908 @decltype -45841 +44063 @usertype -4363319 +4337028 @mangledname -532986 +514256 @type_mention -1699359 +1682135 @routinetype -444572 +436132 @ptrtomember -12180 +13227 @specifier -547 +525 @gnuattribute @@ -141,11 +141,11 @@ @stdattribute -369 +365 @declspec -58441 +57849 @msattribute @@ -153,7 +153,7 @@ @alignas -267 +257 @attribute_arg_empty @@ -161,55 +161,55 @@ @attribute_arg_token -15930 +15768 @attribute_arg_constant -111500 +111565 @attribute_arg_type -60 +58 @derivation -370309 +392220 @frienddecl -231178 +222208 @comment -1743633 +1675974 @namespace -8497 +8167 @specialnamequalifyingelement -12 +11 @namequalifier -1125621 +1116919 @value -8776796 +8788031 @initialiser -1685017 +1668506 @literal -4374193 +4381545 @errorexpr -48066 +46201 @address_of @@ -217,15 +217,15 @@ @reference_to -1077837 +1039133 @indirect -294638 +294811 @ref_indirect -1267903 +1225212 @array_to_pointer @@ -233,31 +233,31 @@ @vacuous_destructor_call -4449 +4288 @assume -3328 +3294 @parexpr -3001187 +3002950 @arithnegexpr -654789 +654792 @unaryplusexpr -206 +198 @complementexpr -28027 +28043 @notexpr -357915 +358125 @conjugation @@ -265,51 +265,51 @@ @realpartexpr -72 +70 @imagpartexpr -72 +70 @postincrexpr -43039 +43064 @postdecrexpr -5401 +5404 @preincrexpr -63954 +61508 @predecrexpr -26586 +25554 @conditionalexpr -154429 +154519 @addexpr -209503 +209626 @subexpr -134974 +135053 @mulexpr -91616 +91670 @divexpr -63973 +64010 @remexpr -4657 +4660 @jmulexpr @@ -337,59 +337,59 @@ @paddexpr -87252 +87303 @psubexpr -23151 +23165 @pdiffexpr -25868 +24865 @lshiftexpr -347564 +347768 @rshiftexpr -59286 +59321 @andexpr -236938 +237077 @orexpr -145217 +143745 @xorexpr -37281 +37303 @eqexpr -212621 +212746 @neexpr -88456 +88508 @gtexpr -43936 +43962 @ltexpr -54831 +54863 @geexpr -22361 +22374 @leexpr -213875 +214001 @minexpr @@ -401,7 +401,7 @@ @assignexpr -551713 +552037 @assignaddexpr @@ -413,15 +413,15 @@ @assignmulexpr -7597 +7302 @assigndivexpr -2297 +2208 @assignremexpr -303 +292 @assignlshiftexpr @@ -433,39 +433,39 @@ @assignandexpr -7740 +7744 @assignorexpr -18663 +18674 @assignxorexpr -21992 +22005 @assignpaddexpr -13214 +13080 @assignpsubexpr -583 +577 @andlogicalexpr -116840 +116908 @orlogicalexpr -57827 +57861 @commaexpr -10721 +10329 @subscriptexpr -165754 +165851 @virtfunptrexpr @@ -473,15 +473,15 @@ @callexpr -248513 +239197 @vastartexpr -3710 +3673 @vaargexpr -1094 +1051 @vaendexpr @@ -493,63 +493,63 @@ @varaccess -5376400 +5325591 @thisaccess -1181340 +1169367 @new_expr -29515 +28370 @delete_expr -6564 +6309 @throw_expr -23777 +22855 @condition_decl -7646 +7349 @braced_init_list -133 +128 @type_id -4899 +4708 @runtime_sizeof -281622 +281787 @runtime_alignof -1560 +1561 @sizeof_pack -267 +502 @expr_stmt -160546 +160640 @routineexpr -2309113 +2232038 @type_operand -127928 +128003 @offsetofexpr -35356 +35377 @hasassignexpr @@ -597,11 +597,11 @@ @isbaseofexpr -19 +39 @isclassexpr -6 +215 @isconvtoexpr @@ -609,15 +609,15 @@ @isemptyexpr -5 +175 @isenumexpr -3 +23 @ispodexpr -3 +11 @ispolyexpr @@ -629,7 +629,7 @@ @typescompexpr -46285 +46312 @intaddrexpr @@ -637,11 +637,11 @@ @hastrivialdestructor -97 +105 @uuidof -856 +848 @aggregateliteral @@ -649,11 +649,11 @@ @delete_array_expr -1495 +1437 @new_array_expr -5364 +5310 @foldexpr @@ -661,59 +661,59 @@ @ctordirectinit -93264 +89645 @ctorvirtualinit -6904 +6636 @ctorfieldinit -209661 +201538 @ctordelegatinginit -741 +712 @dtordirectdestruct -30828 +30111 @dtorvirtualdestruct -2698 +2594 @dtorfielddestruct -32542 +31279 @static_cast -224735 +226064 @reinterpret_cast -31207 +30891 @const_cast -5847 +5643 @dynamic_cast -1094 +1051 @c_style_cast -4242732 +4244118 @lambdaexpr -12641 +12513 @param_ref -53208 +51144 @noopexpr @@ -745,7 +745,7 @@ @istrivialexpr -2565 +2512 @isstandardlayoutexpr @@ -753,7 +753,7 @@ @istriviallycopyableexpr -48 +46 @isliteraltypeexpr @@ -813,11 +813,11 @@ @isfinalexpr -2 +175 @noexceptexpr -449 +432 @builtinshufflevector @@ -825,11 +825,11 @@ @builtinchooseexpr -7028 +7032 @builtinaddressof -4388 +4218 @vec_fill @@ -845,67 +845,67 @@ @lambdacapture -21730 +21509 @stmt_expr -1284462 +1271443 @stmt_if -524558 +524866 @stmt_while -32907 +31630 @stmt_goto -111432 +111498 @stmt_label -85508 +85558 @stmt_return -1197201 +1154730 @stmt_block -1398281 +1348007 @stmt_end_test_while -149900 +149988 @stmt_for -32387 +32059 @stmt_switch_case -281530 +281695 @stmt_switch -55225 +55258 @stmt_asm -251715 +251863 @stmt_try_block -18964 +18228 @stmt_microsoft_try -171 +169 @stmt_decl -647378 +623601 @stmt_set_vla_size @@ -917,27 +917,27 @@ @stmt_assigned_goto -9137 +9142 @stmt_empty -103681 +102630 @stmt_continue -8603 +8608 @stmt_break -232406 +232543 @stmt_range_based_for -24 +23 @stmt_handler -21888 +21666 @stmt_constexpr_if @@ -945,51 +945,51 @@ @ppd_plain_include -321707 +309224 @ppd_define -349947 +336367 @ppd_if -171077 +164439 @ppd_ifdef -66823 +64230 @ppd_ifndef -91793 +88231 @ppd_elif -22768 +21885 @ppd_else -63638 +61169 @ppd_endif -329694 +316901 @ppd_undef -21152 +20331 @ppd_line -12523 +12530 @ppd_error -48 +46 @ppd_pragma -37040 +36665 @ppd_objc_import @@ -997,7 +997,7 @@ @ppd_include_next -97 +93 @ppd_warning @@ -1005,7 +1005,7 @@ @link_target -644 +619 @xmldtd @@ -1034,15 +1034,15 @@ compilations -10588 +10177 id -10588 +10177 cwd -12 +11 @@ -1056,7 +1056,7 @@ 1 2 -10588 +10177 @@ -1072,7 +1072,7 @@ 871 872 -12 +11 @@ -1082,11 +1082,11 @@ compilation_args -394124 +394355 id -4637 +4640 num @@ -1094,7 +1094,7 @@ arg -20097 +20109 @@ -1113,7 +1113,7 @@ 87 88 -3527 +3529 88 @@ -1149,7 +1149,7 @@ 86 87 -3529 +3531 87 @@ -1322,12 +1322,12 @@ 1 2 -19123 +19134 2 2575 -974 +975 @@ -1343,7 +1343,7 @@ 1 2 -19748 +19760 2 @@ -1358,19 +1358,19 @@ compilation_compiling_files -10588 +10177 id -10588 +10177 num -12 +11 file -5373 +5164 @@ -1384,7 +1384,7 @@ 1 2 -10588 +10177 @@ -1400,7 +1400,7 @@ 1 2 -10588 +10177 @@ -1416,7 +1416,7 @@ 871 872 -12 +11 @@ -1432,7 +1432,7 @@ 442 443 -12 +11 @@ -1448,17 +1448,17 @@ 1 2 -303 +292 2 3 -5044 +4849 3 14 -24 +23 @@ -1474,7 +1474,7 @@ 1 2 -5373 +5164 @@ -1484,23 +1484,23 @@ compilation_time -42255 +40616 id -10563 +10154 num -12 +11 kind -48 +46 seconds -12375 +11965 @@ -1514,7 +1514,7 @@ 1 2 -10563 +10154 @@ -1530,7 +1530,7 @@ 4 5 -10563 +10154 @@ -1544,14 +1544,19 @@ 12 +2 +3 +58 + + 3 4 -3160 +2792 4 5 -7403 +7302 @@ -1567,7 +1572,7 @@ 869 870 -12 +11 @@ -1583,7 +1588,7 @@ 4 5 -12 +11 @@ -1597,9 +1602,9 @@ 12 -1018 -1019 -12 +1024 +1025 +11 @@ -1615,7 +1620,7 @@ 869 870 -48 +46 @@ -1631,7 +1636,7 @@ 1 2 -48 +46 @@ -1645,24 +1650,24 @@ 12 -6 -7 -12 +7 +8 +11 -9 -10 -12 +10 +11 +11 -561 -562 -12 +560 +561 +11 -597 -598 -12 +591 +592 +11 @@ -1678,27 +1683,27 @@ 1 2 -7755 +7501 2 3 -2613 +2617 3 4 -1045 +759 4 -324 -936 +8 +899 -417 -614 -24 +8 +632 +186 @@ -1714,7 +1719,7 @@ 1 2 -12375 +11965 @@ -1730,12 +1735,17 @@ 1 2 -10490 +10305 2 3 -1884 +1635 + + +3 +4 +23 @@ -1745,23 +1755,23 @@ diagnostic_for -940397 +903906 diagnostic -940397 +73204 compilation -10223 +9826 file_number -12 +11 file_number_diagnostic_number -7208 +6929 @@ -1775,7 +1785,17 @@ 1 2 -940397 +9861 + + +2 +3 +60456 + + +118 +840 +2886 @@ -1791,7 +1811,7 @@ 1 2 -940397 +73204 @@ -1807,7 +1827,12 @@ 1 2 -940397 +73181 + + +2 +3 +23 @@ -1823,37 +1848,37 @@ 2 3 -24 +23 7 8 -5227 +5024 8 9 -1665 +1600 9 10 -218 +210 247 248 -2066 +1986 263 444 -802 +771 446 594 -218 +210 @@ -1869,7 +1894,7 @@ 1 2 -10223 +9826 @@ -1885,37 +1910,37 @@ 2 3 -24 +23 7 8 -5227 +5024 8 9 -1665 +1600 9 10 -218 +210 247 248 -2066 +1986 263 444 -802 +771 446 594 -218 +210 @@ -1931,7 +1956,7 @@ 6265 6266 -12 +11 @@ -1947,7 +1972,7 @@ 841 842 -12 +11 @@ -1963,7 +1988,7 @@ 593 594 -12 +11 @@ -1979,47 +2004,47 @@ 1 2 -2954 +2839 2 5 -656 +630 5 6 -1057 +1016 7 14 -571 +549 15 16 -60 +58 17 18 -632 +607 18 23 -486 +467 26 40 -583 +560 42 842 -206 +198 @@ -2035,52 +2060,52 @@ 4 9 -619 +595 10 11 -1057 +1016 14 27 -571 +549 30 31 -60 +58 34 35 -632 +607 36 45 -486 +467 52 79 -583 +560 84 85 -194 +186 254 255 -2893 +2780 272 842 -109 +105 @@ -2096,7 +2121,7 @@ 1 2 -7208 +6929 @@ -2106,19 +2131,19 @@ compilation_finished -10588 +10177 id -10588 +10177 cpu_seconds -8436 +7957 elapsed_seconds -182 +186 @@ -2132,7 +2157,7 @@ 1 2 -10588 +10177 @@ -2148,7 +2173,7 @@ 1 2 -10588 +10177 @@ -2164,17 +2189,17 @@ 1 2 -7184 +6730 2 3 -850 +712 3 -12 -401 +9 +514 @@ -2190,12 +2215,12 @@ 1 2 -8023 +7560 2 3 -413 +397 @@ -2211,67 +2236,62 @@ 1 2 -36 +35 2 3 -12 +35 3 4 -12 +11 -4 -5 -12 - - -8 -9 -12 +7 +8 +11 10 11 -12 +11 -20 -21 -12 +21 +22 +11 -22 -23 -12 +27 +28 +11 53 54 -12 +11 -124 -125 -12 +120 +121 +11 -134 -135 -12 +125 +126 +11 -230 -231 -12 +233 +234 +11 -258 -259 -12 +263 +264 +11 @@ -2287,67 +2307,62 @@ 1 2 -36 +35 2 3 -12 +35 3 4 -12 +11 -4 -5 -12 - - -8 -9 -12 +7 +8 +11 10 11 -12 +11 -20 -21 -12 +21 +22 +11 -22 -23 -12 +26 +27 +11 -49 -50 -12 +51 +52 +11 -100 -101 -12 +92 +93 +11 118 119 -12 +11 -172 -173 -12 +163 +164 +11 -217 -218 -12 +215 +216 +11 @@ -2357,23 +2372,23 @@ externalData -145 +140 id -72 +70 path -12 +11 column -24 +23 value -145 +140 @@ -2387,7 +2402,7 @@ 1 2 -72 +70 @@ -2403,7 +2418,7 @@ 2 3 -72 +70 @@ -2419,7 +2434,7 @@ 2 3 -72 +70 @@ -2435,7 +2450,7 @@ 6 7 -12 +11 @@ -2451,7 +2466,7 @@ 2 3 -12 +11 @@ -2467,7 +2482,7 @@ 12 13 -12 +11 @@ -2483,7 +2498,7 @@ 6 7 -24 +23 @@ -2499,7 +2514,7 @@ 1 2 -24 +23 @@ -2515,7 +2530,7 @@ 6 7 -24 +23 @@ -2531,7 +2546,7 @@ 1 2 -145 +140 @@ -2547,7 +2562,7 @@ 1 2 -145 +140 @@ -2563,7 +2578,7 @@ 1 2 -145 +140 @@ -2573,41 +2588,41 @@ snapshotDate -12 +11 snapshotDate -12 +11 sourceLocationPrefix -12 +11 prefix -12 +11 duplicateCode -185332 +185440 id -185332 +185440 relativePath -761 +762 equivClass -76596 +76641 @@ -2621,7 +2636,7 @@ 1 2 -185332 +185440 @@ -2637,7 +2652,7 @@ 1 2 -185332 +185440 @@ -2765,27 +2780,27 @@ 1 2 -20462 +20474 2 3 -32635 +32655 3 4 -10716 +10723 4 5 -6015 +6019 5 9 -5954 +5957 9 @@ -2806,7 +2821,7 @@ 1 2 -75730 +75775 2 @@ -3122,27 +3137,27 @@ tokens -39620249 +39643528 id -279171 +279335 offset -21169 +21181 beginLine -785436 +785898 beginColumn -1302 +1303 endLine -785436 +785898 endColumn @@ -3160,72 +3175,72 @@ 100 101 -8596 +8601 101 102 -27640 +27656 102 105 -22613 +22626 105 108 -24506 +24520 108 111 -13844 +13852 111 114 -23787 +23801 114 116 -22681 +22694 116 124 -23658 +23672 124 132 -21660 +21673 132 154 -21347 +21360 154 186 -21323 +21335 186 202 -23418 +23432 202 416 -20978 +20991 416 3446 -3115 +3117 @@ -3246,47 +3261,47 @@ 5 6 -109755 +109819 6 7 -15399 +15408 7 8 -28395 +28412 8 12 -23645 +23659 12 17 -22797 +22811 17 19 -18969 +18980 19 22 -22791 +22805 22 28 -21470 +21483 28 151 -14545 +14553 @@ -3302,42 +3317,42 @@ 2 26 -22933 +22946 26 31 -22318 +22331 31 32 -2642 +2643 32 33 -163572 +163668 33 51 -21310 +21323 51 61 -22472 +22485 61 80 -21058 +21071 80 132 -2863 +2865 @@ -3358,47 +3373,47 @@ 5 6 -109755 +109819 6 7 -15399 +15408 7 8 -28395 +28412 8 12 -23645 +23659 12 17 -22797 +22811 17 19 -18969 +18980 19 22 -22791 +22805 22 28 -21470 +21483 28 151 -14545 +14553 @@ -3414,42 +3429,42 @@ 2 26 -21667 +21679 26 31 -24352 +24366 31 32 -1622 +1623 32 33 -163861 +163957 33 54 -22103 +22116 54 63 -20942 +20954 63 82 -21488 +21501 82 133 -3133 +3135 @@ -3465,17 +3480,17 @@ 2 3 -4559 +4562 4 5 -1339 +1340 6 7 -2593 +2594 8 @@ -3485,37 +3500,37 @@ 11 12 -1609 +1610 13 23 -1855 +1856 24 62 -1622 +1623 64 130 -1646 +1647 141 250 -1597 +1598 251 982 -1591 +1592 986 45432 -1929 +1930 @@ -3531,17 +3546,17 @@ 2 3 -4559 +4562 4 5 -1339 +1340 6 7 -2593 +2594 8 @@ -3551,42 +3566,42 @@ 11 12 -1609 +1610 13 23 -1855 +1856 24 62 -1622 +1623 64 130 -1646 +1647 141 246 -1597 +1598 247 964 -1591 +1592 969 32541 -1591 +1592 32546 33841 -337 +338 @@ -3602,47 +3617,47 @@ 1 2 -5899 +5902 2 3 -3416 +3418 3 4 -1609 +1610 4 7 -1886 +1887 7 12 -1837 +1838 12 15 -1640 +1641 15 23 -1591 +1592 23 68 -1609 +1610 68 161 -1591 +1592 161 @@ -3663,17 +3678,17 @@ 2 3 -4559 +4562 4 5 -1339 +1340 6 7 -2593 +2594 8 @@ -3683,42 +3698,42 @@ 11 12 -1609 +1610 13 23 -1855 +1856 24 62 -1622 +1623 64 130 -1646 +1647 141 246 -1597 +1598 247 964 -1591 +1592 969 32541 -1591 +1592 32546 33841 -337 +338 @@ -3734,47 +3749,47 @@ 1 2 -5899 +5902 2 3 -3416 +3418 3 4 -1609 +1610 4 7 -1911 +1912 7 12 -1825 +1826 12 15 -1609 +1610 15 24 -1677 +1678 24 74 -1616 +1617 74 169 -1591 +1592 170 @@ -3795,37 +3810,37 @@ 1 2 -403939 +404176 2 3 -103118 +103179 3 4 -44274 +44300 4 6 -70568 +70610 6 8 -58457 +58491 8 13 -65861 +65900 13 138 -39217 +39240 @@ -3841,52 +3856,52 @@ 1 7 -64810 +64849 7 12 -64350 +64387 12 23 -60079 +60114 23 32 -36740 +36762 32 33 -267244 +267401 33 41 -62672 +62709 41 55 -61271 +61307 55 69 -61541 +61577 69 94 -59243 +59278 94 248 -47482 +47510 @@ -3902,47 +3917,47 @@ 1 5 -64429 +64467 5 9 -62611 +62647 9 15 -63016 +63053 15 29 -59870 +59905 29 32 -9205 +9210 32 33 -349310 +349515 33 37 -61959 +61996 37 42 -61400 +61436 42 122 -53633 +53664 @@ -3958,7 +3973,7 @@ 1 2 -785436 +785898 @@ -3974,47 +3989,47 @@ 1 5 -64294 +64332 5 9 -62611 +62647 9 15 -63133 +63170 15 29 -59735 +59770 29 32 -9254 +9259 32 33 -350355 +350560 33 37 -63588 +63625 37 43 -65241 +65279 43 123 -47224 +47251 @@ -4430,37 +4445,37 @@ 1 2 -403939 +404176 2 3 -103118 +103179 3 4 -44274 +44300 4 6 -70568 +70610 6 8 -58457 +58491 8 13 -65861 +65900 13 138 -39217 +39240 @@ -4476,52 +4491,52 @@ 1 7 -64810 +64849 7 12 -64350 +64387 12 23 -60079 +60114 23 32 -36740 +36762 32 33 -267244 +267401 33 41 -62672 +62709 41 55 -61271 +61307 55 69 -61541 +61577 69 94 -59243 +59278 94 248 -47482 +47510 @@ -4537,7 +4552,7 @@ 1 2 -785436 +785898 @@ -4553,47 +4568,47 @@ 1 5 -64429 +64467 5 9 -62611 +62647 9 15 -63016 +63053 15 29 -59870 +59905 29 32 -9205 +9210 32 33 -349310 +349515 33 37 -61959 +61996 37 42 -61400 +61436 42 122 -53633 +53664 @@ -4609,47 +4624,47 @@ 1 5 -64294 +64332 5 9 -62611 +62647 9 15 -63133 +63170 15 29 -59735 +59770 29 32 -9254 +9259 32 33 -350355 +350560 33 37 -63588 +63625 37 43 -65241 +65279 43 123 -47224 +47251 @@ -5039,23 +5054,23 @@ external_packages -133 +128 id -133 +128 namespace -12 +11 package_name -133 +128 version -133 +128 @@ -5069,7 +5084,7 @@ 1 2 -133 +128 @@ -5085,7 +5100,7 @@ 1 2 -133 +128 @@ -5101,7 +5116,7 @@ 1 2 -133 +128 @@ -5117,7 +5132,7 @@ 11 12 -12 +11 @@ -5133,7 +5148,7 @@ 11 12 -12 +11 @@ -5149,7 +5164,7 @@ 11 12 -12 +11 @@ -5165,7 +5180,7 @@ 1 2 -133 +128 @@ -5181,7 +5196,7 @@ 1 2 -133 +128 @@ -5197,7 +5212,7 @@ 1 2 -133 +128 @@ -5213,7 +5228,7 @@ 1 2 -133 +128 @@ -5229,7 +5244,7 @@ 1 2 -133 +128 @@ -5245,7 +5260,7 @@ 1 2 -133 +128 @@ -5255,15 +5270,15 @@ header_to_external_package -9093 +8740 fileid -9093 +8740 package -133 +128 @@ -5277,7 +5292,7 @@ 1 2 -9093 +8740 @@ -5293,42 +5308,42 @@ 1 2 -36 +35 2 3 -12 +11 15 16 -24 +23 63 64 -12 +11 71 72 -12 +11 85 86 -12 +11 243 244 -12 +11 251 252 -12 +11 @@ -6546,31 +6561,31 @@ locations_default -9664446 +9335283 id -9664446 +9335283 container -78275 +75237 startLine -161084 +154834 startColumn -6017 +5818 endLine -160902 +154658 endColumn -8169 +11182 @@ -6584,7 +6599,7 @@ 1 2 -9664446 +9335283 @@ -6600,7 +6615,7 @@ 1 2 -9664446 +9335283 @@ -6616,7 +6631,7 @@ 1 2 -9664446 +9335283 @@ -6632,7 +6647,7 @@ 1 2 -9664446 +9335283 @@ -6648,7 +6663,7 @@ 1 2 -9664446 +9335283 @@ -6664,62 +6679,62 @@ 1 2 -12752 +12257 2 19 -6625 +6368 19 25 -6090 +5818 25 31 -6066 +5830 31 41 -6491 +6204 41 54 -6138 +5854 54 72 -6175 +5877 72 -99 -5968 +98 +5690 -99 -137 -5944 +98 +136 +5702 -137 -221 -5895 +136 +216 +5690 -221 -431 -5871 +216 +417 +5655 -431 +417 19703 -4254 +4288 @@ -6735,62 +6750,62 @@ 1 2 -12752 +12257 2 15 -6503 +6251 15 20 -6758 +6496 20 25 -6102 +5842 25 32 -6710 +6461 32 41 -6284 +6052 41 53 -6321 +6064 53 70 -5932 +5690 70 96 -5908 +5678 96 152 -5883 +5667 152 -325 -5871 +322 +5643 -325 +324 8863 -3245 +3131 @@ -6806,62 +6821,62 @@ 1 2 -12752 +12257 2 4 -6722 +6461 4 8 -7087 +6812 8 11 -5895 +5632 11 14 -6418 +6099 14 18 -6880 +6601 18 23 -6394 +6134 23 29 -6455 +6227 29 37 -6260 +6029 37 50 -6224 +6052 50 78 -5944 +5737 78 -167 -1239 +168 +1191 @@ -6877,62 +6892,62 @@ 1 2 -12752 +12257 2 15 -6479 +6227 15 20 -6795 +6531 20 25 -6029 +5772 25 32 -6710 +6473 32 41 -6297 +6052 41 53 -6309 +6052 53 70 -6017 +5772 70 96 -5920 +5690 96 153 -5932 +5725 153 332 -5883 +5643 332 8863 -3148 +3038 @@ -6948,62 +6963,62 @@ 1 2 -12752 +12257 2 14 -6236 +5994 14 19 -6710 +6414 19 23 -6224 +5994 23 27 -6005 +5690 27 32 -6187 +5994 32 38 -6005 +5690 38 45 -6138 +5830 45 54 -5920 +5713 54 65 -5993 +5807 65 -79 -5883 +80 +5842 -79 -184 -4218 +80 +336 +4007 @@ -7019,62 +7034,62 @@ 1 2 -31193 +29982 2 3 -19802 +19034 3 4 -18234 +17527 4 5 -10260 +9861 5 6 -9129 +8775 6 7 -6734 +6473 7 9 -14344 +13787 9 13 -13943 +13390 13 30 -12350 +11871 30 112 -12119 +11637 112 -2168 -12083 +2116 +11614 -2193 +2135 6440 -887 +876 @@ -7090,42 +7105,42 @@ 1 2 -57268 +55046 2 3 -35496 +34119 3 4 -11341 +10901 4 5 -8983 +8635 5 8 -14794 +14220 8 26 -12363 +11871 26 115 -12095 +11637 115 6440 -8740 +8401 @@ -7141,57 +7156,57 @@ 1 2 -32287 +31034 2 3 -19693 +18929 3 4 -20544 +19747 4 5 -9737 +9359 5 6 -9384 +9020 6 7 -6856 +6590 7 9 -14612 +14033 9 13 -14028 +13495 13 27 -12436 +11953 27 60 -12132 +11637 60 153 -9372 +9032 @@ -7207,22 +7222,22 @@ 1 2 -119911 +115246 2 3 -18976 +18239 3 7 -13530 +13016 7 184 -8667 +8331 @@ -7238,57 +7253,57 @@ 1 2 -32311 +31057 2 3 -19584 +18824 3 4 -19024 +18286 4 5 -10247 +9850 5 6 -9409 +9043 6 7 -6637 +6379 7 9 -14636 +14068 9 13 -13700 +13168 13 28 -12144 +11673 28 -68 -12119 +69 +11813 -68 -190 -11269 +69 +258 +10668 @@ -7304,57 +7319,57 @@ 1 2 -948 +934 2 3 -1142 +1074 3 5 -534 +537 5 8 -547 +514 8 16 -474 +467 16 -38 -461 +37 +444 -39 -126 -461 +37 +119 +444 -135 -517 -461 +125 +511 +444 -553 -5009 -461 +518 +4987 +444 -5423 -19562 -461 +5021 +19113 +444 -23702 -199709 -60 +19590 +199744 +70 @@ -7370,47 +7385,47 @@ 1 2 -2589 +2500 2 3 -522 +525 3 6 -474 +455 6 15 -486 +467 15 55 -461 +444 59 -223 -461 +226 +444 229 -1196 -461 +1198 +444 -1266 +1275 2344 -461 +444 -2536 +2542 6440 -97 +93 @@ -7426,57 +7441,57 @@ 1 2 -984 +969 2 3 -1130 +1063 3 4 -291 +280 4 6 -498 +502 6 10 -486 +455 10 -21 -474 +20 +444 -21 -60 -461 +20 +55 +444 -60 -208 -461 +56 +195 +444 -209 -929 -461 +196 +829 +444 -957 -1965 -461 +851 +1958 +444 -1969 +1958 6490 -303 +327 @@ -7492,55 +7507,55 @@ 1 2 -984 +969 2 3 -1130 +1063 3 4 -291 +280 4 6 -498 +502 6 10 -486 +455 10 -21 -474 +20 +444 -21 -60 -461 +20 +55 +444 -60 -208 -461 +56 +195 +444 -209 -931 -461 +205 +828 +444 -958 -1966 -461 +851 +1962 +467 -1969 +1965 6462 303 @@ -7558,42 +7573,42 @@ 1 2 -2735 +2640 2 3 -522 +525 3 7 -547 +525 7 13 -474 +455 13 29 -498 +479 29 -51 -474 +54 +455 -51 -90 -461 +54 +109 +444 -91 +110 428 -303 +292 @@ -7609,62 +7624,62 @@ 1 2 -30670 +29480 2 3 -20240 +19455 3 4 -17979 +17281 4 5 -10430 +10025 5 6 -8898 +8553 6 7 -6868 +6601 7 9 -14368 +13811 9 13 -13992 +13437 13 30 -12302 +11824 30 111 -12144 +11649 111 -2100 -12071 +2058 +11602 -2100 +2083 6440 -936 +934 @@ -7680,42 +7695,42 @@ 1 2 -56758 +54555 2 3 -35654 +34271 3 4 -11341 +10901 4 5 -9105 +8751 5 7 -11949 +11474 7 19 -12338 +11859 19 76 -12083 +11614 76 6440 -11670 +11229 @@ -7731,22 +7746,22 @@ 1 2 -118792 +114171 2 3 -19267 +18508 3 7 -12983 +12502 7 46 -9858 +9476 @@ -7762,57 +7777,57 @@ 1 2 -31752 +30520 2 3 -20082 +19303 3 4 -20252 +19466 4 5 -9992 +9604 5 6 -9263 +8903 6 7 -6977 +6707 7 9 -14599 +14021 9 13 -14101 +13565 13 27 -12350 +11871 27 60 -12107 +11626 60 153 -9421 +9067 @@ -7828,57 +7843,57 @@ 1 2 -31801 +30567 2 3 -19973 +19197 3 4 -18745 +18017 4 5 -10490 +10083 5 6 -9263 +8903 6 7 -6710 +6449 7 9 -14526 +13963 9 13 -14174 +13612 13 29 -12350 +11871 29 71 -12132 +11602 71 -190 -10734 +258 +10387 @@ -7894,52 +7909,47 @@ 1 2 -2309 +4428 2 3 -1094 +1180 3 4 -607 +888 4 -7 -753 +6 +1004 -7 -17 -656 +6 +13 +841 -17 -49 -619 +13 +61 +841 -55 -236 -619 +61 +698 +841 -241 -4440 -619 +705 +10765 +841 -4617 -11969 -619 - - -12066 -25444 -267 +11014 +25447 +315 @@ -7955,47 +7965,42 @@ 1 2 -3257 +5106 2 3 -1033 +1285 3 4 -583 +1028 4 -9 -644 +7 +969 -9 -29 -619 +7 +33 +841 -29 -166 -619 +33 +376 +841 -172 -1667 -619 +387 +2684 +841 -1667 -2846 -619 - - -2870 +2688 6440 -170 +268 @@ -8011,52 +8016,47 @@ 1 2 -2334 +4463 2 3 -1106 +1180 3 4 -632 +899 4 -7 -741 +6 +1004 -7 -17 -632 +6 +14 +852 -17 -45 -619 +14 +57 +852 -45 -189 -619 +58 +510 +841 -192 -1191 -619 +518 +2401 +841 -1218 -2414 -619 - - -2469 +2415 4808 -243 +245 @@ -8072,42 +8072,42 @@ 1 2 -3367 +5141 2 3 -1130 +1343 3 4 -595 +1028 4 -11 -668 +7 +969 -11 +7 23 -632 +852 23 -40 -632 +47 +864 -40 -68 -632 +47 +81 +864 -68 -82 -510 +81 +83 +116 @@ -8123,52 +8123,47 @@ 1 2 -2334 +4463 2 3 -1106 +1180 3 4 -632 +911 4 -7 -741 +6 +993 -7 -17 -644 +6 +13 +841 -17 -46 -619 +13 +56 +841 -46 -194 -619 +56 +501 +841 -202 -1220 -619 +505 +2374 +841 -1252 -2470 -619 - - -2481 +2398 4808 -230 +268 @@ -8178,31 +8173,31 @@ locations_stmt -2176932 +2178211 id -2176932 +2178211 container -3078 +3080 startLine -296727 +296902 startColumn -1228 +1229 endLine -294872 +295045 endColumn -1493 +1494 @@ -8216,7 +8211,7 @@ 1 2 -2176932 +2178211 @@ -8232,7 +8227,7 @@ 1 2 -2176932 +2178211 @@ -8248,7 +8243,7 @@ 1 2 -2176932 +2178211 @@ -8264,7 +8259,7 @@ 1 2 -2176932 +2178211 @@ -8280,7 +8275,7 @@ 1 2 -2176932 +2178211 @@ -8493,7 +8488,7 @@ 38 48 -251 +252 48 @@ -8534,7 +8529,7 @@ 6 15 -251 +252 15 @@ -8681,37 +8676,37 @@ 1 2 -113847 +113914 2 3 -78993 +79039 3 4 -31327 +31345 4 6 -24942 +24957 6 16 -22619 +22632 16 129 -22275 +22288 129 222 -2722 +2723 @@ -8727,32 +8722,32 @@ 1 2 -175967 +176070 2 3 -51906 +51936 3 5 -22552 +22565 5 13 -22373 +22386 13 125 -22257 +22270 125 176 -1671 +1672 @@ -8768,32 +8763,32 @@ 1 2 -130943 +131019 2 3 -73506 +73549 3 4 -30767 +30785 4 7 -26583 +26598 7 16 -22312 +22325 16 45 -12615 +12623 @@ -8809,27 +8804,27 @@ 1 2 -192251 +192364 2 3 -47310 +47337 3 4 -21765 +21778 4 9 -23264 +23278 9 30 -12136 +12143 @@ -8845,32 +8840,32 @@ 1 2 -156444 +156536 2 3 -62371 +62408 3 4 -20782 +20794 4 9 -24659 +24674 9 30 -22398 +22411 30 73 -10071 +10077 @@ -9266,37 +9261,37 @@ 1 2 -116305 +116374 2 3 -72848 +72891 3 4 -31996 +32015 4 6 -25618 +25633 6 16 -23031 +23044 16 126 -22121 +22134 126 228 -2949 +2951 @@ -9312,27 +9307,27 @@ 1 2 -175604 +175707 2 3 -52066 +52096 3 5 -22207 +22220 5 14 -23375 +23389 14 173 -21617 +21630 @@ -9348,27 +9343,27 @@ 1 2 -194592 +194706 2 3 -42314 +42339 3 4 -20677 +20689 4 8 -22760 +22774 8 32 -14526 +14535 @@ -9384,32 +9379,32 @@ 1 2 -133173 +133251 2 3 -67871 +67910 3 4 -32611 +32630 4 7 -26503 +26518 7 16 -22183 +22196 16 46 -12529 +12536 @@ -9425,32 +9420,32 @@ 1 2 -156272 +156364 2 3 -62230 +62266 3 4 -21132 +21144 4 9 -23756 +23770 9 33 -22318 +22331 33 73 -9162 +9167 @@ -9830,15 +9825,15 @@ locations_expr -9745314 +9746017 id -9745314 +9746017 container -3559 +3563 startLine @@ -9868,7 +9863,7 @@ 1 2 -9745314 +9746017 @@ -9884,7 +9879,7 @@ 1 2 -9745314 +9746017 @@ -9900,7 +9895,7 @@ 1 2 -9745314 +9746017 @@ -9916,7 +9911,7 @@ 1 2 -9745314 +9746017 @@ -9932,7 +9927,7 @@ 1 2 -9745314 +9746017 @@ -9953,67 +9948,67 @@ 4 11 -280 +284 11 -36 -267 +37 +272 -36 -112 -270 +37 +114 +269 -112 -207 +114 +210 +269 + + +210 +328 268 -207 -326 +328 +498 268 -326 -493 -267 +499 +771 +269 -493 -760 -267 +772 +1223 +268 -760 -1208 -267 +1223 +1918 +268 -1210 -1899 -267 +1918 +3307 +268 -1900 -3251 -267 +3322 +7569 +268 -3258 -7330 -267 +7607 +160039 +268 -7359 -51115 -267 - - -51126 +170837 491727 -16 +3 @@ -10029,17 +10024,17 @@ 1 3 -300 +296 3 7 -315 +319 7 17 -271 +272 17 @@ -10049,47 +10044,47 @@ 35 59 -279 +278 59 88 -270 +271 88 138 -268 +271 138 -206 -267 +207 +271 -206 -336 +207 +339 268 -336 -525 +339 +532 268 -525 -946 -267 +532 +949 +268 -947 -2013 -267 +951 +2069 +268 -2019 +2076 142752 -248 +242 @@ -10105,67 +10100,67 @@ 1 3 -308 +307 3 7 -293 +296 7 17 -273 +274 17 -35 -267 +36 +283 -35 -51 -278 +36 +52 +287 -51 -63 -289 +52 +64 +297 -63 -73 -290 +64 +74 +279 -73 -83 +74 +84 +296 + + +84 +93 +270 + + +93 +106 282 -83 -92 -276 +106 +122 +271 -92 -104 -270 +122 +150 +268 -104 -120 -276 - - -120 -145 -270 - - -145 +150 330 -187 +153 @@ -10181,17 +10176,17 @@ 1 3 -300 +296 3 7 -312 +316 7 17 -274 +275 17 @@ -10201,17 +10196,17 @@ 35 59 -278 +277 59 89 -275 +277 89 139 -271 +273 139 @@ -10230,18 +10225,18 @@ 547 -971 -267 +973 +269 -972 -2152 -267 +975 +2167 +268 -2152 +2170 143560 -242 +239 @@ -10257,7 +10252,7 @@ 1 3 -278 +279 3 @@ -10267,57 +10262,57 @@ 7 19 -278 +281 19 -41 -268 +42 +275 -41 +42 60 -279 +272 60 -72 -267 +73 +294 -72 -83 -280 +73 +84 +277 -83 -94 -283 +84 +95 +291 -94 -105 -292 - - -105 -119 -278 - - -119 -136 +95 +106 279 -136 -162 -269 +106 +120 +282 -162 +120 +138 +275 + + +138 +166 +270 + + +166 416 -210 +190 @@ -10667,22 +10662,22 @@ 16130 -46279 +46280 29 -48722 -86671 +48729 +86681 29 -87010 -224371 +87033 +224378 29 -237409 -710014 +237411 +710028 6 @@ -10743,17 +10738,17 @@ 1424 -2061 +2063 29 -2064 -2425 +2066 +2429 29 -2427 -2796 +2429 +2797 22 @@ -11336,18 +11331,18 @@ 35 -20304 -51564 +20305 +51570 35 -54934 +54937 117747 35 -117846 -185890 +117863 +185908 35 @@ -11408,12 +11403,12 @@ 1983 -2458 +2459 35 -2468 -2637 +2470 +2640 32 @@ -11469,7 +11464,7 @@ 2070 -5989 +5990 35 @@ -11616,7 +11611,7 @@ 2067 -5989 +5990 35 @@ -11647,23 +11642,23 @@ numlines -544741 +523603 element_id -537168 +516324 num_lines -10272 +9873 num_code -7938 +7630 num_comment -4364 +4194 @@ -11677,12 +11672,12 @@ 1 2 -529679 +509126 2 7 -7488 +7197 @@ -11698,12 +11693,12 @@ 1 2 -529740 +509184 2 7 -7427 +7139 @@ -11719,12 +11714,12 @@ 1 2 -537083 +516242 2 3 -85 +81 @@ -11740,393 +11735,41 @@ 1 2 -4655 +4475 2 3 -1325 +1273 3 4 -765 +736 4 6 -838 +806 6 12 -814 +782 12 24 -778 +747 24 118 -778 +747 118 7658 -316 - - - - - - -num_lines -num_code - - -12 - - -1 -2 -4728 - - -2 -3 -1337 - - -3 -4 -802 - - -4 -6 -850 - - -6 -11 -923 - - -11 -18 -790 - - -18 -29 -790 - - -29 -32 -48 - - - - - - -num_lines -num_comment - - -12 - - -1 -2 -4716 - - -2 -3 -1337 - - -3 -4 -826 - - -4 -6 -838 - - -6 -10 -802 - - -10 -16 -899 - - -16 -26 -814 - - -26 -27 -36 - - - - - - -num_code -element_id - - -12 - - -1 -2 -3184 - - -2 -3 -1239 - - -3 -4 -632 - - -4 -6 -607 - - -6 -10 -619 - - -10 -21 -619 - - -21 -67 -595 - - -68 -7861 -437 - - - - - - -num_code -num_lines - - -12 - - -1 -2 -3209 - - -2 -3 -1264 - - -3 -4 -644 - - -4 -6 -607 - - -6 -10 -692 - - -10 -21 -644 - - -21 -34 -607 - - -34 -42 -267 - - - - - - -num_code -num_comment - - -12 - - -1 -2 -3233 - - -2 -3 -1227 - - -3 -4 -680 - - -4 -6 -619 - - -6 -10 -680 - - -10 -19 -668 - - -19 -28 -595 - - -28 -33 -230 - - - - - - -num_comment -element_id - - -12 - - -1 -2 -2030 - - -2 -3 -559 - - -3 -4 -328 - - -4 -7 -340 - - -7 -14 -340 - - -14 -38 -328 - - -39 -280 -328 - - -283 -35679 -109 - - - - - - -num_comment -num_lines - - -12 - - -1 -2 -2042 - - -2 -3 -571 - - -3 -5 -389 - - -5 -8 -364 - - -8 -18 -364 - - -18 -58 -328 - - -61 -118 303 @@ -12134,6 +11777,358 @@ +num_lines +num_code + + +12 + + +1 +2 +4545 + + +2 +3 +1285 + + +3 +4 +771 + + +4 +6 +817 + + +6 +11 +888 + + +11 +18 +759 + + +18 +29 +759 + + +29 +32 +46 + + + + + + +num_lines +num_comment + + +12 + + +1 +2 +4533 + + +2 +3 +1285 + + +3 +4 +794 + + +4 +6 +806 + + +6 +10 +771 + + +10 +16 +864 + + +16 +26 +782 + + +26 +27 +35 + + + + + + +num_code +element_id + + +12 + + +1 +2 +3061 + + +2 +3 +1191 + + +3 +4 +607 + + +4 +6 +584 + + +6 +10 +595 + + +10 +21 +595 + + +21 +67 +572 + + +68 +7861 +420 + + + + + + +num_code +num_lines + + +12 + + +1 +2 +3084 + + +2 +3 +1215 + + +3 +4 +619 + + +4 +6 +584 + + +6 +10 +666 + + +10 +21 +619 + + +21 +34 +584 + + +34 +42 +257 + + + + + + +num_code +num_comment + + +12 + + +1 +2 +3108 + + +2 +3 +1180 + + +3 +4 +654 + + +4 +6 +595 + + +6 +10 +654 + + +10 +19 +642 + + +19 +28 +572 + + +28 +33 +222 + + + + + + +num_comment +element_id + + +12 + + +1 +2 +1951 + + +2 +3 +537 + + +3 +4 +315 + + +4 +7 +327 + + +7 +14 +327 + + +14 +38 +315 + + +39 +280 +315 + + +283 +35679 +105 + + + + + + +num_comment +num_lines + + +12 + + +1 +2 +1963 + + +2 +3 +549 + + +3 +5 +373 + + +5 +8 +350 + + +8 +18 +350 + + +18 +58 +315 + + +61 +118 +292 + + + + + + num_comment num_code @@ -12143,37 +12138,37 @@ 1 2 -2042 +1963 2 3 -571 +549 3 5 -389 +373 5 8 -364 +350 8 17 -340 +327 17 52 -328 +315 56 108 -328 +315 @@ -12183,31 +12178,31 @@ diagnostics -76160 +73204 id -76160 +73204 severity -36 +35 error_tag -97 +93 error_message -121 +116 full_error_message -65948 +63389 location -145 +140 @@ -12221,7 +12216,7 @@ 1 2 -76160 +73204 @@ -12237,7 +12232,7 @@ 1 2 -76160 +73204 @@ -12253,7 +12248,7 @@ 1 2 -76160 +73204 @@ -12269,7 +12264,7 @@ 1 2 -76160 +73204 @@ -12285,7 +12280,7 @@ 1 2 -76160 +73204 @@ -12301,17 +12296,17 @@ 1 2 -12 +11 2 3 -12 +11 6262 6263 -12 +11 @@ -12327,12 +12322,12 @@ 1 2 -24 +23 6 7 -12 +11 @@ -12348,12 +12343,12 @@ 1 2 -24 +23 8 9 -12 +11 @@ -12369,17 +12364,17 @@ 1 2 -12 +11 2 3 -12 +11 5422 5423 -12 +11 @@ -12395,17 +12390,17 @@ 1 2 -12 +11 2 3 -12 +11 9 10 -12 +11 @@ -12421,32 +12416,32 @@ 1 2 -24 +23 2 3 -24 +23 5 6 -12 +11 417 418 -12 +11 841 842 -12 +11 4996 4997 -12 +11 @@ -12462,7 +12457,7 @@ 1 2 -97 +93 @@ -12478,12 +12473,12 @@ 1 2 -85 +81 3 4 -12 +11 @@ -12499,27 +12494,27 @@ 1 2 -36 +35 2 3 -24 +23 5 6 -12 +11 417 418 -12 +11 4996 4997 -12 +11 @@ -12535,17 +12530,17 @@ 1 2 -60 +58 2 3 -24 +23 5 6 -12 +11 @@ -12561,42 +12556,42 @@ 1 2 -24 +23 2 3 -24 +23 5 6 -12 +11 10 11 -12 +11 75 76 -12 +11 332 333 -12 +11 841 842 -12 +11 4996 4997 -12 +11 @@ -12612,7 +12607,7 @@ 1 2 -121 +116 @@ -12628,7 +12623,7 @@ 1 2 -121 +116 @@ -12644,37 +12639,37 @@ 1 2 -36 +35 2 3 -24 +23 5 6 -12 +11 10 11 -12 +11 75 76 -12 +11 332 333 -12 +11 4996 4997 -12 +11 @@ -12690,17 +12685,17 @@ 1 2 -85 +81 2 3 -24 +23 5 6 -12 +11 @@ -12716,12 +12711,12 @@ 1 2 -65936 +63377 841 842 -12 +11 @@ -12737,7 +12732,7 @@ 1 2 -65948 +63389 @@ -12753,7 +12748,7 @@ 1 2 -65948 +63389 @@ -12769,7 +12764,7 @@ 1 2 -65948 +63389 @@ -12785,7 +12780,7 @@ 1 2 -65948 +63389 @@ -12801,12 +12796,12 @@ 1 2 -133 +128 6254 6255 -12 +11 @@ -12822,7 +12817,7 @@ 1 2 -145 +140 @@ -12838,12 +12833,12 @@ 1 2 -133 +128 3 4 -12 +11 @@ -12859,12 +12854,12 @@ 1 2 -133 +128 5 6 -12 +11 @@ -12880,12 +12875,12 @@ 1 2 -133 +128 5414 5415 -12 +11 @@ -12895,27 +12890,27 @@ files -66167 +63599 id -66167 +63599 name -66167 +63599 simple -45148 +43397 ext -109 +105 fromSource -12 +11 @@ -12929,7 +12924,7 @@ 1 2 -66167 +63599 @@ -12945,7 +12940,7 @@ 1 2 -66167 +63599 @@ -12961,7 +12956,7 @@ 1 2 -66167 +63599 @@ -12977,7 +12972,7 @@ 1 2 -66167 +63599 @@ -12993,7 +12988,7 @@ 1 2 -66167 +63599 @@ -13009,7 +13004,7 @@ 1 2 -66167 +63599 @@ -13025,7 +13020,7 @@ 1 2 -66167 +63599 @@ -13041,7 +13036,7 @@ 1 2 -66167 +63599 @@ -13057,22 +13052,22 @@ 1 2 -34196 +32869 2 3 -6868 +6601 3 7 -3586 +3446 7 42 -498 +479 @@ -13088,22 +13083,22 @@ 1 2 -34196 +32869 2 3 -6868 +6601 3 7 -3586 +3446 7 42 -498 +479 @@ -13119,17 +13114,17 @@ 1 2 -40322 +38758 2 3 -4193 +4031 3 6 -632 +607 @@ -13145,7 +13140,7 @@ 1 2 -45148 +43397 @@ -13161,47 +13156,47 @@ 1 2 -12 +11 3 4 -12 +11 15 16 -12 +11 38 39 -12 +11 80 81 -12 +11 114 115 -12 +11 441 442 -12 +11 738 739 -12 +11 4013 4014 -12 +11 @@ -13217,47 +13212,47 @@ 1 2 -12 +11 3 4 -12 +11 15 16 -12 +11 38 39 -12 +11 80 81 -12 +11 114 115 -12 +11 441 442 -12 +11 738 739 -12 +11 4013 4014 -12 +11 @@ -13273,47 +13268,47 @@ 1 2 -12 +11 3 4 -12 +11 15 16 -12 +11 38 39 -12 +11 75 76 -12 +11 112 113 -12 +11 428 429 -12 +11 658 659 -12 +11 2838 2839 -12 +11 @@ -13329,7 +13324,7 @@ 1 2 -109 +105 @@ -13345,7 +13340,7 @@ 5443 5444 -12 +11 @@ -13361,7 +13356,7 @@ 5443 5444 -12 +11 @@ -13377,7 +13372,7 @@ 3714 3715 -12 +11 @@ -13393,7 +13388,7 @@ 9 10 -12 +11 @@ -13403,19 +13398,19 @@ folders -12107 +11637 id -12107 +11637 name -12107 +11637 simple -3476 +3341 @@ -13429,7 +13424,7 @@ 1 2 -12107 +11637 @@ -13445,7 +13440,7 @@ 1 2 -12107 +11637 @@ -13461,7 +13456,7 @@ 1 2 -12107 +11637 @@ -13477,7 +13472,7 @@ 1 2 -12107 +11637 @@ -13493,27 +13488,27 @@ 1 2 -1872 +1799 2 3 -741 +712 3 4 -498 +479 4 28 -279 +268 28 121 -85 +81 @@ -13529,27 +13524,27 @@ 1 2 -1872 +1799 2 3 -741 +712 3 4 -498 +479 4 28 -279 +268 28 121 -85 +81 @@ -13559,15 +13554,15 @@ containerparent -78250 +75214 parent -12107 +11637 child -78250 +75214 @@ -13581,42 +13576,42 @@ 1 2 -5506 +5293 2 3 -1568 +1507 3 4 -668 +642 4 6 -1118 +1074 6 10 -899 +864 10 14 -960 +923 14 30 -923 +888 30 153 -461 +444 @@ -13632,7 +13627,7 @@ 1 2 -78250 +75214 @@ -13642,23 +13637,23 @@ fileannotations -5688625 +5467887 id -5348 +5141 kind -24 +23 name -60186 +57851 value -49318 +47404 @@ -13672,12 +13667,12 @@ 1 2 -145 +140 2 3 -5202 +5001 @@ -13693,62 +13688,62 @@ 1 96 -401 +385 96 219 -401 +385 221 285 -401 +385 285 444 -401 +385 445 521 -401 +385 526 619 -425 +408 619 708 -401 +385 708 895 -401 +385 896 928 -97 +93 930 931 -1531 +1472 1076 1667 -401 +385 1689 2272 -85 +81 @@ -13764,57 +13759,57 @@ 1 108 -401 +385 108 269 -401 +385 269 356 -401 +385 371 630 -401 +385 630 729 -401 +385 733 948 -401 +385 948 1062 -401 +385 1079 1494 -279 +268 1495 1496 -1531 +1472 1496 1865 -401 +385 1963 4058 -328 +315 @@ -13830,12 +13825,12 @@ 428 429 -12 +11 440 441 -12 +11 @@ -13851,12 +13846,12 @@ 2 3 -12 +11 4949 4950 -12 +11 @@ -13872,12 +13867,12 @@ 1 2 -12 +11 4057 4058 -12 +11 @@ -13893,62 +13888,62 @@ 1 2 -9871 +9487 2 3 -6491 +6239 3 6 -4996 +4802 6 8 -4935 +4743 8 14 -4850 +4662 14 18 -4424 +4253 18 21 -4619 +4440 21 34 -4862 +4673 34 128 -4813 +4627 129 236 -4595 +4416 236 395 -4558 +4381 395 440 -1167 +1121 @@ -13964,7 +13959,7 @@ 1 2 -60186 +57851 @@ -13980,62 +13975,62 @@ 1 2 -11038 +10609 2 3 -8728 +8389 3 4 -2808 +2699 4 6 -4352 +4183 6 10 -5470 +5258 10 14 -3586 +3446 14 17 -4643 +4463 17 22 -4643 +4463 22 40 -4558 +4381 40 83 -4582 +4405 83 163 -4534 +4358 164 1933 -1239 +1191 @@ -14051,67 +14046,67 @@ 1 2 -7524 +7232 2 5 -2419 +2325 5 8 -3573 +3435 8 21 -3804 +3657 21 23 -2735 +2629 23 25 -4461 +4288 25 40 -3586 +3446 40 195 -3890 +3739 195 207 -3902 +3750 207 273 -4048 +3891 273 327 -3744 +3598 328 407 -4315 +4148 407 441 -1312 +1261 @@ -14127,12 +14122,12 @@ 1 2 -49306 +47393 2 3 -12 +11 @@ -14148,67 +14143,67 @@ 1 2 -7549 +7256 2 5 -2795 +2687 5 8 -3610 +3470 8 16 -4060 +3902 16 18 -3343 +3213 18 21 -4072 +3914 21 31 -4461 +4288 31 42 -4023 +3867 42 54 -3768 +3622 54 81 -3780 +3633 81 109 -3829 +3680 109 133 -3756 +3610 133 149 -267 +257 @@ -14218,15 +14213,15 @@ inmacroexpansion -57126596 +57160160 id -15544516 +15553649 inv -2493763 +2495229 @@ -14240,42 +14235,42 @@ 1 2 -3895411 +3897700 2 3 -2466113 +2467562 3 4 -2018102 +2019287 4 5 -1769908 +1770948 5 6 -1845270 +1846354 6 7 -884925 +885445 7 8 -1535759 +1536661 8 6265 -1129025 +1129688 @@ -14291,52 +14286,52 @@ 1 2 -651228 +651611 2 3 -350884 +351091 3 4 -145822 +145908 4 5 -276335 +276498 5 8 -230677 +230812 8 11 -202111 +202230 11 19 -210471 +210594 19 34 -192538 +192651 34 167 -188020 +188130 167 153127 -45673 +45699 @@ -14346,15 +14341,15 @@ affectedbymacroexpansion -35527526 +35548400 id -4083475 +4085874 inv -3282712 +3284641 @@ -14368,42 +14363,42 @@ 1 2 -1341531 +1342319 2 3 -719304 +719727 3 4 -682963 +683364 4 6 -320945 +321133 6 10 -313534 +313718 10 24 -308059 +308240 24 64 -309945 +310127 64 9803 -87190 +87242 @@ -14419,72 +14414,72 @@ 1 2 -253184 +253333 2 3 -209979 +210102 3 4 -202347 +202466 4 5 -258125 +258276 5 6 -301422 +301599 6 7 -247881 +248027 7 8 -231148 +231284 8 9 -228002 +228136 9 10 -182499 +182606 10 12 -285679 +285847 12 16 -297410 +297584 16 23 -275398 +275560 23 60 -248963 +249109 60 526 -60669 +60704 @@ -14494,23 +14489,23 @@ macroinvocations -40814994 +39320374 id -40814994 +39320374 macro_id -89374 +85906 location -836970 +804492 kind -24 +23 @@ -14524,7 +14519,7 @@ 1 2 -40814994 +39320374 @@ -14540,7 +14535,7 @@ 1 2 -40814994 +39320374 @@ -14556,7 +14551,7 @@ 1 2 -40814994 +39320374 @@ -14572,52 +14567,52 @@ 1 2 -19267 +18286 2 3 -16946 +16475 3 4 -3744 +3598 4 6 -7925 +7630 6 11 -7658 +7326 11 21 -7160 +6823 21 41 -6758 +6555 41 -104 -6710 +107 +6485 -104 -454 -6710 +107 +450 +6449 -454 -201153 -6491 +453 +201240 +6274 @@ -14633,37 +14628,37 @@ 1 2 -47483 +45640 2 3 -11803 +11345 3 4 -5895 +5667 4 6 -7682 +7384 6 13 -7403 +7115 13 65 -6734 +6473 65 3614 -2370 +2278 @@ -14679,12 +14674,12 @@ 1 2 -82566 +79362 2 3 -6807 +6543 @@ -14700,42 +14695,42 @@ 1 2 -314219 +299713 2 3 -186394 +180341 3 4 -44431 +42999 4 5 -58533 +56378 5 8 -67687 +65247 8 16 -64113 +61777 16 46 -64830 +62536 46 -262302 -36761 +262546 +35498 @@ -14751,12 +14746,12 @@ 1 2 -783044 +752659 2 353 -53925 +51833 @@ -14772,7 +14767,7 @@ 1 2 -836970 +804492 @@ -14788,12 +14783,12 @@ 37566 37567 -12 +11 -3319916 -3319917 -12 +3327545 +3327546 +11 @@ -14809,12 +14804,12 @@ 2199 2200 -12 +11 5713 5714 -12 +11 @@ -14830,12 +14825,12 @@ 6537 6538 -12 +11 62313 62314 -12 +11 @@ -14845,15 +14840,15 @@ macroparent -35822215 +34476404 id -35822215 +34476404 parent_id -27895299 +26856682 @@ -14867,7 +14862,7 @@ 1 2 -35822215 +34476404 @@ -14883,17 +14878,17 @@ 1 2 -21477676 +20687700 2 3 -5474478 +5262423 3 88 -943144 +906558 @@ -14903,15 +14898,15 @@ macrolocationbind -4016679 +4019039 id -2801506 +2803152 location -2004363 +2005541 @@ -14925,22 +14920,22 @@ 1 2 -2200726 +2202019 2 3 -339324 +339524 3 7 -231800 +231936 7 57 -29655 +29673 @@ -14956,22 +14951,22 @@ 1 2 -1602305 +1603246 2 3 -171008 +171108 3 8 -155504 +155595 8 723 -75546 +75590 @@ -14981,19 +14976,19 @@ macro_argument_unexpanded -104803767 +100941827 invocation -31131960 +30008413 argument_index -802 +771 text -345935 +332512 @@ -15007,22 +15002,22 @@ 1 2 -8804221 +8477672 2 3 -12965574 +12498009 3 4 -7092535 +6840222 4 67 -2269629 +2192508 @@ -15038,22 +15033,22 @@ 1 2 -8880284 +8550795 2 3 -13152746 +12678071 3 4 -6885304 +6640869 4 67 -2213625 +2138677 @@ -15069,17 +15064,17 @@ 51815 51816 -705 +677 52017 -186703 -60 +187640 +58 -770141 -2560947 -36 +773038 +2568177 +35 @@ -15095,17 +15090,17 @@ 2 3 -705 +677 13 1002 -60 +58 6617 19688 -36 +35 @@ -15121,62 +15116,62 @@ 1 2 -42535 +39868 2 3 -69291 +64826 3 4 -15621 +15435 4 5 -46376 +44296 5 8 -26513 +26980 8 12 -15560 +15447 12 16 -24531 +23275 16 22 -26403 +25414 22 -42 -26257 +41 +25075 -42 -113 -25978 +41 +101 +24970 -113 -51881 -25953 +101 +4363 +24958 -51881 -580841 -911 +4608 +581891 +1963 @@ -15192,17 +15187,17 @@ 1 2 -250082 +240378 2 3 -84450 +81173 3 9 -11402 +10960 @@ -15212,19 +15207,19 @@ macro_argument_expanded -104803767 +100941827 invocation -31131960 +30008413 argument_index -802 +771 text -209491 +201362 @@ -15238,22 +15233,22 @@ 1 2 -8804221 +8477672 2 3 -12965574 +12498009 3 4 -7092535 +6840222 4 67 -2269629 +2192508 @@ -15269,22 +15264,22 @@ 1 2 -12795323 +12315365 2 3 -11169279 +10770085 3 4 -5961987 +5753415 4 9 -1205370 +1169546 @@ -15300,17 +15295,17 @@ 51815 51816 -705 +677 52017 -186703 -60 +187640 +58 -770141 -2560947 -36 +773038 +2568177 +35 @@ -15326,17 +15321,17 @@ 1 2 -692 +666 2 75 -60 +58 867 13964 -48 +46 @@ -15352,62 +15347,57 @@ 1 2 -25820 +23871 2 3 -42583 +40791 3 4 -6758 +6636 4 -5 -15791 - - -5 6 -3367 +18450 6 7 -24555 +23743 7 9 -16702 +16475 9 15 -19146 +17597 15 31 -15851 +15984 31 -87 -15912 +86 +15108 -87 -393 -15742 +86 +365 +15225 -396 -1164221 -7257 +365 +1165688 +7478 @@ -15423,22 +15413,22 @@ 1 2 -105651 +101551 2 3 -87976 +84562 3 6 -15779 +15166 6 66 -85 +81 @@ -15448,19 +15438,19 @@ functions -3565918 +3552236 id -3565918 +3552236 name -315848 +303954 kind -85 +81 @@ -15474,7 +15464,7 @@ 1 2 -3565918 +3552236 @@ -15490,7 +15480,7 @@ 1 2 -3565918 +3552236 @@ -15506,27 +15496,27 @@ 1 2 -214682 +206387 2 3 -31266 +29924 3 5 -28360 +27435 5 13 -23826 +23100 13 -109484 -17711 +118759 +17106 @@ -15542,12 +15532,12 @@ 1 2 -314231 +302400 2 3 -1616 +1554 @@ -15563,37 +15553,37 @@ 32 33 -12 +11 -477 -478 -12 +478 +479 +11 2735 2736 -12 +11 -5928 -5929 -12 +6052 +6053 +11 -43779 -43780 -12 +43879 +43880 +11 -108979 -108980 -12 +109948 +109949 +11 -131406 -131407 -12 +140883 +140884 +11 @@ -15609,37 +15599,37 @@ 11 12 -12 +11 42 43 -12 +11 -228 -229 -12 +229 +230 +11 -1485 -1486 -12 +1494 +1495 +11 2735 2736 -12 +11 -2858 -2859 -12 +2879 +2880 +11 18756 18757 -12 +11 @@ -15649,15 +15639,15 @@ function_entry_point -1068501 +1030977 id -1065255 +1027857 entry_point -1068501 +1030977 @@ -15671,12 +15661,12 @@ 1 2 -1062313 +1025030 2 9 -2941 +2827 @@ -15692,7 +15682,7 @@ 1 2 -1068501 +1030977 @@ -15702,15 +15692,15 @@ function_return_type -3577065 +3562951 id -3565347 +3551686 return_type -1033588 +1048715 @@ -15724,12 +15714,12 @@ 1 2 -3554126 +3540901 2 6 -11220 +10784 @@ -15745,17 +15735,17 @@ 1 2 -319945 +309177 2 3 -649566 +677865 3 -81742 -64076 +82133 +61671 @@ -15765,60 +15755,60 @@ purefunctions -21018 +20805 id -21018 +20805 function_deleted -51251 +49379 id -51251 +49379 function_defaulted -9554 +9184 id -9554 +9184 fun_decls -3668324 +3646017 id -3657006 +3635139 function -3484737 +3469555 type_id -1026294 +1041634 name -281968 +271389 location -875943 +843835 @@ -15832,7 +15822,7 @@ 1 2 -3657006 +3635139 @@ -15848,12 +15838,12 @@ 1 2 -3646053 +3624611 2 6 -10952 +10527 @@ -15869,7 +15859,7 @@ 1 2 -3657006 +3635139 @@ -15885,7 +15875,7 @@ 1 2 -3657006 +3635139 @@ -15901,12 +15891,12 @@ 1 2 -3343699 +3333988 2 9 -141038 +135566 @@ -15922,12 +15912,12 @@ 1 2 -3466345 +3451876 2 6 -18392 +17678 @@ -15943,7 +15933,7 @@ 1 2 -3484737 +3469555 @@ -15959,12 +15949,12 @@ 1 2 -3389832 +3378332 2 9 -94905 +91222 @@ -15980,17 +15970,17 @@ 1 2 -305953 +295716 2 3 -648059 +676381 3 -87017 -72282 +87408 +69535 @@ -16006,17 +15996,17 @@ 1 2 -318972 +308231 2 3 -644096 +672572 3 -80918 -63225 +81309 +60830 @@ -16032,12 +16022,12 @@ 1 2 -956638 +974669 2 -7429 -69656 +7459 +66965 @@ -16053,17 +16043,17 @@ 1 2 -921129 +940538 2 5 -81642 +78474 5 -22296 -23522 +22349 +22621 @@ -16079,32 +16069,32 @@ 1 2 -169351 +162826 2 3 -32554 +31420 3 4 -18866 +17994 4 7 -25650 +24841 7 19 -21261 +20518 19 -109747 -14283 +119022 +13787 @@ -16120,32 +16110,32 @@ 1 2 -181155 +174172 2 3 -31412 +30099 3 4 -16654 +16171 4 7 -22623 +21862 7 -26 -21383 +25 +20366 -26 -109468 -8740 +25 +118743 +8716 @@ -16161,17 +16151,17 @@ 1 2 -246046 +236860 2 5 -23170 +22271 5 -56245 -12752 +60936 +12257 @@ -16187,27 +16177,27 @@ 1 2 -180486 +173599 2 3 -47823 +46213 3 4 -18040 +17340 4 8 -22696 +21815 8 -8793 -12922 +8910 +12420 @@ -16223,27 +16213,27 @@ 1 2 -589769 +567012 2 3 -147895 +142319 3 5 -69790 +67350 5 -179 -65766 +141 +63307 -179 -3027 -2723 +142 +3039 +3844 @@ -16259,22 +16249,22 @@ 1 2 -602727 +579468 2 3 -164743 +158514 3 9 -69753 +67747 9 -3027 -38718 +3039 +38103 @@ -16290,17 +16280,17 @@ 1 2 -773854 +744445 2 4 -68209 +65890 4 -1514 -33879 +1520 +33500 @@ -16316,12 +16306,12 @@ 1 2 -848299 +817018 2 134 -27643 +26816 @@ -16331,22 +16321,22 @@ fun_def -1296860 +1250592 id -1296860 +1250592 fun_specialized -6505 +6439 id -6505 +6439 @@ -16364,11 +16354,11 @@ fun_decl_specifiers -512313 +512614 id -274687 +274848 name @@ -16386,17 +16376,17 @@ 1 2 -72048 +72090 2 3 -167651 +167750 3 4 -34987 +35007 @@ -16583,26 +16573,26 @@ fun_decl_empty_throws -1416734 +1471304 fun_decl -1416734 +1471304 fun_decl_noexcept -16569 +15937 fun_decl -15693 +15096 constant -16435 +15809 @@ -16616,12 +16606,12 @@ 1 2 -14818 +14255 2 3 -875 +841 @@ -16637,12 +16627,12 @@ 1 2 -16301 +15680 2 3 -133 +128 @@ -16652,26 +16642,26 @@ fun_decl_empty_noexcept -364559 +350681 fun_decl -364559 +350681 fun_decl_typedef_type -194 +186 fun_decl -194 +186 typedeftype_id -97 +93 @@ -16685,7 +16675,7 @@ 1 2 -194 +186 @@ -16701,7 +16691,7 @@ 2 3 -97 +93 @@ -16711,19 +16701,19 @@ param_decl_bind -4830661 +4766932 id -4830661 +4766932 index -389 +373 fun_decl -3158896 +3153051 @@ -16737,7 +16727,7 @@ 1 2 -4830661 +4766932 @@ -16753,7 +16743,7 @@ 1 2 -4830661 +4766932 @@ -16769,57 +16759,57 @@ 2 3 -158 +151 4 10 -24 +23 15 44 -24 +23 115 191 -24 +23 263 337 -24 +23 422 615 -24 +23 885 1215 -24 +23 1695 2656 -24 +23 4907 -13240 -24 +13252 +23 -34828 -76062 -24 +34902 +76574 +23 -259854 -259855 -12 +269844 +269845 +11 @@ -16835,57 +16825,57 @@ 2 3 -158 +151 4 10 -24 +23 15 44 -24 +23 115 191 -24 +23 263 337 -24 +23 422 615 -24 +23 885 1215 -24 +23 1695 2656 -24 +23 4907 -13240 -24 +13252 +23 -34828 -76062 -24 +34902 +76574 +23 -259854 -259855 -12 +269844 +269845 +11 @@ -16901,22 +16891,22 @@ 1 2 -2234266 +2258317 2 3 -501246 +486913 3 4 -262445 +252985 4 33 -160938 +154834 @@ -16932,22 +16922,22 @@ 1 2 -2234266 +2258317 2 3 -501246 +486913 3 4 -262445 +252985 4 33 -160938 +154834 @@ -16957,27 +16947,27 @@ var_decls -5602108 +5518014 id -5579181 +5495954 variable -5340611 +5266618 type_id -2038268 +2068405 name -139592 +134175 location -1358468 +1305755 @@ -16991,7 +16981,7 @@ 1 2 -5579181 +5495954 @@ -17007,12 +16997,12 @@ 1 2 -5556716 +5474337 2 7 -22465 +21616 @@ -17028,7 +17018,7 @@ 1 2 -5579181 +5495954 @@ -17044,12 +17034,12 @@ 1 2 -5579132 +5495907 2 3 -48 +46 @@ -17065,12 +17055,12 @@ 1 2 -5146145 +5079674 2 9 -194466 +186943 @@ -17086,12 +17076,12 @@ 1 2 -5290709 +5218605 2 7 -49902 +48012 @@ -17107,12 +17097,12 @@ 1 2 -5321866 +5248600 2 3 -18745 +18017 @@ -17128,12 +17118,12 @@ 1 2 -5225490 +5155963 2 9 -115121 +110654 @@ -17149,22 +17139,22 @@ 1 2 -1580700 +1627085 2 3 -244952 +236522 3 -9 -154629 +10 +155430 -9 -5708 -57986 +10 +5721 +49367 @@ -17180,22 +17170,22 @@ 1 2 -1607080 +1652441 2 3 -234777 +226741 3 -11 -155359 +13 +156353 -11 -5254 -41052 +13 +5267 +32869 @@ -17211,17 +17201,17 @@ 1 2 -1850925 +1888086 2 5 -162458 +156341 5 770 -24884 +23977 @@ -17237,17 +17227,17 @@ 1 2 -1771751 +1811867 2 4 -165132 +159052 4 3604 -101384 +97485 @@ -17263,42 +17253,42 @@ 1 2 -58861 +56530 2 3 -20860 +20039 3 4 -12290 +11801 4 6 -12715 +12268 6 10 -11524 +11088 10 22 -10673 +10270 22 255 -10490 +10083 263 -149390 -2176 +159500 +2091 @@ -17314,37 +17304,37 @@ 1 2 -62277 +59814 2 3 -20118 +19314 3 4 -13359 +12841 4 6 -11949 +11532 6 11 -11499 +11077 11 28 -10515 +10095 28 -148426 -9871 +158536 +9499 @@ -17360,32 +17350,32 @@ 1 2 -84973 +81606 2 3 -18149 +17445 3 4 -9676 +9347 4 7 -11706 +11275 7 28 -10576 +10165 28 -111448 -4510 +120730 +4335 @@ -17401,32 +17391,32 @@ 1 2 -80329 +77212 2 3 -21273 +20448 3 4 -7780 +7478 4 7 -12423 +11941 7 21 -10563 +10154 21 9993 -7220 +6940 @@ -17442,22 +17432,22 @@ 1 2 -1008108 +967927 2 3 -144734 +139422 3 6 -124044 +119546 6 -114124 -81581 +123459 +78860 @@ -17473,22 +17463,22 @@ 1 2 -1060320 +1018112 2 3 -107961 +103970 3 6 -111863 +107943 6 -113877 -78323 +123212 +75728 @@ -17504,17 +17494,17 @@ 1 2 -1166129 +1119863 2 3 -93045 +89797 3 -104379 -99293 +113652 +96095 @@ -17530,12 +17520,12 @@ 1 2 -1348524 +1296197 2 52 -9943 +9558 @@ -17545,11 +17535,11 @@ var_def -2573394 +2477557 id -2573394 +2477557 @@ -17619,19 +17609,19 @@ type_decls -1469165 +1413769 id -1469165 +1413769 type_id -1433996 +1379965 location -1203571 +1156868 @@ -17645,7 +17635,7 @@ 1 2 -1469165 +1413769 @@ -17661,7 +17651,7 @@ 1 2 -1469165 +1413769 @@ -17677,12 +17667,12 @@ 1 2 -1408431 +1355392 2 24 -25564 +24572 @@ -17698,12 +17688,12 @@ 1 2 -1409866 +1356771 2 24 -24130 +23194 @@ -17719,12 +17709,12 @@ 1 2 -1142582 +1098234 2 469 -60988 +58633 @@ -17740,12 +17730,12 @@ 1 2 -1144223 +1099812 2 469 -59347 +57056 @@ -17755,45 +17745,45 @@ type_def -1035654 +995467 id -1035654 +995467 type_decl_top -297552 +286006 type_decl -297552 +286006 namespace_decls -151627 +145743 id -151627 +145743 namespace_id -8485 +8155 location -135422 +130167 bodylocation -135787 +130518 @@ -17807,7 +17797,7 @@ 1 2 -151627 +145743 @@ -17823,7 +17813,7 @@ 1 2 -151627 +145743 @@ -17839,7 +17829,7 @@ 1 2 -151627 +145743 @@ -17855,42 +17845,42 @@ 1 2 -4011 +3855 2 3 -1191 +1145 3 4 -449 +432 4 7 -717 +689 7 13 -656 +630 13 27 -656 +630 28 163 -644 +619 172 3743 -158 +151 @@ -17906,42 +17896,42 @@ 1 2 -4011 +3855 2 3 -1191 +1145 3 4 -449 +432 4 7 -717 +689 7 13 -656 +630 13 27 -656 +630 28 163 -644 +619 172 3743 -158 +151 @@ -17957,42 +17947,42 @@ 1 2 -4011 +3855 2 3 -1191 +1145 3 4 -449 +432 4 7 -717 +689 7 13 -656 +630 13 27 -656 +630 28 163 -644 +619 172 3742 -158 +151 @@ -18008,12 +17998,12 @@ 1 2 -126135 +121240 2 8 -9287 +8927 @@ -18029,12 +18019,12 @@ 1 2 -126135 +121240 2 8 -9287 +8927 @@ -18050,12 +18040,12 @@ 1 2 -134595 +129373 2 3 -826 +794 @@ -18071,12 +18061,12 @@ 1 2 -126900 +121976 2 11 -8886 +8541 @@ -18092,12 +18082,12 @@ 1 2 -126900 +121976 2 9 -8886 +8541 @@ -18113,12 +18103,12 @@ 1 2 -135349 +130097 2 5 -437 +420 @@ -18128,19 +18118,19 @@ usings -320601 +308161 id -320601 +308161 element_id -49002 +47101 location -26464 +25437 @@ -18154,7 +18144,7 @@ 1 2 -320601 +308161 @@ -18170,7 +18160,7 @@ 1 2 -320601 +308161 @@ -18186,17 +18176,17 @@ 1 2 -41234 +39634 2 4 -4169 +4007 4 127 -3598 +3458 @@ -18212,17 +18202,17 @@ 1 2 -41234 +39634 2 4 -4169 +4007 4 127 -3598 +3458 @@ -18238,22 +18228,22 @@ 1 2 -20033 +19256 2 3 -2540 +2442 3 21 -2054 +1974 21 347 -1835 +1764 @@ -18269,22 +18259,22 @@ 1 2 -20033 +19256 2 3 -2540 +2442 3 21 -2054 +1974 21 347 -1835 +1764 @@ -18294,15 +18284,15 @@ using_container -485187 +466360 parent -8667 +8331 child -301029 +289348 @@ -18316,47 +18306,47 @@ 1 2 -3379 +3248 2 3 -559 +537 3 6 -668 +642 6 15 -656 +630 16 31 -705 +677 31 143 -291 +280 178 179 -1397 +1343 179 182 -765 +736 182 501 -243 +233 @@ -18372,22 +18362,22 @@ 1 2 -217478 +209039 2 3 -55773 +53609 3 6 -22659 +21780 6 47 -5117 +4919 @@ -18397,23 +18387,23 @@ static_asserts -132358 +131017 id -132358 +131017 condition -132358 +131017 message -30094 +29789 location -16938 +16766 @@ -18427,7 +18417,7 @@ 1 2 -132358 +131017 @@ -18443,7 +18433,7 @@ 1 2 -132358 +131017 @@ -18459,7 +18449,7 @@ 1 2 -132358 +131017 @@ -18475,7 +18465,7 @@ 1 2 -132358 +131017 @@ -18491,7 +18481,7 @@ 1 2 -132358 +131017 @@ -18507,7 +18497,7 @@ 1 2 -132358 +131017 @@ -18523,32 +18513,32 @@ 1 2 -22395 +22168 2 3 -428 +424 3 4 -2867 +2837 4 11 -1463 +1448 12 17 -2379 +2355 17 513 -560 +554 @@ -18564,32 +18554,32 @@ 1 2 -22395 +22168 2 3 -428 +424 3 4 -2867 +2837 4 11 -1463 +1448 12 17 -2379 +2355 17 513 -560 +554 @@ -18605,12 +18595,12 @@ 1 2 -27912 +27629 2 33 -2181 +2159 @@ -18626,32 +18616,32 @@ 1 2 -2939 +2909 2 3 -2801 +2772 3 4 -1344 +1330 5 6 -3776 +3738 6 7 -177 +176 14 15 -2062 +2042 16 @@ -18661,12 +18651,12 @@ 17 18 -3447 +3412 19 52 -349 +345 @@ -18682,32 +18672,32 @@ 1 2 -2939 +2909 2 3 -2801 +2772 3 4 -1344 +1330 5 6 -3776 +3738 6 7 -177 +176 14 15 -2062 +2042 16 @@ -18717,12 +18707,12 @@ 17 18 -3447 +3412 19 52 -349 +345 @@ -18738,22 +18728,22 @@ 1 2 -4475 +4429 2 3 -6063 +6002 3 4 -6208 +6145 4 7 -191 +189 @@ -18763,23 +18753,23 @@ params -4803552 +4749557 id -4779409 +4724692 function -3118318 +3117564 index -389 +373 type_id -1865866 +1906163 @@ -18793,12 +18783,12 @@ 1 2 -4778668 +4723979 2 69 -741 +712 @@ -18814,7 +18804,7 @@ 1 2 -4779409 +4724692 @@ -18830,12 +18820,12 @@ 1 2 -4757747 +4702211 2 7 -21662 +22481 @@ -18851,22 +18841,22 @@ 1 2 -2207692 +2232786 2 3 -482853 +472740 3 4 -264220 +254691 4 33 -163552 +157346 @@ -18882,22 +18872,22 @@ 1 2 -2207692 +2232786 2 3 -482853 +472740 3 4 -264220 +254691 4 33 -163552 +157346 @@ -18913,22 +18903,22 @@ 1 2 -2314438 +2335471 2 3 -493113 +480884 3 5 -270978 +262941 5 20 -39787 +38267 @@ -18944,57 +18934,57 @@ 2 3 -158 +151 4 10 -24 +23 15 44 -24 +23 115 191 -24 +23 263 337 -24 +23 422 615 -24 +23 883 1209 -24 +23 1659 2596 -24 +23 4880 -13455 -24 +13467 +23 -35189 -74910 -24 +35263 +75722 +23 -256345 -256346 -12 +266636 +266637 +11 @@ -19010,57 +19000,57 @@ 2 3 -158 +151 4 10 -24 +23 15 44 -24 +23 115 191 -24 +23 263 337 -24 +23 422 615 -24 +23 883 1209 -24 +23 1659 2596 -24 +23 4880 -13455 -24 +13467 +23 -35189 -74910 -24 +35263 +75722 +23 -256516 -256517 -12 +266807 +266808 +11 @@ -19076,57 +19066,57 @@ 1 2 -158 +151 3 7 -24 +23 8 20 -24 +23 36 40 -24 +23 42 45 -24 +23 61 105 -24 +23 173 257 -24 +23 406 661 -24 +23 1178 2710 -24 +23 -7491 -16702 -24 +7492 +16795 +23 -135733 -135734 -12 +145286 +145287 +11 @@ -19142,22 +19132,22 @@ 1 2 -1495095 +1547921 2 3 -199608 +193171 3 -13 -141671 +18 +144002 -13 -5275 -29491 +18 +5288 +21067 @@ -19173,22 +19163,22 @@ 1 2 -1517195 +1569164 2 3 -187245 +181276 3 -17 -140893 +25 +143324 -17 -4798 -20532 +25 +4811 +12397 @@ -19204,12 +19194,12 @@ 1 2 -1751170 +1795906 2 33 -114695 +110257 @@ -19219,15 +19209,15 @@ overrides -161127 +159494 new -126169 +124890 old -15666 +15507 @@ -19241,12 +19231,12 @@ 1 2 -91218 +90293 2 3 -34944 +34590 3 @@ -19267,37 +19257,37 @@ 1 2 -8232 +8148 2 3 -2043 +2022 3 4 -883 +874 4 5 -1278 +1265 5 10 -1245 +1233 10 43 -1179 +1167 44 218 -804 +795 @@ -19307,19 +19297,19 @@ membervariables -329658 +325582 id -325099 +321201 type_id -145086 +139772 name -59068 +56776 @@ -19333,12 +19323,12 @@ 1 2 -320637 +316912 2 7 -4461 +4288 @@ -19354,7 +19344,7 @@ 1 2 -325099 +321201 @@ -19370,22 +19360,22 @@ 1 2 -118391 +113949 2 3 -13396 +12934 3 11 -10989 +10656 11 -1212 -2309 +1715 +2231 @@ -19401,17 +19391,17 @@ 1 2 -125916 +121310 2 3 -9883 +9511 3 266 -9287 +8950 @@ -19427,32 +19417,32 @@ 1 2 -31217 +29971 2 3 -9056 +8705 3 4 -5944 +5725 4 6 -4485 +4311 6 15 -4534 +4358 15 -1317 -3829 +1953 +3704 @@ -19468,32 +19458,32 @@ 1 2 -38256 +36736 2 3 -7524 +7232 3 4 -4035 +3891 4 7 -4765 +4592 7 -319 -4437 +291 +4264 -323 +318 605 -48 +58 @@ -19674,19 +19664,19 @@ localvariables -527180 +521836 id -527101 +521758 type_id -48087 +47599 name -76217 +75444 @@ -19700,12 +19690,12 @@ 1 2 -527022 +521680 2 3 -79 +78 @@ -19721,7 +19711,7 @@ 1 2 -527101 +521758 @@ -19737,32 +19727,32 @@ 1 2 -26759 +26487 2 3 -6841 +6772 3 4 -2893 +2864 4 6 -4119 +4077 6 13 -3862 +3823 13 4908 -3611 +3575 @@ -19778,22 +19768,22 @@ 1 2 -36072 +35706 2 3 -4969 +4919 3 5 -4323 +4279 5 1158 -2722 +2694 @@ -19809,32 +19799,32 @@ 1 2 -43526 +43085 2 3 -13096 +12963 3 4 -5140 +5088 4 7 -6821 +6752 7 31 -5767 +5708 31 6112 -1865 +1846 @@ -19850,17 +19840,17 @@ 1 2 -64564 +63910 2 3 -6472 +6406 3 819 -5180 +5127 @@ -19870,11 +19860,11 @@ autoderivation -19759 +19559 var -19759 +19559 derivation_type @@ -19892,7 +19882,7 @@ 1 2 -19759 +19559 @@ -19938,31 +19928,31 @@ enumconstants -94487 +94097 id -94487 +94097 parent -7539 +8031 index -7678 +7600 type_id -7394 +7887 name -73851 +73102 location -76856 +76077 @@ -19976,7 +19966,7 @@ 1 2 -94487 +94097 @@ -19992,7 +19982,7 @@ 1 2 -94487 +94097 @@ -20008,7 +19998,7 @@ 1 2 -94487 +94097 @@ -20024,7 +20014,7 @@ 1 2 -94487 +94097 @@ -20040,7 +20030,7 @@ 1 2 -94487 +94097 @@ -20056,47 +20046,47 @@ 1 2 -1041 +1598 2 3 -830 +822 3 4 -2484 +2459 4 5 -586 +580 5 6 -586 +580 6 -8 -540 +9 +730 -8 -13 -659 +9 +16 +613 -13 -46 -573 +16 +392 +606 -46 +426 1166 -237 +39 @@ -20112,47 +20102,42 @@ 1 2 -1041 +1598 2 3 -843 +835 3 4 -2530 +2505 4 5 -579 +574 5 6 -593 +587 6 -8 -527 +9 +704 -8 -13 -632 +9 +17 +626 -13 -49 -566 - - -50 +17 1166 -224 +600 @@ -20168,12 +20153,12 @@ 1 2 -6788 +7287 2 3 -751 +743 @@ -20189,47 +20174,42 @@ 1 2 -1041 +1598 2 3 -843 +835 3 4 -2530 +2505 4 5 -579 +574 5 6 -593 +587 6 -8 -527 +9 +704 -8 -13 -632 +9 +17 +626 -13 -49 -566 - - -50 +17 1166 -224 +600 @@ -20245,47 +20225,47 @@ 1 2 -1080 +1637 2 3 -843 +835 3 4 -2484 +2459 4 5 -586 +580 5 6 -566 +561 6 -8 -514 +9 +704 -8 -13 -659 +9 +16 +613 -13 -46 -566 +16 +427 +606 -46 +466 1166 -237 +32 @@ -20301,47 +20281,47 @@ 1 2 -2642 +2616 2 3 -942 +932 3 4 -935 +926 4 7 -579 +574 7 10 -698 +691 10 11 -355 +352 11 12 -560 +554 12 30 -606 +600 30 -1166 -355 +1253 +352 @@ -20357,47 +20337,47 @@ 1 2 -2642 +2616 2 3 -942 +932 3 4 -935 +926 4 7 -579 +574 7 9 -685 +678 9 11 -369 +365 11 12 -560 +554 12 29 -606 +600 29 -1145 -355 +1232 +352 @@ -20413,47 +20393,47 @@ 1 2 -2642 +2616 2 3 -942 +932 3 4 -935 +926 4 7 -579 +574 7 9 -685 +678 9 11 -369 +365 11 12 -560 +554 12 28 -606 +600 28 -1123 -355 +1210 +352 @@ -20469,47 +20449,47 @@ 1 2 -2642 +2616 2 3 -942 +932 3 4 -935 +926 4 7 -579 +574 7 10 -698 +691 10 11 -355 +352 11 12 -560 +554 12 28 -606 +600 28 674 -355 +352 @@ -20525,47 +20505,47 @@ 1 2 -2642 +2616 2 3 -942 +932 3 4 -935 +926 4 7 -579 +574 7 10 -698 +691 10 11 -355 +352 11 12 -560 +554 12 28 -606 +600 28 774 -355 +352 @@ -20581,47 +20561,47 @@ 1 2 -1041 +1598 2 3 -810 +802 3 4 -2458 +2433 4 5 -566 +561 5 6 -566 +561 6 -8 -520 +9 +704 -8 -13 -639 +9 +16 +600 -13 -46 -560 +16 +470 +593 -46 +479 1166 -230 +32 @@ -20637,7 +20617,7 @@ 1 2 -7388 +7881 137 @@ -20658,47 +20638,42 @@ 1 2 -1041 +1598 2 3 -823 +815 3 4 -2504 +2479 4 5 -560 +554 5 6 -573 +567 6 -8 -507 +9 +678 -8 -13 -612 +9 +17 +613 -13 -51 -560 - - -52 +17 1166 -210 +580 @@ -20714,47 +20689,42 @@ 1 2 -1041 +1598 2 3 -823 +815 3 4 -2504 +2479 4 5 -560 +554 5 6 -573 +567 6 -8 -507 +9 +678 -8 -13 -612 +9 +17 +613 -13 -51 -560 - - -52 +17 1166 -210 +580 @@ -20770,47 +20740,47 @@ 1 2 -1080 +1637 2 3 -823 +815 3 4 -2458 +2433 4 5 -566 +561 5 6 -547 +541 6 -8 -494 +9 +678 -8 -13 -639 +9 +16 +600 -13 -47 -560 +16 +470 +593 -48 +621 1166 -224 +26 @@ -20826,17 +20796,17 @@ 1 2 -66396 +65723 2 3 -6927 +6856 3 239 -527 +521 @@ -20852,17 +20822,17 @@ 1 2 -67049 +66369 2 3 -6274 +6210 3 239 -527 +521 @@ -20878,12 +20848,12 @@ 1 2 -68762 +68065 2 13 -5088 +5036 @@ -20899,17 +20869,17 @@ 1 2 -61941 +61313 2 3 -11382 +11267 3 239 -527 +521 @@ -20925,12 +20895,12 @@ 1 2 -71346 +70623 2 23 -2504 +2479 @@ -20946,12 +20916,12 @@ 1 2 -71531 +70773 2 229 -5325 +5304 @@ -20967,12 +20937,12 @@ 1 2 -71643 +70884 2 229 -5213 +5193 @@ -20988,12 +20958,12 @@ 1 2 -73211 +72469 2 17 -3644 +3607 @@ -21009,17 +20979,17 @@ 1 2 -66535 +65828 2 3 -10090 +9994 3 229 -230 +254 @@ -21035,12 +21005,12 @@ 1 2 -76685 +75907 2 27 -171 +169 @@ -21050,31 +21020,31 @@ builtintypes -559 +537 id -559 +537 name -559 +537 kind -559 +537 size -85 +81 sign -36 +35 alignment -60 +58 @@ -21088,7 +21058,7 @@ 1 2 -559 +537 @@ -21104,7 +21074,7 @@ 1 2 -559 +537 @@ -21120,7 +21090,7 @@ 1 2 -559 +537 @@ -21136,7 +21106,7 @@ 1 2 -559 +537 @@ -21152,7 +21122,7 @@ 1 2 -559 +537 @@ -21168,7 +21138,7 @@ 1 2 -559 +537 @@ -21184,7 +21154,7 @@ 1 2 -559 +537 @@ -21200,7 +21170,7 @@ 1 2 -559 +537 @@ -21216,7 +21186,7 @@ 1 2 -559 +537 @@ -21232,7 +21202,7 @@ 1 2 -559 +537 @@ -21248,7 +21218,7 @@ 1 2 -559 +537 @@ -21264,7 +21234,7 @@ 1 2 -559 +537 @@ -21280,7 +21250,7 @@ 1 2 -559 +537 @@ -21296,7 +21266,7 @@ 1 2 -559 +537 @@ -21312,7 +21282,7 @@ 1 2 -559 +537 @@ -21328,37 +21298,37 @@ 1 2 -12 +11 2 3 -12 +11 4 5 -12 +11 6 7 -12 +11 9 10 -12 +11 11 12 -12 +11 13 14 -12 +11 @@ -21374,37 +21344,37 @@ 1 2 -12 +11 2 3 -12 +11 4 5 -12 +11 6 7 -12 +11 9 10 -12 +11 11 12 -12 +11 13 14 -12 +11 @@ -21420,37 +21390,37 @@ 1 2 -12 +11 2 3 -12 +11 4 5 -12 +11 6 7 -12 +11 9 10 -12 +11 11 12 -12 +11 13 14 -12 +11 @@ -21466,12 +21436,12 @@ 1 2 -24 +23 3 4 -60 +58 @@ -21487,12 +21457,12 @@ 1 2 -60 +58 2 3 -24 +23 @@ -21508,17 +21478,17 @@ 6 7 -12 +11 12 13 -12 +11 28 29 -12 +11 @@ -21534,17 +21504,17 @@ 6 7 -12 +11 12 13 -12 +11 28 29 -12 +11 @@ -21560,17 +21530,17 @@ 6 7 -12 +11 12 13 -12 +11 28 29 -12 +11 @@ -21586,12 +21556,12 @@ 5 6 -24 +23 7 8 -12 +11 @@ -21607,7 +21577,7 @@ 5 6 -36 +35 @@ -21623,27 +21593,27 @@ 4 5 -12 +11 7 8 -12 +11 10 11 -12 +11 12 13 -12 +11 13 14 -12 +11 @@ -21659,27 +21629,27 @@ 4 5 -12 +11 7 8 -12 +11 10 11 -12 +11 12 13 -12 +11 13 14 -12 +11 @@ -21695,27 +21665,27 @@ 4 5 -12 +11 7 8 -12 +11 10 11 -12 +11 12 13 -12 +11 13 14 -12 +11 @@ -21731,12 +21701,12 @@ 1 2 -12 +11 2 3 -48 +46 @@ -21752,7 +21722,7 @@ 3 4 -60 +58 @@ -21762,23 +21732,23 @@ derivedtypes -4572495 +4651908 id -4572495 +4651908 name -2240442 +2328554 kind -97 +93 type_id -2743147 +2780308 @@ -21792,7 +21762,7 @@ 1 2 -4572495 +4651908 @@ -21808,7 +21778,7 @@ 1 2 -4572495 +4651908 @@ -21824,7 +21794,7 @@ 1 2 -4572495 +4651908 @@ -21840,17 +21810,17 @@ 1 2 -1640327 +1709696 2 3 -479376 +500222 3 -42612 -120737 +43371 +118634 @@ -21866,12 +21836,12 @@ 1 2 -2240417 +2328530 2 3 -24 +23 @@ -21887,17 +21857,17 @@ 1 2 -1640607 +1709965 2 3 -479097 +499954 3 -42594 -120737 +43353 +118634 @@ -21913,42 +21883,42 @@ 21 22 -12 +11 61 62 -12 +11 2051 2052 -12 +11 -25122 -25123 -12 +27346 +27347 +11 -42664 -42665 -12 +43423 +43424 +11 -53936 -53937 -12 +58521 +58522 +11 -97759 -97760 -12 +102765 +102766 +11 -154522 -154523 -12 +163929 +163930 +11 @@ -21964,42 +21934,42 @@ 1 2 -12 +11 13 14 -12 +11 38 39 -12 +11 1152 1153 -12 +11 -13367 -13368 -12 +15027 +15028 +11 -36098 -36099 -12 +39331 +39332 +11 -50248 -50249 -12 +53789 +53790 +11 -83386 -83387 -12 +89933 +89934 +11 @@ -22015,42 +21985,42 @@ 12 13 -12 +11 21 22 -12 +11 969 970 -12 +11 -25122 -25123 -12 +27346 +27347 +11 -42664 -42665 -12 +43423 +43424 +11 -53936 -53937 -12 +58521 +58522 +11 -97431 -97432 -12 +102434 +102435 +11 -154522 -154523 -12 +163929 +163930 +11 @@ -22066,22 +22036,22 @@ 1 2 -1661856 +1683160 2 3 -405550 +392781 3 4 -615674 +646083 4 202 -60064 +58283 @@ -22097,22 +22067,22 @@ 1 2 -1663206 +1684457 2 3 -405380 +392618 3 4 -614495 +644949 4 198 -60064 +58283 @@ -22128,22 +22098,22 @@ 1 2 -1663534 +1684784 2 3 -406814 +393985 3 4 -614446 +644902 4 7 -58350 +56635 @@ -22153,19 +22123,19 @@ pointerishsize -3358396 +3426426 id -3358396 +3426426 size -24 +23 alignment -12 +11 @@ -22179,7 +22149,7 @@ 1 2 -3358396 +3426426 @@ -22195,7 +22165,7 @@ 1 2 -3358396 +3426426 @@ -22211,12 +22181,12 @@ 21 22 -12 +11 -276244 -276245 -12 +293219 +293220 +11 @@ -22232,7 +22202,7 @@ 1 2 -24 +23 @@ -22246,9 +22216,9 @@ 12 -276265 -276266 -12 +293240 +293241 +11 @@ -22264,7 +22234,7 @@ 2 3 -12 +11 @@ -22274,23 +22244,23 @@ arraysizes -18830 +18099 id -18830 +18099 num_elements -2394 +2301 bytesize -2783 +2675 alignment -85 +81 @@ -22304,7 +22274,7 @@ 1 2 -18830 +18099 @@ -22320,7 +22290,7 @@ 1 2 -18830 +18099 @@ -22336,7 +22306,7 @@ 1 2 -18830 +18099 @@ -22352,37 +22322,37 @@ 1 2 -182 +175 2 3 -1422 +1367 3 4 -85 +81 4 5 -182 +175 5 13 -182 +175 13 25 -182 +175 38 116 -158 +151 @@ -22398,27 +22368,27 @@ 1 2 -1762 +1694 2 3 -243 +233 3 4 -133 +128 4 6 -182 +175 6 11 -72 +70 @@ -22434,27 +22404,27 @@ 1 2 -1774 +1705 2 3 -255 +245 3 4 -158 +151 4 7 -182 +175 7 8 -24 +23 @@ -22470,42 +22440,42 @@ 1 2 -170 +163 2 3 -1556 +1495 3 4 -133 +128 4 6 -218 +210 6 9 -218 +210 9 17 -218 +210 17 53 -218 +210 55 75 -48 +46 @@ -22521,22 +22491,22 @@ 1 2 -2115 +2033 2 3 -389 +373 3 6 -243 +233 6 7 -36 +35 @@ -22552,22 +22522,22 @@ 1 2 -2176 +2091 2 3 -303 +292 3 5 -255 +245 5 7 -48 +46 @@ -22583,37 +22553,37 @@ 17 18 -12 +11 18 19 -12 +11 33 34 -12 +11 50 51 -12 +11 181 182 -12 +11 389 390 -12 +11 861 862 -12 +11 @@ -22629,37 +22599,37 @@ 4 5 -12 +11 5 6 -12 +11 13 14 -12 +11 16 17 -12 +11 39 40 -12 +11 40 41 -12 +11 190 191 -12 +11 @@ -22675,37 +22645,37 @@ 1 2 -12 +11 2 3 -12 +11 14 15 -12 +11 17 18 -12 +11 41 42 -12 +11 53 54 -12 +11 191 192 -12 +11 @@ -22715,15 +22685,15 @@ typedefbase -1919913 +1867884 id -1919913 +1867884 type_id -899600 +871937 @@ -22737,7 +22707,7 @@ 1 2 -1919913 +1867884 @@ -22753,22 +22723,22 @@ 1 2 -698168 +676919 2 3 -93312 +90264 3 6 -72975 +70856 6 -5423 -35144 +5485 +33897 @@ -22778,23 +22748,23 @@ decltypes -45841 +44063 id -45841 +44063 expr -43325 +41644 base_type -6479 +6227 parentheses_would_change_meaning -24 +23 @@ -22808,7 +22778,7 @@ 1 2 -45841 +44063 @@ -22824,7 +22794,7 @@ 1 2 -45841 +44063 @@ -22840,7 +22810,7 @@ 1 2 -45841 +44063 @@ -22856,12 +22826,12 @@ 1 2 -40809 +39225 2 3 -2516 +2418 @@ -22877,12 +22847,12 @@ 1 2 -40809 +39225 2 3 -2516 +2418 @@ -22898,7 +22868,7 @@ 1 2 -43325 +41644 @@ -22914,17 +22884,17 @@ 1 2 -3622 +3482 2 3 -2552 +2453 3 277 -303 +292 @@ -22940,22 +22910,22 @@ 1 2 -2540 +2442 2 3 -3282 +3154 3 12 -522 +502 13 2445 -133 +128 @@ -22971,7 +22941,7 @@ 1 2 -6479 +6227 @@ -22987,12 +22957,12 @@ 8 9 -12 +11 1082 1083 -12 +11 @@ -23008,12 +22978,12 @@ 8 9 -12 +11 3556 3557 -12 +11 @@ -23029,12 +22999,12 @@ 8 9 -12 +11 525 526 -12 +11 @@ -23044,19 +23014,19 @@ usertypes -4363319 +4337028 id -4363319 +4337028 name -899429 +917472 kind -133 +128 @@ -23070,7 +23040,7 @@ 1 2 -4363319 +4337028 @@ -23086,7 +23056,7 @@ 1 2 -4363319 +4337028 @@ -23102,22 +23072,22 @@ 1 2 -596127 +606962 2 3 -199888 +203676 3 8 -67589 +69886 8 -31201 -35824 +32070 +36947 @@ -23133,12 +23103,12 @@ 1 2 -842355 +861619 2 10 -57074 +55852 @@ -23154,57 +23124,57 @@ 23 24 -12 +11 372 373 -12 +11 773 774 -12 +11 -1526 -1527 -12 +1856 +1857 +11 -4123 -4124 -12 +4195 +4196 +11 14604 14605 -12 +11 -17528 -17529 -12 +17544 +17545 +11 -20287 -20288 -12 +20425 +20426 +11 -75247 -75248 -12 +75551 +75552 +11 -81118 -81119 -12 +90575 +90576 +11 -143330 -143331 -12 +145253 +145254 +11 @@ -23220,52 +23190,52 @@ 16 17 -12 +11 38 39 -24 +23 404 405 -12 +11 548 549 -12 +11 -776 -777 -12 +777 +778 +11 -2846 -2847 -12 +2848 +2849 +11 4545 4546 -12 +11 -9121 -9122 -12 +9129 +9130 +11 11659 11660 -12 +11 -49218 -49219 -12 +53824 +53825 +11 @@ -23275,19 +23245,19 @@ usertypesize -1364814 +1420908 id -1364814 +1420908 size -1641 +1577 alignment -97 +93 @@ -23301,7 +23271,7 @@ 1 2 -1364814 +1420908 @@ -23317,7 +23287,7 @@ 1 2 -1364814 +1420908 @@ -23333,52 +23303,52 @@ 1 2 -474 +455 2 3 -218 +210 3 4 -72 +70 4 5 -109 +105 5 8 -121 +116 8 12 -109 +105 12 16 -133 +128 16 36 -133 +128 37 170 -133 +128 260 -86086 -133 +95028 +128 @@ -23394,17 +23364,17 @@ 1 2 -1349 +1297 2 3 -194 +186 3 6 -97 +93 @@ -23420,42 +23390,42 @@ 1 2 -12 +11 3 4 -12 +11 7 8 -12 +11 50 51 -12 +11 54 55 -12 +11 -1916 -1917 -12 +2246 +2247 +11 -9656 -9657 -12 +9717 +9718 +11 -100584 -100585 -12 +109526 +109527 +11 @@ -23471,37 +23441,37 @@ 1 2 -24 +23 3 4 -12 +11 8 9 -12 +11 12 13 -12 +11 17 18 -12 +11 25 26 -12 +11 106 107 -12 +11 @@ -23511,26 +23481,26 @@ usertype_final -1331 +1317 id -1331 +1317 usertype_uuid -4897 +4847 id -4897 +4847 uuid -4897 +4847 @@ -23544,7 +23514,7 @@ 1 2 -4897 +4847 @@ -23560,7 +23530,7 @@ 1 2 -4897 +4847 @@ -23570,15 +23540,15 @@ mangled_name -4359684 +4333558 id -4359684 +4333558 mangled_name -532986 +514256 @@ -23592,7 +23562,7 @@ 1 2 -4359684 +4333558 @@ -23608,32 +23578,32 @@ 1 2 -325269 +310895 2 3 -68246 +66497 3 4 -35958 +35217 4 -8 -45307 +7 +39225 -8 -34 -40237 +7 +23 +38664 -34 -8470 -17967 +23 +8589 +23755 @@ -23643,59 +23613,59 @@ is_pod_class -1041477 +1104649 id -1041477 +1104649 is_standard_layout_class -1118962 +1180366 id -1118962 +1180366 is_complete -1345984 +1398952 id -1345984 +1398952 is_class_template -246617 +238660 id -246617 +238660 class_instantiation -1108921 +1176522 to -1107195 +1174863 from -72513 +72363 @@ -23709,12 +23679,12 @@ 1 2 -1105566 +1173297 2 4 -1628 +1565 @@ -23730,47 +23700,47 @@ 1 2 -21601 +21289 2 3 -12897 +12771 3 4 -7488 +7314 4 5 -4789 +4942 5 7 -5871 +5994 7 11 -6503 +6438 11 20 -5555 +5585 20 -89 -5470 +87 +5456 -89 -2079 -2334 +87 +3629 +2570 @@ -23780,19 +23750,19 @@ class_template_argument -2800063 +3135757 type_id -1339675 +1428725 index -1361 +1308 arg_type -921287 +904899 @@ -23806,27 +23776,27 @@ 1 2 -593732 +586000 2 3 -438105 +428957 3 4 -175599 +258501 4 7 -108629 +129501 7 113 -23607 +25764 @@ -23842,22 +23812,22 @@ 1 2 -619710 +613658 2 3 -445691 +442173 3 4 -187999 +272382 4 113 -86274 +100511 @@ -23873,37 +23843,37 @@ 1 2 -12 +11 2 3 -863 +829 3 26 -109 +105 29 64 -109 +105 69 -427 -109 +435 +105 -594 -8438 -109 +616 +9263 +105 -11951 -101100 -48 +13601 +119714 +46 @@ -23919,37 +23889,37 @@ 1 2 -12 +11 2 3 -863 +829 3 14 -121 +116 14 26 -109 +105 29 -147 -109 +148 +105 -191 -3560 -109 +198 +3591 +105 -11321 -39550 -36 +11582 +41130 +35 @@ -23965,22 +23935,27 @@ 1 2 -571096 +550198 2 3 -205784 +200100 3 -5 -75369 +4 +54918 -5 -5259 -69036 +4 +10 +70727 + + +10 +11421 +28954 @@ -23996,17 +23971,253 @@ 1 2 -805922 +786767 2 3 -96011 +98069 3 22 -19353 +20062 + + + + + + + + +class_template_argument_value +362635 + + +type_id +233565 + + +index +163 + + +arg_value +345447 + + + + +type_id +index + + +12 + + +1 +2 +209845 + + +2 +3 +14512 + + +3 +14 +9207 + + + + + + +type_id +arg_value + + +12 + + +1 +2 +197436 + + +2 +3 +17971 + + +3 +22 +17527 + + +24 +173 +630 + + + + + + +index +type_id + + +12 + + +8 +9 +58 + + +20 +21 +11 + + +25 +26 +11 + + +206 +207 +11 + + +389 +390 +11 + + +552 +553 +11 + + +1312 +1313 +11 + + +5393 +5394 +11 + + +5423 +5424 +11 + + +9668 +9669 +11 + + + + + + +index +arg_value + + +12 + + +8 +9 +58 + + +20 +21 +11 + + +42 +43 +11 + + +311 +312 +11 + + +514 +515 +11 + + +715 +716 +11 + + +1585 +1586 +11 + + +6302 +6303 +11 + + +8160 +8161 +11 + + +11875 +11876 +11 + + + + + + +arg_value +type_id + + +12 + + +1 +2 +328387 + + +2 +4 +17059 + + + + + + +arg_value +index + + +12 + + +1 +2 +345447 @@ -24016,15 +24227,15 @@ is_proxy_class_for -50120 +49017 id -50120 +49017 templ_param_id -50120 +49017 @@ -24038,7 +24249,7 @@ 1 2 -50120 +49017 @@ -24054,7 +24265,7 @@ 1 2 -50120 +49017 @@ -24064,19 +24275,19 @@ type_mentions -1699359 +1682135 id -1699359 +1682135 type_id -68077 +67387 location -1668455 +1651543 kind @@ -24094,7 +24305,7 @@ 1 2 -1699359 +1682135 @@ -24110,7 +24321,7 @@ 1 2 -1699359 +1682135 @@ -24126,7 +24337,7 @@ 1 2 -1699359 +1682135 @@ -24142,37 +24353,37 @@ 1 2 -30463 +30154 2 3 -12463 +12337 3 4 -3684 +3646 4 7 -6142 +6080 7 13 -5213 +5160 13 35 -5259 +5206 35 9490 -4850 +4801 @@ -24188,37 +24399,37 @@ 1 2 -30463 +30154 2 3 -12463 +12337 3 4 -3684 +3646 4 7 -6142 +6080 7 13 -5213 +5160 13 35 -5259 +5206 35 9490 -4850 +4801 @@ -24234,12 +24445,12 @@ 1 2 -66818 +66141 2 3 -1258 +1246 @@ -24255,12 +24466,12 @@ 1 2 -1637892 +1621291 2 5 -30562 +30252 @@ -24276,12 +24487,12 @@ 1 2 -1637892 +1621291 2 5 -30562 +30252 @@ -24297,7 +24508,7 @@ 1 2 -1668455 +1651543 @@ -24370,26 +24581,26 @@ is_function_template -1058083 +1023581 id -1058083 +1023581 function_instantiation -739463 +719194 to -739463 +719194 from -136103 +134923 @@ -24403,7 +24614,7 @@ 1 2 -739463 +719194 @@ -24419,37 +24630,32 @@ 1 2 -63018 +64125 2 3 -32396 +31385 3 4 -8193 +7898 4 -5 -9299 +6 +12467 -5 -10 -10940 +6 +15 +10434 -10 -57 -10223 - - -58 +15 645 -2030 +8611 @@ -24459,19 +24665,19 @@ function_template_argument -1910796 +1981225 function_id -1112422 +1088560 index -243 +233 arg_type -369847 +359386 @@ -24485,22 +24691,22 @@ 1 2 -634796 +600045 2 3 -361033 +302330 3 -5 -84645 +4 +131242 -5 +4 21 -31947 +54941 @@ -24516,22 +24722,22 @@ 1 2 -657966 +618530 2 3 -332393 +293520 3 -5 -90905 +4 +116683 -5 +4 21 -31156 +59825 @@ -24547,102 +24753,102 @@ 4 5 -12 +11 7 8 -12 +11 17 18 -12 +11 39 40 -12 +11 65 66 -12 +11 152 153 -12 +11 -238 -239 -12 +241 +242 +11 -325 -326 -12 +328 +329 +11 -422 -423 -12 +425 +426 +11 -520 -521 -12 +523 +524 +11 -754 -755 -12 +758 +759 +11 -1007 -1008 -12 +1011 +1012 +11 -1259 -1260 -12 +1520 +1521 +11 -1514 -1515 -12 +1701 +1702 +11 -2559 -2560 -12 +2566 +2567 +11 -2804 -2805 -12 +2917 +2918 +11 -4818 -4819 -12 +5686 +5687 +11 -13309 -13310 -12 +17602 +17603 +11 -40569 -40570 -12 +42858 +42859 +11 -84931 -84932 -12 +88286 +88287 +11 @@ -24658,102 +24864,102 @@ 4 5 -12 +11 7 8 -12 +11 14 15 -12 +11 22 23 -12 +11 32 33 -12 +11 54 55 -12 +11 -57 -58 -12 +60 +61 +11 -61 -62 -12 +62 +63 +11 -75 -76 -12 +78 +79 +11 -90 -91 -12 +91 +92 +11 -137 -138 -12 +140 +141 +11 214 215 -12 +11 -238 -239 -12 +242 +243 +11 -316 -317 -12 +317 +318 +11 -517 -518 -12 +521 +522 +11 -695 -696 -12 +700 +701 +11 -1468 -1469 -12 +1491 +1492 +11 -3652 -3653 -12 +3698 +3699 +11 -8773 -8774 -12 +8798 +8799 +11 -17388 -17389 -12 +17653 +17654 +11 @@ -24769,27 +24975,27 @@ 1 2 -249547 +242738 2 3 -48698 +46902 3 6 -29783 +28756 6 -19 -27996 +20 +27704 -19 -906 -13821 +20 +1989 +13285 @@ -24805,17 +25011,238 @@ 1 2 -341230 +331740 2 5 -28129 +27131 5 -10 -486 +12 +514 + + + + + + + + +function_template_argument_value +209892 + + +function_id +113037 + + +index +163 + + +arg_value +181755 + + + + +function_id +index + + +12 + + +1 +2 +107207 + + +2 +14 +5830 + + + + + + +function_id +arg_value + + +12 + + +1 +2 +89610 + + +2 +3 +17106 + + +3 +113 +6321 + + + + + + +index +function_id + + +12 + + +3 +4 +70 + + +5 +6 +11 + + +6 +7 +11 + + +111 +112 +11 + + +441 +442 +11 + + +857 +858 +11 + + +2136 +2137 +11 + + +2428 +2429 +11 + + +4217 +4218 +11 + + + + + + +index +arg_value + + +12 + + +5 +6 +70 + + +7 +8 +11 + + +8 +9 +11 + + +157 +158 +11 + + +405 +406 +11 + + +973 +974 +11 + + +2523 +2524 +11 + + +4848 +4849 +11 + + +6604 +6605 +11 + + + + + + +arg_value +function_id + + +12 + + +1 +2 +153712 + + +2 +3 +27949 + + +3 +4 +93 + + + + + + +arg_value +index + + +12 + + +1 +2 +181755 @@ -24825,26 +25252,26 @@ is_variable_template -19778 +19011 id -19778 +19011 variable_instantiation -31837 +38057 to -31837 +38057 from -6734 +6929 @@ -24858,7 +25285,7 @@ 1 2 -31837 +38057 @@ -24874,37 +25301,37 @@ 1 2 -2382 +2383 2 3 -2030 +2033 3 4 -449 +432 4 5 -692 +782 5 9 -534 +560 9 -29 -534 +21 +525 -42 -214 -109 +24 +286 +210 @@ -24914,11 +25341,11 @@ variable_template_argument -5529 +5499 variable_id -843 +848 index @@ -24926,7 +25353,7 @@ arg_type -4257 +4214 @@ -24940,12 +25367,12 @@ 1 2 -692 +685 2 3 -112 +123 3 @@ -24966,12 +25393,12 @@ 1 2 -369 +371 2 3 -125 +130 3 @@ -24981,12 +25408,12 @@ 4 6 -72 +71 6 8 -72 +71 8 @@ -25025,13 +25452,13 @@ 6 -9 -10 +10 +11 6 -17 -18 +20 +21 6 @@ -25066,8 +25493,8 @@ 6 -137 -138 +139 +140 6 @@ -25089,17 +25516,17 @@ 1 2 -3532 +3490 2 3 -481 +476 3 11 -243 +247 @@ -25115,12 +25542,148 @@ 1 2 -4046 +3999 + + +2 +4 +215 + + + + + + + + +variable_template_argument_value +137 + + +variable_id +19 + + +index +13 + + +arg_value +137 + + + + +variable_id +index + + +12 + + +1 +2 +13 2 3 -210 +6 + + + + + + +variable_id +arg_value + + +12 + + +3 +4 +13 + + +15 +16 +6 + + + + + + +index +variable_id + + +12 + + +1 +2 +6 + + +3 +4 +6 + + + + + + +index +arg_value + + +12 + + +6 +7 +6 + + +15 +16 +6 + + + + + + +arg_value +variable_id + + +12 + + +1 +2 +137 + + + + + + +arg_value +index + + +12 + + +1 +2 +137 @@ -25130,15 +25693,15 @@ routinetypes -444572 +436132 id -444572 +436132 return_type -184814 +178086 @@ -25152,7 +25715,7 @@ 1 2 -444572 +436132 @@ -25168,22 +25731,22 @@ 1 2 -148344 +142985 2 3 -21030 +20191 3 -18 -13943 +17 +13367 -18 -7709 -1495 +17 +8001 +1542 @@ -25193,19 +25756,19 @@ routinetypeargs -741201 +726544 routine -362760 +357377 index -389 +373 type_id -209394 +208724 @@ -25219,27 +25782,27 @@ 1 2 -169412 +166448 2 3 -95355 +96574 3 4 -58144 +55888 4 6 -31351 +30298 6 33 -8497 +8167 @@ -25255,22 +25818,22 @@ 1 2 -194831 +190916 2 3 -95853 +97018 3 4 -49707 +47778 4 22 -22367 +21663 @@ -25286,62 +25849,62 @@ 1 2 -133 +128 2 7 -24 +23 10 16 -24 +23 19 33 -24 +23 52 74 -24 +23 93 115 -24 +23 139 199 -24 +23 269 364 -24 +23 473 700 -24 +23 1319 -3279 -24 +3293 +23 -8061 -15906 -24 +8075 +16341 +23 -29841 -29842 -12 +30585 +30586 +11 @@ -25357,62 +25920,62 @@ 1 2 -133 +128 2 5 -24 +23 6 10 -24 +23 11 22 -24 +23 33 37 -24 +23 38 42 -24 +23 44 83 -24 +23 124 183 -24 +23 248 346 -24 +23 463 950 -24 +23 -2463 -5546 -24 +2464 +5642 +23 -12306 -12307 -12 +12850 +12851 +11 @@ -25428,27 +25991,27 @@ 1 2 -123691 +124231 2 3 -40869 +41258 3 4 -13505 +13016 4 7 -17942 +17293 7 -1097 -13384 +1099 +12923 @@ -25464,17 +26027,17 @@ 1 2 -156830 +158176 2 3 -41161 +39576 3 33 -11402 +10971 @@ -25484,19 +26047,19 @@ ptrtomembers -12180 +13227 id -12180 +13227 type_id -10247 +10013 class_id -5519 +6601 @@ -25510,7 +26073,7 @@ 1 2 -12180 +13227 @@ -25526,7 +26089,7 @@ 1 2 -12180 +13227 @@ -25542,12 +26105,12 @@ 1 2 -9895 +9628 2 -65 -352 +100 +385 @@ -25563,12 +26126,12 @@ 1 2 -9895 +9628 2 -65 -352 +100 +385 @@ -25584,22 +26147,22 @@ 1 2 -4619 +5573 2 -7 -352 +3 +490 8 -9 -461 +17 +502 -16 +64 65 -85 +35 @@ -25615,22 +26178,22 @@ 1 2 -4619 +5573 2 -7 -352 +3 +490 8 -9 -461 +17 +502 -16 +64 65 -85 +35 @@ -25640,15 +26203,15 @@ specifiers -547 +525 id -547 +525 str -547 +525 @@ -25662,7 +26225,7 @@ 1 2 -547 +525 @@ -25678,7 +26241,7 @@ 1 2 -547 +525 @@ -25688,15 +26251,15 @@ typespecifiers -1464874 +1479986 type_id -1460193 +1472695 spec_id -85 +81 @@ -25710,12 +26273,12 @@ 1 2 -1455513 +1465403 2 3 -4680 +7291 @@ -25731,37 +26294,37 @@ 102 103 -12 +11 222 223 -12 +11 518 519 -12 +11 -718 -719 -12 +957 +958 +11 2323 2324 -12 +11 -19328 -19329 -12 +20241 +20242 +11 -97291 -97292 -12 +102297 +102298 +11 @@ -25771,15 +26334,15 @@ funspecifiers -11370456 +11412148 func_id -3511992 +3500391 spec_id -194 +186 @@ -25793,27 +26356,27 @@ 1 2 -342616 +329999 2 3 -464083 +448167 3 4 -909155 +883458 4 5 -1670402 +1717910 5 8 -125733 +120855 @@ -25829,82 +26392,82 @@ 22 23 -12 +11 169 170 -12 +11 491 492 -12 +11 -506 -507 -12 +598 +599 +11 632 633 -12 +11 5650 5651 -12 +11 9530 9531 -12 +11 10451 10452 -12 +11 -11821 -11822 -12 +11834 +11835 +11 14848 14849 -12 +11 -25330 -25331 -12 +26196 +26197 +11 -33532 -33533 -12 +33724 +33725 +11 -122462 -122463 -12 +131801 +131802 +11 -204591 -204592 -12 +214925 +214926 +11 -232301 -232302 -12 +242884 +242885 +11 -263009 -263010 -12 +272918 +272919 +11 @@ -25914,11 +26477,11 @@ varspecifiers -1124158 +1113938 var_id -935091 +926194 spec_id @@ -25936,17 +26499,17 @@ 1 2 -795258 +787198 2 3 -92279 +91911 3 5 -47553 +47084 @@ -25980,13 +26543,13 @@ 6 -8409 -8410 +8411 +8412 6 -8751 -8752 +8753 +8754 6 @@ -25995,13 +26558,13 @@ 6 -13352 -13353 +13439 +13440 6 -42323 -42324 +42412 +42413 6 @@ -26590,11 +27153,11 @@ attribute_args -118319 +118389 id -118319 +118389 kind @@ -26602,7 +27165,7 @@ attribute -116952 +117020 index @@ -26610,7 +27173,7 @@ location -58256 +58290 @@ -26624,7 +27187,7 @@ 1 2 -118319 +118389 @@ -26640,7 +27203,7 @@ 1 2 -118319 +118389 @@ -26656,7 +27219,7 @@ 1 2 -118319 +118389 @@ -26672,7 +27235,7 @@ 1 2 -118319 +118389 @@ -26772,12 +27335,12 @@ 1 2 -116132 +116200 2 4 -819 +820 @@ -26793,7 +27356,7 @@ 1 2 -116431 +116499 2 @@ -26814,12 +27377,12 @@ 1 2 -116132 +116200 2 4 -819 +820 @@ -26835,7 +27398,7 @@ 1 2 -116137 +116205 2 @@ -26955,22 +27518,22 @@ 1 2 -28468 +28485 2 3 -7516 +7521 3 4 -19458 +19469 4 25 -2812 +2814 @@ -26986,12 +27549,12 @@ 1 2 -52020 +52051 2 3 -6235 +6239 @@ -27007,22 +27570,22 @@ 1 2 -28452 +28469 2 3 -7534 +7539 3 4 -19454 +19466 4 25 -2814 +2815 @@ -27038,7 +27601,7 @@ 1 2 -58250 +58285 3 @@ -27053,15 +27616,15 @@ attribute_arg_value -118292 +118362 arg -118292 +118362 value -2257 +2258 @@ -27075,7 +27638,7 @@ 1 2 -118292 +118362 @@ -27091,7 +27654,7 @@ 1 2 -1808 +1809 2 @@ -27116,15 +27679,15 @@ attribute_arg_type -60 +58 arg -60 +58 type_id -36 +35 @@ -27138,7 +27701,7 @@ 1 2 -60 +58 @@ -27154,12 +27717,12 @@ 1 2 -12 +11 2 3 -24 +23 @@ -27222,15 +27785,15 @@ typeattributes -12119 +12701 type_id -10831 +11462 spec_id -12119 +12701 @@ -27244,12 +27807,12 @@ 1 2 -10296 +10948 2 34 -534 +514 @@ -27265,7 +27828,7 @@ 1 2 -12119 +12701 @@ -27275,15 +27838,15 @@ funcattributes -327044 +314529 func_id -174943 +168330 spec_id -327044 +314529 @@ -27297,22 +27860,22 @@ 1 2 -94078 +90603 2 3 -13554 +13028 3 4 -65134 +62606 4 14 -2176 +2091 @@ -27328,7 +27891,7 @@ 1 2 -327044 +314529 @@ -27444,15 +28007,15 @@ unspecifiedtype -9406353 +9451546 type_id -9406353 +9451546 unspecified_type_id -5062897 +5133540 @@ -27466,7 +28029,7 @@ 1 2 -9406353 +9451546 @@ -27482,22 +28045,17 @@ 1 2 -2733810 +2776289 2 3 -1943594 +1978655 3 -30 -379779 - - -30 -7873 -5713 +7936 +378596 @@ -27507,19 +28065,19 @@ member -5112192 +5066844 parent -809800 +833190 index -2966 +2851 child -5095258 +5050544 @@ -27533,47 +28091,47 @@ 1 2 -46948 +45126 2 3 -191658 +219789 3 4 -208336 +209109 4 5 -90285 +90638 5 7 -65073 +67210 7 9 -67212 +65539 9 15 -68221 +66497 15 -39 -62471 +45 +62758 -39 +45 245 -9591 +6520 @@ -27589,47 +28147,47 @@ 1 2 -46218 +44425 2 3 -191719 +219824 3 4 -202769 +203723 4 5 -93154 +93454 5 7 -65766 +67876 7 9 -67346 +65668 9 15 -68999 +67245 15 -38 -61462 +41 +62641 -38 +41 281 -12363 +8331 @@ -27645,62 +28203,62 @@ 1 2 -547 +525 2 5 -267 +257 5 9 -255 +245 9 18 -230 +222 23 100 -230 +222 122 186 -230 +222 188 293 -230 +222 296 374 -230 +222 375 542 -230 +222 572 3257 -230 +222 3427 -21556 -230 +22111 +222 -29162 -65993 -48 +30337 +70680 +46 @@ -27716,62 +28274,62 @@ 1 2 -534 +514 2 5 -218 +210 5 7 -230 +222 7 13 -230 +222 13 70 -230 +222 71 160 -230 +222 160 256 -230 +222 263 345 -230 +222 346 476 -243 +233 492 1685 -230 +222 1926 -8765 -230 +8775 +222 -10213 -66838 -121 +10226 +71530 +116 @@ -27787,7 +28345,7 @@ 1 2 -5095258 +5050544 @@ -27803,12 +28361,12 @@ 1 2 -5078555 +5034466 2 7 -16702 +16078 @@ -27818,15 +28376,15 @@ enclosingfunction -131751 +127164 child -131751 +127164 parent -74239 +71639 @@ -27840,7 +28398,7 @@ 1 2 -131751 +127164 @@ -27856,27 +28414,27 @@ 1 2 -39240 +37811 2 3 -21930 +21231 3 4 -7208 +6952 4 6 -5652 +5445 6 45 -206 +198 @@ -27886,27 +28444,27 @@ derivations -370309 +392220 derivation -370309 +392220 sub -346555 +367484 index -72 +70 super -237840 +236475 location -96351 +92613 @@ -27920,7 +28478,7 @@ 1 2 -370309 +392220 @@ -27936,7 +28494,7 @@ 1 2 -370309 +392220 @@ -27952,7 +28510,7 @@ 1 2 -370309 +392220 @@ -27968,7 +28526,7 @@ 1 2 -370309 +392220 @@ -27984,12 +28542,12 @@ 1 2 -326108 +345926 2 7 -20447 +21558 @@ -28005,12 +28563,12 @@ 1 2 -334933 +356161 2 7 -11621 +11322 @@ -28026,12 +28584,12 @@ 1 2 -326120 +345937 2 7 -20434 +21546 @@ -28047,12 +28605,12 @@ 1 2 -334921 +356150 2 7 -11633 +11334 @@ -28068,32 +28626,32 @@ 1 2 -12 +11 4 5 -12 +11 44 45 -12 +11 220 221 -12 +11 -957 -958 -12 +970 +971 +11 -29236 -29237 -12 +32328 +32329 +11 @@ -28109,32 +28667,32 @@ 1 2 -12 +11 4 5 -12 +11 44 45 -12 +11 220 221 -12 +11 -956 -957 -12 +969 +970 +11 -28508 -28509 -12 +31450 +31451 +11 @@ -28150,32 +28708,32 @@ 1 2 -12 +11 3 4 -12 +11 29 30 -12 +11 84 85 -12 +11 -441 -442 -12 +452 +453 +11 -19051 -19052 -12 +19713 +19714 +11 @@ -28191,32 +28749,32 @@ 1 2 -12 +11 4 5 -12 +11 17 18 -12 +11 51 52 -12 +11 254 255 -12 +11 7602 7603 -12 +11 @@ -28232,12 +28790,12 @@ 1 2 -222438 +221343 2 -766 -15402 +1134 +15131 @@ -28253,12 +28811,12 @@ 1 2 -222450 +221355 2 -766 -15390 +1134 +15120 @@ -28274,12 +28832,12 @@ 1 2 -237342 +235996 2 4 -498 +479 @@ -28295,12 +28853,12 @@ 1 2 -229780 +228634 2 439 -8059 +7840 @@ -28316,22 +28874,22 @@ 1 2 -74652 +70786 2 3 -9336 +8985 3 8 -7306 +7606 8 -682 -5057 +698 +5234 @@ -28347,22 +28905,22 @@ 1 2 -77193 +73146 2 3 -7002 +6858 3 -9 -7609 +8 +7443 -9 -682 -4546 +8 +698 +5164 @@ -28378,12 +28936,12 @@ 1 2 -96327 +92589 2 4 -24 +23 @@ -28399,22 +28957,22 @@ 1 2 -77655 +73882 2 3 -9056 +8833 3 -11 -7269 +10 +7326 -11 -682 -2370 +10 +698 +2570 @@ -28424,15 +28982,15 @@ derspecifiers -372947 +394756 der_id -370272 +392185 spec_id -48 +46 @@ -28446,12 +29004,12 @@ 1 2 -367598 +389615 2 3 -2674 +2570 @@ -28467,22 +29025,22 @@ 220 221 -12 +11 242 243 -12 +11 979 980 -12 +11 -29238 -29239 -12 +32343 +32344 +11 @@ -28492,15 +29050,15 @@ direct_base_offsets -282029 +307366 der_id -282029 +307366 offset -206 +210 @@ -28514,7 +29072,7 @@ 1 2 -282029 +307366 @@ -28530,62 +29088,67 @@ 1 2 -36 +46 2 3 -12 +11 4 5 -24 +23 5 6 -12 +11 6 7 -24 +11 7 8 -12 +23 8 9 -24 +11 + + +10 +11 +11 11 12 -12 +11 21 22 -12 +11 -78 -79 -12 +85 +86 +11 200 201 -12 +11 -22837 -22838 -12 +25931 +25932 +11 @@ -28595,19 +29158,19 @@ virtual_base_offsets -7026 +6753 sub -3890 +3739 super -534 +514 offset -267 +257 @@ -28621,22 +29184,22 @@ 1 2 -3063 +2944 2 4 -340 +327 4 7 -279 +268 7 11 -206 +198 @@ -28652,17 +29215,17 @@ 1 2 -3282 +3154 2 4 -328 +315 4 8 -279 +268 @@ -28678,52 +29241,52 @@ 1 2 -85 +81 2 3 -48 +46 3 4 -60 +58 4 5 -97 +93 5 7 -36 +35 8 13 -48 +46 13 15 -48 +46 15 23 -48 +46 24 60 -48 +46 196 197 -12 +11 @@ -28739,32 +29302,32 @@ 1 2 -303 +292 2 3 -85 +81 4 6 -36 +35 6 8 -48 +46 8 10 -48 +46 14 15 -12 +11 @@ -28780,57 +29343,57 @@ 2 3 -36 +35 4 5 -12 +11 5 6 -24 +23 6 8 -24 +23 8 9 -36 +35 10 12 -24 +23 14 19 -24 +23 20 27 -24 +23 28 31 -24 +23 36 97 -24 +23 97 98 -12 +11 @@ -28846,37 +29409,37 @@ 1 2 -85 +81 2 3 -36 +35 3 4 -48 +46 5 7 -24 +23 7 10 -24 +23 12 14 -24 +23 21 29 -24 +23 @@ -28886,23 +29449,23 @@ frienddecls -231178 +222208 id -231178 +222208 type_id -19511 +18753 decl_id -28810 +27692 location -8096 +7782 @@ -28916,7 +29479,7 @@ 1 2 -231178 +222208 @@ -28932,7 +29495,7 @@ 1 2 -231178 +222208 @@ -28948,7 +29511,7 @@ 1 2 -231178 +222208 @@ -28964,47 +29527,47 @@ 1 2 -6856 +6590 2 3 -2467 +2371 3 4 -1191 +1145 4 6 -1714 +1647 6 10 -1556 +1495 10 16 -1470 +1413 16 34 -1786 +1717 36 59 -1470 +1413 59 129 -996 +958 @@ -29020,47 +29583,47 @@ 1 2 -6856 +6590 2 3 -2467 +2371 3 4 -1191 +1145 4 6 -1714 +1647 6 10 -1556 +1495 10 16 -1470 +1413 16 34 -1786 +1717 36 59 -1470 +1413 59 129 -996 +958 @@ -29076,17 +29639,17 @@ 1 2 -17748 +17059 2 5 -1543 +1483 5 31 -218 +210 @@ -29102,37 +29665,37 @@ 1 2 -15815 +15201 2 3 -2261 +2173 3 5 -2479 +2383 5 9 -2188 +2103 9 20 -2030 +1951 20 28 -2467 +2371 28 390 -1568 +1507 @@ -29148,37 +29711,37 @@ 1 2 -15815 +15201 2 3 -2261 +2173 3 5 -2479 +2383 5 9 -2188 +2103 9 20 -2030 +1951 20 28 -2467 +2371 28 390 -1568 +1507 @@ -29194,12 +29757,12 @@ 1 2 -28215 +27120 2 46 -595 +572 @@ -29215,17 +29778,17 @@ 1 2 -6917 +6648 2 3 -1045 +1004 3 18239 -133 +128 @@ -29241,12 +29804,12 @@ 1 2 -7609 +7314 2 1215 -486 +467 @@ -29262,17 +29825,17 @@ 1 2 -6929 +6660 2 3 -1033 +993 3 1734 -133 +128 @@ -29282,19 +29845,19 @@ comments -1743633 +1675974 id -1743633 +1675974 contents -864492 +830947 location -1743633 +1675974 @@ -29308,7 +29871,7 @@ 1 2 -1743633 +1675974 @@ -29324,7 +29887,7 @@ 1 2 -1743633 +1675974 @@ -29340,17 +29903,17 @@ 1 2 -731525 +703139 2 3 -83149 +79923 3 10736 -49817 +47883 @@ -29366,17 +29929,17 @@ 1 2 -731525 +703139 2 3 -83149 +79923 3 10736 -49817 +47883 @@ -29392,7 +29955,7 @@ 1 2 -1743633 +1675974 @@ -29408,7 +29971,7 @@ 1 2 -1743633 +1675974 @@ -29418,15 +29981,15 @@ commentbinding -778436 +748230 id -679021 +652673 element -747438 +718434 @@ -29440,17 +30003,17 @@ 1 2 -616002 +592099 2 4 -58545 +56273 4 97 -4473 +4299 @@ -29466,12 +30029,12 @@ 1 2 -716439 +688638 2 3 -30998 +29796 @@ -29481,15 +30044,15 @@ exprconv -6445331 +6446816 converted -6445038 +6446523 conversion -6445331 +6446816 @@ -29503,7 +30066,7 @@ 1 2 -6444746 +6446231 2 @@ -29524,7 +30087,7 @@ 1 2 -6445331 +6446816 @@ -29534,30 +30097,30 @@ compgenerated -6720341 +6652484 id -6720341 +6652484 synthetic_destructor_call -59493 +57185 element -47422 +45582 i -340 +327 destructor_call -49573 +47650 @@ -29571,17 +30134,17 @@ 1 2 -38791 +37285 2 3 -6321 +6076 3 29 -2309 +2220 @@ -29597,17 +30160,17 @@ 1 2 -38791 +37285 2 3 -6321 +6076 3 29 -2309 +2220 @@ -29623,27 +30186,27 @@ 1 2 -255 +245 2 7 -24 +23 22 43 -24 +23 190 711 -24 +23 3901 3902 -12 +11 @@ -29659,27 +30222,27 @@ 1 2 -255 +245 2 7 -24 +23 21 37 -24 +23 146 550 -24 +23 3297 3298 -12 +11 @@ -29695,17 +30258,17 @@ 1 2 -43823 +42123 2 3 -3719 +3575 3 26 -2030 +1951 @@ -29721,7 +30284,7 @@ 1 2 -49573 +47650 @@ -29731,15 +30294,15 @@ namespaces -8497 +8167 id -8497 +8167 name -4570 +4393 @@ -29753,7 +30316,7 @@ 1 2 -8497 +8167 @@ -29769,17 +30332,17 @@ 1 2 -3841 +3692 2 3 -461 +444 3 139 -267 +257 @@ -29789,26 +30352,26 @@ namespace_inline -170 +163 id -170 +163 namespacembrs -1570027 +1616300 parentid -7913 +7606 memberid -1570027 +1616300 @@ -29822,62 +30385,67 @@ 1 2 -875 +829 2 3 -826 +794 3 4 -644 +385 4 -6 -680 - - -6 -9 +5 607 -9 -16 -680 +5 +8 +666 -16 -27 -607 +8 +14 +677 -27 -46 -619 - - -46 -85 -607 - - -85 -169 -607 - - -169 -444 +14 +22 595 -475 -29073 -559 +22 +42 +595 + + +42 +63 +572 + + +63 +127 +572 + + +127 +304 +572 + + +321 +1041 +572 + + +1101 +32701 +163 @@ -29893,7 +30461,7 @@ 1 2 -1570027 +1616300 @@ -29903,19 +30471,19 @@ exprparents -13615303 +13481241 expr_id -13615112 +13481052 child_index -3163 +3131 parent_id -9644209 +9549204 @@ -29929,7 +30497,7 @@ 1 2 -13615105 +13481045 2 @@ -29950,12 +30518,12 @@ 1 2 -13614927 +13480869 2 4 -184 +182 @@ -29971,37 +30539,37 @@ 1 2 -72 +71 2 3 -652 +645 3 4 -1674 +1657 4 46 -243 +241 46 56 -237 +234 56 3660 -237 +234 6434 -1187727 -46 +1188148 +45 @@ -30017,37 +30585,37 @@ 1 2 -72 +71 2 3 -652 +645 3 4 -1674 +1657 4 31 -243 +241 31 41 -237 +234 41 3645 -237 +234 6419 -1187740 -46 +1188161 +45 @@ -30063,17 +30631,17 @@ 1 2 -6840662 +6772879 2 3 -2212086 +2190858 3 1681 -591461 +585466 @@ -30089,17 +30657,17 @@ 1 2 -6840682 +6772898 2 3 -2212066 +2190839 3 480 -591461 +585466 @@ -30109,22 +30677,22 @@ expr_isload -5063114 +5014574 expr_id -5063114 +5014574 conversionkinds -4254113 +4255501 expr_id -4254113 +4255501 kind @@ -30142,7 +30710,7 @@ 1 2 -4254113 +4255501 @@ -30166,8 +30734,8 @@ 1 -13109 -13110 +13672 +13673 1 @@ -30181,8 +30749,8 @@ 1 -4161592 -4161593 +4162417 +4162418 1 @@ -30193,15 +30761,15 @@ iscall -2365240 +2284876 caller -2365240 +2284876 kind -36 +35 @@ -30215,7 +30783,7 @@ 1 2 -2365240 +2284876 @@ -30231,17 +30799,17 @@ 1319 1320 -12 +11 -5604 -5605 -12 +5643 +5644 +11 -187644 -187645 -12 +188582 +188583 +11 @@ -30251,15 +30819,15 @@ numtemplatearguments -157948 +152181 expr_id -157948 +152181 num -48 +46 @@ -30273,7 +30841,7 @@ 1 2 -157948 +152181 @@ -30289,22 +30857,22 @@ 3 4 -12 +11 41 42 -12 +11 651 652 -12 +11 -12298 -12299 -12 +12329 +12330 +11 @@ -30314,15 +30882,15 @@ specialnamequalifyingelements -12 +11 id -12 +11 name -12 +11 @@ -30336,7 +30904,7 @@ 1 2 -12 +11 @@ -30352,7 +30920,7 @@ 1 2 -12 +11 @@ -30362,23 +30930,23 @@ namequalifiers -1125621 +1116919 id -1125621 +1116919 qualifiableelement -1125621 +1116919 qualifyingelement -37001 +38961 location -509589 +506087 @@ -30392,7 +30960,7 @@ 1 2 -1125621 +1116919 @@ -30408,7 +30976,7 @@ 1 2 -1125621 +1116919 @@ -30424,7 +30992,7 @@ 1 2 -1125621 +1116919 @@ -30440,7 +31008,7 @@ 1 2 -1125621 +1116919 @@ -30456,7 +31024,7 @@ 1 2 -1125621 +1116919 @@ -30472,7 +31040,7 @@ 1 2 -1125621 +1116919 @@ -30488,109 +31056,109 @@ 1 2 -17109 +18965 2 3 -7935 +8142 3 4 -5081 - - -4 -10 -2860 - - -10 -86 -2781 - - -86 -24926 -1232 - - - - - - -qualifyingelement -qualifiableelement - - -12 - - -1 -2 -17109 - - -2 -3 -7935 - - -3 -4 -5081 - - -4 -10 -2860 - - -10 -86 -2781 - - -86 -24926 -1232 - - - - - - -qualifyingelement -location - - -12 - - -1 -2 -22745 - - -2 -3 -4817 - - -3 -4 -3802 +5043 4 11 -3018 +3027 + + +11 +129 +2935 + + +132 +24926 +848 + + + + + + +qualifyingelement +qualifiableelement + + +12 + + +1 +2 +18965 + + +2 +3 +8142 + + +3 +4 +5043 + + +4 +11 +3027 + + +11 +129 +2935 + + +132 +24926 +848 + + + + + + +qualifyingelement +location + + +12 + + +1 +2 +24850 + + +2 +3 +4762 + + +3 +4 +3770 + + +4 +11 +2974 11 16728 -2616 +2603 @@ -30606,22 +31174,22 @@ 1 2 -387650 +384719 2 3 -57004 +56877 3 7 -39037 +38851 7 381 -25895 +25639 @@ -30637,22 +31205,22 @@ 1 2 -387650 +384719 2 3 -57004 +56877 3 7 -39037 +38851 7 381 -25895 +25639 @@ -30668,17 +31236,17 @@ 1 2 -452478 +449080 2 3 -44785 +44650 3 190 -12324 +12356 @@ -30688,15 +31256,15 @@ varbind -5497554 +5445518 expr -5497428 +5445394 var -1549133 +1534266 @@ -30710,12 +31278,12 @@ 1 2 -5497303 +5445270 2 3 -125 +123 @@ -30731,32 +31299,32 @@ 1 2 -685882 +679661 2 3 -311295 +308179 3 4 -236831 +234430 4 5 -93953 +93020 5 9 -134777 +133430 9 6150 -86393 +85544 @@ -30766,15 +31334,15 @@ funbind -2442767 +2419854 expr -2142538 +2122577 fun -438611 +434205 @@ -30788,17 +31356,17 @@ 1 2 -1842553 +1825541 2 3 -299807 +296859 3 5 -177 +176 @@ -30814,32 +31382,32 @@ 1 2 -255153 +252065 2 3 -76151 +75516 3 4 -31642 +31302 4 7 -33910 +33957 7 37 -33831 +33520 37 6664 -7922 +7841 @@ -30849,19 +31417,19 @@ expr_allocator -27692 +26617 expr -27692 +26617 func -133 +128 form -12 +11 @@ -30875,7 +31443,7 @@ 1 2 -27692 +26617 @@ -30891,7 +31459,7 @@ 1 2 -27692 +26617 @@ -30907,42 +31475,42 @@ 1 2 -36 +35 3 4 -12 +11 4 5 -12 +11 5 6 -12 +11 7 8 -24 +23 39 40 -12 +11 973 974 -12 +11 1237 1238 -12 +11 @@ -30958,7 +31526,7 @@ 1 2 -133 +128 @@ -30974,7 +31542,7 @@ 2278 2279 -12 +11 @@ -30990,7 +31558,7 @@ 11 12 -12 +11 @@ -31000,19 +31568,19 @@ expr_deallocator -30998 +29796 expr -30998 +29796 func -145 +140 form -24 +23 @@ -31026,7 +31594,7 @@ 1 2 -30998 +29796 @@ -31042,7 +31610,7 @@ 1 2 -30998 +29796 @@ -31058,42 +31626,42 @@ 1 2 -36 +35 2 3 -24 +23 3 4 -12 +11 4 5 -12 +11 7 8 -24 +23 118 119 -12 +11 883 884 -12 +11 1521 1522 -12 +11 @@ -31109,7 +31677,7 @@ 1 2 -145 +140 @@ -31125,12 +31693,12 @@ 891 892 -12 +11 1659 1660 -12 +11 @@ -31146,12 +31714,12 @@ 4 5 -12 +11 8 9 -12 +11 @@ -31161,26 +31729,26 @@ expr_cond_two_operand -610 +611 cond -610 +611 expr_cond_guard -154429 +154519 cond -154429 +154519 guard -154429 +154519 @@ -31194,7 +31762,7 @@ 1 2 -154429 +154519 @@ -31210,7 +31778,7 @@ 1 2 -154429 +154519 @@ -31220,15 +31788,15 @@ expr_cond_true -154429 +154519 cond -154429 +154519 true -154429 +154519 @@ -31242,7 +31810,7 @@ 1 2 -154429 +154519 @@ -31258,7 +31826,7 @@ 1 2 -154429 +154519 @@ -31268,15 +31836,15 @@ expr_cond_false -154429 +154519 cond -154429 +154519 false -154429 +154519 @@ -31290,7 +31858,7 @@ 1 2 -154429 +154519 @@ -31306,7 +31874,7 @@ 1 2 -154429 +154519 @@ -31316,15 +31884,15 @@ values -8776796 +8788031 id -8776796 +8788031 str -651390 +651491 @@ -31338,7 +31906,7 @@ 1 2 -8776796 +8788031 @@ -31354,17 +31922,17 @@ 1 2 -540103 +540120 2 3 -65463 +65472 3 -4044535 -45824 +4046841 +45899 @@ -31374,15 +31942,15 @@ valuetext -4759381 +4766569 id -4759381 +4766569 text -704971 +705085 @@ -31396,7 +31964,7 @@ 1 2 -4759381 +4766569 @@ -31412,22 +31980,22 @@ 1 2 -528095 +528108 2 3 -102815 +102830 3 7 -56849 +56879 7 427516 -17212 +17268 @@ -31437,15 +32005,15 @@ valuebind -9499071 +9509366 val -8769631 +8779926 expr -9499071 +9509366 @@ -31459,7 +32027,7 @@ 1 2 -8040923 +8051218 2 @@ -31485,7 +32053,7 @@ 1 2 -9499071 +9509366 @@ -31495,19 +32063,19 @@ fieldoffsets -259539 +251575 id -259539 +251575 byteoffset -3914 +9022 bitoffset -85 +52 @@ -31521,7 +32089,7 @@ 1 2 -259539 +251575 @@ -31537,7 +32105,7 @@ 1 2 -259539 +251575 @@ -31553,42 +32121,27 @@ 1 2 -1689 +6132 2 3 -534 +782 3 -4 -194 - - -4 6 -340 +750 6 -11 -328 +17 +678 -11 -23 -328 - - -23 -84 -303 - - -90 -12369 -194 +17 +11685 +678 @@ -31604,12 +32157,12 @@ 1 2 -3853 +8579 2 -8 -60 +9 +443 @@ -31623,29 +32176,44 @@ 12 -1 -2 -36 +83 +84 +6 -2 -3 -12 +87 +88 +6 -3 -4 -12 +102 +103 +6 -4 -5 -12 +122 +123 +6 -21338 -21339 -12 +127 +128 +6 + + +153 +154 +6 + + +195 +196 +6 + + +37692 +37693 +6 @@ -31659,24 +32227,44 @@ 12 -1 -2 -36 +40 +41 +6 -2 -3 -24 +44 +45 +6 -3 -4 -12 +45 +46 +6 -322 -323 -12 +52 +53 +6 + + +54 +55 +6 + + +58 +59 +6 + + +66 +67 +6 + + +1383 +1384 +6 @@ -31686,11 +32274,11 @@ bitfield -13357 +13365 id -13357 +13365 bits @@ -31712,7 +32300,7 @@ 1 2 -13357 +13365 @@ -31728,7 +32316,7 @@ 1 2 -13357 +13365 @@ -31892,23 +32480,23 @@ initialisers -1685017 +1668506 init -1685017 +1668506 var -649685 +643667 expr -1685017 +1668506 location -321906 +318643 @@ -31922,7 +32510,7 @@ 1 2 -1685017 +1668506 @@ -31938,7 +32526,7 @@ 1 2 -1685017 +1668506 @@ -31954,7 +32542,7 @@ 1 2 -1685017 +1668506 @@ -31970,22 +32558,22 @@ 1 2 -562000 +556871 2 16 -29079 +28784 16 17 -49688 +49185 17 53 -8917 +8827 @@ -32001,22 +32589,22 @@ 1 2 -562000 +556871 2 16 -29079 +28784 16 17 -49688 +49185 17 53 -8917 +8827 @@ -32032,7 +32620,7 @@ 1 2 -649672 +643654 2 @@ -32053,7 +32641,7 @@ 1 2 -1685017 +1668506 @@ -32069,7 +32657,7 @@ 1 2 -1685017 +1668506 @@ -32085,7 +32673,7 @@ 1 2 -1685017 +1668506 @@ -32101,27 +32689,27 @@ 1 2 -248450 +245906 2 3 -24096 +23845 3 7 -24485 +24243 7 65 -24346 +24126 67 109238 -527 +521 @@ -32137,22 +32725,22 @@ 1 2 -271334 +268551 2 3 -25342 +25091 3 -24 -24155 +23 +23904 -24 +23 12632 -1074 +1096 @@ -32168,27 +32756,27 @@ 1 2 -248450 +245906 2 3 -24096 +23845 3 7 -24485 +24243 7 65 -24346 +24126 67 109238 -527 +521 @@ -32198,15 +32786,15 @@ expr_ancestor -67772 +68706 exp -67176 +68133 ancestor -49695 +51330 @@ -32220,12 +32808,12 @@ 1 2 -66605 +67584 2 4 -571 +549 @@ -32241,17 +32829,17 @@ 1 2 -37405 +39517 2 3 -10150 +9756 3 29 -2139 +2056 @@ -32261,19 +32849,19 @@ exprs -18449753 +18460593 id -18449753 +18460593 kind -393 +1168 location -6150603 +3836046 @@ -32287,7 +32875,7 @@ 1 2 -18449753 +18460593 @@ -32303,7 +32891,7 @@ 1 2 -18449753 +18460593 @@ -32317,69 +32905,69 @@ 12 -5 -28 -30 +1 +14 +105 -71 -82 -30 +15 +44 +93 -94 -255 -30 +47 +86 +93 -271 -627 -30 +90 +223 +93 -858 -1879 -30 +296 +463 +93 -2191 -3716 -30 +483 +715 +93 -4305 -6068 -30 +788 +2129 +93 -7004 -11661 -30 +2165 +2950 +93 -12107 -20202 -30 +3030 +4378 +93 -21965 -29561 -30 +4477 +6077 +93 -32830 -41032 -30 +6490 +17249 +93 -44670 -145995 -30 +19347 +188353 +93 -447805 -725766 -24 +191022 +403956 +35 @@ -32394,68 +32982,68 @@ 1 +4 +105 + + +6 +13 +105 + + +13 24 -30 +93 -27 -72 -30 +24 +38 +93 -77 -157 -30 +38 +134 +93 -171 -402 -30 +144 +259 +93 -422 -1083 -30 +269 +480 +93 -1179 -1862 -30 +481 +1074 +93 -2201 -4268 -30 +1095 +1411 +93 -4679 -6584 -30 +1422 +2045 +93 -6624 -11083 -30 +2059 +4557 +93 -11359 -12983 -30 +5888 +59687 +93 -17158 -28621 -30 - - -29980 -88945 -30 - - -128315 -425042 -24 +72153 +117893 +23 @@ -32471,22 +33059,37 @@ 1 2 -4450587 +1838158 2 3 -874643 +753582 3 -6 -496205 +4 +356208 -6 -22445 -329167 +4 +5 +276250 + + +5 +9 +301489 + + +9 +72 +287759 + + +72 +136887 +22598 @@ -32502,22 +33105,17 @@ 1 2 -4599301 +2734142 2 3 -812812 +859259 3 -5 -498909 - - -5 -33 -239579 +30 +242644 @@ -32527,19 +33125,19 @@ expr_types -18617706 +18629051 id -18444987 +18456012 typeid -1372691 +1345343 value_category -36 +35 @@ -32553,12 +33151,12 @@ 1 2 -18272500 +18283254 2 4 -172487 +172758 @@ -32574,7 +33172,7 @@ 1 2 -18444987 +18456012 @@ -32590,42 +33188,42 @@ 1 2 -530591 +526443 2 3 -259102 +254107 3 4 -113553 +110864 4 5 -95427 +92110 5 8 -122925 +118483 8 14 -105736 +102381 14 -46 -103864 +47 +101797 -46 -111456 -41489 +47 +123210 +39155 @@ -32641,17 +33239,17 @@ 1 2 -1207109 +1185928 2 3 -157753 +151877 3 4 -7828 +7536 @@ -32667,17 +33265,17 @@ 4533 4534 -12 +11 -340895 -340896 -12 +342547 +342548 +11 -1171875 -1171876 -12 +1232420 +1232421 +11 @@ -32691,19 +33289,19 @@ 12 -1340 -1341 -12 +1341 +1342 +11 -29733 -29734 -12 +29841 +29842 +11 -96111 -96112 -12 +98243 +98244 +11 @@ -32713,15 +33311,15 @@ new_allocated_type -29527 +28382 expr -29527 +28382 type_id -18234 +17527 @@ -32735,7 +33333,7 @@ 1 2 -29527 +28382 @@ -32751,22 +33349,22 @@ 1 2 -12667 +12175 2 3 -4035 +3879 3 9 -1446 +1390 10 92 -85 +81 @@ -32776,15 +33374,15 @@ new_array_allocated_type -5364 +5310 expr -5364 +5310 type_id -2306 +2283 @@ -32798,7 +33396,7 @@ 1 2 -5364 +5310 @@ -32819,12 +33417,12 @@ 2 3 -2043 +2022 3 7 -177 +176 8 @@ -33376,15 +33974,15 @@ condition_decl_bind -7646 +7349 expr -7646 +7349 decl -7646 +7349 @@ -33398,7 +33996,7 @@ 1 2 -7646 +7349 @@ -33414,7 +34012,7 @@ 1 2 -7646 +7349 @@ -33424,15 +34022,15 @@ typeid_bind -4899 +4708 expr -4899 +4708 type_id -2601 +2500 @@ -33446,7 +34044,7 @@ 1 2 -4899 +4708 @@ -33462,22 +34060,22 @@ 1 2 -1300 +1250 2 3 -996 +958 3 6 -230 +222 6 17 -72 +70 @@ -33487,15 +34085,15 @@ uuidof_bind -856 +848 expr -856 +848 type_id -652 +645 @@ -33509,7 +34107,7 @@ 1 2 -856 +848 @@ -33525,12 +34123,12 @@ 1 2 -481 +476 2 3 -138 +137 3 @@ -33545,15 +34143,15 @@ sizeof_bind -156997 +157089 expr -156997 +157089 type_id -2673 +2674 @@ -33567,7 +34165,7 @@ 1 2 -156997 +157089 @@ -33583,7 +34181,7 @@ 1 2 -1044 +1045 2 @@ -33681,11 +34279,11 @@ lambdas -12641 +12513 expr -12641 +12513 default_capture @@ -33707,7 +34305,7 @@ 1 2 -12641 +12513 @@ -33723,7 +34321,7 @@ 1 2 -12641 +12513 @@ -33812,23 +34410,23 @@ lambda_capture -21730 +21509 id -21730 +21509 lambda -10097 +9994 index -112 +110 field -21730 +21509 captured_by_reference @@ -33840,7 +34438,7 @@ location -14051 +13909 @@ -33854,7 +34452,7 @@ 1 2 -21730 +21509 @@ -33870,7 +34468,7 @@ 1 2 -21730 +21509 @@ -33886,7 +34484,7 @@ 1 2 -21730 +21509 @@ -33902,7 +34500,7 @@ 1 2 -21730 +21509 @@ -33918,7 +34516,7 @@ 1 2 -21730 +21509 @@ -33934,7 +34532,7 @@ 1 2 -21730 +21509 @@ -33950,27 +34548,27 @@ 1 2 -5002 +4951 2 3 -2379 +2355 3 4 -1265 +1252 4 6 -922 +913 6 18 -527 +521 @@ -33986,27 +34584,27 @@ 1 2 -5002 +4951 2 3 -2379 +2355 3 4 -1265 +1252 4 6 -922 +913 6 18 -527 +521 @@ -34022,27 +34620,27 @@ 1 2 -5002 +4951 2 3 -2379 +2355 3 4 -1265 +1252 4 6 -922 +913 6 18 -527 +521 @@ -34058,12 +34656,12 @@ 1 2 -9629 +9531 2 3 -467 +463 @@ -34079,7 +34677,7 @@ 1 2 -10077 +9975 2 @@ -34100,27 +34698,27 @@ 1 2 -5483 +5428 2 3 -2504 +2479 3 4 -1041 +1030 4 7 -823 +815 7 18 -243 +241 @@ -34429,7 +35027,7 @@ 2 3 -85 +84 @@ -34450,7 +35048,7 @@ 2 3 -46 +45 @@ -34562,7 +35160,7 @@ 1 2 -21730 +21509 @@ -34578,7 +35176,7 @@ 1 2 -21730 +21509 @@ -34594,7 +35192,7 @@ 1 2 -21730 +21509 @@ -34610,7 +35208,7 @@ 1 2 -21730 +21509 @@ -34626,7 +35224,7 @@ 1 2 -21730 +21509 @@ -34642,7 +35240,7 @@ 1 2 -21730 +21509 @@ -34900,17 +35498,17 @@ 1 2 -12667 +12539 2 6 -1061 +1050 6 68 -322 +319 @@ -34926,12 +35524,12 @@ 1 2 -13115 +12982 2 68 -935 +926 @@ -34947,12 +35545,12 @@ 1 2 -13511 +13374 2 8 -540 +534 @@ -34968,17 +35566,17 @@ 1 2 -12667 +12539 2 6 -1061 +1050 6 68 -322 +319 @@ -34994,7 +35592,7 @@ 1 2 -14032 +13889 2 @@ -35015,7 +35613,7 @@ 1 2 -14051 +13909 @@ -35141,19 +35739,19 @@ stmts -4943740 +4765273 id -4943740 +4765273 kind -230 +222 location -1317574 +1266448 @@ -35167,7 +35765,7 @@ 1 2 -4943740 +4765273 @@ -35183,7 +35781,7 @@ 1 2 -4943740 +4765273 @@ -35199,97 +35797,97 @@ 2 3 -12 +11 28 29 -12 +11 338 339 -12 +11 473 474 -12 +11 690 691 -12 +11 1560 1561 -12 +11 1757 1758 -12 +11 -2076 -2077 -12 +2080 +2081 +11 -2191 -2192 -12 +2193 +2194 +11 2707 2708 -12 +11 2748 2749 -12 +11 -2944 -2945 -12 +2946 +2947 +11 3296 3297 -12 +11 4540 4541 -12 +11 -28688 -28689 -12 +28694 +28695 +11 -53254 -53255 -12 +53369 +53370 +11 -85878 -85879 -12 +86211 +86212 +11 -98483 -98484 -12 +98824 +98825 +11 -115024 -115025 -12 +115365 +115366 +11 @@ -35305,97 +35903,97 @@ 2 3 -12 +11 23 24 -12 +11 106 107 -12 +11 112 113 -12 +11 178 179 -12 +11 252 253 -12 +11 296 297 -12 +11 661 662 -12 +11 663 664 -12 +11 991 992 -12 +11 1030 1031 -12 +11 1408 1409 -12 +11 1918 1919 -12 +11 2676 2677 -12 +11 10172 10173 -12 +11 10231 10232 -12 +11 22268 22269 -12 +11 26534 26535 -12 +11 31957 31958 -12 +11 @@ -35411,32 +36009,32 @@ 1 2 -779628 +747015 2 3 -179173 +173050 3 4 -120275 +116169 4 6 -106891 +103199 6 19 -102794 +99168 19 -4895 -28810 +4923 +27844 @@ -35452,12 +36050,12 @@ 1 2 -1291693 +1241571 2 9 -25881 +24876 @@ -35563,15 +36161,15 @@ if_then -524558 +524866 if_stmt -524558 +524866 then_id -524558 +524866 @@ -35585,7 +36183,7 @@ 1 2 -524558 +524866 @@ -35601,7 +36199,7 @@ 1 2 -524558 +524866 @@ -35611,15 +36209,15 @@ if_else -148234 +148322 if_stmt -148234 +148322 else_id -148234 +148322 @@ -35633,7 +36231,7 @@ 1 2 -148234 +148322 @@ -35649,7 +36247,7 @@ 1 2 -148234 +148322 @@ -35755,15 +36353,15 @@ while_body -32907 +31630 while_stmt -32907 +31630 body_id -32907 +31630 @@ -35777,7 +36375,7 @@ 1 2 -32907 +31630 @@ -35793,7 +36391,7 @@ 1 2 -32907 +31630 @@ -35803,15 +36401,15 @@ do_body -149900 +149988 do_stmt -149900 +149988 body_id -149900 +149988 @@ -35825,7 +36423,7 @@ 1 2 -149900 +149988 @@ -35841,7 +36439,7 @@ 1 2 -149900 +149988 @@ -35851,11 +36449,11 @@ switch_case -281530 +281695 switch_stmt -55225 +55258 index @@ -35863,7 +36461,7 @@ case_id -281530 +281695 @@ -35877,17 +36475,17 @@ 1 5 -4288 +4290 5 6 -48725 +48753 6 156 -2212 +2213 @@ -35903,17 +36501,17 @@ 1 5 -4288 +4290 5 6 -48725 +48753 6 156 -2212 +2213 @@ -36031,7 +36629,7 @@ 1 2 -281530 +281695 @@ -36047,7 +36645,7 @@ 1 2 -281530 +281695 @@ -36057,15 +36655,15 @@ switch_body -55225 +55258 switch_stmt -55225 +55258 body_id -55225 +55258 @@ -36079,7 +36677,7 @@ 1 2 -55225 +55258 @@ -36095,7 +36693,7 @@ 1 2 -55225 +55258 @@ -36105,15 +36703,15 @@ for_initialization -29922 +29619 for_stmt -29922 +29619 init_id -29922 +29619 @@ -36127,7 +36725,7 @@ 1 2 -29922 +29619 @@ -36143,7 +36741,7 @@ 1 2 -29922 +29619 @@ -36153,15 +36751,15 @@ for_condition -31781 +31459 for_stmt -31781 +31459 condition_id -31781 +31459 @@ -36175,7 +36773,7 @@ 1 2 -31781 +31459 @@ -36191,7 +36789,7 @@ 1 2 -31781 +31459 @@ -36201,15 +36799,15 @@ for_update -29659 +29358 for_stmt -29659 +29358 update_id -29659 +29358 @@ -36223,7 +36821,7 @@ 1 2 -29659 +29358 @@ -36239,7 +36837,7 @@ 1 2 -29659 +29358 @@ -36249,15 +36847,15 @@ for_body -32387 +32059 for_stmt -32387 +32059 body_id -32387 +32059 @@ -36271,7 +36869,7 @@ 1 2 -32387 +32059 @@ -36287,7 +36885,7 @@ 1 2 -32387 +32059 @@ -36297,19 +36895,19 @@ stmtparents -4168478 +4131960 id -4168478 +4131960 index -12799 +836 parent -1762006 +1583254 @@ -36323,7 +36921,7 @@ 1 2 -4168478 +4131960 @@ -36339,7 +36937,7 @@ 1 2 -4168478 +4131960 @@ -36355,52 +36953,57 @@ 1 2 -4020 +182 2 3 -1094 +149 3 -4 -520 +5 +41 -4 -5 -1496 +5 +7 +72 7 -8 -1047 +9 +68 -8 -12 -830 +9 +18 +63 -12 -29 -1127 +18 +39 +64 -29 -37 -909 +39 +111 +63 -37 -74 -975 +112 +836 +63 -74 -191996 -777 +920 +136298 +63 + + +254134 +706946 +5 @@ -36416,52 +37019,57 @@ 1 2 -4020 +182 2 3 -1094 +149 3 -4 -520 +5 +41 -4 -5 -1496 +5 +7 +72 7 -8 -1047 +9 +68 -8 -12 -830 +9 +18 +63 -12 -29 -1127 +18 +39 +64 -29 -37 -909 +39 +111 +63 -37 -74 -975 +112 +836 +63 -74 -191996 -777 +920 +136298 +63 + + +254134 +706946 +5 @@ -36477,32 +37085,27 @@ 1 2 -1004414 +841847 2 3 -386602 +376317 3 4 -109343 +145318 4 -6 -115439 +9 +119501 -6 -17 -133386 - - -17 -1943 -12819 +9 +465 +100269 @@ -36518,32 +37121,27 @@ 1 2 -1004414 +841847 2 3 -386602 +376317 3 4 -109343 +145318 4 -6 -115439 +9 +119501 -6 -17 -133386 - - -17 -1943 -12819 +9 +465 +100269 @@ -36553,26 +37151,26 @@ ishandler -21888 +21666 block -21888 +21666 successors -17214104 +17224218 from -16042874 +16052300 to -16040997 +16050421 @@ -36586,12 +37184,12 @@ 1 2 -15044821 +15053661 2 156 -998052 +998638 @@ -36607,12 +37205,12 @@ 1 2 -15328885 +15337891 2 419 -712111 +712530 @@ -36622,15 +37220,15 @@ truecond -966805 +967373 from -966805 +967373 to -937112 +937663 @@ -36644,7 +37242,7 @@ 1 2 -966805 +967373 @@ -36660,12 +37258,12 @@ 1 2 -913540 +914077 2 21 -23572 +23585 @@ -36675,15 +37273,15 @@ falsecond -966805 +967373 from -966805 +967373 to -812105 +812583 @@ -36697,7 +37295,7 @@ 1 2 -966805 +967373 @@ -36713,17 +37311,17 @@ 1 2 -698749 +699160 2 3 -87006 +87057 3 25 -26349 +26365 @@ -36733,11 +37331,11 @@ stmt_decl_bind -538233 +532777 stmt -531279 +525894 num @@ -36745,7 +37343,7 @@ decl -538233 +532777 @@ -36759,12 +37357,12 @@ 1 2 -525776 +520447 2 9 -5503 +5447 @@ -36780,12 +37378,12 @@ 1 2 -525756 +520427 2 9 -5523 +5467 @@ -36903,7 +37501,7 @@ 1 2 -538233 +532777 @@ -36919,7 +37517,7 @@ 1 2 -538233 +532777 @@ -36929,19 +37527,19 @@ stmt_decl_entry_bind -519726 +520031 stmt -474524 +474803 num -491 +492 decl_entry -495657 +495948 @@ -36955,12 +37553,12 @@ 1 2 -441842 +442101 2 274 -32682 +32702 @@ -36976,12 +37574,12 @@ 1 2 -441842 +442101 2 15 -32682 +32702 @@ -37064,12 +37662,12 @@ 1 2 -483634 +483918 2 85 -12022 +12029 @@ -37085,7 +37683,7 @@ 1 2 -495588 +495879 2 @@ -37100,15 +37698,15 @@ blockscope -1398256 +1347984 block -1398256 +1347984 enclosing -1254288 +1209602 @@ -37122,7 +37720,7 @@ 1 2 -1398256 +1347984 @@ -37138,12 +37736,12 @@ 1 2 -1171636 +1130157 2 509 -82651 +79444 @@ -37153,19 +37751,19 @@ jumpinfo -366503 +366719 id -366503 +366719 str -6361 +6365 target -85508 +85558 @@ -37179,7 +37777,7 @@ 1 2 -366503 +366719 @@ -37195,7 +37793,7 @@ 1 2 -366503 +366719 @@ -37216,12 +37814,12 @@ 2 3 -3507 +3509 3 4 -835 +836 4 @@ -37231,12 +37829,12 @@ 5 7 -491 +492 7 15 -500 +501 15 @@ -37257,12 +37855,12 @@ 1 2 -5095 +5098 2 3 -700 +701 3 @@ -37293,32 +37891,32 @@ 2 3 -21251 +21263 3 4 -7559 +7564 4 5 -3816 +3818 5 6 -39695 +39718 6 7 -11019 +11025 7 162 -1880 +1882 @@ -37334,7 +37932,7 @@ 1 2 -85508 +85558 @@ -37344,19 +37942,19 @@ preprocdirects -1456121 +1399618 id -1456121 +1399618 kind -158 +151 location -1449131 +1392900 @@ -37370,7 +37968,7 @@ 1 2 -1456121 +1399618 @@ -37386,7 +37984,7 @@ 1 2 -1456121 +1399618 @@ -37402,67 +38000,67 @@ 4 5 -12 +11 8 9 -12 +11 500 501 -12 +11 929 930 -12 +11 1740 1741 -12 +11 1873 1874 -12 +11 5235 5236 -12 +11 5497 5498 -12 +11 7551 7552 -12 +11 14073 14074 -12 +11 26464 26465 -12 +11 27121 27122 -12 +11 28787 28788 -12 +11 @@ -37478,67 +38076,67 @@ 4 5 -12 +11 7 8 -12 +11 500 501 -12 +11 929 930 -12 +11 1740 1741 -12 +11 1873 1874 -12 +11 5235 5236 -12 +11 5497 5498 -12 +11 7551 7552 -12 +11 14073 14074 -12 +11 26122 26123 -12 +11 27121 27122 -12 +11 28555 28556 -12 +11 @@ -37554,12 +38152,12 @@ 1 2 -1448766 +1392549 2 234 -364 +350 @@ -37575,7 +38173,7 @@ 1 2 -1449131 +1392900 @@ -37585,15 +38183,15 @@ preprocpair -416102 +399956 begin -329694 +316901 elseelifend -416102 +399956 @@ -37607,17 +38205,17 @@ 1 2 -261399 +251256 2 3 -60247 +57909 3 53 -8047 +7735 @@ -37633,7 +38231,7 @@ 1 2 -416102 +399956 @@ -37643,41 +38241,41 @@ preproctrue -183112 +176006 branch -183112 +176006 preprocfalse -130000 +124956 branch -130000 +124956 preproctext -1062775 +1021536 id -1062775 +1021536 head -510083 +490290 body -192959 +185471 @@ -37691,7 +38289,7 @@ 1 2 -1062775 +1021536 @@ -37707,7 +38305,7 @@ 1 2 -1062775 +1021536 @@ -37723,22 +38321,22 @@ 1 2 -380459 +365696 2 3 -86116 +82774 3 19 -38414 +36923 19 752 -5093 +4895 @@ -37754,12 +38352,12 @@ 1 2 -486208 +467341 2 38 -23875 +22948 @@ -37775,12 +38373,12 @@ 1 2 -181252 +174219 2 64395 -11706 +11252 @@ -37796,12 +38394,12 @@ 1 2 -182893 +175796 2 21671 -10065 +9674 @@ -37811,15 +38409,15 @@ includes -321805 +309317 id -321805 +309317 included -60162 +57827 @@ -37833,7 +38431,7 @@ 1 2 -321805 +309317 @@ -37849,37 +38447,37 @@ 1 2 -29503 +28358 2 3 -9895 +9511 3 4 -5117 +4919 4 6 -5348 +5141 6 11 -4643 +4463 11 41 -4558 +4381 41 763 -1094 +1051 @@ -37889,15 +38487,15 @@ link_targets -644 +619 id -644 +619 binary -644 +619 @@ -37911,7 +38509,7 @@ 1 2 -644 +619 @@ -37927,7 +38525,7 @@ 1 2 -644 +619 @@ -37937,15 +38535,15 @@ link_parent -19143690 +19072521 element -5076549 +5117392 link_target -644 +619 @@ -37959,32 +38557,32 @@ 1 2 -1439430 +1455425 2 3 -1904730 +1924496 3 4 -772395 +779113 4 6 -426167 +434215 6 -27 -383109 +28 +394382 -27 +28 45 -150715 +129758 @@ -38000,67 +38598,67 @@ 2 3 -97 +93 5 557 -48 +46 -2555 -5912 -48 +2662 +6059 +46 -6322 -8240 -48 +6479 +8402 +46 -9873 -12705 -48 +10060 +12929 +46 -12726 -19568 -48 +13044 +20082 +46 -24613 -26319 -48 +24978 +26985 +46 -26410 -31881 -48 +27088 +32537 +46 -32502 -37729 -48 +33104 +38465 +46 -39858 -40615 -48 +41123 +42511 +46 -43096 -52498 -48 +44410 +55889 +46 -53361 -126529 -48 +55937 +132605 +46 -345660 -345661 -12 +362472 +362473 +11 diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/BarrierGuard.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/BarrierGuard.cpp new file mode 100644 index 00000000000..9c3c8bc4569 --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/BarrierGuard.cpp @@ -0,0 +1,68 @@ +int source(); +void sink(int); +bool guarded(int); + +void bg_basic(int source) { + if (guarded(source)) { + sink(source); // no flow + } else { + sink(source); // flow + } +} + +void bg_not(int source) { + if (!guarded(source)) { + sink(source); // flow + } else { + sink(source); // no flow + } +} + +void bg_and(int source, bool arbitrary) { + if (guarded(source) && arbitrary) { + sink(source); // no flow + } else { + sink(source); // flow + } +} + +void bg_or(int source, bool arbitrary) { + if (guarded(source) || arbitrary) { + sink(source); // flow + } else { + sink(source); // flow + } +} + +void bg_return(int source) { + if (!guarded(source)) { + return; + } + sink(source); // no flow +} + +struct XY { + int x, y; +}; + +void bg_stackstruct(XY s1, XY s2) { + s1.x = source(); + if (guarded(s1.x)) { + sink(s1.x); // no flow + } else if (guarded(s1.y)) { + sink(s1.x); // flow + } else if (guarded(s2.y)) { + sink(s1.x); // flow + } +} + +void bg_structptr(XY *p1, XY *p2) { + p1->x = source(); + if (guarded(p1->x)) { + sink(p1->x); // no flow [FALSE POSITIVE in AST] + } else if (guarded(p1->y)) { + sink(p1->x); // flow [NOT DETECTED in IR] + } else if (guarded(p2->x)) { + sink(p1->x); // flow [NOT DETECTED in IR] + } +} diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/DataflowTestCommon.qll b/cpp/ql/test/library-tests/dataflow/dataflow-tests/DataflowTestCommon.qll index 02ee4d45380..a81394640ee 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/DataflowTestCommon.qll +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/DataflowTestCommon.qll @@ -1,6 +1,20 @@ import cpp import semmle.code.cpp.dataflow.DataFlow +/** + * A `BarrierGuard` that stops flow to all occurrences of `x` within statement + * S in `if (guarded(x)) S`. + */ +// This is tested in `BarrierGuard.cpp`. +class TestBarrierGuard extends DataFlow::BarrierGuard { + TestBarrierGuard() { this.(FunctionCall).getTarget().getName() = "guarded" } + + override predicate checks(Expr checked, boolean isTrue) { + checked = this.(FunctionCall).getArgument(0) and + isTrue = true + } +} + /** Common data flow configuration to be used by tests. */ class TestAllocationConfig extends DataFlow::Configuration { TestAllocationConfig() { this = "TestAllocationConfig" } @@ -26,4 +40,6 @@ class TestAllocationConfig extends DataFlow::Configuration { override predicate isBarrier(DataFlow::Node barrier) { barrier.asExpr().(VariableAccess).getTarget().hasName("barrier") } + + override predicate isBarrierGuard(DataFlow::BarrierGuard bg) { bg instanceof TestBarrierGuard } } diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/IRDataflowTestCommon.qll b/cpp/ql/test/library-tests/dataflow/dataflow-tests/IRDataflowTestCommon.qll index eb5fa14e2e0..490f7e4290a 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/IRDataflowTestCommon.qll +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/IRDataflowTestCommon.qll @@ -1,5 +1,20 @@ import cpp import semmle.code.cpp.ir.dataflow.DataFlow +import semmle.code.cpp.ir.IR + +/** + * A `BarrierGuard` that stops flow to all occurrences of `x` within statement + * S in `if (guarded(x)) S`. + */ +// This is tested in `BarrierGuard.cpp`. +class TestBarrierGuard extends DataFlow::BarrierGuard { + TestBarrierGuard() { this.(CallInstruction).getStaticCallTarget().getName() = "guarded" } + + override predicate checks(Instruction checked, boolean isTrue) { + checked = this.(CallInstruction).getPositionalArgument(0) and + isTrue = true + } +} /** Common data flow configuration to be used by tests. */ class TestAllocationConfig extends DataFlow::Configuration { @@ -24,4 +39,6 @@ class TestAllocationConfig extends DataFlow::Configuration { override predicate isBarrier(DataFlow::Node barrier) { barrier.asExpr().(VariableAccess).getTarget().hasName("barrier") } + + override predicate isBarrierGuard(DataFlow::BarrierGuard bg) { bg instanceof TestBarrierGuard } } diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dispatch.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dispatch.cpp new file mode 100644 index 00000000000..5e4f2f97f46 --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dispatch.cpp @@ -0,0 +1,46 @@ +int source(); +void sink(int); + +// This class has the opposite behavior of what the member function names suggest. +struct Top { + virtual int isSource1() { return 0; } + virtual int isSource2() { return 0; } + virtual void isSink(int x) { } + virtual int notSource1() { return source(); } + virtual int notSource2() { return source(); } + virtual void notSink(int x) { sink(x); } +}; + +// This class has the correct behavior for just the functions ending in 2. +struct Middle : Top { + int isSource2() override { return source(); } + int notSource2() override { return 0; } +}; + +// This class has all the behavior suggested by the function names. +struct Bottom : Middle { + int isSource1() override { return source(); } + void isSink(int x) override { sink(x); } + int notSource1() override { return 0; } + void notSink(int x) override { } +}; + +void VirtualDispatch(Bottom *bottomPtr, Bottom &bottomRef) { + Top *topPtr = bottomPtr, &topRef = bottomRef; + + sink(topPtr->isSource1()); // flow [NOT DETECTED by AST] + sink(topPtr->isSource2()); // flow [NOT DETECTED by AST] + topPtr->isSink(source()); // flow [NOT DETECTED by AST] + + sink(topPtr->notSource1()); // no flow [FALSE POSITIVE] + sink(topPtr->notSource2()); // no flow [FALSE POSITIVE] + topPtr->notSink(source()); // no flow [FALSE POSITIVE] + + sink(topRef.isSource1()); // flow [NOT DETECTED by AST] + sink(topRef.isSource2()); // flow [NOT DETECTED by AST] + topRef.isSink(source()); // flow [NOT DETECTED by AST] + + sink(topRef.notSource1()); // no flow [FALSE POSITIVE] + sink(topRef.notSource2()); // no flow [FALSE POSITIVE] + topRef.notSink(source()); // no flow [FALSE POSITIVE] +} diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected index b9fca1f678f..24fa6fdb5bd 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected @@ -1,3 +1,13 @@ +| BarrierGuard.cpp:9:10:9:15 | source | BarrierGuard.cpp:5:19:5:24 | source | +| BarrierGuard.cpp:15:10:15:15 | source | BarrierGuard.cpp:13:17:13:22 | source | +| BarrierGuard.cpp:25:10:25:15 | source | BarrierGuard.cpp:21:17:21:22 | source | +| BarrierGuard.cpp:31:10:31:15 | source | BarrierGuard.cpp:29:16:29:21 | source | +| BarrierGuard.cpp:33:10:33:15 | source | BarrierGuard.cpp:29:16:29:21 | source | +| BarrierGuard.cpp:53:13:53:13 | x | BarrierGuard.cpp:49:10:49:15 | call to source | +| BarrierGuard.cpp:55:13:55:13 | x | BarrierGuard.cpp:49:10:49:15 | call to source | +| BarrierGuard.cpp:62:14:62:14 | x | BarrierGuard.cpp:60:11:60:16 | call to source | +| BarrierGuard.cpp:64:14:64:14 | x | BarrierGuard.cpp:60:11:60:16 | call to source | +| BarrierGuard.cpp:66:14:66:14 | x | BarrierGuard.cpp:60:11:60:16 | call to source | | acrossLinkTargets.cpp:12:8:12:8 | x | acrossLinkTargets.cpp:19:27:19:32 | call to source | | clang.cpp:18:8:18:19 | sourceArray1 | clang.cpp:12:9:12:20 | sourceArray1 | | clang.cpp:22:8:22:20 | & ... | clang.cpp:12:9:12:20 | sourceArray1 | @@ -5,6 +15,12 @@ | clang.cpp:30:27:30:34 | call to getFirst | clang.cpp:28:27:28:32 | call to source | | clang.cpp:37:10:37:11 | m2 | clang.cpp:34:32:34:37 | call to source | | clang.cpp:45:17:45:18 | m2 | clang.cpp:43:35:43:40 | call to source | +| dispatch.cpp:11:38:11:38 | x | dispatch.cpp:37:19:37:24 | call to source | +| dispatch.cpp:11:38:11:38 | x | dispatch.cpp:45:18:45:23 | call to source | +| dispatch.cpp:35:16:35:25 | call to notSource1 | dispatch.cpp:9:37:9:42 | call to source | +| dispatch.cpp:36:16:36:25 | call to notSource2 | dispatch.cpp:10:37:10:42 | call to source | +| dispatch.cpp:43:15:43:24 | call to notSource1 | dispatch.cpp:9:37:9:42 | call to source | +| dispatch.cpp:44:15:44:24 | call to notSource2 | dispatch.cpp:10:37:10:42 | call to source | | lambdas.cpp:14:3:14:6 | t | lambdas.cpp:8:10:8:15 | call to source | | lambdas.cpp:18:8:18:8 | call to operator() | lambdas.cpp:8:10:8:15 | call to source | | lambdas.cpp:21:3:21:6 | t | lambdas.cpp:8:10:8:15 | call to source | diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_diff.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_diff.expected index 0af544675d7..d0961962f29 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_diff.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_diff.expected @@ -1,8 +1,17 @@ +| BarrierGuard.cpp:60:11:60:16 | BarrierGuard.cpp:62:14:62:14 | AST only | +| BarrierGuard.cpp:60:11:60:16 | BarrierGuard.cpp:64:14:64:14 | AST only | +| BarrierGuard.cpp:60:11:60:16 | BarrierGuard.cpp:66:14:66:14 | AST only | | clang.cpp:12:9:12:20 | clang.cpp:18:8:18:19 | AST only | | clang.cpp:12:9:12:20 | clang.cpp:22:8:22:20 | AST only | | clang.cpp:28:27:28:32 | clang.cpp:29:27:29:28 | AST only | | clang.cpp:28:27:28:32 | clang.cpp:30:27:30:34 | AST only | | clang.cpp:39:42:39:47 | clang.cpp:41:18:41:19 | IR only | +| dispatch.cpp:16:37:16:42 | dispatch.cpp:32:16:32:24 | IR only | +| dispatch.cpp:16:37:16:42 | dispatch.cpp:40:15:40:23 | IR only | +| dispatch.cpp:22:37:22:42 | dispatch.cpp:31:16:31:24 | IR only | +| dispatch.cpp:22:37:22:42 | dispatch.cpp:39:15:39:23 | IR only | +| dispatch.cpp:33:18:33:23 | dispatch.cpp:23:38:23:38 | IR only | +| dispatch.cpp:41:17:41:22 | dispatch.cpp:23:38:23:38 | IR only | | lambdas.cpp:8:10:8:15 | lambdas.cpp:14:3:14:6 | AST only | | lambdas.cpp:8:10:8:15 | lambdas.cpp:18:8:18:8 | AST only | | lambdas.cpp:8:10:8:15 | lambdas.cpp:21:3:21:6 | AST only | diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_ir.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_ir.expected index ec1fc39b04e..2e97f6812f4 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_ir.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_ir.expected @@ -1,8 +1,27 @@ +| BarrierGuard.cpp:9:10:9:15 | Load: source | BarrierGuard.cpp:5:19:5:24 | InitializeParameter: source | +| BarrierGuard.cpp:15:10:15:15 | Load: source | BarrierGuard.cpp:13:17:13:22 | InitializeParameter: source | +| BarrierGuard.cpp:25:10:25:15 | Load: source | BarrierGuard.cpp:21:17:21:22 | InitializeParameter: source | +| BarrierGuard.cpp:31:10:31:15 | Load: source | BarrierGuard.cpp:29:16:29:21 | InitializeParameter: source | +| BarrierGuard.cpp:33:10:33:15 | Load: source | BarrierGuard.cpp:29:16:29:21 | InitializeParameter: source | +| BarrierGuard.cpp:53:13:53:13 | Load: x | BarrierGuard.cpp:49:10:49:15 | Call: call to source | +| BarrierGuard.cpp:55:13:55:13 | Load: x | BarrierGuard.cpp:49:10:49:15 | Call: call to source | | acrossLinkTargets.cpp:12:8:12:8 | Convert: (int)... | acrossLinkTargets.cpp:19:27:19:32 | Call: call to source | | acrossLinkTargets.cpp:12:8:12:8 | Load: x | acrossLinkTargets.cpp:19:27:19:32 | Call: call to source | | clang.cpp:37:10:37:11 | Load: m2 | clang.cpp:34:32:34:37 | Call: call to source | | clang.cpp:41:18:41:19 | Load: m2 | clang.cpp:39:42:39:47 | Call: call to source | | clang.cpp:45:17:45:18 | Load: m2 | clang.cpp:43:35:43:40 | Call: call to source | +| dispatch.cpp:11:38:11:38 | Load: x | dispatch.cpp:37:19:37:24 | Call: call to source | +| dispatch.cpp:11:38:11:38 | Load: x | dispatch.cpp:45:18:45:23 | Call: call to source | +| dispatch.cpp:23:38:23:38 | Load: x | dispatch.cpp:33:18:33:23 | Call: call to source | +| dispatch.cpp:23:38:23:38 | Load: x | dispatch.cpp:41:17:41:22 | Call: call to source | +| dispatch.cpp:31:16:31:24 | Call: call to isSource1 | dispatch.cpp:22:37:22:42 | Call: call to source | +| dispatch.cpp:32:16:32:24 | Call: call to isSource2 | dispatch.cpp:16:37:16:42 | Call: call to source | +| dispatch.cpp:35:16:35:25 | Call: call to notSource1 | dispatch.cpp:9:37:9:42 | Call: call to source | +| dispatch.cpp:36:16:36:25 | Call: call to notSource2 | dispatch.cpp:10:37:10:42 | Call: call to source | +| dispatch.cpp:39:15:39:23 | Call: call to isSource1 | dispatch.cpp:22:37:22:42 | Call: call to source | +| dispatch.cpp:40:15:40:23 | Call: call to isSource2 | dispatch.cpp:16:37:16:42 | Call: call to source | +| dispatch.cpp:43:15:43:24 | Call: call to notSource1 | dispatch.cpp:9:37:9:42 | Call: call to source | +| dispatch.cpp:44:15:44:24 | Call: call to notSource2 | dispatch.cpp:10:37:10:42 | Call: call to source | | test.cpp:7:8:7:9 | Load: t1 | test.cpp:6:12:6:17 | Call: call to source | | test.cpp:9:8:9:9 | Load: t1 | test.cpp:6:12:6:17 | Call: call to source | | test.cpp:10:8:10:9 | Load: t2 | test.cpp:6:12:6:17 | Call: call to source | diff --git a/cpp/ql/test/library-tests/ir/escape/points_to.expected b/cpp/ql/test/library-tests/ir/escape/points_to.expected index f40460f4d91..ac518b5dd79 100644 --- a/cpp/ql/test/library-tests/ir/escape/points_to.expected +++ b/cpp/ql/test/library-tests/ir/escape/points_to.expected @@ -1,6 +1,16 @@ +| escape.cpp:111:18:111:21 | CopyValue | no_+0:0 | no_+0:0 | | escape.cpp:115:19:115:28 | PointerAdd[4] | no_+0:0 | no_+0:0 | +| escape.cpp:115:20:115:23 | CopyValue | no_+0:0 | no_+0:0 | | escape.cpp:116:19:116:28 | PointerSub[4] | no_+0:0 | no_+0:0 | +| escape.cpp:116:20:116:23 | CopyValue | no_+0:0 | no_+0:0 | | escape.cpp:117:19:117:26 | PointerAdd[4] | no_+0:0 | no_+0:0 | +| escape.cpp:117:23:117:26 | CopyValue | no_+0:0 | no_+0:0 | +| escape.cpp:118:9:118:12 | CopyValue | no_+0:0 | no_+0:0 | +| escape.cpp:120:12:120:15 | CopyValue | no_+0:0 | no_+0:0 | +| escape.cpp:123:14:123:17 | CopyValue | no_+0:0 | no_+0:0 | +| escape.cpp:124:15:124:18 | CopyValue | no_+0:0 | no_+0:0 | +| escape.cpp:127:9:127:12 | CopyValue | no_+0:0 | no_+0:0 | +| escape.cpp:129:12:129:15 | CopyValue | no_+0:0 | no_+0:0 | | escape.cpp:134:5:134:18 | Convert | no_Array+0:0 | no_Array+0:0 | | escape.cpp:134:11:134:18 | Convert | no_Array+0:0 | no_Array+0:0 | | escape.cpp:135:5:135:12 | Convert | no_Array+0:0 | no_Array+0:0 | @@ -16,32 +26,61 @@ | escape.cpp:140:21:140:32 | FieldAddress[z] | no_Point+8:0 | no_Point+8:0 | | escape.cpp:141:27:141:27 | FieldAddress[x] | no_Point+0:0 | no_Point+0:0 | | escape.cpp:142:14:142:14 | FieldAddress[y] | no_Point+4:0 | no_Point+4:0 | +| escape.cpp:143:19:143:27 | CopyValue | no_Point+0:0 | no_Point+0:0 | | escape.cpp:143:31:143:31 | FieldAddress[y] | no_Point+4:0 | no_Point+4:0 | +| escape.cpp:144:6:144:14 | CopyValue | no_Point+0:0 | no_Point+0:0 | | escape.cpp:144:18:144:18 | FieldAddress[y] | no_Point+4:0 | no_Point+4:0 | +| escape.cpp:145:20:145:30 | CopyValue | no_Point+8:0 | no_Point+8:0 | | escape.cpp:145:30:145:30 | FieldAddress[z] | no_Point+8:0 | no_Point+8:0 | +| escape.cpp:146:5:146:18 | CopyValue | no_Point+8:0 | no_Point+8:0 | +| escape.cpp:146:7:146:17 | CopyValue | no_Point+8:0 | no_Point+8:0 | | escape.cpp:146:17:146:17 | FieldAddress[z] | no_Point+8:0 | no_Point+8:0 | -| escape.cpp:149:5:149:14 | ConvertToBase[Derived : Intermediate1] | no_Derived+0:0 | no_Derived+0:0 | -| escape.cpp:149:5:149:14 | ConvertToBase[Intermediate1 : Base] | no_Derived+0:0 | no_Derived+0:0 | +| escape.cpp:149:5:149:14 | ConvertToNonVirtualBase[Derived : Intermediate1] | no_Derived+0:0 | no_Derived+0:0 | +| escape.cpp:149:5:149:14 | ConvertToNonVirtualBase[Intermediate1 : Base] | no_Derived+0:0 | no_Derived+0:0 | | escape.cpp:149:16:149:16 | FieldAddress[b] | no_Derived+0:0 | no_Derived+0:0 | -| escape.cpp:150:18:150:27 | ConvertToBase[Derived : Intermediate1] | no_Derived+0:0 | no_Derived+0:0 | -| escape.cpp:150:18:150:27 | ConvertToBase[Intermediate1 : Base] | no_Derived+0:0 | no_Derived+0:0 | +| escape.cpp:150:18:150:27 | ConvertToNonVirtualBase[Derived : Intermediate1] | no_Derived+0:0 | no_Derived+0:0 | +| escape.cpp:150:18:150:27 | ConvertToNonVirtualBase[Intermediate1 : Base] | no_Derived+0:0 | no_Derived+0:0 | | escape.cpp:150:29:150:29 | FieldAddress[b] | no_Derived+0:0 | no_Derived+0:0 | -| escape.cpp:151:5:151:14 | ConvertToBase[Derived : Intermediate2] | no_Derived+12:0 | no_Derived+12:0 | +| escape.cpp:151:5:151:14 | ConvertToNonVirtualBase[Derived : Intermediate2] | no_Derived+12:0 | no_Derived+12:0 | | escape.cpp:151:16:151:17 | FieldAddress[i2] | no_Derived+16:0 | no_Derived+16:0 | -| escape.cpp:152:19:152:28 | ConvertToBase[Derived : Intermediate2] | no_Derived+12:0 | no_Derived+12:0 | +| escape.cpp:152:19:152:28 | ConvertToNonVirtualBase[Derived : Intermediate2] | no_Derived+12:0 | no_Derived+12:0 | | escape.cpp:152:30:152:31 | FieldAddress[i2] | no_Derived+16:0 | no_Derived+16:0 | +| escape.cpp:155:17:155:30 | CopyValue | no_ssa_addrOf+0:0 | no_ssa_addrOf+0:0 | | escape.cpp:155:17:155:30 | Store | no_ssa_addrOf+0:0 | no_ssa_addrOf+0:0 | +| escape.cpp:158:17:158:28 | CopyValue | no_ssa_refTo+0:0 | no_ssa_refTo+0:0 | | escape.cpp:158:17:158:28 | Store | no_ssa_refTo+0:0 | no_ssa_refTo+0:0 | | escape.cpp:161:19:161:42 | Convert | no_ssa_refToArrayElement+0:0 | no_ssa_refToArrayElement+0:0 | +| escape.cpp:161:19:161:45 | CopyValue | no_ssa_refToArrayElement+20:0 | no_ssa_refToArrayElement+20:0 | | escape.cpp:161:19:161:45 | PointerAdd[4] | no_ssa_refToArrayElement+20:0 | no_ssa_refToArrayElement+20:0 | | escape.cpp:161:19:161:45 | Store | no_ssa_refToArrayElement+20:0 | no_ssa_refToArrayElement+20:0 | +| escape.cpp:164:24:164:40 | CopyValue | no_ssa_refToArray+0:0 | no_ssa_refToArray+0:0 | | escape.cpp:164:24:164:40 | Store | no_ssa_refToArray+0:0 | no_ssa_refToArray+0:0 | +| escape.cpp:167:19:167:28 | CopyValue | passByPtr+0:0 | passByPtr+0:0 | +| escape.cpp:170:21:170:29 | CopyValue | passByRef+0:0 | passByRef+0:0 | +| escape.cpp:173:22:173:38 | CopyValue | no_ssa_passByPtr+0:0 | no_ssa_passByPtr+0:0 | +| escape.cpp:176:24:176:39 | CopyValue | no_ssa_passByRef+0:0 | no_ssa_passByRef+0:0 | +| escape.cpp:179:22:179:42 | CopyValue | no_ssa_passByPtr_ret+0:0 | no_ssa_passByPtr_ret+0:0 | +| escape.cpp:182:24:182:43 | CopyValue | no_ssa_passByRef_ret+0:0 | no_ssa_passByRef_ret+0:0 | +| escape.cpp:185:30:185:40 | CopyValue | passByPtr2+0:0 | passByPtr2+0:0 | +| escape.cpp:188:32:188:41 | CopyValue | passByRef2+0:0 | passByRef2+0:0 | | escape.cpp:191:30:191:42 | Call | none | passByPtr3+0:0 | +| escape.cpp:191:44:191:54 | CopyValue | passByPtr3+0:0 | passByPtr3+0:0 | | escape.cpp:194:32:194:46 | Call | none | passByRef3+0:0 | +| escape.cpp:194:32:194:59 | CopyValue | none | passByRef3+0:0 | +| escape.cpp:194:48:194:57 | CopyValue | passByRef3+0:0 | passByRef3+0:0 | +| escape.cpp:199:17:199:34 | CopyValue | no_ssa_passByPtr4+0:0 | no_ssa_passByPtr4+0:0 | +| escape.cpp:199:37:199:54 | CopyValue | no_ssa_passByPtr5+0:0 | no_ssa_passByPtr5+0:0 | | escape.cpp:202:5:202:19 | Call | none | passByRef6+0:0 | +| escape.cpp:202:5:202:32 | CopyValue | none | passByRef6+0:0 | +| escape.cpp:202:21:202:30 | CopyValue | passByRef6+0:0 | passByRef6+0:0 | | escape.cpp:205:5:205:19 | Call | none | no_ssa_passByRef7+0:0 | +| escape.cpp:205:5:205:39 | CopyValue | none | no_ssa_passByRef7+0:0 | +| escape.cpp:205:21:205:37 | CopyValue | no_ssa_passByRef7+0:0 | no_ssa_passByRef7+0:0 | | escape.cpp:209:14:209:25 | Call | none | no_ssa_c+0:0 | +| escape.cpp:217:14:217:16 | CopyValue | c2+0:0 | c2+0:0 | | escape.cpp:221:8:221:19 | Call | none | c3+0:0 | | escape.cpp:225:17:225:28 | Call | none | c4+0:0 | | escape.cpp:247:2:247:27 | Store | condEscape1+0:0 | condEscape1+0:0 | +| escape.cpp:247:16:247:27 | CopyValue | condEscape1+0:0 | condEscape1+0:0 | | escape.cpp:249:9:249:34 | Store | condEscape2+0:0 | condEscape2+0:0 | +| escape.cpp:249:23:249:34 | CopyValue | condEscape2+0:0 | condEscape2+0:0 | diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index 3e393151f9b..dab6a40fae6 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -67,7 +67,7 @@ bad_asts.cpp: # 5| params: #-----| 0: [Parameter] p#0 #-----| Type = [RValueReferenceType] S && -# 9| [FunctionTemplateInstantiation,MemberFunction] int Bad::S::MemberFunction(int) +# 9| [FunctionTemplateInstantiation,MemberFunction] int Bad::S::MemberFunction(int) # 9| params: # 9| 0: [Parameter] y # 9| Type = [IntType] int @@ -92,7 +92,7 @@ bad_asts.cpp: # 10| 1: [VariableAccess] y # 10| Type = [IntType] int # 10| ValueCategory = prvalue(load) -# 9| [MemberFunction,TemplateFunction] int Bad::S::MemberFunction(int) +# 9| [MemberFunction,TemplateFunction] int Bad::S::MemberFunction(int) # 9| params: # 9| 0: [Parameter] y # 9| Type = [IntType] int diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_sanity.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_sanity.expected index 928f535f9d8..e5e666c020b 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_sanity.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_sanity.expected @@ -1,8 +1,13 @@ missingOperand +| ir.cpp:809:7:809:13 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | +| ir.cpp:810:7:810:26 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | +| ir.cpp:823:7:823:13 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | +| ir.cpp:824:7:824:26 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | unexpectedOperand duplicateOperand missingPhiOperand missingOperandType +duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor ambiguousSuccessors diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index e31be3c0034..948b031e18c 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -1,5 +1,5 @@ bad_asts.cpp: -# 9| int Bad::S::MemberFunction(int) +# 9| int Bad::S::MemberFunction(int) # 9| Block 0 # 9| v0_0(void) = EnterFunction : # 9| mu0_1(unknown) = AliasedDefinition : @@ -20,7 +20,8 @@ bad_asts.cpp: # 9| r0_16(glval) = VariableAddress[#return] : # 9| v0_17(void) = ReturnValue : &:r0_16, ~mu0_2 # 9| v0_18(void) = UnmodeledUse : mu* -# 9| v0_19(void) = ExitFunction : +# 9| v0_19(void) = AliasedUse : ~mu0_2 +# 9| v0_20(void) = ExitFunction : # 14| void Bad::CallBadMemberFunction() # 14| Block 0 @@ -37,12 +38,13 @@ bad_asts.cpp: # 16| r0_10(int) = Constant[1] : # 16| r0_11(int) = Call : func:r0_9, this:r0_8, 0:r0_10 # 16| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 -# 16| v0_13(void) = ^IndirectReadSideEffect[-1] : &:r0_8, ~mu0_2 +# 16| v0_13(void) = ^BufferReadSideEffect[-1] : &:r0_8, ~mu0_2 # 16| mu0_14(S) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 # 17| v0_15(void) = NoOp : # 14| v0_16(void) = ReturnVoid : # 14| v0_17(void) = UnmodeledUse : mu* -# 14| v0_18(void) = ExitFunction : +# 14| v0_18(void) = AliasedUse : ~mu0_2 +# 14| v0_19(void) = ExitFunction : # 22| void Bad::Point::Point() # 22| Block 0 @@ -53,7 +55,8 @@ bad_asts.cpp: # 23| v0_4(void) = NoOp : # 22| v0_5(void) = ReturnVoid : # 22| v0_6(void) = UnmodeledUse : mu* -# 22| v0_7(void) = ExitFunction : +# 22| v0_7(void) = AliasedUse : ~mu0_2 +# 22| v0_8(void) = ExitFunction : # 26| void Bad::CallCopyConstructor(Bad::Point const&) # 26| Block 0 @@ -67,14 +70,16 @@ bad_asts.cpp: # 27| r0_7(glval) = VariableAddress[b] : # 27| r0_8(glval) = VariableAddress[a] : # 27| r0_9(Point &) = Load : &:r0_8, ~mu0_2 -# 27| r0_10(glval) = Convert : r0_9 -# 27| r0_11(Point) = Load : &:r0_10, ~mu0_2 -# 27| mu0_12(Point) = Store : &:r0_7, r0_11 -# 28| v0_13(void) = NoOp : -# 26| v0_14(void) = ReturnIndirection : &:r0_5, ~mu0_2 -# 26| v0_15(void) = ReturnVoid : -# 26| v0_16(void) = UnmodeledUse : mu* -# 26| v0_17(void) = ExitFunction : +# 27| r0_10(glval) = CopyValue : r0_9 +# 27| r0_11(glval) = Convert : r0_10 +# 27| r0_12(Point) = Load : &:r0_11, ~mu0_2 +# 27| mu0_13(Point) = Store : &:r0_7, r0_12 +# 28| v0_14(void) = NoOp : +# 26| v0_15(void) = ReturnIndirection : &:r0_5, ~mu0_2 +# 26| v0_16(void) = ReturnVoid : +# 26| v0_17(void) = UnmodeledUse : mu* +# 26| v0_18(void) = AliasedUse : ~mu0_2 +# 26| v0_19(void) = ExitFunction : # 30| void Bad::errorExpr() # 30| Block 0 @@ -94,7 +99,8 @@ bad_asts.cpp: # 34| v0_13(void) = NoOp : # 30| v0_14(void) = ReturnVoid : # 30| v0_15(void) = UnmodeledUse : mu* -# 30| v0_16(void) = ExitFunction : +# 30| v0_16(void) = AliasedUse : ~mu0_2 +# 30| v0_17(void) = ExitFunction : clang.cpp: # 5| int* globalIntAddress() @@ -104,11 +110,13 @@ clang.cpp: # 5| mu0_2(unknown) = UnmodeledDefinition : # 6| r0_3(glval) = VariableAddress[#return] : # 6| r0_4(glval) = VariableAddress[globalInt] : -# 6| mu0_5(int *) = Store : &:r0_3, r0_4 -# 5| r0_6(glval) = VariableAddress[#return] : -# 5| v0_7(void) = ReturnValue : &:r0_6, ~mu0_2 -# 5| v0_8(void) = UnmodeledUse : mu* -# 5| v0_9(void) = ExitFunction : +# 6| r0_5(int *) = CopyValue : r0_4 +# 6| mu0_6(int *) = Store : &:r0_3, r0_5 +# 5| r0_7(glval) = VariableAddress[#return] : +# 5| v0_8(void) = ReturnValue : &:r0_7, ~mu0_2 +# 5| v0_9(void) = UnmodeledUse : mu* +# 5| v0_10(void) = AliasedUse : ~mu0_2 +# 5| v0_11(void) = ExitFunction : ir.cpp: # 1| void Constants() @@ -203,7 +211,8 @@ ir.cpp: # 41| v0_87(void) = NoOp : # 1| v0_88(void) = ReturnVoid : # 1| v0_89(void) = UnmodeledUse : mu* -# 1| v0_90(void) = ExitFunction : +# 1| v0_90(void) = AliasedUse : ~mu0_2 +# 1| v0_91(void) = ExitFunction : # 43| void Foo() # 43| Block 0 @@ -236,7 +245,8 @@ ir.cpp: # 48| v0_26(void) = NoOp : # 43| v0_27(void) = ReturnVoid : # 43| v0_28(void) = UnmodeledUse : mu* -# 43| v0_29(void) = ExitFunction : +# 43| v0_29(void) = AliasedUse : ~mu0_2 +# 43| v0_30(void) = ExitFunction : # 50| void IntegerOps(int, int) # 50| Block 0 @@ -409,7 +419,8 @@ ir.cpp: # 85| v0_166(void) = NoOp : # 50| v0_167(void) = ReturnVoid : # 50| v0_168(void) = UnmodeledUse : mu* -# 50| v0_169(void) = ExitFunction : +# 50| v0_169(void) = AliasedUse : ~mu0_2 +# 50| v0_170(void) = ExitFunction : # 87| void IntegerCompare(int, int) # 87| Block 0 @@ -467,7 +478,8 @@ ir.cpp: # 96| v0_51(void) = NoOp : # 87| v0_52(void) = ReturnVoid : # 87| v0_53(void) = UnmodeledUse : mu* -# 87| v0_54(void) = ExitFunction : +# 87| v0_54(void) = AliasedUse : ~mu0_2 +# 87| v0_55(void) = ExitFunction : # 98| void IntegerCrement(int) # 98| Block 0 @@ -509,7 +521,8 @@ ir.cpp: # 105| v0_35(void) = NoOp : # 98| v0_36(void) = ReturnVoid : # 98| v0_37(void) = UnmodeledUse : mu* -# 98| v0_38(void) = ExitFunction : +# 98| v0_38(void) = AliasedUse : ~mu0_2 +# 98| v0_39(void) = ExitFunction : # 107| void IntegerCrement_LValue(int) # 107| Block 0 @@ -525,19 +538,24 @@ ir.cpp: # 110| r0_9(int) = Constant[1] : # 110| r0_10(int) = Add : r0_8, r0_9 # 110| mu0_11(int) = Store : &:r0_7, r0_10 -# 110| r0_12(glval) = VariableAddress[p] : -# 110| mu0_13(int *) = Store : &:r0_12, r0_7 -# 111| r0_14(glval) = VariableAddress[x] : -# 111| r0_15(int) = Load : &:r0_14, ~mu0_2 -# 111| r0_16(int) = Constant[1] : -# 111| r0_17(int) = Sub : r0_15, r0_16 -# 111| mu0_18(int) = Store : &:r0_14, r0_17 -# 111| r0_19(glval) = VariableAddress[p] : -# 111| mu0_20(int *) = Store : &:r0_19, r0_14 -# 112| v0_21(void) = NoOp : -# 107| v0_22(void) = ReturnVoid : -# 107| v0_23(void) = UnmodeledUse : mu* -# 107| v0_24(void) = ExitFunction : +# 110| r0_12(glval) = CopyValue : r0_7 +# 110| r0_13(int *) = CopyValue : r0_12 +# 110| r0_14(glval) = VariableAddress[p] : +# 110| mu0_15(int *) = Store : &:r0_14, r0_13 +# 111| r0_16(glval) = VariableAddress[x] : +# 111| r0_17(int) = Load : &:r0_16, ~mu0_2 +# 111| r0_18(int) = Constant[1] : +# 111| r0_19(int) = Sub : r0_17, r0_18 +# 111| mu0_20(int) = Store : &:r0_16, r0_19 +# 111| r0_21(glval) = CopyValue : r0_16 +# 111| r0_22(int *) = CopyValue : r0_21 +# 111| r0_23(glval) = VariableAddress[p] : +# 111| mu0_24(int *) = Store : &:r0_23, r0_22 +# 112| v0_25(void) = NoOp : +# 107| v0_26(void) = ReturnVoid : +# 107| v0_27(void) = UnmodeledUse : mu* +# 107| v0_28(void) = AliasedUse : ~mu0_2 +# 107| v0_29(void) = ExitFunction : # 114| void FloatOps(double, double) # 114| Block 0 @@ -619,7 +637,8 @@ ir.cpp: # 131| v0_75(void) = NoOp : # 114| v0_76(void) = ReturnVoid : # 114| v0_77(void) = UnmodeledUse : mu* -# 114| v0_78(void) = ExitFunction : +# 114| v0_78(void) = AliasedUse : ~mu0_2 +# 114| v0_79(void) = ExitFunction : # 133| void FloatCompare(double, double) # 133| Block 0 @@ -677,7 +696,8 @@ ir.cpp: # 142| v0_51(void) = NoOp : # 133| v0_52(void) = ReturnVoid : # 133| v0_53(void) = UnmodeledUse : mu* -# 133| v0_54(void) = ExitFunction : +# 133| v0_54(void) = AliasedUse : ~mu0_2 +# 133| v0_55(void) = ExitFunction : # 144| void FloatCrement(float) # 144| Block 0 @@ -719,7 +739,8 @@ ir.cpp: # 151| v0_35(void) = NoOp : # 144| v0_36(void) = ReturnVoid : # 144| v0_37(void) = UnmodeledUse : mu* -# 144| v0_38(void) = ExitFunction : +# 144| v0_38(void) = AliasedUse : ~mu0_2 +# 144| v0_39(void) = ExitFunction : # 153| void PointerOps(int*, int) # 153| Block 0 @@ -798,7 +819,8 @@ ir.cpp: # 153| v0_72(void) = ReturnIndirection : &:r0_5, ~mu0_2 # 153| v0_73(void) = ReturnVoid : # 153| v0_74(void) = UnmodeledUse : mu* -# 153| v0_75(void) = ExitFunction : +# 153| v0_75(void) = AliasedUse : ~mu0_2 +# 153| v0_76(void) = ExitFunction : # 171| void ArrayAccess(int*, int) # 171| Block 0 @@ -883,7 +905,8 @@ ir.cpp: # 171| v0_78(void) = ReturnIndirection : &:r0_5, ~mu0_2 # 171| v0_79(void) = ReturnVoid : # 171| v0_80(void) = UnmodeledUse : mu* -# 171| v0_81(void) = ExitFunction : +# 171| v0_81(void) = AliasedUse : ~mu0_2 +# 171| v0_82(void) = ExitFunction : # 187| void StringLiteral(int) # 187| Block 0 @@ -916,7 +939,8 @@ ir.cpp: # 191| v0_26(void) = NoOp : # 187| v0_27(void) = ReturnVoid : # 187| v0_28(void) = UnmodeledUse : mu* -# 187| v0_29(void) = ExitFunction : +# 187| v0_29(void) = AliasedUse : ~mu0_2 +# 187| v0_30(void) = ExitFunction : # 193| void PointerCompare(int*, int*) # 193| Block 0 @@ -980,7 +1004,8 @@ ir.cpp: # 193| v0_57(void) = ReturnIndirection : &:r0_9, ~mu0_2 # 193| v0_58(void) = ReturnVoid : # 193| v0_59(void) = UnmodeledUse : mu* -# 193| v0_60(void) = ExitFunction : +# 193| v0_60(void) = AliasedUse : ~mu0_2 +# 193| v0_61(void) = ExitFunction : # 204| void PointerCrement(int*) # 204| Block 0 @@ -1025,7 +1050,8 @@ ir.cpp: # 204| v0_38(void) = ReturnIndirection : &:r0_5, ~mu0_2 # 204| v0_39(void) = ReturnVoid : # 204| v0_40(void) = UnmodeledUse : mu* -# 204| v0_41(void) = ExitFunction : +# 204| v0_41(void) = AliasedUse : ~mu0_2 +# 204| v0_42(void) = ExitFunction : # 213| void CompoundAssignment() # 213| Block 0 @@ -1069,7 +1095,8 @@ ir.cpp: # 228| v0_37(void) = NoOp : # 213| v0_38(void) = ReturnVoid : # 213| v0_39(void) = UnmodeledUse : mu* -# 213| v0_40(void) = ExitFunction : +# 213| v0_40(void) = AliasedUse : ~mu0_2 +# 213| v0_41(void) = ExitFunction : # 230| void UninitializedVariables() # 230| Block 0 @@ -1085,7 +1112,8 @@ ir.cpp: # 233| v0_9(void) = NoOp : # 230| v0_10(void) = ReturnVoid : # 230| v0_11(void) = UnmodeledUse : mu* -# 230| v0_12(void) = ExitFunction : +# 230| v0_12(void) = AliasedUse : ~mu0_2 +# 230| v0_13(void) = ExitFunction : # 235| int Parameters(int, int) # 235| Block 0 @@ -1106,7 +1134,8 @@ ir.cpp: # 235| r0_14(glval) = VariableAddress[#return] : # 235| v0_15(void) = ReturnValue : &:r0_14, ~mu0_2 # 235| v0_16(void) = UnmodeledUse : mu* -# 235| v0_17(void) = ExitFunction : +# 235| v0_17(void) = AliasedUse : ~mu0_2 +# 235| v0_18(void) = ExitFunction : # 239| void IfStatements(bool, int, int) # 239| Block 0 @@ -1164,7 +1193,8 @@ ir.cpp: # 251| v6_0(void) = NoOp : # 239| v6_1(void) = ReturnVoid : # 239| v6_2(void) = UnmodeledUse : mu* -# 239| v6_3(void) = ExitFunction : +# 239| v6_3(void) = AliasedUse : ~mu0_2 +# 239| v6_4(void) = ExitFunction : # 240| Block 7 # 240| v7_0(void) = NoOp : @@ -1191,7 +1221,8 @@ ir.cpp: # 257| v2_0(void) = NoOp : # 253| v2_1(void) = ReturnVoid : # 253| v2_2(void) = UnmodeledUse : mu* -# 253| v2_3(void) = ExitFunction : +# 253| v2_3(void) = AliasedUse : ~mu0_2 +# 253| v2_4(void) = ExitFunction : # 254| Block 3 # 254| r3_0(glval) = VariableAddress[n] : @@ -1229,7 +1260,8 @@ ir.cpp: # 263| v2_0(void) = NoOp : # 259| v2_1(void) = ReturnVoid : # 259| v2_2(void) = UnmodeledUse : mu* -# 259| v2_3(void) = ExitFunction : +# 259| v2_3(void) = AliasedUse : ~mu0_2 +# 259| v2_4(void) = ExitFunction : # 265| void For_Empty() # 265| Block 0 @@ -1243,7 +1275,8 @@ ir.cpp: # 265| Block 1 # 265| v1_0(void) = ReturnVoid : # 265| v1_1(void) = UnmodeledUse : mu* -# 265| v1_2(void) = ExitFunction : +# 265| v1_2(void) = AliasedUse : ~mu0_2 +# 265| v1_3(void) = ExitFunction : # 268| Block 2 # 268| v2_0(void) = NoOp : @@ -1262,7 +1295,8 @@ ir.cpp: # 272| Block 1 # 272| v1_0(void) = ReturnVoid : # 272| v1_1(void) = UnmodeledUse : mu* -# 272| v1_2(void) = ExitFunction : +# 272| v1_2(void) = AliasedUse : ~mu0_2 +# 272| v1_3(void) = ExitFunction : # 274| Block 2 # 274| v2_0(void) = NoOp : @@ -1295,7 +1329,8 @@ ir.cpp: # 283| v3_0(void) = NoOp : # 278| v3_1(void) = ReturnVoid : # 278| v3_2(void) = UnmodeledUse : mu* -# 278| v3_3(void) = ExitFunction : +# 278| v3_3(void) = AliasedUse : ~mu0_2 +# 278| v3_4(void) = ExitFunction : # 285| void For_Update() # 285| Block 0 @@ -1310,7 +1345,8 @@ ir.cpp: # 285| Block 1 # 285| v1_0(void) = ReturnVoid : # 285| v1_1(void) = UnmodeledUse : mu* -# 285| v1_2(void) = ExitFunction : +# 285| v1_2(void) = AliasedUse : ~mu0_2 +# 285| v1_3(void) = ExitFunction : # 288| Block 2 # 288| v2_0(void) = NoOp : @@ -1348,7 +1384,8 @@ ir.cpp: # 296| v3_0(void) = NoOp : # 292| v3_1(void) = ReturnVoid : # 292| v3_2(void) = UnmodeledUse : mu* -# 292| v3_3(void) = ExitFunction : +# 292| v3_3(void) = AliasedUse : ~mu0_2 +# 292| v3_4(void) = ExitFunction : # 298| void For_InitUpdate() # 298| Block 0 @@ -1363,7 +1400,8 @@ ir.cpp: # 298| Block 1 # 298| v1_0(void) = ReturnVoid : # 298| v1_1(void) = UnmodeledUse : mu* -# 298| v1_2(void) = ExitFunction : +# 298| v1_2(void) = AliasedUse : ~mu0_2 +# 298| v1_3(void) = ExitFunction : # 300| Block 2 # 300| v2_0(void) = NoOp : @@ -1406,7 +1444,8 @@ ir.cpp: # 309| v3_0(void) = NoOp : # 304| v3_1(void) = ReturnVoid : # 304| v3_2(void) = UnmodeledUse : mu* -# 304| v3_3(void) = ExitFunction : +# 304| v3_3(void) = AliasedUse : ~mu0_2 +# 304| v3_4(void) = ExitFunction : # 311| void For_InitConditionUpdate() # 311| Block 0 @@ -1440,7 +1479,8 @@ ir.cpp: # 315| v3_0(void) = NoOp : # 311| v3_1(void) = ReturnVoid : # 311| v3_2(void) = UnmodeledUse : mu* -# 311| v3_3(void) = ExitFunction : +# 311| v3_3(void) = AliasedUse : ~mu0_2 +# 311| v3_4(void) = ExitFunction : # 317| void For_Break() # 317| Block 0 @@ -1487,7 +1527,8 @@ ir.cpp: # 323| v5_1(void) = NoOp : # 317| v5_2(void) = ReturnVoid : # 317| v5_3(void) = UnmodeledUse : mu* -# 317| v5_4(void) = ExitFunction : +# 317| v5_4(void) = AliasedUse : ~mu0_2 +# 317| v5_5(void) = ExitFunction : # 325| void For_Continue_Update() # 325| Block 0 @@ -1534,7 +1575,8 @@ ir.cpp: # 331| v5_0(void) = NoOp : # 325| v5_1(void) = ReturnVoid : # 325| v5_2(void) = UnmodeledUse : mu* -# 325| v5_3(void) = ExitFunction : +# 325| v5_3(void) = AliasedUse : ~mu0_2 +# 325| v5_4(void) = ExitFunction : # 333| void For_Continue_NoUpdate() # 333| Block 0 @@ -1576,7 +1618,8 @@ ir.cpp: # 339| v5_0(void) = NoOp : # 333| v5_1(void) = ReturnVoid : # 333| v5_2(void) = UnmodeledUse : mu* -# 333| v5_3(void) = ExitFunction : +# 333| v5_3(void) = AliasedUse : ~mu0_2 +# 333| v5_4(void) = ExitFunction : # 341| int Dereference(int*) # 341| Block 0 @@ -1590,17 +1633,19 @@ ir.cpp: # 342| r0_7(int) = Constant[1] : # 342| r0_8(glval) = VariableAddress[p] : # 342| r0_9(int *) = Load : &:r0_8, ~mu0_2 -# 342| mu0_10(int) = Store : &:r0_9, r0_7 -# 343| r0_11(glval) = VariableAddress[#return] : -# 343| r0_12(glval) = VariableAddress[p] : -# 343| r0_13(int *) = Load : &:r0_12, ~mu0_2 -# 343| r0_14(int) = Load : &:r0_13, ~mu0_2 -# 343| mu0_15(int) = Store : &:r0_11, r0_14 -# 341| v0_16(void) = ReturnIndirection : &:r0_5, ~mu0_2 -# 341| r0_17(glval) = VariableAddress[#return] : -# 341| v0_18(void) = ReturnValue : &:r0_17, ~mu0_2 -# 341| v0_19(void) = UnmodeledUse : mu* -# 341| v0_20(void) = ExitFunction : +# 342| r0_10(glval) = CopyValue : r0_9 +# 342| mu0_11(int) = Store : &:r0_10, r0_7 +# 343| r0_12(glval) = VariableAddress[#return] : +# 343| r0_13(glval) = VariableAddress[p] : +# 343| r0_14(int *) = Load : &:r0_13, ~mu0_2 +# 343| r0_15(int) = Load : &:r0_14, ~mu0_2 +# 343| mu0_16(int) = Store : &:r0_12, r0_15 +# 341| v0_17(void) = ReturnIndirection : &:r0_5, ~mu0_2 +# 341| r0_18(glval) = VariableAddress[#return] : +# 341| v0_19(void) = ReturnValue : &:r0_18, ~mu0_2 +# 341| v0_20(void) = UnmodeledUse : mu* +# 341| v0_21(void) = AliasedUse : ~mu0_2 +# 341| v0_22(void) = ExitFunction : # 348| int* AddressOf() # 348| Block 0 @@ -1609,11 +1654,13 @@ ir.cpp: # 348| mu0_2(unknown) = UnmodeledDefinition : # 349| r0_3(glval) = VariableAddress[#return] : # 349| r0_4(glval) = VariableAddress[g] : -# 349| mu0_5(int *) = Store : &:r0_3, r0_4 -# 348| r0_6(glval) = VariableAddress[#return] : -# 348| v0_7(void) = ReturnValue : &:r0_6, ~mu0_2 -# 348| v0_8(void) = UnmodeledUse : mu* -# 348| v0_9(void) = ExitFunction : +# 349| r0_5(int *) = CopyValue : r0_4 +# 349| mu0_6(int *) = Store : &:r0_3, r0_5 +# 348| r0_7(glval) = VariableAddress[#return] : +# 348| v0_8(void) = ReturnValue : &:r0_7, ~mu0_2 +# 348| v0_9(void) = UnmodeledUse : mu* +# 348| v0_10(void) = AliasedUse : ~mu0_2 +# 348| v0_11(void) = ExitFunction : # 352| void Break(int) # 352| Block 0 @@ -1650,7 +1697,8 @@ ir.cpp: # 358| v4_1(void) = NoOp : # 352| v4_2(void) = ReturnVoid : # 352| v4_3(void) = UnmodeledUse : mu* -# 352| v4_4(void) = ExitFunction : +# 352| v4_4(void) = AliasedUse : ~mu0_2 +# 352| v4_5(void) = ExitFunction : # 353| Block 5 # 353| r5_0(glval) = VariableAddress[n] : @@ -1705,7 +1753,8 @@ ir.cpp: # 367| v5_0(void) = NoOp : # 360| v5_1(void) = ReturnVoid : # 360| v5_2(void) = UnmodeledUse : mu* -# 360| v5_3(void) = ExitFunction : +# 360| v5_3(void) = AliasedUse : ~mu0_2 +# 360| v5_4(void) = ExitFunction : # 372| void Call() # 372| Block 0 @@ -1718,7 +1767,8 @@ ir.cpp: # 374| v0_6(void) = NoOp : # 372| v0_7(void) = ReturnVoid : # 372| v0_8(void) = UnmodeledUse : mu* -# 372| v0_9(void) = ExitFunction : +# 372| v0_9(void) = AliasedUse : ~mu0_2 +# 372| v0_10(void) = ExitFunction : # 376| int CallAdd(int, int) # 376| Block 0 @@ -1741,7 +1791,8 @@ ir.cpp: # 376| r0_16(glval) = VariableAddress[#return] : # 376| v0_17(void) = ReturnValue : &:r0_16, ~mu0_2 # 376| v0_18(void) = UnmodeledUse : mu* -# 376| v0_19(void) = ExitFunction : +# 376| v0_19(void) = AliasedUse : ~mu0_2 +# 376| v0_20(void) = ExitFunction : # 380| int Comma(int, int) # 380| Block 0 @@ -1763,11 +1814,13 @@ ir.cpp: # 381| r0_15(int) = Load : &:r0_14, ~mu0_2 # 381| r0_16(int) = Call : func:r0_11, 0:r0_13, 1:r0_15 # 381| mu0_17(unknown) = ^CallSideEffect : ~mu0_2 -# 381| mu0_18(int) = Store : &:r0_7, r0_16 -# 380| r0_19(glval) = VariableAddress[#return] : -# 380| v0_20(void) = ReturnValue : &:r0_19, ~mu0_2 -# 380| v0_21(void) = UnmodeledUse : mu* -# 380| v0_22(void) = ExitFunction : +# 381| r0_18(int) = CopyValue : r0_16 +# 381| mu0_19(int) = Store : &:r0_7, r0_18 +# 380| r0_20(glval) = VariableAddress[#return] : +# 380| v0_21(void) = ReturnValue : &:r0_20, ~mu0_2 +# 380| v0_22(void) = UnmodeledUse : mu* +# 380| v0_23(void) = AliasedUse : ~mu0_2 +# 380| v0_24(void) = ExitFunction : # 384| void Switch(int) # 384| Block 0 @@ -1848,7 +1901,8 @@ ir.cpp: # 410| v9_1(void) = NoOp : # 384| v9_2(void) = ReturnVoid : # 384| v9_3(void) = UnmodeledUse : mu* -# 384| v9_4(void) = ExitFunction : +# 384| v9_4(void) = AliasedUse : ~mu0_2 +# 384| v9_5(void) = ExitFunction : # 422| Point ReturnStruct(Point) # 422| Block 0 @@ -1864,7 +1918,8 @@ ir.cpp: # 422| r0_9(glval) = VariableAddress[#return] : # 422| v0_10(void) = ReturnValue : &:r0_9, ~mu0_2 # 422| v0_11(void) = UnmodeledUse : mu* -# 422| v0_12(void) = ExitFunction : +# 422| v0_12(void) = AliasedUse : ~mu0_2 +# 422| v0_13(void) = ExitFunction : # 426| void FieldAccess() # 426| Block 0 @@ -1886,11 +1941,13 @@ ir.cpp: # 430| r0_15(glval) = VariableAddress[p] : # 430| r0_16(glval) = VariableAddress[pt] : # 430| r0_17(glval) = FieldAddress[y] : r0_16 -# 430| mu0_18(int *) = Store : &:r0_15, r0_17 -# 431| v0_19(void) = NoOp : -# 426| v0_20(void) = ReturnVoid : -# 426| v0_21(void) = UnmodeledUse : mu* -# 426| v0_22(void) = ExitFunction : +# 430| r0_18(int *) = CopyValue : r0_17 +# 430| mu0_19(int *) = Store : &:r0_15, r0_18 +# 431| v0_20(void) = NoOp : +# 426| v0_21(void) = ReturnVoid : +# 426| v0_22(void) = UnmodeledUse : mu* +# 426| v0_23(void) = AliasedUse : ~mu0_2 +# 426| v0_24(void) = ExitFunction : # 433| void LogicalOr(bool, bool) # 433| Block 0 @@ -1952,7 +2009,8 @@ ir.cpp: # 445| v7_0(void) = NoOp : # 433| v7_1(void) = ReturnVoid : # 433| v7_2(void) = UnmodeledUse : mu* -# 433| v7_3(void) = ExitFunction : +# 433| v7_3(void) = AliasedUse : ~mu0_2 +# 433| v7_4(void) = ExitFunction : # 447| void LogicalAnd(bool, bool) # 447| Block 0 @@ -2014,7 +2072,8 @@ ir.cpp: # 459| v7_0(void) = NoOp : # 447| v7_1(void) = ReturnVoid : # 447| v7_2(void) = UnmodeledUse : mu* -# 447| v7_3(void) = ExitFunction : +# 447| v7_3(void) = AliasedUse : ~mu0_2 +# 447| v7_4(void) = ExitFunction : # 461| void LogicalNot(bool, bool) # 461| Block 0 @@ -2069,7 +2128,8 @@ ir.cpp: # 473| v6_0(void) = NoOp : # 461| v6_1(void) = ReturnVoid : # 461| v6_2(void) = UnmodeledUse : mu* -# 461| v6_3(void) = ExitFunction : +# 461| v6_3(void) = AliasedUse : ~mu0_2 +# 461| v6_4(void) = ExitFunction : # 475| void ConditionValues(bool, bool) # 475| Block 0 @@ -2140,7 +2200,8 @@ ir.cpp: # 480| v7_5(void) = NoOp : # 475| v7_6(void) = ReturnVoid : # 475| v7_7(void) = UnmodeledUse : mu* -# 475| v7_8(void) = ExitFunction : +# 475| v7_8(void) = AliasedUse : ~mu0_2 +# 475| v7_9(void) = ExitFunction : # 479| Block 8 # 479| r8_0(glval) = VariableAddress[#temp479:11] : @@ -2217,7 +2278,8 @@ ir.cpp: # 484| v3_3(void) = NoOp : # 482| v3_4(void) = ReturnVoid : # 482| v3_5(void) = UnmodeledUse : mu* -# 482| v3_6(void) = ExitFunction : +# 482| v3_6(void) = AliasedUse : ~mu0_2 +# 482| v3_7(void) = ExitFunction : # 486| void Conditional_LValue(bool) # 486| Block 0 @@ -2244,7 +2306,8 @@ ir.cpp: # 490| v1_3(void) = NoOp : # 486| v1_4(void) = ReturnVoid : # 486| v1_5(void) = UnmodeledUse : mu* -# 486| v1_6(void) = ExitFunction : +# 486| v1_6(void) = AliasedUse : ~mu0_2 +# 486| v1_7(void) = ExitFunction : # 489| Block 2 # 489| r2_0(glval) = VariableAddress[x] : @@ -2281,7 +2344,8 @@ ir.cpp: # 494| v2_0(void) = NoOp : # 492| v2_1(void) = ReturnVoid : # 492| v2_2(void) = UnmodeledUse : mu* -# 492| v2_3(void) = ExitFunction : +# 492| v2_3(void) = AliasedUse : ~mu0_2 +# 492| v2_4(void) = ExitFunction : # 493| Block 3 # 493| r3_0(glval) = FunctionAddress[VoidFunc] : @@ -2309,7 +2373,8 @@ ir.cpp: # 501| v0_15(void) = NoOp : # 496| v0_16(void) = ReturnVoid : # 496| v0_17(void) = UnmodeledUse : mu* -# 496| v0_18(void) = ExitFunction : +# 496| v0_18(void) = AliasedUse : ~mu0_2 +# 496| v0_19(void) = ExitFunction : # 503| void InitList(int, float) # 503| Block 0 @@ -2357,7 +2422,8 @@ ir.cpp: # 510| v0_41(void) = NoOp : # 503| v0_42(void) = ReturnVoid : # 503| v0_43(void) = UnmodeledUse : mu* -# 503| v0_44(void) = ExitFunction : +# 503| v0_44(void) = AliasedUse : ~mu0_2 +# 503| v0_45(void) = ExitFunction : # 512| void NestedInitList(int, float) # 512| Block 0 @@ -2434,7 +2500,8 @@ ir.cpp: # 517| v0_70(void) = NoOp : # 512| v0_71(void) = ReturnVoid : # 512| v0_72(void) = UnmodeledUse : mu* -# 512| v0_73(void) = ExitFunction : +# 512| v0_73(void) = AliasedUse : ~mu0_2 +# 512| v0_74(void) = ExitFunction : # 519| void ArrayInit(int, float) # 519| Block 0 @@ -2482,7 +2549,8 @@ ir.cpp: # 523| v0_41(void) = NoOp : # 519| v0_42(void) = ReturnVoid : # 519| v0_43(void) = UnmodeledUse : mu* -# 519| v0_44(void) = ExitFunction : +# 519| v0_44(void) = AliasedUse : ~mu0_2 +# 519| v0_45(void) = ExitFunction : # 530| void UnionInit(int, float) # 530| Block 0 @@ -2503,7 +2571,8 @@ ir.cpp: # 533| v0_14(void) = NoOp : # 530| v0_15(void) = ReturnVoid : # 530| v0_16(void) = UnmodeledUse : mu* -# 530| v0_17(void) = ExitFunction : +# 530| v0_17(void) = AliasedUse : ~mu0_2 +# 530| v0_18(void) = ExitFunction : # 535| void EarlyReturn(int, int) # 535| Block 0 @@ -2526,7 +2595,8 @@ ir.cpp: # 535| Block 1 # 535| v1_0(void) = ReturnVoid : # 535| v1_1(void) = UnmodeledUse : mu* -# 535| v1_2(void) = ExitFunction : +# 535| v1_2(void) = AliasedUse : ~mu0_2 +# 535| v1_3(void) = ExitFunction : # 537| Block 2 # 537| v2_0(void) = NoOp : @@ -2562,7 +2632,8 @@ ir.cpp: # 543| r1_0(glval) = VariableAddress[#return] : # 543| v1_1(void) = ReturnValue : &:r1_0, ~mu0_2 # 543| v1_2(void) = UnmodeledUse : mu* -# 543| v1_3(void) = ExitFunction : +# 543| v1_3(void) = AliasedUse : ~mu0_2 +# 543| v1_4(void) = ExitFunction : # 545| Block 2 # 545| r2_0(glval) = VariableAddress[#return] : @@ -2598,7 +2669,8 @@ ir.cpp: # 551| r0_12(glval) = VariableAddress[#return] : # 551| v0_13(void) = ReturnValue : &:r0_12, ~mu0_2 # 551| v0_14(void) = UnmodeledUse : mu* -# 551| v0_15(void) = ExitFunction : +# 551| v0_15(void) = AliasedUse : ~mu0_2 +# 551| v0_16(void) = ExitFunction : # 560| int EnumSwitch(E) # 560| Block 0 @@ -2619,7 +2691,8 @@ ir.cpp: # 560| r1_0(glval) = VariableAddress[#return] : # 560| v1_1(void) = ReturnValue : &:r1_0, ~mu0_2 # 560| v1_2(void) = UnmodeledUse : mu* -# 560| v1_3(void) = ExitFunction : +# 560| v1_3(void) = AliasedUse : ~mu0_2 +# 560| v1_4(void) = ExitFunction : # 564| Block 2 # 564| v2_0(void) = NoOp : @@ -2648,63 +2721,65 @@ ir.cpp: # 571| mu0_1(unknown) = AliasedDefinition : # 571| mu0_2(unknown) = UnmodeledDefinition : # 572| r0_3(glval) = VariableAddress[a_pad] : -# 572| r0_4(glval) = StringConstant[""] : -# 572| r0_5(char[1]) = Load : &:r0_4, ~mu0_2 -# 572| mu0_6(char[1]) = Store : &:r0_3, r0_5 -# 572| r0_7(unknown[31]) = Constant[0] : -# 572| r0_8(int) = Constant[1] : -# 572| r0_9(glval) = PointerAdd[1] : r0_3, r0_8 -# 572| mu0_10(unknown[31]) = Store : &:r0_9, r0_7 -# 573| r0_11(glval) = VariableAddress[a_nopad] : -# 573| r0_12(glval) = StringConstant["foo"] : -# 573| r0_13(char[4]) = Load : &:r0_12, ~mu0_2 -# 573| mu0_14(char[4]) = Store : &:r0_11, r0_13 -# 574| r0_15(glval) = VariableAddress[a_infer] : -# 574| r0_16(glval) = StringConstant["blah"] : -# 574| r0_17(char[5]) = Load : &:r0_16, ~mu0_2 -# 574| mu0_18(char[5]) = Store : &:r0_15, r0_17 -# 575| r0_19(glval) = VariableAddress[b] : -# 575| mu0_20(char[2]) = Uninitialized[b] : &:r0_19 -# 576| r0_21(glval) = VariableAddress[c] : -# 576| mu0_22(char[2]) = Uninitialized[c] : &:r0_21 -# 576| r0_23(int) = Constant[0] : -# 576| r0_24(glval) = PointerAdd[1] : r0_21, r0_23 -# 576| r0_25(unknown[2]) = Constant[0] : -# 576| mu0_26(unknown[2]) = Store : &:r0_24, r0_25 -# 577| r0_27(glval) = VariableAddress[d] : -# 577| mu0_28(char[2]) = Uninitialized[d] : &:r0_27 -# 577| r0_29(int) = Constant[0] : -# 577| r0_30(glval) = PointerAdd[1] : r0_27, r0_29 -# 577| r0_31(char) = Constant[0] : -# 577| mu0_32(char) = Store : &:r0_30, r0_31 -# 577| r0_33(int) = Constant[1] : -# 577| r0_34(glval) = PointerAdd[1] : r0_27, r0_33 -# 577| r0_35(char) = Constant[0] : -# 577| mu0_36(char) = Store : &:r0_34, r0_35 -# 578| r0_37(glval) = VariableAddress[e] : -# 578| mu0_38(char[2]) = Uninitialized[e] : &:r0_37 -# 578| r0_39(int) = Constant[0] : -# 578| r0_40(glval) = PointerAdd[1] : r0_37, r0_39 -# 578| r0_41(char) = Constant[0] : -# 578| mu0_42(char) = Store : &:r0_40, r0_41 -# 578| r0_43(int) = Constant[1] : -# 578| r0_44(glval) = PointerAdd[1] : r0_37, r0_43 -# 578| r0_45(char) = Constant[1] : -# 578| mu0_46(char) = Store : &:r0_44, r0_45 -# 579| r0_47(glval) = VariableAddress[f] : -# 579| mu0_48(char[3]) = Uninitialized[f] : &:r0_47 -# 579| r0_49(int) = Constant[0] : -# 579| r0_50(glval) = PointerAdd[1] : r0_47, r0_49 -# 579| r0_51(char) = Constant[0] : -# 579| mu0_52(char) = Store : &:r0_50, r0_51 -# 579| r0_53(int) = Constant[1] : -# 579| r0_54(glval) = PointerAdd[1] : r0_47, r0_53 -# 579| r0_55(unknown[2]) = Constant[0] : -# 579| mu0_56(unknown[2]) = Store : &:r0_54, r0_55 -# 580| v0_57(void) = NoOp : -# 571| v0_58(void) = ReturnVoid : -# 571| v0_59(void) = UnmodeledUse : mu* -# 571| v0_60(void) = ExitFunction : +# 572| mu0_4(char[32]) = Uninitialized[a_pad] : &:r0_3 +# 572| r0_5(glval) = StringConstant[""] : +# 572| r0_6(char[1]) = Load : &:r0_5, ~mu0_2 +# 572| mu0_7(char[1]) = Store : &:r0_3, r0_6 +# 572| r0_8(unknown[31]) = Constant[0] : +# 572| r0_9(int) = Constant[1] : +# 572| r0_10(glval) = PointerAdd[1] : r0_3, r0_9 +# 572| mu0_11(unknown[31]) = Store : &:r0_10, r0_8 +# 573| r0_12(glval) = VariableAddress[a_nopad] : +# 573| r0_13(glval) = StringConstant["foo"] : +# 573| r0_14(char[4]) = Load : &:r0_13, ~mu0_2 +# 573| mu0_15(char[4]) = Store : &:r0_12, r0_14 +# 574| r0_16(glval) = VariableAddress[a_infer] : +# 574| r0_17(glval) = StringConstant["blah"] : +# 574| r0_18(char[5]) = Load : &:r0_17, ~mu0_2 +# 574| mu0_19(char[5]) = Store : &:r0_16, r0_18 +# 575| r0_20(glval) = VariableAddress[b] : +# 575| mu0_21(char[2]) = Uninitialized[b] : &:r0_20 +# 576| r0_22(glval) = VariableAddress[c] : +# 576| mu0_23(char[2]) = Uninitialized[c] : &:r0_22 +# 576| r0_24(int) = Constant[0] : +# 576| r0_25(glval) = PointerAdd[1] : r0_22, r0_24 +# 576| r0_26(unknown[2]) = Constant[0] : +# 576| mu0_27(unknown[2]) = Store : &:r0_25, r0_26 +# 577| r0_28(glval) = VariableAddress[d] : +# 577| mu0_29(char[2]) = Uninitialized[d] : &:r0_28 +# 577| r0_30(int) = Constant[0] : +# 577| r0_31(glval) = PointerAdd[1] : r0_28, r0_30 +# 577| r0_32(char) = Constant[0] : +# 577| mu0_33(char) = Store : &:r0_31, r0_32 +# 577| r0_34(int) = Constant[1] : +# 577| r0_35(glval) = PointerAdd[1] : r0_28, r0_34 +# 577| r0_36(char) = Constant[0] : +# 577| mu0_37(char) = Store : &:r0_35, r0_36 +# 578| r0_38(glval) = VariableAddress[e] : +# 578| mu0_39(char[2]) = Uninitialized[e] : &:r0_38 +# 578| r0_40(int) = Constant[0] : +# 578| r0_41(glval) = PointerAdd[1] : r0_38, r0_40 +# 578| r0_42(char) = Constant[0] : +# 578| mu0_43(char) = Store : &:r0_41, r0_42 +# 578| r0_44(int) = Constant[1] : +# 578| r0_45(glval) = PointerAdd[1] : r0_38, r0_44 +# 578| r0_46(char) = Constant[1] : +# 578| mu0_47(char) = Store : &:r0_45, r0_46 +# 579| r0_48(glval) = VariableAddress[f] : +# 579| mu0_49(char[3]) = Uninitialized[f] : &:r0_48 +# 579| r0_50(int) = Constant[0] : +# 579| r0_51(glval) = PointerAdd[1] : r0_48, r0_50 +# 579| r0_52(char) = Constant[0] : +# 579| mu0_53(char) = Store : &:r0_51, r0_52 +# 579| r0_54(int) = Constant[1] : +# 579| r0_55(glval) = PointerAdd[1] : r0_48, r0_54 +# 579| r0_56(unknown[2]) = Constant[0] : +# 579| mu0_57(unknown[2]) = Store : &:r0_55, r0_56 +# 580| v0_58(void) = NoOp : +# 571| v0_59(void) = ReturnVoid : +# 571| v0_60(void) = UnmodeledUse : mu* +# 571| v0_61(void) = AliasedUse : ~mu0_2 +# 571| v0_62(void) = ExitFunction : # 584| void VarArgs() # 584| Block 0 @@ -2719,14 +2794,15 @@ ir.cpp: # 585| r0_8(char *) = Convert : r0_7 # 585| v0_9(void) = Call : func:r0_3, 0:r0_5, 1:r0_6, 2:r0_8 # 585| mu0_10(unknown) = ^CallSideEffect : ~mu0_2 -# 585| v0_11(void) = ^IndirectReadSideEffect[0] : &:r0_5, ~mu0_2 -# 585| v0_12(void) = ^IndirectReadSideEffect[2] : &:r0_8, ~mu0_2 +# 585| v0_11(void) = ^BufferReadSideEffect[0] : &:r0_5, ~mu0_2 +# 585| v0_12(void) = ^BufferReadSideEffect[2] : &:r0_8, ~mu0_2 # 585| mu0_13(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_5 # 585| mu0_14(unknown) = ^BufferMayWriteSideEffect[2] : &:r0_8 # 586| v0_15(void) = NoOp : # 584| v0_16(void) = ReturnVoid : # 584| v0_17(void) = UnmodeledUse : mu* -# 584| v0_18(void) = ExitFunction : +# 584| v0_18(void) = AliasedUse : ~mu0_2 +# 584| v0_19(void) = ExitFunction : # 590| void SetFuncPtr() # 590| Block 0 @@ -2737,53 +2813,67 @@ ir.cpp: # 591| r0_4(..(*)(..)) = FunctionAddress[FuncPtrTarget] : # 591| mu0_5(..(*)(..)) = Store : &:r0_3, r0_4 # 592| r0_6(glval<..()(..)>) = FunctionAddress[FuncPtrTarget] : -# 592| r0_7(glval<..(*)(..)>) = VariableAddress[pfn] : -# 592| mu0_8(..(*)(..)) = Store : &:r0_7, r0_6 -# 593| r0_9(..(*)(..)) = FunctionAddress[FuncPtrTarget] : -# 593| r0_10(glval<..(*)(..)>) = VariableAddress[pfn] : -# 593| mu0_11(..(*)(..)) = Store : &:r0_10, r0_9 -# 594| r0_12(glval<..()(..)>) = FunctionAddress[FuncPtrTarget] : -# 594| r0_13(glval<..(*)(..)>) = VariableAddress[pfn] : -# 594| mu0_14(..(*)(..)) = Store : &:r0_13, r0_12 -# 595| v0_15(void) = NoOp : -# 590| v0_16(void) = ReturnVoid : -# 590| v0_17(void) = UnmodeledUse : mu* -# 590| v0_18(void) = ExitFunction : +# 592| r0_7(..(*)(..)) = CopyValue : r0_6 +# 592| r0_8(glval<..(*)(..)>) = VariableAddress[pfn] : +# 592| mu0_9(..(*)(..)) = Store : &:r0_8, r0_7 +# 593| r0_10(..(*)(..)) = FunctionAddress[FuncPtrTarget] : +# 593| r0_11(..(*)(..)) = CopyValue : r0_10 +# 593| r0_12(glval<..(*)(..)>) = VariableAddress[pfn] : +# 593| mu0_13(..(*)(..)) = Store : &:r0_12, r0_11 +# 594| r0_14(glval<..()(..)>) = FunctionAddress[FuncPtrTarget] : +# 594| r0_15(..(*)(..)) = CopyValue : r0_14 +# 594| r0_16(..(*)(..)) = CopyValue : r0_15 +# 594| r0_17(..(*)(..)) = CopyValue : r0_16 +# 594| r0_18(..(*)(..)) = CopyValue : r0_17 +# 594| r0_19(glval<..(*)(..)>) = VariableAddress[pfn] : +# 594| mu0_20(..(*)(..)) = Store : &:r0_19, r0_18 +# 595| v0_21(void) = NoOp : +# 590| v0_22(void) = ReturnVoid : +# 590| v0_23(void) = UnmodeledUse : mu* +# 590| v0_24(void) = AliasedUse : ~mu0_2 +# 590| v0_25(void) = ExitFunction : # 615| void DeclareObject() # 615| Block 0 -# 615| v0_0(void) = EnterFunction : -# 615| mu0_1(unknown) = AliasedDefinition : -# 615| mu0_2(unknown) = UnmodeledDefinition : -# 616| r0_3(glval) = VariableAddress[s1] : -# 616| r0_4(glval) = FunctionAddress[String] : -# 616| v0_5(void) = Call : func:r0_4, this:r0_3 -# 616| mu0_6(unknown) = ^CallSideEffect : ~mu0_2 -# 617| r0_7(glval) = VariableAddress[s2] : -# 617| r0_8(glval) = FunctionAddress[String] : -# 617| r0_9(glval) = StringConstant["hello"] : -# 617| r0_10(char *) = Convert : r0_9 -# 617| v0_11(void) = Call : func:r0_8, this:r0_7, 0:r0_10 -# 617| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 -# 617| v0_13(void) = ^IndirectReadSideEffect[0] : &:r0_10, ~mu0_2 -# 617| mu0_14(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_10 -# 618| r0_15(glval) = VariableAddress[s3] : -# 618| r0_16(glval) = FunctionAddress[ReturnObject] : -# 618| r0_17(String) = Call : func:r0_16 -# 618| mu0_18(unknown) = ^CallSideEffect : ~mu0_2 -# 618| mu0_19(String) = Store : &:r0_15, r0_17 -# 619| r0_20(glval) = VariableAddress[s4] : -# 619| r0_21(glval) = FunctionAddress[String] : -# 619| r0_22(glval) = StringConstant["test"] : -# 619| r0_23(char *) = Convert : r0_22 -# 619| v0_24(void) = Call : func:r0_21, this:r0_20, 0:r0_23 -# 619| mu0_25(unknown) = ^CallSideEffect : ~mu0_2 -# 619| v0_26(void) = ^IndirectReadSideEffect[0] : &:r0_23, ~mu0_2 -# 619| mu0_27(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_23 -# 620| v0_28(void) = NoOp : -# 615| v0_29(void) = ReturnVoid : -# 615| v0_30(void) = UnmodeledUse : mu* -# 615| v0_31(void) = ExitFunction : +# 615| v0_0(void) = EnterFunction : +# 615| mu0_1(unknown) = AliasedDefinition : +# 615| mu0_2(unknown) = UnmodeledDefinition : +# 616| r0_3(glval) = VariableAddress[s1] : +# 616| mu0_4(String) = Uninitialized[s1] : &:r0_3 +# 616| r0_5(glval) = FunctionAddress[String] : +# 616| v0_6(void) = Call : func:r0_5, this:r0_3 +# 616| mu0_7(unknown) = ^CallSideEffect : ~mu0_2 +# 616| mu0_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_3 +# 617| r0_9(glval) = VariableAddress[s2] : +# 617| mu0_10(String) = Uninitialized[s2] : &:r0_9 +# 617| r0_11(glval) = FunctionAddress[String] : +# 617| r0_12(glval) = StringConstant["hello"] : +# 617| r0_13(char *) = Convert : r0_12 +# 617| v0_14(void) = Call : func:r0_11, this:r0_9, 0:r0_13 +# 617| mu0_15(unknown) = ^CallSideEffect : ~mu0_2 +# 617| mu0_16(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_9 +# 617| v0_17(void) = ^BufferReadSideEffect[0] : &:r0_13, ~mu0_2 +# 617| mu0_18(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_13 +# 618| r0_19(glval) = VariableAddress[s3] : +# 618| r0_20(glval) = FunctionAddress[ReturnObject] : +# 618| r0_21(String) = Call : func:r0_20 +# 618| mu0_22(unknown) = ^CallSideEffect : ~mu0_2 +# 618| mu0_23(String) = Store : &:r0_19, r0_21 +# 619| r0_24(glval) = VariableAddress[s4] : +# 619| mu0_25(String) = Uninitialized[s4] : &:r0_24 +# 619| r0_26(glval) = FunctionAddress[String] : +# 619| r0_27(glval) = StringConstant["test"] : +# 619| r0_28(char *) = Convert : r0_27 +# 619| v0_29(void) = Call : func:r0_26, this:r0_24, 0:r0_28 +# 619| mu0_30(unknown) = ^CallSideEffect : ~mu0_2 +# 619| mu0_31(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_24 +# 619| v0_32(void) = ^BufferReadSideEffect[0] : &:r0_28, ~mu0_2 +# 619| mu0_33(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_28 +# 620| v0_34(void) = NoOp : +# 615| v0_35(void) = ReturnVoid : +# 615| v0_36(void) = UnmodeledUse : mu* +# 615| v0_37(void) = AliasedUse : ~mu0_2 +# 615| v0_38(void) = ExitFunction : # 622| void CallMethods(String&, String*, String) # 622| Block 0 @@ -2802,33 +2892,35 @@ ir.cpp: # 622| mu0_12(String) = InitializeParameter[s] : &:r0_11 # 623| r0_13(glval) = VariableAddress[r] : # 623| r0_14(String &) = Load : &:r0_13, ~mu0_2 -# 623| r0_15(glval) = Convert : r0_14 -# 623| r0_16(glval) = FunctionAddress[c_str] : -# 623| r0_17(char *) = Call : func:r0_16, this:r0_15 -# 623| mu0_18(unknown) = ^CallSideEffect : ~mu0_2 -# 623| v0_19(void) = ^IndirectReadSideEffect[-1] : &:r0_15, ~mu0_2 -# 623| mu0_20(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_15 -# 624| r0_21(glval) = VariableAddress[p] : -# 624| r0_22(String *) = Load : &:r0_21, ~mu0_2 -# 624| r0_23(String *) = Convert : r0_22 -# 624| r0_24(glval) = FunctionAddress[c_str] : -# 624| r0_25(char *) = Call : func:r0_24, this:r0_23 -# 624| mu0_26(unknown) = ^CallSideEffect : ~mu0_2 -# 624| v0_27(void) = ^IndirectReadSideEffect[-1] : &:r0_23, ~mu0_2 -# 624| mu0_28(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_23 -# 625| r0_29(glval) = VariableAddress[s] : -# 625| r0_30(glval) = Convert : r0_29 -# 625| r0_31(glval) = FunctionAddress[c_str] : -# 625| r0_32(char *) = Call : func:r0_31, this:r0_30 -# 625| mu0_33(unknown) = ^CallSideEffect : ~mu0_2 -# 625| v0_34(void) = ^IndirectReadSideEffect[-1] : &:r0_30, ~mu0_2 -# 625| mu0_35(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_30 -# 626| v0_36(void) = NoOp : -# 622| v0_37(void) = ReturnIndirection : &:r0_5, ~mu0_2 -# 622| v0_38(void) = ReturnIndirection : &:r0_9, ~mu0_2 -# 622| v0_39(void) = ReturnVoid : -# 622| v0_40(void) = UnmodeledUse : mu* -# 622| v0_41(void) = ExitFunction : +# 623| r0_15(glval) = CopyValue : r0_14 +# 623| r0_16(glval) = Convert : r0_15 +# 623| r0_17(glval) = FunctionAddress[c_str] : +# 623| r0_18(char *) = Call : func:r0_17, this:r0_16 +# 623| mu0_19(unknown) = ^CallSideEffect : ~mu0_2 +# 623| v0_20(void) = ^BufferReadSideEffect[-1] : &:r0_16, ~mu0_2 +# 623| mu0_21(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_16 +# 624| r0_22(glval) = VariableAddress[p] : +# 624| r0_23(String *) = Load : &:r0_22, ~mu0_2 +# 624| r0_24(String *) = Convert : r0_23 +# 624| r0_25(glval) = FunctionAddress[c_str] : +# 624| r0_26(char *) = Call : func:r0_25, this:r0_24 +# 624| mu0_27(unknown) = ^CallSideEffect : ~mu0_2 +# 624| v0_28(void) = ^BufferReadSideEffect[-1] : &:r0_24, ~mu0_2 +# 624| mu0_29(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_24 +# 625| r0_30(glval) = VariableAddress[s] : +# 625| r0_31(glval) = Convert : r0_30 +# 625| r0_32(glval) = FunctionAddress[c_str] : +# 625| r0_33(char *) = Call : func:r0_32, this:r0_31 +# 625| mu0_34(unknown) = ^CallSideEffect : ~mu0_2 +# 625| v0_35(void) = ^BufferReadSideEffect[-1] : &:r0_31, ~mu0_2 +# 625| mu0_36(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_31 +# 626| v0_37(void) = NoOp : +# 622| v0_38(void) = ReturnIndirection : &:r0_5, ~mu0_2 +# 622| v0_39(void) = ReturnIndirection : &:r0_9, ~mu0_2 +# 622| v0_40(void) = ReturnVoid : +# 622| v0_41(void) = UnmodeledUse : mu* +# 622| v0_42(void) = AliasedUse : ~mu0_2 +# 622| v0_43(void) = ExitFunction : # 630| int C::StaticMemberFunction(int) # 630| Block 0 @@ -2844,7 +2936,8 @@ ir.cpp: # 630| r0_9(glval) = VariableAddress[#return] : # 630| v0_10(void) = ReturnValue : &:r0_9, ~mu0_2 # 630| v0_11(void) = UnmodeledUse : mu* -# 630| v0_12(void) = ExitFunction : +# 630| v0_12(void) = AliasedUse : ~mu0_2 +# 630| v0_13(void) = ExitFunction : # 634| int C::InstanceMemberFunction(int) # 634| Block 0 @@ -2861,7 +2954,8 @@ ir.cpp: # 634| r0_10(glval) = VariableAddress[#return] : # 634| v0_11(void) = ReturnValue : &:r0_10, ~mu0_2 # 634| v0_12(void) = UnmodeledUse : mu* -# 634| v0_13(void) = ExitFunction : +# 634| v0_13(void) = AliasedUse : ~mu0_2 +# 634| v0_14(void) = ExitFunction : # 638| int C::VirtualMemberFunction(int) # 638| Block 0 @@ -2878,7 +2972,8 @@ ir.cpp: # 638| r0_10(glval) = VariableAddress[#return] : # 638| v0_11(void) = ReturnValue : &:r0_10, ~mu0_2 # 638| v0_12(void) = UnmodeledUse : mu* -# 638| v0_13(void) = ExitFunction : +# 638| v0_13(void) = AliasedUse : ~mu0_2 +# 638| v0_14(void) = ExitFunction : # 642| void C::FieldAccess() # 642| Block 0 @@ -2892,33 +2987,36 @@ ir.cpp: # 643| mu0_7(int) = Store : &:r0_6, r0_4 # 644| r0_8(int) = Constant[1] : # 644| r0_9(C *) = CopyValue : r0_3 -# 644| r0_10(glval) = FieldAddress[m_a] : r0_9 -# 644| mu0_11(int) = Store : &:r0_10, r0_8 -# 645| r0_12(int) = Constant[2] : -#-----| r0_13(C *) = CopyValue : r0_3 -# 645| r0_14(glval) = FieldAddress[m_a] : r0_13 -# 645| mu0_15(int) = Store : &:r0_14, r0_12 -# 646| r0_16(glval) = VariableAddress[x] : -# 646| mu0_17(int) = Uninitialized[x] : &:r0_16 -# 647| r0_18(C *) = CopyValue : r0_3 -# 647| r0_19(glval) = FieldAddress[m_a] : r0_18 -# 647| r0_20(int) = Load : &:r0_19, ~mu0_2 -# 647| r0_21(glval) = VariableAddress[x] : -# 647| mu0_22(int) = Store : &:r0_21, r0_20 -# 648| r0_23(C *) = CopyValue : r0_3 -# 648| r0_24(glval) = FieldAddress[m_a] : r0_23 -# 648| r0_25(int) = Load : &:r0_24, ~mu0_2 -# 648| r0_26(glval) = VariableAddress[x] : -# 648| mu0_27(int) = Store : &:r0_26, r0_25 -#-----| r0_28(C *) = CopyValue : r0_3 -# 649| r0_29(glval) = FieldAddress[m_a] : r0_28 -# 649| r0_30(int) = Load : &:r0_29, ~mu0_2 -# 649| r0_31(glval) = VariableAddress[x] : -# 649| mu0_32(int) = Store : &:r0_31, r0_30 -# 650| v0_33(void) = NoOp : -# 642| v0_34(void) = ReturnVoid : -# 642| v0_35(void) = UnmodeledUse : mu* -# 642| v0_36(void) = ExitFunction : +# 644| r0_10(glval) = CopyValue : r0_9 +# 644| r0_11(glval) = FieldAddress[m_a] : r0_10 +# 644| mu0_12(int) = Store : &:r0_11, r0_8 +# 645| r0_13(int) = Constant[2] : +#-----| r0_14(C *) = CopyValue : r0_3 +# 645| r0_15(glval) = FieldAddress[m_a] : r0_14 +# 645| mu0_16(int) = Store : &:r0_15, r0_13 +# 646| r0_17(glval) = VariableAddress[x] : +# 646| mu0_18(int) = Uninitialized[x] : &:r0_17 +# 647| r0_19(C *) = CopyValue : r0_3 +# 647| r0_20(glval) = FieldAddress[m_a] : r0_19 +# 647| r0_21(int) = Load : &:r0_20, ~mu0_2 +# 647| r0_22(glval) = VariableAddress[x] : +# 647| mu0_23(int) = Store : &:r0_22, r0_21 +# 648| r0_24(C *) = CopyValue : r0_3 +# 648| r0_25(glval) = CopyValue : r0_24 +# 648| r0_26(glval) = FieldAddress[m_a] : r0_25 +# 648| r0_27(int) = Load : &:r0_26, ~mu0_2 +# 648| r0_28(glval) = VariableAddress[x] : +# 648| mu0_29(int) = Store : &:r0_28, r0_27 +#-----| r0_30(C *) = CopyValue : r0_3 +# 649| r0_31(glval) = FieldAddress[m_a] : r0_30 +# 649| r0_32(int) = Load : &:r0_31, ~mu0_2 +# 649| r0_33(glval) = VariableAddress[x] : +# 649| mu0_34(int) = Store : &:r0_33, r0_32 +# 650| v0_35(void) = NoOp : +# 642| v0_36(void) = ReturnVoid : +# 642| v0_37(void) = UnmodeledUse : mu* +# 642| v0_38(void) = AliasedUse : ~mu0_2 +# 642| v0_39(void) = ExitFunction : # 652| void C::MethodCalls() # 652| Block 0 @@ -2931,58 +3029,63 @@ ir.cpp: # 653| r0_6(int) = Constant[0] : # 653| r0_7(int) = Call : func:r0_5, this:r0_4, 0:r0_6 # 653| mu0_8(unknown) = ^CallSideEffect : ~mu0_2 -# 653| v0_9(void) = ^IndirectReadSideEffect[-1] : &:r0_4, ~mu0_2 +# 653| v0_9(void) = ^BufferReadSideEffect[-1] : &:r0_4, ~mu0_2 # 653| mu0_10(C) = ^IndirectMayWriteSideEffect[-1] : &:r0_4 # 654| r0_11(C *) = CopyValue : r0_3 -# 654| r0_12(glval) = FunctionAddress[InstanceMemberFunction] : -# 654| r0_13(int) = Constant[1] : -# 654| r0_14(int) = Call : func:r0_12, this:r0_11, 0:r0_13 -# 654| mu0_15(unknown) = ^CallSideEffect : ~mu0_2 -# 654| v0_16(void) = ^IndirectReadSideEffect[-1] : &:r0_11, ~mu0_2 -# 654| mu0_17(C) = ^IndirectMayWriteSideEffect[-1] : &:r0_11 -#-----| r0_18(C *) = CopyValue : r0_3 -# 655| r0_19(glval) = FunctionAddress[InstanceMemberFunction] : -# 655| r0_20(int) = Constant[2] : -# 655| r0_21(int) = Call : func:r0_19, this:r0_18, 0:r0_20 -# 655| mu0_22(unknown) = ^CallSideEffect : ~mu0_2 -#-----| v0_23(void) = ^IndirectReadSideEffect[-1] : &:r0_18, ~mu0_2 -#-----| mu0_24(C) = ^IndirectMayWriteSideEffect[-1] : &:r0_18 -# 656| v0_25(void) = NoOp : -# 652| v0_26(void) = ReturnVoid : -# 652| v0_27(void) = UnmodeledUse : mu* -# 652| v0_28(void) = ExitFunction : +# 654| r0_12(glval) = CopyValue : r0_11 +# 654| r0_13(glval) = FunctionAddress[InstanceMemberFunction] : +# 654| r0_14(int) = Constant[1] : +# 654| r0_15(int) = Call : func:r0_13, this:r0_12, 0:r0_14 +# 654| mu0_16(unknown) = ^CallSideEffect : ~mu0_2 +# 654| v0_17(void) = ^BufferReadSideEffect[-1] : &:r0_12, ~mu0_2 +# 654| mu0_18(C) = ^IndirectMayWriteSideEffect[-1] : &:r0_12 +#-----| r0_19(C *) = CopyValue : r0_3 +# 655| r0_20(glval) = FunctionAddress[InstanceMemberFunction] : +# 655| r0_21(int) = Constant[2] : +# 655| r0_22(int) = Call : func:r0_20, this:r0_19, 0:r0_21 +# 655| mu0_23(unknown) = ^CallSideEffect : ~mu0_2 +#-----| v0_24(void) = ^BufferReadSideEffect[-1] : &:r0_19, ~mu0_2 +#-----| mu0_25(C) = ^IndirectMayWriteSideEffect[-1] : &:r0_19 +# 656| v0_26(void) = NoOp : +# 652| v0_27(void) = ReturnVoid : +# 652| v0_28(void) = UnmodeledUse : mu* +# 652| v0_29(void) = AliasedUse : ~mu0_2 +# 652| v0_30(void) = ExitFunction : # 658| void C::C() # 658| Block 0 -# 658| v0_0(void) = EnterFunction : -# 658| mu0_1(unknown) = AliasedDefinition : -# 658| mu0_2(unknown) = UnmodeledDefinition : -# 658| r0_3(glval) = InitializeThis : -# 659| r0_4(glval) = FieldAddress[m_a] : r0_3 -# 659| r0_5(int) = Constant[1] : -# 659| mu0_6(int) = Store : &:r0_4, r0_5 -# 663| r0_7(glval) = FieldAddress[m_b] : r0_3 -# 663| r0_8(glval) = FunctionAddress[String] : -# 663| v0_9(void) = Call : func:r0_8, this:r0_7 -# 663| mu0_10(unknown) = ^CallSideEffect : ~mu0_2 -# 660| r0_11(glval) = FieldAddress[m_c] : r0_3 -# 660| r0_12(char) = Constant[3] : -# 660| mu0_13(char) = Store : &:r0_11, r0_12 -# 661| r0_14(glval) = FieldAddress[m_e] : r0_3 -# 661| r0_15(void *) = Constant[0] : -# 661| mu0_16(void *) = Store : &:r0_14, r0_15 -# 662| r0_17(glval) = FieldAddress[m_f] : r0_3 -# 662| r0_18(glval) = FunctionAddress[String] : -# 662| r0_19(glval) = StringConstant["test"] : -# 662| r0_20(char *) = Convert : r0_19 -# 662| v0_21(void) = Call : func:r0_18, this:r0_17, 0:r0_20 -# 662| mu0_22(unknown) = ^CallSideEffect : ~mu0_2 -# 662| v0_23(void) = ^IndirectReadSideEffect[0] : &:r0_20, ~mu0_2 -# 662| mu0_24(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_20 -# 664| v0_25(void) = NoOp : -# 658| v0_26(void) = ReturnVoid : -# 658| v0_27(void) = UnmodeledUse : mu* -# 658| v0_28(void) = ExitFunction : +# 658| v0_0(void) = EnterFunction : +# 658| mu0_1(unknown) = AliasedDefinition : +# 658| mu0_2(unknown) = UnmodeledDefinition : +# 658| r0_3(glval) = InitializeThis : +# 659| r0_4(glval) = FieldAddress[m_a] : r0_3 +# 659| r0_5(int) = Constant[1] : +# 659| mu0_6(int) = Store : &:r0_4, r0_5 +# 663| r0_7(glval) = FieldAddress[m_b] : r0_3 +# 663| r0_8(glval) = FunctionAddress[String] : +# 663| v0_9(void) = Call : func:r0_8, this:r0_7 +# 663| mu0_10(unknown) = ^CallSideEffect : ~mu0_2 +# 663| mu0_11(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_7 +# 660| r0_12(glval) = FieldAddress[m_c] : r0_3 +# 660| r0_13(char) = Constant[3] : +# 660| mu0_14(char) = Store : &:r0_12, r0_13 +# 661| r0_15(glval) = FieldAddress[m_e] : r0_3 +# 661| r0_16(void *) = Constant[0] : +# 661| mu0_17(void *) = Store : &:r0_15, r0_16 +# 662| r0_18(glval) = FieldAddress[m_f] : r0_3 +# 662| r0_19(glval) = FunctionAddress[String] : +# 662| r0_20(glval) = StringConstant["test"] : +# 662| r0_21(char *) = Convert : r0_20 +# 662| v0_22(void) = Call : func:r0_19, this:r0_18, 0:r0_21 +# 662| mu0_23(unknown) = ^CallSideEffect : ~mu0_2 +# 662| mu0_24(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_18 +# 662| v0_25(void) = ^BufferReadSideEffect[0] : &:r0_21, ~mu0_2 +# 662| mu0_26(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_21 +# 664| v0_27(void) = NoOp : +# 658| v0_28(void) = ReturnVoid : +# 658| v0_29(void) = UnmodeledUse : mu* +# 658| v0_30(void) = AliasedUse : ~mu0_2 +# 658| v0_31(void) = ExitFunction : # 675| int DerefReference(int&) # 675| Block 0 @@ -3002,7 +3105,8 @@ ir.cpp: # 675| r0_13(glval) = VariableAddress[#return] : # 675| v0_14(void) = ReturnValue : &:r0_13, ~mu0_2 # 675| v0_15(void) = UnmodeledUse : mu* -# 675| v0_16(void) = ExitFunction : +# 675| v0_16(void) = AliasedUse : ~mu0_2 +# 675| v0_17(void) = ExitFunction : # 679| int& TakeReference() # 679| Block 0 @@ -3011,11 +3115,13 @@ ir.cpp: # 679| mu0_2(unknown) = UnmodeledDefinition : # 680| r0_3(glval) = VariableAddress[#return] : # 680| r0_4(glval) = VariableAddress[g] : -# 680| mu0_5(int &) = Store : &:r0_3, r0_4 -# 679| r0_6(glval) = VariableAddress[#return] : -# 679| v0_7(void) = ReturnValue : &:r0_6, ~mu0_2 -# 679| v0_8(void) = UnmodeledUse : mu* -# 679| v0_9(void) = ExitFunction : +# 680| r0_5(int &) = CopyValue : r0_4 +# 680| mu0_6(int &) = Store : &:r0_3, r0_5 +# 679| r0_7(glval) = VariableAddress[#return] : +# 679| v0_8(void) = ReturnValue : &:r0_7, ~mu0_2 +# 679| v0_9(void) = UnmodeledUse : mu* +# 679| v0_10(void) = AliasedUse : ~mu0_2 +# 679| v0_11(void) = ExitFunction : # 685| void InitReference(int) # 685| Block 0 @@ -3026,44 +3132,53 @@ ir.cpp: # 685| mu0_4(int) = InitializeParameter[x] : &:r0_3 # 686| r0_5(glval) = VariableAddress[r] : # 686| r0_6(glval) = VariableAddress[x] : -# 686| mu0_7(int &) = Store : &:r0_5, r0_6 -# 687| r0_8(glval) = VariableAddress[r2] : -# 687| r0_9(glval) = VariableAddress[r] : -# 687| r0_10(int &) = Load : &:r0_9, ~mu0_2 -# 687| mu0_11(int &) = Store : &:r0_8, r0_10 -# 688| r0_12(glval) = VariableAddress[r3] : -# 688| r0_13(glval) = FunctionAddress[ReturnReference] : -# 688| r0_14(String &) = Call : func:r0_13 -# 688| mu0_15(unknown) = ^CallSideEffect : ~mu0_2 -# 688| r0_16(glval) = Convert : r0_14 -# 688| mu0_17(String &) = Store : &:r0_12, r0_16 -# 689| v0_18(void) = NoOp : -# 685| v0_19(void) = ReturnVoid : -# 685| v0_20(void) = UnmodeledUse : mu* -# 685| v0_21(void) = ExitFunction : +# 686| r0_7(int &) = CopyValue : r0_6 +# 686| mu0_8(int &) = Store : &:r0_5, r0_7 +# 687| r0_9(glval) = VariableAddress[r2] : +# 687| r0_10(glval) = VariableAddress[r] : +# 687| r0_11(int &) = Load : &:r0_10, ~mu0_2 +# 687| r0_12(glval) = CopyValue : r0_11 +# 687| r0_13(int &) = CopyValue : r0_12 +# 687| mu0_14(int &) = Store : &:r0_9, r0_13 +# 688| r0_15(glval) = VariableAddress[r3] : +# 688| r0_16(glval) = FunctionAddress[ReturnReference] : +# 688| r0_17(String &) = Call : func:r0_16 +# 688| mu0_18(unknown) = ^CallSideEffect : ~mu0_2 +# 688| r0_19(glval) = CopyValue : r0_17 +# 688| r0_20(glval) = Convert : r0_19 +# 688| r0_21(String &) = CopyValue : r0_20 +# 688| mu0_22(String &) = Store : &:r0_15, r0_21 +# 689| v0_23(void) = NoOp : +# 685| v0_24(void) = ReturnVoid : +# 685| v0_25(void) = UnmodeledUse : mu* +# 685| v0_26(void) = AliasedUse : ~mu0_2 +# 685| v0_27(void) = ExitFunction : # 691| void ArrayReferences() # 691| Block 0 -# 691| v0_0(void) = EnterFunction : -# 691| mu0_1(unknown) = AliasedDefinition : -# 691| mu0_2(unknown) = UnmodeledDefinition : -# 692| r0_3(glval) = VariableAddress[a] : -# 692| mu0_4(int[10]) = Uninitialized[a] : &:r0_3 -# 693| r0_5(glval) = VariableAddress[ra] : -# 693| r0_6(glval) = VariableAddress[a] : -# 693| mu0_7(int(&)[10]) = Store : &:r0_5, r0_6 -# 694| r0_8(glval) = VariableAddress[x] : -# 694| r0_9(glval) = VariableAddress[ra] : -# 694| r0_10(int(&)[10]) = Load : &:r0_9, ~mu0_2 -# 694| r0_11(int *) = Convert : r0_10 -# 694| r0_12(int) = Constant[5] : -# 694| r0_13(glval) = PointerAdd[4] : r0_11, r0_12 -# 694| r0_14(int) = Load : &:r0_13, ~mu0_2 -# 694| mu0_15(int) = Store : &:r0_8, r0_14 -# 695| v0_16(void) = NoOp : -# 691| v0_17(void) = ReturnVoid : -# 691| v0_18(void) = UnmodeledUse : mu* -# 691| v0_19(void) = ExitFunction : +# 691| v0_0(void) = EnterFunction : +# 691| mu0_1(unknown) = AliasedDefinition : +# 691| mu0_2(unknown) = UnmodeledDefinition : +# 692| r0_3(glval) = VariableAddress[a] : +# 692| mu0_4(int[10]) = Uninitialized[a] : &:r0_3 +# 693| r0_5(glval) = VariableAddress[ra] : +# 693| r0_6(glval) = VariableAddress[a] : +# 693| r0_7(int(&)[10]) = CopyValue : r0_6 +# 693| mu0_8(int(&)[10]) = Store : &:r0_5, r0_7 +# 694| r0_9(glval) = VariableAddress[x] : +# 694| r0_10(glval) = VariableAddress[ra] : +# 694| r0_11(int(&)[10]) = Load : &:r0_10, ~mu0_2 +# 694| r0_12(glval) = CopyValue : r0_11 +# 694| r0_13(int *) = Convert : r0_12 +# 694| r0_14(int) = Constant[5] : +# 694| r0_15(glval) = PointerAdd[4] : r0_13, r0_14 +# 694| r0_16(int) = Load : &:r0_15, ~mu0_2 +# 694| mu0_17(int) = Store : &:r0_9, r0_16 +# 695| v0_18(void) = NoOp : +# 691| v0_19(void) = ReturnVoid : +# 691| v0_20(void) = UnmodeledUse : mu* +# 691| v0_21(void) = AliasedUse : ~mu0_2 +# 691| v0_22(void) = ExitFunction : # 697| void FunctionReferences() # 697| Block 0 @@ -3072,20 +3187,24 @@ ir.cpp: # 697| mu0_2(unknown) = UnmodeledDefinition : # 698| r0_3(glval<..(&)(..)>) = VariableAddress[rfn] : # 698| r0_4(glval<..()(..)>) = FunctionAddress[FuncPtrTarget] : -# 698| mu0_5(..(&)(..)) = Store : &:r0_3, r0_4 -# 699| r0_6(glval<..(*)(..)>) = VariableAddress[pfn] : -# 699| r0_7(glval<..(&)(..)>) = VariableAddress[rfn] : -# 699| r0_8(..(&)(..)) = Load : &:r0_7, ~mu0_2 -# 699| mu0_9(..(*)(..)) = Store : &:r0_6, r0_8 -# 700| r0_10(glval<..(&)(..)>) = VariableAddress[rfn] : -# 700| r0_11(..(&)(..)) = Load : &:r0_10, ~mu0_2 -# 700| r0_12(int) = Constant[5] : -# 700| r0_13(int) = Call : func:r0_11, 0:r0_12 -# 700| mu0_14(unknown) = ^CallSideEffect : ~mu0_2 -# 701| v0_15(void) = NoOp : -# 697| v0_16(void) = ReturnVoid : -# 697| v0_17(void) = UnmodeledUse : mu* -# 697| v0_18(void) = ExitFunction : +# 698| r0_5(..(&)(..)) = CopyValue : r0_4 +# 698| mu0_6(..(&)(..)) = Store : &:r0_3, r0_5 +# 699| r0_7(glval<..(*)(..)>) = VariableAddress[pfn] : +# 699| r0_8(glval<..(&)(..)>) = VariableAddress[rfn] : +# 699| r0_9(..(&)(..)) = Load : &:r0_8, ~mu0_2 +# 699| r0_10(..(*)(..)) = CopyValue : r0_9 +# 699| mu0_11(..(*)(..)) = Store : &:r0_7, r0_10 +# 700| r0_12(glval<..(&)(..)>) = VariableAddress[rfn] : +# 700| r0_13(..(&)(..)) = Load : &:r0_12, ~mu0_2 +# 700| r0_14(..(*)(..)) = CopyValue : r0_13 +# 700| r0_15(int) = Constant[5] : +# 700| r0_16(int) = Call : func:r0_14, 0:r0_15 +# 700| mu0_17(unknown) = ^CallSideEffect : ~mu0_2 +# 701| v0_18(void) = NoOp : +# 697| v0_19(void) = ReturnVoid : +# 697| v0_20(void) = UnmodeledUse : mu* +# 697| v0_21(void) = AliasedUse : ~mu0_2 +# 697| v0_22(void) = ExitFunction : # 704| int min(int, int) # 704| Block 0 @@ -3127,7 +3246,8 @@ ir.cpp: # 704| r3_3(glval) = VariableAddress[#return] : # 704| v3_4(void) = ReturnValue : &:r3_3, ~mu0_2 # 704| v3_5(void) = UnmodeledUse : mu* -# 704| v3_6(void) = ExitFunction : +# 704| v3_6(void) = AliasedUse : ~mu0_2 +# 704| v3_7(void) = ExitFunction : # 708| int CallMin(int, int) # 708| Block 0 @@ -3150,7 +3270,8 @@ ir.cpp: # 708| r0_16(glval) = VariableAddress[#return] : # 708| v0_17(void) = ReturnValue : &:r0_16, ~mu0_2 # 708| v0_18(void) = UnmodeledUse : mu* -# 708| v0_19(void) = ExitFunction : +# 708| v0_19(void) = AliasedUse : ~mu0_2 +# 708| v0_20(void) = ExitFunction : # 715| long Outer::Func(void*, char) # 715| Block 0 @@ -3170,7 +3291,8 @@ ir.cpp: # 715| r0_13(glval) = VariableAddress[#return] : # 715| v0_14(void) = ReturnValue : &:r0_13, ~mu0_2 # 715| v0_15(void) = UnmodeledUse : mu* -# 715| v0_16(void) = ExitFunction : +# 715| v0_16(void) = AliasedUse : ~mu0_2 +# 715| v0_17(void) = ExitFunction : # 720| double CallNestedTemplateFunc() # 720| Block 0 @@ -3183,14 +3305,15 @@ ir.cpp: # 721| r0_6(char) = Constant[111] : # 721| r0_7(long) = Call : func:r0_4, 0:r0_5, 1:r0_6 # 721| mu0_8(unknown) = ^CallSideEffect : ~mu0_2 -# 721| v0_9(void) = ^IndirectReadSideEffect[0] : &:r0_5, ~mu0_2 +# 721| v0_9(void) = ^BufferReadSideEffect[0] : &:r0_5, ~mu0_2 # 721| mu0_10(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_5 # 721| r0_11(double) = Convert : r0_7 # 721| mu0_12(double) = Store : &:r0_3, r0_11 # 720| r0_13(glval) = VariableAddress[#return] : # 720| v0_14(void) = ReturnValue : &:r0_13, ~mu0_2 # 720| v0_15(void) = UnmodeledUse : mu* -# 720| v0_16(void) = ExitFunction : +# 720| v0_16(void) = AliasedUse : ~mu0_2 +# 720| v0_17(void) = ExitFunction : # 724| void TryCatch(bool) # 724| Block 0 @@ -3210,7 +3333,8 @@ ir.cpp: # 724| Block 1 # 724| v1_0(void) = UnmodeledUse : mu* -# 724| v1_1(void) = ExitFunction : +# 724| v1_1(void) = AliasedUse : ~mu0_2 +# 724| v1_2(void) = ExitFunction : # 724| Block 2 # 724| v2_0(void) = Unwind : @@ -3257,9 +3381,10 @@ ir.cpp: # 731| r7_3(char *) = Convert : r7_2 # 731| v7_4(void) = Call : func:r7_1, this:r7_0, 0:r7_3 # 731| mu7_5(unknown) = ^CallSideEffect : ~mu0_2 -# 731| v7_6(void) = ^IndirectReadSideEffect[0] : &:r7_3, ~mu0_2 -# 731| mu7_7(unknown) = ^BufferMayWriteSideEffect[0] : &:r7_3 -# 731| v7_8(void) = ThrowValue : &:r7_0, ~mu0_2 +# 731| mu7_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r7_0 +# 731| v7_7(void) = ^BufferReadSideEffect[0] : &:r7_3, ~mu0_2 +# 731| mu7_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r7_3 +# 731| v7_9(void) = ThrowValue : &:r7_0, ~mu0_2 #-----| Exception -> Block 9 # 733| Block 8 @@ -3274,19 +3399,20 @@ ir.cpp: #-----| Goto -> Block 10 # 735| Block 10 -# 735| r10_0(glval) = VariableAddress[s] : -# 735| mu10_1(char *) = InitializeParameter[s] : &:r10_0 -# 735| r10_2(char *) = Load : &:r10_0, ~mu10_1 -# 735| mu10_3(unknown) = InitializeIndirection[s] : &:r10_2 -# 736| r10_4(glval) = VariableAddress[#throw736:5] : -# 736| r10_5(glval) = FunctionAddress[String] : -# 736| r10_6(glval) = VariableAddress[s] : -# 736| r10_7(char *) = Load : &:r10_6, ~mu0_2 -# 736| v10_8(void) = Call : func:r10_5, this:r10_4, 0:r10_7 -# 736| mu10_9(unknown) = ^CallSideEffect : ~mu0_2 -# 736| v10_10(void) = ^IndirectReadSideEffect[0] : &:r10_7, ~mu0_2 -# 736| mu10_11(unknown) = ^BufferMayWriteSideEffect[0] : &:r10_7 -# 736| v10_12(void) = ThrowValue : &:r10_4, ~mu0_2 +# 735| r10_0(glval) = VariableAddress[s] : +# 735| mu10_1(char *) = InitializeParameter[s] : &:r10_0 +# 735| r10_2(char *) = Load : &:r10_0, ~mu10_1 +# 735| mu10_3(unknown) = InitializeIndirection[s] : &:r10_2 +# 736| r10_4(glval) = VariableAddress[#throw736:5] : +# 736| r10_5(glval) = FunctionAddress[String] : +# 736| r10_6(glval) = VariableAddress[s] : +# 736| r10_7(char *) = Load : &:r10_6, ~mu0_2 +# 736| v10_8(void) = Call : func:r10_5, this:r10_4, 0:r10_7 +# 736| mu10_9(unknown) = ^CallSideEffect : ~mu0_2 +# 736| mu10_10(String) = ^IndirectMayWriteSideEffect[-1] : &:r10_4 +# 736| v10_11(void) = ^BufferReadSideEffect[0] : &:r10_7, ~mu0_2 +# 736| mu10_12(unknown) = ^BufferMayWriteSideEffect[0] : &:r10_7 +# 736| v10_13(void) = ThrowValue : &:r10_4, ~mu0_2 #-----| Exception -> Block 2 # 738| Block 11 @@ -3324,59 +3450,70 @@ ir.cpp: #-----| mu0_7(unknown) = InitializeIndirection[p#0] : &:r0_6 #-----| r0_8(Base *) = CopyValue : r0_3 #-----| r0_9(glval) = FieldAddress[base_s] : r0_8 -# 745| r0_10(glval) = FunctionAddress[operator=] : -#-----| r0_11(glval) = VariableAddress[p#0] : -#-----| r0_12(Base &) = Load : &:r0_11, ~mu0_2 -#-----| r0_13(glval) = FieldAddress[base_s] : r0_12 -# 745| r0_14(String &) = Call : func:r0_10, this:r0_9, 0:r0_13 -# 745| mu0_15(unknown) = ^CallSideEffect : ~mu0_2 -#-----| v0_16(void) = ^IndirectReadSideEffect[-1] : &:r0_9, ~mu0_2 -#-----| v0_17(void) = ^IndirectReadSideEffect[0] : &:r0_13, ~mu0_2 -#-----| mu0_18(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_9 -#-----| mu0_19(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_13 -#-----| r0_20(glval) = VariableAddress[#return] : -#-----| r0_21(Base *) = CopyValue : r0_3 -#-----| mu0_22(Base &) = Store : &:r0_20, r0_21 -#-----| v0_23(void) = ReturnIndirection : &:r0_6, ~mu0_2 -# 745| r0_24(glval) = VariableAddress[#return] : -# 745| v0_25(void) = ReturnValue : &:r0_24, ~mu0_2 -# 745| v0_26(void) = UnmodeledUse : mu* -# 745| v0_27(void) = ExitFunction : +#-----| r0_10(String *) = CopyValue : r0_9 +# 745| r0_11(glval) = FunctionAddress[operator=] : +#-----| r0_12(glval) = VariableAddress[p#0] : +#-----| r0_13(Base &) = Load : &:r0_12, ~mu0_2 +#-----| r0_14(glval) = CopyValue : r0_13 +#-----| r0_15(glval) = FieldAddress[base_s] : r0_14 +#-----| r0_16(String &) = CopyValue : r0_15 +# 745| r0_17(String &) = Call : func:r0_11, this:r0_10, 0:r0_16 +# 745| mu0_18(unknown) = ^CallSideEffect : ~mu0_2 +#-----| v0_19(void) = ^BufferReadSideEffect[-1] : &:r0_10, ~mu0_2 +#-----| v0_20(void) = ^BufferReadSideEffect[0] : &:r0_16, ~mu0_2 +#-----| mu0_21(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_10 +#-----| mu0_22(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_16 +#-----| r0_23(glval) = CopyValue : r0_17 +#-----| r0_24(glval) = VariableAddress[#return] : +#-----| r0_25(Base *) = CopyValue : r0_3 +#-----| r0_26(glval) = CopyValue : r0_25 +#-----| r0_27(Base &) = CopyValue : r0_26 +#-----| mu0_28(Base &) = Store : &:r0_24, r0_27 +#-----| v0_29(void) = ReturnIndirection : &:r0_6, ~mu0_2 +# 745| r0_30(glval) = VariableAddress[#return] : +# 745| v0_31(void) = ReturnValue : &:r0_30, ~mu0_2 +# 745| v0_32(void) = UnmodeledUse : mu* +# 745| v0_33(void) = AliasedUse : ~mu0_2 +# 745| v0_34(void) = ExitFunction : # 745| void Base::Base(Base const&) # 745| Block 0 -# 745| v0_0(void) = EnterFunction : -# 745| mu0_1(unknown) = AliasedDefinition : -# 745| mu0_2(unknown) = UnmodeledDefinition : -# 745| r0_3(glval) = InitializeThis : -#-----| r0_4(glval) = VariableAddress[p#0] : -#-----| mu0_5(Base &) = InitializeParameter[p#0] : &:r0_4 -#-----| r0_6(Base &) = Load : &:r0_4, ~mu0_5 -#-----| mu0_7(unknown) = InitializeIndirection[p#0] : &:r0_6 -# 745| r0_8(glval) = FieldAddress[base_s] : r0_3 -# 745| r0_9(glval) = FunctionAddress[String] : -# 745| v0_10(void) = Call : func:r0_9, this:r0_8 -# 745| mu0_11(unknown) = ^CallSideEffect : ~mu0_2 -# 745| v0_12(void) = NoOp : -#-----| v0_13(void) = ReturnIndirection : &:r0_6, ~mu0_2 -# 745| v0_14(void) = ReturnVoid : -# 745| v0_15(void) = UnmodeledUse : mu* -# 745| v0_16(void) = ExitFunction : +# 745| v0_0(void) = EnterFunction : +# 745| mu0_1(unknown) = AliasedDefinition : +# 745| mu0_2(unknown) = UnmodeledDefinition : +# 745| r0_3(glval) = InitializeThis : +#-----| r0_4(glval) = VariableAddress[p#0] : +#-----| mu0_5(Base &) = InitializeParameter[p#0] : &:r0_4 +#-----| r0_6(Base &) = Load : &:r0_4, ~mu0_5 +#-----| mu0_7(unknown) = InitializeIndirection[p#0] : &:r0_6 +# 745| r0_8(glval) = FieldAddress[base_s] : r0_3 +# 745| r0_9(glval) = FunctionAddress[String] : +# 745| v0_10(void) = Call : func:r0_9, this:r0_8 +# 745| mu0_11(unknown) = ^CallSideEffect : ~mu0_2 +# 745| mu0_12(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 +# 745| v0_13(void) = NoOp : +#-----| v0_14(void) = ReturnIndirection : &:r0_6, ~mu0_2 +# 745| v0_15(void) = ReturnVoid : +# 745| v0_16(void) = UnmodeledUse : mu* +# 745| v0_17(void) = AliasedUse : ~mu0_2 +# 745| v0_18(void) = ExitFunction : # 748| void Base::Base() # 748| Block 0 -# 748| v0_0(void) = EnterFunction : -# 748| mu0_1(unknown) = AliasedDefinition : -# 748| mu0_2(unknown) = UnmodeledDefinition : -# 748| r0_3(glval) = InitializeThis : -# 748| r0_4(glval) = FieldAddress[base_s] : r0_3 -# 748| r0_5(glval) = FunctionAddress[String] : -# 748| v0_6(void) = Call : func:r0_5, this:r0_4 -# 748| mu0_7(unknown) = ^CallSideEffect : ~mu0_2 -# 749| v0_8(void) = NoOp : -# 748| v0_9(void) = ReturnVoid : -# 748| v0_10(void) = UnmodeledUse : mu* -# 748| v0_11(void) = ExitFunction : +# 748| v0_0(void) = EnterFunction : +# 748| mu0_1(unknown) = AliasedDefinition : +# 748| mu0_2(unknown) = UnmodeledDefinition : +# 748| r0_3(glval) = InitializeThis : +# 748| r0_4(glval) = FieldAddress[base_s] : r0_3 +# 748| r0_5(glval) = FunctionAddress[String] : +# 748| v0_6(void) = Call : func:r0_5, this:r0_4 +# 748| mu0_7(unknown) = ^CallSideEffect : ~mu0_2 +# 748| mu0_8(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_4 +# 749| v0_9(void) = NoOp : +# 748| v0_10(void) = ReturnVoid : +# 748| v0_11(void) = UnmodeledUse : mu* +# 748| v0_12(void) = AliasedUse : ~mu0_2 +# 748| v0_13(void) = ExitFunction : # 750| void Base::~Base() # 750| Block 0 @@ -3391,554 +3528,639 @@ ir.cpp: # 751| mu0_8(unknown) = ^CallSideEffect : ~mu0_2 # 750| v0_9(void) = ReturnVoid : # 750| v0_10(void) = UnmodeledUse : mu* -# 750| v0_11(void) = ExitFunction : +# 750| v0_11(void) = AliasedUse : ~mu0_2 +# 750| v0_12(void) = ExitFunction : # 754| Middle& Middle::operator=(Middle const&) # 754| Block 0 -# 754| v0_0(void) = EnterFunction : -# 754| mu0_1(unknown) = AliasedDefinition : -# 754| mu0_2(unknown) = UnmodeledDefinition : -# 754| r0_3(glval) = InitializeThis : -#-----| r0_4(glval) = VariableAddress[p#0] : -#-----| mu0_5(Middle &) = InitializeParameter[p#0] : &:r0_4 -#-----| r0_6(Middle &) = Load : &:r0_4, ~mu0_5 -#-----| mu0_7(unknown) = InitializeIndirection[p#0] : &:r0_6 -#-----| r0_8(Middle *) = CopyValue : r0_3 -#-----| r0_9(Base *) = ConvertToBase[Middle : Base] : r0_8 -# 754| r0_10(glval) = FunctionAddress[operator=] : -#-----| r0_11(glval) = VariableAddress[p#0] : -#-----| r0_12(Middle &) = Load : &:r0_11, ~mu0_2 -#-----| r0_13(Base *) = ConvertToBase[Middle : Base] : r0_12 -# 754| r0_14(Base &) = Call : func:r0_10, this:r0_9, 0:r0_13 -# 754| mu0_15(unknown) = ^CallSideEffect : ~mu0_2 -#-----| v0_16(void) = ^IndirectReadSideEffect[-1] : &:r0_9, ~mu0_2 -#-----| v0_17(void) = ^IndirectReadSideEffect[0] : &:r0_13, ~mu0_2 -#-----| mu0_18(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_9 -#-----| mu0_19(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_13 -#-----| r0_20(Middle *) = CopyValue : r0_3 -#-----| r0_21(glval) = FieldAddress[middle_s] : r0_20 -# 754| r0_22(glval) = FunctionAddress[operator=] : -#-----| r0_23(glval) = VariableAddress[p#0] : -#-----| r0_24(Middle &) = Load : &:r0_23, ~mu0_2 -#-----| r0_25(glval) = FieldAddress[middle_s] : r0_24 -# 754| r0_26(String &) = Call : func:r0_22, this:r0_21, 0:r0_25 -# 754| mu0_27(unknown) = ^CallSideEffect : ~mu0_2 -#-----| v0_28(void) = ^IndirectReadSideEffect[-1] : &:r0_21, ~mu0_2 -#-----| v0_29(void) = ^IndirectReadSideEffect[0] : &:r0_25, ~mu0_2 -#-----| mu0_30(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_21 -#-----| mu0_31(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_25 -#-----| r0_32(glval) = VariableAddress[#return] : -#-----| r0_33(Middle *) = CopyValue : r0_3 -#-----| mu0_34(Middle &) = Store : &:r0_32, r0_33 -#-----| v0_35(void) = ReturnIndirection : &:r0_6, ~mu0_2 -# 754| r0_36(glval) = VariableAddress[#return] : -# 754| v0_37(void) = ReturnValue : &:r0_36, ~mu0_2 -# 754| v0_38(void) = UnmodeledUse : mu* -# 754| v0_39(void) = ExitFunction : +# 754| v0_0(void) = EnterFunction : +# 754| mu0_1(unknown) = AliasedDefinition : +# 754| mu0_2(unknown) = UnmodeledDefinition : +# 754| r0_3(glval) = InitializeThis : +#-----| r0_4(glval) = VariableAddress[p#0] : +#-----| mu0_5(Middle &) = InitializeParameter[p#0] : &:r0_4 +#-----| r0_6(Middle &) = Load : &:r0_4, ~mu0_5 +#-----| mu0_7(unknown) = InitializeIndirection[p#0] : &:r0_6 +#-----| r0_8(Middle *) = CopyValue : r0_3 +#-----| r0_9(Base *) = ConvertToNonVirtualBase[Middle : Base] : r0_8 +# 754| r0_10(glval) = FunctionAddress[operator=] : +#-----| r0_11(glval) = VariableAddress[p#0] : +#-----| r0_12(Middle &) = Load : &:r0_11, ~mu0_2 +#-----| r0_13(glval) = CopyValue : r0_12 +#-----| r0_14(Middle *) = CopyValue : r0_13 +#-----| r0_15(Base *) = ConvertToNonVirtualBase[Middle : Base] : r0_14 +#-----| r0_16(glval) = CopyValue : r0_15 +#-----| r0_17(Base &) = CopyValue : r0_16 +# 754| r0_18(Base &) = Call : func:r0_10, this:r0_9, 0:r0_17 +# 754| mu0_19(unknown) = ^CallSideEffect : ~mu0_2 +#-----| v0_20(void) = ^BufferReadSideEffect[-1] : &:r0_9, ~mu0_2 +#-----| v0_21(void) = ^BufferReadSideEffect[0] : &:r0_17, ~mu0_2 +#-----| mu0_22(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_9 +#-----| mu0_23(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_17 +#-----| r0_24(glval) = CopyValue : r0_18 +#-----| r0_25(Middle *) = CopyValue : r0_3 +#-----| r0_26(glval) = FieldAddress[middle_s] : r0_25 +#-----| r0_27(String *) = CopyValue : r0_26 +# 754| r0_28(glval) = FunctionAddress[operator=] : +#-----| r0_29(glval) = VariableAddress[p#0] : +#-----| r0_30(Middle &) = Load : &:r0_29, ~mu0_2 +#-----| r0_31(glval) = CopyValue : r0_30 +#-----| r0_32(glval) = FieldAddress[middle_s] : r0_31 +#-----| r0_33(String &) = CopyValue : r0_32 +# 754| r0_34(String &) = Call : func:r0_28, this:r0_27, 0:r0_33 +# 754| mu0_35(unknown) = ^CallSideEffect : ~mu0_2 +#-----| v0_36(void) = ^BufferReadSideEffect[-1] : &:r0_27, ~mu0_2 +#-----| v0_37(void) = ^BufferReadSideEffect[0] : &:r0_33, ~mu0_2 +#-----| mu0_38(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_27 +#-----| mu0_39(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_33 +#-----| r0_40(glval) = CopyValue : r0_34 +#-----| r0_41(glval) = VariableAddress[#return] : +#-----| r0_42(Middle *) = CopyValue : r0_3 +#-----| r0_43(glval) = CopyValue : r0_42 +#-----| r0_44(Middle &) = CopyValue : r0_43 +#-----| mu0_45(Middle &) = Store : &:r0_41, r0_44 +#-----| v0_46(void) = ReturnIndirection : &:r0_6, ~mu0_2 +# 754| r0_47(glval) = VariableAddress[#return] : +# 754| v0_48(void) = ReturnValue : &:r0_47, ~mu0_2 +# 754| v0_49(void) = UnmodeledUse : mu* +# 754| v0_50(void) = AliasedUse : ~mu0_2 +# 754| v0_51(void) = ExitFunction : # 757| void Middle::Middle() # 757| Block 0 -# 757| v0_0(void) = EnterFunction : -# 757| mu0_1(unknown) = AliasedDefinition : -# 757| mu0_2(unknown) = UnmodeledDefinition : -# 757| r0_3(glval) = InitializeThis : -# 757| r0_4(glval) = ConvertToBase[Middle : Base] : r0_3 -# 757| r0_5(glval) = FunctionAddress[Base] : -# 757| v0_6(void) = Call : func:r0_5, this:r0_4 -# 757| mu0_7(unknown) = ^CallSideEffect : ~mu0_2 -# 757| r0_8(glval) = FieldAddress[middle_s] : r0_3 -# 757| r0_9(glval) = FunctionAddress[String] : -# 757| v0_10(void) = Call : func:r0_9, this:r0_8 -# 757| mu0_11(unknown) = ^CallSideEffect : ~mu0_2 -# 758| v0_12(void) = NoOp : -# 757| v0_13(void) = ReturnVoid : -# 757| v0_14(void) = UnmodeledUse : mu* -# 757| v0_15(void) = ExitFunction : +# 757| v0_0(void) = EnterFunction : +# 757| mu0_1(unknown) = AliasedDefinition : +# 757| mu0_2(unknown) = UnmodeledDefinition : +# 757| r0_3(glval) = InitializeThis : +# 757| r0_4(glval) = ConvertToNonVirtualBase[Middle : Base] : r0_3 +# 757| r0_5(glval) = FunctionAddress[Base] : +# 757| v0_6(void) = Call : func:r0_5, this:r0_4 +# 757| mu0_7(unknown) = ^CallSideEffect : ~mu0_2 +# 757| mu0_8(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_4 +# 757| r0_9(glval) = FieldAddress[middle_s] : r0_3 +# 757| r0_10(glval) = FunctionAddress[String] : +# 757| v0_11(void) = Call : func:r0_10, this:r0_9 +# 757| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 +# 757| mu0_13(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_9 +# 758| v0_14(void) = NoOp : +# 757| v0_15(void) = ReturnVoid : +# 757| v0_16(void) = UnmodeledUse : mu* +# 757| v0_17(void) = AliasedUse : ~mu0_2 +# 757| v0_18(void) = ExitFunction : # 759| void Middle::~Middle() # 759| Block 0 -# 759| v0_0(void) = EnterFunction : -# 759| mu0_1(unknown) = AliasedDefinition : -# 759| mu0_2(unknown) = UnmodeledDefinition : -# 759| r0_3(glval) = InitializeThis : -# 760| v0_4(void) = NoOp : -# 760| r0_5(glval) = FieldAddress[middle_s] : r0_3 -# 760| r0_6(glval) = FunctionAddress[~String] : -# 760| v0_7(void) = Call : func:r0_6, this:r0_5 -# 760| mu0_8(unknown) = ^CallSideEffect : ~mu0_2 -# 760| r0_9(glval) = ConvertToBase[Middle : Base] : r0_3 -# 760| r0_10(glval) = FunctionAddress[~Base] : -# 760| v0_11(void) = Call : func:r0_10, this:r0_9 -# 760| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 -# 759| v0_13(void) = ReturnVoid : -# 759| v0_14(void) = UnmodeledUse : mu* -# 759| v0_15(void) = ExitFunction : +# 759| v0_0(void) = EnterFunction : +# 759| mu0_1(unknown) = AliasedDefinition : +# 759| mu0_2(unknown) = UnmodeledDefinition : +# 759| r0_3(glval) = InitializeThis : +# 760| v0_4(void) = NoOp : +# 760| r0_5(glval) = FieldAddress[middle_s] : r0_3 +# 760| r0_6(glval) = FunctionAddress[~String] : +# 760| v0_7(void) = Call : func:r0_6, this:r0_5 +# 760| mu0_8(unknown) = ^CallSideEffect : ~mu0_2 +# 760| r0_9(glval) = ConvertToNonVirtualBase[Middle : Base] : r0_3 +# 760| r0_10(glval) = FunctionAddress[~Base] : +# 760| v0_11(void) = Call : func:r0_10, this:r0_9 +# 760| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 +# 759| v0_13(void) = ReturnVoid : +# 759| v0_14(void) = UnmodeledUse : mu* +# 759| v0_15(void) = AliasedUse : ~mu0_2 +# 759| v0_16(void) = ExitFunction : # 763| Derived& Derived::operator=(Derived const&) # 763| Block 0 -# 763| v0_0(void) = EnterFunction : -# 763| mu0_1(unknown) = AliasedDefinition : -# 763| mu0_2(unknown) = UnmodeledDefinition : -# 763| r0_3(glval) = InitializeThis : -#-----| r0_4(glval) = VariableAddress[p#0] : -#-----| mu0_5(Derived &) = InitializeParameter[p#0] : &:r0_4 -#-----| r0_6(Derived &) = Load : &:r0_4, ~mu0_5 -#-----| mu0_7(unknown) = InitializeIndirection[p#0] : &:r0_6 -#-----| r0_8(Derived *) = CopyValue : r0_3 -#-----| r0_9(Middle *) = ConvertToBase[Derived : Middle] : r0_8 -# 763| r0_10(glval) = FunctionAddress[operator=] : -#-----| r0_11(glval) = VariableAddress[p#0] : -#-----| r0_12(Derived &) = Load : &:r0_11, ~mu0_2 -#-----| r0_13(Middle *) = ConvertToBase[Derived : Middle] : r0_12 -# 763| r0_14(Middle &) = Call : func:r0_10, this:r0_9, 0:r0_13 -# 763| mu0_15(unknown) = ^CallSideEffect : ~mu0_2 -#-----| v0_16(void) = ^IndirectReadSideEffect[-1] : &:r0_9, ~mu0_2 -#-----| v0_17(void) = ^IndirectReadSideEffect[0] : &:r0_13, ~mu0_2 -#-----| mu0_18(Middle) = ^IndirectMayWriteSideEffect[-1] : &:r0_9 -#-----| mu0_19(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_13 -#-----| r0_20(Derived *) = CopyValue : r0_3 -#-----| r0_21(glval) = FieldAddress[derived_s] : r0_20 -# 763| r0_22(glval) = FunctionAddress[operator=] : -#-----| r0_23(glval) = VariableAddress[p#0] : -#-----| r0_24(Derived &) = Load : &:r0_23, ~mu0_2 -#-----| r0_25(glval) = FieldAddress[derived_s] : r0_24 -# 763| r0_26(String &) = Call : func:r0_22, this:r0_21, 0:r0_25 -# 763| mu0_27(unknown) = ^CallSideEffect : ~mu0_2 -#-----| v0_28(void) = ^IndirectReadSideEffect[-1] : &:r0_21, ~mu0_2 -#-----| v0_29(void) = ^IndirectReadSideEffect[0] : &:r0_25, ~mu0_2 -#-----| mu0_30(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_21 -#-----| mu0_31(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_25 -#-----| r0_32(glval) = VariableAddress[#return] : -#-----| r0_33(Derived *) = CopyValue : r0_3 -#-----| mu0_34(Derived &) = Store : &:r0_32, r0_33 -#-----| v0_35(void) = ReturnIndirection : &:r0_6, ~mu0_2 -# 763| r0_36(glval) = VariableAddress[#return] : -# 763| v0_37(void) = ReturnValue : &:r0_36, ~mu0_2 -# 763| v0_38(void) = UnmodeledUse : mu* -# 763| v0_39(void) = ExitFunction : +# 763| v0_0(void) = EnterFunction : +# 763| mu0_1(unknown) = AliasedDefinition : +# 763| mu0_2(unknown) = UnmodeledDefinition : +# 763| r0_3(glval) = InitializeThis : +#-----| r0_4(glval) = VariableAddress[p#0] : +#-----| mu0_5(Derived &) = InitializeParameter[p#0] : &:r0_4 +#-----| r0_6(Derived &) = Load : &:r0_4, ~mu0_5 +#-----| mu0_7(unknown) = InitializeIndirection[p#0] : &:r0_6 +#-----| r0_8(Derived *) = CopyValue : r0_3 +#-----| r0_9(Middle *) = ConvertToNonVirtualBase[Derived : Middle] : r0_8 +# 763| r0_10(glval) = FunctionAddress[operator=] : +#-----| r0_11(glval) = VariableAddress[p#0] : +#-----| r0_12(Derived &) = Load : &:r0_11, ~mu0_2 +#-----| r0_13(glval) = CopyValue : r0_12 +#-----| r0_14(Derived *) = CopyValue : r0_13 +#-----| r0_15(Middle *) = ConvertToNonVirtualBase[Derived : Middle] : r0_14 +#-----| r0_16(glval) = CopyValue : r0_15 +#-----| r0_17(Middle &) = CopyValue : r0_16 +# 763| r0_18(Middle &) = Call : func:r0_10, this:r0_9, 0:r0_17 +# 763| mu0_19(unknown) = ^CallSideEffect : ~mu0_2 +#-----| v0_20(void) = ^BufferReadSideEffect[-1] : &:r0_9, ~mu0_2 +#-----| v0_21(void) = ^BufferReadSideEffect[0] : &:r0_17, ~mu0_2 +#-----| mu0_22(Middle) = ^IndirectMayWriteSideEffect[-1] : &:r0_9 +#-----| mu0_23(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_17 +#-----| r0_24(glval) = CopyValue : r0_18 +#-----| r0_25(Derived *) = CopyValue : r0_3 +#-----| r0_26(glval) = FieldAddress[derived_s] : r0_25 +#-----| r0_27(String *) = CopyValue : r0_26 +# 763| r0_28(glval) = FunctionAddress[operator=] : +#-----| r0_29(glval) = VariableAddress[p#0] : +#-----| r0_30(Derived &) = Load : &:r0_29, ~mu0_2 +#-----| r0_31(glval) = CopyValue : r0_30 +#-----| r0_32(glval) = FieldAddress[derived_s] : r0_31 +#-----| r0_33(String &) = CopyValue : r0_32 +# 763| r0_34(String &) = Call : func:r0_28, this:r0_27, 0:r0_33 +# 763| mu0_35(unknown) = ^CallSideEffect : ~mu0_2 +#-----| v0_36(void) = ^BufferReadSideEffect[-1] : &:r0_27, ~mu0_2 +#-----| v0_37(void) = ^BufferReadSideEffect[0] : &:r0_33, ~mu0_2 +#-----| mu0_38(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_27 +#-----| mu0_39(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_33 +#-----| r0_40(glval) = CopyValue : r0_34 +#-----| r0_41(glval) = VariableAddress[#return] : +#-----| r0_42(Derived *) = CopyValue : r0_3 +#-----| r0_43(glval) = CopyValue : r0_42 +#-----| r0_44(Derived &) = CopyValue : r0_43 +#-----| mu0_45(Derived &) = Store : &:r0_41, r0_44 +#-----| v0_46(void) = ReturnIndirection : &:r0_6, ~mu0_2 +# 763| r0_47(glval) = VariableAddress[#return] : +# 763| v0_48(void) = ReturnValue : &:r0_47, ~mu0_2 +# 763| v0_49(void) = UnmodeledUse : mu* +# 763| v0_50(void) = AliasedUse : ~mu0_2 +# 763| v0_51(void) = ExitFunction : # 766| void Derived::Derived() # 766| Block 0 -# 766| v0_0(void) = EnterFunction : -# 766| mu0_1(unknown) = AliasedDefinition : -# 766| mu0_2(unknown) = UnmodeledDefinition : -# 766| r0_3(glval) = InitializeThis : -# 766| r0_4(glval) = ConvertToBase[Derived : Middle] : r0_3 -# 766| r0_5(glval) = FunctionAddress[Middle] : -# 766| v0_6(void) = Call : func:r0_5, this:r0_4 -# 766| mu0_7(unknown) = ^CallSideEffect : ~mu0_2 -# 766| r0_8(glval) = FieldAddress[derived_s] : r0_3 -# 766| r0_9(glval) = FunctionAddress[String] : -# 766| v0_10(void) = Call : func:r0_9, this:r0_8 -# 766| mu0_11(unknown) = ^CallSideEffect : ~mu0_2 -# 767| v0_12(void) = NoOp : -# 766| v0_13(void) = ReturnVoid : -# 766| v0_14(void) = UnmodeledUse : mu* -# 766| v0_15(void) = ExitFunction : +# 766| v0_0(void) = EnterFunction : +# 766| mu0_1(unknown) = AliasedDefinition : +# 766| mu0_2(unknown) = UnmodeledDefinition : +# 766| r0_3(glval) = InitializeThis : +# 766| r0_4(glval) = ConvertToNonVirtualBase[Derived : Middle] : r0_3 +# 766| r0_5(glval) = FunctionAddress[Middle] : +# 766| v0_6(void) = Call : func:r0_5, this:r0_4 +# 766| mu0_7(unknown) = ^CallSideEffect : ~mu0_2 +# 766| mu0_8(Middle) = ^IndirectMayWriteSideEffect[-1] : &:r0_4 +# 766| r0_9(glval) = FieldAddress[derived_s] : r0_3 +# 766| r0_10(glval) = FunctionAddress[String] : +# 766| v0_11(void) = Call : func:r0_10, this:r0_9 +# 766| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 +# 766| mu0_13(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_9 +# 767| v0_14(void) = NoOp : +# 766| v0_15(void) = ReturnVoid : +# 766| v0_16(void) = UnmodeledUse : mu* +# 766| v0_17(void) = AliasedUse : ~mu0_2 +# 766| v0_18(void) = ExitFunction : # 768| void Derived::~Derived() # 768| Block 0 -# 768| v0_0(void) = EnterFunction : -# 768| mu0_1(unknown) = AliasedDefinition : -# 768| mu0_2(unknown) = UnmodeledDefinition : -# 768| r0_3(glval) = InitializeThis : -# 769| v0_4(void) = NoOp : -# 769| r0_5(glval) = FieldAddress[derived_s] : r0_3 -# 769| r0_6(glval) = FunctionAddress[~String] : -# 769| v0_7(void) = Call : func:r0_6, this:r0_5 -# 769| mu0_8(unknown) = ^CallSideEffect : ~mu0_2 -# 769| r0_9(glval) = ConvertToBase[Derived : Middle] : r0_3 -# 769| r0_10(glval) = FunctionAddress[~Middle] : -# 769| v0_11(void) = Call : func:r0_10, this:r0_9 -# 769| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 -# 768| v0_13(void) = ReturnVoid : -# 768| v0_14(void) = UnmodeledUse : mu* -# 768| v0_15(void) = ExitFunction : +# 768| v0_0(void) = EnterFunction : +# 768| mu0_1(unknown) = AliasedDefinition : +# 768| mu0_2(unknown) = UnmodeledDefinition : +# 768| r0_3(glval) = InitializeThis : +# 769| v0_4(void) = NoOp : +# 769| r0_5(glval) = FieldAddress[derived_s] : r0_3 +# 769| r0_6(glval) = FunctionAddress[~String] : +# 769| v0_7(void) = Call : func:r0_6, this:r0_5 +# 769| mu0_8(unknown) = ^CallSideEffect : ~mu0_2 +# 769| r0_9(glval) = ConvertToNonVirtualBase[Derived : Middle] : r0_3 +# 769| r0_10(glval) = FunctionAddress[~Middle] : +# 769| v0_11(void) = Call : func:r0_10, this:r0_9 +# 769| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 +# 768| v0_13(void) = ReturnVoid : +# 768| v0_14(void) = UnmodeledUse : mu* +# 768| v0_15(void) = AliasedUse : ~mu0_2 +# 768| v0_16(void) = ExitFunction : # 775| void MiddleVB1::MiddleVB1() # 775| Block 0 -# 775| v0_0(void) = EnterFunction : -# 775| mu0_1(unknown) = AliasedDefinition : -# 775| mu0_2(unknown) = UnmodeledDefinition : -# 775| r0_3(glval) = InitializeThis : -# 775| r0_4(glval) = ConvertToBase[MiddleVB1 : Base] : r0_3 -# 775| r0_5(glval) = FunctionAddress[Base] : -# 775| v0_6(void) = Call : func:r0_5, this:r0_4 -# 775| mu0_7(unknown) = ^CallSideEffect : ~mu0_2 -# 775| r0_8(glval) = FieldAddress[middlevb1_s] : r0_3 -# 775| r0_9(glval) = FunctionAddress[String] : -# 775| v0_10(void) = Call : func:r0_9, this:r0_8 -# 775| mu0_11(unknown) = ^CallSideEffect : ~mu0_2 -# 776| v0_12(void) = NoOp : -# 775| v0_13(void) = ReturnVoid : -# 775| v0_14(void) = UnmodeledUse : mu* -# 775| v0_15(void) = ExitFunction : +# 775| v0_0(void) = EnterFunction : +# 775| mu0_1(unknown) = AliasedDefinition : +# 775| mu0_2(unknown) = UnmodeledDefinition : +# 775| r0_3(glval) = InitializeThis : +# 775| r0_4(glval) = ConvertToNonVirtualBase[MiddleVB1 : Base] : r0_3 +# 775| r0_5(glval) = FunctionAddress[Base] : +# 775| v0_6(void) = Call : func:r0_5, this:r0_4 +# 775| mu0_7(unknown) = ^CallSideEffect : ~mu0_2 +# 775| mu0_8(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_4 +# 775| r0_9(glval) = FieldAddress[middlevb1_s] : r0_3 +# 775| r0_10(glval) = FunctionAddress[String] : +# 775| v0_11(void) = Call : func:r0_10, this:r0_9 +# 775| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 +# 775| mu0_13(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_9 +# 776| v0_14(void) = NoOp : +# 775| v0_15(void) = ReturnVoid : +# 775| v0_16(void) = UnmodeledUse : mu* +# 775| v0_17(void) = AliasedUse : ~mu0_2 +# 775| v0_18(void) = ExitFunction : # 777| void MiddleVB1::~MiddleVB1() # 777| Block 0 -# 777| v0_0(void) = EnterFunction : -# 777| mu0_1(unknown) = AliasedDefinition : -# 777| mu0_2(unknown) = UnmodeledDefinition : -# 777| r0_3(glval) = InitializeThis : -# 778| v0_4(void) = NoOp : -# 778| r0_5(glval) = FieldAddress[middlevb1_s] : r0_3 -# 778| r0_6(glval) = FunctionAddress[~String] : -# 778| v0_7(void) = Call : func:r0_6, this:r0_5 -# 778| mu0_8(unknown) = ^CallSideEffect : ~mu0_2 -# 778| r0_9(glval) = ConvertToBase[MiddleVB1 : Base] : r0_3 -# 778| r0_10(glval) = FunctionAddress[~Base] : -# 778| v0_11(void) = Call : func:r0_10, this:r0_9 -# 778| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 -# 777| v0_13(void) = ReturnVoid : -# 777| v0_14(void) = UnmodeledUse : mu* -# 777| v0_15(void) = ExitFunction : +# 777| v0_0(void) = EnterFunction : +# 777| mu0_1(unknown) = AliasedDefinition : +# 777| mu0_2(unknown) = UnmodeledDefinition : +# 777| r0_3(glval) = InitializeThis : +# 778| v0_4(void) = NoOp : +# 778| r0_5(glval) = FieldAddress[middlevb1_s] : r0_3 +# 778| r0_6(glval) = FunctionAddress[~String] : +# 778| v0_7(void) = Call : func:r0_6, this:r0_5 +# 778| mu0_8(unknown) = ^CallSideEffect : ~mu0_2 +# 778| r0_9(glval) = ConvertToNonVirtualBase[MiddleVB1 : Base] : r0_3 +# 778| r0_10(glval) = FunctionAddress[~Base] : +# 778| v0_11(void) = Call : func:r0_10, this:r0_9 +# 778| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 +# 777| v0_13(void) = ReturnVoid : +# 777| v0_14(void) = UnmodeledUse : mu* +# 777| v0_15(void) = AliasedUse : ~mu0_2 +# 777| v0_16(void) = ExitFunction : # 784| void MiddleVB2::MiddleVB2() # 784| Block 0 -# 784| v0_0(void) = EnterFunction : -# 784| mu0_1(unknown) = AliasedDefinition : -# 784| mu0_2(unknown) = UnmodeledDefinition : -# 784| r0_3(glval) = InitializeThis : -# 784| r0_4(glval) = ConvertToBase[MiddleVB2 : Base] : r0_3 -# 784| r0_5(glval) = FunctionAddress[Base] : -# 784| v0_6(void) = Call : func:r0_5, this:r0_4 -# 784| mu0_7(unknown) = ^CallSideEffect : ~mu0_2 -# 784| r0_8(glval) = FieldAddress[middlevb2_s] : r0_3 -# 784| r0_9(glval) = FunctionAddress[String] : -# 784| v0_10(void) = Call : func:r0_9, this:r0_8 -# 784| mu0_11(unknown) = ^CallSideEffect : ~mu0_2 -# 785| v0_12(void) = NoOp : -# 784| v0_13(void) = ReturnVoid : -# 784| v0_14(void) = UnmodeledUse : mu* -# 784| v0_15(void) = ExitFunction : +# 784| v0_0(void) = EnterFunction : +# 784| mu0_1(unknown) = AliasedDefinition : +# 784| mu0_2(unknown) = UnmodeledDefinition : +# 784| r0_3(glval) = InitializeThis : +# 784| r0_4(glval) = ConvertToNonVirtualBase[MiddleVB2 : Base] : r0_3 +# 784| r0_5(glval) = FunctionAddress[Base] : +# 784| v0_6(void) = Call : func:r0_5, this:r0_4 +# 784| mu0_7(unknown) = ^CallSideEffect : ~mu0_2 +# 784| mu0_8(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_4 +# 784| r0_9(glval) = FieldAddress[middlevb2_s] : r0_3 +# 784| r0_10(glval) = FunctionAddress[String] : +# 784| v0_11(void) = Call : func:r0_10, this:r0_9 +# 784| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 +# 784| mu0_13(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_9 +# 785| v0_14(void) = NoOp : +# 784| v0_15(void) = ReturnVoid : +# 784| v0_16(void) = UnmodeledUse : mu* +# 784| v0_17(void) = AliasedUse : ~mu0_2 +# 784| v0_18(void) = ExitFunction : # 786| void MiddleVB2::~MiddleVB2() # 786| Block 0 -# 786| v0_0(void) = EnterFunction : -# 786| mu0_1(unknown) = AliasedDefinition : -# 786| mu0_2(unknown) = UnmodeledDefinition : -# 786| r0_3(glval) = InitializeThis : -# 787| v0_4(void) = NoOp : -# 787| r0_5(glval) = FieldAddress[middlevb2_s] : r0_3 -# 787| r0_6(glval) = FunctionAddress[~String] : -# 787| v0_7(void) = Call : func:r0_6, this:r0_5 -# 787| mu0_8(unknown) = ^CallSideEffect : ~mu0_2 -# 787| r0_9(glval) = ConvertToBase[MiddleVB2 : Base] : r0_3 -# 787| r0_10(glval) = FunctionAddress[~Base] : -# 787| v0_11(void) = Call : func:r0_10, this:r0_9 -# 787| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 -# 786| v0_13(void) = ReturnVoid : -# 786| v0_14(void) = UnmodeledUse : mu* -# 786| v0_15(void) = ExitFunction : +# 786| v0_0(void) = EnterFunction : +# 786| mu0_1(unknown) = AliasedDefinition : +# 786| mu0_2(unknown) = UnmodeledDefinition : +# 786| r0_3(glval) = InitializeThis : +# 787| v0_4(void) = NoOp : +# 787| r0_5(glval) = FieldAddress[middlevb2_s] : r0_3 +# 787| r0_6(glval) = FunctionAddress[~String] : +# 787| v0_7(void) = Call : func:r0_6, this:r0_5 +# 787| mu0_8(unknown) = ^CallSideEffect : ~mu0_2 +# 787| r0_9(glval) = ConvertToNonVirtualBase[MiddleVB2 : Base] : r0_3 +# 787| r0_10(glval) = FunctionAddress[~Base] : +# 787| v0_11(void) = Call : func:r0_10, this:r0_9 +# 787| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 +# 786| v0_13(void) = ReturnVoid : +# 786| v0_14(void) = UnmodeledUse : mu* +# 786| v0_15(void) = AliasedUse : ~mu0_2 +# 786| v0_16(void) = ExitFunction : # 793| void DerivedVB::DerivedVB() # 793| Block 0 -# 793| v0_0(void) = EnterFunction : -# 793| mu0_1(unknown) = AliasedDefinition : -# 793| mu0_2(unknown) = UnmodeledDefinition : -# 793| r0_3(glval) = InitializeThis : -# 793| r0_4(glval) = ConvertToBase[DerivedVB : Base] : r0_3 -# 793| r0_5(glval) = FunctionAddress[Base] : -# 793| v0_6(void) = Call : func:r0_5, this:r0_4 -# 793| mu0_7(unknown) = ^CallSideEffect : ~mu0_2 -# 793| r0_8(glval) = ConvertToBase[DerivedVB : MiddleVB1] : r0_3 -# 793| r0_9(glval) = FunctionAddress[MiddleVB1] : -# 793| v0_10(void) = Call : func:r0_9, this:r0_8 -# 793| mu0_11(unknown) = ^CallSideEffect : ~mu0_2 -# 793| r0_12(glval) = ConvertToBase[DerivedVB : MiddleVB2] : r0_3 -# 793| r0_13(glval) = FunctionAddress[MiddleVB2] : -# 793| v0_14(void) = Call : func:r0_13, this:r0_12 -# 793| mu0_15(unknown) = ^CallSideEffect : ~mu0_2 -# 793| r0_16(glval) = FieldAddress[derivedvb_s] : r0_3 -# 793| r0_17(glval) = FunctionAddress[String] : -# 793| v0_18(void) = Call : func:r0_17, this:r0_16 -# 793| mu0_19(unknown) = ^CallSideEffect : ~mu0_2 -# 794| v0_20(void) = NoOp : -# 793| v0_21(void) = ReturnVoid : -# 793| v0_22(void) = UnmodeledUse : mu* -# 793| v0_23(void) = ExitFunction : +# 793| v0_0(void) = EnterFunction : +# 793| mu0_1(unknown) = AliasedDefinition : +# 793| mu0_2(unknown) = UnmodeledDefinition : +# 793| r0_3(glval) = InitializeThis : +# 793| r0_4(glval) = ConvertToNonVirtualBase[DerivedVB : Base] : r0_3 +# 793| r0_5(glval) = FunctionAddress[Base] : +# 793| v0_6(void) = Call : func:r0_5, this:r0_4 +# 793| mu0_7(unknown) = ^CallSideEffect : ~mu0_2 +# 793| mu0_8(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_4 +# 793| r0_9(glval) = ConvertToNonVirtualBase[DerivedVB : MiddleVB1] : r0_3 +# 793| r0_10(glval) = FunctionAddress[MiddleVB1] : +# 793| v0_11(void) = Call : func:r0_10, this:r0_9 +# 793| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 +# 793| mu0_13(MiddleVB1) = ^IndirectMayWriteSideEffect[-1] : &:r0_9 +# 793| r0_14(glval) = ConvertToNonVirtualBase[DerivedVB : MiddleVB2] : r0_3 +# 793| r0_15(glval) = FunctionAddress[MiddleVB2] : +# 793| v0_16(void) = Call : func:r0_15, this:r0_14 +# 793| mu0_17(unknown) = ^CallSideEffect : ~mu0_2 +# 793| mu0_18(MiddleVB2) = ^IndirectMayWriteSideEffect[-1] : &:r0_14 +# 793| r0_19(glval) = FieldAddress[derivedvb_s] : r0_3 +# 793| r0_20(glval) = FunctionAddress[String] : +# 793| v0_21(void) = Call : func:r0_20, this:r0_19 +# 793| mu0_22(unknown) = ^CallSideEffect : ~mu0_2 +# 793| mu0_23(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_19 +# 794| v0_24(void) = NoOp : +# 793| v0_25(void) = ReturnVoid : +# 793| v0_26(void) = UnmodeledUse : mu* +# 793| v0_27(void) = AliasedUse : ~mu0_2 +# 793| v0_28(void) = ExitFunction : # 795| void DerivedVB::~DerivedVB() # 795| Block 0 -# 795| v0_0(void) = EnterFunction : -# 795| mu0_1(unknown) = AliasedDefinition : -# 795| mu0_2(unknown) = UnmodeledDefinition : -# 795| r0_3(glval) = InitializeThis : -# 796| v0_4(void) = NoOp : -# 796| r0_5(glval) = FieldAddress[derivedvb_s] : r0_3 -# 796| r0_6(glval) = FunctionAddress[~String] : -# 796| v0_7(void) = Call : func:r0_6, this:r0_5 -# 796| mu0_8(unknown) = ^CallSideEffect : ~mu0_2 -# 796| r0_9(glval) = ConvertToBase[DerivedVB : MiddleVB2] : r0_3 -# 796| r0_10(glval) = FunctionAddress[~MiddleVB2] : -# 796| v0_11(void) = Call : func:r0_10, this:r0_9 -# 796| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 -# 796| r0_13(glval) = ConvertToBase[DerivedVB : MiddleVB1] : r0_3 -# 796| r0_14(glval) = FunctionAddress[~MiddleVB1] : -# 796| v0_15(void) = Call : func:r0_14, this:r0_13 -# 796| mu0_16(unknown) = ^CallSideEffect : ~mu0_2 -# 796| r0_17(glval) = ConvertToBase[DerivedVB : Base] : r0_3 -# 796| r0_18(glval) = FunctionAddress[~Base] : -# 796| v0_19(void) = Call : func:r0_18, this:r0_17 -# 796| mu0_20(unknown) = ^CallSideEffect : ~mu0_2 -# 795| v0_21(void) = ReturnVoid : -# 795| v0_22(void) = UnmodeledUse : mu* -# 795| v0_23(void) = ExitFunction : +# 795| v0_0(void) = EnterFunction : +# 795| mu0_1(unknown) = AliasedDefinition : +# 795| mu0_2(unknown) = UnmodeledDefinition : +# 795| r0_3(glval) = InitializeThis : +# 796| v0_4(void) = NoOp : +# 796| r0_5(glval) = FieldAddress[derivedvb_s] : r0_3 +# 796| r0_6(glval) = FunctionAddress[~String] : +# 796| v0_7(void) = Call : func:r0_6, this:r0_5 +# 796| mu0_8(unknown) = ^CallSideEffect : ~mu0_2 +# 796| r0_9(glval) = ConvertToNonVirtualBase[DerivedVB : MiddleVB2] : r0_3 +# 796| r0_10(glval) = FunctionAddress[~MiddleVB2] : +# 796| v0_11(void) = Call : func:r0_10, this:r0_9 +# 796| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 +# 796| r0_13(glval) = ConvertToNonVirtualBase[DerivedVB : MiddleVB1] : r0_3 +# 796| r0_14(glval) = FunctionAddress[~MiddleVB1] : +# 796| v0_15(void) = Call : func:r0_14, this:r0_13 +# 796| mu0_16(unknown) = ^CallSideEffect : ~mu0_2 +# 796| r0_17(glval) = ConvertToNonVirtualBase[DerivedVB : Base] : r0_3 +# 796| r0_18(glval) = FunctionAddress[~Base] : +# 796| v0_19(void) = Call : func:r0_18, this:r0_17 +# 796| mu0_20(unknown) = ^CallSideEffect : ~mu0_2 +# 795| v0_21(void) = ReturnVoid : +# 795| v0_22(void) = UnmodeledUse : mu* +# 795| v0_23(void) = AliasedUse : ~mu0_2 +# 795| v0_24(void) = ExitFunction : # 799| void HierarchyConversions() # 799| Block 0 -# 799| v0_0(void) = EnterFunction : -# 799| mu0_1(unknown) = AliasedDefinition : -# 799| mu0_2(unknown) = UnmodeledDefinition : -# 800| r0_3(glval) = VariableAddress[b] : -# 800| r0_4(glval) = FunctionAddress[Base] : -# 800| v0_5(void) = Call : func:r0_4, this:r0_3 -# 800| mu0_6(unknown) = ^CallSideEffect : ~mu0_2 -# 801| r0_7(glval) = VariableAddress[m] : -# 801| r0_8(glval) = FunctionAddress[Middle] : -# 801| v0_9(void) = Call : func:r0_8, this:r0_7 -# 801| mu0_10(unknown) = ^CallSideEffect : ~mu0_2 -# 802| r0_11(glval) = VariableAddress[d] : -# 802| r0_12(glval) = FunctionAddress[Derived] : -# 802| v0_13(void) = Call : func:r0_12, this:r0_11 -# 802| mu0_14(unknown) = ^CallSideEffect : ~mu0_2 -# 804| r0_15(glval) = VariableAddress[pb] : -# 804| r0_16(glval) = VariableAddress[b] : -# 804| mu0_17(Base *) = Store : &:r0_15, r0_16 -# 805| r0_18(glval) = VariableAddress[pm] : -# 805| r0_19(glval) = VariableAddress[m] : -# 805| mu0_20(Middle *) = Store : &:r0_18, r0_19 -# 806| r0_21(glval) = VariableAddress[pd] : -# 806| r0_22(glval) = VariableAddress[d] : -# 806| mu0_23(Derived *) = Store : &:r0_21, r0_22 -# 808| r0_24(glval) = VariableAddress[b] : -# 808| r0_25(glval) = FunctionAddress[operator=] : -# 808| r0_26(glval) = VariableAddress[m] : -# 808| r0_27(glval) = ConvertToBase[Middle : Base] : r0_26 -# 808| r0_28(Base &) = Call : func:r0_25, this:r0_24, 0:r0_27 -# 808| mu0_29(unknown) = ^CallSideEffect : ~mu0_2 -# 808| v0_30(void) = ^IndirectReadSideEffect[-1] : &:r0_24, ~mu0_2 -# 808| v0_31(void) = ^IndirectReadSideEffect[0] : &:r0_27, ~mu0_2 -# 808| mu0_32(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_24 -# 808| mu0_33(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_27 -# 809| r0_34(glval) = VariableAddress[b] : -# 809| r0_35(glval) = FunctionAddress[operator=] : -# 809| r0_36(glval) = FunctionAddress[Base] : -# 809| r0_37(glval) = VariableAddress[m] : -# 809| r0_38(glval) = ConvertToBase[Middle : Base] : r0_37 -# 809| v0_39(void) = Call : func:r0_36, 0:r0_38 -# 809| mu0_40(unknown) = ^CallSideEffect : ~mu0_2 -# 809| v0_41(void) = ^IndirectReadSideEffect[0] : &:r0_38, ~mu0_2 -# 809| mu0_42(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_38 -# 809| r0_43(glval) = Convert : v0_39 -# 809| r0_44(Base &) = Call : func:r0_35, this:r0_34, 0:r0_43 -# 809| mu0_45(unknown) = ^CallSideEffect : ~mu0_2 -# 809| v0_46(void) = ^IndirectReadSideEffect[-1] : &:r0_34, ~mu0_2 -# 809| v0_47(void) = ^IndirectReadSideEffect[0] : &:r0_43, ~mu0_2 -# 809| mu0_48(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_34 -# 809| mu0_49(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_43 -# 810| r0_50(glval) = VariableAddress[b] : -# 810| r0_51(glval) = FunctionAddress[operator=] : -# 810| r0_52(glval) = FunctionAddress[Base] : -# 810| r0_53(glval) = VariableAddress[m] : -# 810| r0_54(glval) = ConvertToBase[Middle : Base] : r0_53 -# 810| v0_55(void) = Call : func:r0_52, 0:r0_54 -# 810| mu0_56(unknown) = ^CallSideEffect : ~mu0_2 -# 810| v0_57(void) = ^IndirectReadSideEffect[0] : &:r0_54, ~mu0_2 -# 810| mu0_58(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_54 -# 810| r0_59(glval) = Convert : v0_55 -# 810| r0_60(Base &) = Call : func:r0_51, this:r0_50, 0:r0_59 -# 810| mu0_61(unknown) = ^CallSideEffect : ~mu0_2 -# 810| v0_62(void) = ^IndirectReadSideEffect[-1] : &:r0_50, ~mu0_2 -# 810| v0_63(void) = ^IndirectReadSideEffect[0] : &:r0_59, ~mu0_2 -# 810| mu0_64(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_50 -# 810| mu0_65(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_59 -# 811| r0_66(glval) = VariableAddress[pm] : -# 811| r0_67(Middle *) = Load : &:r0_66, ~mu0_2 -# 811| r0_68(Base *) = ConvertToBase[Middle : Base] : r0_67 -# 811| r0_69(glval) = VariableAddress[pb] : -# 811| mu0_70(Base *) = Store : &:r0_69, r0_68 -# 812| r0_71(glval) = VariableAddress[pm] : -# 812| r0_72(Middle *) = Load : &:r0_71, ~mu0_2 -# 812| r0_73(Base *) = ConvertToBase[Middle : Base] : r0_72 -# 812| r0_74(glval) = VariableAddress[pb] : -# 812| mu0_75(Base *) = Store : &:r0_74, r0_73 -# 813| r0_76(glval) = VariableAddress[pm] : -# 813| r0_77(Middle *) = Load : &:r0_76, ~mu0_2 -# 813| r0_78(Base *) = ConvertToBase[Middle : Base] : r0_77 -# 813| r0_79(glval) = VariableAddress[pb] : -# 813| mu0_80(Base *) = Store : &:r0_79, r0_78 -# 814| r0_81(glval) = VariableAddress[pm] : -# 814| r0_82(Middle *) = Load : &:r0_81, ~mu0_2 -# 814| r0_83(Base *) = Convert : r0_82 -# 814| r0_84(glval) = VariableAddress[pb] : -# 814| mu0_85(Base *) = Store : &:r0_84, r0_83 -# 816| r0_86(glval) = VariableAddress[m] : -# 816| r0_87(glval) = FunctionAddress[operator=] : -# 816| r0_88(glval) = VariableAddress[b] : -# 816| r0_89(glval) = ConvertToDerived[Middle : Base] : r0_88 -# 816| r0_90(glval) = Convert : r0_89 -# 816| r0_91(Middle &) = Call : func:r0_87, this:r0_86, 0:r0_90 -# 816| mu0_92(unknown) = ^CallSideEffect : ~mu0_2 -# 816| v0_93(void) = ^IndirectReadSideEffect[-1] : &:r0_86, ~mu0_2 -# 816| v0_94(void) = ^IndirectReadSideEffect[0] : &:r0_90, ~mu0_2 -# 816| mu0_95(Middle) = ^IndirectMayWriteSideEffect[-1] : &:r0_86 -# 816| mu0_96(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_90 -# 817| r0_97(glval) = VariableAddress[m] : -# 817| r0_98(glval) = FunctionAddress[operator=] : -# 817| r0_99(glval) = VariableAddress[b] : -# 817| r0_100(glval) = ConvertToDerived[Middle : Base] : r0_99 -# 817| r0_101(glval) = Convert : r0_100 -# 817| r0_102(Middle &) = Call : func:r0_98, this:r0_97, 0:r0_101 -# 817| mu0_103(unknown) = ^CallSideEffect : ~mu0_2 -# 817| v0_104(void) = ^IndirectReadSideEffect[-1] : &:r0_97, ~mu0_2 -# 817| v0_105(void) = ^IndirectReadSideEffect[0] : &:r0_101, ~mu0_2 -# 817| mu0_106(Middle) = ^IndirectMayWriteSideEffect[-1] : &:r0_97 -# 817| mu0_107(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_101 -# 818| r0_108(glval) = VariableAddress[pb] : -# 818| r0_109(Base *) = Load : &:r0_108, ~mu0_2 -# 818| r0_110(Middle *) = ConvertToDerived[Middle : Base] : r0_109 -# 818| r0_111(glval) = VariableAddress[pm] : -# 818| mu0_112(Middle *) = Store : &:r0_111, r0_110 -# 819| r0_113(glval) = VariableAddress[pb] : -# 819| r0_114(Base *) = Load : &:r0_113, ~mu0_2 -# 819| r0_115(Middle *) = ConvertToDerived[Middle : Base] : r0_114 -# 819| r0_116(glval) = VariableAddress[pm] : -# 819| mu0_117(Middle *) = Store : &:r0_116, r0_115 -# 820| r0_118(glval) = VariableAddress[pb] : -# 820| r0_119(Base *) = Load : &:r0_118, ~mu0_2 -# 820| r0_120(Middle *) = Convert : r0_119 -# 820| r0_121(glval) = VariableAddress[pm] : -# 820| mu0_122(Middle *) = Store : &:r0_121, r0_120 -# 822| r0_123(glval) = VariableAddress[b] : -# 822| r0_124(glval) = FunctionAddress[operator=] : -# 822| r0_125(glval) = VariableAddress[d] : -# 822| r0_126(glval) = ConvertToBase[Derived : Middle] : r0_125 -# 822| r0_127(glval) = ConvertToBase[Middle : Base] : r0_126 -# 822| r0_128(Base &) = Call : func:r0_124, this:r0_123, 0:r0_127 -# 822| mu0_129(unknown) = ^CallSideEffect : ~mu0_2 -# 822| v0_130(void) = ^IndirectReadSideEffect[-1] : &:r0_123, ~mu0_2 -# 822| v0_131(void) = ^IndirectReadSideEffect[0] : &:r0_127, ~mu0_2 -# 822| mu0_132(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_123 -# 822| mu0_133(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_127 -# 823| r0_134(glval) = VariableAddress[b] : -# 823| r0_135(glval) = FunctionAddress[operator=] : -# 823| r0_136(glval) = FunctionAddress[Base] : -# 823| r0_137(glval) = VariableAddress[d] : -# 823| r0_138(glval) = ConvertToBase[Derived : Middle] : r0_137 -# 823| r0_139(glval) = ConvertToBase[Middle : Base] : r0_138 -# 823| v0_140(void) = Call : func:r0_136, 0:r0_139 -# 823| mu0_141(unknown) = ^CallSideEffect : ~mu0_2 -# 823| v0_142(void) = ^IndirectReadSideEffect[0] : &:r0_139, ~mu0_2 -# 823| mu0_143(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_139 -# 823| r0_144(glval) = Convert : v0_140 -# 823| r0_145(Base &) = Call : func:r0_135, this:r0_134, 0:r0_144 -# 823| mu0_146(unknown) = ^CallSideEffect : ~mu0_2 -# 823| v0_147(void) = ^IndirectReadSideEffect[-1] : &:r0_134, ~mu0_2 -# 823| v0_148(void) = ^IndirectReadSideEffect[0] : &:r0_144, ~mu0_2 -# 823| mu0_149(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_134 -# 823| mu0_150(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_144 -# 824| r0_151(glval) = VariableAddress[b] : -# 824| r0_152(glval) = FunctionAddress[operator=] : -# 824| r0_153(glval) = FunctionAddress[Base] : -# 824| r0_154(glval) = VariableAddress[d] : -# 824| r0_155(glval) = ConvertToBase[Derived : Middle] : r0_154 -# 824| r0_156(glval) = ConvertToBase[Middle : Base] : r0_155 -# 824| v0_157(void) = Call : func:r0_153, 0:r0_156 -# 824| mu0_158(unknown) = ^CallSideEffect : ~mu0_2 -# 824| v0_159(void) = ^IndirectReadSideEffect[0] : &:r0_156, ~mu0_2 -# 824| mu0_160(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_156 -# 824| r0_161(glval) = Convert : v0_157 -# 824| r0_162(Base &) = Call : func:r0_152, this:r0_151, 0:r0_161 -# 824| mu0_163(unknown) = ^CallSideEffect : ~mu0_2 -# 824| v0_164(void) = ^IndirectReadSideEffect[-1] : &:r0_151, ~mu0_2 -# 824| v0_165(void) = ^IndirectReadSideEffect[0] : &:r0_161, ~mu0_2 -# 824| mu0_166(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_151 -# 824| mu0_167(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_161 -# 825| r0_168(glval) = VariableAddress[pd] : -# 825| r0_169(Derived *) = Load : &:r0_168, ~mu0_2 -# 825| r0_170(Middle *) = ConvertToBase[Derived : Middle] : r0_169 -# 825| r0_171(Base *) = ConvertToBase[Middle : Base] : r0_170 -# 825| r0_172(glval) = VariableAddress[pb] : -# 825| mu0_173(Base *) = Store : &:r0_172, r0_171 -# 826| r0_174(glval) = VariableAddress[pd] : -# 826| r0_175(Derived *) = Load : &:r0_174, ~mu0_2 -# 826| r0_176(Middle *) = ConvertToBase[Derived : Middle] : r0_175 -# 826| r0_177(Base *) = ConvertToBase[Middle : Base] : r0_176 -# 826| r0_178(glval) = VariableAddress[pb] : -# 826| mu0_179(Base *) = Store : &:r0_178, r0_177 -# 827| r0_180(glval) = VariableAddress[pd] : -# 827| r0_181(Derived *) = Load : &:r0_180, ~mu0_2 -# 827| r0_182(Middle *) = ConvertToBase[Derived : Middle] : r0_181 -# 827| r0_183(Base *) = ConvertToBase[Middle : Base] : r0_182 -# 827| r0_184(glval) = VariableAddress[pb] : -# 827| mu0_185(Base *) = Store : &:r0_184, r0_183 -# 828| r0_186(glval) = VariableAddress[pd] : -# 828| r0_187(Derived *) = Load : &:r0_186, ~mu0_2 -# 828| r0_188(Base *) = Convert : r0_187 -# 828| r0_189(glval) = VariableAddress[pb] : -# 828| mu0_190(Base *) = Store : &:r0_189, r0_188 -# 830| r0_191(glval) = VariableAddress[d] : -# 830| r0_192(glval) = FunctionAddress[operator=] : -# 830| r0_193(glval) = VariableAddress[b] : -# 830| r0_194(glval) = ConvertToDerived[Middle : Base] : r0_193 -# 830| r0_195(glval) = ConvertToDerived[Derived : Middle] : r0_194 -# 830| r0_196(glval) = Convert : r0_195 -# 830| r0_197(Derived &) = Call : func:r0_192, this:r0_191, 0:r0_196 -# 830| mu0_198(unknown) = ^CallSideEffect : ~mu0_2 -# 830| v0_199(void) = ^IndirectReadSideEffect[-1] : &:r0_191, ~mu0_2 -# 830| v0_200(void) = ^IndirectReadSideEffect[0] : &:r0_196, ~mu0_2 -# 830| mu0_201(Derived) = ^IndirectMayWriteSideEffect[-1] : &:r0_191 -# 830| mu0_202(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_196 -# 831| r0_203(glval) = VariableAddress[d] : -# 831| r0_204(glval) = FunctionAddress[operator=] : -# 831| r0_205(glval) = VariableAddress[b] : -# 831| r0_206(glval) = ConvertToDerived[Middle : Base] : r0_205 -# 831| r0_207(glval) = ConvertToDerived[Derived : Middle] : r0_206 -# 831| r0_208(glval) = Convert : r0_207 -# 831| r0_209(Derived &) = Call : func:r0_204, this:r0_203, 0:r0_208 -# 831| mu0_210(unknown) = ^CallSideEffect : ~mu0_2 -# 831| v0_211(void) = ^IndirectReadSideEffect[-1] : &:r0_203, ~mu0_2 -# 831| v0_212(void) = ^IndirectReadSideEffect[0] : &:r0_208, ~mu0_2 -# 831| mu0_213(Derived) = ^IndirectMayWriteSideEffect[-1] : &:r0_203 -# 831| mu0_214(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_208 -# 832| r0_215(glval) = VariableAddress[pb] : -# 832| r0_216(Base *) = Load : &:r0_215, ~mu0_2 -# 832| r0_217(Middle *) = ConvertToDerived[Middle : Base] : r0_216 -# 832| r0_218(Derived *) = ConvertToDerived[Derived : Middle] : r0_217 -# 832| r0_219(glval) = VariableAddress[pd] : -# 832| mu0_220(Derived *) = Store : &:r0_219, r0_218 -# 833| r0_221(glval) = VariableAddress[pb] : -# 833| r0_222(Base *) = Load : &:r0_221, ~mu0_2 -# 833| r0_223(Middle *) = ConvertToDerived[Middle : Base] : r0_222 -# 833| r0_224(Derived *) = ConvertToDerived[Derived : Middle] : r0_223 -# 833| r0_225(glval) = VariableAddress[pd] : -# 833| mu0_226(Derived *) = Store : &:r0_225, r0_224 -# 834| r0_227(glval) = VariableAddress[pb] : -# 834| r0_228(Base *) = Load : &:r0_227, ~mu0_2 -# 834| r0_229(Derived *) = Convert : r0_228 -# 834| r0_230(glval) = VariableAddress[pd] : -# 834| mu0_231(Derived *) = Store : &:r0_230, r0_229 -# 836| r0_232(glval) = VariableAddress[pmv] : -# 836| r0_233(MiddleVB1 *) = Constant[0] : -# 836| mu0_234(MiddleVB1 *) = Store : &:r0_232, r0_233 -# 837| r0_235(glval) = VariableAddress[pdv] : -# 837| r0_236(DerivedVB *) = Constant[0] : -# 837| mu0_237(DerivedVB *) = Store : &:r0_235, r0_236 -# 838| r0_238(glval) = VariableAddress[pmv] : -# 838| r0_239(MiddleVB1 *) = Load : &:r0_238, ~mu0_2 -# 838| r0_240(Base *) = ConvertToVirtualBase[MiddleVB1 : Base] : r0_239 -# 838| r0_241(glval) = VariableAddress[pb] : -# 838| mu0_242(Base *) = Store : &:r0_241, r0_240 -# 839| r0_243(glval) = VariableAddress[pdv] : -# 839| r0_244(DerivedVB *) = Load : &:r0_243, ~mu0_2 -# 839| r0_245(Base *) = ConvertToVirtualBase[DerivedVB : Base] : r0_244 -# 839| r0_246(glval) = VariableAddress[pb] : -# 839| mu0_247(Base *) = Store : &:r0_246, r0_245 -# 840| v0_248(void) = NoOp : -# 799| v0_249(void) = ReturnVoid : -# 799| v0_250(void) = UnmodeledUse : mu* -# 799| v0_251(void) = ExitFunction : +# 799| v0_0(void) = EnterFunction : +# 799| mu0_1(unknown) = AliasedDefinition : +# 799| mu0_2(unknown) = UnmodeledDefinition : +# 800| r0_3(glval) = VariableAddress[b] : +# 800| mu0_4(Base) = Uninitialized[b] : &:r0_3 +# 800| r0_5(glval) = FunctionAddress[Base] : +# 800| v0_6(void) = Call : func:r0_5, this:r0_3 +# 800| mu0_7(unknown) = ^CallSideEffect : ~mu0_2 +# 800| mu0_8(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_3 +# 801| r0_9(glval) = VariableAddress[m] : +# 801| mu0_10(Middle) = Uninitialized[m] : &:r0_9 +# 801| r0_11(glval) = FunctionAddress[Middle] : +# 801| v0_12(void) = Call : func:r0_11, this:r0_9 +# 801| mu0_13(unknown) = ^CallSideEffect : ~mu0_2 +# 801| mu0_14(Middle) = ^IndirectMayWriteSideEffect[-1] : &:r0_9 +# 802| r0_15(glval) = VariableAddress[d] : +# 802| mu0_16(Derived) = Uninitialized[d] : &:r0_15 +# 802| r0_17(glval) = FunctionAddress[Derived] : +# 802| v0_18(void) = Call : func:r0_17, this:r0_15 +# 802| mu0_19(unknown) = ^CallSideEffect : ~mu0_2 +# 802| mu0_20(Derived) = ^IndirectMayWriteSideEffect[-1] : &:r0_15 +# 804| r0_21(glval) = VariableAddress[pb] : +# 804| r0_22(glval) = VariableAddress[b] : +# 804| r0_23(Base *) = CopyValue : r0_22 +# 804| mu0_24(Base *) = Store : &:r0_21, r0_23 +# 805| r0_25(glval) = VariableAddress[pm] : +# 805| r0_26(glval) = VariableAddress[m] : +# 805| r0_27(Middle *) = CopyValue : r0_26 +# 805| mu0_28(Middle *) = Store : &:r0_25, r0_27 +# 806| r0_29(glval) = VariableAddress[pd] : +# 806| r0_30(glval) = VariableAddress[d] : +# 806| r0_31(Derived *) = CopyValue : r0_30 +# 806| mu0_32(Derived *) = Store : &:r0_29, r0_31 +# 808| r0_33(glval) = VariableAddress[b] : +# 808| r0_34(glval) = FunctionAddress[operator=] : +# 808| r0_35(glval) = VariableAddress[m] : +# 808| r0_36(glval) = ConvertToNonVirtualBase[Middle : Base] : r0_35 +# 808| r0_37(Base &) = CopyValue : r0_36 +# 808| r0_38(Base &) = Call : func:r0_34, this:r0_33, 0:r0_37 +# 808| mu0_39(unknown) = ^CallSideEffect : ~mu0_2 +# 808| v0_40(void) = ^BufferReadSideEffect[-1] : &:r0_33, ~mu0_2 +# 808| v0_41(void) = ^BufferReadSideEffect[0] : &:r0_37, ~mu0_2 +# 808| mu0_42(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_33 +# 808| mu0_43(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_37 +# 808| r0_44(glval) = CopyValue : r0_38 +# 809| r0_45(glval) = VariableAddress[b] : +# 809| r0_46(glval) = FunctionAddress[operator=] : +# 809| r0_47(glval) = FunctionAddress[Base] : +# 809| r0_48(glval) = VariableAddress[m] : +# 809| r0_49(glval) = ConvertToNonVirtualBase[Middle : Base] : r0_48 +# 809| r0_50(Base &) = CopyValue : r0_49 +# 809| v0_51(void) = Call : func:r0_47, 0:r0_50 +# 809| mu0_52(unknown) = ^CallSideEffect : ~mu0_2 +# 809| mu0_53(Base) = ^IndirectMayWriteSideEffect[-1] : +# 809| v0_54(void) = ^BufferReadSideEffect[0] : &:r0_50, ~mu0_2 +# 809| mu0_55(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_50 +# 809| r0_56(glval) = Convert : v0_51 +# 809| r0_57(Base &) = CopyValue : r0_56 +# 809| r0_58(Base &) = Call : func:r0_46, this:r0_45, 0:r0_57 +# 809| mu0_59(unknown) = ^CallSideEffect : ~mu0_2 +# 809| v0_60(void) = ^BufferReadSideEffect[-1] : &:r0_45, ~mu0_2 +# 809| v0_61(void) = ^BufferReadSideEffect[0] : &:r0_57, ~mu0_2 +# 809| mu0_62(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_45 +# 809| mu0_63(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_57 +# 809| r0_64(glval) = CopyValue : r0_58 +# 810| r0_65(glval) = VariableAddress[b] : +# 810| r0_66(glval) = FunctionAddress[operator=] : +# 810| r0_67(glval) = FunctionAddress[Base] : +# 810| r0_68(glval) = VariableAddress[m] : +# 810| r0_69(glval) = ConvertToNonVirtualBase[Middle : Base] : r0_68 +# 810| r0_70(Base &) = CopyValue : r0_69 +# 810| v0_71(void) = Call : func:r0_67, 0:r0_70 +# 810| mu0_72(unknown) = ^CallSideEffect : ~mu0_2 +# 810| mu0_73(Base) = ^IndirectMayWriteSideEffect[-1] : +# 810| v0_74(void) = ^BufferReadSideEffect[0] : &:r0_70, ~mu0_2 +# 810| mu0_75(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_70 +# 810| r0_76(glval) = Convert : v0_71 +# 810| r0_77(Base &) = CopyValue : r0_76 +# 810| r0_78(Base &) = Call : func:r0_66, this:r0_65, 0:r0_77 +# 810| mu0_79(unknown) = ^CallSideEffect : ~mu0_2 +# 810| v0_80(void) = ^BufferReadSideEffect[-1] : &:r0_65, ~mu0_2 +# 810| v0_81(void) = ^BufferReadSideEffect[0] : &:r0_77, ~mu0_2 +# 810| mu0_82(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_65 +# 810| mu0_83(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_77 +# 810| r0_84(glval) = CopyValue : r0_78 +# 811| r0_85(glval) = VariableAddress[pm] : +# 811| r0_86(Middle *) = Load : &:r0_85, ~mu0_2 +# 811| r0_87(Base *) = ConvertToNonVirtualBase[Middle : Base] : r0_86 +# 811| r0_88(glval) = VariableAddress[pb] : +# 811| mu0_89(Base *) = Store : &:r0_88, r0_87 +# 812| r0_90(glval) = VariableAddress[pm] : +# 812| r0_91(Middle *) = Load : &:r0_90, ~mu0_2 +# 812| r0_92(Base *) = ConvertToNonVirtualBase[Middle : Base] : r0_91 +# 812| r0_93(glval) = VariableAddress[pb] : +# 812| mu0_94(Base *) = Store : &:r0_93, r0_92 +# 813| r0_95(glval) = VariableAddress[pm] : +# 813| r0_96(Middle *) = Load : &:r0_95, ~mu0_2 +# 813| r0_97(Base *) = ConvertToNonVirtualBase[Middle : Base] : r0_96 +# 813| r0_98(glval) = VariableAddress[pb] : +# 813| mu0_99(Base *) = Store : &:r0_98, r0_97 +# 814| r0_100(glval) = VariableAddress[pm] : +# 814| r0_101(Middle *) = Load : &:r0_100, ~mu0_2 +# 814| r0_102(Base *) = Convert : r0_101 +# 814| r0_103(glval) = VariableAddress[pb] : +# 814| mu0_104(Base *) = Store : &:r0_103, r0_102 +# 816| r0_105(glval) = VariableAddress[m] : +# 816| r0_106(glval) = FunctionAddress[operator=] : +# 816| r0_107(glval) = VariableAddress[b] : +# 816| r0_108(glval) = ConvertToDerived[Middle : Base] : r0_107 +# 816| r0_109(glval) = Convert : r0_108 +# 816| r0_110(Middle &) = CopyValue : r0_109 +# 816| r0_111(Middle &) = Call : func:r0_106, this:r0_105, 0:r0_110 +# 816| mu0_112(unknown) = ^CallSideEffect : ~mu0_2 +# 816| v0_113(void) = ^BufferReadSideEffect[-1] : &:r0_105, ~mu0_2 +# 816| v0_114(void) = ^BufferReadSideEffect[0] : &:r0_110, ~mu0_2 +# 816| mu0_115(Middle) = ^IndirectMayWriteSideEffect[-1] : &:r0_105 +# 816| mu0_116(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_110 +# 816| r0_117(glval) = CopyValue : r0_111 +# 817| r0_118(glval) = VariableAddress[m] : +# 817| r0_119(glval) = FunctionAddress[operator=] : +# 817| r0_120(glval) = VariableAddress[b] : +# 817| r0_121(glval) = ConvertToDerived[Middle : Base] : r0_120 +# 817| r0_122(glval) = Convert : r0_121 +# 817| r0_123(Middle &) = CopyValue : r0_122 +# 817| r0_124(Middle &) = Call : func:r0_119, this:r0_118, 0:r0_123 +# 817| mu0_125(unknown) = ^CallSideEffect : ~mu0_2 +# 817| v0_126(void) = ^BufferReadSideEffect[-1] : &:r0_118, ~mu0_2 +# 817| v0_127(void) = ^BufferReadSideEffect[0] : &:r0_123, ~mu0_2 +# 817| mu0_128(Middle) = ^IndirectMayWriteSideEffect[-1] : &:r0_118 +# 817| mu0_129(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_123 +# 817| r0_130(glval) = CopyValue : r0_124 +# 818| r0_131(glval) = VariableAddress[pb] : +# 818| r0_132(Base *) = Load : &:r0_131, ~mu0_2 +# 818| r0_133(Middle *) = ConvertToDerived[Middle : Base] : r0_132 +# 818| r0_134(glval) = VariableAddress[pm] : +# 818| mu0_135(Middle *) = Store : &:r0_134, r0_133 +# 819| r0_136(glval) = VariableAddress[pb] : +# 819| r0_137(Base *) = Load : &:r0_136, ~mu0_2 +# 819| r0_138(Middle *) = ConvertToDerived[Middle : Base] : r0_137 +# 819| r0_139(glval) = VariableAddress[pm] : +# 819| mu0_140(Middle *) = Store : &:r0_139, r0_138 +# 820| r0_141(glval) = VariableAddress[pb] : +# 820| r0_142(Base *) = Load : &:r0_141, ~mu0_2 +# 820| r0_143(Middle *) = Convert : r0_142 +# 820| r0_144(glval) = VariableAddress[pm] : +# 820| mu0_145(Middle *) = Store : &:r0_144, r0_143 +# 822| r0_146(glval) = VariableAddress[b] : +# 822| r0_147(glval) = FunctionAddress[operator=] : +# 822| r0_148(glval) = VariableAddress[d] : +# 822| r0_149(glval) = ConvertToNonVirtualBase[Derived : Middle] : r0_148 +# 822| r0_150(glval) = ConvertToNonVirtualBase[Middle : Base] : r0_149 +# 822| r0_151(Base &) = CopyValue : r0_150 +# 822| r0_152(Base &) = Call : func:r0_147, this:r0_146, 0:r0_151 +# 822| mu0_153(unknown) = ^CallSideEffect : ~mu0_2 +# 822| v0_154(void) = ^BufferReadSideEffect[-1] : &:r0_146, ~mu0_2 +# 822| v0_155(void) = ^BufferReadSideEffect[0] : &:r0_151, ~mu0_2 +# 822| mu0_156(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_146 +# 822| mu0_157(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_151 +# 822| r0_158(glval) = CopyValue : r0_152 +# 823| r0_159(glval) = VariableAddress[b] : +# 823| r0_160(glval) = FunctionAddress[operator=] : +# 823| r0_161(glval) = FunctionAddress[Base] : +# 823| r0_162(glval) = VariableAddress[d] : +# 823| r0_163(glval) = ConvertToNonVirtualBase[Derived : Middle] : r0_162 +# 823| r0_164(glval) = ConvertToNonVirtualBase[Middle : Base] : r0_163 +# 823| r0_165(Base &) = CopyValue : r0_164 +# 823| v0_166(void) = Call : func:r0_161, 0:r0_165 +# 823| mu0_167(unknown) = ^CallSideEffect : ~mu0_2 +# 823| mu0_168(Base) = ^IndirectMayWriteSideEffect[-1] : +# 823| v0_169(void) = ^BufferReadSideEffect[0] : &:r0_165, ~mu0_2 +# 823| mu0_170(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_165 +# 823| r0_171(glval) = Convert : v0_166 +# 823| r0_172(Base &) = CopyValue : r0_171 +# 823| r0_173(Base &) = Call : func:r0_160, this:r0_159, 0:r0_172 +# 823| mu0_174(unknown) = ^CallSideEffect : ~mu0_2 +# 823| v0_175(void) = ^BufferReadSideEffect[-1] : &:r0_159, ~mu0_2 +# 823| v0_176(void) = ^BufferReadSideEffect[0] : &:r0_172, ~mu0_2 +# 823| mu0_177(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_159 +# 823| mu0_178(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_172 +# 823| r0_179(glval) = CopyValue : r0_173 +# 824| r0_180(glval) = VariableAddress[b] : +# 824| r0_181(glval) = FunctionAddress[operator=] : +# 824| r0_182(glval) = FunctionAddress[Base] : +# 824| r0_183(glval) = VariableAddress[d] : +# 824| r0_184(glval) = ConvertToNonVirtualBase[Derived : Middle] : r0_183 +# 824| r0_185(glval) = ConvertToNonVirtualBase[Middle : Base] : r0_184 +# 824| r0_186(Base &) = CopyValue : r0_185 +# 824| v0_187(void) = Call : func:r0_182, 0:r0_186 +# 824| mu0_188(unknown) = ^CallSideEffect : ~mu0_2 +# 824| mu0_189(Base) = ^IndirectMayWriteSideEffect[-1] : +# 824| v0_190(void) = ^BufferReadSideEffect[0] : &:r0_186, ~mu0_2 +# 824| mu0_191(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_186 +# 824| r0_192(glval) = Convert : v0_187 +# 824| r0_193(Base &) = CopyValue : r0_192 +# 824| r0_194(Base &) = Call : func:r0_181, this:r0_180, 0:r0_193 +# 824| mu0_195(unknown) = ^CallSideEffect : ~mu0_2 +# 824| v0_196(void) = ^BufferReadSideEffect[-1] : &:r0_180, ~mu0_2 +# 824| v0_197(void) = ^BufferReadSideEffect[0] : &:r0_193, ~mu0_2 +# 824| mu0_198(Base) = ^IndirectMayWriteSideEffect[-1] : &:r0_180 +# 824| mu0_199(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_193 +# 824| r0_200(glval) = CopyValue : r0_194 +# 825| r0_201(glval) = VariableAddress[pd] : +# 825| r0_202(Derived *) = Load : &:r0_201, ~mu0_2 +# 825| r0_203(Middle *) = ConvertToNonVirtualBase[Derived : Middle] : r0_202 +# 825| r0_204(Base *) = ConvertToNonVirtualBase[Middle : Base] : r0_203 +# 825| r0_205(glval) = VariableAddress[pb] : +# 825| mu0_206(Base *) = Store : &:r0_205, r0_204 +# 826| r0_207(glval) = VariableAddress[pd] : +# 826| r0_208(Derived *) = Load : &:r0_207, ~mu0_2 +# 826| r0_209(Middle *) = ConvertToNonVirtualBase[Derived : Middle] : r0_208 +# 826| r0_210(Base *) = ConvertToNonVirtualBase[Middle : Base] : r0_209 +# 826| r0_211(glval) = VariableAddress[pb] : +# 826| mu0_212(Base *) = Store : &:r0_211, r0_210 +# 827| r0_213(glval) = VariableAddress[pd] : +# 827| r0_214(Derived *) = Load : &:r0_213, ~mu0_2 +# 827| r0_215(Middle *) = ConvertToNonVirtualBase[Derived : Middle] : r0_214 +# 827| r0_216(Base *) = ConvertToNonVirtualBase[Middle : Base] : r0_215 +# 827| r0_217(glval) = VariableAddress[pb] : +# 827| mu0_218(Base *) = Store : &:r0_217, r0_216 +# 828| r0_219(glval) = VariableAddress[pd] : +# 828| r0_220(Derived *) = Load : &:r0_219, ~mu0_2 +# 828| r0_221(Base *) = Convert : r0_220 +# 828| r0_222(glval) = VariableAddress[pb] : +# 828| mu0_223(Base *) = Store : &:r0_222, r0_221 +# 830| r0_224(glval) = VariableAddress[d] : +# 830| r0_225(glval) = FunctionAddress[operator=] : +# 830| r0_226(glval) = VariableAddress[b] : +# 830| r0_227(glval) = ConvertToDerived[Middle : Base] : r0_226 +# 830| r0_228(glval) = ConvertToDerived[Derived : Middle] : r0_227 +# 830| r0_229(glval) = Convert : r0_228 +# 830| r0_230(Derived &) = CopyValue : r0_229 +# 830| r0_231(Derived &) = Call : func:r0_225, this:r0_224, 0:r0_230 +# 830| mu0_232(unknown) = ^CallSideEffect : ~mu0_2 +# 830| v0_233(void) = ^BufferReadSideEffect[-1] : &:r0_224, ~mu0_2 +# 830| v0_234(void) = ^BufferReadSideEffect[0] : &:r0_230, ~mu0_2 +# 830| mu0_235(Derived) = ^IndirectMayWriteSideEffect[-1] : &:r0_224 +# 830| mu0_236(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_230 +# 830| r0_237(glval) = CopyValue : r0_231 +# 831| r0_238(glval) = VariableAddress[d] : +# 831| r0_239(glval) = FunctionAddress[operator=] : +# 831| r0_240(glval) = VariableAddress[b] : +# 831| r0_241(glval) = ConvertToDerived[Middle : Base] : r0_240 +# 831| r0_242(glval) = ConvertToDerived[Derived : Middle] : r0_241 +# 831| r0_243(glval) = Convert : r0_242 +# 831| r0_244(Derived &) = CopyValue : r0_243 +# 831| r0_245(Derived &) = Call : func:r0_239, this:r0_238, 0:r0_244 +# 831| mu0_246(unknown) = ^CallSideEffect : ~mu0_2 +# 831| v0_247(void) = ^BufferReadSideEffect[-1] : &:r0_238, ~mu0_2 +# 831| v0_248(void) = ^BufferReadSideEffect[0] : &:r0_244, ~mu0_2 +# 831| mu0_249(Derived) = ^IndirectMayWriteSideEffect[-1] : &:r0_238 +# 831| mu0_250(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_244 +# 831| r0_251(glval) = CopyValue : r0_245 +# 832| r0_252(glval) = VariableAddress[pb] : +# 832| r0_253(Base *) = Load : &:r0_252, ~mu0_2 +# 832| r0_254(Middle *) = ConvertToDerived[Middle : Base] : r0_253 +# 832| r0_255(Derived *) = ConvertToDerived[Derived : Middle] : r0_254 +# 832| r0_256(glval) = VariableAddress[pd] : +# 832| mu0_257(Derived *) = Store : &:r0_256, r0_255 +# 833| r0_258(glval) = VariableAddress[pb] : +# 833| r0_259(Base *) = Load : &:r0_258, ~mu0_2 +# 833| r0_260(Middle *) = ConvertToDerived[Middle : Base] : r0_259 +# 833| r0_261(Derived *) = ConvertToDerived[Derived : Middle] : r0_260 +# 833| r0_262(glval) = VariableAddress[pd] : +# 833| mu0_263(Derived *) = Store : &:r0_262, r0_261 +# 834| r0_264(glval) = VariableAddress[pb] : +# 834| r0_265(Base *) = Load : &:r0_264, ~mu0_2 +# 834| r0_266(Derived *) = Convert : r0_265 +# 834| r0_267(glval) = VariableAddress[pd] : +# 834| mu0_268(Derived *) = Store : &:r0_267, r0_266 +# 836| r0_269(glval) = VariableAddress[pmv] : +# 836| r0_270(MiddleVB1 *) = Constant[0] : +# 836| mu0_271(MiddleVB1 *) = Store : &:r0_269, r0_270 +# 837| r0_272(glval) = VariableAddress[pdv] : +# 837| r0_273(DerivedVB *) = Constant[0] : +# 837| mu0_274(DerivedVB *) = Store : &:r0_272, r0_273 +# 838| r0_275(glval) = VariableAddress[pmv] : +# 838| r0_276(MiddleVB1 *) = Load : &:r0_275, ~mu0_2 +# 838| r0_277(Base *) = ConvertToVirtualBase[MiddleVB1 : Base] : r0_276 +# 838| r0_278(glval) = VariableAddress[pb] : +# 838| mu0_279(Base *) = Store : &:r0_278, r0_277 +# 839| r0_280(glval) = VariableAddress[pdv] : +# 839| r0_281(DerivedVB *) = Load : &:r0_280, ~mu0_2 +# 839| r0_282(Base *) = ConvertToVirtualBase[DerivedVB : Base] : r0_281 +# 839| r0_283(glval) = VariableAddress[pb] : +# 839| mu0_284(Base *) = Store : &:r0_283, r0_282 +# 840| v0_285(void) = NoOp : +# 799| v0_286(void) = ReturnVoid : +# 799| v0_287(void) = UnmodeledUse : mu* +# 799| v0_288(void) = AliasedUse : ~mu0_2 +# 799| v0_289(void) = ExitFunction : # 842| void PolymorphicBase::PolymorphicBase() # 842| Block 0 @@ -3949,37 +4171,41 @@ ir.cpp: # 842| v0_4(void) = NoOp : # 842| v0_5(void) = ReturnVoid : # 842| v0_6(void) = UnmodeledUse : mu* -# 842| v0_7(void) = ExitFunction : +# 842| v0_7(void) = AliasedUse : ~mu0_2 +# 842| v0_8(void) = ExitFunction : # 846| void PolymorphicDerived::PolymorphicDerived() # 846| Block 0 -# 846| v0_0(void) = EnterFunction : -# 846| mu0_1(unknown) = AliasedDefinition : -# 846| mu0_2(unknown) = UnmodeledDefinition : -# 846| r0_3(glval) = InitializeThis : -# 846| r0_4(glval) = ConvertToBase[PolymorphicDerived : PolymorphicBase] : r0_3 -# 846| r0_5(glval) = FunctionAddress[PolymorphicBase] : -# 846| v0_6(void) = Call : func:r0_5, this:r0_4 -# 846| mu0_7(unknown) = ^CallSideEffect : ~mu0_2 -# 846| v0_8(void) = NoOp : -# 846| v0_9(void) = ReturnVoid : -# 846| v0_10(void) = UnmodeledUse : mu* -# 846| v0_11(void) = ExitFunction : +# 846| v0_0(void) = EnterFunction : +# 846| mu0_1(unknown) = AliasedDefinition : +# 846| mu0_2(unknown) = UnmodeledDefinition : +# 846| r0_3(glval) = InitializeThis : +# 846| r0_4(glval) = ConvertToNonVirtualBase[PolymorphicDerived : PolymorphicBase] : r0_3 +# 846| r0_5(glval) = FunctionAddress[PolymorphicBase] : +# 846| v0_6(void) = Call : func:r0_5, this:r0_4 +# 846| mu0_7(unknown) = ^CallSideEffect : ~mu0_2 +# 846| mu0_8(PolymorphicBase) = ^IndirectMayWriteSideEffect[-1] : &:r0_4 +# 846| v0_9(void) = NoOp : +# 846| v0_10(void) = ReturnVoid : +# 846| v0_11(void) = UnmodeledUse : mu* +# 846| v0_12(void) = AliasedUse : ~mu0_2 +# 846| v0_13(void) = ExitFunction : # 846| void PolymorphicDerived::~PolymorphicDerived() # 846| Block 0 -# 846| v0_0(void) = EnterFunction : -# 846| mu0_1(unknown) = AliasedDefinition : -# 846| mu0_2(unknown) = UnmodeledDefinition : -# 846| r0_3(glval) = InitializeThis : -#-----| v0_4(void) = NoOp : -# 846| r0_5(glval) = ConvertToBase[PolymorphicDerived : PolymorphicBase] : r0_3 -# 846| r0_6(glval) = FunctionAddress[~PolymorphicBase] : -# 846| v0_7(void) = Call : func:r0_6, this:r0_5 -# 846| mu0_8(unknown) = ^CallSideEffect : ~mu0_2 -# 846| v0_9(void) = ReturnVoid : -# 846| v0_10(void) = UnmodeledUse : mu* -# 846| v0_11(void) = ExitFunction : +# 846| v0_0(void) = EnterFunction : +# 846| mu0_1(unknown) = AliasedDefinition : +# 846| mu0_2(unknown) = UnmodeledDefinition : +# 846| r0_3(glval) = InitializeThis : +#-----| v0_4(void) = NoOp : +# 846| r0_5(glval) = ConvertToNonVirtualBase[PolymorphicDerived : PolymorphicBase] : r0_3 +# 846| r0_6(glval) = FunctionAddress[~PolymorphicBase] : +# 846| v0_7(void) = Call : func:r0_6, this:r0_5 +# 846| mu0_8(unknown) = ^CallSideEffect : ~mu0_2 +# 846| v0_9(void) = ReturnVoid : +# 846| v0_10(void) = UnmodeledUse : mu* +# 846| v0_11(void) = AliasedUse : ~mu0_2 +# 846| v0_12(void) = ExitFunction : # 849| void DynamicCast() # 849| Block 0 @@ -3987,69 +4213,80 @@ ir.cpp: # 849| mu0_1(unknown) = AliasedDefinition : # 849| mu0_2(unknown) = UnmodeledDefinition : # 850| r0_3(glval) = VariableAddress[b] : -#-----| r0_4(glval) = FunctionAddress[PolymorphicBase] : -#-----| v0_5(void) = Call : func:r0_4, this:r0_3 -#-----| mu0_6(unknown) = ^CallSideEffect : ~mu0_2 -# 851| r0_7(glval) = VariableAddress[d] : -# 851| r0_8(glval) = FunctionAddress[PolymorphicDerived] : -# 851| v0_9(void) = Call : func:r0_8, this:r0_7 -# 851| mu0_10(unknown) = ^CallSideEffect : ~mu0_2 -# 853| r0_11(glval) = VariableAddress[pb] : -# 853| r0_12(glval) = VariableAddress[b] : -# 853| mu0_13(PolymorphicBase *) = Store : &:r0_11, r0_12 -# 854| r0_14(glval) = VariableAddress[pd] : -# 854| r0_15(glval) = VariableAddress[d] : -# 854| mu0_16(PolymorphicDerived *) = Store : &:r0_14, r0_15 -# 857| r0_17(glval) = VariableAddress[pd] : -# 857| r0_18(PolymorphicDerived *) = Load : &:r0_17, ~mu0_2 -# 857| r0_19(PolymorphicBase *) = CheckedConvertOrNull : r0_18 -# 857| r0_20(glval) = VariableAddress[pb] : -# 857| mu0_21(PolymorphicBase *) = Store : &:r0_20, r0_19 -# 858| r0_22(glval) = VariableAddress[rb] : -# 858| r0_23(glval) = VariableAddress[d] : -# 858| r0_24(glval) = CheckedConvertOrThrow : r0_23 -# 858| mu0_25(PolymorphicBase &) = Store : &:r0_22, r0_24 -# 860| r0_26(glval) = VariableAddress[pb] : -# 860| r0_27(PolymorphicBase *) = Load : &:r0_26, ~mu0_2 -# 860| r0_28(PolymorphicDerived *) = CheckedConvertOrNull : r0_27 -# 860| r0_29(glval) = VariableAddress[pd] : -# 860| mu0_30(PolymorphicDerived *) = Store : &:r0_29, r0_28 -# 861| r0_31(glval) = VariableAddress[rd] : -# 861| r0_32(glval) = VariableAddress[b] : -# 861| r0_33(glval) = CheckedConvertOrThrow : r0_32 -# 861| mu0_34(PolymorphicDerived &) = Store : &:r0_31, r0_33 -# 863| r0_35(glval) = VariableAddress[pv] : -# 863| r0_36(glval) = VariableAddress[pb] : -# 863| r0_37(PolymorphicBase *) = Load : &:r0_36, ~mu0_2 -# 863| r0_38(void *) = DynamicCastToVoid : r0_37 -# 863| mu0_39(void *) = Store : &:r0_35, r0_38 -# 864| r0_40(glval) = VariableAddress[pcv] : -# 864| r0_41(glval) = VariableAddress[pd] : -# 864| r0_42(PolymorphicDerived *) = Load : &:r0_41, ~mu0_2 -# 864| r0_43(void *) = DynamicCastToVoid : r0_42 -# 864| mu0_44(void *) = Store : &:r0_40, r0_43 -# 865| v0_45(void) = NoOp : -# 849| v0_46(void) = ReturnVoid : -# 849| v0_47(void) = UnmodeledUse : mu* -# 849| v0_48(void) = ExitFunction : +# 850| mu0_4(PolymorphicBase) = Uninitialized[b] : &:r0_3 +#-----| r0_5(glval) = FunctionAddress[PolymorphicBase] : +#-----| v0_6(void) = Call : func:r0_5, this:r0_3 +#-----| mu0_7(unknown) = ^CallSideEffect : ~mu0_2 +#-----| mu0_8(PolymorphicBase) = ^IndirectMayWriteSideEffect[-1] : &:r0_3 +# 851| r0_9(glval) = VariableAddress[d] : +# 851| mu0_10(PolymorphicDerived) = Uninitialized[d] : &:r0_9 +# 851| r0_11(glval) = FunctionAddress[PolymorphicDerived] : +# 851| v0_12(void) = Call : func:r0_11, this:r0_9 +# 851| mu0_13(unknown) = ^CallSideEffect : ~mu0_2 +# 851| mu0_14(PolymorphicDerived) = ^IndirectMayWriteSideEffect[-1] : &:r0_9 +# 853| r0_15(glval) = VariableAddress[pb] : +# 853| r0_16(glval) = VariableAddress[b] : +# 853| r0_17(PolymorphicBase *) = CopyValue : r0_16 +# 853| mu0_18(PolymorphicBase *) = Store : &:r0_15, r0_17 +# 854| r0_19(glval) = VariableAddress[pd] : +# 854| r0_20(glval) = VariableAddress[d] : +# 854| r0_21(PolymorphicDerived *) = CopyValue : r0_20 +# 854| mu0_22(PolymorphicDerived *) = Store : &:r0_19, r0_21 +# 857| r0_23(glval) = VariableAddress[pd] : +# 857| r0_24(PolymorphicDerived *) = Load : &:r0_23, ~mu0_2 +# 857| r0_25(PolymorphicBase *) = CheckedConvertOrNull : r0_24 +# 857| r0_26(glval) = VariableAddress[pb] : +# 857| mu0_27(PolymorphicBase *) = Store : &:r0_26, r0_25 +# 858| r0_28(glval) = VariableAddress[rb] : +# 858| r0_29(glval) = VariableAddress[d] : +# 858| r0_30(glval) = CheckedConvertOrThrow : r0_29 +# 858| r0_31(PolymorphicBase &) = CopyValue : r0_30 +# 858| mu0_32(PolymorphicBase &) = Store : &:r0_28, r0_31 +# 860| r0_33(glval) = VariableAddress[pb] : +# 860| r0_34(PolymorphicBase *) = Load : &:r0_33, ~mu0_2 +# 860| r0_35(PolymorphicDerived *) = CheckedConvertOrNull : r0_34 +# 860| r0_36(glval) = VariableAddress[pd] : +# 860| mu0_37(PolymorphicDerived *) = Store : &:r0_36, r0_35 +# 861| r0_38(glval) = VariableAddress[rd] : +# 861| r0_39(glval) = VariableAddress[b] : +# 861| r0_40(glval) = CheckedConvertOrThrow : r0_39 +# 861| r0_41(PolymorphicDerived &) = CopyValue : r0_40 +# 861| mu0_42(PolymorphicDerived &) = Store : &:r0_38, r0_41 +# 863| r0_43(glval) = VariableAddress[pv] : +# 863| r0_44(glval) = VariableAddress[pb] : +# 863| r0_45(PolymorphicBase *) = Load : &:r0_44, ~mu0_2 +# 863| r0_46(void *) = DynamicCastToVoid : r0_45 +# 863| mu0_47(void *) = Store : &:r0_43, r0_46 +# 864| r0_48(glval) = VariableAddress[pcv] : +# 864| r0_49(glval) = VariableAddress[pd] : +# 864| r0_50(PolymorphicDerived *) = Load : &:r0_49, ~mu0_2 +# 864| r0_51(void *) = DynamicCastToVoid : r0_50 +# 864| mu0_52(void *) = Store : &:r0_48, r0_51 +# 865| v0_53(void) = NoOp : +# 849| v0_54(void) = ReturnVoid : +# 849| v0_55(void) = UnmodeledUse : mu* +# 849| v0_56(void) = AliasedUse : ~mu0_2 +# 849| v0_57(void) = ExitFunction : # 867| void String::String() # 867| Block 0 -# 867| v0_0(void) = EnterFunction : -# 867| mu0_1(unknown) = AliasedDefinition : -# 867| mu0_2(unknown) = UnmodeledDefinition : -# 867| r0_3(glval) = InitializeThis : -# 868| r0_4(glval) = FunctionAddress[String] : -# 868| r0_5(glval) = StringConstant[""] : -# 868| r0_6(char *) = Convert : r0_5 -# 868| v0_7(void) = Call : func:r0_4, this:r0_3, 0:r0_6 -# 868| mu0_8(unknown) = ^CallSideEffect : ~mu0_2 -# 868| v0_9(void) = ^IndirectReadSideEffect[0] : &:r0_6, ~mu0_2 -# 868| mu0_10(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_6 -# 869| v0_11(void) = NoOp : -# 867| v0_12(void) = ReturnVoid : -# 867| v0_13(void) = UnmodeledUse : mu* -# 867| v0_14(void) = ExitFunction : +# 867| v0_0(void) = EnterFunction : +# 867| mu0_1(unknown) = AliasedDefinition : +# 867| mu0_2(unknown) = UnmodeledDefinition : +# 867| r0_3(glval) = InitializeThis : +# 868| r0_4(glval) = FunctionAddress[String] : +# 868| r0_5(glval) = StringConstant[""] : +# 868| r0_6(char *) = Convert : r0_5 +# 868| v0_7(void) = Call : func:r0_4, this:r0_3, 0:r0_6 +# 868| mu0_8(unknown) = ^CallSideEffect : ~mu0_2 +# 868| mu0_9(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_3 +# 868| v0_10(void) = ^BufferReadSideEffect[0] : &:r0_6, ~mu0_2 +# 868| mu0_11(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_6 +# 869| v0_12(void) = NoOp : +# 867| v0_13(void) = ReturnVoid : +# 867| v0_14(void) = UnmodeledUse : mu* +# 867| v0_15(void) = AliasedUse : ~mu0_2 +# 867| v0_16(void) = ExitFunction : # 871| void ArrayConversions() # 871| Block 0 @@ -4071,32 +4308,39 @@ ir.cpp: # 875| r0_15(char *) = Convert : r0_14 # 875| r0_16(int) = Constant[0] : # 875| r0_17(glval) = PointerAdd[1] : r0_15, r0_16 -# 875| r0_18(char *) = Convert : r0_17 -# 875| r0_19(glval) = VariableAddress[p] : -# 875| mu0_20(char *) = Store : &:r0_19, r0_18 -# 876| r0_21(glval) = StringConstant["test"] : -# 876| r0_22(char *) = Convert : r0_21 -# 876| r0_23(int) = Constant[0] : -# 876| r0_24(glval) = PointerAdd[1] : r0_22, r0_23 -# 876| r0_25(glval) = VariableAddress[p] : -# 876| mu0_26(char *) = Store : &:r0_25, r0_24 -# 877| r0_27(glval) = VariableAddress[ra] : -# 877| r0_28(glval) = VariableAddress[a] : -# 877| mu0_29(char(&)[5]) = Store : &:r0_27, r0_28 -# 878| r0_30(glval) = VariableAddress[rs] : -# 878| r0_31(glval) = StringConstant["test"] : -# 878| mu0_32(char(&)[5]) = Store : &:r0_30, r0_31 -# 879| r0_33(glval) = VariableAddress[pa] : -# 879| r0_34(glval) = VariableAddress[a] : -# 879| r0_35(char(*)[5]) = Convert : r0_34 -# 879| mu0_36(char(*)[5]) = Store : &:r0_33, r0_35 -# 880| r0_37(glval) = StringConstant["test"] : -# 880| r0_38(glval) = VariableAddress[pa] : -# 880| mu0_39(char(*)[5]) = Store : &:r0_38, r0_37 -# 881| v0_40(void) = NoOp : -# 871| v0_41(void) = ReturnVoid : -# 871| v0_42(void) = UnmodeledUse : mu* -# 871| v0_43(void) = ExitFunction : +# 875| r0_18(char *) = CopyValue : r0_17 +# 875| r0_19(char *) = Convert : r0_18 +# 875| r0_20(glval) = VariableAddress[p] : +# 875| mu0_21(char *) = Store : &:r0_20, r0_19 +# 876| r0_22(glval) = StringConstant["test"] : +# 876| r0_23(char *) = Convert : r0_22 +# 876| r0_24(int) = Constant[0] : +# 876| r0_25(glval) = PointerAdd[1] : r0_23, r0_24 +# 876| r0_26(char *) = CopyValue : r0_25 +# 876| r0_27(glval) = VariableAddress[p] : +# 876| mu0_28(char *) = Store : &:r0_27, r0_26 +# 877| r0_29(glval) = VariableAddress[ra] : +# 877| r0_30(glval) = VariableAddress[a] : +# 877| r0_31(char(&)[5]) = CopyValue : r0_30 +# 877| mu0_32(char(&)[5]) = Store : &:r0_29, r0_31 +# 878| r0_33(glval) = VariableAddress[rs] : +# 878| r0_34(glval) = StringConstant["test"] : +# 878| r0_35(char(&)[5]) = CopyValue : r0_34 +# 878| mu0_36(char(&)[5]) = Store : &:r0_33, r0_35 +# 879| r0_37(glval) = VariableAddress[pa] : +# 879| r0_38(glval) = VariableAddress[a] : +# 879| r0_39(char(*)[5]) = CopyValue : r0_38 +# 879| r0_40(char(*)[5]) = Convert : r0_39 +# 879| mu0_41(char(*)[5]) = Store : &:r0_37, r0_40 +# 880| r0_42(glval) = StringConstant["test"] : +# 880| r0_43(char(*)[5]) = CopyValue : r0_42 +# 880| r0_44(glval) = VariableAddress[pa] : +# 880| mu0_45(char(*)[5]) = Store : &:r0_44, r0_43 +# 881| v0_46(void) = NoOp : +# 871| v0_47(void) = ReturnVoid : +# 871| v0_48(void) = UnmodeledUse : mu* +# 871| v0_49(void) = AliasedUse : ~mu0_2 +# 871| v0_50(void) = ExitFunction : # 883| void FuncPtrConversions(int(*)(int), void*) # 883| Block 0 @@ -4123,7 +4367,8 @@ ir.cpp: # 883| v0_20(void) = ReturnIndirection : &:r0_7, ~mu0_2 # 883| v0_21(void) = ReturnVoid : # 883| v0_22(void) = UnmodeledUse : mu* -# 883| v0_23(void) = ExitFunction : +# 883| v0_23(void) = AliasedUse : ~mu0_2 +# 883| v0_24(void) = ExitFunction : # 888| void VarArgUsage(int) # 888| Block 0 @@ -4167,7 +4412,8 @@ ir.cpp: # 898| v0_37(void) = NoOp : # 888| v0_38(void) = ReturnVoid : # 888| v0_39(void) = UnmodeledUse : mu* -# 888| v0_40(void) = ExitFunction : +# 888| v0_40(void) = AliasedUse : ~mu0_2 +# 888| v0_41(void) = ExitFunction : # 900| void CastToVoid(int) # 900| Block 0 @@ -4181,7 +4427,8 @@ ir.cpp: # 902| v0_7(void) = NoOp : # 900| v0_8(void) = ReturnVoid : # 900| v0_9(void) = UnmodeledUse : mu* -# 900| v0_10(void) = ExitFunction : +# 900| v0_10(void) = AliasedUse : ~mu0_2 +# 900| v0_11(void) = ExitFunction : # 904| void ConstantConditions(int) # 904| Block 0 @@ -4206,7 +4453,8 @@ ir.cpp: # 907| v1_3(void) = NoOp : # 904| v1_4(void) = ReturnVoid : # 904| v1_5(void) = UnmodeledUse : mu* -# 904| v1_6(void) = ExitFunction : +# 904| v1_6(void) = AliasedUse : ~mu0_2 +# 904| v1_7(void) = ExitFunction : # 906| Block 2 # 906| r2_0(glval) = VariableAddress[x] : @@ -4224,67 +4472,70 @@ ir.cpp: # 940| void OperatorNew() # 940| Block 0 -# 940| v0_0(void) = EnterFunction : -# 940| mu0_1(unknown) = AliasedDefinition : -# 940| mu0_2(unknown) = UnmodeledDefinition : -# 941| r0_3(glval) = FunctionAddress[operator new] : -# 941| r0_4(unsigned long) = Constant[4] : -# 941| r0_5(void *) = Call : func:r0_3, 0:r0_4 -# 941| mu0_6(unknown) = ^CallSideEffect : ~mu0_2 -# 941| r0_7(int *) = Convert : r0_5 -# 942| r0_8(glval) = FunctionAddress[operator new] : -# 942| r0_9(unsigned long) = Constant[4] : -# 942| r0_10(float) = Constant[1.0] : -# 942| r0_11(void *) = Call : func:r0_8, 0:r0_9, 1:r0_10 -# 942| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 -# 942| r0_13(int *) = Convert : r0_11 -# 943| r0_14(glval) = FunctionAddress[operator new] : -# 943| r0_15(unsigned long) = Constant[4] : -# 943| r0_16(void *) = Call : func:r0_14, 0:r0_15 -# 943| mu0_17(unknown) = ^CallSideEffect : ~mu0_2 -# 943| r0_18(int *) = Convert : r0_16 -# 943| r0_19(int) = Constant[0] : -# 943| mu0_20(int) = Store : &:r0_18, r0_19 -# 944| r0_21(glval) = FunctionAddress[operator new] : -# 944| r0_22(unsigned long) = Constant[8] : -# 944| r0_23(void *) = Call : func:r0_21, 0:r0_22 -# 944| mu0_24(unknown) = ^CallSideEffect : ~mu0_2 -# 944| r0_25(String *) = Convert : r0_23 -# 944| r0_26(glval) = FunctionAddress[String] : -# 944| v0_27(void) = Call : func:r0_26, this:r0_25 -# 944| mu0_28(unknown) = ^CallSideEffect : ~mu0_2 -# 945| r0_29(glval) = FunctionAddress[operator new] : -# 945| r0_30(unsigned long) = Constant[8] : -# 945| r0_31(float) = Constant[1.0] : -# 945| r0_32(void *) = Call : func:r0_29, 0:r0_30, 1:r0_31 -# 945| mu0_33(unknown) = ^CallSideEffect : ~mu0_2 -# 945| r0_34(String *) = Convert : r0_32 -# 945| r0_35(glval) = FunctionAddress[String] : -# 945| r0_36(glval) = StringConstant["hello"] : -# 945| r0_37(char *) = Convert : r0_36 -# 945| v0_38(void) = Call : func:r0_35, this:r0_34, 0:r0_37 -# 945| mu0_39(unknown) = ^CallSideEffect : ~mu0_2 -# 945| v0_40(void) = ^IndirectReadSideEffect[0] : &:r0_37, ~mu0_2 -# 945| mu0_41(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_37 -# 946| r0_42(glval) = FunctionAddress[operator new] : -# 946| r0_43(unsigned long) = Constant[256] : -# 946| r0_44(align_val_t) = Constant[128] : -# 946| r0_45(void *) = Call : func:r0_42, 0:r0_43, 1:r0_44 -# 946| mu0_46(unknown) = ^CallSideEffect : ~mu0_2 -# 946| r0_47(Overaligned *) = Convert : r0_45 -# 947| r0_48(glval) = FunctionAddress[operator new] : -# 947| r0_49(unsigned long) = Constant[256] : -# 947| r0_50(align_val_t) = Constant[128] : -# 947| r0_51(float) = Constant[1.0] : -# 947| r0_52(void *) = Call : func:r0_48, 0:r0_49, 1:r0_50, 2:r0_51 -# 947| mu0_53(unknown) = ^CallSideEffect : ~mu0_2 -# 947| r0_54(Overaligned *) = Convert : r0_52 -# 947| r0_55(Overaligned) = Constant[0] : -# 947| mu0_56(Overaligned) = Store : &:r0_54, r0_55 -# 948| v0_57(void) = NoOp : -# 940| v0_58(void) = ReturnVoid : -# 940| v0_59(void) = UnmodeledUse : mu* -# 940| v0_60(void) = ExitFunction : +# 940| v0_0(void) = EnterFunction : +# 940| mu0_1(unknown) = AliasedDefinition : +# 940| mu0_2(unknown) = UnmodeledDefinition : +# 941| r0_3(glval) = FunctionAddress[operator new] : +# 941| r0_4(unsigned long) = Constant[4] : +# 941| r0_5(void *) = Call : func:r0_3, 0:r0_4 +# 941| mu0_6(unknown) = ^CallSideEffect : ~mu0_2 +# 941| r0_7(int *) = Convert : r0_5 +# 942| r0_8(glval) = FunctionAddress[operator new] : +# 942| r0_9(unsigned long) = Constant[4] : +# 942| r0_10(float) = Constant[1.0] : +# 942| r0_11(void *) = Call : func:r0_8, 0:r0_9, 1:r0_10 +# 942| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 +# 942| r0_13(int *) = Convert : r0_11 +# 943| r0_14(glval) = FunctionAddress[operator new] : +# 943| r0_15(unsigned long) = Constant[4] : +# 943| r0_16(void *) = Call : func:r0_14, 0:r0_15 +# 943| mu0_17(unknown) = ^CallSideEffect : ~mu0_2 +# 943| r0_18(int *) = Convert : r0_16 +# 943| r0_19(int) = Constant[0] : +# 943| mu0_20(int) = Store : &:r0_18, r0_19 +# 944| r0_21(glval) = FunctionAddress[operator new] : +# 944| r0_22(unsigned long) = Constant[8] : +# 944| r0_23(void *) = Call : func:r0_21, 0:r0_22 +# 944| mu0_24(unknown) = ^CallSideEffect : ~mu0_2 +# 944| r0_25(String *) = Convert : r0_23 +# 944| r0_26(glval) = FunctionAddress[String] : +# 944| v0_27(void) = Call : func:r0_26, this:r0_25 +# 944| mu0_28(unknown) = ^CallSideEffect : ~mu0_2 +# 944| mu0_29(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_25 +# 945| r0_30(glval) = FunctionAddress[operator new] : +# 945| r0_31(unsigned long) = Constant[8] : +# 945| r0_32(float) = Constant[1.0] : +# 945| r0_33(void *) = Call : func:r0_30, 0:r0_31, 1:r0_32 +# 945| mu0_34(unknown) = ^CallSideEffect : ~mu0_2 +# 945| r0_35(String *) = Convert : r0_33 +# 945| r0_36(glval) = FunctionAddress[String] : +# 945| r0_37(glval) = StringConstant["hello"] : +# 945| r0_38(char *) = Convert : r0_37 +# 945| v0_39(void) = Call : func:r0_36, this:r0_35, 0:r0_38 +# 945| mu0_40(unknown) = ^CallSideEffect : ~mu0_2 +# 945| mu0_41(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_35 +# 945| v0_42(void) = ^BufferReadSideEffect[0] : &:r0_38, ~mu0_2 +# 945| mu0_43(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_38 +# 946| r0_44(glval) = FunctionAddress[operator new] : +# 946| r0_45(unsigned long) = Constant[256] : +# 946| r0_46(align_val_t) = Constant[128] : +# 946| r0_47(void *) = Call : func:r0_44, 0:r0_45, 1:r0_46 +# 946| mu0_48(unknown) = ^CallSideEffect : ~mu0_2 +# 946| r0_49(Overaligned *) = Convert : r0_47 +# 947| r0_50(glval) = FunctionAddress[operator new] : +# 947| r0_51(unsigned long) = Constant[256] : +# 947| r0_52(align_val_t) = Constant[128] : +# 947| r0_53(float) = Constant[1.0] : +# 947| r0_54(void *) = Call : func:r0_50, 0:r0_51, 1:r0_52, 2:r0_53 +# 947| mu0_55(unknown) = ^CallSideEffect : ~mu0_2 +# 947| r0_56(Overaligned *) = Convert : r0_54 +# 947| r0_57(Overaligned) = Constant[0] : +# 947| mu0_58(Overaligned) = Store : &:r0_56, r0_57 +# 948| v0_59(void) = NoOp : +# 940| v0_60(void) = ReturnVoid : +# 940| v0_61(void) = UnmodeledUse : mu* +# 940| v0_62(void) = AliasedUse : ~mu0_2 +# 940| v0_63(void) = ExitFunction : # 950| void OperatorNewArray(int) # 950| Block 0 @@ -4364,7 +4615,8 @@ ir.cpp: # 959| v0_73(void) = NoOp : # 950| v0_74(void) = ReturnVoid : # 950| v0_75(void) = UnmodeledUse : mu* -# 950| v0_76(void) = ExitFunction : +# 950| v0_76(void) = AliasedUse : ~mu0_2 +# 950| v0_77(void) = ExitFunction : # 961| int designatedInit() # 961| Block 0 @@ -4403,7 +4655,8 @@ ir.cpp: # 961| r0_32(glval) = VariableAddress[#return] : # 961| v0_33(void) = ReturnValue : &:r0_32, ~mu0_2 # 961| v0_34(void) = UnmodeledUse : mu* -# 961| v0_35(void) = ExitFunction : +# 961| v0_35(void) = AliasedUse : ~mu0_2 +# 961| v0_36(void) = ExitFunction : # 966| void IfStmtWithDeclaration(int, int) # 966| Block 0 @@ -4423,7 +4676,8 @@ ir.cpp: # 967| mu0_13(bool) = Store : &:r0_7, r0_12 # 967| r0_14(glval) = VariableAddress[b] : # 967| r0_15(bool) = Load : &:r0_14, ~mu0_2 -# 967| v0_16(void) = ConditionalBranch : r0_15 +# 967| r0_16(bool) = CopyValue : r0_15 +# 967| v0_17(void) = ConditionalBranch : r0_16 #-----| False -> Block 2 #-----| True -> Block 1 @@ -4445,7 +4699,8 @@ ir.cpp: # 970| r2_8(int) = Load : &:r2_7, ~mu0_2 # 970| r2_9(int) = Constant[0] : # 970| r2_10(bool) = CompareNE : r2_8, r2_9 -# 970| v2_11(void) = ConditionalBranch : r2_10 +# 970| r2_11(bool) = CopyValue : r2_10 +# 970| v2_12(void) = ConditionalBranch : r2_11 #-----| False -> Block 4 #-----| True -> Block 3 @@ -4458,12 +4713,14 @@ ir.cpp: # 973| Block 4 # 973| r4_0(glval) = VariableAddress[p] : # 973| r4_1(glval) = VariableAddress[x] : -# 973| mu4_2(int *) = Store : &:r4_0, r4_1 -# 973| r4_3(glval) = VariableAddress[p] : -# 973| r4_4(int *) = Load : &:r4_3, ~mu0_2 -# 973| r4_5(int *) = Constant[0] : -# 973| r4_6(bool) = CompareNE : r4_4, r4_5 -# 973| v4_7(void) = ConditionalBranch : r4_6 +# 973| r4_2(int *) = CopyValue : r4_1 +# 973| mu4_3(int *) = Store : &:r4_0, r4_2 +# 973| r4_4(glval) = VariableAddress[p] : +# 973| r4_5(int *) = Load : &:r4_4, ~mu0_2 +# 973| r4_6(int *) = Constant[0] : +# 973| r4_7(bool) = CompareNE : r4_5, r4_6 +# 973| r4_8(bool) = CopyValue : r4_7 +# 973| v4_9(void) = ConditionalBranch : r4_8 #-----| False -> Block 6 #-----| True -> Block 5 @@ -4471,14 +4728,16 @@ ir.cpp: # 974| r5_0(int) = Constant[2] : # 974| r5_1(glval) = VariableAddress[p] : # 974| r5_2(int *) = Load : &:r5_1, ~mu0_2 -# 974| mu5_3(int) = Store : &:r5_2, r5_0 +# 974| r5_3(glval) = CopyValue : r5_2 +# 974| mu5_4(int) = Store : &:r5_3, r5_0 #-----| Goto -> Block 6 # 976| Block 6 # 976| v6_0(void) = NoOp : # 966| v6_1(void) = ReturnVoid : # 966| v6_2(void) = UnmodeledUse : mu* -# 966| v6_3(void) = ExitFunction : +# 966| v6_3(void) = AliasedUse : ~mu0_2 +# 966| v6_4(void) = ExitFunction : # 978| void WhileStmtWithDeclaration(int, int) # 978| Block 0 @@ -4507,7 +4766,8 @@ ir.cpp: # 981| r2_8(int) = Load : &:r2_7, ~mu0_2 # 981| r2_9(int) = Constant[0] : # 981| r2_10(bool) = CompareNE : r2_8, r2_9 -# 981| v2_11(void) = ConditionalBranch : r2_10 +# 981| r2_11(bool) = CopyValue : r2_10 +# 981| v2_12(void) = ConditionalBranch : r2_11 #-----| False -> Block 4 #-----| True -> Block 3 @@ -4518,12 +4778,14 @@ ir.cpp: # 983| Block 4 # 983| r4_0(glval) = VariableAddress[p] : # 983| r4_1(glval) = VariableAddress[x] : -# 983| mu4_2(int *) = Store : &:r4_0, r4_1 -# 983| r4_3(glval) = VariableAddress[p] : -# 983| r4_4(int *) = Load : &:r4_3, ~mu0_2 -# 983| r4_5(int *) = Constant[0] : -# 983| r4_6(bool) = CompareNE : r4_4, r4_5 -# 983| v4_7(void) = ConditionalBranch : r4_6 +# 983| r4_2(int *) = CopyValue : r4_1 +# 983| mu4_3(int *) = Store : &:r4_0, r4_2 +# 983| r4_4(glval) = VariableAddress[p] : +# 983| r4_5(int *) = Load : &:r4_4, ~mu0_2 +# 983| r4_6(int *) = Constant[0] : +# 983| r4_7(bool) = CompareNE : r4_5, r4_6 +# 983| r4_8(bool) = CopyValue : r4_7 +# 983| v4_9(void) = ConditionalBranch : r4_8 #-----| False -> Block 6 #-----| True -> Block 5 @@ -4535,7 +4797,8 @@ ir.cpp: # 985| v6_0(void) = NoOp : # 978| v6_1(void) = ReturnVoid : # 978| v6_2(void) = UnmodeledUse : mu* -# 978| v6_3(void) = ExitFunction : +# 978| v6_3(void) = AliasedUse : ~mu0_2 +# 978| v6_4(void) = ExitFunction : # 979| Block 7 # 979| r7_0(glval) = VariableAddress[b] : @@ -4547,7 +4810,8 @@ ir.cpp: # 979| mu7_6(bool) = Store : &:r7_0, r7_5 # 979| r7_7(glval) = VariableAddress[b] : # 979| r7_8(bool) = Load : &:r7_7, ~mu0_2 -# 979| v7_9(void) = ConditionalBranch : r7_8 +# 979| r7_9(bool) = CopyValue : r7_8 +# 979| v7_10(void) = ConditionalBranch : r7_9 #-----| False -> Block 2 #-----| True -> Block 1 @@ -4579,7 +4843,8 @@ ir.cpp: # 987| r0_23(glval) = VariableAddress[#return] : # 987| v0_24(void) = ReturnValue : &:r0_23, ~mu0_2 # 987| v0_25(void) = UnmodeledUse : mu* -# 987| v0_26(void) = ExitFunction : +# 987| v0_26(void) = AliasedUse : ~mu0_2 +# 987| v0_27(void) = ExitFunction : # 991| int ExprStmt(int, int, int) # 991| Block 0 @@ -4630,7 +4895,8 @@ ir.cpp: # 991| r3_9(glval) = VariableAddress[#return] : # 991| v3_10(void) = ReturnValue : &:r3_9, ~mu0_2 # 991| v3_11(void) = UnmodeledUse : mu* -# 991| v3_12(void) = ExitFunction : +# 991| v3_12(void) = AliasedUse : ~mu0_2 +# 991| v3_13(void) = ExitFunction : # 1006| void OperatorDelete() # 1006| Block 0 @@ -4650,7 +4916,8 @@ ir.cpp: # 1012| v0_13(void) = NoOp : # 1006| v0_14(void) = ReturnVoid : # 1006| v0_15(void) = UnmodeledUse : mu* -# 1006| v0_16(void) = ExitFunction : +# 1006| v0_16(void) = AliasedUse : ~mu0_2 +# 1006| v0_17(void) = ExitFunction : # 1015| void OperatorDeleteArray() # 1015| Block 0 @@ -4670,7 +4937,8 @@ ir.cpp: # 1021| v0_13(void) = NoOp : # 1015| v0_14(void) = ReturnVoid : # 1015| v0_15(void) = UnmodeledUse : mu* -# 1015| v0_16(void) = ExitFunction : +# 1015| v0_16(void) = AliasedUse : ~mu0_2 +# 1015| v0_17(void) = ExitFunction : # 1025| void EmptyStructInit() # 1025| Block 0 @@ -4682,7 +4950,8 @@ ir.cpp: # 1027| v0_5(void) = NoOp : # 1025| v0_6(void) = ReturnVoid : # 1025| v0_7(void) = UnmodeledUse : mu* -# 1025| v0_8(void) = ExitFunction : +# 1025| v0_8(void) = AliasedUse : ~mu0_2 +# 1025| v0_9(void) = ExitFunction : # 1029| void (lambda [] type at line 1029, col. 12)::(constructor)((lambda [] type at line 1029, col. 12)&&) # 1029| Block 0 @@ -4698,7 +4967,8 @@ ir.cpp: #-----| v0_9(void) = ReturnIndirection : &:r0_6, ~mu0_2 # 1029| v0_10(void) = ReturnVoid : # 1029| v0_11(void) = UnmodeledUse : mu* -# 1029| v0_12(void) = ExitFunction : +# 1029| v0_12(void) = AliasedUse : ~mu0_2 +# 1029| v0_13(void) = ExitFunction : # 1029| void (lambda [] type at line 1029, col. 12)::operator()() const # 1029| Block 0 @@ -4709,7 +4979,8 @@ ir.cpp: # 1029| v0_4(void) = NoOp : # 1029| v0_5(void) = ReturnVoid : # 1029| v0_6(void) = UnmodeledUse : mu* -# 1029| v0_7(void) = ExitFunction : +# 1029| v0_7(void) = AliasedUse : ~mu0_2 +# 1029| v0_8(void) = ExitFunction : # 1029| void(* (lambda [] type at line 1029, col. 12)::operator void (*)()() const)() # 1029| Block 0 @@ -4723,170 +4994,190 @@ ir.cpp: # 1029| r0_7(glval<..(*)(..)>) = VariableAddress[#return] : # 1029| v0_8(void) = ReturnValue : &:r0_7, ~mu0_2 # 1029| v0_9(void) = UnmodeledUse : mu* -# 1029| v0_10(void) = ExitFunction : +# 1029| v0_10(void) = AliasedUse : ~mu0_2 +# 1029| v0_11(void) = ExitFunction : # 1031| void Lambda(int, String const&) # 1031| Block 0 -# 1031| v0_0(void) = EnterFunction : -# 1031| mu0_1(unknown) = AliasedDefinition : -# 1031| mu0_2(unknown) = UnmodeledDefinition : -# 1031| r0_3(glval) = VariableAddress[x] : -# 1031| mu0_4(int) = InitializeParameter[x] : &:r0_3 -# 1031| r0_5(glval) = VariableAddress[s] : -# 1031| mu0_6(String &) = InitializeParameter[s] : &:r0_5 -# 1031| r0_7(String &) = Load : &:r0_5, ~mu0_6 -# 1031| mu0_8(unknown) = InitializeIndirection[s] : &:r0_7 -# 1032| r0_9(glval) = VariableAddress[lambda_empty] : -# 1032| r0_10(glval) = VariableAddress[#temp1032:23] : -# 1032| mu0_11(decltype([...](...){...})) = Uninitialized[#temp1032:23] : &:r0_10 -# 1032| r0_12(decltype([...](...){...})) = Load : &:r0_10, ~mu0_2 -# 1032| mu0_13(decltype([...](...){...})) = Store : &:r0_9, r0_12 -# 1033| r0_14(char) = Constant[65] : -# 1034| r0_15(glval) = VariableAddress[lambda_ref] : -# 1034| r0_16(glval) = VariableAddress[#temp1034:21] : -# 1034| mu0_17(decltype([...](...){...})) = Uninitialized[#temp1034:21] : &:r0_16 -# 1034| r0_18(glval) = FieldAddress[s] : r0_16 -#-----| r0_19(glval) = VariableAddress[s] : -#-----| r0_20(String &) = Load : &:r0_19, ~mu0_2 -# 1034| mu0_21(String &) = Store : &:r0_18, r0_20 -# 1034| r0_22(glval) = FieldAddress[x] : r0_16 -#-----| r0_23(glval) = VariableAddress[x] : -#-----| mu0_24(int &) = Store : &:r0_22, r0_23 -# 1034| r0_25(decltype([...](...){...})) = Load : &:r0_16, ~mu0_2 -# 1034| mu0_26(decltype([...](...){...})) = Store : &:r0_15, r0_25 -# 1035| r0_27(glval) = VariableAddress[lambda_ref] : -# 1035| r0_28(glval) = Convert : r0_27 -# 1035| r0_29(glval) = FunctionAddress[operator()] : -# 1035| r0_30(float) = Constant[1.0] : -# 1035| r0_31(char) = Call : func:r0_29, this:r0_28, 0:r0_30 -# 1035| mu0_32(unknown) = ^CallSideEffect : ~mu0_2 -# 1035| v0_33(void) = ^IndirectReadSideEffect[-1] : &:r0_28, ~mu0_2 -# 1035| mu0_34(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_28 -# 1036| r0_35(glval) = VariableAddress[lambda_val] : -# 1036| r0_36(glval) = FunctionAddress[(constructor)] : -# 1036| r0_37(glval) = VariableAddress[#temp1036:21] : -# 1036| mu0_38(decltype([...](...){...})) = Uninitialized[#temp1036:21] : &:r0_37 -# 1036| r0_39(glval) = FieldAddress[s] : r0_37 -#-----| r0_40(glval) = FunctionAddress[String] : -#-----| v0_41(void) = Call : func:r0_40, this:r0_39 -#-----| mu0_42(unknown) = ^CallSideEffect : ~mu0_2 -# 1036| r0_43(glval) = FieldAddress[x] : r0_37 -#-----| r0_44(glval) = VariableAddress[x] : -#-----| r0_45(int) = Load : &:r0_44, ~mu0_2 -#-----| mu0_46(int) = Store : &:r0_43, r0_45 -# 1036| r0_47(decltype([...](...){...})) = Load : &:r0_37, ~mu0_2 -# 1036| v0_48(void) = Call : func:r0_36, this:r0_35, 0:r0_47 -# 1036| mu0_49(unknown) = ^CallSideEffect : ~mu0_2 -# 1036| v0_50(void) = ^IndirectReadSideEffect[0] : &:r0_47, ~mu0_2 -# 1036| mu0_51(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_47 -# 1037| r0_52(glval) = VariableAddress[lambda_val] : -# 1037| r0_53(glval) = Convert : r0_52 -# 1037| r0_54(glval) = FunctionAddress[operator()] : -# 1037| r0_55(float) = Constant[2.0] : -# 1037| r0_56(char) = Call : func:r0_54, this:r0_53, 0:r0_55 -# 1037| mu0_57(unknown) = ^CallSideEffect : ~mu0_2 -# 1037| v0_58(void) = ^IndirectReadSideEffect[-1] : &:r0_53, ~mu0_2 -# 1037| mu0_59(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_53 -# 1038| r0_60(glval) = VariableAddress[lambda_ref_explicit] : -# 1038| r0_61(glval) = VariableAddress[#temp1038:30] : -# 1038| mu0_62(decltype([...](...){...})) = Uninitialized[#temp1038:30] : &:r0_61 -# 1038| r0_63(glval) = FieldAddress[s] : r0_61 -# 1038| r0_64(glval) = VariableAddress[s] : -# 1038| r0_65(String &) = Load : &:r0_64, ~mu0_2 -# 1038| mu0_66(String &) = Store : &:r0_63, r0_65 -# 1038| r0_67(decltype([...](...){...})) = Load : &:r0_61, ~mu0_2 -# 1038| mu0_68(decltype([...](...){...})) = Store : &:r0_60, r0_67 -# 1039| r0_69(glval) = VariableAddress[lambda_ref_explicit] : -# 1039| r0_70(glval) = Convert : r0_69 -# 1039| r0_71(glval) = FunctionAddress[operator()] : -# 1039| r0_72(float) = Constant[3.0] : -# 1039| r0_73(char) = Call : func:r0_71, this:r0_70, 0:r0_72 -# 1039| mu0_74(unknown) = ^CallSideEffect : ~mu0_2 -# 1039| v0_75(void) = ^IndirectReadSideEffect[-1] : &:r0_70, ~mu0_2 -# 1039| mu0_76(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_70 -# 1040| r0_77(glval) = VariableAddress[lambda_val_explicit] : -# 1040| r0_78(glval) = FunctionAddress[(constructor)] : -# 1040| r0_79(glval) = VariableAddress[#temp1040:30] : -# 1040| mu0_80(decltype([...](...){...})) = Uninitialized[#temp1040:30] : &:r0_79 -# 1040| r0_81(glval) = FieldAddress[s] : r0_79 -#-----| r0_82(glval) = FunctionAddress[String] : -#-----| v0_83(void) = Call : func:r0_82, this:r0_81 -#-----| mu0_84(unknown) = ^CallSideEffect : ~mu0_2 -# 1040| r0_85(decltype([...](...){...})) = Load : &:r0_79, ~mu0_2 -# 1040| v0_86(void) = Call : func:r0_78, this:r0_77, 0:r0_85 -# 1040| mu0_87(unknown) = ^CallSideEffect : ~mu0_2 -# 1040| v0_88(void) = ^IndirectReadSideEffect[0] : &:r0_85, ~mu0_2 -# 1040| mu0_89(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_85 -# 1041| r0_90(glval) = VariableAddress[lambda_val_explicit] : -# 1041| r0_91(glval) = Convert : r0_90 -# 1041| r0_92(glval) = FunctionAddress[operator()] : -# 1041| r0_93(float) = Constant[4.0] : -# 1041| r0_94(char) = Call : func:r0_92, this:r0_91, 0:r0_93 -# 1041| mu0_95(unknown) = ^CallSideEffect : ~mu0_2 -# 1041| v0_96(void) = ^IndirectReadSideEffect[-1] : &:r0_91, ~mu0_2 -# 1041| mu0_97(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_91 -# 1042| r0_98(glval) = VariableAddress[lambda_mixed_explicit] : -# 1042| r0_99(glval) = VariableAddress[#temp1042:32] : -# 1042| mu0_100(decltype([...](...){...})) = Uninitialized[#temp1042:32] : &:r0_99 -# 1042| r0_101(glval) = FieldAddress[s] : r0_99 -# 1042| r0_102(glval) = VariableAddress[s] : -# 1042| r0_103(String &) = Load : &:r0_102, ~mu0_2 -# 1042| mu0_104(String &) = Store : &:r0_101, r0_103 -# 1042| r0_105(glval) = FieldAddress[x] : r0_99 -# 1042| r0_106(glval) = VariableAddress[x] : -# 1042| r0_107(int) = Load : &:r0_106, ~mu0_2 -# 1042| mu0_108(int) = Store : &:r0_105, r0_107 -# 1042| r0_109(decltype([...](...){...})) = Load : &:r0_99, ~mu0_2 -# 1042| mu0_110(decltype([...](...){...})) = Store : &:r0_98, r0_109 -# 1043| r0_111(glval) = VariableAddress[lambda_mixed_explicit] : -# 1043| r0_112(glval) = Convert : r0_111 -# 1043| r0_113(glval) = FunctionAddress[operator()] : -# 1043| r0_114(float) = Constant[5.0] : -# 1043| r0_115(char) = Call : func:r0_113, this:r0_112, 0:r0_114 -# 1043| mu0_116(unknown) = ^CallSideEffect : ~mu0_2 -# 1043| v0_117(void) = ^IndirectReadSideEffect[-1] : &:r0_112, ~mu0_2 -# 1043| mu0_118(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_112 -# 1044| r0_119(glval) = VariableAddress[r] : -# 1044| r0_120(glval) = VariableAddress[x] : -# 1044| r0_121(int) = Load : &:r0_120, ~mu0_2 -# 1044| r0_122(int) = Constant[1] : -# 1044| r0_123(int) = Sub : r0_121, r0_122 -# 1044| mu0_124(int) = Store : &:r0_119, r0_123 -# 1045| r0_125(glval) = VariableAddress[lambda_inits] : -# 1045| r0_126(glval) = VariableAddress[#temp1045:23] : -# 1045| mu0_127(decltype([...](...){...})) = Uninitialized[#temp1045:23] : &:r0_126 -# 1045| r0_128(glval) = FieldAddress[s] : r0_126 -# 1045| r0_129(glval) = VariableAddress[s] : -# 1045| r0_130(String &) = Load : &:r0_129, ~mu0_2 -# 1045| mu0_131(String &) = Store : &:r0_128, r0_130 -# 1045| r0_132(glval) = FieldAddress[x] : r0_126 -# 1045| r0_133(glval) = VariableAddress[x] : -# 1045| r0_134(int) = Load : &:r0_133, ~mu0_2 -# 1045| mu0_135(int) = Store : &:r0_132, r0_134 -# 1045| r0_136(glval) = FieldAddress[i] : r0_126 -# 1045| r0_137(glval) = VariableAddress[x] : -# 1045| r0_138(int) = Load : &:r0_137, ~mu0_2 -# 1045| r0_139(int) = Constant[1] : -# 1045| r0_140(int) = Add : r0_138, r0_139 -# 1045| mu0_141(int) = Store : &:r0_136, r0_140 -# 1045| r0_142(glval) = FieldAddress[j] : r0_126 -# 1045| r0_143(glval) = VariableAddress[r] : -# 1045| mu0_144(int &) = Store : &:r0_142, r0_143 -# 1045| r0_145(decltype([...](...){...})) = Load : &:r0_126, ~mu0_2 -# 1045| mu0_146(decltype([...](...){...})) = Store : &:r0_125, r0_145 -# 1046| r0_147(glval) = VariableAddress[lambda_inits] : -# 1046| r0_148(glval) = Convert : r0_147 -# 1046| r0_149(glval) = FunctionAddress[operator()] : -# 1046| r0_150(float) = Constant[6.0] : -# 1046| r0_151(char) = Call : func:r0_149, this:r0_148, 0:r0_150 -# 1046| mu0_152(unknown) = ^CallSideEffect : ~mu0_2 -# 1046| v0_153(void) = ^IndirectReadSideEffect[-1] : &:r0_148, ~mu0_2 -# 1046| mu0_154(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_148 -# 1047| v0_155(void) = NoOp : -# 1031| v0_156(void) = ReturnIndirection : &:r0_7, ~mu0_2 -# 1031| v0_157(void) = ReturnVoid : -# 1031| v0_158(void) = UnmodeledUse : mu* -# 1031| v0_159(void) = ExitFunction : +# 1031| v0_0(void) = EnterFunction : +# 1031| mu0_1(unknown) = AliasedDefinition : +# 1031| mu0_2(unknown) = UnmodeledDefinition : +# 1031| r0_3(glval) = VariableAddress[x] : +# 1031| mu0_4(int) = InitializeParameter[x] : &:r0_3 +# 1031| r0_5(glval) = VariableAddress[s] : +# 1031| mu0_6(String &) = InitializeParameter[s] : &:r0_5 +# 1031| r0_7(String &) = Load : &:r0_5, ~mu0_6 +# 1031| mu0_8(unknown) = InitializeIndirection[s] : &:r0_7 +# 1032| r0_9(glval) = VariableAddress[lambda_empty] : +# 1032| r0_10(glval) = VariableAddress[#temp1032:23] : +# 1032| mu0_11(decltype([...](...){...})) = Uninitialized[#temp1032:23] : &:r0_10 +# 1032| r0_12(decltype([...](...){...})) = Load : &:r0_10, ~mu0_2 +# 1032| mu0_13(decltype([...](...){...})) = Store : &:r0_9, r0_12 +# 1033| r0_14(char) = Constant[65] : +# 1034| r0_15(glval) = VariableAddress[lambda_ref] : +# 1034| r0_16(glval) = VariableAddress[#temp1034:21] : +# 1034| mu0_17(decltype([...](...){...})) = Uninitialized[#temp1034:21] : &:r0_16 +# 1034| r0_18(glval) = FieldAddress[s] : r0_16 +#-----| r0_19(glval) = VariableAddress[s] : +#-----| r0_20(String &) = Load : &:r0_19, ~mu0_2 +# 1034| r0_21(glval) = CopyValue : r0_20 +# 1034| r0_22(String &) = CopyValue : r0_21 +# 1034| mu0_23(String &) = Store : &:r0_18, r0_22 +# 1034| r0_24(glval) = FieldAddress[x] : r0_16 +#-----| r0_25(glval) = VariableAddress[x] : +#-----| r0_26(int &) = CopyValue : r0_25 +#-----| mu0_27(int &) = Store : &:r0_24, r0_26 +# 1034| r0_28(decltype([...](...){...})) = Load : &:r0_16, ~mu0_2 +# 1034| mu0_29(decltype([...](...){...})) = Store : &:r0_15, r0_28 +# 1035| r0_30(glval) = VariableAddress[lambda_ref] : +# 1035| r0_31(glval) = Convert : r0_30 +# 1035| r0_32(glval) = FunctionAddress[operator()] : +# 1035| r0_33(float) = Constant[1.0] : +# 1035| r0_34(char) = Call : func:r0_32, this:r0_31, 0:r0_33 +# 1035| mu0_35(unknown) = ^CallSideEffect : ~mu0_2 +# 1035| v0_36(void) = ^BufferReadSideEffect[-1] : &:r0_31, ~mu0_2 +# 1035| mu0_37(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_31 +# 1036| r0_38(glval) = VariableAddress[lambda_val] : +# 1036| mu0_39(decltype([...](...){...})) = Uninitialized[lambda_val] : &:r0_38 +# 1036| r0_40(glval) = FunctionAddress[(constructor)] : +# 1036| r0_41(glval) = VariableAddress[#temp1036:21] : +# 1036| mu0_42(decltype([...](...){...})) = Uninitialized[#temp1036:21] : &:r0_41 +# 1036| r0_43(glval) = FieldAddress[s] : r0_41 +#-----| r0_44(glval) = FunctionAddress[String] : +#-----| v0_45(void) = Call : func:r0_44, this:r0_43 +#-----| mu0_46(unknown) = ^CallSideEffect : ~mu0_2 +#-----| mu0_47(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_43 +# 1036| r0_48(glval) = FieldAddress[x] : r0_41 +#-----| r0_49(glval) = VariableAddress[x] : +#-----| r0_50(int) = Load : &:r0_49, ~mu0_2 +#-----| mu0_51(int) = Store : &:r0_48, r0_50 +# 1036| r0_52(decltype([...](...){...})) = Load : &:r0_41, ~mu0_2 +# 1036| r0_53(lambda [] type at line 1036, col. 21 &) = CopyValue : r0_52 +# 1036| v0_54(void) = Call : func:r0_40, this:r0_38, 0:r0_53 +# 1036| mu0_55(unknown) = ^CallSideEffect : ~mu0_2 +# 1036| mu0_56(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_38 +# 1036| v0_57(void) = ^BufferReadSideEffect[0] : &:r0_53, ~mu0_2 +# 1036| mu0_58(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_53 +# 1037| r0_59(glval) = VariableAddress[lambda_val] : +# 1037| r0_60(glval) = Convert : r0_59 +# 1037| r0_61(glval) = FunctionAddress[operator()] : +# 1037| r0_62(float) = Constant[2.0] : +# 1037| r0_63(char) = Call : func:r0_61, this:r0_60, 0:r0_62 +# 1037| mu0_64(unknown) = ^CallSideEffect : ~mu0_2 +# 1037| v0_65(void) = ^BufferReadSideEffect[-1] : &:r0_60, ~mu0_2 +# 1037| mu0_66(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_60 +# 1038| r0_67(glval) = VariableAddress[lambda_ref_explicit] : +# 1038| r0_68(glval) = VariableAddress[#temp1038:30] : +# 1038| mu0_69(decltype([...](...){...})) = Uninitialized[#temp1038:30] : &:r0_68 +# 1038| r0_70(glval) = FieldAddress[s] : r0_68 +# 1038| r0_71(glval) = VariableAddress[s] : +# 1038| r0_72(String &) = Load : &:r0_71, ~mu0_2 +# 1038| r0_73(glval) = CopyValue : r0_72 +# 1038| r0_74(String &) = CopyValue : r0_73 +# 1038| mu0_75(String &) = Store : &:r0_70, r0_74 +# 1038| r0_76(decltype([...](...){...})) = Load : &:r0_68, ~mu0_2 +# 1038| mu0_77(decltype([...](...){...})) = Store : &:r0_67, r0_76 +# 1039| r0_78(glval) = VariableAddress[lambda_ref_explicit] : +# 1039| r0_79(glval) = Convert : r0_78 +# 1039| r0_80(glval) = FunctionAddress[operator()] : +# 1039| r0_81(float) = Constant[3.0] : +# 1039| r0_82(char) = Call : func:r0_80, this:r0_79, 0:r0_81 +# 1039| mu0_83(unknown) = ^CallSideEffect : ~mu0_2 +# 1039| v0_84(void) = ^BufferReadSideEffect[-1] : &:r0_79, ~mu0_2 +# 1039| mu0_85(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_79 +# 1040| r0_86(glval) = VariableAddress[lambda_val_explicit] : +# 1040| mu0_87(decltype([...](...){...})) = Uninitialized[lambda_val_explicit] : &:r0_86 +# 1040| r0_88(glval) = FunctionAddress[(constructor)] : +# 1040| r0_89(glval) = VariableAddress[#temp1040:30] : +# 1040| mu0_90(decltype([...](...){...})) = Uninitialized[#temp1040:30] : &:r0_89 +# 1040| r0_91(glval) = FieldAddress[s] : r0_89 +#-----| r0_92(glval) = FunctionAddress[String] : +#-----| v0_93(void) = Call : func:r0_92, this:r0_91 +#-----| mu0_94(unknown) = ^CallSideEffect : ~mu0_2 +#-----| mu0_95(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_91 +# 1040| r0_96(decltype([...](...){...})) = Load : &:r0_89, ~mu0_2 +# 1040| r0_97(lambda [] type at line 1040, col. 30 &) = CopyValue : r0_96 +# 1040| v0_98(void) = Call : func:r0_88, this:r0_86, 0:r0_97 +# 1040| mu0_99(unknown) = ^CallSideEffect : ~mu0_2 +# 1040| mu0_100(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_86 +# 1040| v0_101(void) = ^BufferReadSideEffect[0] : &:r0_97, ~mu0_2 +# 1040| mu0_102(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_97 +# 1041| r0_103(glval) = VariableAddress[lambda_val_explicit] : +# 1041| r0_104(glval) = Convert : r0_103 +# 1041| r0_105(glval) = FunctionAddress[operator()] : +# 1041| r0_106(float) = Constant[4.0] : +# 1041| r0_107(char) = Call : func:r0_105, this:r0_104, 0:r0_106 +# 1041| mu0_108(unknown) = ^CallSideEffect : ~mu0_2 +# 1041| v0_109(void) = ^BufferReadSideEffect[-1] : &:r0_104, ~mu0_2 +# 1041| mu0_110(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_104 +# 1042| r0_111(glval) = VariableAddress[lambda_mixed_explicit] : +# 1042| r0_112(glval) = VariableAddress[#temp1042:32] : +# 1042| mu0_113(decltype([...](...){...})) = Uninitialized[#temp1042:32] : &:r0_112 +# 1042| r0_114(glval) = FieldAddress[s] : r0_112 +# 1042| r0_115(glval) = VariableAddress[s] : +# 1042| r0_116(String &) = Load : &:r0_115, ~mu0_2 +# 1042| r0_117(glval) = CopyValue : r0_116 +# 1042| r0_118(String &) = CopyValue : r0_117 +# 1042| mu0_119(String &) = Store : &:r0_114, r0_118 +# 1042| r0_120(glval) = FieldAddress[x] : r0_112 +# 1042| r0_121(glval) = VariableAddress[x] : +# 1042| r0_122(int) = Load : &:r0_121, ~mu0_2 +# 1042| mu0_123(int) = Store : &:r0_120, r0_122 +# 1042| r0_124(decltype([...](...){...})) = Load : &:r0_112, ~mu0_2 +# 1042| mu0_125(decltype([...](...){...})) = Store : &:r0_111, r0_124 +# 1043| r0_126(glval) = VariableAddress[lambda_mixed_explicit] : +# 1043| r0_127(glval) = Convert : r0_126 +# 1043| r0_128(glval) = FunctionAddress[operator()] : +# 1043| r0_129(float) = Constant[5.0] : +# 1043| r0_130(char) = Call : func:r0_128, this:r0_127, 0:r0_129 +# 1043| mu0_131(unknown) = ^CallSideEffect : ~mu0_2 +# 1043| v0_132(void) = ^BufferReadSideEffect[-1] : &:r0_127, ~mu0_2 +# 1043| mu0_133(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_127 +# 1044| r0_134(glval) = VariableAddress[r] : +# 1044| r0_135(glval) = VariableAddress[x] : +# 1044| r0_136(int) = Load : &:r0_135, ~mu0_2 +# 1044| r0_137(int) = Constant[1] : +# 1044| r0_138(int) = Sub : r0_136, r0_137 +# 1044| mu0_139(int) = Store : &:r0_134, r0_138 +# 1045| r0_140(glval) = VariableAddress[lambda_inits] : +# 1045| r0_141(glval) = VariableAddress[#temp1045:23] : +# 1045| mu0_142(decltype([...](...){...})) = Uninitialized[#temp1045:23] : &:r0_141 +# 1045| r0_143(glval) = FieldAddress[s] : r0_141 +# 1045| r0_144(glval) = VariableAddress[s] : +# 1045| r0_145(String &) = Load : &:r0_144, ~mu0_2 +# 1045| r0_146(glval) = CopyValue : r0_145 +# 1045| r0_147(String &) = CopyValue : r0_146 +# 1045| mu0_148(String &) = Store : &:r0_143, r0_147 +# 1045| r0_149(glval) = FieldAddress[x] : r0_141 +# 1045| r0_150(glval) = VariableAddress[x] : +# 1045| r0_151(int) = Load : &:r0_150, ~mu0_2 +# 1045| mu0_152(int) = Store : &:r0_149, r0_151 +# 1045| r0_153(glval) = FieldAddress[i] : r0_141 +# 1045| r0_154(glval) = VariableAddress[x] : +# 1045| r0_155(int) = Load : &:r0_154, ~mu0_2 +# 1045| r0_156(int) = Constant[1] : +# 1045| r0_157(int) = Add : r0_155, r0_156 +# 1045| mu0_158(int) = Store : &:r0_153, r0_157 +# 1045| r0_159(glval) = FieldAddress[j] : r0_141 +# 1045| r0_160(glval) = VariableAddress[r] : +# 1045| r0_161(int &) = CopyValue : r0_160 +# 1045| mu0_162(int &) = Store : &:r0_159, r0_161 +# 1045| r0_163(decltype([...](...){...})) = Load : &:r0_141, ~mu0_2 +# 1045| mu0_164(decltype([...](...){...})) = Store : &:r0_140, r0_163 +# 1046| r0_165(glval) = VariableAddress[lambda_inits] : +# 1046| r0_166(glval) = Convert : r0_165 +# 1046| r0_167(glval) = FunctionAddress[operator()] : +# 1046| r0_168(float) = Constant[6.0] : +# 1046| r0_169(char) = Call : func:r0_167, this:r0_166, 0:r0_168 +# 1046| mu0_170(unknown) = ^CallSideEffect : ~mu0_2 +# 1046| v0_171(void) = ^BufferReadSideEffect[-1] : &:r0_166, ~mu0_2 +# 1046| mu0_172(decltype([...](...){...})) = ^IndirectMayWriteSideEffect[-1] : &:r0_166 +# 1047| v0_173(void) = NoOp : +# 1031| v0_174(void) = ReturnIndirection : &:r0_7, ~mu0_2 +# 1031| v0_175(void) = ReturnVoid : +# 1031| v0_176(void) = UnmodeledUse : mu* +# 1031| v0_177(void) = AliasedUse : ~mu0_2 +# 1031| v0_178(void) = ExitFunction : # 1032| void (void Lambda(int, String const&))::(lambda [] type at line 1032, col. 23)::(constructor)((void Lambda(int, String const&))::(lambda [] type at line 1032, col. 23)&&) # 1032| Block 0 @@ -4902,7 +5193,8 @@ ir.cpp: #-----| v0_9(void) = ReturnIndirection : &:r0_6, ~mu0_2 # 1032| v0_10(void) = ReturnVoid : # 1032| v0_11(void) = UnmodeledUse : mu* -# 1032| v0_12(void) = ExitFunction : +# 1032| v0_12(void) = AliasedUse : ~mu0_2 +# 1032| v0_13(void) = ExitFunction : # 1032| char (void Lambda(int, String const&))::(lambda [] type at line 1032, col. 23)::operator()(float) const # 1032| Block 0 @@ -4918,7 +5210,8 @@ ir.cpp: # 1032| r0_9(glval) = VariableAddress[#return] : # 1032| v0_10(void) = ReturnValue : &:r0_9, ~mu0_2 # 1032| v0_11(void) = UnmodeledUse : mu* -# 1032| v0_12(void) = ExitFunction : +# 1032| v0_12(void) = AliasedUse : ~mu0_2 +# 1032| v0_13(void) = ExitFunction : # 1032| char(* (void Lambda(int, String const&))::(lambda [] type at line 1032, col. 23)::operator char (*)(float)() const)(float) # 1032| Block 0 @@ -4932,7 +5225,8 @@ ir.cpp: # 1032| r0_7(glval<..(*)(..)>) = VariableAddress[#return] : # 1032| v0_8(void) = ReturnValue : &:r0_7, ~mu0_2 # 1032| v0_9(void) = UnmodeledUse : mu* -# 1032| v0_10(void) = ExitFunction : +# 1032| v0_10(void) = AliasedUse : ~mu0_2 +# 1032| v0_11(void) = ExitFunction : # 1034| char (void Lambda(int, String const&))::(lambda [] type at line 1034, col. 21)::operator()(float) const # 1034| Block 0 @@ -4946,22 +5240,24 @@ ir.cpp: #-----| r0_7(lambda [] type at line 1034, col. 21 *) = CopyValue : r0_3 #-----| r0_8(glval) = FieldAddress[s] : r0_7 #-----| r0_9(String &) = Load : &:r0_8, ~mu0_2 -# 1034| r0_10(glval) = FunctionAddress[c_str] : -# 1034| r0_11(char *) = Call : func:r0_10, this:r0_9 -# 1034| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 -# 1034| v0_13(void) = ^IndirectReadSideEffect[-1] : &:r0_9, ~mu0_2 -# 1034| mu0_14(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_9 -#-----| r0_15(lambda [] type at line 1034, col. 21 *) = CopyValue : r0_3 -#-----| r0_16(glval) = FieldAddress[x] : r0_15 -#-----| r0_17(int &) = Load : &:r0_16, ~mu0_2 -# 1034| r0_18(int) = Load : &:r0_17, ~mu0_2 -# 1034| r0_19(glval) = PointerAdd[1] : r0_11, r0_18 -# 1034| r0_20(char) = Load : &:r0_19, ~mu0_2 -# 1034| mu0_21(char) = Store : &:r0_6, r0_20 -# 1034| r0_22(glval) = VariableAddress[#return] : -# 1034| v0_23(void) = ReturnValue : &:r0_22, ~mu0_2 -# 1034| v0_24(void) = UnmodeledUse : mu* -# 1034| v0_25(void) = ExitFunction : +# 1034| r0_10(glval) = CopyValue : r0_9 +# 1034| r0_11(glval) = FunctionAddress[c_str] : +# 1034| r0_12(char *) = Call : func:r0_11, this:r0_10 +# 1034| mu0_13(unknown) = ^CallSideEffect : ~mu0_2 +# 1034| v0_14(void) = ^BufferReadSideEffect[-1] : &:r0_10, ~mu0_2 +# 1034| mu0_15(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_10 +#-----| r0_16(lambda [] type at line 1034, col. 21 *) = CopyValue : r0_3 +#-----| r0_17(glval) = FieldAddress[x] : r0_16 +#-----| r0_18(int &) = Load : &:r0_17, ~mu0_2 +# 1034| r0_19(int) = Load : &:r0_18, ~mu0_2 +# 1034| r0_20(glval) = PointerAdd[1] : r0_12, r0_19 +# 1034| r0_21(char) = Load : &:r0_20, ~mu0_2 +# 1034| mu0_22(char) = Store : &:r0_6, r0_21 +# 1034| r0_23(glval) = VariableAddress[#return] : +# 1034| v0_24(void) = ReturnValue : &:r0_23, ~mu0_2 +# 1034| v0_25(void) = UnmodeledUse : mu* +# 1034| v0_26(void) = AliasedUse : ~mu0_2 +# 1034| v0_27(void) = ExitFunction : # 1036| void (void Lambda(int, String const&))::(lambda [] type at line 1036, col. 21)::~() # 1036| Block 0 @@ -4976,7 +5272,8 @@ ir.cpp: # 1036| mu0_8(unknown) = ^CallSideEffect : ~mu0_2 # 1036| v0_9(void) = ReturnVoid : # 1036| v0_10(void) = UnmodeledUse : mu* -# 1036| v0_11(void) = ExitFunction : +# 1036| v0_11(void) = AliasedUse : ~mu0_2 +# 1036| v0_12(void) = ExitFunction : # 1036| char (void Lambda(int, String const&))::(lambda [] type at line 1036, col. 21)::operator()(float) const # 1036| Block 0 @@ -4992,7 +5289,7 @@ ir.cpp: # 1036| r0_9(glval) = FunctionAddress[c_str] : # 1036| r0_10(char *) = Call : func:r0_9, this:r0_8 # 1036| mu0_11(unknown) = ^CallSideEffect : ~mu0_2 -#-----| v0_12(void) = ^IndirectReadSideEffect[-1] : &:r0_8, ~mu0_2 +#-----| v0_12(void) = ^BufferReadSideEffect[-1] : &:r0_8, ~mu0_2 #-----| mu0_13(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 #-----| r0_14(lambda [] type at line 1036, col. 21 *) = CopyValue : r0_3 #-----| r0_15(glval) = FieldAddress[x] : r0_14 @@ -5003,7 +5300,8 @@ ir.cpp: # 1036| r0_20(glval) = VariableAddress[#return] : # 1036| v0_21(void) = ReturnValue : &:r0_20, ~mu0_2 # 1036| v0_22(void) = UnmodeledUse : mu* -# 1036| v0_23(void) = ExitFunction : +# 1036| v0_23(void) = AliasedUse : ~mu0_2 +# 1036| v0_24(void) = ExitFunction : # 1038| char (void Lambda(int, String const&))::(lambda [] type at line 1038, col. 30)::operator()(float) const # 1038| Block 0 @@ -5017,39 +5315,43 @@ ir.cpp: #-----| r0_7(lambda [] type at line 1038, col. 30 *) = CopyValue : r0_3 #-----| r0_8(glval) = FieldAddress[s] : r0_7 #-----| r0_9(String &) = Load : &:r0_8, ~mu0_2 -# 1038| r0_10(glval) = FunctionAddress[c_str] : -# 1038| r0_11(char *) = Call : func:r0_10, this:r0_9 -# 1038| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 -# 1038| v0_13(void) = ^IndirectReadSideEffect[-1] : &:r0_9, ~mu0_2 -# 1038| mu0_14(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_9 -# 1038| r0_15(int) = Constant[0] : -# 1038| r0_16(glval) = PointerAdd[1] : r0_11, r0_15 -# 1038| r0_17(char) = Load : &:r0_16, ~mu0_2 -# 1038| mu0_18(char) = Store : &:r0_6, r0_17 -# 1038| r0_19(glval) = VariableAddress[#return] : -# 1038| v0_20(void) = ReturnValue : &:r0_19, ~mu0_2 -# 1038| v0_21(void) = UnmodeledUse : mu* -# 1038| v0_22(void) = ExitFunction : +# 1038| r0_10(glval) = CopyValue : r0_9 +# 1038| r0_11(glval) = FunctionAddress[c_str] : +# 1038| r0_12(char *) = Call : func:r0_11, this:r0_10 +# 1038| mu0_13(unknown) = ^CallSideEffect : ~mu0_2 +# 1038| v0_14(void) = ^BufferReadSideEffect[-1] : &:r0_10, ~mu0_2 +# 1038| mu0_15(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_10 +# 1038| r0_16(int) = Constant[0] : +# 1038| r0_17(glval) = PointerAdd[1] : r0_12, r0_16 +# 1038| r0_18(char) = Load : &:r0_17, ~mu0_2 +# 1038| mu0_19(char) = Store : &:r0_6, r0_18 +# 1038| r0_20(glval) = VariableAddress[#return] : +# 1038| v0_21(void) = ReturnValue : &:r0_20, ~mu0_2 +# 1038| v0_22(void) = UnmodeledUse : mu* +# 1038| v0_23(void) = AliasedUse : ~mu0_2 +# 1038| v0_24(void) = ExitFunction : # 1040| void (void Lambda(int, String const&))::(lambda [] type at line 1040, col. 30)::(constructor)((void Lambda(int, String const&))::(lambda [] type at line 1040, col. 30)&&) # 1040| Block 0 -# 1040| v0_0(void) = EnterFunction : -# 1040| mu0_1(unknown) = AliasedDefinition : -# 1040| mu0_2(unknown) = UnmodeledDefinition : -# 1040| r0_3(glval) = InitializeThis : -#-----| r0_4(glval) = VariableAddress[p#0] : -#-----| mu0_5(lambda [] type at line 1040, col. 30 &&) = InitializeParameter[p#0] : &:r0_4 -#-----| r0_6(lambda [] type at line 1040, col. 30 &&) = Load : &:r0_4, ~mu0_5 -#-----| mu0_7(unknown) = InitializeIndirection[p#0] : &:r0_6 -# 1040| r0_8(glval) = FieldAddress[s] : r0_3 -# 1040| r0_9(glval) = FunctionAddress[String] : -# 1040| v0_10(void) = Call : func:r0_9, this:r0_8 -# 1040| mu0_11(unknown) = ^CallSideEffect : ~mu0_2 -# 1040| v0_12(void) = NoOp : -#-----| v0_13(void) = ReturnIndirection : &:r0_6, ~mu0_2 -# 1040| v0_14(void) = ReturnVoid : -# 1040| v0_15(void) = UnmodeledUse : mu* -# 1040| v0_16(void) = ExitFunction : +# 1040| v0_0(void) = EnterFunction : +# 1040| mu0_1(unknown) = AliasedDefinition : +# 1040| mu0_2(unknown) = UnmodeledDefinition : +# 1040| r0_3(glval) = InitializeThis : +#-----| r0_4(glval) = VariableAddress[p#0] : +#-----| mu0_5(lambda [] type at line 1040, col. 30 &&) = InitializeParameter[p#0] : &:r0_4 +#-----| r0_6(lambda [] type at line 1040, col. 30 &&) = Load : &:r0_4, ~mu0_5 +#-----| mu0_7(unknown) = InitializeIndirection[p#0] : &:r0_6 +# 1040| r0_8(glval) = FieldAddress[s] : r0_3 +# 1040| r0_9(glval) = FunctionAddress[String] : +# 1040| v0_10(void) = Call : func:r0_9, this:r0_8 +# 1040| mu0_11(unknown) = ^CallSideEffect : ~mu0_2 +# 1040| mu0_12(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 +# 1040| v0_13(void) = NoOp : +#-----| v0_14(void) = ReturnIndirection : &:r0_6, ~mu0_2 +# 1040| v0_15(void) = ReturnVoid : +# 1040| v0_16(void) = UnmodeledUse : mu* +# 1040| v0_17(void) = AliasedUse : ~mu0_2 +# 1040| v0_18(void) = ExitFunction : # 1040| void (void Lambda(int, String const&))::(lambda [] type at line 1040, col. 30)::~() # 1040| Block 0 @@ -5064,7 +5366,8 @@ ir.cpp: # 1040| mu0_8(unknown) = ^CallSideEffect : ~mu0_2 # 1040| v0_9(void) = ReturnVoid : # 1040| v0_10(void) = UnmodeledUse : mu* -# 1040| v0_11(void) = ExitFunction : +# 1040| v0_11(void) = AliasedUse : ~mu0_2 +# 1040| v0_12(void) = ExitFunction : # 1040| char (void Lambda(int, String const&))::(lambda [] type at line 1040, col. 30)::operator()(float) const # 1040| Block 0 @@ -5080,7 +5383,7 @@ ir.cpp: # 1040| r0_9(glval) = FunctionAddress[c_str] : # 1040| r0_10(char *) = Call : func:r0_9, this:r0_8 # 1040| mu0_11(unknown) = ^CallSideEffect : ~mu0_2 -#-----| v0_12(void) = ^IndirectReadSideEffect[-1] : &:r0_8, ~mu0_2 +#-----| v0_12(void) = ^BufferReadSideEffect[-1] : &:r0_8, ~mu0_2 #-----| mu0_13(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 # 1040| r0_14(int) = Constant[0] : # 1040| r0_15(glval) = PointerAdd[1] : r0_10, r0_14 @@ -5089,7 +5392,8 @@ ir.cpp: # 1040| r0_18(glval) = VariableAddress[#return] : # 1040| v0_19(void) = ReturnValue : &:r0_18, ~mu0_2 # 1040| v0_20(void) = UnmodeledUse : mu* -# 1040| v0_21(void) = ExitFunction : +# 1040| v0_21(void) = AliasedUse : ~mu0_2 +# 1040| v0_22(void) = ExitFunction : # 1042| char (void Lambda(int, String const&))::(lambda [] type at line 1042, col. 32)::operator()(float) const # 1042| Block 0 @@ -5103,21 +5407,23 @@ ir.cpp: #-----| r0_7(lambda [] type at line 1042, col. 32 *) = CopyValue : r0_3 #-----| r0_8(glval) = FieldAddress[s] : r0_7 #-----| r0_9(String &) = Load : &:r0_8, ~mu0_2 -# 1042| r0_10(glval) = FunctionAddress[c_str] : -# 1042| r0_11(char *) = Call : func:r0_10, this:r0_9 -# 1042| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 -# 1042| v0_13(void) = ^IndirectReadSideEffect[-1] : &:r0_9, ~mu0_2 -# 1042| mu0_14(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_9 -#-----| r0_15(lambda [] type at line 1042, col. 32 *) = CopyValue : r0_3 -#-----| r0_16(glval) = FieldAddress[x] : r0_15 -#-----| r0_17(int) = Load : &:r0_16, ~mu0_2 -# 1042| r0_18(glval) = PointerAdd[1] : r0_11, r0_17 -# 1042| r0_19(char) = Load : &:r0_18, ~mu0_2 -# 1042| mu0_20(char) = Store : &:r0_6, r0_19 -# 1042| r0_21(glval) = VariableAddress[#return] : -# 1042| v0_22(void) = ReturnValue : &:r0_21, ~mu0_2 -# 1042| v0_23(void) = UnmodeledUse : mu* -# 1042| v0_24(void) = ExitFunction : +# 1042| r0_10(glval) = CopyValue : r0_9 +# 1042| r0_11(glval) = FunctionAddress[c_str] : +# 1042| r0_12(char *) = Call : func:r0_11, this:r0_10 +# 1042| mu0_13(unknown) = ^CallSideEffect : ~mu0_2 +# 1042| v0_14(void) = ^BufferReadSideEffect[-1] : &:r0_10, ~mu0_2 +# 1042| mu0_15(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_10 +#-----| r0_16(lambda [] type at line 1042, col. 32 *) = CopyValue : r0_3 +#-----| r0_17(glval) = FieldAddress[x] : r0_16 +#-----| r0_18(int) = Load : &:r0_17, ~mu0_2 +# 1042| r0_19(glval) = PointerAdd[1] : r0_12, r0_18 +# 1042| r0_20(char) = Load : &:r0_19, ~mu0_2 +# 1042| mu0_21(char) = Store : &:r0_6, r0_20 +# 1042| r0_22(glval) = VariableAddress[#return] : +# 1042| v0_23(void) = ReturnValue : &:r0_22, ~mu0_2 +# 1042| v0_24(void) = UnmodeledUse : mu* +# 1042| v0_25(void) = AliasedUse : ~mu0_2 +# 1042| v0_26(void) = ExitFunction : # 1045| char (void Lambda(int, String const&))::(lambda [] type at line 1045, col. 23)::operator()(float) const # 1045| Block 0 @@ -5131,30 +5437,32 @@ ir.cpp: #-----| r0_7(lambda [] type at line 1045, col. 23 *) = CopyValue : r0_3 #-----| r0_8(glval) = FieldAddress[s] : r0_7 #-----| r0_9(String &) = Load : &:r0_8, ~mu0_2 -# 1045| r0_10(glval) = FunctionAddress[c_str] : -# 1045| r0_11(char *) = Call : func:r0_10, this:r0_9 -# 1045| mu0_12(unknown) = ^CallSideEffect : ~mu0_2 -# 1045| v0_13(void) = ^IndirectReadSideEffect[-1] : &:r0_9, ~mu0_2 -# 1045| mu0_14(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_9 -#-----| r0_15(lambda [] type at line 1045, col. 23 *) = CopyValue : r0_3 -#-----| r0_16(glval) = FieldAddress[x] : r0_15 -#-----| r0_17(int) = Load : &:r0_16, ~mu0_2 -#-----| r0_18(lambda [] type at line 1045, col. 23 *) = CopyValue : r0_3 -# 1045| r0_19(glval) = FieldAddress[i] : r0_18 -# 1045| r0_20(int) = Load : &:r0_19, ~mu0_2 -# 1045| r0_21(int) = Add : r0_17, r0_20 -#-----| r0_22(lambda [] type at line 1045, col. 23 *) = CopyValue : r0_3 -# 1045| r0_23(glval) = FieldAddress[j] : r0_22 -# 1045| r0_24(int &) = Load : &:r0_23, ~mu0_2 -# 1045| r0_25(int) = Load : &:r0_24, ~mu0_2 -# 1045| r0_26(int) = Sub : r0_21, r0_25 -# 1045| r0_27(glval) = PointerAdd[1] : r0_11, r0_26 -# 1045| r0_28(char) = Load : &:r0_27, ~mu0_2 -# 1045| mu0_29(char) = Store : &:r0_6, r0_28 -# 1045| r0_30(glval) = VariableAddress[#return] : -# 1045| v0_31(void) = ReturnValue : &:r0_30, ~mu0_2 -# 1045| v0_32(void) = UnmodeledUse : mu* -# 1045| v0_33(void) = ExitFunction : +# 1045| r0_10(glval) = CopyValue : r0_9 +# 1045| r0_11(glval) = FunctionAddress[c_str] : +# 1045| r0_12(char *) = Call : func:r0_11, this:r0_10 +# 1045| mu0_13(unknown) = ^CallSideEffect : ~mu0_2 +# 1045| v0_14(void) = ^BufferReadSideEffect[-1] : &:r0_10, ~mu0_2 +# 1045| mu0_15(String) = ^IndirectMayWriteSideEffect[-1] : &:r0_10 +#-----| r0_16(lambda [] type at line 1045, col. 23 *) = CopyValue : r0_3 +#-----| r0_17(glval) = FieldAddress[x] : r0_16 +#-----| r0_18(int) = Load : &:r0_17, ~mu0_2 +#-----| r0_19(lambda [] type at line 1045, col. 23 *) = CopyValue : r0_3 +# 1045| r0_20(glval) = FieldAddress[i] : r0_19 +# 1045| r0_21(int) = Load : &:r0_20, ~mu0_2 +# 1045| r0_22(int) = Add : r0_18, r0_21 +#-----| r0_23(lambda [] type at line 1045, col. 23 *) = CopyValue : r0_3 +# 1045| r0_24(glval) = FieldAddress[j] : r0_23 +# 1045| r0_25(int &) = Load : &:r0_24, ~mu0_2 +# 1045| r0_26(int) = Load : &:r0_25, ~mu0_2 +# 1045| r0_27(int) = Sub : r0_22, r0_26 +# 1045| r0_28(glval) = PointerAdd[1] : r0_12, r0_27 +# 1045| r0_29(char) = Load : &:r0_28, ~mu0_2 +# 1045| mu0_30(char) = Store : &:r0_6, r0_29 +# 1045| r0_31(glval) = VariableAddress[#return] : +# 1045| v0_32(void) = ReturnValue : &:r0_31, ~mu0_2 +# 1045| v0_33(void) = UnmodeledUse : mu* +# 1045| v0_34(void) = AliasedUse : ~mu0_2 +# 1045| v0_35(void) = ExitFunction : # 1068| void RangeBasedFor(vector const&) # 1068| Block 0 @@ -5168,153 +5476,166 @@ ir.cpp: # 1069| r0_7(glval &>) = VariableAddress[(__range)] : # 1069| r0_8(glval &>) = VariableAddress[v] : # 1069| r0_9(vector &) = Load : &:r0_8, ~mu0_2 -# 1069| mu0_10(vector &) = Store : &:r0_7, r0_9 -# 1069| r0_11(glval) = VariableAddress[(__begin)] : -#-----| r0_12(glval &>) = VariableAddress[(__range)] : -#-----| r0_13(vector &) = Load : &:r0_12, ~mu0_2 -# 1069| r0_14(glval) = FunctionAddress[begin] : -# 1069| r0_15(iterator) = Call : func:r0_14, this:r0_13 -# 1069| mu0_16(unknown) = ^CallSideEffect : ~mu0_2 -#-----| v0_17(void) = ^IndirectReadSideEffect[-1] : &:r0_13, ~mu0_2 -#-----| mu0_18(vector) = ^IndirectMayWriteSideEffect[-1] : &:r0_13 -# 1069| mu0_19(iterator) = Store : &:r0_11, r0_15 -# 1069| r0_20(glval) = VariableAddress[(__end)] : -#-----| r0_21(glval &>) = VariableAddress[(__range)] : -#-----| r0_22(vector &) = Load : &:r0_21, ~mu0_2 -# 1069| r0_23(glval) = FunctionAddress[end] : -# 1069| r0_24(iterator) = Call : func:r0_23, this:r0_22 -# 1069| mu0_25(unknown) = ^CallSideEffect : ~mu0_2 -#-----| v0_26(void) = ^IndirectReadSideEffect[-1] : &:r0_22, ~mu0_2 -#-----| mu0_27(vector) = ^IndirectMayWriteSideEffect[-1] : &:r0_22 -# 1069| mu0_28(iterator) = Store : &:r0_20, r0_24 -#-----| Goto -> Block 5 +# 1069| r0_10(glval>) = CopyValue : r0_9 +# 1069| r0_11(vector &) = CopyValue : r0_10 +# 1069| mu0_12(vector &) = Store : &:r0_7, r0_11 +# 1069| r0_13(glval) = VariableAddress[(__begin)] : +#-----| r0_14(glval &>) = VariableAddress[(__range)] : +#-----| r0_15(vector &) = Load : &:r0_14, ~mu0_2 +#-----| r0_16(glval>) = CopyValue : r0_15 +# 1069| r0_17(glval) = FunctionAddress[begin] : +# 1069| r0_18(iterator) = Call : func:r0_17, this:r0_16 +# 1069| mu0_19(unknown) = ^CallSideEffect : ~mu0_2 +#-----| v0_20(void) = ^BufferReadSideEffect[-1] : &:r0_16, ~mu0_2 +#-----| mu0_21(vector) = ^IndirectMayWriteSideEffect[-1] : &:r0_16 +# 1069| mu0_22(iterator) = Store : &:r0_13, r0_18 +# 1069| r0_23(glval) = VariableAddress[(__end)] : +#-----| r0_24(glval &>) = VariableAddress[(__range)] : +#-----| r0_25(vector &) = Load : &:r0_24, ~mu0_2 +#-----| r0_26(glval>) = CopyValue : r0_25 +# 1069| r0_27(glval) = FunctionAddress[end] : +# 1069| r0_28(iterator) = Call : func:r0_27, this:r0_26 +# 1069| mu0_29(unknown) = ^CallSideEffect : ~mu0_2 +#-----| v0_30(void) = ^BufferReadSideEffect[-1] : &:r0_26, ~mu0_2 +#-----| mu0_31(vector) = ^IndirectMayWriteSideEffect[-1] : &:r0_26 +# 1069| mu0_32(iterator) = Store : &:r0_23, r0_28 +#-----| Goto -> Block 6 #-----| Block 1 #-----| r1_0(glval) = VariableAddress[(__begin)] : -# 1075| r1_1(glval) = FunctionAddress[operator++] : -# 1075| r1_2(iterator &) = Call : func:r1_1, this:r1_0 -# 1075| mu1_3(unknown) = ^CallSideEffect : ~mu0_2 -#-----| v1_4(void) = ^IndirectReadSideEffect[-1] : &:r1_0, ~mu0_2 -#-----| mu1_5(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r1_0 -#-----| Goto (back edge) -> Block 10 - -# 1075| Block 2 -# 1075| r2_0(glval) = VariableAddress[e] : -#-----| r2_1(glval) = VariableAddress[(__begin)] : -#-----| r2_2(glval) = Convert : r2_1 -# 1075| r2_3(glval) = FunctionAddress[operator*] : -# 1075| r2_4(int &) = Call : func:r2_3, this:r2_2 -# 1075| mu2_5(unknown) = ^CallSideEffect : ~mu0_2 -#-----| v2_6(void) = ^IndirectReadSideEffect[-1] : &:r2_2, ~mu0_2 -#-----| mu2_7(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2_2 -# 1075| r2_8(glval) = Convert : r2_4 -# 1075| mu2_9(int &) = Store : &:r2_0, r2_8 -# 1076| r2_10(glval) = VariableAddress[e] : -# 1076| r2_11(int &) = Load : &:r2_10, ~mu0_2 -# 1076| r2_12(int) = Load : &:r2_11, ~mu0_2 -# 1076| r2_13(int) = Constant[5] : -# 1076| r2_14(bool) = CompareLT : r2_12, r2_13 -# 1076| v2_15(void) = ConditionalBranch : r2_14 -#-----| False -> Block 1 +#-----| r1_1(glval) = Convert : r1_0 +# 1075| r1_2(glval) = FunctionAddress[operator!=] : +#-----| r1_3(glval) = VariableAddress[(__end)] : +#-----| r1_4(iterator) = Load : &:r1_3, ~mu0_2 +# 1075| r1_5(bool) = Call : func:r1_2, this:r1_1, 0:r1_4 +# 1075| mu1_6(unknown) = ^CallSideEffect : ~mu0_2 +#-----| v1_7(void) = ^BufferReadSideEffect[-1] : &:r1_1, ~mu0_2 +#-----| mu1_8(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r1_1 +# 1075| v1_9(void) = ConditionalBranch : r1_5 +#-----| False -> Block 5 #-----| True -> Block 3 -# 1077| Block 3 -# 1077| v3_0(void) = NoOp : -#-----| Goto -> Block 4 +#-----| Block 2 +#-----| r2_0(glval) = VariableAddress[(__begin)] : +# 1075| r2_1(glval) = FunctionAddress[operator++] : +# 1075| r2_2(iterator &) = Call : func:r2_1, this:r2_0 +# 1075| mu2_3(unknown) = ^CallSideEffect : ~mu0_2 +#-----| v2_4(void) = ^BufferReadSideEffect[-1] : &:r2_0, ~mu0_2 +#-----| mu2_5(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r2_0 +# 1075| r2_6(glval) = CopyValue : r2_2 +#-----| Goto (back edge) -> Block 1 -# 1079| Block 4 -# 1079| v4_0(void) = NoOp : -# 1080| v4_1(void) = NoOp : -# 1068| v4_2(void) = ReturnIndirection : &:r0_5, ~mu0_2 -# 1068| v4_3(void) = ReturnVoid : -# 1068| v4_4(void) = UnmodeledUse : mu* -# 1068| v4_5(void) = ExitFunction : +# 1075| Block 3 +# 1075| r3_0(glval) = VariableAddress[e] : +#-----| r3_1(glval) = VariableAddress[(__begin)] : +#-----| r3_2(glval) = Convert : r3_1 +# 1075| r3_3(glval) = FunctionAddress[operator*] : +# 1075| r3_4(int &) = Call : func:r3_3, this:r3_2 +# 1075| mu3_5(unknown) = ^CallSideEffect : ~mu0_2 +#-----| v3_6(void) = ^BufferReadSideEffect[-1] : &:r3_2, ~mu0_2 +#-----| mu3_7(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r3_2 +# 1075| r3_8(glval) = CopyValue : r3_4 +# 1075| r3_9(glval) = Convert : r3_8 +# 1075| r3_10(int &) = CopyValue : r3_9 +# 1075| mu3_11(int &) = Store : &:r3_0, r3_10 +# 1076| r3_12(glval) = VariableAddress[e] : +# 1076| r3_13(int &) = Load : &:r3_12, ~mu0_2 +# 1076| r3_14(int) = Load : &:r3_13, ~mu0_2 +# 1076| r3_15(int) = Constant[5] : +# 1076| r3_16(bool) = CompareLT : r3_14, r3_15 +# 1076| v3_17(void) = ConditionalBranch : r3_16 +#-----| False -> Block 2 +#-----| True -> Block 4 -#-----| Block 5 -#-----| r5_0(glval) = VariableAddress[(__begin)] : -#-----| r5_1(glval) = Convert : r5_0 -# 1069| r5_2(glval) = FunctionAddress[operator!=] : -#-----| r5_3(glval) = VariableAddress[(__end)] : -#-----| r5_4(iterator) = Load : &:r5_3, ~mu0_2 -# 1069| r5_5(bool) = Call : func:r5_2, this:r5_1, 0:r5_4 -# 1069| mu5_6(unknown) = ^CallSideEffect : ~mu0_2 -#-----| v5_7(void) = ^IndirectReadSideEffect[-1] : &:r5_1, ~mu0_2 -#-----| mu5_8(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r5_1 -# 1069| v5_9(void) = ConditionalBranch : r5_5 -#-----| False -> Block 9 -#-----| True -> Block 6 +# 1077| Block 4 +# 1077| v4_0(void) = NoOp : +#-----| Goto -> Block 5 -# 1069| Block 6 -# 1069| r6_0(glval) = VariableAddress[e] : -#-----| r6_1(glval) = VariableAddress[(__begin)] : -#-----| r6_2(glval) = Convert : r6_1 -# 1069| r6_3(glval) = FunctionAddress[operator*] : -# 1069| r6_4(int &) = Call : func:r6_3, this:r6_2 -# 1069| mu6_5(unknown) = ^CallSideEffect : ~mu0_2 -#-----| v6_6(void) = ^IndirectReadSideEffect[-1] : &:r6_2, ~mu0_2 -#-----| mu6_7(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r6_2 -# 1069| r6_8(int) = Load : &:r6_4, ~mu0_2 -# 1069| mu6_9(int) = Store : &:r6_0, r6_8 -# 1070| r6_10(glval) = VariableAddress[e] : -# 1070| r6_11(int) = Load : &:r6_10, ~mu0_2 -# 1070| r6_12(int) = Constant[0] : -# 1070| r6_13(bool) = CompareGT : r6_11, r6_12 -# 1070| v6_14(void) = ConditionalBranch : r6_13 -#-----| False -> Block 8 +# 1079| Block 5 +# 1079| v5_0(void) = NoOp : +# 1080| v5_1(void) = NoOp : +# 1068| v5_2(void) = ReturnIndirection : &:r0_5, ~mu0_2 +# 1068| v5_3(void) = ReturnVoid : +# 1068| v5_4(void) = UnmodeledUse : mu* +# 1068| v5_5(void) = AliasedUse : ~mu0_2 +# 1068| v5_6(void) = ExitFunction : + +#-----| Block 6 +#-----| r6_0(glval) = VariableAddress[(__begin)] : +#-----| r6_1(glval) = Convert : r6_0 +# 1069| r6_2(glval) = FunctionAddress[operator!=] : +#-----| r6_3(glval) = VariableAddress[(__end)] : +#-----| r6_4(iterator) = Load : &:r6_3, ~mu0_2 +# 1069| r6_5(bool) = Call : func:r6_2, this:r6_1, 0:r6_4 +# 1069| mu6_6(unknown) = ^CallSideEffect : ~mu0_2 +#-----| v6_7(void) = ^BufferReadSideEffect[-1] : &:r6_1, ~mu0_2 +#-----| mu6_8(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r6_1 +# 1069| v6_9(void) = ConditionalBranch : r6_5 +#-----| False -> Block 10 #-----| True -> Block 7 -# 1071| Block 7 -# 1071| v7_0(void) = NoOp : -#-----| Goto -> Block 8 +# 1069| Block 7 +# 1069| r7_0(glval) = VariableAddress[e] : +#-----| r7_1(glval) = VariableAddress[(__begin)] : +#-----| r7_2(glval) = Convert : r7_1 +# 1069| r7_3(glval) = FunctionAddress[operator*] : +# 1069| r7_4(int &) = Call : func:r7_3, this:r7_2 +# 1069| mu7_5(unknown) = ^CallSideEffect : ~mu0_2 +#-----| v7_6(void) = ^BufferReadSideEffect[-1] : &:r7_2, ~mu0_2 +#-----| mu7_7(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r7_2 +# 1069| r7_8(int) = Load : &:r7_4, ~mu0_2 +# 1069| mu7_9(int) = Store : &:r7_0, r7_8 +# 1070| r7_10(glval) = VariableAddress[e] : +# 1070| r7_11(int) = Load : &:r7_10, ~mu0_2 +# 1070| r7_12(int) = Constant[0] : +# 1070| r7_13(bool) = CompareGT : r7_11, r7_12 +# 1070| v7_14(void) = ConditionalBranch : r7_13 +#-----| False -> Block 9 +#-----| True -> Block 8 -# 1069| Block 8 -# 1069| v8_0(void) = NoOp : -#-----| r8_1(glval) = VariableAddress[(__begin)] : -# 1069| r8_2(glval) = FunctionAddress[operator++] : -# 1069| r8_3(iterator &) = Call : func:r8_2, this:r8_1 -# 1069| mu8_4(unknown) = ^CallSideEffect : ~mu0_2 -#-----| v8_5(void) = ^IndirectReadSideEffect[-1] : &:r8_1, ~mu0_2 -#-----| mu8_6(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r8_1 -#-----| Goto (back edge) -> Block 5 +# 1071| Block 8 +# 1071| v8_0(void) = NoOp : +#-----| Goto -> Block 9 -# 1075| Block 9 -# 1075| r9_0(glval &>) = VariableAddress[(__range)] : -# 1075| r9_1(glval &>) = VariableAddress[v] : -# 1075| r9_2(vector &) = Load : &:r9_1, ~mu0_2 -# 1075| mu9_3(vector &) = Store : &:r9_0, r9_2 -# 1075| r9_4(glval) = VariableAddress[(__begin)] : -#-----| r9_5(glval &>) = VariableAddress[(__range)] : -#-----| r9_6(vector &) = Load : &:r9_5, ~mu0_2 -# 1075| r9_7(glval) = FunctionAddress[begin] : -# 1075| r9_8(iterator) = Call : func:r9_7, this:r9_6 -# 1075| mu9_9(unknown) = ^CallSideEffect : ~mu0_2 -#-----| v9_10(void) = ^IndirectReadSideEffect[-1] : &:r9_6, ~mu0_2 -#-----| mu9_11(vector) = ^IndirectMayWriteSideEffect[-1] : &:r9_6 -# 1075| mu9_12(iterator) = Store : &:r9_4, r9_8 -# 1075| r9_13(glval) = VariableAddress[(__end)] : -#-----| r9_14(glval &>) = VariableAddress[(__range)] : -#-----| r9_15(vector &) = Load : &:r9_14, ~mu0_2 -# 1075| r9_16(glval) = FunctionAddress[end] : -# 1075| r9_17(iterator) = Call : func:r9_16, this:r9_15 -# 1075| mu9_18(unknown) = ^CallSideEffect : ~mu0_2 -#-----| v9_19(void) = ^IndirectReadSideEffect[-1] : &:r9_15, ~mu0_2 -#-----| mu9_20(vector) = ^IndirectMayWriteSideEffect[-1] : &:r9_15 -# 1075| mu9_21(iterator) = Store : &:r9_13, r9_17 -#-----| Goto -> Block 10 +# 1069| Block 9 +# 1069| v9_0(void) = NoOp : +#-----| r9_1(glval) = VariableAddress[(__begin)] : +# 1069| r9_2(glval) = FunctionAddress[operator++] : +# 1069| r9_3(iterator &) = Call : func:r9_2, this:r9_1 +# 1069| mu9_4(unknown) = ^CallSideEffect : ~mu0_2 +#-----| v9_5(void) = ^BufferReadSideEffect[-1] : &:r9_1, ~mu0_2 +#-----| mu9_6(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r9_1 +# 1069| r9_7(glval) = CopyValue : r9_3 +#-----| Goto (back edge) -> Block 6 -#-----| Block 10 -#-----| r10_0(glval) = VariableAddress[(__begin)] : -#-----| r10_1(glval) = Convert : r10_0 -# 1075| r10_2(glval) = FunctionAddress[operator!=] : -#-----| r10_3(glval) = VariableAddress[(__end)] : -#-----| r10_4(iterator) = Load : &:r10_3, ~mu0_2 -# 1075| r10_5(bool) = Call : func:r10_2, this:r10_1, 0:r10_4 -# 1075| mu10_6(unknown) = ^CallSideEffect : ~mu0_2 -#-----| v10_7(void) = ^IndirectReadSideEffect[-1] : &:r10_1, ~mu0_2 -#-----| mu10_8(iterator) = ^IndirectMayWriteSideEffect[-1] : &:r10_1 -# 1075| v10_9(void) = ConditionalBranch : r10_5 -#-----| False -> Block 4 -#-----| True -> Block 2 +# 1075| Block 10 +# 1075| r10_0(glval &>) = VariableAddress[(__range)] : +# 1075| r10_1(glval &>) = VariableAddress[v] : +# 1075| r10_2(vector &) = Load : &:r10_1, ~mu0_2 +# 1075| r10_3(glval>) = CopyValue : r10_2 +# 1075| r10_4(vector &) = CopyValue : r10_3 +# 1075| mu10_5(vector &) = Store : &:r10_0, r10_4 +# 1075| r10_6(glval) = VariableAddress[(__begin)] : +#-----| r10_7(glval &>) = VariableAddress[(__range)] : +#-----| r10_8(vector &) = Load : &:r10_7, ~mu0_2 +#-----| r10_9(glval>) = CopyValue : r10_8 +# 1075| r10_10(glval) = FunctionAddress[begin] : +# 1075| r10_11(iterator) = Call : func:r10_10, this:r10_9 +# 1075| mu10_12(unknown) = ^CallSideEffect : ~mu0_2 +#-----| v10_13(void) = ^BufferReadSideEffect[-1] : &:r10_9, ~mu0_2 +#-----| mu10_14(vector) = ^IndirectMayWriteSideEffect[-1] : &:r10_9 +# 1075| mu10_15(iterator) = Store : &:r10_6, r10_11 +# 1075| r10_16(glval) = VariableAddress[(__end)] : +#-----| r10_17(glval &>) = VariableAddress[(__range)] : +#-----| r10_18(vector &) = Load : &:r10_17, ~mu0_2 +#-----| r10_19(glval>) = CopyValue : r10_18 +# 1075| r10_20(glval) = FunctionAddress[end] : +# 1075| r10_21(iterator) = Call : func:r10_20, this:r10_19 +# 1075| mu10_22(unknown) = ^CallSideEffect : ~mu0_2 +#-----| v10_23(void) = ^BufferReadSideEffect[-1] : &:r10_19, ~mu0_2 +#-----| mu10_24(vector) = ^IndirectMayWriteSideEffect[-1] : &:r10_19 +# 1075| mu10_25(iterator) = Store : &:r10_16, r10_21 +#-----| Goto -> Block 1 # 1099| int AsmStmt(int) # 1099| Block 0 @@ -5331,7 +5652,8 @@ ir.cpp: # 1099| r0_10(glval) = VariableAddress[#return] : # 1099| v0_11(void) = ReturnValue : &:r0_10, ~mu0_2 # 1099| v0_12(void) = UnmodeledUse : mu* -# 1099| v0_13(void) = ExitFunction : +# 1099| v0_13(void) = AliasedUse : ~mu0_2 +# 1099| v0_14(void) = ExitFunction : # 1104| void AsmStmtWithOutputs(unsigned int&, unsigned int, unsigned int&, unsigned int) # 1104| Block 0 @@ -5352,19 +5674,21 @@ ir.cpp: # 1104| mu0_14(unsigned int) = InitializeParameter[d] : &:r0_13 # 1109| r0_15(glval) = VariableAddress[a] : # 1109| r0_16(unsigned int &) = Load : &:r0_15, ~mu0_2 -# 1109| r0_17(glval) = VariableAddress[b] : -# 1109| r0_18(glval) = VariableAddress[c] : -# 1109| r0_19(unsigned int &) = Load : &:r0_18, ~mu0_2 -# 1109| r0_20(unsigned int) = Load : &:r0_19, ~mu0_2 -# 1109| r0_21(glval) = VariableAddress[d] : -# 1109| r0_22(unsigned int) = Load : &:r0_21, ~mu0_2 -# 1106| mu0_23(unknown) = InlineAsm : ~mu0_2, 0:r0_16, 1:r0_17, 2:r0_20, 3:r0_22 -# 1111| v0_24(void) = NoOp : -# 1104| v0_25(void) = ReturnIndirection : &:r0_5, ~mu0_2 -# 1104| v0_26(void) = ReturnIndirection : &:r0_11, ~mu0_2 -# 1104| v0_27(void) = ReturnVoid : -# 1104| v0_28(void) = UnmodeledUse : mu* -# 1104| v0_29(void) = ExitFunction : +# 1109| r0_17(glval) = CopyValue : r0_16 +# 1109| r0_18(glval) = VariableAddress[b] : +# 1109| r0_19(glval) = VariableAddress[c] : +# 1109| r0_20(unsigned int &) = Load : &:r0_19, ~mu0_2 +# 1109| r0_21(unsigned int) = Load : &:r0_20, ~mu0_2 +# 1109| r0_22(glval) = VariableAddress[d] : +# 1109| r0_23(unsigned int) = Load : &:r0_22, ~mu0_2 +# 1106| mu0_24(unknown) = InlineAsm : ~mu0_2, 0:r0_17, 1:r0_18, 2:r0_21, 3:r0_23 +# 1111| v0_25(void) = NoOp : +# 1104| v0_26(void) = ReturnIndirection : &:r0_5, ~mu0_2 +# 1104| v0_27(void) = ReturnIndirection : &:r0_11, ~mu0_2 +# 1104| v0_28(void) = ReturnVoid : +# 1104| v0_29(void) = UnmodeledUse : mu* +# 1104| v0_30(void) = AliasedUse : ~mu0_2 +# 1104| v0_31(void) = ExitFunction : # 1113| void ExternDeclarations() # 1113| Block 0 @@ -5380,7 +5704,8 @@ ir.cpp: # 1120| v0_9(void) = NoOp : # 1113| v0_10(void) = ReturnVoid : # 1113| v0_11(void) = UnmodeledUse : mu* -# 1113| v0_12(void) = ExitFunction : +# 1113| v0_12(void) = AliasedUse : ~mu0_2 +# 1113| v0_13(void) = ExitFunction : # 1128| void ExternDeclarationsInMacro() # 1128| Block 0 @@ -5414,7 +5739,8 @@ ir.cpp: # 1131| v3_1(void) = NoOp : # 1128| v3_2(void) = ReturnVoid : # 1128| v3_3(void) = UnmodeledUse : mu* -# 1128| v3_4(void) = ExitFunction : +# 1128| v3_4(void) = AliasedUse : ~mu0_2 +# 1128| v3_5(void) = ExitFunction : # 1133| void TryCatchNoCatchAny(bool) # 1133| Block 0 @@ -5434,7 +5760,8 @@ ir.cpp: # 1133| Block 1 # 1133| v1_0(void) = UnmodeledUse : mu* -# 1133| v1_1(void) = ExitFunction : +# 1133| v1_1(void) = AliasedUse : ~mu0_2 +# 1133| v1_2(void) = ExitFunction : # 1133| Block 2 # 1133| v2_0(void) = Unwind : @@ -5481,9 +5808,10 @@ ir.cpp: # 1140| r7_3(char *) = Convert : r7_2 # 1140| v7_4(void) = Call : func:r7_1, this:r7_0, 0:r7_3 # 1140| mu7_5(unknown) = ^CallSideEffect : ~mu0_2 -# 1140| v7_6(void) = ^IndirectReadSideEffect[0] : &:r7_3, ~mu0_2 -# 1140| mu7_7(unknown) = ^BufferMayWriteSideEffect[0] : &:r7_3 -# 1140| v7_8(void) = ThrowValue : &:r7_0, ~mu0_2 +# 1140| mu7_6(String) = ^IndirectMayWriteSideEffect[-1] : &:r7_0 +# 1140| v7_7(void) = ^BufferReadSideEffect[0] : &:r7_3, ~mu0_2 +# 1140| mu7_8(unknown) = ^BufferMayWriteSideEffect[0] : &:r7_3 +# 1140| v7_9(void) = ThrowValue : &:r7_0, ~mu0_2 #-----| Exception -> Block 9 # 1142| Block 8 @@ -5498,19 +5826,20 @@ ir.cpp: #-----| Goto -> Block 10 # 1144| Block 10 -# 1144| r10_0(glval) = VariableAddress[s] : -# 1144| mu10_1(char *) = InitializeParameter[s] : &:r10_0 -# 1144| r10_2(char *) = Load : &:r10_0, ~mu10_1 -# 1144| mu10_3(unknown) = InitializeIndirection[s] : &:r10_2 -# 1145| r10_4(glval) = VariableAddress[#throw1145:5] : -# 1145| r10_5(glval) = FunctionAddress[String] : -# 1145| r10_6(glval) = VariableAddress[s] : -# 1145| r10_7(char *) = Load : &:r10_6, ~mu0_2 -# 1145| v10_8(void) = Call : func:r10_5, this:r10_4, 0:r10_7 -# 1145| mu10_9(unknown) = ^CallSideEffect : ~mu0_2 -# 1145| v10_10(void) = ^IndirectReadSideEffect[0] : &:r10_7, ~mu0_2 -# 1145| mu10_11(unknown) = ^BufferMayWriteSideEffect[0] : &:r10_7 -# 1145| v10_12(void) = ThrowValue : &:r10_4, ~mu0_2 +# 1144| r10_0(glval) = VariableAddress[s] : +# 1144| mu10_1(char *) = InitializeParameter[s] : &:r10_0 +# 1144| r10_2(char *) = Load : &:r10_0, ~mu10_1 +# 1144| mu10_3(unknown) = InitializeIndirection[s] : &:r10_2 +# 1145| r10_4(glval) = VariableAddress[#throw1145:5] : +# 1145| r10_5(glval) = FunctionAddress[String] : +# 1145| r10_6(glval) = VariableAddress[s] : +# 1145| r10_7(char *) = Load : &:r10_6, ~mu0_2 +# 1145| v10_8(void) = Call : func:r10_5, this:r10_4, 0:r10_7 +# 1145| mu10_9(unknown) = ^CallSideEffect : ~mu0_2 +# 1145| mu10_10(String) = ^IndirectMayWriteSideEffect[-1] : &:r10_4 +# 1145| v10_11(void) = ^BufferReadSideEffect[0] : &:r10_7, ~mu0_2 +# 1145| mu10_12(unknown) = ^BufferMayWriteSideEffect[0] : &:r10_7 +# 1145| v10_13(void) = ThrowValue : &:r10_4, ~mu0_2 #-----| Exception -> Block 2 # 1147| Block 11 @@ -5591,7 +5920,8 @@ ir.cpp: # 1159| v0_55(void) = NoOp : # 1153| v0_56(void) = ReturnVoid : # 1153| v0_57(void) = UnmodeledUse : mu* -# 1153| v0_58(void) = ExitFunction : +# 1153| v0_58(void) = AliasedUse : ~mu0_2 +# 1153| v0_59(void) = ExitFunction : # 1163| int ModeledCallTarget(int) # 1163| Block 0 @@ -5604,21 +5934,24 @@ ir.cpp: # 1164| mu0_6(int) = Uninitialized[y] : &:r0_5 # 1165| r0_7(glval) = FunctionAddress[memcpy] : # 1165| r0_8(glval) = VariableAddress[y] : -# 1165| r0_9(void *) = Convert : r0_8 -# 1165| r0_10(glval) = VariableAddress[x] : -# 1165| r0_11(void *) = Convert : r0_10 -# 1165| r0_12(int) = Constant[4] : -# 1165| r0_13(void *) = Call : func:r0_7, 0:r0_9, 1:r0_11, 2:r0_12 -# 1165| v0_14(void) = ^SizedBufferReadSideEffect[1] : &:r0_11, r0_12, ~mu0_2 -# 1165| mu0_15(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r0_9, r0_12 -# 1166| r0_16(glval) = VariableAddress[#return] : -# 1166| r0_17(glval) = VariableAddress[y] : -# 1166| r0_18(int) = Load : &:r0_17, ~mu0_2 -# 1166| mu0_19(int) = Store : &:r0_16, r0_18 -# 1163| r0_20(glval) = VariableAddress[#return] : -# 1163| v0_21(void) = ReturnValue : &:r0_20, ~mu0_2 -# 1163| v0_22(void) = UnmodeledUse : mu* -# 1163| v0_23(void) = ExitFunction : +# 1165| r0_9(int *) = CopyValue : r0_8 +# 1165| r0_10(void *) = Convert : r0_9 +# 1165| r0_11(glval) = VariableAddress[x] : +# 1165| r0_12(int *) = CopyValue : r0_11 +# 1165| r0_13(void *) = Convert : r0_12 +# 1165| r0_14(int) = Constant[4] : +# 1165| r0_15(void *) = Call : func:r0_7, 0:r0_10, 1:r0_13, 2:r0_14 +# 1165| v0_16(void) = ^SizedBufferReadSideEffect[1] : &:r0_13, r0_14, ~mu0_2 +# 1165| mu0_17(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r0_10, r0_14 +# 1166| r0_18(glval) = VariableAddress[#return] : +# 1166| r0_19(glval) = VariableAddress[y] : +# 1166| r0_20(int) = Load : &:r0_19, ~mu0_2 +# 1166| mu0_21(int) = Store : &:r0_18, r0_20 +# 1163| r0_22(glval) = VariableAddress[#return] : +# 1163| v0_23(void) = ReturnValue : &:r0_22, ~mu0_2 +# 1163| v0_24(void) = UnmodeledUse : mu* +# 1163| v0_25(void) = AliasedUse : ~mu0_2 +# 1163| v0_26(void) = ExitFunction : perf-regression.cpp: # 6| void Big::Big() @@ -5635,27 +5968,30 @@ perf-regression.cpp: # 6| v0_9(void) = NoOp : # 6| v0_10(void) = ReturnVoid : # 6| v0_11(void) = UnmodeledUse : mu* -# 6| v0_12(void) = ExitFunction : +# 6| v0_12(void) = AliasedUse : ~mu0_2 +# 6| v0_13(void) = ExitFunction : # 9| int main() # 9| Block 0 -# 9| v0_0(void) = EnterFunction : -# 9| mu0_1(unknown) = AliasedDefinition : -# 9| mu0_2(unknown) = UnmodeledDefinition : -# 10| r0_3(glval) = VariableAddress[big] : -# 10| r0_4(glval) = FunctionAddress[operator new] : -# 10| r0_5(unsigned long) = Constant[1073741824] : -# 10| r0_6(void *) = Call : func:r0_4, 0:r0_5 -# 10| mu0_7(unknown) = ^CallSideEffect : ~mu0_2 -# 10| r0_8(Big *) = Convert : r0_6 -# 10| r0_9(glval) = FunctionAddress[Big] : -# 10| v0_10(void) = Call : func:r0_9, this:r0_8 -# 10| mu0_11(unknown) = ^CallSideEffect : ~mu0_2 -# 10| mu0_12(Big *) = Store : &:r0_3, r0_8 -# 12| r0_13(glval) = VariableAddress[#return] : -# 12| r0_14(int) = Constant[0] : -# 12| mu0_15(int) = Store : &:r0_13, r0_14 -# 9| r0_16(glval) = VariableAddress[#return] : -# 9| v0_17(void) = ReturnValue : &:r0_16, ~mu0_2 -# 9| v0_18(void) = UnmodeledUse : mu* -# 9| v0_19(void) = ExitFunction : +# 9| v0_0(void) = EnterFunction : +# 9| mu0_1(unknown) = AliasedDefinition : +# 9| mu0_2(unknown) = UnmodeledDefinition : +# 10| r0_3(glval) = VariableAddress[big] : +# 10| r0_4(glval) = FunctionAddress[operator new] : +# 10| r0_5(unsigned long) = Constant[1073741824] : +# 10| r0_6(void *) = Call : func:r0_4, 0:r0_5 +# 10| mu0_7(unknown) = ^CallSideEffect : ~mu0_2 +# 10| r0_8(Big *) = Convert : r0_6 +# 10| r0_9(glval) = FunctionAddress[Big] : +# 10| v0_10(void) = Call : func:r0_9, this:r0_8 +# 10| mu0_11(unknown) = ^CallSideEffect : ~mu0_2 +# 10| mu0_12(Big) = ^IndirectMayWriteSideEffect[-1] : &:r0_8 +# 10| mu0_13(Big *) = Store : &:r0_3, r0_8 +# 12| r0_14(glval) = VariableAddress[#return] : +# 12| r0_15(int) = Constant[0] : +# 12| mu0_16(int) = Store : &:r0_14, r0_15 +# 9| r0_17(glval) = VariableAddress[#return] : +# 9| v0_18(void) = ReturnValue : &:r0_17, ~mu0_2 +# 9| v0_19(void) = UnmodeledUse : mu* +# 9| v0_20(void) = AliasedUse : ~mu0_2 +# 9| v0_21(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/ir/ir/raw_sanity.expected b/cpp/ql/test/library-tests/ir/ir/raw_sanity.expected index 928f535f9d8..e5e666c020b 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_sanity.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_sanity.expected @@ -1,8 +1,13 @@ missingOperand +| ir.cpp:809:7:809:13 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | +| ir.cpp:810:7:810:26 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | +| ir.cpp:823:7:823:13 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | +| ir.cpp:824:7:824:26 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | unexpectedOperand duplicateOperand missingPhiOperand missingOperandType +duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor ambiguousSuccessors diff --git a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_sanity.expected b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_sanity.expected index 928f535f9d8..e5e666c020b 100644 --- a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_sanity.expected +++ b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_sanity.expected @@ -1,8 +1,13 @@ missingOperand +| ir.cpp:809:7:809:13 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | +| ir.cpp:810:7:810:26 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | +| ir.cpp:823:7:823:13 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | +| ir.cpp:824:7:824:26 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | unexpectedOperand duplicateOperand missingPhiOperand missingOperandType +duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor ambiguousSuccessors diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected index 50542e52824..4e3e51f3947 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected @@ -88,7 +88,8 @@ ssa.cpp: # 13| r6_13(glval) = VariableAddress[#return] : # 13| v6_14(void) = ReturnValue : &:r6_13, m6_11 # 13| v6_15(void) = UnmodeledUse : mu* -# 13| v6_16(void) = ExitFunction : +# 13| v6_16(void) = AliasedUse : ~m6_0 +# 13| v6_17(void) = ExitFunction : # 31| int UnreachableViaGoto() # 31| Block 0 @@ -103,7 +104,8 @@ ssa.cpp: # 31| r0_8(glval) = VariableAddress[#return] : # 31| v0_9(void) = ReturnValue : &:r0_8, m0_7 # 31| v0_10(void) = UnmodeledUse : mu* -# 31| v0_11(void) = ExitFunction : +# 31| v0_11(void) = AliasedUse : ~m0_1 +# 31| v0_12(void) = ExitFunction : # 38| int UnreachableIf(bool) # 38| Block 0 @@ -129,7 +131,8 @@ ssa.cpp: # 38| r1_1(glval) = VariableAddress[#return] : # 38| v1_2(void) = ReturnValue : &:r1_1, m1_0 # 38| v1_3(void) = UnmodeledUse : mu* -# 38| v1_4(void) = ExitFunction : +# 38| v1_4(void) = AliasedUse : ~m0_1 +# 38| v1_5(void) = ExitFunction : # 42| Block 2 # 42| r2_0(glval) = VariableAddress[x] : @@ -192,7 +195,8 @@ ssa.cpp: # 59| r1_4(glval) = VariableAddress[#return] : # 59| v1_5(void) = ReturnValue : &:r1_4, m1_3 # 59| v1_6(void) = UnmodeledUse : mu* -# 59| v1_7(void) = ExitFunction : +# 59| v1_7(void) = AliasedUse : ~m0_1 +# 59| v1_8(void) = ExitFunction : # 59| Block 2 # 59| v2_0(void) = Unreached : @@ -218,8 +222,9 @@ ssa.cpp: # 70| r1_3(int) = Constant[1] : # 70| r1_4(char *) = PointerAdd[1] : r1_2, r1_3 # 70| m1_5(char *) = Store : &:r1_1, r1_4 -# 70| m1_6(char) = Store : &:r1_2, r1_0 -# 70| m1_7(unknown) = Chi : total:m3_0, partial:m1_6 +# 70| r1_6(glval) = CopyValue : r1_2 +# 70| m1_7(char) = Store : &:r1_6, r1_0 +# 70| m1_8(unknown) = Chi : total:m3_0, partial:m1_7 #-----| Goto (back edge) -> Block 3 # 71| Block 2 @@ -227,10 +232,11 @@ ssa.cpp: # 68| v2_1(void) = ReturnIndirection : &:r0_7, ~m3_0 # 68| v2_2(void) = ReturnVoid : # 68| v2_3(void) = UnmodeledUse : mu* -# 68| v2_4(void) = ExitFunction : +# 68| v2_4(void) = AliasedUse : ~m3_0 +# 68| v2_5(void) = ExitFunction : # 69| Block 3 -# 69| m3_0(unknown) = Phi : from 0:~m0_9, from 1:~m1_7 +# 69| m3_0(unknown) = Phi : from 0:~m0_9, from 1:~m1_8 # 69| m3_1(int) = Phi : from 0:m0_4, from 1:m3_7 # 69| m3_2(char *) = Phi : from 0:m0_6, from 1:m1_5 # 69| r3_3(glval) = VariableAddress[n] : @@ -299,7 +305,8 @@ ssa.cpp: # 89| v3_14(void) = NoOp : # 75| v3_15(void) = ReturnVoid : # 75| v3_16(void) = UnmodeledUse : mu* -# 75| v3_17(void) = ExitFunction : +# 75| v3_17(void) = AliasedUse : ~m0_1 +# 75| v3_18(void) = ExitFunction : # 91| void MustExactlyOverlap(Point) # 91| Block 0 @@ -315,7 +322,8 @@ ssa.cpp: # 93| v0_9(void) = NoOp : # 91| v0_10(void) = ReturnVoid : # 91| v0_11(void) = UnmodeledUse : mu* -# 91| v0_12(void) = ExitFunction : +# 91| v0_12(void) = AliasedUse : ~m0_1 +# 91| v0_13(void) = ExitFunction : # 95| void MustExactlyOverlapEscaped(Point) # 95| Block 0 @@ -331,17 +339,19 @@ ssa.cpp: # 96| m0_9(Point) = Store : &:r0_6, r0_8 # 97| r0_10(glval) = FunctionAddress[Escape] : # 97| r0_11(glval) = VariableAddress[a] : -# 97| r0_12(void *) = Convert : r0_11 -# 97| v0_13(void) = Call : func:r0_10, 0:r0_12 -# 97| m0_14(unknown) = ^CallSideEffect : ~m0_5 -# 97| m0_15(unknown) = Chi : total:m0_5, partial:m0_14 -# 97| v0_16(void) = ^IndirectReadSideEffect[0] : &:r0_12, ~m0_15 -# 97| m0_17(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_12 -# 97| m0_18(unknown) = Chi : total:m0_15, partial:m0_17 -# 98| v0_19(void) = NoOp : -# 95| v0_20(void) = ReturnVoid : -# 95| v0_21(void) = UnmodeledUse : mu* -# 95| v0_22(void) = ExitFunction : +# 97| r0_12(Point *) = CopyValue : r0_11 +# 97| r0_13(void *) = Convert : r0_12 +# 97| v0_14(void) = Call : func:r0_10, 0:r0_13 +# 97| m0_15(unknown) = ^CallSideEffect : ~m0_5 +# 97| m0_16(unknown) = Chi : total:m0_5, partial:m0_15 +# 97| v0_17(void) = ^BufferReadSideEffect[0] : &:r0_13, ~m0_16 +# 97| m0_18(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_13 +# 97| m0_19(unknown) = Chi : total:m0_16, partial:m0_18 +# 98| v0_20(void) = NoOp : +# 95| v0_21(void) = ReturnVoid : +# 95| v0_22(void) = UnmodeledUse : mu* +# 95| v0_23(void) = AliasedUse : ~m0_16 +# 95| v0_24(void) = ExitFunction : # 100| void MustTotallyOverlap(Point) # 100| Block 0 @@ -363,7 +373,8 @@ ssa.cpp: # 103| v0_15(void) = NoOp : # 100| v0_16(void) = ReturnVoid : # 100| v0_17(void) = UnmodeledUse : mu* -# 100| v0_18(void) = ExitFunction : +# 100| v0_18(void) = AliasedUse : ~m0_1 +# 100| v0_19(void) = ExitFunction : # 105| void MustTotallyOverlapEscaped(Point) # 105| Block 0 @@ -385,17 +396,19 @@ ssa.cpp: # 107| m0_15(int) = Store : &:r0_11, r0_14 # 108| r0_16(glval) = FunctionAddress[Escape] : # 108| r0_17(glval) = VariableAddress[a] : -# 108| r0_18(void *) = Convert : r0_17 -# 108| v0_19(void) = Call : func:r0_16, 0:r0_18 -# 108| m0_20(unknown) = ^CallSideEffect : ~m0_5 -# 108| m0_21(unknown) = Chi : total:m0_5, partial:m0_20 -# 108| v0_22(void) = ^IndirectReadSideEffect[0] : &:r0_18, ~m0_21 -# 108| m0_23(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_18 -# 108| m0_24(unknown) = Chi : total:m0_21, partial:m0_23 -# 109| v0_25(void) = NoOp : -# 105| v0_26(void) = ReturnVoid : -# 105| v0_27(void) = UnmodeledUse : mu* -# 105| v0_28(void) = ExitFunction : +# 108| r0_18(Point *) = CopyValue : r0_17 +# 108| r0_19(void *) = Convert : r0_18 +# 108| v0_20(void) = Call : func:r0_16, 0:r0_19 +# 108| m0_21(unknown) = ^CallSideEffect : ~m0_5 +# 108| m0_22(unknown) = Chi : total:m0_5, partial:m0_21 +# 108| v0_23(void) = ^BufferReadSideEffect[0] : &:r0_19, ~m0_22 +# 108| m0_24(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_19 +# 108| m0_25(unknown) = Chi : total:m0_22, partial:m0_24 +# 109| v0_26(void) = NoOp : +# 105| v0_27(void) = ReturnVoid : +# 105| v0_28(void) = UnmodeledUse : mu* +# 105| v0_29(void) = AliasedUse : ~m0_22 +# 105| v0_30(void) = ExitFunction : # 111| void MayPartiallyOverlap(int, int) # 111| Block 0 @@ -425,7 +438,8 @@ ssa.cpp: # 114| v0_23(void) = NoOp : # 111| v0_24(void) = ReturnVoid : # 111| v0_25(void) = UnmodeledUse : mu* -# 111| v0_26(void) = ExitFunction : +# 111| v0_26(void) = AliasedUse : ~m0_1 +# 111| v0_27(void) = ExitFunction : # 116| void MayPartiallyOverlapEscaped(int, int) # 116| Block 0 @@ -455,17 +469,19 @@ ssa.cpp: # 118| m0_23(Point) = Store : &:r0_20, r0_22 # 119| r0_24(glval) = FunctionAddress[Escape] : # 119| r0_25(glval) = VariableAddress[a] : -# 119| r0_26(void *) = Convert : r0_25 -# 119| v0_27(void) = Call : func:r0_24, 0:r0_26 -# 119| m0_28(unknown) = ^CallSideEffect : ~m0_19 -# 119| m0_29(unknown) = Chi : total:m0_19, partial:m0_28 -# 119| v0_30(void) = ^IndirectReadSideEffect[0] : &:r0_26, ~m0_29 -# 119| m0_31(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_26 -# 119| m0_32(unknown) = Chi : total:m0_29, partial:m0_31 -# 120| v0_33(void) = NoOp : -# 116| v0_34(void) = ReturnVoid : -# 116| v0_35(void) = UnmodeledUse : mu* -# 116| v0_36(void) = ExitFunction : +# 119| r0_26(Point *) = CopyValue : r0_25 +# 119| r0_27(void *) = Convert : r0_26 +# 119| v0_28(void) = Call : func:r0_24, 0:r0_27 +# 119| m0_29(unknown) = ^CallSideEffect : ~m0_19 +# 119| m0_30(unknown) = Chi : total:m0_19, partial:m0_29 +# 119| v0_31(void) = ^BufferReadSideEffect[0] : &:r0_27, ~m0_30 +# 119| m0_32(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_27 +# 119| m0_33(unknown) = Chi : total:m0_30, partial:m0_32 +# 120| v0_34(void) = NoOp : +# 116| v0_35(void) = ReturnVoid : +# 116| v0_36(void) = UnmodeledUse : mu* +# 116| v0_37(void) = AliasedUse : ~m0_30 +# 116| v0_38(void) = ExitFunction : # 122| void MergeMustExactlyOverlap(bool, int, int) # 122| Block 0 @@ -527,7 +543,8 @@ ssa.cpp: # 132| v3_11(void) = NoOp : # 122| v3_12(void) = ReturnVoid : # 122| v3_13(void) = UnmodeledUse : mu* -# 122| v3_14(void) = ExitFunction : +# 122| v3_14(void) = AliasedUse : ~m0_1 +# 122| v3_15(void) = ExitFunction : # 134| void MergeMustExactlyWithMustTotallyOverlap(bool, Point, int) # 134| Block 0 @@ -583,7 +600,8 @@ ssa.cpp: # 143| v3_7(void) = NoOp : # 134| v3_8(void) = ReturnVoid : # 134| v3_9(void) = UnmodeledUse : mu* -# 134| v3_10(void) = ExitFunction : +# 134| v3_10(void) = AliasedUse : ~m0_1 +# 134| v3_11(void) = ExitFunction : # 145| void MergeMustExactlyWithMayPartiallyOverlap(bool, Point, int) # 145| Block 0 @@ -637,7 +655,8 @@ ssa.cpp: # 154| v3_5(void) = NoOp : # 145| v3_6(void) = ReturnVoid : # 145| v3_7(void) = UnmodeledUse : mu* -# 145| v3_8(void) = ExitFunction : +# 145| v3_8(void) = AliasedUse : ~m0_1 +# 145| v3_9(void) = ExitFunction : # 156| void MergeMustTotallyOverlapWithMayPartiallyOverlap(bool, Rect, int) # 156| Block 0 @@ -693,7 +712,8 @@ ssa.cpp: # 165| v3_6(void) = NoOp : # 156| v3_7(void) = ReturnVoid : # 156| v3_8(void) = UnmodeledUse : mu* -# 156| v3_9(void) = ExitFunction : +# 156| v3_9(void) = AliasedUse : ~m0_1 +# 156| v3_10(void) = ExitFunction : # 171| void WrapperStruct(Wrapper) # 171| Block 0 @@ -727,7 +747,8 @@ ssa.cpp: # 177| v0_27(void) = NoOp : # 171| v0_28(void) = ReturnVoid : # 171| v0_29(void) = UnmodeledUse : mu* -# 171| v0_30(void) = ExitFunction : +# 171| v0_30(void) = AliasedUse : ~m0_1 +# 171| v0_31(void) = ExitFunction : # 179| int AsmStmt(int*) # 179| Block 0 @@ -750,7 +771,8 @@ ssa.cpp: # 179| r0_16(glval) = VariableAddress[#return] : # 179| v0_17(void) = ReturnValue : &:r0_16, m0_14 # 179| v0_18(void) = UnmodeledUse : mu* -# 179| v0_19(void) = ExitFunction : +# 179| v0_19(void) = AliasedUse : ~m0_9 +# 179| v0_20(void) = ExitFunction : # 184| void AsmStmtWithOutputs(unsigned int&, unsigned int&, unsigned int&, unsigned int&) # 184| Block 0 @@ -779,24 +801,27 @@ ssa.cpp: # 184| m0_22(unknown) = Chi : total:m0_17, partial:m0_21 # 189| r0_23(glval) = VariableAddress[a] : # 189| r0_24(unsigned int &) = Load : &:r0_23, m0_4 -# 189| r0_25(glval) = VariableAddress[b] : -# 189| r0_26(unsigned int &) = Load : &:r0_25, m0_9 -# 190| r0_27(glval) = VariableAddress[c] : -# 190| r0_28(unsigned int &) = Load : &:r0_27, m0_14 -# 190| r0_29(unsigned int) = Load : &:r0_28, ~m0_22 -# 190| r0_30(glval) = VariableAddress[d] : -# 190| r0_31(unsigned int &) = Load : &:r0_30, m0_19 -# 190| r0_32(unsigned int) = Load : &:r0_31, ~m0_22 -# 186| m0_33(unknown) = InlineAsm : ~mu0_2, 0:r0_24, 1:r0_26, 2:r0_29, 3:r0_32 -# 186| m0_34(unknown) = Chi : total:m0_22, partial:m0_33 -# 192| v0_35(void) = NoOp : -# 184| v0_36(void) = ReturnIndirection : &:r0_5, ~m0_34 -# 184| v0_37(void) = ReturnIndirection : &:r0_10, ~m0_34 -# 184| v0_38(void) = ReturnIndirection : &:r0_15, ~m0_34 -# 184| v0_39(void) = ReturnIndirection : &:r0_20, ~m0_34 -# 184| v0_40(void) = ReturnVoid : -# 184| v0_41(void) = UnmodeledUse : mu* -# 184| v0_42(void) = ExitFunction : +# 189| r0_25(glval) = CopyValue : r0_24 +# 189| r0_26(glval) = VariableAddress[b] : +# 189| r0_27(unsigned int &) = Load : &:r0_26, m0_9 +# 189| r0_28(glval) = CopyValue : r0_27 +# 190| r0_29(glval) = VariableAddress[c] : +# 190| r0_30(unsigned int &) = Load : &:r0_29, m0_14 +# 190| r0_31(unsigned int) = Load : &:r0_30, ~m0_22 +# 190| r0_32(glval) = VariableAddress[d] : +# 190| r0_33(unsigned int &) = Load : &:r0_32, m0_19 +# 190| r0_34(unsigned int) = Load : &:r0_33, ~m0_22 +# 186| m0_35(unknown) = InlineAsm : ~mu0_2, 0:r0_25, 1:r0_28, 2:r0_31, 3:r0_34 +# 186| m0_36(unknown) = Chi : total:m0_22, partial:m0_35 +# 192| v0_37(void) = NoOp : +# 184| v0_38(void) = ReturnIndirection : &:r0_5, ~m0_36 +# 184| v0_39(void) = ReturnIndirection : &:r0_10, ~m0_36 +# 184| v0_40(void) = ReturnIndirection : &:r0_15, ~m0_36 +# 184| v0_41(void) = ReturnIndirection : &:r0_20, ~m0_36 +# 184| v0_42(void) = ReturnVoid : +# 184| v0_43(void) = UnmodeledUse : mu* +# 184| v0_44(void) = AliasedUse : ~m0_36 +# 184| v0_45(void) = ExitFunction : # 198| int PureFunctions(char*, char*, int) # 198| Block 0 @@ -853,7 +878,8 @@ ssa.cpp: # 198| r0_50(glval) = VariableAddress[#return] : # 198| v0_51(void) = ReturnValue : &:r0_50, m0_47 # 198| v0_52(void) = UnmodeledUse : mu* -# 198| v0_53(void) = ExitFunction : +# 198| v0_53(void) = AliasedUse : ~m0_12 +# 198| v0_54(void) = ExitFunction : # 207| int ModeledCallTarget(int) # 207| Block 0 @@ -868,19 +894,201 @@ ssa.cpp: # 208| m0_8(unknown) = Chi : total:m0_5, partial:m0_7 # 209| r0_9(glval) = FunctionAddress[memcpy] : # 209| r0_10(glval) = VariableAddress[y] : -# 209| r0_11(void *) = Convert : r0_10 -# 209| r0_12(glval) = VariableAddress[x] : -# 209| r0_13(void *) = Convert : r0_12 -# 209| r0_14(int) = Constant[4] : -# 209| r0_15(void *) = Call : func:r0_9, 0:r0_11, 1:r0_13, 2:r0_14 -# 209| v0_16(void) = ^SizedBufferReadSideEffect[1] : &:r0_13, r0_14, ~mu0_2 -# 209| m0_17(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r0_11, r0_14 -# 209| m0_18(unknown) = Chi : total:m0_8, partial:m0_17 -# 210| r0_19(glval) = VariableAddress[#return] : -# 210| r0_20(glval) = VariableAddress[y] : -# 210| r0_21(int) = Load : &:r0_20, ~m0_18 -# 210| m0_22(int) = Store : &:r0_19, r0_21 -# 207| r0_23(glval) = VariableAddress[#return] : -# 207| v0_24(void) = ReturnValue : &:r0_23, m0_22 -# 207| v0_25(void) = UnmodeledUse : mu* -# 207| v0_26(void) = ExitFunction : +# 209| r0_11(int *) = CopyValue : r0_10 +# 209| r0_12(void *) = Convert : r0_11 +# 209| r0_13(glval) = VariableAddress[x] : +# 209| r0_14(int *) = CopyValue : r0_13 +# 209| r0_15(void *) = Convert : r0_14 +# 209| r0_16(int) = Constant[4] : +# 209| r0_17(void *) = Call : func:r0_9, 0:r0_12, 1:r0_15, 2:r0_16 +# 209| v0_18(void) = ^SizedBufferReadSideEffect[1] : &:r0_15, r0_16, ~mu0_2 +# 209| m0_19(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r0_12, r0_16 +# 209| m0_20(unknown) = Chi : total:m0_8, partial:m0_19 +# 210| r0_21(glval) = VariableAddress[#return] : +# 210| r0_22(glval) = VariableAddress[y] : +# 210| r0_23(int) = Load : &:r0_22, ~m0_20 +# 210| m0_24(int) = Store : &:r0_21, r0_23 +# 207| r0_25(glval) = VariableAddress[#return] : +# 207| v0_26(void) = ReturnValue : &:r0_25, m0_24 +# 207| v0_27(void) = UnmodeledUse : mu* +# 207| v0_28(void) = AliasedUse : ~m0_1 +# 207| v0_29(void) = ExitFunction : + +# 213| void InitArray() +# 213| Block 0 +# 213| v0_0(void) = EnterFunction : +# 213| m0_1(unknown) = AliasedDefinition : +# 213| mu0_2(unknown) = UnmodeledDefinition : +# 214| r0_3(glval) = VariableAddress[a_pad] : +# 214| m0_4(char[32]) = Uninitialized[a_pad] : &:r0_3 +# 214| r0_5(glval) = StringConstant[""] : +# 214| r0_6(char[1]) = Load : &:r0_5, ~m0_1 +# 214| m0_7(char[1]) = Store : &:r0_3, r0_6 +# 214| m0_8(char[32]) = Chi : total:m0_4, partial:m0_7 +# 214| r0_9(unknown[31]) = Constant[0] : +# 214| r0_10(int) = Constant[1] : +# 214| r0_11(glval) = PointerAdd[1] : r0_3, r0_10 +# 214| m0_12(unknown[31]) = Store : &:r0_11, r0_9 +# 214| m0_13(char[32]) = Chi : total:m0_8, partial:m0_12 +# 215| r0_14(glval) = VariableAddress[a_nopad] : +# 215| r0_15(glval) = StringConstant["foo"] : +# 215| r0_16(char[4]) = Load : &:r0_15, ~m0_1 +# 215| m0_17(char[4]) = Store : &:r0_14, r0_16 +# 216| r0_18(glval) = VariableAddress[a_infer] : +# 216| r0_19(glval) = StringConstant["blah"] : +# 216| r0_20(char[5]) = Load : &:r0_19, ~m0_1 +# 216| m0_21(char[5]) = Store : &:r0_18, r0_20 +# 217| r0_22(glval) = VariableAddress[b] : +# 217| m0_23(char[2]) = Uninitialized[b] : &:r0_22 +# 218| r0_24(glval) = VariableAddress[c] : +# 218| m0_25(char[2]) = Uninitialized[c] : &:r0_24 +# 218| r0_26(int) = Constant[0] : +# 218| r0_27(glval) = PointerAdd[1] : r0_24, r0_26 +# 218| r0_28(unknown[2]) = Constant[0] : +# 218| m0_29(unknown[2]) = Store : &:r0_27, r0_28 +# 219| r0_30(glval) = VariableAddress[d] : +# 219| m0_31(char[2]) = Uninitialized[d] : &:r0_30 +# 219| r0_32(int) = Constant[0] : +# 219| r0_33(glval) = PointerAdd[1] : r0_30, r0_32 +# 219| r0_34(char) = Constant[0] : +# 219| m0_35(char) = Store : &:r0_33, r0_34 +# 219| m0_36(char[2]) = Chi : total:m0_31, partial:m0_35 +# 219| r0_37(int) = Constant[1] : +# 219| r0_38(glval) = PointerAdd[1] : r0_30, r0_37 +# 219| r0_39(char) = Constant[0] : +# 219| m0_40(char) = Store : &:r0_38, r0_39 +# 219| m0_41(char[2]) = Chi : total:m0_36, partial:m0_40 +# 220| r0_42(glval) = VariableAddress[e] : +# 220| m0_43(char[2]) = Uninitialized[e] : &:r0_42 +# 220| r0_44(int) = Constant[0] : +# 220| r0_45(glval) = PointerAdd[1] : r0_42, r0_44 +# 220| r0_46(char) = Constant[0] : +# 220| m0_47(char) = Store : &:r0_45, r0_46 +# 220| m0_48(char[2]) = Chi : total:m0_43, partial:m0_47 +# 220| r0_49(int) = Constant[1] : +# 220| r0_50(glval) = PointerAdd[1] : r0_42, r0_49 +# 220| r0_51(char) = Constant[1] : +# 220| m0_52(char) = Store : &:r0_50, r0_51 +# 220| m0_53(char[2]) = Chi : total:m0_48, partial:m0_52 +# 221| r0_54(glval) = VariableAddress[f] : +# 221| m0_55(char[3]) = Uninitialized[f] : &:r0_54 +# 221| r0_56(int) = Constant[0] : +# 221| r0_57(glval) = PointerAdd[1] : r0_54, r0_56 +# 221| r0_58(char) = Constant[0] : +# 221| m0_59(char) = Store : &:r0_57, r0_58 +# 221| m0_60(char[3]) = Chi : total:m0_55, partial:m0_59 +# 221| r0_61(int) = Constant[1] : +# 221| r0_62(glval) = PointerAdd[1] : r0_54, r0_61 +# 221| r0_63(unknown[2]) = Constant[0] : +# 221| m0_64(unknown[2]) = Store : &:r0_62, r0_63 +# 221| m0_65(char[3]) = Chi : total:m0_60, partial:m0_64 +# 222| v0_66(void) = NoOp : +# 213| v0_67(void) = ReturnVoid : +# 213| v0_68(void) = UnmodeledUse : mu* +# 213| v0_69(void) = AliasedUse : ~m0_1 +# 213| v0_70(void) = ExitFunction : + +# 226| char StringLiteralAliasing() +# 226| Block 0 +# 226| v0_0(void) = EnterFunction : +# 226| m0_1(unknown) = AliasedDefinition : +# 226| mu0_2(unknown) = UnmodeledDefinition : +# 227| r0_3(glval) = FunctionAddress[ExternalFunc] : +# 227| v0_4(void) = Call : func:r0_3 +# 227| m0_5(unknown) = ^CallSideEffect : ~m0_1 +# 227| m0_6(unknown) = Chi : total:m0_1, partial:m0_5 +# 229| r0_7(glval) = VariableAddress[s] : +# 229| r0_8(glval) = StringConstant["Literal"] : +# 229| r0_9(char *) = Convert : r0_8 +# 229| m0_10(char *) = Store : &:r0_7, r0_9 +# 230| r0_11(glval) = VariableAddress[#return] : +# 230| r0_12(glval) = VariableAddress[s] : +# 230| r0_13(char *) = Load : &:r0_12, m0_10 +# 230| r0_14(int) = Constant[2] : +# 230| r0_15(glval) = PointerAdd[1] : r0_13, r0_14 +# 230| r0_16(char) = Load : &:r0_15, ~m0_1 +# 230| m0_17(char) = Store : &:r0_11, r0_16 +# 226| r0_18(glval) = VariableAddress[#return] : +# 226| v0_19(void) = ReturnValue : &:r0_18, m0_17 +# 226| v0_20(void) = UnmodeledUse : mu* +# 226| v0_21(void) = AliasedUse : ~m0_6 +# 226| v0_22(void) = ExitFunction : + +# 235| void Constructible::Constructible(int) +# 235| Block 0 +# 235| v0_0(void) = EnterFunction : +# 235| m0_1(unknown) = AliasedDefinition : +# 235| mu0_2(unknown) = UnmodeledDefinition : +# 235| r0_3(glval) = InitializeThis : +# 235| r0_4(glval) = VariableAddress[x] : +# 235| m0_5(int) = InitializeParameter[x] : &:r0_4 +# 235| v0_6(void) = NoOp : +# 235| v0_7(void) = ReturnVoid : +# 235| v0_8(void) = UnmodeledUse : mu* +# 235| v0_9(void) = AliasedUse : ~m0_1 +# 235| v0_10(void) = ExitFunction : + +# 236| void Constructible::g() +# 236| Block 0 +# 236| v0_0(void) = EnterFunction : +# 236| m0_1(unknown) = AliasedDefinition : +# 236| mu0_2(unknown) = UnmodeledDefinition : +# 236| r0_3(glval) = InitializeThis : +# 236| v0_4(void) = NoOp : +# 236| v0_5(void) = ReturnVoid : +# 236| v0_6(void) = UnmodeledUse : mu* +# 236| v0_7(void) = AliasedUse : ~m0_1 +# 236| v0_8(void) = ExitFunction : + +# 239| void ExplicitConstructorCalls() +# 239| Block 0 +# 239| v0_0(void) = EnterFunction : +# 239| m0_1(unknown) = AliasedDefinition : +# 239| mu0_2(unknown) = UnmodeledDefinition : +# 240| r0_3(glval) = VariableAddress[c] : +# 240| m0_4(Constructible) = Uninitialized[c] : &:r0_3 +# 240| r0_5(glval) = FunctionAddress[Constructible] : +# 240| r0_6(int) = Constant[1] : +# 240| v0_7(void) = Call : func:r0_5, this:r0_3, 0:r0_6 +# 240| m0_8(unknown) = ^CallSideEffect : ~m0_1 +# 240| m0_9(unknown) = Chi : total:m0_1, partial:m0_8 +# 240| m0_10(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r0_3 +# 240| m0_11(Constructible) = Chi : total:m0_4, partial:m0_10 +# 241| r0_12(glval) = VariableAddress[c] : +# 241| r0_13(glval) = FunctionAddress[g] : +# 241| v0_14(void) = Call : func:r0_13, this:r0_12 +# 241| m0_15(unknown) = ^CallSideEffect : ~m0_9 +# 241| m0_16(unknown) = Chi : total:m0_9, partial:m0_15 +# 241| v0_17(void) = ^BufferReadSideEffect[-1] : &:r0_12, ~m0_11 +# 241| m0_18(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r0_12 +# 241| m0_19(Constructible) = Chi : total:m0_11, partial:m0_18 +# 242| r0_20(glval) = VariableAddress[c] : +# 242| r0_21(glval) = FunctionAddress[g] : +# 242| v0_22(void) = Call : func:r0_21, this:r0_20 +# 242| m0_23(unknown) = ^CallSideEffect : ~m0_16 +# 242| m0_24(unknown) = Chi : total:m0_16, partial:m0_23 +# 242| v0_25(void) = ^BufferReadSideEffect[-1] : &:r0_20, ~m0_19 +# 242| m0_26(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r0_20 +# 242| m0_27(Constructible) = Chi : total:m0_19, partial:m0_26 +# 243| r0_28(glval) = VariableAddress[c2] : +# 243| m0_29(Constructible) = Uninitialized[c2] : &:r0_28 +# 243| r0_30(glval) = FunctionAddress[Constructible] : +# 243| r0_31(int) = Constant[2] : +# 243| v0_32(void) = Call : func:r0_30, this:r0_28, 0:r0_31 +# 243| m0_33(unknown) = ^CallSideEffect : ~m0_24 +# 243| m0_34(unknown) = Chi : total:m0_24, partial:m0_33 +# 243| m0_35(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r0_28 +# 243| m0_36(Constructible) = Chi : total:m0_29, partial:m0_35 +# 244| r0_37(glval) = VariableAddress[c2] : +# 244| r0_38(glval) = FunctionAddress[g] : +# 244| v0_39(void) = Call : func:r0_38, this:r0_37 +# 244| m0_40(unknown) = ^CallSideEffect : ~m0_34 +# 244| m0_41(unknown) = Chi : total:m0_34, partial:m0_40 +# 244| v0_42(void) = ^BufferReadSideEffect[-1] : &:r0_37, ~m0_36 +# 244| m0_43(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r0_37 +# 244| m0_44(Constructible) = Chi : total:m0_36, partial:m0_43 +# 245| v0_45(void) = NoOp : +# 239| v0_46(void) = ReturnVoid : +# 239| v0_47(void) = UnmodeledUse : mu* +# 239| v0_48(void) = AliasedUse : ~m0_41 +# 239| v0_49(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_sanity.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_sanity.expected index 928f535f9d8..9769ee11f99 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_sanity.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_sanity.expected @@ -3,6 +3,7 @@ unexpectedOperand duplicateOperand missingPhiOperand missingOperandType +duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor ambiguousSuccessors diff --git a/cpp/ql/test/library-tests/ir/ssa/ssa.cpp b/cpp/ql/test/library-tests/ir/ssa/ssa.cpp index 4dfb0a2f6cd..e60a575cf5e 100644 --- a/cpp/ql/test/library-tests/ir/ssa/ssa.cpp +++ b/cpp/ql/test/library-tests/ir/ssa/ssa.cpp @@ -210,3 +210,36 @@ int ModeledCallTarget(int x) { return y; } +void InitArray() { + char a_pad[32] = ""; + char a_nopad[4] = "foo"; + char a_infer[] = "blah"; + char b[2]; + char c[2] = {}; + char d[2] = { 0 }; + char e[2] = { 0, 1 }; + char f[3] = { 0 }; +} + +extern void ExternalFunc(); + +char StringLiteralAliasing() { + ExternalFunc(); + + const char* s = "Literal"; + return s[2]; // Should be defined by `AliasedDefinition`, not `Chi` or `CallSideEffect`. +} + +class Constructible { + public: + Constructible(int x) {}; + void g() {} +}; + +void ExplicitConstructorCalls() { + Constructible c(1); + c.g(); + c.g(); + Constructible c2 = Constructible(2); + c2.g(); +} diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected index 46845bdeca4..6a14ce014f6 100644 --- a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected @@ -81,7 +81,8 @@ ssa.cpp: # 13| r6_12(glval) = VariableAddress[#return] : # 13| v6_13(void) = ReturnValue : &:r6_12, m6_10 # 13| v6_14(void) = UnmodeledUse : mu* -# 13| v6_15(void) = ExitFunction : +# 13| v6_15(void) = AliasedUse : ~mu0_2 +# 13| v6_16(void) = ExitFunction : # 31| int UnreachableViaGoto() # 31| Block 0 @@ -96,7 +97,8 @@ ssa.cpp: # 31| r0_8(glval) = VariableAddress[#return] : # 31| v0_9(void) = ReturnValue : &:r0_8, m0_7 # 31| v0_10(void) = UnmodeledUse : mu* -# 31| v0_11(void) = ExitFunction : +# 31| v0_11(void) = AliasedUse : ~mu0_2 +# 31| v0_12(void) = ExitFunction : # 38| int UnreachableIf(bool) # 38| Block 0 @@ -122,7 +124,8 @@ ssa.cpp: # 38| r1_1(glval) = VariableAddress[#return] : # 38| v1_2(void) = ReturnValue : &:r1_1, m1_0 # 38| v1_3(void) = UnmodeledUse : mu* -# 38| v1_4(void) = ExitFunction : +# 38| v1_4(void) = AliasedUse : ~mu0_2 +# 38| v1_5(void) = ExitFunction : # 42| Block 2 # 42| r2_0(glval) = VariableAddress[x] : @@ -194,7 +197,8 @@ ssa.cpp: # 59| r1_4(glval) = VariableAddress[#return] : # 59| v1_5(void) = ReturnValue : &:r1_4, m1_3 # 59| v1_6(void) = UnmodeledUse : mu* -# 59| v1_7(void) = ExitFunction : +# 59| v1_7(void) = AliasedUse : ~mu0_2 +# 59| v1_8(void) = ExitFunction : # 59| Block 2 # 59| v2_0(void) = Unreached : @@ -219,7 +223,8 @@ ssa.cpp: # 70| r1_3(int) = Constant[1] : # 70| r1_4(char *) = PointerAdd[1] : r1_2, r1_3 # 70| m1_5(char *) = Store : &:r1_1, r1_4 -# 70| mu1_6(char) = Store : &:r1_2, r1_0 +# 70| r1_6(glval) = CopyValue : r1_2 +# 70| mu1_7(char) = Store : &:r1_6, r1_0 #-----| Goto (back edge) -> Block 3 # 71| Block 2 @@ -227,7 +232,8 @@ ssa.cpp: # 68| v2_1(void) = ReturnIndirection : &:r0_7, ~mu0_2 # 68| v2_2(void) = ReturnVoid : # 68| v2_3(void) = UnmodeledUse : mu* -# 68| v2_4(void) = ExitFunction : +# 68| v2_4(void) = AliasedUse : ~mu0_2 +# 68| v2_5(void) = ExitFunction : # 69| Block 3 # 69| m3_0(int) = Phi : from 0:m0_4, from 1:m3_6 @@ -298,7 +304,8 @@ ssa.cpp: # 89| v3_14(void) = NoOp : # 75| v3_15(void) = ReturnVoid : # 75| v3_16(void) = UnmodeledUse : mu* -# 75| v3_17(void) = ExitFunction : +# 75| v3_17(void) = AliasedUse : ~mu0_2 +# 75| v3_18(void) = ExitFunction : # 91| void MustExactlyOverlap(Point) # 91| Block 0 @@ -314,7 +321,8 @@ ssa.cpp: # 93| v0_9(void) = NoOp : # 91| v0_10(void) = ReturnVoid : # 91| v0_11(void) = UnmodeledUse : mu* -# 91| v0_12(void) = ExitFunction : +# 91| v0_12(void) = AliasedUse : ~mu0_2 +# 91| v0_13(void) = ExitFunction : # 95| void MustExactlyOverlapEscaped(Point) # 95| Block 0 @@ -329,15 +337,17 @@ ssa.cpp: # 96| m0_8(Point) = Store : &:r0_5, r0_7 # 97| r0_9(glval) = FunctionAddress[Escape] : # 97| r0_10(glval) = VariableAddress[a] : -# 97| r0_11(void *) = Convert : r0_10 -# 97| v0_12(void) = Call : func:r0_9, 0:r0_11 -# 97| mu0_13(unknown) = ^CallSideEffect : ~mu0_2 -# 97| v0_14(void) = ^IndirectReadSideEffect[0] : &:r0_11, ~mu0_2 -# 97| mu0_15(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_11 -# 98| v0_16(void) = NoOp : -# 95| v0_17(void) = ReturnVoid : -# 95| v0_18(void) = UnmodeledUse : mu* -# 95| v0_19(void) = ExitFunction : +# 97| r0_11(Point *) = CopyValue : r0_10 +# 97| r0_12(void *) = Convert : r0_11 +# 97| v0_13(void) = Call : func:r0_9, 0:r0_12 +# 97| mu0_14(unknown) = ^CallSideEffect : ~mu0_2 +# 97| v0_15(void) = ^BufferReadSideEffect[0] : &:r0_12, ~mu0_2 +# 97| mu0_16(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_12 +# 98| v0_17(void) = NoOp : +# 95| v0_18(void) = ReturnVoid : +# 95| v0_19(void) = UnmodeledUse : mu* +# 95| v0_20(void) = AliasedUse : ~mu0_2 +# 95| v0_21(void) = ExitFunction : # 100| void MustTotallyOverlap(Point) # 100| Block 0 @@ -359,7 +369,8 @@ ssa.cpp: # 103| v0_15(void) = NoOp : # 100| v0_16(void) = ReturnVoid : # 100| v0_17(void) = UnmodeledUse : mu* -# 100| v0_18(void) = ExitFunction : +# 100| v0_18(void) = AliasedUse : ~mu0_2 +# 100| v0_19(void) = ExitFunction : # 105| void MustTotallyOverlapEscaped(Point) # 105| Block 0 @@ -380,15 +391,17 @@ ssa.cpp: # 107| m0_14(int) = Store : &:r0_10, r0_13 # 108| r0_15(glval) = FunctionAddress[Escape] : # 108| r0_16(glval) = VariableAddress[a] : -# 108| r0_17(void *) = Convert : r0_16 -# 108| v0_18(void) = Call : func:r0_15, 0:r0_17 -# 108| mu0_19(unknown) = ^CallSideEffect : ~mu0_2 -# 108| v0_20(void) = ^IndirectReadSideEffect[0] : &:r0_17, ~mu0_2 -# 108| mu0_21(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_17 -# 109| v0_22(void) = NoOp : -# 105| v0_23(void) = ReturnVoid : -# 105| v0_24(void) = UnmodeledUse : mu* -# 105| v0_25(void) = ExitFunction : +# 108| r0_17(Point *) = CopyValue : r0_16 +# 108| r0_18(void *) = Convert : r0_17 +# 108| v0_19(void) = Call : func:r0_15, 0:r0_18 +# 108| mu0_20(unknown) = ^CallSideEffect : ~mu0_2 +# 108| v0_21(void) = ^BufferReadSideEffect[0] : &:r0_18, ~mu0_2 +# 108| mu0_22(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_18 +# 109| v0_23(void) = NoOp : +# 105| v0_24(void) = ReturnVoid : +# 105| v0_25(void) = UnmodeledUse : mu* +# 105| v0_26(void) = AliasedUse : ~mu0_2 +# 105| v0_27(void) = ExitFunction : # 111| void MayPartiallyOverlap(int, int) # 111| Block 0 @@ -416,7 +429,8 @@ ssa.cpp: # 114| v0_21(void) = NoOp : # 111| v0_22(void) = ReturnVoid : # 111| v0_23(void) = UnmodeledUse : mu* -# 111| v0_24(void) = ExitFunction : +# 111| v0_24(void) = AliasedUse : ~mu0_2 +# 111| v0_25(void) = ExitFunction : # 116| void MayPartiallyOverlapEscaped(int, int) # 116| Block 0 @@ -443,15 +457,17 @@ ssa.cpp: # 118| m0_20(Point) = Store : &:r0_17, r0_19 # 119| r0_21(glval) = FunctionAddress[Escape] : # 119| r0_22(glval) = VariableAddress[a] : -# 119| r0_23(void *) = Convert : r0_22 -# 119| v0_24(void) = Call : func:r0_21, 0:r0_23 -# 119| mu0_25(unknown) = ^CallSideEffect : ~mu0_2 -# 119| v0_26(void) = ^IndirectReadSideEffect[0] : &:r0_23, ~mu0_2 -# 119| mu0_27(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_23 -# 120| v0_28(void) = NoOp : -# 116| v0_29(void) = ReturnVoid : -# 116| v0_30(void) = UnmodeledUse : mu* -# 116| v0_31(void) = ExitFunction : +# 119| r0_23(Point *) = CopyValue : r0_22 +# 119| r0_24(void *) = Convert : r0_23 +# 119| v0_25(void) = Call : func:r0_21, 0:r0_24 +# 119| mu0_26(unknown) = ^CallSideEffect : ~mu0_2 +# 119| v0_27(void) = ^BufferReadSideEffect[0] : &:r0_24, ~mu0_2 +# 119| mu0_28(unknown) = ^BufferMayWriteSideEffect[0] : &:r0_24 +# 120| v0_29(void) = NoOp : +# 116| v0_30(void) = ReturnVoid : +# 116| v0_31(void) = UnmodeledUse : mu* +# 116| v0_32(void) = AliasedUse : ~mu0_2 +# 116| v0_33(void) = ExitFunction : # 122| void MergeMustExactlyOverlap(bool, int, int) # 122| Block 0 @@ -507,7 +523,8 @@ ssa.cpp: # 132| v3_9(void) = NoOp : # 122| v3_10(void) = ReturnVoid : # 122| v3_11(void) = UnmodeledUse : mu* -# 122| v3_12(void) = ExitFunction : +# 122| v3_12(void) = AliasedUse : ~mu0_2 +# 122| v3_13(void) = ExitFunction : # 134| void MergeMustExactlyWithMustTotallyOverlap(bool, Point, int) # 134| Block 0 @@ -558,7 +575,8 @@ ssa.cpp: # 143| v3_5(void) = NoOp : # 134| v3_6(void) = ReturnVoid : # 134| v3_7(void) = UnmodeledUse : mu* -# 134| v3_8(void) = ExitFunction : +# 134| v3_8(void) = AliasedUse : ~mu0_2 +# 134| v3_9(void) = ExitFunction : # 145| void MergeMustExactlyWithMayPartiallyOverlap(bool, Point, int) # 145| Block 0 @@ -608,7 +626,8 @@ ssa.cpp: # 154| v3_4(void) = NoOp : # 145| v3_5(void) = ReturnVoid : # 145| v3_6(void) = UnmodeledUse : mu* -# 145| v3_7(void) = ExitFunction : +# 145| v3_7(void) = AliasedUse : ~mu0_2 +# 145| v3_8(void) = ExitFunction : # 156| void MergeMustTotallyOverlapWithMayPartiallyOverlap(bool, Rect, int) # 156| Block 0 @@ -660,7 +679,8 @@ ssa.cpp: # 165| v3_5(void) = NoOp : # 156| v3_6(void) = ReturnVoid : # 156| v3_7(void) = UnmodeledUse : mu* -# 156| v3_8(void) = ExitFunction : +# 156| v3_8(void) = AliasedUse : ~mu0_2 +# 156| v3_9(void) = ExitFunction : # 171| void WrapperStruct(Wrapper) # 171| Block 0 @@ -694,7 +714,8 @@ ssa.cpp: # 177| v0_27(void) = NoOp : # 171| v0_28(void) = ReturnVoid : # 171| v0_29(void) = UnmodeledUse : mu* -# 171| v0_30(void) = ExitFunction : +# 171| v0_30(void) = AliasedUse : ~mu0_2 +# 171| v0_31(void) = ExitFunction : # 179| int AsmStmt(int*) # 179| Block 0 @@ -715,7 +736,8 @@ ssa.cpp: # 179| r0_14(glval) = VariableAddress[#return] : # 179| v0_15(void) = ReturnValue : &:r0_14, m0_12 # 179| v0_16(void) = UnmodeledUse : mu* -# 179| v0_17(void) = ExitFunction : +# 179| v0_17(void) = AliasedUse : ~mu0_2 +# 179| v0_18(void) = ExitFunction : # 184| void AsmStmtWithOutputs(unsigned int&, unsigned int&, unsigned int&, unsigned int&) # 184| Block 0 @@ -740,23 +762,26 @@ ssa.cpp: # 184| mu0_18(unknown) = InitializeIndirection[d] : &:r0_17 # 189| r0_19(glval) = VariableAddress[a] : # 189| r0_20(unsigned int &) = Load : &:r0_19, m0_4 -# 189| r0_21(glval) = VariableAddress[b] : -# 189| r0_22(unsigned int &) = Load : &:r0_21, m0_8 -# 190| r0_23(glval) = VariableAddress[c] : -# 190| r0_24(unsigned int &) = Load : &:r0_23, m0_12 -# 190| r0_25(unsigned int) = Load : &:r0_24, ~mu0_2 -# 190| r0_26(glval) = VariableAddress[d] : -# 190| r0_27(unsigned int &) = Load : &:r0_26, m0_16 -# 190| r0_28(unsigned int) = Load : &:r0_27, ~mu0_2 -# 186| mu0_29(unknown) = InlineAsm : ~mu0_2, 0:r0_20, 1:r0_22, 2:r0_25, 3:r0_28 -# 192| v0_30(void) = NoOp : -# 184| v0_31(void) = ReturnIndirection : &:r0_5, ~mu0_2 -# 184| v0_32(void) = ReturnIndirection : &:r0_9, ~mu0_2 -# 184| v0_33(void) = ReturnIndirection : &:r0_13, ~mu0_2 -# 184| v0_34(void) = ReturnIndirection : &:r0_17, ~mu0_2 -# 184| v0_35(void) = ReturnVoid : -# 184| v0_36(void) = UnmodeledUse : mu* -# 184| v0_37(void) = ExitFunction : +# 189| r0_21(glval) = CopyValue : r0_20 +# 189| r0_22(glval) = VariableAddress[b] : +# 189| r0_23(unsigned int &) = Load : &:r0_22, m0_8 +# 189| r0_24(glval) = CopyValue : r0_23 +# 190| r0_25(glval) = VariableAddress[c] : +# 190| r0_26(unsigned int &) = Load : &:r0_25, m0_12 +# 190| r0_27(unsigned int) = Load : &:r0_26, ~mu0_2 +# 190| r0_28(glval) = VariableAddress[d] : +# 190| r0_29(unsigned int &) = Load : &:r0_28, m0_16 +# 190| r0_30(unsigned int) = Load : &:r0_29, ~mu0_2 +# 186| mu0_31(unknown) = InlineAsm : ~mu0_2, 0:r0_21, 1:r0_24, 2:r0_27, 3:r0_30 +# 192| v0_32(void) = NoOp : +# 184| v0_33(void) = ReturnIndirection : &:r0_5, ~mu0_2 +# 184| v0_34(void) = ReturnIndirection : &:r0_9, ~mu0_2 +# 184| v0_35(void) = ReturnIndirection : &:r0_13, ~mu0_2 +# 184| v0_36(void) = ReturnIndirection : &:r0_17, ~mu0_2 +# 184| v0_37(void) = ReturnVoid : +# 184| v0_38(void) = UnmodeledUse : mu* +# 184| v0_39(void) = AliasedUse : ~mu0_2 +# 184| v0_40(void) = ExitFunction : # 198| int PureFunctions(char*, char*, int) # 198| Block 0 @@ -811,7 +836,8 @@ ssa.cpp: # 198| r0_48(glval) = VariableAddress[#return] : # 198| v0_49(void) = ReturnValue : &:r0_48, m0_45 # 198| v0_50(void) = UnmodeledUse : mu* -# 198| v0_51(void) = ExitFunction : +# 198| v0_51(void) = AliasedUse : ~mu0_2 +# 198| v0_52(void) = ExitFunction : # 207| int ModeledCallTarget(int) # 207| Block 0 @@ -824,18 +850,181 @@ ssa.cpp: # 208| mu0_6(int) = Uninitialized[y] : &:r0_5 # 209| r0_7(glval) = FunctionAddress[memcpy] : # 209| r0_8(glval) = VariableAddress[y] : -# 209| r0_9(void *) = Convert : r0_8 -# 209| r0_10(glval) = VariableAddress[x] : -# 209| r0_11(void *) = Convert : r0_10 -# 209| r0_12(int) = Constant[4] : -# 209| r0_13(void *) = Call : func:r0_7, 0:r0_9, 1:r0_11, 2:r0_12 -# 209| v0_14(void) = ^SizedBufferReadSideEffect[1] : &:r0_11, r0_12, ~mu0_2 -# 209| mu0_15(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r0_9, r0_12 -# 210| r0_16(glval) = VariableAddress[#return] : -# 210| r0_17(glval) = VariableAddress[y] : -# 210| r0_18(int) = Load : &:r0_17, ~mu0_2 -# 210| m0_19(int) = Store : &:r0_16, r0_18 -# 207| r0_20(glval) = VariableAddress[#return] : -# 207| v0_21(void) = ReturnValue : &:r0_20, m0_19 -# 207| v0_22(void) = UnmodeledUse : mu* -# 207| v0_23(void) = ExitFunction : +# 209| r0_9(int *) = CopyValue : r0_8 +# 209| r0_10(void *) = Convert : r0_9 +# 209| r0_11(glval) = VariableAddress[x] : +# 209| r0_12(int *) = CopyValue : r0_11 +# 209| r0_13(void *) = Convert : r0_12 +# 209| r0_14(int) = Constant[4] : +# 209| r0_15(void *) = Call : func:r0_7, 0:r0_10, 1:r0_13, 2:r0_14 +# 209| v0_16(void) = ^SizedBufferReadSideEffect[1] : &:r0_13, r0_14, ~mu0_2 +# 209| mu0_17(unknown) = ^SizedBufferMustWriteSideEffect[0] : &:r0_10, r0_14 +# 210| r0_18(glval) = VariableAddress[#return] : +# 210| r0_19(glval) = VariableAddress[y] : +# 210| r0_20(int) = Load : &:r0_19, ~mu0_2 +# 210| m0_21(int) = Store : &:r0_18, r0_20 +# 207| r0_22(glval) = VariableAddress[#return] : +# 207| v0_23(void) = ReturnValue : &:r0_22, m0_21 +# 207| v0_24(void) = UnmodeledUse : mu* +# 207| v0_25(void) = AliasedUse : ~mu0_2 +# 207| v0_26(void) = ExitFunction : + +# 213| void InitArray() +# 213| Block 0 +# 213| v0_0(void) = EnterFunction : +# 213| mu0_1(unknown) = AliasedDefinition : +# 213| mu0_2(unknown) = UnmodeledDefinition : +# 214| r0_3(glval) = VariableAddress[a_pad] : +# 214| mu0_4(char[32]) = Uninitialized[a_pad] : &:r0_3 +# 214| r0_5(glval) = StringConstant[""] : +# 214| r0_6(char[1]) = Load : &:r0_5, ~mu0_2 +# 214| mu0_7(char[1]) = Store : &:r0_3, r0_6 +# 214| r0_8(unknown[31]) = Constant[0] : +# 214| r0_9(int) = Constant[1] : +# 214| r0_10(glval) = PointerAdd[1] : r0_3, r0_9 +# 214| mu0_11(unknown[31]) = Store : &:r0_10, r0_8 +# 215| r0_12(glval) = VariableAddress[a_nopad] : +# 215| r0_13(glval) = StringConstant["foo"] : +# 215| r0_14(char[4]) = Load : &:r0_13, ~mu0_2 +# 215| m0_15(char[4]) = Store : &:r0_12, r0_14 +# 216| r0_16(glval) = VariableAddress[a_infer] : +# 216| r0_17(glval) = StringConstant["blah"] : +# 216| r0_18(char[5]) = Load : &:r0_17, ~mu0_2 +# 216| m0_19(char[5]) = Store : &:r0_16, r0_18 +# 217| r0_20(glval) = VariableAddress[b] : +# 217| m0_21(char[2]) = Uninitialized[b] : &:r0_20 +# 218| r0_22(glval) = VariableAddress[c] : +# 218| mu0_23(char[2]) = Uninitialized[c] : &:r0_22 +# 218| r0_24(int) = Constant[0] : +# 218| r0_25(glval) = PointerAdd[1] : r0_22, r0_24 +# 218| r0_26(unknown[2]) = Constant[0] : +# 218| mu0_27(unknown[2]) = Store : &:r0_25, r0_26 +# 219| r0_28(glval) = VariableAddress[d] : +# 219| mu0_29(char[2]) = Uninitialized[d] : &:r0_28 +# 219| r0_30(int) = Constant[0] : +# 219| r0_31(glval) = PointerAdd[1] : r0_28, r0_30 +# 219| r0_32(char) = Constant[0] : +# 219| mu0_33(char) = Store : &:r0_31, r0_32 +# 219| r0_34(int) = Constant[1] : +# 219| r0_35(glval) = PointerAdd[1] : r0_28, r0_34 +# 219| r0_36(char) = Constant[0] : +# 219| mu0_37(char) = Store : &:r0_35, r0_36 +# 220| r0_38(glval) = VariableAddress[e] : +# 220| mu0_39(char[2]) = Uninitialized[e] : &:r0_38 +# 220| r0_40(int) = Constant[0] : +# 220| r0_41(glval) = PointerAdd[1] : r0_38, r0_40 +# 220| r0_42(char) = Constant[0] : +# 220| mu0_43(char) = Store : &:r0_41, r0_42 +# 220| r0_44(int) = Constant[1] : +# 220| r0_45(glval) = PointerAdd[1] : r0_38, r0_44 +# 220| r0_46(char) = Constant[1] : +# 220| mu0_47(char) = Store : &:r0_45, r0_46 +# 221| r0_48(glval) = VariableAddress[f] : +# 221| mu0_49(char[3]) = Uninitialized[f] : &:r0_48 +# 221| r0_50(int) = Constant[0] : +# 221| r0_51(glval) = PointerAdd[1] : r0_48, r0_50 +# 221| r0_52(char) = Constant[0] : +# 221| mu0_53(char) = Store : &:r0_51, r0_52 +# 221| r0_54(int) = Constant[1] : +# 221| r0_55(glval) = PointerAdd[1] : r0_48, r0_54 +# 221| r0_56(unknown[2]) = Constant[0] : +# 221| mu0_57(unknown[2]) = Store : &:r0_55, r0_56 +# 222| v0_58(void) = NoOp : +# 213| v0_59(void) = ReturnVoid : +# 213| v0_60(void) = UnmodeledUse : mu* +# 213| v0_61(void) = AliasedUse : ~mu0_2 +# 213| v0_62(void) = ExitFunction : + +# 226| char StringLiteralAliasing() +# 226| Block 0 +# 226| v0_0(void) = EnterFunction : +# 226| mu0_1(unknown) = AliasedDefinition : +# 226| mu0_2(unknown) = UnmodeledDefinition : +# 227| r0_3(glval) = FunctionAddress[ExternalFunc] : +# 227| v0_4(void) = Call : func:r0_3 +# 227| mu0_5(unknown) = ^CallSideEffect : ~mu0_2 +# 229| r0_6(glval) = VariableAddress[s] : +# 229| r0_7(glval) = StringConstant["Literal"] : +# 229| r0_8(char *) = Convert : r0_7 +# 229| m0_9(char *) = Store : &:r0_6, r0_8 +# 230| r0_10(glval) = VariableAddress[#return] : +# 230| r0_11(glval) = VariableAddress[s] : +# 230| r0_12(char *) = Load : &:r0_11, m0_9 +# 230| r0_13(int) = Constant[2] : +# 230| r0_14(glval) = PointerAdd[1] : r0_12, r0_13 +# 230| r0_15(char) = Load : &:r0_14, ~mu0_2 +# 230| m0_16(char) = Store : &:r0_10, r0_15 +# 226| r0_17(glval) = VariableAddress[#return] : +# 226| v0_18(void) = ReturnValue : &:r0_17, m0_16 +# 226| v0_19(void) = UnmodeledUse : mu* +# 226| v0_20(void) = AliasedUse : ~mu0_2 +# 226| v0_21(void) = ExitFunction : + +# 235| void Constructible::Constructible(int) +# 235| Block 0 +# 235| v0_0(void) = EnterFunction : +# 235| mu0_1(unknown) = AliasedDefinition : +# 235| mu0_2(unknown) = UnmodeledDefinition : +# 235| r0_3(glval) = InitializeThis : +# 235| r0_4(glval) = VariableAddress[x] : +# 235| m0_5(int) = InitializeParameter[x] : &:r0_4 +# 235| v0_6(void) = NoOp : +# 235| v0_7(void) = ReturnVoid : +# 235| v0_8(void) = UnmodeledUse : mu* +# 235| v0_9(void) = AliasedUse : ~mu0_2 +# 235| v0_10(void) = ExitFunction : + +# 236| void Constructible::g() +# 236| Block 0 +# 236| v0_0(void) = EnterFunction : +# 236| mu0_1(unknown) = AliasedDefinition : +# 236| mu0_2(unknown) = UnmodeledDefinition : +# 236| r0_3(glval) = InitializeThis : +# 236| v0_4(void) = NoOp : +# 236| v0_5(void) = ReturnVoid : +# 236| v0_6(void) = UnmodeledUse : mu* +# 236| v0_7(void) = AliasedUse : ~mu0_2 +# 236| v0_8(void) = ExitFunction : + +# 239| void ExplicitConstructorCalls() +# 239| Block 0 +# 239| v0_0(void) = EnterFunction : +# 239| mu0_1(unknown) = AliasedDefinition : +# 239| mu0_2(unknown) = UnmodeledDefinition : +# 240| r0_3(glval) = VariableAddress[c] : +# 240| mu0_4(Constructible) = Uninitialized[c] : &:r0_3 +# 240| r0_5(glval) = FunctionAddress[Constructible] : +# 240| r0_6(int) = Constant[1] : +# 240| v0_7(void) = Call : func:r0_5, this:r0_3, 0:r0_6 +# 240| mu0_8(unknown) = ^CallSideEffect : ~mu0_2 +# 240| mu0_9(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r0_3 +# 241| r0_10(glval) = VariableAddress[c] : +# 241| r0_11(glval) = FunctionAddress[g] : +# 241| v0_12(void) = Call : func:r0_11, this:r0_10 +# 241| mu0_13(unknown) = ^CallSideEffect : ~mu0_2 +# 241| v0_14(void) = ^BufferReadSideEffect[-1] : &:r0_10, ~mu0_2 +# 241| mu0_15(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r0_10 +# 242| r0_16(glval) = VariableAddress[c] : +# 242| r0_17(glval) = FunctionAddress[g] : +# 242| v0_18(void) = Call : func:r0_17, this:r0_16 +# 242| mu0_19(unknown) = ^CallSideEffect : ~mu0_2 +# 242| v0_20(void) = ^BufferReadSideEffect[-1] : &:r0_16, ~mu0_2 +# 242| mu0_21(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r0_16 +# 243| r0_22(glval) = VariableAddress[c2] : +# 243| mu0_23(Constructible) = Uninitialized[c2] : &:r0_22 +# 243| r0_24(glval) = FunctionAddress[Constructible] : +# 243| r0_25(int) = Constant[2] : +# 243| v0_26(void) = Call : func:r0_24, this:r0_22, 0:r0_25 +# 243| mu0_27(unknown) = ^CallSideEffect : ~mu0_2 +# 243| mu0_28(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r0_22 +# 244| r0_29(glval) = VariableAddress[c2] : +# 244| r0_30(glval) = FunctionAddress[g] : +# 244| v0_31(void) = Call : func:r0_30, this:r0_29 +# 244| mu0_32(unknown) = ^CallSideEffect : ~mu0_2 +# 244| v0_33(void) = ^BufferReadSideEffect[-1] : &:r0_29, ~mu0_2 +# 244| mu0_34(Constructible) = ^IndirectMayWriteSideEffect[-1] : &:r0_29 +# 245| v0_35(void) = NoOp : +# 239| v0_36(void) = ReturnVoid : +# 239| v0_37(void) = UnmodeledUse : mu* +# 239| v0_38(void) = AliasedUse : ~mu0_2 +# 239| v0_39(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_sanity.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_sanity.expected index 928f535f9d8..9769ee11f99 100644 --- a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_sanity.expected +++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_sanity.expected @@ -3,6 +3,7 @@ unexpectedOperand duplicateOperand missingPhiOperand missingOperandType +duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor ambiguousSuccessors diff --git a/cpp/ql/test/library-tests/noexcept/copy_from_prototype/copy_from_prototype.expected b/cpp/ql/test/library-tests/noexcept/copy_from_prototype/copy_from_prototype.expected index 9d77efe772f..f5ef2d77c98 100644 --- a/cpp/ql/test/library-tests/noexcept/copy_from_prototype/copy_from_prototype.expected +++ b/cpp/ql/test/library-tests/noexcept/copy_from_prototype/copy_from_prototype.expected @@ -13,7 +13,7 @@ | copy_from_prototype.cpp:13:7:13:7 | c | c::c(const c &) -> void | copy_from_prototype.cpp:13:7:13:7 | c | | | copy_from_prototype.cpp:13:7:13:7 | operator= | c::operator=(c &&) -> c & | copy_from_prototype.cpp:13:7:13:7 | c | | | copy_from_prototype.cpp:13:7:13:7 | operator= | c::operator=(const c &) -> c & | copy_from_prototype.cpp:13:7:13:7 | c | | -| copy_from_prototype.cpp:14:26:14:26 | c | c::c<(unnamed)>() -> void | copy_from_prototype.cpp:13:7:13:7 | c | Unknown literal | +| copy_from_prototype.cpp:14:26:14:26 | c | c::c<(unnamed)>() -> void | copy_from_prototype.cpp:13:7:13:7 | c | X | | copy_from_prototype.cpp:14:26:14:26 | c | c::c<(unnamed)>() -> void | copy_from_prototype.cpp:13:7:13:7 | c | | | copy_from_prototype.cpp:17:7:17:7 | d | d::d() -> void | copy_from_prototype.cpp:17:7:17:7 | d | | | copy_from_prototype.cpp:17:7:17:7 | d | d::d(const d &) -> void | copy_from_prototype.cpp:17:7:17:7 | d | | diff --git a/cpp/ql/test/library-tests/ptr_to_member/segfault/exprs.expected b/cpp/ql/test/library-tests/ptr_to_member/segfault/exprs.expected index 7af2f7c8c17..e5539a762ab 100644 --- a/cpp/ql/test/library-tests/ptr_to_member/segfault/exprs.expected +++ b/cpp/ql/test/library-tests/ptr_to_member/segfault/exprs.expected @@ -1,3 +1,7 @@ +| file://:0:0:0:0 | __i | file://:0:0:0:0 | unsigned long | +| file://:0:0:0:0 | uls | file://:0:0:0:0 | unsigned long | +| file://:0:0:0:0 | uls | file://:0:0:0:0 | unsigned long | +| file://:0:0:0:0 | uls | file://:0:0:0:0 | unsigned long | | segfault.cpp:25:46:25:65 | call to S | file://:0:0:0:0 | void | | segfault.cpp:25:46:25:65 | call to S | file://:0:0:0:0 | void | | segfault.cpp:25:48:25:55 | __second | segfault.cpp:15:7:15:11 | tuple | diff --git a/cpp/ql/test/library-tests/rangeanalysis/rangeanalysis/RangeAnalysis.expected b/cpp/ql/test/library-tests/rangeanalysis/rangeanalysis/RangeAnalysis.expected index cb3366e91b5..a7d7a6684e3 100644 --- a/cpp/ql/test/library-tests/rangeanalysis/rangeanalysis/RangeAnalysis.expected +++ b/cpp/ql/test/library-tests/rangeanalysis/rangeanalysis/RangeAnalysis.expected @@ -51,7 +51,6 @@ | test.cpp:163:12:163:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | -1 | false | CompareNE: ... != ... | test.cpp:160:9:160:16 | test.cpp:160:9:160:16 | | test.cpp:163:12:163:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | -1 | true | CompareLT: ... < ... | test.cpp:154:6:154:10 | test.cpp:154:6:154:10 | | test.cpp:163:12:163:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | -1 | true | CompareNE: ... != ... | test.cpp:160:9:160:16 | test.cpp:160:9:160:16 | -| test.cpp:167:12:167:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | 0 | false | CompareLT: ... < ... | test.cpp:154:6:154:10 | test.cpp:154:6:154:10 | | test.cpp:167:12:167:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | 1 | false | CompareEQ: ... == ... | test.cpp:166:9:166:16 | test.cpp:166:9:166:16 | | test.cpp:167:12:167:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | 1 | true | CompareEQ: ... == ... | test.cpp:166:9:166:16 | test.cpp:166:9:166:16 | | test.cpp:169:12:169:12 | Load: x | test.cpp:153:23:153:23 | InitializeParameter: y | 0 | false | CompareLT: ... < ... | test.cpp:154:6:154:10 | test.cpp:154:6:154:10 | diff --git a/cpp/ql/test/library-tests/rangeanalysis/rangeanalysis/RangeAnalysis.ql b/cpp/ql/test/library-tests/rangeanalysis/rangeanalysis/RangeAnalysis.ql index b009ce5001f..ef158f0de28 100644 --- a/cpp/ql/test/library-tests/rangeanalysis/rangeanalysis/RangeAnalysis.ql +++ b/cpp/ql/test/library-tests/rangeanalysis/rangeanalysis/RangeAnalysis.ql @@ -11,13 +11,7 @@ query predicate instructionBounds( or exists(ReturnValueInstruction retInstr | retInstr.getReturnValueOperand() = i.getAUse()) ) and - ( - upper = true and - delta = min(int d | boundedInstruction(i, b, d, upper, reason)) - or - upper = false and - delta = max(int d | boundedInstruction(i, b, d, upper, reason)) - ) and + boundedInstruction(i, b, delta, upper, reason) and not valueNumber(b.getInstruction()) = valueNumber(i) and if reason instanceof CondReason then reasonLoc = reason.(CondReason).getCond().getLocation() diff --git a/cpp/ql/test/library-tests/rangeanalysis/signanalysis/SignAnalysis.expected b/cpp/ql/test/library-tests/rangeanalysis/signanalysis/SignAnalysis.expected index cdc15c4b45a..0c8f9c1cff1 100644 --- a/cpp/ql/test/library-tests/rangeanalysis/signanalysis/SignAnalysis.expected +++ b/cpp/ql/test/library-tests/rangeanalysis/signanalysis/SignAnalysis.expected @@ -649,12 +649,14 @@ | test.c:397:9:397:11 | Constant: ++ ... | positive strictlyPositive | | test.c:397:9:397:11 | Load: ++ ... | positive | | test.c:397:9:397:11 | Store: ++ ... | positive strictlyPositive | +| test.c:397:9:397:14 | CopyValue: ... , ... | positive strictlyPositive | | test.c:397:14:397:14 | Load: y | positive strictlyPositive | | test.c:398:3:398:23 | Store: ... = ... | positive strictlyPositive | | test.c:398:9:398:11 | Add: ... ++ | positive strictlyPositive | | test.c:398:9:398:11 | Constant: ... ++ | positive strictlyPositive | | test.c:398:9:398:11 | Load: ... ++ | positive strictlyPositive | | test.c:398:9:398:11 | Store: ... ++ | positive strictlyPositive | +| test.c:398:9:398:22 | CopyValue: ... , ... | positive strictlyPositive | | test.c:398:14:398:19 | Add: ... += ... | positive strictlyPositive | | test.c:398:14:398:19 | Load: ... += ... | positive strictlyPositive | | test.c:398:14:398:19 | Store: ... += ... | positive strictlyPositive | diff --git a/cpp/ql/test/library-tests/syntax-zoo/aliased_ssa_sanity.expected b/cpp/ql/test/library-tests/syntax-zoo/aliased_ssa_sanity.expected index 4d33a9c0d21..c26e5883ec2 100644 --- a/cpp/ql/test/library-tests/syntax-zoo/aliased_ssa_sanity.expected +++ b/cpp/ql/test/library-tests/syntax-zoo/aliased_ssa_sanity.expected @@ -1,15 +1,40 @@ missingOperand +| conditional_destructors.cpp:30:9:30:13 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:30:9:30:13 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:1:6:1:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:30:18:30:22 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:30:18:30:22 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:1:6:1:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:33:9:33:13 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:33:9:33:13 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:1:6:1:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:33:18:33:22 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:33:18:33:22 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:1:6:1:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:39:9:39:13 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | IR: f2 | void f2() | +| conditional_destructors.cpp:39:9:39:13 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:8:6:8:7 | IR: f2 | void f2() | +| conditional_destructors.cpp:39:18:39:22 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | IR: f2 | void f2() | +| conditional_destructors.cpp:39:18:39:22 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:8:6:8:7 | IR: f2 | void f2() | +| conditional_destructors.cpp:42:9:42:13 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | IR: f2 | void f2() | +| conditional_destructors.cpp:42:9:42:13 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:8:6:8:7 | IR: f2 | void f2() | +| conditional_destructors.cpp:42:18:42:22 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | IR: f2 | void f2() | +| conditional_destructors.cpp:42:18:42:22 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:8:6:8:7 | IR: f2 | void f2() | +| cpp11.cpp:77:19:77:21 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:76:8:76:8 | IR: apply | void lambda::apply<(void lambda::apply2(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)>(lambda::Val, (void lambda::apply2(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)) | +| cpp11.cpp:82:11:82:14 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:81:8:81:8 | IR: apply2 | void lambda::apply2(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val) | +| cpp11.cpp:82:17:82:55 | IndirectMayWriteSideEffect: call to (constructor) | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:81:8:81:8 | IR: apply2 | void lambda::apply2(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val) | +| cpp11.cpp:82:45:82:48 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:82:20:82:20 | IR: operator() | void (void lambda::apply2(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)::operator()(lambda::Val) const | +| cpp11.cpp:82:51:82:51 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:82:20:82:20 | IR: operator() | void (void lambda::apply2(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)::operator()(lambda::Val) const | +| cpp11.cpp:88:25:88:30 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:87:8:87:11 | IR: main | void lambda::main() | +| cpp11.cpp:88:33:88:38 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:87:8:87:11 | IR: main | void lambda::main() | +| destructors.cpp:51:36:51:38 | IndirectMayWriteSideEffect: call to C | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | destructors.cpp:49:7:49:7 | IR: f | int cond_destruct::f(int) | +| ir.cpp:809:7:809:13 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | +| ir.cpp:810:7:810:26 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | +| ir.cpp:823:7:823:13 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | +| ir.cpp:824:7:824:26 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | | misc.c:125:5:125:11 | CopyValue: (statement expression) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | misc.c:97:6:97:10 | IR: misc3 | void misc3() | -| parameterinitializer.cpp:27:3:27:6 | IndirectReadSideEffect: my_c | Instruction 'IndirectReadSideEffect' is missing an expected operand with tag 'SideEffect' in function '$@'. | allocators.cpp:14:5:14:8 | IR: main | int main() | -| parameterinitializer.cpp:27:3:27:6 | IndirectReadSideEffect: my_c | Instruction 'IndirectReadSideEffect' is missing an expected operand with tag 'SideEffect' in function '$@'. | no_dynamic_init.cpp:9:5:9:8 | IR: main | int main() | -| parameterinitializer.cpp:27:3:27:6 | IndirectReadSideEffect: my_c | Instruction 'IndirectReadSideEffect' is missing an expected operand with tag 'SideEffect' in function '$@'. | parameterinitializer.cpp:18:5:18:8 | IR: main | int main() | -| parameterinitializer.cpp:27:3:27:6 | IndirectReadSideEffect: my_c | Instruction 'IndirectReadSideEffect' is missing an expected operand with tag 'SideEffect' in function '$@'. | stream_it.cpp:16:5:16:8 | IR: main | int main() | -| try_catch.cpp:13:5:13:16 | ThrowValue: throw ... | Instruction 'ThrowValue' is missing an expected operand with tag 'Load' in function '$@'. | try_catch.cpp:11:6:11:17 | IR: bypass_catch | void bypass_catch() | +| try_catch.cpp:13:5:13:16 | Chi: call to exn1 | Instruction 'Chi' is missing an expected operand with tag 'ChiTotal' in function '$@'. | try_catch.cpp:11:6:11:17 | IR: bypass_catch | void bypass_catch() | unexpectedOperand duplicateOperand missingPhiOperand | cpp11.cpp:141:7:141:7 | Phi: g | cpp11.cpp:161:16:161:16 | NoOp: label ...: | missingOperandType +duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor | VacuousDestructorCall.cpp:2:29:2:29 | Chi: y | diff --git a/cpp/ql/test/library-tests/syntax-zoo/drawDifferent.expected b/cpp/ql/test/library-tests/syntax-zoo/drawDifferent.expected deleted file mode 100644 index 2d0be306bbe..00000000000 --- a/cpp/ql/test/library-tests/syntax-zoo/drawDifferent.expected +++ /dev/null @@ -1,108 +0,0 @@ -| pointer_to_member__pmIsConstT_extractor | false | 15733 | 15733 | pmIsConstT | -| pointer_to_member__pmIsConstT_extractor | false | 15741 | 15741 | declaration | -| pointer_to_member__pmIsConstT_extractor | false | 15743 | 15743 | return ... | -| pointer_to_member__pmIsConstT_extractor | false | 15745 | 15745 | { ... } | -| pointer_to_member__pmIsConstT_extractor | false | 15748 | 15748 | {...} | -| pointer_to_member__pmIsConstT_extractor | false | 15753 | 15753 | x1 | -| pointer_to_member__pmIsConstT_extractor | false | 15755 | 15755 | & ... | -| pointer_to_member__pmIsConstT_extractor | false | 15760 | 15760 | f1 | -| pointer_to_member__pmIsConstT_extractor | false | 15762 | 15762 | & ... | -| pointer_to_member__pmIsConstT_extractor | false | 15764 | 15764 | initializer for pms | -| pointer_to_member__pmIsConstT_extractor | true | 15741 | 15743 | | -| pointer_to_member__pmIsConstT_extractor | true | 15743 | 15733 | | -| pointer_to_member__pmIsConstT_extractor | true | 15745 | 15741 | | -| pointer_to_member__pmIsConstT_ql | false | 15733 | 15733 | pmIsConstT | -| pointer_to_member__pmIsConstT_ql | false | 15741 | 15741 | declaration | -| pointer_to_member__pmIsConstT_ql | false | 15743 | 15743 | return ... | -| pointer_to_member__pmIsConstT_ql | false | 15745 | 15745 | { ... } | -| pointer_to_member__pmIsConstT_ql | false | 15748 | 15748 | {...} | -| pointer_to_member__pmIsConstT_ql | false | 15753 | 15753 | x1 | -| pointer_to_member__pmIsConstT_ql | false | 15755 | 15755 | & ... | -| pointer_to_member__pmIsConstT_ql | false | 15760 | 15760 | f1 | -| pointer_to_member__pmIsConstT_ql | false | 15762 | 15762 | & ... | -| pointer_to_member__pmIsConstT_ql | false | 15764 | 15764 | initializer for pms | -| pointer_to_member__pmIsConstT_ql | true | 15741 | 15764 | | -| pointer_to_member__pmIsConstT_ql | true | 15743 | 15733 | | -| pointer_to_member__pmIsConstT_ql | true | 15745 | 15741 | | -| pointer_to_member__pmIsConstT_ql | true | 15748 | 15743 | | -| pointer_to_member__pmIsConstT_ql | true | 15753 | 15755 | | -| pointer_to_member__pmIsConstT_ql | true | 15755 | 15760 | | -| pointer_to_member__pmIsConstT_ql | true | 15760 | 15762 | | -| pointer_to_member__pmIsConstT_ql | true | 15762 | 15748 | | -| pointer_to_member__pmIsConstT_ql | true | 15764 | 15753 | | -| staticlocals__staticlocals_f2_extractor | false | 22550 | 22550 | f2 | -| staticlocals__staticlocals_f2_extractor | false | 22555 | 22555 | declaration | -| staticlocals__staticlocals_f2_extractor | false | 22557 | 22557 | declaration | -| staticlocals__staticlocals_f2_extractor | false | 22559 | 22559 | declaration | -| staticlocals__staticlocals_f2_extractor | false | 22561 | 22561 | declaration | -| staticlocals__staticlocals_f2_extractor | false | 22563 | 22563 | return ... | -| staticlocals__staticlocals_f2_extractor | false | 22565 | 22565 | { ... } | -| staticlocals__staticlocals_f2_extractor | false | 22567 | 22567 | call to C | -| staticlocals__staticlocals_f2_extractor | false | 22569 | 22569 | initializer for c | -| staticlocals__staticlocals_f2_extractor | false | 22571 | 22571 | call to addOne | -| staticlocals__staticlocals_f2_extractor | false | 22575 | 22575 | 2 | -| staticlocals__staticlocals_f2_extractor | false | 22578 | 22578 | initializer for j | -| staticlocals__staticlocals_f2_extractor | false | 22579 | 22579 | call to addOne | -| staticlocals__staticlocals_f2_extractor | false | 22584 | 22584 | 2 | -| staticlocals__staticlocals_f2_extractor | false | 22585 | 22585 | initializer for two | -| staticlocals__staticlocals_f2_extractor | false | 22588 | 22588 | two | -| staticlocals__staticlocals_f2_extractor | false | 22593 | 22593 | initializer for i | -| staticlocals__staticlocals_f2_extractor | true | 22555 | 22585 | | -| staticlocals__staticlocals_f2_extractor | true | 22557 | 22559 | | -| staticlocals__staticlocals_f2_extractor | true | 22559 | 22561 | | -| staticlocals__staticlocals_f2_extractor | true | 22561 | 22563 | | -| staticlocals__staticlocals_f2_extractor | true | 22563 | 22550 | | -| staticlocals__staticlocals_f2_extractor | true | 22565 | 22555 | | -| staticlocals__staticlocals_f2_extractor | true | 22584 | 22557 | | -| staticlocals__staticlocals_f2_extractor | true | 22585 | 22584 | | -| staticlocals__staticlocals_f2_ql | false | 22550 | 22550 | f2 | -| staticlocals__staticlocals_f2_ql | false | 22555 | 22555 | declaration | -| staticlocals__staticlocals_f2_ql | false | 22557 | 22557 | declaration | -| staticlocals__staticlocals_f2_ql | false | 22559 | 22559 | declaration | -| staticlocals__staticlocals_f2_ql | false | 22561 | 22561 | declaration | -| staticlocals__staticlocals_f2_ql | false | 22563 | 22563 | return ... | -| staticlocals__staticlocals_f2_ql | false | 22565 | 22565 | { ... } | -| staticlocals__staticlocals_f2_ql | false | 22567 | 22567 | call to C | -| staticlocals__staticlocals_f2_ql | false | 22569 | 22569 | initializer for c | -| staticlocals__staticlocals_f2_ql | false | 22571 | 22571 | call to addOne | -| staticlocals__staticlocals_f2_ql | false | 22575 | 22575 | 2 | -| staticlocals__staticlocals_f2_ql | false | 22578 | 22578 | initializer for j | -| staticlocals__staticlocals_f2_ql | false | 22579 | 22579 | call to addOne | -| staticlocals__staticlocals_f2_ql | false | 22584 | 22584 | 2 | -| staticlocals__staticlocals_f2_ql | false | 22585 | 22585 | initializer for two | -| staticlocals__staticlocals_f2_ql | false | 22588 | 22588 | two | -| staticlocals__staticlocals_f2_ql | false | 22593 | 22593 | initializer for i | -| staticlocals__staticlocals_f2_ql | true | 22555 | 22585 | | -| staticlocals__staticlocals_f2_ql | true | 22557 | 22559 | | -| staticlocals__staticlocals_f2_ql | true | 22559 | 22561 | | -| staticlocals__staticlocals_f2_ql | true | 22561 | 22563 | | -| staticlocals__staticlocals_f2_ql | true | 22561 | 22569 | | -| staticlocals__staticlocals_f2_ql | true | 22563 | 22550 | | -| staticlocals__staticlocals_f2_ql | true | 22565 | 22555 | | -| staticlocals__staticlocals_f2_ql | true | 22567 | 22563 | | -| staticlocals__staticlocals_f2_ql | true | 22569 | 22567 | | -| staticlocals__staticlocals_f2_ql | true | 22584 | 22557 | | -| staticlocals__staticlocals_f2_ql | true | 22585 | 22584 | | -| staticlocals__staticlocals_f3_extractor | false | 22529 | 22529 | f3 | -| staticlocals__staticlocals_f3_extractor | false | 22532 | 22532 | declaration | -| staticlocals__staticlocals_f3_extractor | false | 22534 | 22534 | return ... | -| staticlocals__staticlocals_f3_extractor | false | 22536 | 22536 | { ... } | -| staticlocals__staticlocals_f3_extractor | false | 22543 | 22543 | value | -| staticlocals__staticlocals_f3_extractor | false | 22545 | 22545 | (int)... | -| staticlocals__staticlocals_f3_extractor | false | 22546 | 22546 | initializer for i | -| staticlocals__staticlocals_f3_extractor | true | 22532 | 22534 | | -| staticlocals__staticlocals_f3_extractor | true | 22534 | 22529 | | -| staticlocals__staticlocals_f3_extractor | true | 22536 | 22532 | | -| staticlocals__staticlocals_f3_ql | false | 22529 | 22529 | f3 | -| staticlocals__staticlocals_f3_ql | false | 22532 | 22532 | declaration | -| staticlocals__staticlocals_f3_ql | false | 22534 | 22534 | return ... | -| staticlocals__staticlocals_f3_ql | false | 22536 | 22536 | { ... } | -| staticlocals__staticlocals_f3_ql | false | 22543 | 22543 | value | -| staticlocals__staticlocals_f3_ql | false | 22545 | 22545 | (int)... | -| staticlocals__staticlocals_f3_ql | false | 22546 | 22546 | initializer for i | -| staticlocals__staticlocals_f3_ql | true | 22532 | 22534 | | -| staticlocals__staticlocals_f3_ql | true | 22532 | 22546 | | -| staticlocals__staticlocals_f3_ql | true | 22534 | 22529 | | -| staticlocals__staticlocals_f3_ql | true | 22536 | 22532 | | -| staticlocals__staticlocals_f3_ql | true | 22543 | 22534 | | -| staticlocals__staticlocals_f3_ql | true | 22546 | 22543 | | diff --git a/cpp/ql/test/library-tests/syntax-zoo/drawDifferent.ql b/cpp/ql/test/library-tests/syntax-zoo/drawDifferent.ql deleted file mode 100644 index 5b80f3c92a0..00000000000 --- a/cpp/ql/test/library-tests/syntax-zoo/drawDifferent.ql +++ /dev/null @@ -1,10 +0,0 @@ -// query-type: graph -import Compare - -from - Element scopeElement, string scopeString, boolean isEdge, ControlFlowNode x, ControlFlowNode y, - string label -where - AllCFG::qltestGraph(scopeElement, scopeString, isEdge, x, y, label) and - differentScope(scopeElement) -select scopeString, isEdge, x, y, label diff --git a/cpp/ql/test/library-tests/syntax-zoo/raw_sanity.expected b/cpp/ql/test/library-tests/syntax-zoo/raw_sanity.expected index ceced4142a2..7fec1b04ab9 100644 --- a/cpp/ql/test/library-tests/syntax-zoo/raw_sanity.expected +++ b/cpp/ql/test/library-tests/syntax-zoo/raw_sanity.expected @@ -1,8 +1,36 @@ missingOperand -| condition_decls.cpp:16:6:16:20 | ConditionalBranch: (condition decl) | Instruction 'ConditionalBranch' is missing an expected operand with tag 'Condition' in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) | -| condition_decls.cpp:26:3:36:3 | Switch: switch (...) ... | Instruction 'Switch' is missing an expected operand with tag 'Condition' in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) | -| condition_decls.cpp:41:9:41:23 | ConditionalBranch: (condition decl) | Instruction 'ConditionalBranch' is missing an expected operand with tag 'Condition' in function '$@'. | condition_decls.cpp:40:6:40:20 | IR: while_decl_bind | void while_decl_bind(int) | -| condition_decls.cpp:48:39:48:53 | ConditionalBranch: (condition decl) | Instruction 'ConditionalBranch' is missing an expected operand with tag 'Condition' in function '$@'. | condition_decls.cpp:47:6:47:18 | IR: for_decl_bind | void for_decl_bind(int) | +| condition_decls.cpp:16:6:16:20 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) | +| condition_decls.cpp:26:10:26:24 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) | +| condition_decls.cpp:41:9:41:23 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:40:6:40:20 | IR: while_decl_bind | void while_decl_bind(int) | +| condition_decls.cpp:48:39:48:53 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:47:6:47:18 | IR: for_decl_bind | void for_decl_bind(int) | +| conditional_destructors.cpp:30:9:30:13 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:30:9:30:13 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:1:6:1:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:30:18:30:22 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:30:18:30:22 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:1:6:1:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:33:9:33:13 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:33:9:33:13 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:1:6:1:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:33:18:33:22 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:33:18:33:22 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:1:6:1:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:39:9:39:13 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | IR: f2 | void f2() | +| conditional_destructors.cpp:39:9:39:13 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:8:6:8:7 | IR: f2 | void f2() | +| conditional_destructors.cpp:39:18:39:22 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | IR: f2 | void f2() | +| conditional_destructors.cpp:39:18:39:22 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:8:6:8:7 | IR: f2 | void f2() | +| conditional_destructors.cpp:42:9:42:13 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | IR: f2 | void f2() | +| conditional_destructors.cpp:42:9:42:13 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:8:6:8:7 | IR: f2 | void f2() | +| conditional_destructors.cpp:42:18:42:22 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | IR: f2 | void f2() | +| conditional_destructors.cpp:42:18:42:22 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:8:6:8:7 | IR: f2 | void f2() | +| cpp11.cpp:77:19:77:21 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:76:8:76:8 | IR: apply | void lambda::apply<(void lambda::apply2(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)>(lambda::Val, (void lambda::apply2(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)) | +| cpp11.cpp:82:11:82:14 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:81:8:81:8 | IR: apply2 | void lambda::apply2(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val) | +| cpp11.cpp:82:17:82:55 | IndirectMayWriteSideEffect: call to (constructor) | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:81:8:81:8 | IR: apply2 | void lambda::apply2(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val) | +| cpp11.cpp:82:45:82:48 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:82:20:82:20 | IR: operator() | void (void lambda::apply2(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)::operator()(lambda::Val) const | +| cpp11.cpp:82:51:82:51 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:82:20:82:20 | IR: operator() | void (void lambda::apply2(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)::operator()(lambda::Val) const | +| cpp11.cpp:88:25:88:30 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:87:8:87:11 | IR: main | void lambda::main() | +| cpp11.cpp:88:33:88:38 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:87:8:87:11 | IR: main | void lambda::main() | +| destructors.cpp:51:36:51:38 | IndirectMayWriteSideEffect: call to C | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | destructors.cpp:49:7:49:7 | IR: f | int cond_destruct::f(int) | +| ir.cpp:809:7:809:13 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | +| ir.cpp:810:7:810:26 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | +| ir.cpp:823:7:823:13 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | +| ir.cpp:824:7:824:26 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | | misc.c:125:5:125:11 | CopyValue: (statement expression) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | misc.c:97:6:97:10 | IR: misc3 | void misc3() | | misc.c:220:3:223:3 | Store: ... = ... | Instruction 'Store' is missing an expected operand with tag 'StoreValue' in function '$@'. | misc.c:219:5:219:26 | IR: assign_designated_init | int assign_designated_init(someStruct*) | | misc.c:220:9:223:3 | FieldAddress: {...} | Instruction 'FieldAddress' is missing an expected operand with tag 'Unary' in function '$@'. | misc.c:219:5:219:26 | IR: assign_designated_init | int assign_designated_init(someStruct*) | @@ -21,16 +49,17 @@ unexpectedOperand duplicateOperand missingPhiOperand missingOperandType +duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor | VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | | VacuousDestructorCall.cpp:3:3:3:3 | VariableAddress: x | | VacuousDestructorCall.cpp:4:3:4:3 | Load: y | -| condition_decls.cpp:16:19:16:20 | CallSideEffect: call to BoxedInt | +| condition_decls.cpp:16:19:16:20 | IndirectMayWriteSideEffect: call to BoxedInt | | condition_decls.cpp:26:19:26:20 | IndirectMayWriteSideEffect: bi | -| condition_decls.cpp:26:23:26:24 | CallSideEffect: call to BoxedInt | -| condition_decls.cpp:41:22:41:23 | CallSideEffect: call to BoxedInt | -| condition_decls.cpp:48:52:48:53 | CallSideEffect: call to BoxedInt | +| condition_decls.cpp:26:23:26:24 | IndirectMayWriteSideEffect: call to BoxedInt | +| condition_decls.cpp:41:22:41:23 | IndirectMayWriteSideEffect: call to BoxedInt | +| condition_decls.cpp:48:52:48:53 | IndirectMayWriteSideEffect: call to BoxedInt | | cpp17.cpp:15:11:15:21 | Convert: (void *)... | | file://:0:0:0:0 | CompareNE: (bool)... | | file://:0:0:0:0 | CompareNE: (bool)... | @@ -53,16 +82,16 @@ instructionWithoutSuccessor | ms_try_except.cpp:17:13:17:17 | Store: ... = ... | | ms_try_except.cpp:19:17:19:21 | Sub: ... - ... | | ms_try_except.cpp:20:9:20:13 | Store: ... = ... | -| ms_try_mix.cpp:11:12:11:15 | CallSideEffect: call to C | +| ms_try_mix.cpp:11:12:11:15 | IndirectMayWriteSideEffect: call to C | | ms_try_mix.cpp:16:13:16:19 | ThrowValue: throw ... | -| ms_try_mix.cpp:18:16:18:19 | CallSideEffect: call to C | +| ms_try_mix.cpp:18:16:18:19 | IndirectMayWriteSideEffect: call to C | | ms_try_mix.cpp:20:15:20:39 | Constant: 1 | -| ms_try_mix.cpp:21:16:21:19 | CallSideEffect: call to C | -| ms_try_mix.cpp:28:12:28:15 | CallSideEffect: call to C | +| ms_try_mix.cpp:21:16:21:19 | IndirectMayWriteSideEffect: call to C | +| ms_try_mix.cpp:28:12:28:15 | IndirectMayWriteSideEffect: call to C | | ms_try_mix.cpp:33:13:33:19 | ThrowValue: throw ... | -| ms_try_mix.cpp:35:16:35:19 | CallSideEffect: call to C | -| ms_try_mix.cpp:38:16:38:19 | CallSideEffect: call to C | -| ms_try_mix.cpp:48:10:48:13 | CallSideEffect: call to C | +| ms_try_mix.cpp:35:16:35:19 | IndirectMayWriteSideEffect: call to C | +| ms_try_mix.cpp:38:16:38:19 | IndirectMayWriteSideEffect: call to C | +| ms_try_mix.cpp:48:10:48:13 | IndirectMayWriteSideEffect: call to C | | ms_try_mix.cpp:51:5:51:11 | ThrowValue: throw ... | | ms_try_mix.cpp:53:13:54:3 | NoOp: { ... } | | pointer_to_member.cpp:36:11:36:30 | FieldAddress: {...} | @@ -611,94 +640,12 @@ lostReachability backEdgeCountMismatch useNotDominatedByDefinition | VacuousDestructorCall.cpp:2:29:2:29 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | IR: CallDestructor | void CallDestructor(int, int*) | -| VacuousDestructorCall.cpp:2:29:2:29 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | IR: CallDestructor | void CallDestructor(int, int*) | -| VacuousDestructorCall.cpp:4:3:4:3 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | IR: CallDestructor | void CallDestructor(int, int*) | -| condition_decls.cpp:16:15:16:15 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) | -| condition_decls.cpp:16:15:16:16 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) | -| condition_decls.cpp:16:15:16:16 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) | -| condition_decls.cpp:17:5:17:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) | -| condition_decls.cpp:17:11:17:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) | -| condition_decls.cpp:20:5:20:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) | -| condition_decls.cpp:20:11:20:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:15:6:15:17 | IR: if_decl_bind | void if_decl_bind(int) | -| condition_decls.cpp:26:19:26:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) | -| condition_decls.cpp:26:19:26:20 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) | -| condition_decls.cpp:26:19:26:20 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) | -| condition_decls.cpp:28:5:28:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) | -| condition_decls.cpp:28:11:28:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) | -| condition_decls.cpp:31:5:31:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) | -| condition_decls.cpp:31:11:31:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) | -| condition_decls.cpp:34:5:34:18 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) | -| condition_decls.cpp:34:9:34:13 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:25:6:25:21 | IR: switch_decl_bind | void switch_decl_bind(int) | -| condition_decls.cpp:41:18:41:18 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:40:6:40:20 | IR: while_decl_bind | void while_decl_bind(int) | -| condition_decls.cpp:41:18:41:19 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:40:6:40:20 | IR: while_decl_bind | void while_decl_bind(int) | -| condition_decls.cpp:41:18:41:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:40:6:40:20 | IR: while_decl_bind | void while_decl_bind(int) | -| condition_decls.cpp:42:5:42:7 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:40:6:40:20 | IR: while_decl_bind | void while_decl_bind(int) | -| condition_decls.cpp:44:3:44:5 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:40:6:40:20 | IR: while_decl_bind | void while_decl_bind(int) | -| condition_decls.cpp:48:48:48:48 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:47:6:47:18 | IR: for_decl_bind | void for_decl_bind(int) | -| condition_decls.cpp:48:48:48:49 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:47:6:47:18 | IR: for_decl_bind | void for_decl_bind(int) | -| condition_decls.cpp:48:48:48:49 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | condition_decls.cpp:47:6:47:18 | IR: for_decl_bind | void for_decl_bind(int) | -| condition_decls.cpp:48:56:48:61 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:47:6:47:18 | IR: for_decl_bind | void for_decl_bind(int) | -| condition_decls.cpp:49:5:49:7 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:47:6:47:18 | IR: for_decl_bind | void for_decl_bind(int) | -| condition_decls.cpp:51:3:51:5 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | condition_decls.cpp:47:6:47:18 | IR: for_decl_bind | void for_decl_bind(int) | -| cpp11.cpp:28:21:28:21 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | cpp11.cpp:27:7:27:14 | IR: getFirst | int range_based_for_11::getFirst() | -| file://:0:0:0:0 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | cpp11.cpp:27:7:27:14 | IR: getFirst | int range_based_for_11::getFirst() | -| misc.c:68:16:68:16 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) | -| misc.c:70:13:70:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) | -| misc.c:72:11:72:11 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) | -| misc.c:82:5:82:12 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) | -| misc.c:83:5:83:12 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) | -| misc.c:83:14:83:14 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) | -| misc.c:83:17:83:17 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) | -| misc.c:84:6:84:13 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) | -| misc.c:84:6:84:13 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) | -| misc.c:84:16:84:16 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) | -| misc.c:84:19:84:19 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) | -| misc.c:85:9:85:13 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) | -| misc.c:86:9:86:9 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) | -| misc.c:87:10:87:10 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) | -| misc.c:88:9:88:9 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) | -| misc.c:88:9:88:17 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:16:6:16:10 | IR: misc1 | void misc1(int, int) | -| misc.c:171:15:171:15 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:168:6:168:8 | IR: vla | void vla() | -| misc.c:173:19:173:24 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | misc.c:168:6:168:8 | IR: vla | void vla() | -| misc.c:174:17:174:22 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | misc.c:168:6:168:8 | IR: vla | void vla() | -| misc.c:174:30:174:35 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | misc.c:168:6:168:8 | IR: vla | void vla() | -| misc.c:219:5:219:26 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:219:5:219:26 | IR: assign_designated_init | int assign_designated_init(someStruct*) | | misc.c:219:47:219:48 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | misc.c:219:5:219:26 | IR: assign_designated_init | int assign_designated_init(someStruct*) | -| misc.c:219:47:219:48 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | misc.c:219:5:219:26 | IR: assign_designated_init | int assign_designated_init(someStruct*) | -| misc.c:220:4:220:5 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | misc.c:219:5:219:26 | IR: assign_designated_init | int assign_designated_init(someStruct*) | -| ms_try_except.cpp:9:19:9:19 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | ms_try_except.cpp:2:6:2:18 | IR: ms_try_except | void ms_try_except(int) | -| ms_try_except.cpp:19:17:19:17 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | ms_try_except.cpp:2:6:2:18 | IR: ms_try_except | void ms_try_except(int) | -| ms_try_mix.cpp:14:16:14:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:10:6:10:18 | IR: ms_except_mix | void ms_except_mix(int) | -| ms_try_mix.cpp:15:13:15:14 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:10:6:10:18 | IR: ms_except_mix | void ms_except_mix(int) | -| ms_try_mix.cpp:16:13:16:19 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:10:6:10:18 | IR: ms_except_mix | void ms_except_mix(int) | -| ms_try_mix.cpp:18:16:18:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:10:6:10:18 | IR: ms_except_mix | void ms_except_mix(int) | -| ms_try_mix.cpp:21:16:21:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:10:6:10:18 | IR: ms_except_mix | void ms_except_mix(int) | -| ms_try_mix.cpp:24:12:24:15 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:10:6:10:18 | IR: ms_except_mix | void ms_except_mix(int) | -| ms_try_mix.cpp:31:16:31:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:27:6:27:19 | IR: ms_finally_mix | void ms_finally_mix(int) | -| ms_try_mix.cpp:32:13:32:14 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:27:6:27:19 | IR: ms_finally_mix | void ms_finally_mix(int) | -| ms_try_mix.cpp:33:13:33:19 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:27:6:27:19 | IR: ms_finally_mix | void ms_finally_mix(int) | -| ms_try_mix.cpp:35:16:35:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:27:6:27:19 | IR: ms_finally_mix | void ms_finally_mix(int) | -| ms_try_mix.cpp:38:16:38:19 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:27:6:27:19 | IR: ms_finally_mix | void ms_finally_mix(int) | -| ms_try_mix.cpp:41:12:41:15 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:27:6:27:19 | IR: ms_finally_mix | void ms_finally_mix(int) | -| ms_try_mix.cpp:51:5:51:11 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | ms_try_mix.cpp:47:6:47:28 | IR: ms_empty_finally_at_end | void ms_empty_finally_at_end() | | pointer_to_member.cpp:36:11:36:30 | Unary | Operand 'Unary' is not dominated by its definition in function '$@'. | pointer_to_member.cpp:32:6:32:14 | IR: pmIsConst | void pmIsConst() | | pointer_to_member.cpp:36:13:36:19 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | pointer_to_member.cpp:32:6:32:14 | IR: pmIsConst | void pmIsConst() | | pointer_to_member.cpp:36:22:36:28 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | pointer_to_member.cpp:32:6:32:14 | IR: pmIsConst | void pmIsConst() | -| stmt_expr.cpp:30:20:30:21 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | stmt_expr.cpp:21:6:21:6 | IR: g | void stmtexpr::g(int) | -| stmt_expr.cpp:31:16:31:18 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | stmt_expr.cpp:21:6:21:6 | IR: g | void stmtexpr::g(int) | | try_catch.cpp:21:13:21:24 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | try_catch.cpp:19:6:19:23 | IR: throw_from_nonstmt | void throw_from_nonstmt(int) | -| vla.c:3:5:3:8 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | vla.c:3:5:3:8 | IR: main | int main(int, char**) | | vla.c:3:27:3:30 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | vla.c:3:5:3:8 | IR: main | int main(int, char**) | -| vla.c:3:27:3:30 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | vla.c:3:5:3:8 | IR: main | int main(int, char**) | -| vla.c:5:16:5:19 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | vla.c:3:5:3:8 | IR: main | int main(int, char**) | -| vla.c:5:22:5:25 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | vla.c:3:5:3:8 | IR: main | int main(int, char**) | -| vla.c:5:27:5:30 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | vla.c:3:5:3:8 | IR: main | int main(int, char**) | -| vla.c:5:27:5:33 | Load | Operand 'Load' is not dominated by its definition in function '$@'. | vla.c:3:5:3:8 | IR: main | int main(int, char**) | -| vla.c:12:37:12:42 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | vla.c:11:6:11:16 | IR: vla_typedef | void vla_typedef() | -| vla.c:12:55:12:60 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | vla.c:11:6:11:16 | IR: vla_typedef | void vla_typedef() | -| vla.c:14:40:14:45 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | vla.c:11:6:11:16 | IR: vla_typedef | void vla_typedef() | -| vla.c:14:58:14:63 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | vla.c:11:6:11:16 | IR: vla_typedef | void vla_typedef() | -| vla.c:14:74:14:79 | Operand | Operand 'Operand' is not dominated by its definition in function '$@'. | vla.c:11:6:11:16 | IR: vla_typedef | void vla_typedef() | missingCanonicalLanguageType multipleCanonicalLanguageTypes missingIRType diff --git a/cpp/ql/test/library-tests/syntax-zoo/tellDifferent.expected b/cpp/ql/test/library-tests/syntax-zoo/tellDifferent.expected deleted file mode 100644 index ae6f3429892..00000000000 --- a/cpp/ql/test/library-tests/syntax-zoo/tellDifferent.expected +++ /dev/null @@ -1,14 +0,0 @@ -| pointer_to_member__pmIsConstT | pointer_to_member.cpp:41:3:44:29 | declaration | pointer_to_member.cpp:44:11:44:28 | initializer for pms | Standard edge, only from QL | uninstantiated | -| pointer_to_member__pmIsConstT | pointer_to_member.cpp:41:3:44:29 | declaration | pointer_to_member.cpp:45:1:45:1 | return ... | Standard edge, only from extractor | uninstantiated | -| pointer_to_member__pmIsConstT | pointer_to_member.cpp:44:11:44:28 | initializer for pms | pointer_to_member.cpp:44:14:44:18 | x1 | Standard edge, only from QL | uninstantiated | -| pointer_to_member__pmIsConstT | pointer_to_member.cpp:44:11:44:28 | {...} | pointer_to_member.cpp:45:1:45:1 | return ... | Standard edge, only from QL | uninstantiated | -| pointer_to_member__pmIsConstT | pointer_to_member.cpp:44:13:44:18 | & ... | pointer_to_member.cpp:44:22:44:26 | f1 | Standard edge, only from QL | uninstantiated | -| pointer_to_member__pmIsConstT | pointer_to_member.cpp:44:14:44:18 | x1 | pointer_to_member.cpp:44:13:44:18 | & ... | Standard edge, only from QL | uninstantiated | -| pointer_to_member__pmIsConstT | pointer_to_member.cpp:44:21:44:26 | & ... | pointer_to_member.cpp:44:11:44:28 | {...} | Standard edge, only from QL | uninstantiated | -| pointer_to_member__pmIsConstT | pointer_to_member.cpp:44:22:44:26 | f1 | pointer_to_member.cpp:44:21:44:26 | & ... | Standard edge, only from QL | uninstantiated | -| staticlocals__staticlocals_f2 | file://:0:0:0:0 | call to C | staticlocals.cpp:30:1:30:1 | return ... | Standard edge, only from QL | | -| staticlocals__staticlocals_f2 | file://:0:0:0:0 | initializer for c | file://:0:0:0:0 | call to C | Standard edge, only from QL | | -| staticlocals__staticlocals_f2 | staticlocals.cpp:29:5:29:17 | declaration | file://:0:0:0:0 | initializer for c | Standard edge, only from QL | | -| staticlocals__staticlocals_f3 | staticlocals.cpp:39:3:39:34 | declaration | staticlocals.cpp:39:18:39:33 | initializer for i | Standard edge, only from QL | uninstantiated | -| staticlocals__staticlocals_f3 | staticlocals.cpp:39:18:39:33 | initializer for i | staticlocals.cpp:39:18:39:33 | value | Standard edge, only from QL | uninstantiated | -| staticlocals__staticlocals_f3 | staticlocals.cpp:39:18:39:33 | value | staticlocals.cpp:40:1:40:1 | return ... | Standard edge, only from QL | uninstantiated | diff --git a/cpp/ql/test/library-tests/syntax-zoo/tellDifferent.ql b/cpp/ql/test/library-tests/syntax-zoo/tellDifferent.ql deleted file mode 100644 index f4b2509c17b..00000000000 --- a/cpp/ql/test/library-tests/syntax-zoo/tellDifferent.ql +++ /dev/null @@ -1,13 +0,0 @@ -import Compare - -string describeTemplate(ControlFlowNode node) { - node.isFromTemplateInstantiation(_) and - result = "instantiation" - or - node.isFromUninstantiatedTemplate(_) and - result = "uninstantiated" -} - -from ControlFlowNode n1, ControlFlowNode n2, string msg -where differentEdge(n1, n2, msg) -select getScopeName(n1), n1, n2, msg, concat(describeTemplate(n1), ", ") diff --git a/cpp/ql/test/library-tests/syntax-zoo/unaliased_ssa_sanity.expected b/cpp/ql/test/library-tests/syntax-zoo/unaliased_ssa_sanity.expected index 05d03810a40..e244faf3e34 100644 --- a/cpp/ql/test/library-tests/syntax-zoo/unaliased_ssa_sanity.expected +++ b/cpp/ql/test/library-tests/syntax-zoo/unaliased_ssa_sanity.expected @@ -1,10 +1,33 @@ missingOperand +| conditional_destructors.cpp:30:9:30:13 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:30:9:30:13 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:1:6:1:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:30:18:30:22 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:30:18:30:22 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:1:6:1:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:33:9:33:13 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:33:9:33:13 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:1:6:1:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:33:18:33:22 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:29:6:29:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:33:18:33:22 | IndirectMayWriteSideEffect: call to C1 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:1:6:1:7 | IR: f1 | void f1() | +| conditional_destructors.cpp:39:9:39:13 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | IR: f2 | void f2() | +| conditional_destructors.cpp:39:9:39:13 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:8:6:8:7 | IR: f2 | void f2() | +| conditional_destructors.cpp:39:18:39:22 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | IR: f2 | void f2() | +| conditional_destructors.cpp:39:18:39:22 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:8:6:8:7 | IR: f2 | void f2() | +| conditional_destructors.cpp:42:9:42:13 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | IR: f2 | void f2() | +| conditional_destructors.cpp:42:9:42:13 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:8:6:8:7 | IR: f2 | void f2() | +| conditional_destructors.cpp:42:18:42:22 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | conditional_destructors.cpp:38:6:38:7 | IR: f2 | void f2() | +| conditional_destructors.cpp:42:18:42:22 | IndirectMayWriteSideEffect: call to C2 | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | forstmt.cpp:8:6:8:7 | IR: f2 | void f2() | +| cpp11.cpp:77:19:77:21 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:76:8:76:8 | IR: apply | void lambda::apply<(void lambda::apply2(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)>(lambda::Val, (void lambda::apply2(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)) | +| cpp11.cpp:82:11:82:14 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:81:8:81:8 | IR: apply2 | void lambda::apply2(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val) | +| cpp11.cpp:82:17:82:55 | IndirectMayWriteSideEffect: call to (constructor) | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:81:8:81:8 | IR: apply2 | void lambda::apply2(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val) | +| cpp11.cpp:82:45:82:48 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:82:20:82:20 | IR: operator() | void (void lambda::apply2(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)::operator()(lambda::Val) const | +| cpp11.cpp:82:51:82:51 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:82:20:82:20 | IR: operator() | void (void lambda::apply2(int(*)(lambda::Val, lambda::Val), lambda::Val, lambda::Val))::(lambda [] type at line 82, col. 17)::operator()(lambda::Val) const | +| cpp11.cpp:88:25:88:30 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:87:8:87:11 | IR: main | void lambda::main() | +| cpp11.cpp:88:33:88:38 | IndirectMayWriteSideEffect: call to Val | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | cpp11.cpp:87:8:87:11 | IR: main | void lambda::main() | +| destructors.cpp:51:36:51:38 | IndirectMayWriteSideEffect: call to C | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | destructors.cpp:49:7:49:7 | IR: f | int cond_destruct::f(int) | +| ir.cpp:809:7:809:13 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | +| ir.cpp:810:7:810:26 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | +| ir.cpp:823:7:823:13 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | +| ir.cpp:824:7:824:26 | IndirectMayWriteSideEffect: call to Base | Instruction 'IndirectMayWriteSideEffect' is missing an expected operand with tag 'Address' in function '$@'. | ir.cpp:799:6:799:25 | IR: HierarchyConversions | void HierarchyConversions() | | misc.c:125:5:125:11 | CopyValue: (statement expression) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | misc.c:97:6:97:10 | IR: misc3 | void misc3() | -| parameterinitializer.cpp:27:3:27:6 | IndirectReadSideEffect: my_c | Instruction 'IndirectReadSideEffect' is missing an expected operand with tag 'SideEffect' in function '$@'. | allocators.cpp:14:5:14:8 | IR: main | int main() | -| parameterinitializer.cpp:27:3:27:6 | IndirectReadSideEffect: my_c | Instruction 'IndirectReadSideEffect' is missing an expected operand with tag 'SideEffect' in function '$@'. | no_dynamic_init.cpp:9:5:9:8 | IR: main | int main() | -| parameterinitializer.cpp:27:3:27:6 | IndirectReadSideEffect: my_c | Instruction 'IndirectReadSideEffect' is missing an expected operand with tag 'SideEffect' in function '$@'. | parameterinitializer.cpp:18:5:18:8 | IR: main | int main() | -| parameterinitializer.cpp:27:3:27:6 | IndirectReadSideEffect: my_c | Instruction 'IndirectReadSideEffect' is missing an expected operand with tag 'SideEffect' in function '$@'. | stream_it.cpp:16:5:16:8 | IR: main | int main() | -| try_catch.cpp:13:5:13:16 | ThrowValue: throw ... | Instruction 'ThrowValue' is missing an expected operand with tag 'Load' in function '$@'. | try_catch.cpp:11:6:11:17 | IR: bypass_catch | void bypass_catch() | unexpectedOperand duplicateOperand missingPhiOperand @@ -19,20 +42,21 @@ missingPhiOperand | range_analysis.c:389:3:389:32 | Phi: return ... | range_analysis.c:387:38:387:38 | Constant: 5 | | range_analysis.c:389:3:389:32 | Phi: return ... | range_analysis.c:387:38:387:38 | Constant: 5 | missingOperandType +duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor | VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | -| condition_decls.cpp:16:19:16:20 | CallSideEffect: call to BoxedInt | -| condition_decls.cpp:26:23:26:24 | CallSideEffect: call to BoxedInt | -| condition_decls.cpp:41:22:41:23 | CallSideEffect: call to BoxedInt | -| condition_decls.cpp:48:52:48:53 | CallSideEffect: call to BoxedInt | +| condition_decls.cpp:16:19:16:20 | IndirectMayWriteSideEffect: call to BoxedInt | +| condition_decls.cpp:26:23:26:24 | IndirectMayWriteSideEffect: call to BoxedInt | +| condition_decls.cpp:41:22:41:23 | IndirectMayWriteSideEffect: call to BoxedInt | +| condition_decls.cpp:48:52:48:53 | IndirectMayWriteSideEffect: call to BoxedInt | | cpp17.cpp:15:11:15:21 | Convert: (void *)... | | misc.c:171:10:171:13 | Uninitialized: definition of str2 | | misc.c:219:47:219:48 | InitializeIndirection: sp | | ms_try_except.cpp:3:9:3:9 | Uninitialized: definition of x | -| ms_try_mix.cpp:11:12:11:15 | CallSideEffect: call to C | -| ms_try_mix.cpp:28:12:28:15 | CallSideEffect: call to C | -| ms_try_mix.cpp:48:10:48:13 | CallSideEffect: call to C | +| ms_try_mix.cpp:11:12:11:15 | IndirectMayWriteSideEffect: call to C | +| ms_try_mix.cpp:28:12:28:15 | IndirectMayWriteSideEffect: call to C | +| ms_try_mix.cpp:48:10:48:13 | IndirectMayWriteSideEffect: call to C | | pointer_to_member.cpp:36:11:36:30 | FieldAddress: {...} | | stmt_expr.cpp:27:5:27:15 | Store: ... = ... | | vla.c:5:9:5:14 | Uninitialized: definition of matrix | diff --git a/cpp/ql/test/library-tests/templates/CPP-172-template-members/test.cpp b/cpp/ql/test/library-tests/templates/CPP-172-template-members/test.cpp new file mode 100644 index 00000000000..9a624d5d9f0 --- /dev/null +++ b/cpp/ql/test/library-tests/templates/CPP-172-template-members/test.cpp @@ -0,0 +1,19 @@ + + +class A { +public: + void foo(); + int k; +}; + +class B { +public: + template + B(T x) { + int k = x.k; + x.foo(); + } +}; + +A a; +B b(a); diff --git a/cpp/ql/test/library-tests/templates/CPP-172-template-members/test.expected b/cpp/ql/test/library-tests/templates/CPP-172-template-members/test.expected new file mode 100644 index 00000000000..29d00dc147a --- /dev/null +++ b/cpp/ql/test/library-tests/templates/CPP-172-template-members/test.expected @@ -0,0 +1,2 @@ +| test.cpp:13:15:13:15 | k | +| test.cpp:14:7:14:9 | foo | diff --git a/cpp/ql/test/library-tests/templates/CPP-172-template-members/test.ql b/cpp/ql/test/library-tests/templates/CPP-172-template-members/test.ql new file mode 100644 index 00000000000..233c7cdce8d --- /dev/null +++ b/cpp/ql/test/library-tests/templates/CPP-172-template-members/test.ql @@ -0,0 +1,4 @@ +import cpp + +from Literal l +select l diff --git a/cpp/ql/test/library-tests/templates/CPP-202/template_args.expected b/cpp/ql/test/library-tests/templates/CPP-202/template_args.expected index 0f20692d443..f38eef610e4 100644 --- a/cpp/ql/test/library-tests/templates/CPP-202/template_args.expected +++ b/cpp/ql/test/library-tests/templates/CPP-202/template_args.expected @@ -1,6 +1,6 @@ | file://:0:0:0:0 | __va_list_tag | | -| test.cpp:3:8:3:9 | s1<> | | -| test.cpp:3:8:3:9 | s1<> | | +| test.cpp:3:8:3:9 | s1<> | {...} | +| test.cpp:3:8:3:9 | s1<> | (null) | | test.cpp:5:8:5:9 | s2 | T | | test.cpp:5:8:5:9 | s2 | T | | test.cpp:7:8:7:9 | s3> | (unnamed) | diff --git a/cpp/ql/test/library-tests/templates/CPP-204/element.expected b/cpp/ql/test/library-tests/templates/CPP-204/element.expected index 6cb84a117d5..44384471af9 100644 --- a/cpp/ql/test/library-tests/templates/CPP-204/element.expected +++ b/cpp/ql/test/library-tests/templates/CPP-204/element.expected @@ -1,6 +1,12 @@ | file://:0:0:0:0 | | | file://:0:0:0:0 | 0 | | file://:0:0:0:0 | (global namespace) | +| file://:0:0:0:0 | B | +| file://:0:0:0:0 | X | +| file://:0:0:0:0 | X | +| file://:0:0:0:0 | X | +| file://:0:0:0:0 | X | +| file://:0:0:0:0 | Y | | file://:0:0:0:0 | __va_list_tag | | file://:0:0:0:0 | __va_list_tag & | | file://:0:0:0:0 | __va_list_tag && | diff --git a/cpp/ql/test/library-tests/templates/instantiations_functions/elements.expected b/cpp/ql/test/library-tests/templates/instantiations_functions/elements.expected index 802903a40b6..99a6201c59c 100644 --- a/cpp/ql/test/library-tests/templates/instantiations_functions/elements.expected +++ b/cpp/ql/test/library-tests/templates/instantiations_functions/elements.expected @@ -317,8 +317,8 @@ | test.cpp:19:9:19:24 | call to expression | | test.cpp:19:9:19:25 | ExprStmt | | test.cpp:19:9:19:25 | ExprStmt | -| test.cpp:19:15:19:18 | Unknown literal | | test.cpp:19:15:19:18 | call to funx | +| test.cpp:19:15:19:18 | funx | | test.cpp:19:20:19:23 | (reference to) | | test.cpp:19:20:19:23 | valx | | test.cpp:19:20:19:23 | valx | @@ -356,8 +356,8 @@ | test.cpp:30:13:30:22 | call to expression | | test.cpp:30:13:30:23 | ExprStmt | | test.cpp:30:13:30:23 | ExprStmt | -| test.cpp:30:15:30:20 | Unknown literal | | test.cpp:30:15:30:20 | call to eparse | +| test.cpp:30:15:30:20 | eparse | | test.cpp:31:9:31:9 | return ... | | test.cpp:31:9:31:9 | return ... | | test.cpp:34:6:34:11 | define | diff --git a/cpp/ql/test/library-tests/templates/nontype_instantiations/classes/test.cpp b/cpp/ql/test/library-tests/templates/nontype_instantiations/classes/test.cpp new file mode 100644 index 00000000000..4f16f623daf --- /dev/null +++ b/cpp/ql/test/library-tests/templates/nontype_instantiations/classes/test.cpp @@ -0,0 +1,4 @@ +template +class Int { }; + +Int<10> i; diff --git a/cpp/ql/test/library-tests/templates/nontype_instantiations/classes/test.expected b/cpp/ql/test/library-tests/templates/nontype_instantiations/classes/test.expected new file mode 100644 index 00000000000..ffa9bfb2cf4 --- /dev/null +++ b/cpp/ql/test/library-tests/templates/nontype_instantiations/classes/test.expected @@ -0,0 +1,2 @@ +| test.cpp:2:7:2:9 | Int<10> | file://:0:0:0:0 | int | test.cpp:4:5:4:6 | 10 | +| test.cpp:2:7:2:9 | Int | file://:0:0:0:0 | int | file://:0:0:0:0 | i | diff --git a/cpp/ql/test/library-tests/templates/nontype_instantiations/classes/test.ql b/cpp/ql/test/library-tests/templates/nontype_instantiations/classes/test.ql new file mode 100644 index 00000000000..900424eb501 --- /dev/null +++ b/cpp/ql/test/library-tests/templates/nontype_instantiations/classes/test.ql @@ -0,0 +1,4 @@ +import cpp + +from Class c +select c, c.getATemplateArgumentKind(), c.getATemplateArgument() diff --git a/cpp/ql/test/library-tests/templates/nontype_instantiations/functions/test.cpp b/cpp/ql/test/library-tests/templates/nontype_instantiations/functions/test.cpp new file mode 100644 index 00000000000..625258906db --- /dev/null +++ b/cpp/ql/test/library-tests/templates/nontype_instantiations/functions/test.cpp @@ -0,0 +1,5 @@ +// semmle-extractor-options: --edg --trap_container=folder --edg --trap-compression=none +template +int addToSelf() { return i + i; }; + +int bar() { return addToSelf<10>(); } diff --git a/cpp/ql/test/library-tests/templates/nontype_instantiations/functions/test.expected b/cpp/ql/test/library-tests/templates/nontype_instantiations/functions/test.expected new file mode 100644 index 00000000000..493e9f03b20 --- /dev/null +++ b/cpp/ql/test/library-tests/templates/nontype_instantiations/functions/test.expected @@ -0,0 +1,2 @@ +| test.cpp:3:5:3:5 | addToSelf | file://:0:0:0:0 | int | test.cpp:5:30:5:31 | 10 | +| test.cpp:3:5:3:13 | addToSelf | file://:0:0:0:0 | int | file://:0:0:0:0 | i | diff --git a/cpp/ql/test/library-tests/templates/nontype_instantiations/functions/test.ql b/cpp/ql/test/library-tests/templates/nontype_instantiations/functions/test.ql new file mode 100644 index 00000000000..98f8a4112d4 --- /dev/null +++ b/cpp/ql/test/library-tests/templates/nontype_instantiations/functions/test.ql @@ -0,0 +1,4 @@ +import cpp + +from Function f +select f, f.getATemplateArgumentKind(), f.getATemplateArgument() diff --git a/cpp/ql/test/library-tests/templates/nontype_instantiations/general/test.cpp b/cpp/ql/test/library-tests/templates/nontype_instantiations/general/test.cpp new file mode 100644 index 00000000000..1baabe3ca30 --- /dev/null +++ b/cpp/ql/test/library-tests/templates/nontype_instantiations/general/test.cpp @@ -0,0 +1,19 @@ +// semmle-extractor-options: --edg --trap_container=folder --edg --trap-compression=none +template +struct C { }; + +static const int one1 = 1, one2 = 1; +C c = C(); +C e; + +template +struct D { }; + +D a; +D b; + +template +struct E { }; + +E z; + diff --git a/cpp/ql/test/library-tests/templates/nontype_instantiations/general/test.expected b/cpp/ql/test/library-tests/templates/nontype_instantiations/general/test.expected new file mode 100644 index 00000000000..fa5df86f68f --- /dev/null +++ b/cpp/ql/test/library-tests/templates/nontype_instantiations/general/test.expected @@ -0,0 +1,13 @@ +| test.cpp:3:8:3:8 | C<1> | 0 | int | test.cpp:5:25:5:25 | 1 | +| test.cpp:3:8:3:8 | C<2> | 0 | int | file://:0:0:0:0 | 2 | +| test.cpp:3:8:3:8 | C | 0 | int | file://:0:0:0:0 | x | +| test.cpp:10:8:10:8 | D | 0 | | test.cpp:9:19:9:19 | T | +| test.cpp:10:8:10:8 | D | 1 | T | file://:0:0:0:0 | X | +| test.cpp:10:8:10:8 | D | 0 | | file://:0:0:0:0 | int | +| test.cpp:10:8:10:8 | D | 1 | int | test.cpp:12:8:12:8 | 2 | +| test.cpp:10:8:10:8 | D | 0 | | file://:0:0:0:0 | long | +| test.cpp:10:8:10:8 | D | 1 | long | file://:0:0:0:0 | 2 | +| test.cpp:16:8:16:8 | E | 0 | | test.cpp:15:19:15:19 | T | +| test.cpp:16:8:16:8 | E | 1 | T * | file://:0:0:0:0 | X | +| test.cpp:16:8:16:8 | E | 0 | | file://:0:0:0:0 | int | +| test.cpp:16:8:16:8 | E | 1 | int * | file://:0:0:0:0 | 0 | diff --git a/cpp/ql/test/library-tests/templates/nontype_instantiations/general/test.ql b/cpp/ql/test/library-tests/templates/nontype_instantiations/general/test.ql new file mode 100644 index 00000000000..68d597e0f98 --- /dev/null +++ b/cpp/ql/test/library-tests/templates/nontype_instantiations/general/test.ql @@ -0,0 +1,14 @@ +import cpp + +string maybeGetTemplateArgumentKind(Declaration d, int i) { + ( + if exists(d.getTemplateArgumentKind(i)) + then result = d.getTemplateArgumentKind(i).toString() + else result = "" + ) and + i = [0 .. d.getNumberOfTemplateArguments()] +} + +from Declaration d, int i +where i >= 0 and i < d.getNumberOfTemplateArguments() +select d, i, maybeGetTemplateArgumentKind(d, i), d.getTemplateArgument(i) diff --git a/cpp/ql/test/library-tests/types/error/exprs.expected b/cpp/ql/test/library-tests/types/error/exprs.expected new file mode 100644 index 00000000000..7d280ac30dd --- /dev/null +++ b/cpp/ql/test/library-tests/types/error/exprs.expected @@ -0,0 +1 @@ +| file://:0:0:0:0 | | file://:0:0:0:0 | error | diff --git a/cpp/ql/test/library-tests/types/error/exprs.ql b/cpp/ql/test/library-tests/types/error/exprs.ql new file mode 100644 index 00000000000..278f3ca004a --- /dev/null +++ b/cpp/ql/test/library-tests/types/error/exprs.ql @@ -0,0 +1,5 @@ +import cpp + +from Expr e, Type t +where t = e.getType() +select e, t diff --git a/cpp/ql/test/library-tests/types/error/test.cpp b/cpp/ql/test/library-tests/types/error/test.cpp new file mode 100644 index 00000000000..50c89773ebf --- /dev/null +++ b/cpp/ql/test/library-tests/types/error/test.cpp @@ -0,0 +1,3 @@ +// semmle-extractor-options: --expect_errors + +int &intref = 0; // ErrorExpr with ErroneousType diff --git a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ir_gvn.expected b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ir_gvn.expected index 01d36b53198..452704f9698 100644 --- a/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ir_gvn.expected +++ b/cpp/ql/test/library-tests/valuenumbering/GlobalValueNumbering/ir_gvn.expected @@ -67,7 +67,8 @@ test.cpp: # 1| valnum = unique # 1| v0_33(void) = ReturnValue : &:r0_32 # 1| v0_34(void) = UnmodeledUse : mu* -# 1| v0_35(void) = ExitFunction : +# 1| v0_35(void) = AliasedUse : ~m0_1 +# 1| v0_36(void) = ExitFunction : # 12| int test01(int, int) # 12| Block 0 @@ -149,7 +150,8 @@ test.cpp: # 12| valnum = unique # 12| v0_39(void) = ReturnValue : &:r0_38 # 12| v0_40(void) = UnmodeledUse : mu* -# 12| v0_41(void) = ExitFunction : +# 12| v0_41(void) = AliasedUse : ~m0_1 +# 12| v0_42(void) = ExitFunction : # 25| int test02(int, int) # 25| Block 0 @@ -238,7 +240,8 @@ test.cpp: # 25| valnum = unique # 25| v0_43(void) = ReturnValue : &:r0_42 # 25| v0_44(void) = UnmodeledUse : mu* -# 25| v0_45(void) = ExitFunction : +# 25| v0_45(void) = AliasedUse : ~m0_26 +# 25| v0_46(void) = ExitFunction : # 39| int test03(int, int, int*) # 39| Block 0 @@ -303,45 +306,48 @@ test.cpp: # 44| valnum = r0_7 # 44| r0_30(int *) = Load : &:r0_29, m0_8 # 44| valnum = m0_8 -# 44| m0_31(int) = Store : &:r0_30, r0_28 +# 44| r0_31(glval) = CopyValue : r0_30 +# 44| valnum = m0_8 +# 44| m0_32(int) = Store : &:r0_31, r0_28 # 44| valnum = r0_28 -# 44| m0_32(unknown) = Chi : total:m0_11, partial:m0_31 +# 44| m0_33(unknown) = Chi : total:m0_11, partial:m0_32 # 44| valnum = unique -# 45| r0_33(glval) = VariableAddress[p0] : +# 45| r0_34(glval) = VariableAddress[p0] : # 45| valnum = r0_3 -# 45| r0_34(int) = Load : &:r0_33, m0_4 +# 45| r0_35(int) = Load : &:r0_34, m0_4 # 45| valnum = m0_4 -# 45| r0_35(glval) = VariableAddress[p1] : +# 45| r0_36(glval) = VariableAddress[p1] : # 45| valnum = r0_5 -# 45| r0_36(int) = Load : &:r0_35, m0_6 +# 45| r0_37(int) = Load : &:r0_36, m0_6 # 45| valnum = m0_6 -# 45| r0_37(int) = Add : r0_34, r0_36 +# 45| r0_38(int) = Add : r0_35, r0_37 # 45| valnum = r0_22 -# 45| r0_38(glval) = VariableAddress[global03] : +# 45| r0_39(glval) = VariableAddress[global03] : # 45| valnum = r0_23 -# 45| r0_39(int) = Load : &:r0_38, ~m0_32 +# 45| r0_40(int) = Load : &:r0_39, ~m0_33 # 45| valnum = unique -# 45| r0_40(int) = Add : r0_37, r0_39 -# 45| valnum = r0_40 -# 45| r0_41(glval) = VariableAddress[x] : +# 45| r0_41(int) = Add : r0_38, r0_40 +# 45| valnum = r0_41 +# 45| r0_42(glval) = VariableAddress[x] : # 45| valnum = r0_12 -# 45| m0_42(int) = Store : &:r0_41, r0_40 -# 45| valnum = r0_40 -# 46| r0_43(glval) = VariableAddress[x] : +# 45| m0_43(int) = Store : &:r0_42, r0_41 +# 45| valnum = r0_41 +# 46| r0_44(glval) = VariableAddress[x] : # 46| valnum = r0_12 -# 46| r0_44(int) = Load : &:r0_43, m0_42 -# 46| valnum = r0_40 -# 46| r0_45(glval) = VariableAddress[y] : +# 46| r0_45(int) = Load : &:r0_44, m0_43 +# 46| valnum = r0_41 +# 46| r0_46(glval) = VariableAddress[y] : # 46| valnum = r0_14 -# 46| m0_46(int) = Store : &:r0_45, r0_44 -# 46| valnum = r0_40 -# 47| v0_47(void) = NoOp : -# 39| v0_48(void) = ReturnIndirection : &:r0_9, ~m0_32 -# 39| r0_49(glval) = VariableAddress[#return] : +# 46| m0_47(int) = Store : &:r0_46, r0_45 +# 46| valnum = r0_41 +# 47| v0_48(void) = NoOp : +# 39| v0_49(void) = ReturnIndirection : &:r0_9, ~m0_33 +# 39| r0_50(glval) = VariableAddress[#return] : # 39| valnum = unique -# 39| v0_50(void) = ReturnValue : &:r0_49 -# 39| v0_51(void) = UnmodeledUse : mu* -# 39| v0_52(void) = ExitFunction : +# 39| v0_51(void) = ReturnValue : &:r0_50 +# 39| v0_52(void) = UnmodeledUse : mu* +# 39| v0_53(void) = AliasedUse : ~m0_33 +# 39| v0_54(void) = ExitFunction : # 49| unsigned int my_strspn(char const*, char const*) # 49| Block 0 @@ -517,7 +523,8 @@ test.cpp: # 49| valnum = r9_1 # 49| v9_8(void) = ReturnValue : &:r9_7, m9_4 # 49| v9_9(void) = UnmodeledUse : mu* -# 49| v9_10(void) = ExitFunction : +# 49| v9_10(void) = AliasedUse : ~m0_12 +# 49| v9_11(void) = ExitFunction : # 75| void test04(two_values*) # 75| Block 0 @@ -608,7 +615,8 @@ test.cpp: # 75| v2_2(void) = ReturnIndirection : &:r0_5, ~m2_0 # 75| v2_3(void) = ReturnVoid : # 75| v2_4(void) = UnmodeledUse : mu* -# 75| v2_5(void) = ExitFunction : +# 75| v2_5(void) = AliasedUse : ~m2_0 +# 75| v2_6(void) = ExitFunction : # 84| void test05(int, int, void*) # 84| Block 0 @@ -666,7 +674,8 @@ test.cpp: # 84| v1_6(void) = ReturnIndirection : &:r0_9, ~m0_11 # 84| v1_7(void) = ReturnVoid : # 84| v1_8(void) = UnmodeledUse : mu* -# 84| v1_9(void) = ExitFunction : +# 84| v1_9(void) = AliasedUse : ~m0_11 +# 84| v1_10(void) = ExitFunction : # 88| Block 2 # 88| r2_0(glval) = VariableAddress[x] : @@ -705,89 +714,93 @@ test.cpp: # 92| valnum = r0_3 # 92| m0_6(int) = Store : &:r0_5, r0_4 # 92| valnum = r0_4 -# 92| m0_7(int) = Store : &:r0_3, r0_4 +# 92| r0_7(int) = CopyValue : r0_4 # 92| valnum = r0_4 -# 93| r0_8(glval) = VariableAddress[#return] : -# 93| valnum = r0_8 -# 93| r0_9(glval) = VariableAddress[x] : +# 92| m0_8(int) = Store : &:r0_3, r0_7 +# 92| valnum = r0_4 +# 93| r0_9(glval) = VariableAddress[#return] : +# 93| valnum = r0_9 +# 93| r0_10(glval) = VariableAddress[x] : # 93| valnum = r0_3 -# 93| r0_10(int) = Load : &:r0_9, m0_7 +# 93| r0_11(int) = Load : &:r0_10, m0_8 # 93| valnum = r0_4 -# 93| m0_11(int) = Store : &:r0_8, r0_10 +# 93| m0_12(int) = Store : &:r0_9, r0_11 # 93| valnum = r0_4 -# 91| r0_12(glval) = VariableAddress[#return] : -# 91| valnum = r0_8 -# 91| v0_13(void) = ReturnValue : &:r0_12, m0_11 -# 91| v0_14(void) = UnmodeledUse : mu* -# 91| v0_15(void) = ExitFunction : +# 91| r0_13(glval) = VariableAddress[#return] : +# 91| valnum = r0_9 +# 91| v0_14(void) = ReturnValue : &:r0_13, m0_12 +# 91| v0_15(void) = UnmodeledUse : mu* +# 91| v0_16(void) = AliasedUse : ~m0_1 +# 91| v0_17(void) = ExitFunction : # 104| int inheritanceConversions(Derived*) # 104| Block 0 -# 104| v0_0(void) = EnterFunction : -# 104| m0_1(unknown) = AliasedDefinition : +# 104| v0_0(void) = EnterFunction : +# 104| m0_1(unknown) = AliasedDefinition : # 104| valnum = unique -# 104| mu0_2(unknown) = UnmodeledDefinition : +# 104| mu0_2(unknown) = UnmodeledDefinition : # 104| valnum = unique -# 104| r0_3(glval) = VariableAddress[pd] : +# 104| r0_3(glval) = VariableAddress[pd] : # 104| valnum = r0_3 -# 104| m0_4(Derived *) = InitializeParameter[pd] : &:r0_3 +# 104| m0_4(Derived *) = InitializeParameter[pd] : &:r0_3 # 104| valnum = m0_4 -# 104| r0_5(Derived *) = Load : &:r0_3, m0_4 +# 104| r0_5(Derived *) = Load : &:r0_3, m0_4 # 104| valnum = m0_4 -# 104| m0_6(unknown) = InitializeIndirection[pd] : &:r0_5 +# 104| m0_6(unknown) = InitializeIndirection[pd] : &:r0_5 # 104| valnum = unique -# 104| m0_7(unknown) = Chi : total:m0_1, partial:m0_6 +# 104| m0_7(unknown) = Chi : total:m0_1, partial:m0_6 # 104| valnum = unique -# 105| r0_8(glval) = VariableAddress[x] : +# 105| r0_8(glval) = VariableAddress[x] : # 105| valnum = unique -# 105| r0_9(glval) = VariableAddress[pd] : +# 105| r0_9(glval) = VariableAddress[pd] : # 105| valnum = r0_3 -# 105| r0_10(Derived *) = Load : &:r0_9, m0_4 +# 105| r0_10(Derived *) = Load : &:r0_9, m0_4 # 105| valnum = m0_4 -# 105| r0_11(Base *) = ConvertToBase[Derived : Base] : r0_10 +# 105| r0_11(Base *) = ConvertToNonVirtualBase[Derived : Base] : r0_10 # 105| valnum = r0_11 -# 105| r0_12(glval) = FieldAddress[b] : r0_11 +# 105| r0_12(glval) = FieldAddress[b] : r0_11 # 105| valnum = r0_12 -# 105| r0_13(int) = Load : &:r0_12, ~m0_7 +# 105| r0_13(int) = Load : &:r0_12, ~m0_7 # 105| valnum = r0_13 -# 105| m0_14(int) = Store : &:r0_8, r0_13 +# 105| m0_14(int) = Store : &:r0_8, r0_13 # 105| valnum = r0_13 -# 106| r0_15(glval) = VariableAddress[pb] : +# 106| r0_15(glval) = VariableAddress[pb] : # 106| valnum = r0_15 -# 106| r0_16(glval) = VariableAddress[pd] : +# 106| r0_16(glval) = VariableAddress[pd] : # 106| valnum = r0_3 -# 106| r0_17(Derived *) = Load : &:r0_16, m0_4 +# 106| r0_17(Derived *) = Load : &:r0_16, m0_4 # 106| valnum = m0_4 -# 106| r0_18(Base *) = ConvertToBase[Derived : Base] : r0_17 +# 106| r0_18(Base *) = ConvertToNonVirtualBase[Derived : Base] : r0_17 # 106| valnum = r0_11 -# 106| m0_19(Base *) = Store : &:r0_15, r0_18 +# 106| m0_19(Base *) = Store : &:r0_15, r0_18 # 106| valnum = r0_11 -# 107| r0_20(glval) = VariableAddress[y] : +# 107| r0_20(glval) = VariableAddress[y] : # 107| valnum = r0_20 -# 107| r0_21(glval) = VariableAddress[pb] : +# 107| r0_21(glval) = VariableAddress[pb] : # 107| valnum = r0_15 -# 107| r0_22(Base *) = Load : &:r0_21, m0_19 +# 107| r0_22(Base *) = Load : &:r0_21, m0_19 # 107| valnum = r0_11 -# 107| r0_23(glval) = FieldAddress[b] : r0_22 +# 107| r0_23(glval) = FieldAddress[b] : r0_22 # 107| valnum = r0_12 -# 107| r0_24(int) = Load : &:r0_23, ~m0_7 +# 107| r0_24(int) = Load : &:r0_23, ~m0_7 # 107| valnum = r0_24 -# 107| m0_25(int) = Store : &:r0_20, r0_24 +# 107| m0_25(int) = Store : &:r0_20, r0_24 # 107| valnum = r0_24 -# 109| r0_26(glval) = VariableAddress[#return] : +# 109| r0_26(glval) = VariableAddress[#return] : # 109| valnum = r0_26 -# 109| r0_27(glval) = VariableAddress[y] : +# 109| r0_27(glval) = VariableAddress[y] : # 109| valnum = r0_20 -# 109| r0_28(int) = Load : &:r0_27, m0_25 +# 109| r0_28(int) = Load : &:r0_27, m0_25 # 109| valnum = r0_24 -# 109| m0_29(int) = Store : &:r0_26, r0_28 +# 109| m0_29(int) = Store : &:r0_26, r0_28 # 109| valnum = r0_24 -# 104| v0_30(void) = ReturnIndirection : &:r0_5, ~m0_7 -# 104| r0_31(glval) = VariableAddress[#return] : +# 104| v0_30(void) = ReturnIndirection : &:r0_5, ~m0_7 +# 104| r0_31(glval) = VariableAddress[#return] : # 104| valnum = r0_26 -# 104| v0_32(void) = ReturnValue : &:r0_31, m0_29 -# 104| v0_33(void) = UnmodeledUse : mu* -# 104| v0_34(void) = ExitFunction : +# 104| v0_32(void) = ReturnValue : &:r0_31, m0_29 +# 104| v0_33(void) = UnmodeledUse : mu* +# 104| v0_34(void) = AliasedUse : ~m0_7 +# 104| v0_35(void) = ExitFunction : # 112| void test06() # 112| Block 0 @@ -807,4 +820,5 @@ test.cpp: # 117| v0_7(void) = NoOp : # 112| v0_8(void) = ReturnVoid : # 112| v0_9(void) = UnmodeledUse : mu* -# 112| v0_10(void) = ExitFunction : +# 112| v0_10(void) = AliasedUse : ~m0_1 +# 112| v0_11(void) = ExitFunction : diff --git a/cpp/ql/test/qlpack.yml b/cpp/ql/test/qlpack.yml new file mode 100644 index 00000000000..36dcb70d4ef --- /dev/null +++ b/cpp/ql/test/qlpack.yml @@ -0,0 +1,3 @@ +name: codeql-cpp-tests +version: 0.0.0 +libraryPathDependencies: codeql-cpp diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/BadAdditionOverflowCheck.expected b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/BadAdditionOverflowCheck.expected index 9cb1aaa02af..920a1f820f8 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/BadAdditionOverflowCheck.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/BadAdditionOverflowCheck.expected @@ -1 +1,3 @@ +| SignedOverflowCheck.cpp:35:9:35:23 | ... < ... | Bad overflow check. | +| SignedOverflowCheck.cpp:113:12:113:66 | ... < ... | Bad overflow check. | | test.cpp:3:11:3:19 | ... < ... | Bad overflow check. | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/PointlessSelfComparison.expected b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/PointlessSelfComparison.expected index 2318c286c60..8d1911edfcd 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/PointlessSelfComparison.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/PointlessSelfComparison.expected @@ -1,3 +1,4 @@ +| templates.cpp:17:5:17:25 | ... < ... | Self comparison. | | test.cpp:13:11:13:21 | ... == ... | Self comparison. | | test.cpp:79:11:79:32 | ... == ... | Self comparison. | | test.cpp:83:10:83:15 | ... == ... | Self comparison. | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/SignedOverflowCheck.cpp b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/SignedOverflowCheck.cpp new file mode 100644 index 00000000000..e359fb098eb --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/SignedOverflowCheck.cpp @@ -0,0 +1,130 @@ +// Signed-comparison tests + +/* 1. Signed-signed comparison. The semantics are undefined. */ +bool cannotHoldAnother8(int n1) { + // clang 8.0.0 -O2: deleted (silently) + // gcc 9.2 -O2: deleted (silently) + // msvc 19.22 /O2: not deleted + return n1 + 8 < n1; // BAD +} + +/* 2. Signed comparison with a narrower unsigned type. The narrower + type gets promoted to the (signed) larger type, and so the + semantics are undefined. */ +bool cannotHoldAnotherUShort(int n1, unsigned short delta) { + // clang 8.0.0 -O2: deleted (silently) + // gcc 9.2 -O2: deleted (silently) + // msvc 19.22 /O2: not deleted + return n1 + delta < n1; // BAD +} + +/* 3. Signed comparison with a non-narrower unsigned type. The + signed type gets promoted to (a possibly wider) unsigned type, + and the resulting comparison is unsigned. */ +bool cannotHoldAnotherUInt(int n1, unsigned int delta) { + // clang 8.0.0 -O2: not deleted + // gcc 9.2 -O2: not deleted + // msvc 19.22 /O2: not deleted + return n1 + delta < n1; // GOOD +} + +bool shortShort1(unsigned short n1, unsigned short delta) { + + // BAD [BadAdditionOverflowCheck.ql] + // GOOD [SigneOverflowCheck.ql]: Test always fails, but will never overflow. + return n1 + delta < n1; +} + +bool shortShort2(unsigned short n1, unsigned short delta) { + // clang 8.0.0 -O2: not deleted + // gcc 9.2 -O2: not deleted + // msvc 19.22 /O2: not deleted + return (unsigned short)(n1 + delta) < n1; // GOOD +} + +/* Distinguish `varname` from `ptr->varname` and `obj.varname` */ +struct N { + int n1; +} n, *np; + +bool shortStruct1(unsigned short n1, unsigned short delta) { + return np->n1 + delta < n1; // GOOD +} + +bool shortStruct1a(unsigned short n1, unsigned short delta) { + return n1 + delta < n.n1; // GOOD +} + +bool shortStruct2(unsigned short n1, unsigned short delta) { + return (unsigned short)(n1 + delta) < n.n1; // GOOD +} + +struct se { + int xPos; + short yPos; + short xSize; + short ySize; +}; + +extern se *getSo(void); + +bool func1(se *so) { + se *o = getSo(); + if (so->xPos + so->xSize < so->xPos // BAD + || so->xPos > o->xPos + o->xSize) { // GOOD + // clang 8.0.0 -O2: not deleted + // gcc 9.2 -O2: not deleted + // msvc 19.22 /O2: not deleted + return false; + } + return true; +} + +bool checkOverflow3(unsigned int a, unsigned short b) { + return (a + b < a); // GOOD +} + +struct C { + unsigned int length; +}; + +int checkOverflow4(unsigned int ioff, C c) { + // not deleted by gcc or clang + if ((int)(ioff + c.length) < (int)ioff) return 0; // GOOD + return 1; +} + +int overflow12(int n) { + // not deleted by gcc or clang + return (n + 32 <= (unsigned)n? -1: 1); // BAD: n + 32 can overflow +} + +bool multipleCasts(char x) { + + // BAD [UNDETECTED - BadAdditionOverflowCheck.ql] + // GOOD [SigneOverflowCheck.ql]: Test always fails, but will never overflow. + return (int)(unsigned short)x + 2 < (int)(unsigned short)x; // GOOD: cannot overflow +} + +bool multipleCasts2(char x) { + + // BAD [BadAdditionOverflowCheck.ql] + // GOOD [SigneOverflowCheck.ql]: Test always fails, but will never overflow. + return (int)(unsigned short)(x + '1') < (int)(unsigned short)x; +} + +int does_it_overflow(int n1, unsigned short delta) { + return n1 + (unsigned)delta < n1; // GOOD: everything converted to unsigned +} + +int overflow12b(int n) { + // not deleted by gcc or clang + return ((unsigned)(n + 32) <= (unsigned)n? -1: 1); // BAD: n + 32 may overflow +} + +#define MACRO(E1, E2) (E1) <= (E2)? -1: 1 + +int overflow12_macro(int n) { + return MACRO((unsigned)(n + 32), (unsigned)n); // GOOD: inside a macro expansion +} + diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/SignedOverflowCheck.expected b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/SignedOverflowCheck.expected new file mode 100644 index 00000000000..414bc74f99e --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/SignedOverflowCheck.expected @@ -0,0 +1,5 @@ +| SignedOverflowCheck.cpp:8:12:8:22 | ... < ... | Testing for signed overflow may produce undefined results. | +| SignedOverflowCheck.cpp:18:12:18:26 | ... < ... | Testing for signed overflow may produce undefined results. | +| SignedOverflowCheck.cpp:73:6:73:36 | ... < ... | Testing for signed overflow may produce undefined results. | +| SignedOverflowCheck.cpp:99:10:99:30 | ... <= ... | Testing for signed overflow may produce undefined results. | +| SignedOverflowCheck.cpp:122:10:122:42 | ... <= ... | Testing for signed overflow may produce undefined results. | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/SignedOverflowCheck.qlref b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/SignedOverflowCheck.qlref new file mode 100644 index 00000000000..dde64840202 --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/SignedOverflowCheck.qlref @@ -0,0 +1 @@ +Likely Bugs/Arithmetic/SignedOverflowCheck.ql diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/templates.cpp b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/templates.cpp new file mode 100644 index 00000000000..0fbd2643404 --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/templates.cpp @@ -0,0 +1,22 @@ +struct C1 { + static const int value = 5; +}; + +struct C2 { + static const int value = 6; +}; + +template +bool compareValues() { + // Not all instantiations have T1 and T2 equal. Even if that's the case for + // all instantiations in the program, there could still be more such + // instantiations outside. + return + T1::value < T2::value || // GOOD + T1::value < T1::value || // BAD [NOT DETECTED] + C1::value < C1::value ; // BAD +} + +bool callCompareValues() { + return compareValues || compareValues(); +} diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/test.cpp b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/test.cpp index 4669b709bc4..e36956f9c69 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/test.cpp +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/BadAdditionOverflowCheck/test.cpp @@ -1,11 +1,11 @@ // Test for BadAdditionOverflowCheck. bool checkOverflow1(unsigned short a, unsigned short b) { - return (a + b < a); // BAD: a + b is automatically promoted to int. + return (a + b < a); // BAD: comparison always false (due to promotion). } // Test for BadAdditionOverflowCheck. bool checkOverflow2(unsigned short a, unsigned short b) { - return ((unsigned short)(a + b) < a); // GOOD: explicit cast + return ((unsigned short)(a + b) < a); // GOOD } // Test for PointlessSelfComparison. diff --git a/cpp/ql/test/query-tests/Likely Bugs/Format/NonConstantFormat/a.c b/cpp/ql/test/query-tests/Likely Bugs/Format/NonConstantFormat/a.c new file mode 100644 index 00000000000..5b31d31b9fb --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Format/NonConstantFormat/a.c @@ -0,0 +1,19 @@ + +__attribute__((format(printf, 1, 3))) +void myMultiplyDefinedPrintf(const char *format, const char *extraArg, ...) +{ + // ... +} + +__attribute__((format(printf, 1, 3))) +void myMultiplyDefinedPrintf2(const char *format, const char *extraArg, ...); + +char *getString(); + +void test_custom_printf1() +{ + myMultiplyDefinedPrintf("string", getString()); // GOOD + myMultiplyDefinedPrintf(getString(), "string"); // BAD [NOT DETECTED] + myMultiplyDefinedPrintf2("string", getString()); // GOOD (we can't tell which declaration is correct so we have to assume this is OK) + myMultiplyDefinedPrintf2(getString(), "string"); // GOOD (we can't tell which declaration is correct so we have to assume this is OK) +} diff --git a/cpp/ql/test/query-tests/Likely Bugs/Format/NonConstantFormat/b.c b/cpp/ql/test/query-tests/Likely Bugs/Format/NonConstantFormat/b.c new file mode 100644 index 00000000000..b0addf37881 --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Format/NonConstantFormat/b.c @@ -0,0 +1,16 @@ + +__attribute__((format(printf, 2, 3))) +void myMultiplyDefinedPrintf(const char *extraArg, const char *format, ...); // this declaration does not match the definition + +__attribute__((format(printf, 2, 3))) +void myMultiplyDefinedPrintf2(const char *extraArg, const char *format, ...); + +char *getString(); + +void test_custom_printf2(char *string) +{ + myMultiplyDefinedPrintf("string", getString()); // GOOD + myMultiplyDefinedPrintf(getString(), "string"); // BAD [NOT DETECTED] + myMultiplyDefinedPrintf2("string", getString()); // GOOD (we can't tell which declaration is correct so we have to assume this is OK) + myMultiplyDefinedPrintf2(getString(), "string"); // GOOD (we can't tell which declaration is correct so we have to assume this is OK) +} \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_signed_chars/WrongTypeFormatArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_signed_chars/WrongTypeFormatArguments.expected index 65f4f546976..c67057710bb 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_signed_chars/WrongTypeFormatArguments.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_signed_chars/WrongTypeFormatArguments.expected @@ -16,6 +16,43 @@ | printf1.h:114:18:114:18 | d | This argument should be of type 'long double' but is of type 'double' | | printf1.h:147:19:147:19 | i | This argument should be of type 'long long' but is of type 'int' | | printf1.h:148:19:148:20 | ui | This argument should be of type 'unsigned long long' but is of type 'unsigned int' | +| printf1.h:160:18:160:18 | i | This argument should be of type 'char *' but is of type 'int' | +| printf1.h:161:21:161:21 | s | This argument should be of type 'int' but is of type 'char *' | +| printf1.h:167:17:167:17 | i | This argument should be of type 'char *' but is of type 'int' | +| printf1.h:168:18:168:18 | i | This argument should be of type 'char *' but is of type 'int' | +| printf1.h:169:19:169:19 | i | This argument should be of type 'char *' but is of type 'int' | +| printf1.h:174:17:174:17 | s | This argument should be of type 'int' but is of type 'char *' | +| printf1.h:175:18:175:18 | s | This argument should be of type 'int' but is of type 'char *' | +| printf1.h:176:19:176:19 | s | This argument should be of type 'int' but is of type 'char *' | +| printf1.h:180:17:180:17 | s | This argument should be of type 'int' but is of type 'char *' | +| printf1.h:181:20:181:20 | i | This argument should be of type 'char *' but is of type 'int' | +| printf1.h:183:18:183:18 | s | This argument should be of type 'int' but is of type 'char *' | +| printf1.h:184:21:184:21 | i | This argument should be of type 'char *' but is of type 'int' | +| printf1.h:186:19:186:19 | s | This argument should be of type 'int' but is of type 'char *' | +| printf1.h:187:22:187:22 | i | This argument should be of type 'char *' but is of type 'int' | +| printf1.h:189:19:189:19 | s | This argument should be of type 'int' but is of type 'char *' | +| printf1.h:190:22:190:22 | i | This argument should be of type 'char *' but is of type 'int' | +| printf1.h:192:19:192:19 | s | This argument should be of type 'int' but is of type 'char *' | +| printf1.h:193:22:193:22 | s | This argument should be of type 'int' but is of type 'char *' | +| printf1.h:194:25:194:25 | i | This argument should be of type 'char *' but is of type 'int' | +| printf1.h:198:24:198:24 | s | This argument should be of type 'int' but is of type 'char *' | +| printf1.h:199:21:199:21 | i | This argument should be of type 'char *' but is of type 'int' | +| printf1.h:202:26:202:26 | s | This argument should be of type 'int' but is of type 'char *' | +| printf1.h:203:23:203:23 | i | This argument should be of type 'char *' but is of type 'int' | +| printf1.h:206:25:206:25 | s | This argument should be of type 'int' but is of type 'char *' | +| printf1.h:207:22:207:22 | i | This argument should be of type 'char *' but is of type 'int' | +| printf1.h:210:26:210:26 | s | This argument should be of type 'int' but is of type 'char *' | +| printf1.h:211:23:211:23 | i | This argument should be of type 'char *' but is of type 'int' | +| printf1.h:214:28:214:28 | s | This argument should be of type 'int' but is of type 'char *' | +| printf1.h:215:28:215:28 | s | This argument should be of type 'int' but is of type 'char *' | +| printf1.h:216:25:216:25 | i | This argument should be of type 'char *' but is of type 'int' | +| printf1.h:221:18:221:18 | s | This argument should be of type 'int' but is of type 'char *' | +| printf1.h:222:20:222:20 | s | This argument should be of type 'int' but is of type 'char *' | +| printf1.h:225:23:225:23 | i | This argument should be of type 'char *' but is of type 'int' | +| printf1.h:228:24:228:24 | i | This argument should be of type 'char *' but is of type 'int' | +| printf1.h:231:25:231:25 | i | This argument should be of type 'char *' but is of type 'int' | +| printf1.h:234:25:234:25 | i | This argument should be of type 'char *' but is of type 'int' | +| printf1.h:235:22:235:22 | s | This argument should be of type 'int' but is of type 'char *' | | real_world.h:61:21:61:22 | & ... | This argument should be of type 'int *' but is of type 'short *' | | real_world.h:62:22:62:23 | & ... | This argument should be of type 'short *' but is of type 'int *' | | real_world.h:63:22:63:24 | & ... | This argument should be of type 'short *' but is of type 'unsigned int *' | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_signed_chars/a.c b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_signed_chars/a.c new file mode 100644 index 00000000000..17d1bd98fed --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_signed_chars/a.c @@ -0,0 +1,16 @@ + +__attribute__((format(printf, 1, 3))) +void myMultiplyDefinedPrintf(const char *format, const char *extraArg, ...) +{ + // ... +} +__attribute__((format(printf, 1, 3))) +void myMultiplyDefinedPrintf2(const char *format, const char *extraArg, ...); + +void test_custom_printf1() +{ + myMultiplyDefinedPrintf("%i", "%f", 1); // GOOD + myMultiplyDefinedPrintf("%i", "%f", 1.0f); // BAD [NOT DETECTED] + myMultiplyDefinedPrintf2("%i", "%f", 1); // GOOD (we can't tell which declaration is correct so we have to assume this is OK) + myMultiplyDefinedPrintf2("%i", "%f", 1.0f); // GOOD (we can't tell which declaration is correct so we have to assume this is OK) +} diff --git a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_signed_chars/b.c b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_signed_chars/b.c new file mode 100644 index 00000000000..adf443c1e9d --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_signed_chars/b.c @@ -0,0 +1,14 @@ + +__attribute__((format(printf, 2, 3))) +void myMultiplyDefinedPrintf(const char *extraArg, const char *format, ...); // this declaration does not match the definition + +__attribute__((format(printf, 2, 3))) +void myMultiplyDefinedPrintf2(const char *extraArg, const char *format, ...); + +void test_custom_printf2() +{ + myMultiplyDefinedPrintf("%i", "%f", 1); // GOOD + myMultiplyDefinedPrintf("%i", "%f", 1.0f); // BAD [NOT DETECTED] + myMultiplyDefinedPrintf2("%i", "%f", 1); // GOOD (we can't tell which declaration is correct so we have to assume this is OK) + myMultiplyDefinedPrintf2("%i", "%f", 1.0f); // GOOD (we can't tell which declaration is correct so we have to assume this is OK) +} \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_signed_chars/printf1.h b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_signed_chars/printf1.h index ab9a9e18635..4517cfadf56 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_signed_chars/printf1.h +++ b/cpp/ql/test/query-tests/Likely Bugs/Format/WrongTypeFormatArguments/Linux_signed_chars/printf1.h @@ -151,3 +151,86 @@ void fun4() printf("%qi\n", ll); // GOOD printf("%qu\n", ull); // GOOD } + +void complexFormatSymbols(int i, const char *s) +{ + // positional arguments + printf("%1$i", i, s); // GOOD + printf("%2$s", i, s); // GOOD + printf("%1$s", i, s); // BAD + printf("%2$i", i, s); // BAD + + // width / precision + printf("%4i", i); // GOOD + printf("%.4i", i); // GOOD + printf("%4.4i", i); // GOOD + printf("%4s", i); // BAD + printf("%.4s", i); // BAD + printf("%4.4s", i); // BAD + + printf("%4s", s); // GOOD + printf("%.4s", s); // GOOD + printf("%4.4s", s); // GOOD + printf("%4i", s); // BAD + printf("%.4i", s); // BAD + printf("%4.4i", s); // BAD + + // variable width / precision + printf("%*s", i, s); // GOOD + printf("%*s", s, s); // BAD + printf("%*s", i, i); // BAD + printf("%.*s", i, s); // GOOD + printf("%.*s", s, s); // BAD + printf("%.*s", i, i); // BAD + printf("%*.4s", i, s); // GOOD + printf("%*.4s", s, s); // BAD + printf("%*.4s", i, i); // BAD + printf("%4.*s", i, s); // GOOD + printf("%4.*s", s, s); // BAD + printf("%4.*s", i, i); // BAD + printf("%*.*s", i, i, s); // GOOD + printf("%*.*s", s, i, s); // BAD + printf("%*.*s", i, s, s); // BAD + printf("%*.*s", i, i, i); // BAD + + // positional arguments mixed with variable width / precision + printf("%2$*1$s", i, s); // GOOD + printf("%2$*2$s", i, s); // BAD + printf("%1$*1$s", i, s); // BAD + + printf("%2$*1$.4s", i, s); // GOOD + printf("%2$*2$.4s", i, s); // BAD + printf("%1$*1$.4s", i, s); // BAD + + printf("%2$.*1$s", i, s); // GOOD + printf("%2$.*2$s", i, s); // BAD + printf("%1$.*1$s", i, s); // BAD + + printf("%2$4.*1$s", i, s); // GOOD + printf("%2$4.*2$s", i, s); // BAD + printf("%1$4.*1$s", i, s); // BAD + + printf("%2$*1$.*1$s", i, s); // GOOD + printf("%2$*2$.*1$s", i, s); // BAD + printf("%2$*1$.*2$s", i, s); // BAD + printf("%1$*1$.*1$s", i, s); // BAD + + // left justify flag + printf("%-4s", s); // GOOD + printf("%1$-4s", s); // GOOD + printf("%-4i", s); // BAD + printf("%1$-4i", s); // BAD + + printf("%1$-4s", s, i); // GOOD + printf("%2$-4s", s, i); // BAD + + printf("%1$-.4s", s, i); // GOOD + printf("%2$-.4s", s, i); // BAD + + printf("%1$-4.4s", s, i); // GOOD + printf("%2$-4.4s", s, i); // BAD + + printf("%1$-*2$s", s, i); // GOOD + printf("%2$-*2$s", s, i); // BAD + printf("%1$-*1$s", s, i); // BAD +} diff --git a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/NtohlArrayNoBound/NtohlArrayNoBound.expected b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/NtohlArrayNoBound/NtohlArrayNoBound.expected new file mode 100644 index 00000000000..6c2fa97858c --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/NtohlArrayNoBound/NtohlArrayNoBound.expected @@ -0,0 +1,8 @@ +| test.cpp:12:25:12:29 | call to ntohl | Unchecked use of data from network function $@ | test.cpp:12:25:12:29 | call to ntohl | call to ntohl | +| test.cpp:21:26:21:29 | len2 | Unchecked use of data from network function $@ | test.cpp:10:16:10:20 | call to ntohl | call to ntohl | +| test.cpp:31:26:31:29 | len2 | Unchecked use of data from network function $@ | test.cpp:10:16:10:20 | call to ntohl | call to ntohl | +| test.cpp:61:26:61:29 | len2 | Unchecked use of data from network function $@ | test.cpp:10:16:10:20 | call to ntohl | call to ntohl | +| test.cpp:64:9:64:12 | len2 | Unchecked use of data from network function $@ | test.cpp:10:16:10:20 | call to ntohl | call to ntohl | +| test.cpp:73:10:73:13 | lens | Unchecked use of data from network function $@ | test.cpp:10:16:10:20 | call to ntohl | call to ntohl | +| test.cpp:86:10:86:13 | len3 | Unchecked use of data from network function $@ | test.cpp:85:10:85:14 | call to ntohl | call to ntohl | +| test.cpp:94:9:94:11 | len | Unchecked use of data from network function $@ | test.cpp:99:8:99:12 | call to ntohl | call to ntohl | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/NtohlArrayNoBound/NtohlArrayNoBound.qlref b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/NtohlArrayNoBound/NtohlArrayNoBound.qlref new file mode 100644 index 00000000000..58e62b13e6d --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/NtohlArrayNoBound/NtohlArrayNoBound.qlref @@ -0,0 +1 @@ +Likely Bugs/Memory Management/NtohlArrayNoBound.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Likely Bugs/Memory Management/NtohlArrayNoBound/test.cpp b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/NtohlArrayNoBound/test.cpp new file mode 100644 index 00000000000..e3f01f9ae77 --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Memory Management/NtohlArrayNoBound/test.cpp @@ -0,0 +1,100 @@ + +typedef unsigned int size_t; +void *memcpy(void *s1, const void *s2, size_t n); +size_t strlen(const char *s); +int ntohl(int x); + +void test1(const char *source, size_t len) +{ + char buffer[256]; + size_t len2 = ntohl(len); + + memcpy(buffer, source, ntohl(len)); // BAD + + if (len2 < 256) + { + memcpy(buffer, source, len2); // GOOD + } + + if (source != 0) + { + memcpy(buffer, source, len2); // BAD + } + + if ((len2 < 256) && (source != 0)) + { + memcpy(buffer, source, len2); // GOOD + } + + if ((len2 < 256) || (source != 0)) + { + memcpy(buffer, source, len2); // BAD + } + + if (len2 < 256) + { + if (source != 0) + { + memcpy(buffer, source, len2); // GOOD + } + } + + if (len2 >= 256) + { + // fail + } else { + memcpy(buffer, source, len2); // GOOD + } + + if (len2 + 1 < 256) + { + memcpy(buffer, source, len2 + 1); // GOOD + } + + if (strlen(source) < 256) + { + memcpy(buffer, source, strlen(source)); // GOOD + } + + if (strlen(source) < 256) + { + memcpy(buffer, source, len2); // BAD + } + + buffer[len2] = 0; // BAD + + if (len2 < 256) + { + buffer[len2] = 0; // GOOD + } + + { + unsigned short lens = len2; + buffer[lens] = 0; // BAD + } + + if (len2 < 256) + { + unsigned short lens = len2; + buffer[lens] = 0; // GOOD + } + + size_t len3 = 0; + if (len3 < 256) + { + len3 = ntohl(len); + buffer[len3] = 0; // BAD + } +} + +void test2(size_t len) +{ + char buffer[256]; + + buffer[len] = 0; // BAD +} + +void test3(size_t len) +{ + test2(ntohl(len)); +} diff --git a/cpp/ql/test/query-tests/Likely Bugs/Protocols/TlsSettingsMisconfiguration.expected b/cpp/ql/test/query-tests/Likely Bugs/Protocols/TlsSettingsMisconfiguration.expected new file mode 100644 index 00000000000..c6883e156d1 --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Protocols/TlsSettingsMisconfiguration.expected @@ -0,0 +1,18 @@ +| test2.cpp:15:32:15:33 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test2.cpp:15:32:15:33 | call to context | boost::asio::ssl::context::context | test2.cpp:14:40:14:72 | sslv23 | sslv23 | test2.cpp:15:32:15:33 | call to context | no_sslv3 has not been set | +| test2.cpp:23:32:23:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test2.cpp:23:32:23:65 | call to context | boost::asio::ssl::context::context | test2.cpp:23:32:23:64 | sslv23 | sslv23 | test2.cpp:23:32:23:65 | call to context | no_sslv3 has not been set | +| test2.cpp:23:32:23:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test2.cpp:23:32:23:65 | call to context | boost::asio::ssl::context::context | test2.cpp:23:32:23:64 | sslv23 | sslv23 | test2.cpp:23:32:23:65 | call to context | no_tlsv1 has not been set | +| test2.cpp:23:32:23:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test2.cpp:23:32:23:65 | call to context | boost::asio::ssl::context::context | test2.cpp:23:32:23:64 | sslv23 | sslv23 | test2.cpp:23:32:23:65 | call to context | no_tlsv1_1 has not been set | +| test2.cpp:31:32:31:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test2.cpp:31:32:31:65 | call to context | boost::asio::ssl::context::context | test2.cpp:31:32:31:64 | sslv23 | sslv23 | test2.cpp:31:32:31:65 | call to context | no_sslv3 has not been set | +| test2.cpp:31:32:31:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test2.cpp:31:32:31:65 | call to context | boost::asio::ssl::context::context | test2.cpp:31:32:31:64 | sslv23 | sslv23 | test2.cpp:31:32:31:65 | call to context | no_tlsv1 has not been set | +| test2.cpp:31:32:31:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test2.cpp:31:32:31:65 | call to context | boost::asio::ssl::context::context | test2.cpp:31:32:31:64 | sslv23 | sslv23 | test2.cpp:31:32:31:65 | call to context | no_tlsv1_1 has not been set | +| test2.cpp:45:35:45:98 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test2.cpp:45:35:45:98 | call to context | boost::asio::ssl::context::context | test2.cpp:45:65:45:97 | sslv23 | sslv23 | test2.cpp:45:35:45:98 | call to context | no_sslv3 has not been set | +| test2.cpp:52:32:52:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test2.cpp:52:32:52:65 | call to context | boost::asio::ssl::context::context | test2.cpp:52:32:52:64 | sslv23 | sslv23 | test2.cpp:52:32:52:65 | call to context | no_sslv3 has not been set | +| test2.cpp:52:32:52:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test2.cpp:52:32:52:65 | call to context | boost::asio::ssl::context::context | test2.cpp:52:32:52:64 | sslv23 | sslv23 | test2.cpp:52:32:52:65 | call to context | no_tlsv1 has not been set | +| test2.cpp:52:32:52:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test2.cpp:52:32:52:65 | call to context | boost::asio::ssl::context::context | test2.cpp:52:32:52:64 | sslv23 | sslv23 | test2.cpp:52:32:52:65 | call to context | no_tlsv1_1 has not been set | +| test.cpp:25:32:25:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test.cpp:25:32:25:65 | call to context | boost::asio::ssl::context::context | test.cpp:25:32:25:64 | sslv23 | sslv23 | test.cpp:25:32:25:65 | call to context | no_sslv3 has not been set | +| test.cpp:31:32:31:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test.cpp:31:32:31:65 | call to context | boost::asio::ssl::context::context | test.cpp:31:32:31:64 | sslv23 | sslv23 | test.cpp:31:32:31:65 | call to context | no_sslv3 has not been set | +| test.cpp:31:32:31:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test.cpp:31:32:31:65 | call to context | boost::asio::ssl::context::context | test.cpp:31:32:31:64 | sslv23 | sslv23 | test.cpp:31:32:31:65 | call to context | no_tlsv1 has not been set | +| test.cpp:31:32:31:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test.cpp:31:32:31:65 | call to context | boost::asio::ssl::context::context | test.cpp:31:32:31:64 | sslv23 | sslv23 | test.cpp:31:32:31:65 | call to context | no_tlsv1_1 has not been set | +| test.cpp:36:32:36:62 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test.cpp:36:32:36:62 | call to context | boost::asio::ssl::context::context | test.cpp:36:32:36:61 | tls | tls | test.cpp:36:32:36:62 | call to context | no_tlsv1 has not been set | +| test.cpp:36:32:36:62 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test.cpp:36:32:36:62 | call to context | boost::asio::ssl::context::context | test.cpp:36:32:36:61 | tls | tls | test.cpp:36:32:36:62 | call to context | no_tlsv1_1 has not been set | +| test.cpp:41:32:41:62 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test.cpp:41:32:41:62 | call to context | boost::asio::ssl::context::context | test.cpp:41:32:41:61 | tls | tls | test.cpp:43:6:43:16 | call to set_options | no_tlsv1_2 was set | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Protocols/TlsSettingsMisconfiguration.qlref b/cpp/ql/test/query-tests/Likely Bugs/Protocols/TlsSettingsMisconfiguration.qlref new file mode 100644 index 00000000000..8c1c54ff960 --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Protocols/TlsSettingsMisconfiguration.qlref @@ -0,0 +1 @@ +Likely Bugs/Protocols/TlsSettingsMisconfiguration.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Likely Bugs/Protocols/boostorg/UseOfDeprecatedHardcodedProtocol.expected b/cpp/ql/test/query-tests/Likely Bugs/Protocols/UseOfDeprecatedHardcodedProtocol.expected similarity index 100% rename from cpp/ql/test/query-tests/Likely Bugs/Protocols/boostorg/UseOfDeprecatedHardcodedProtocol.expected rename to cpp/ql/test/query-tests/Likely Bugs/Protocols/UseOfDeprecatedHardcodedProtocol.expected diff --git a/cpp/ql/test/query-tests/Likely Bugs/Protocols/UseOfDeprecatedHardcodedProtocol.qlref b/cpp/ql/test/query-tests/Likely Bugs/Protocols/UseOfDeprecatedHardcodedProtocol.qlref new file mode 100644 index 00000000000..2cef090faef --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Protocols/UseOfDeprecatedHardcodedProtocol.qlref @@ -0,0 +1 @@ +Likely Bugs/Protocols/UseOfDeprecatedHardcodedProtocol.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Likely Bugs/Protocols/boostorg/asio/boost_simulation.hpp b/cpp/ql/test/query-tests/Likely Bugs/Protocols/asio/boost_simulation.hpp similarity index 100% rename from cpp/ql/test/query-tests/Likely Bugs/Protocols/boostorg/asio/boost_simulation.hpp rename to cpp/ql/test/query-tests/Likely Bugs/Protocols/asio/boost_simulation.hpp diff --git a/cpp/ql/test/query-tests/Likely Bugs/Protocols/boostorg/TlsSettingsMisconfiguration.expected b/cpp/ql/test/query-tests/Likely Bugs/Protocols/boostorg/TlsSettingsMisconfiguration.expected deleted file mode 100644 index 8a3acb1aeb5..00000000000 --- a/cpp/ql/test/query-tests/Likely Bugs/Protocols/boostorg/TlsSettingsMisconfiguration.expected +++ /dev/null @@ -1,7 +0,0 @@ -| test.cpp:25:32:25:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test.cpp:25:32:25:65 | call to context | boost::asio::ssl::context::context | test.cpp:25:32:25:64 | sslv23 | sslv23 | test.cpp:25:32:25:65 | call to context | no_sslv3 has not been set | -| test.cpp:31:32:31:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test.cpp:31:32:31:65 | call to context | boost::asio::ssl::context::context | test.cpp:31:32:31:64 | sslv23 | sslv23 | test.cpp:31:32:31:65 | call to context | no_sslv3 has not been set | -| test.cpp:31:32:31:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test.cpp:31:32:31:65 | call to context | boost::asio::ssl::context::context | test.cpp:31:32:31:64 | sslv23 | sslv23 | test.cpp:31:32:31:65 | call to context | no_tlsv1 has not been set | -| test.cpp:31:32:31:65 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test.cpp:31:32:31:65 | call to context | boost::asio::ssl::context::context | test.cpp:31:32:31:64 | sslv23 | sslv23 | test.cpp:31:32:31:65 | call to context | no_tlsv1_1 has not been set | -| test.cpp:36:32:36:62 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test.cpp:36:32:36:62 | call to context | boost::asio::ssl::context::context | test.cpp:36:32:36:61 | tls | tls | test.cpp:36:32:36:62 | call to context | no_tlsv1 has not been set | -| test.cpp:36:32:36:62 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test.cpp:36:32:36:62 | call to context | boost::asio::ssl::context::context | test.cpp:36:32:36:61 | tls | tls | test.cpp:36:32:36:62 | call to context | no_tlsv1_1 has not been set | -| test.cpp:41:32:41:62 | call to context | Usage of $@ with protocol $@ is not configured correctly: The option $@. | test.cpp:41:32:41:62 | call to context | boost::asio::ssl::context::context | test.cpp:41:32:41:61 | tls | tls | test.cpp:43:6:43:16 | call to set_options | no_tlsv1_2 was set | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Protocols/boostorg/TlsSettingsMisconfiguration.qlref b/cpp/ql/test/query-tests/Likely Bugs/Protocols/boostorg/TlsSettingsMisconfiguration.qlref deleted file mode 100644 index fd20bf3f8bd..00000000000 --- a/cpp/ql/test/query-tests/Likely Bugs/Protocols/boostorg/TlsSettingsMisconfiguration.qlref +++ /dev/null @@ -1 +0,0 @@ -Likely Bugs/Protocols/boostorg/TlsSettingsMisconfiguration.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Likely Bugs/Protocols/boostorg/UseOfDeprecatedHardcodedProtocol.qlref b/cpp/ql/test/query-tests/Likely Bugs/Protocols/boostorg/UseOfDeprecatedHardcodedProtocol.qlref deleted file mode 100644 index 75800f425f8..00000000000 --- a/cpp/ql/test/query-tests/Likely Bugs/Protocols/boostorg/UseOfDeprecatedHardcodedProtocol.qlref +++ /dev/null @@ -1 +0,0 @@ -Likely Bugs/Protocols/boostorg/UseOfDeprecatedHardcodedProtocol.ql \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Likely Bugs/Protocols/boostorg/test.cpp b/cpp/ql/test/query-tests/Likely Bugs/Protocols/test.cpp similarity index 100% rename from cpp/ql/test/query-tests/Likely Bugs/Protocols/boostorg/test.cpp rename to cpp/ql/test/query-tests/Likely Bugs/Protocols/test.cpp diff --git a/cpp/ql/test/query-tests/Likely Bugs/Protocols/test2.cpp b/cpp/ql/test/query-tests/Likely Bugs/Protocols/test2.cpp new file mode 100644 index 00000000000..5679cee8b0f --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Protocols/test2.cpp @@ -0,0 +1,55 @@ +#include "asio/boost_simulation.hpp" + +void good1() +{ + // GOOD + boost::asio::ssl::context::method m = boost::asio::ssl::context::sslv23; + boost::asio::ssl::context ctx(m); + ctx.set_options(boost::asio::ssl::context::no_tlsv1 | boost::asio::ssl::context::no_tlsv1_1 | boost::asio::ssl::context::no_sslv3); +} + +void bad1() +{ + // BAD: missing disable SSLv3 + boost::asio::ssl::context::method m = boost::asio::ssl::context::sslv23; + boost::asio::ssl::context ctx(m); + ctx.set_options(boost::asio::ssl::context::no_tlsv1 | boost::asio::ssl::context::no_tlsv1_1); +} + +void good2() +{ + // GOOD [FALSE POSITIVE x 3] + boost::asio::ssl::context::options opts = boost::asio::ssl::context::no_tlsv1 | boost::asio::ssl::context::no_tlsv1_1 | boost::asio::ssl::context::no_sslv3; + boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23); + ctx.set_options(opts); +} + +void bad2() +{ + // BAD: missing disable SSLv3 [WITH FALSE POSITIVE x 2] + boost::asio::ssl::context::options opts = boost::asio::ssl::context::no_tlsv1 | boost::asio::ssl::context::no_tlsv1_1; + boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23); + ctx.set_options(opts); +} + +void good3() +{ + // GOOD + boost::asio::ssl::context *ctx = new boost::asio::ssl::context(boost::asio::ssl::context::sslv23); + ctx->set_options(boost::asio::ssl::context::no_tlsv1 | boost::asio::ssl::context::no_tlsv1_1 | boost::asio::ssl::context::no_sslv3); +} + +void bad3() +{ + // BAD: missing disable SSLv3 + boost::asio::ssl::context *ctx = new boost::asio::ssl::context(boost::asio::ssl::context::sslv23); + ctx->set_options(boost::asio::ssl::context::no_tlsv1 | boost::asio::ssl::context::no_tlsv1_1); +} + +void bad4() +{ + // BAD: missing disable SSLv3 + boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23); +} + + diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/ConditionallyUninitializedVariable/ConditionallyUninitializedVariable.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/ConditionallyUninitializedVariable/ConditionallyUninitializedVariable.expected new file mode 100644 index 00000000000..60964c8f178 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/ConditionallyUninitializedVariable/ConditionallyUninitializedVariable.expected @@ -0,0 +1,3 @@ +| examples.cpp:38:3:38:18 | call to initDeviceConfig | The status of this call to $@ is not checked, potentially leaving $@ uninitialized. | examples.cpp:13:5:13:20 | initDeviceConfig | initDeviceConfig | examples.cpp:37:16:37:21 | config | config | +| test.cpp:22:2:22:17 | call to maybeInitialize1 | The status of this call to $@ is not checked, potentially leaving $@ uninitialized. | test.cpp:4:5:4:20 | maybeInitialize1 | maybeInitialize1 | test.cpp:19:6:19:6 | a | a | +| test.cpp:68:2:68:17 | call to maybeInitialize2 | The status of this call to $@ is not checked, potentially leaving $@ uninitialized. | test.cpp:51:6:51:21 | maybeInitialize2 | maybeInitialize2 | test.cpp:66:6:66:6 | a | a | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/ConditionallyUninitializedVariable/ConditionallyUninitializedVariable.qlref b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/ConditionallyUninitializedVariable/ConditionallyUninitializedVariable.qlref new file mode 100644 index 00000000000..5150d627257 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/ConditionallyUninitializedVariable/ConditionallyUninitializedVariable.qlref @@ -0,0 +1 @@ +Security/CWE/CWE-457/ConditionallyUninitializedVariable.ql diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/ConditionallyUninitializedVariable/examples.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/ConditionallyUninitializedVariable/examples.cpp new file mode 100644 index 00000000000..ccb15904d02 --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/ConditionallyUninitializedVariable/examples.cpp @@ -0,0 +1,43 @@ +// based on the qhelp + +int getMaxDevices(); +bool fetchIsDeviceEnabled(int deviceNumber); +int fetchDeviceChannel(int deviceNumber); +void notifyChannel(int channel); + +struct DeviceConfig { + bool isEnabled; + int channel; +}; + +int initDeviceConfig(DeviceConfig *ref, int deviceNumber) { + if (deviceNumber >= getMaxDevices()) { + // No device with that number, return -1 to indicate failure + return -1; + } + // Device with that number, fetch parameters and initialize struct + ref->isEnabled = fetchIsDeviceEnabled(deviceNumber); + ref->channel = fetchDeviceChannel(deviceNumber); + // Return 0 to indicate success + return 0; +} + +void notifyGood(int deviceNumber) { + DeviceConfig config; + int statusCode = initDeviceConfig(&config, deviceNumber); + if (statusCode == 0) { + // GOOD: Status code returned by initialization function is checked, so this is safe + if (config.isEnabled) { + notifyChannel(config.channel); + } + } +} + +int notifyBad(int deviceNumber) { + DeviceConfig config; + initDeviceConfig(&config, deviceNumber); + // BAD: Using config without checking the status code that is returned + if (config.isEnabled) { + notifyChannel(config.channel); + } +} \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/ConditionallyUninitializedVariable/test.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/ConditionallyUninitializedVariable/test.cpp new file mode 100644 index 00000000000..a3c9b0a24aa --- /dev/null +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/ConditionallyUninitializedVariable/test.cpp @@ -0,0 +1,96 @@ + +void use(int i); + +int maybeInitialize1(int *v) +{ + static int resources = 100; + + if (resources == 0) + { + return 0; // FAIL + } + + *v = resources--; + return 1; // SUCCESS +} + +void test1() +{ + int a, b, c, d, e, f; + int result1, result2; + + maybeInitialize1(&a); // BAD (initialization not checked) + use(a); + + if (maybeInitialize1(&b) == 1) // GOOD + { + use(b); + } + + if (maybeInitialize1(&c) == 0) // BAD (initialization check is wrong) [NOT DETECTED] + { + use(c); + } + + result1 = maybeInitialize1(&d); // BAD (initialization stored but not checked) [NOT DETECTED] + use(d); + + result2 = maybeInitialize1(&e); // GOOD + if (result2 == 1) + { + use(e); + } + + if (maybeInitialize1(&f) == 0) // GOOD + { + return; + } + use(f); +} + +bool maybeInitialize2(int *v) +{ + static int resources = 100; + + if (resources > 0) + { + *v = resources--; + return true; // SUCCESS + } + + return false; // FAIL +} + +void test2() +{ + int a, b; + + maybeInitialize2(&a); // BAD (initialization not checked) + use(a); + + if (maybeInitialize2(&b)) // GOOD + { + use(b); + } +} + +int alwaysInitialize(int *v) +{ + static int resources = 0; + + *v = resources++; + return 1; // SUCCESS +} + +void test3() +{ + int a, b; + + alwaysInitialize(&a); // GOOD (initialization never fails) + use(a); + + if (alwaysInitialize(&b) == 1) // GOOD + { + use(b); + } +} diff --git a/cpp/upgrades/98a075d5495d7be7ede26557708cf22cfa3964ef/old.dbscheme b/cpp/upgrades/98a075d5495d7be7ede26557708cf22cfa3964ef/old.dbscheme new file mode 100644 index 00000000000..98a075d5495 --- /dev/null +++ b/cpp/upgrades/98a075d5495d7be7ede26557708cf22cfa3964ef/old.dbscheme @@ -0,0 +1,1918 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The date of the snapshot. + */ +snapshotDate(unique date snapshotDate : date ref); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Data used by the 'duplicate code' detection. + */ +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +/** + * Data used by the 'similar code' detection. + */ +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +/** + * Data used by the 'duplicate code' and 'similar code' detection. + */ +@duplication_or_similarity = @duplication | @similarity + +/** + * Data used by the 'duplicate code' and 'similar code' detection. + */ +#keyset[id, offset] +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref +); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +/* + case @macroinvocations.kind of + 1 = macro expansion + | 2 = other macro reference + ; +*/ +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* + case @function.kind of + 1 = normal + | 2 = constructor + | 3 = destructor + | 4 = conversion + | 5 = operator + | 6 = builtin // GCC built-in functions, e.g. __builtin___memcpy_chk + ; +*/ +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point(int id: @function ref, unique int entry_point: @stmt ref); + +function_return_type(int id: @function ref, int return_type: @type ref); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + + + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides(int new: @function ref, int old: @function ref); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/* + Built-in types are the fundamental types, e.g., integral, floating, and void. + + case @builtintype.kind of + 1 = error + | 2 = unknown + | 3 = void + | 4 = boolean + | 5 = char + | 6 = unsigned_char + | 7 = signed_char + | 8 = short + | 9 = unsigned_short + | 10 = signed_short + | 11 = int + | 12 = unsigned_int + | 13 = signed_int + | 14 = long + | 15 = unsigned_long + | 16 = signed_long + | 17 = long_long + | 18 = unsigned_long_long + | 19 = signed_long_long + | 20 = __int8 // Microsoft-specific + | 21 = __int16 // Microsoft-specific + | 22 = __int32 // Microsoft-specific + | 23 = __int64 // Microsoft-specific + | 24 = float + | 25 = double + | 26 = long_double + | 27 = _Complex_float // C99-specific + | 28 = _Complex_double // C99-specific + | 29 = _Complex_long double // C99-specific + | 30 = _Imaginary_float // C99-specific + | 31 = _Imaginary_double // C99-specific + | 32 = _Imaginary_long_double // C99-specific + | 33 = wchar_t // Microsoft-specific + | 34 = decltype_nullptr // C++11 + | 35 = __int128 + | 36 = unsigned___int128 + | 37 = signed___int128 + | 38 = __float128 + | 39 = _Complex___float128 + | 40 = _Decimal32 + | 41 = _Decimal64 + | 42 = _Decimal128 + | 43 = char16_t + | 44 = char32_t + | 45 = _Float32 + | 46 = _Float32x + | 47 = _Float64 + | 48 = _Float64x + | 49 = _Float128 + | 50 = _Float128x + ; +*/ +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/* + Derived types are types that are directly derived from existing types and + point to, refer to, transform type data to return a new type. + + case @derivedtype.kind of + 1 = pointer + | 2 = reference + | 3 = type_with_specifiers + | 4 = array + | 5 = gnu_vector + | 6 = routineptr + | 7 = routinereference + | 8 = rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated + | 10 = block + ; +*/ +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +decltypes( + unique int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* + case @usertype.kind of + 1 = struct + | 2 = class + | 3 = union + | 4 = enum + | 5 = typedef // classic C: typedef typedef type name + | 6 = template + | 7 = template_parameter + | 8 = template_template_parameter + | 9 = proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated + | 13 = scoped_enum + | 14 = using_alias // a using name = type style typedef + ; +*/ +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + unique string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the EDG frontend. See symbol_ref.h there. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall(unique int caller: @funbindexpr ref, int kind: int ref); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // EDG internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. + */ +#keyset[aggregate, field] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. + */ +#keyset[aggregate, element_index] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; +successors( + int from: @cfgnode ref, + int to: @cfgnode ref +); + +truecond( + unique int from: @cfgnode ref, + int to: @cfgnode ref +); + +falsecond( + unique int from: @cfgnode ref, + int to: @cfgnode ref +); + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/upgrades/98a075d5495d7be7ede26557708cf22cfa3964ef/semmlecode.cpp.dbscheme b/cpp/upgrades/98a075d5495d7be7ede26557708cf22cfa3964ef/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..bd182f697bf --- /dev/null +++ b/cpp/upgrades/98a075d5495d7be7ede26557708cf22cfa3964ef/semmlecode.cpp.dbscheme @@ -0,0 +1,1933 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The date of the snapshot. + */ +snapshotDate(unique date snapshotDate : date ref); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Data used by the 'duplicate code' detection. + */ +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +/** + * Data used by the 'similar code' detection. + */ +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +/** + * Data used by the 'duplicate code' and 'similar code' detection. + */ +@duplication_or_similarity = @duplication | @similarity + +/** + * Data used by the 'duplicate code' and 'similar code' detection. + */ +#keyset[id, offset] +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files( + unique int id: @file, + string name: string ref, + string simple: string ref, + string ext: string ref, + int fromSource: int ref +); + +folders( + unique int id: @folder, + string name: string ref, + string simple: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +/* + case @macroinvocations.kind of + 1 = macro expansion + | 2 = other macro reference + ; +*/ +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* + case @function.kind of + 1 = normal + | 2 = constructor + | 3 = destructor + | 4 = conversion + | 5 = operator + | 6 = builtin // GCC built-in functions, e.g. __builtin___memcpy_chk + ; +*/ +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point(int id: @function ref, unique int entry_point: @stmt ref); + +function_return_type(int id: @function ref, int return_type: @type ref); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + + + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides(int new: @function ref, int old: @function ref); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/* + Built-in types are the fundamental types, e.g., integral, floating, and void. + + case @builtintype.kind of + 1 = error + | 2 = unknown + | 3 = void + | 4 = boolean + | 5 = char + | 6 = unsigned_char + | 7 = signed_char + | 8 = short + | 9 = unsigned_short + | 10 = signed_short + | 11 = int + | 12 = unsigned_int + | 13 = signed_int + | 14 = long + | 15 = unsigned_long + | 16 = signed_long + | 17 = long_long + | 18 = unsigned_long_long + | 19 = signed_long_long + | 20 = __int8 // Microsoft-specific + | 21 = __int16 // Microsoft-specific + | 22 = __int32 // Microsoft-specific + | 23 = __int64 // Microsoft-specific + | 24 = float + | 25 = double + | 26 = long_double + | 27 = _Complex_float // C99-specific + | 28 = _Complex_double // C99-specific + | 29 = _Complex_long double // C99-specific + | 30 = _Imaginary_float // C99-specific + | 31 = _Imaginary_double // C99-specific + | 32 = _Imaginary_long_double // C99-specific + | 33 = wchar_t // Microsoft-specific + | 34 = decltype_nullptr // C++11 + | 35 = __int128 + | 36 = unsigned___int128 + | 37 = signed___int128 + | 38 = __float128 + | 39 = _Complex___float128 + | 40 = _Decimal32 + | 41 = _Decimal64 + | 42 = _Decimal128 + | 43 = char16_t + | 44 = char32_t + | 45 = _Float32 + | 46 = _Float32x + | 47 = _Float64 + | 48 = _Float64x + | 49 = _Float128 + | 50 = _Float128x + ; +*/ +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/* + Derived types are types that are directly derived from existing types and + point to, refer to, transform type data to return a new type. + + case @derivedtype.kind of + 1 = pointer + | 2 = reference + | 3 = type_with_specifiers + | 4 = array + | 5 = gnu_vector + | 6 = routineptr + | 7 = routinereference + | 8 = rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated + | 10 = block + ; +*/ +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +decltypes( + unique int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* + case @usertype.kind of + 1 = struct + | 2 = class + | 3 = union + | 4 = enum + | 5 = typedef // classic C: typedef typedef type name + | 6 = template + | 7 = template_parameter + | 8 = template_template_parameter + | 9 = proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated + | 13 = scoped_enum + | 14 = using_alias // a using name = type style typedef + ; +*/ +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + unique string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the EDG frontend. See symbol_ref.h there. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall(unique int caller: @funbindexpr ref, int kind: int ref); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // EDG internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. + */ +#keyset[aggregate, field] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. + */ +#keyset[aggregate, element_index] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; +successors( + int from: @cfgnode ref, + int to: @cfgnode ref +); + +truecond( + unique int from: @cfgnode ref, + int to: @cfgnode ref +); + +falsecond( + unique int from: @cfgnode ref, + int to: @cfgnode ref +); + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/upgrades/98a075d5495d7be7ede26557708cf22cfa3964ef/upgrade.properties b/cpp/upgrades/98a075d5495d7be7ede26557708cf22cfa3964ef/upgrade.properties new file mode 100644 index 00000000000..495bdeebdac --- /dev/null +++ b/cpp/upgrades/98a075d5495d7be7ede26557708cf22cfa3964ef/upgrade.properties @@ -0,0 +1,2 @@ +description: Add support for value template parameters. +compatibility: partial diff --git a/cpp/upgrades/qlpack.yml b/cpp/upgrades/qlpack.yml new file mode 100644 index 00000000000..eaf90d6cf90 --- /dev/null +++ b/cpp/upgrades/qlpack.yml @@ -0,0 +1,2 @@ +name: codeql-cpp-upgrades +upgrades: . diff --git a/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs b/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs index b08c8d04d3c..20d19a3525c 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs +++ b/csharp/autobuilder/Semmle.Autobuild.Tests/BuildScripts.cs @@ -457,7 +457,7 @@ namespace Semmle.Extraction.Tests [Fact] public void TestCppAutobuilderSuccess() { - Actions.RunProcess[@"cmd.exe /C C:\codeql\csharp\tools\nuget.exe restore C:\Project\test.sln"] = 1; + Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore C:\Project\test.sln"] = 1; Actions.RunProcess[@"cmd.exe /C CALL ^""C:\Program Files ^(x86^)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat^"" && C:\odasa\tools\odasa index --auto msbuild C:\Project\test.sln /p:UseSharedCompilation=false /t:rebuild /p:Platform=""x86"" /p:Configuration=""Release"" /p:MvcBuildViews=true"] = 0; Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = ""; Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = 1; @@ -720,9 +720,9 @@ namespace Semmle.Extraction.Tests [Fact] public void TestWindowCSharpMsBuild() { - Actions.RunProcess[@"cmd.exe /C C:\codeql\csharp\tools\nuget.exe restore C:\Project\test1.sln"] = 0; + Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore C:\Project\test1.sln"] = 0; Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0; - Actions.RunProcess[@"cmd.exe /C C:\codeql\csharp\tools\nuget.exe restore C:\Project\test2.sln"] = 0; + Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore C:\Project\test2.sln"] = 0; Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test2.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0; Actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0; Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0; @@ -751,9 +751,9 @@ namespace Semmle.Extraction.Tests [Fact] public void TestWindowCSharpMsBuildMultipleSolutions() { - Actions.RunProcess[@"cmd.exe /C C:\codeql\csharp\tools\nuget.exe restore test1.csproj"] = 0; + Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore test1.csproj"] = 0; Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && C:\\odasa\\tools\\odasa index --auto msbuild test1.csproj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0; - Actions.RunProcess[@"cmd.exe /C C:\codeql\csharp\tools\nuget.exe restore test2.csproj"] = 0; + Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore test2.csproj"] = 0; Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && C:\\odasa\\tools\\odasa index --auto msbuild test2.csproj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0; Actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0; Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0; @@ -798,7 +798,7 @@ namespace Semmle.Extraction.Tests [Fact] public void TestWindowCSharpMsBuildFailed() { - Actions.RunProcess[@"cmd.exe /C C:\codeql\csharp\tools\nuget.exe restore C:\Project\test1.sln"] = 0; + Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore C:\Project\test1.sln"] = 0; Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && C:\\odasa\\tools\\odasa index --auto msbuild C:\\Project\\test1.sln /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 1; Actions.FileExists["csharp.log"] = true; Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false; @@ -902,7 +902,7 @@ namespace Semmle.Extraction.Tests { Actions.RunProcess["dotnet --list-sdks"] = 0; Actions.RunProcessOut["dotnet --list-sdks"] = "2.1.2 [C:\\Program Files\\dotnet\\sdks]\n2.1.4 [C:\\Program Files\\dotnet\\sdks]"; - Actions.RunProcess[@"curl -sO https://dot.net/v1/dotnet-install.sh"] = 0; + Actions.RunProcess[@"curl -L -sO https://dot.net/v1/dotnet-install.sh"] = 0; Actions.RunProcess[@"chmod u+x dotnet-install.sh"] = 0; Actions.RunProcess[@"./dotnet-install.sh --channel release --version 2.1.3 --install-dir C:\Project/.dotnet"] = 0; Actions.RunProcess[@"rm dotnet-install.sh"] = 0; @@ -938,7 +938,7 @@ namespace Semmle.Extraction.Tests { Actions.RunProcess["dotnet --list-sdks"] = 0; Actions.RunProcessOut["dotnet --list-sdks"] = "2.1.3 [C:\\Program Files\\dotnet\\sdks]\n2.1.4 [C:\\Program Files\\dotnet\\sdks]"; - Actions.RunProcess[@"curl -sO https://dot.net/v1/dotnet-install.sh"] = 0; + Actions.RunProcess[@"curl -L -sO https://dot.net/v1/dotnet-install.sh"] = 0; Actions.RunProcess[@"chmod u+x dotnet-install.sh"] = 0; Actions.RunProcess[@"./dotnet-install.sh --channel release --version 2.1.3 --install-dir C:\Project/.dotnet"] = 0; Actions.RunProcess[@"rm dotnet-install.sh"] = 0; @@ -1006,7 +1006,7 @@ namespace Semmle.Extraction.Tests [Fact] public void TestDirsProjWindows() { - Actions.RunProcess[@"cmd.exe /C C:\codeql\csharp\tools\nuget.exe restore dirs.proj"] = 1; + Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore dirs.proj"] = 1; Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && C:\\odasa\\tools\\odasa index --auto msbuild dirs.proj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0; Actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0; Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0; @@ -1049,7 +1049,7 @@ namespace Semmle.Extraction.Tests [Fact] public void TestDirsProjLinux() { - Actions.RunProcess[@"mono C:\codeql\csharp/tools/nuget.exe restore dirs.proj"] = 1; + Actions.RunProcess[@"mono C:\odasa\tools/csharp/nuget/nuget.exe restore dirs.proj"] = 1; Actions.RunProcess[@"C:\odasa/tools/odasa index --auto msbuild dirs.proj /p:UseSharedCompilation=false /t:rebuild /p:MvcBuildViews=true"] = 0; Actions.RunProcess[@"C:\codeql\tools\java/bin/java -jar C:\codeql\csharp/tools/extractor-asp.jar ."] = 0; Actions.RunProcess[@"C:\odasa/tools/odasa index --xml --extensions config csproj props xml"] = 0; diff --git a/csharp/autobuilder/Semmle.Autobuild/DotNetRule.cs b/csharp/autobuilder/Semmle.Autobuild/DotNetRule.cs index 49a71fd23a3..789d68db30a 100644 --- a/csharp/autobuilder/Semmle.Autobuild/DotNetRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild/DotNetRule.cs @@ -196,6 +196,7 @@ Invoke-Command -ScriptBlock $ScriptBlock"; { var curl = new CommandBuilder(builder.Actions). RunCommand("curl"). + Argument("-L"). Argument("-sO"). Argument("https://dot.net/v1/dotnet-install.sh"); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/SymbolExtensions.cs b/csharp/extractor/Semmle.Extraction.CSharp/SymbolExtensions.cs index 5bd9c90cc76..107fe42b7e2 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/SymbolExtensions.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/SymbolExtensions.cs @@ -193,8 +193,30 @@ namespace Semmle.Extraction.CSharp trapFile.Write(']'); } + private static void BuildAssembly(IAssemblySymbol asm, TextWriter trapFile, bool extraPrecise = false) + { + var assembly = asm.Identity; + trapFile.Write(assembly.Name); + trapFile.Write('_'); + trapFile.Write(assembly.Version.Major); + trapFile.Write('.'); + trapFile.Write(assembly.Version.Minor); + trapFile.Write('.'); + trapFile.Write(assembly.Version.Build); + if (extraPrecise) + { + trapFile.Write('.'); + trapFile.Write(assembly.Version.Revision); + } + trapFile.Write("::"); + } + static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter trapFile, Action subTermAction) { + bool prefixAssembly = true; + if (cx.Extractor.Standalone) prefixAssembly = false; + if (named.ContainingAssembly is null) prefixAssembly = false; + if (named.IsTupleType) { trapFile.Write('('); @@ -217,6 +239,8 @@ namespace Semmle.Extraction.CSharp } else if (named.ContainingNamespace != null) { + if (prefixAssembly) + BuildAssembly(named.ContainingAssembly, trapFile); named.ContainingNamespace.BuildNamespace(cx, trapFile); } @@ -245,26 +269,6 @@ namespace Semmle.Extraction.CSharp static void BuildNamespace(this INamespaceSymbol ns, Context cx, TextWriter trapFile) { - // Only include the assembly information in each type ID - // for normal extractions. This is because standalone extractions - // lack assembly information or may be ambiguous. - bool prependAssemblyToTypeId = !cx.Extractor.Standalone && ns.ContainingAssembly != null; - - if (prependAssemblyToTypeId) - { - // Note that we exclude the revision number as this has - // been observed to be unstable. - var assembly = ns.ContainingAssembly.Identity; - trapFile.Write(assembly.Name); - trapFile.Write('_'); - trapFile.Write(assembly.Version.Major); - trapFile.Write('.'); - trapFile.Write(assembly.Version.Minor); - trapFile.Write('.'); - trapFile.Write(assembly.Version.Build); - trapFile.Write("::"); - } - trapFile.WriteSubId(Namespace.Create(cx, ns)); trapFile.Write('.'); } diff --git a/csharp/ql/src/Security Features/CWE-079/XSS.qhelp b/csharp/ql/src/Security Features/CWE-079/XSS.qhelp index 9a71290694d..409be1030e7 100644 --- a/csharp/ql/src/Security Features/CWE-079/XSS.qhelp +++ b/csharp/ql/src/Security Features/CWE-079/XSS.qhelp @@ -29,7 +29,7 @@ leaving the website vulnerable to cross-site scripting.

  • OWASP: -XSS +XSS (Cross Site Scripting) Prevention Cheat Sheet.
  • diff --git a/csharp/ql/src/Security Features/CWE-090/LDAPInjection.qhelp b/csharp/ql/src/Security Features/CWE-090/LDAPInjection.qhelp index 118e91ed4d9..04f01720ce6 100644 --- a/csharp/ql/src/Security Features/CWE-090/LDAPInjection.qhelp +++ b/csharp/ql/src/Security Features/CWE-090/LDAPInjection.qhelp @@ -33,7 +33,7 @@ the query cannot be changed by a malicious user.

    -
  • OWASP: LDAP Injection Prevention Cheat Sheet.
  • +
  • OWASP: LDAP Injection Prevention Cheat Sheet.
  • OWASP: Preventing LDAP Injection in Java.
  • AntiXSS doc: LdapFilterEncode.
  • AntiXSS doc: LdapDistinguishedNameEncode.
  • diff --git a/csharp/ql/src/Security Features/CWE-091/XMLInjection.qhelp b/csharp/ql/src/Security Features/CWE-091/XMLInjection.qhelp index 4e70b06531a..3aff9901bfc 100644 --- a/csharp/ql/src/Security Features/CWE-091/XMLInjection.qhelp +++ b/csharp/ql/src/Security Features/CWE-091/XMLInjection.qhelp @@ -36,10 +36,10 @@ which ensures the content is appropriately escaped.

  • - XML Injection (The Web Application Security Consortium). + Web Application Security Consortium: XML Injection.
  • - WriteRaw (Microsoft documentation). + Microsoft Docs: WriteRaw.
  • diff --git a/csharp/ql/src/Security Features/CWE-114/AssemblyPathInjection.qhelp b/csharp/ql/src/Security Features/CWE-114/AssemblyPathInjection.qhelp index 5f95181c092..e1dbe9c1bd0 100644 --- a/csharp/ql/src/Security Features/CWE-114/AssemblyPathInjection.qhelp +++ b/csharp/ql/src/Security Features/CWE-114/AssemblyPathInjection.qhelp @@ -14,7 +14,7 @@ was not intended to be loaded, and executing arbitrary code.

    Avoid loading assemblies based on user provided input. If this is not possible, ensure that the path is validated before being used with Assembly. For example, compare the provided input -against a whitelist of known safe assemblies, or confirm that path is restricted to a single +against a whitelist of known safe assemblies, or confirm that the path is restricted to a single directory which only contains safe assemblies.

    @@ -30,8 +30,8 @@ is only loaded if the user input matches one of those options.

    -
  • - System.Reflection.Assembly (Microsoft documentation). +
  • Microsoft: + System.Reflection.Assembly.
  • diff --git a/csharp/ql/src/Security Features/CWE-321/HardcodedEncryptionKey.ql b/csharp/ql/src/Security Features/CWE-321/HardcodedEncryptionKey.ql index c09a67d756c..cce122ffa62 100644 --- a/csharp/ql/src/Security Features/CWE-321/HardcodedEncryptionKey.ql +++ b/csharp/ql/src/Security Features/CWE-321/HardcodedEncryptionKey.ql @@ -1,6 +1,6 @@ /** - * @name Do not use hard-coded encryption keys. - * @description The .Key property or rgbKey parameter of a SymmetricAlgorithm should never be a hardcoded value. + * @name Hard-coded encryption key + * @description The .Key property or rgbKey parameter of a SymmetricAlgorithm should never be a hard-coded value. * @kind problem * @id cs/hardcoded-key * @problem.severity error diff --git a/csharp/ql/src/Security Features/CWE-327/InsecureSQLConnection.qhelp b/csharp/ql/src/Security Features/CWE-327/InsecureSQLConnection.qhelp index ae69402eb7e..c59feeed61c 100644 --- a/csharp/ql/src/Security Features/CWE-327/InsecureSQLConnection.qhelp +++ b/csharp/ql/src/Security Features/CWE-327/InsecureSQLConnection.qhelp @@ -3,7 +3,6 @@ "qhelp.dtd"> -

    Finds uses of insecure SQL Connections string by not enabling the Encrypt option.

    SQL Server connections where the client is not enforcing the encryption in transit are susceptible to multiple attacks, including a man-in-the-middle, that would potentially compromise the user credentials and/or the TDS session. @@ -29,18 +28,17 @@ - -

  • - Selectively using secure connection to SQL Server +
  • Microsoft, SQL Protocols blog: + Selectively using secure connection to SQL Server.
  • -
  • - Net SqlClient (ADO .Net) +
  • Microsoft: + SqlConnection.ConnectionString Property. +
  • +
  • Microsoft: + Using Connection String Keywords with SQL Server Native Client. +
  • +
  • Microsoft: + Setting the connection properties.
  • -
  • SQL native driver (SNAC) -
  • -
  • - JDBC driver -
  • -
    diff --git a/csharp/ql/src/Security Features/CWE-327/InsecureSQLConnection.ql b/csharp/ql/src/Security Features/CWE-327/InsecureSQLConnection.ql index 0f855150aa9..78bcc1c19e5 100644 --- a/csharp/ql/src/Security Features/CWE-327/InsecureSQLConnection.ql +++ b/csharp/ql/src/Security Features/CWE-327/InsecureSQLConnection.ql @@ -1,6 +1,6 @@ /** * @name Insecure SQL connection - * @description TODO. + * @description Using an SQL Server connection without enforcing encryption is a security vulnerability. * @kind path-problem * @id cs/insecure-sql-connection * @problem.severity error diff --git a/csharp/ql/src/Security Features/CWE-451/MissingXFrameOptions.qhelp b/csharp/ql/src/Security Features/CWE-451/MissingXFrameOptions.qhelp index 7df415aff5b..6d5d298c8e4 100644 --- a/csharp/ql/src/Security Features/CWE-451/MissingXFrameOptions.qhelp +++ b/csharp/ql/src/Security Features/CWE-451/MissingXFrameOptions.qhelp @@ -51,7 +51,7 @@ This next example shows how to specify the X-Frame-Options header w
  • OWASP: -Clickjacking Defense Cheat Sheet. +Clickjacking Defense Cheat Sheet.
  • Mozilla: diff --git a/csharp/ql/src/Security Features/CWE-502/DeserializedDelegate.ql b/csharp/ql/src/Security Features/CWE-502/DeserializedDelegate.ql index 1c68f01e78b..31d28311908 100644 --- a/csharp/ql/src/Security Features/CWE-502/DeserializedDelegate.ql +++ b/csharp/ql/src/Security Features/CWE-502/DeserializedDelegate.ql @@ -5,14 +5,11 @@ * @kind problem * @id cs/deserialized-delegate * @problem.severity warning + * @precision high * @tags security * external/cwe/cwe-502 */ -/* - * consider: @precision high - */ - import csharp import semmle.code.csharp.frameworks.system.linq.Expressions import semmle.code.csharp.serialization.Deserializers diff --git a/csharp/ql/src/Security Features/CWE-502/UnsafeDeserialization.qhelp b/csharp/ql/src/Security Features/CWE-502/UnsafeDeserialization.qhelp index 7acfd20fe3a..3c68b74a1d9 100644 --- a/csharp/ql/src/Security Features/CWE-502/UnsafeDeserialization.qhelp +++ b/csharp/ql/src/Security Features/CWE-502/UnsafeDeserialization.qhelp @@ -5,7 +5,7 @@

    Deserializing an object from untrusted input may result in security problems, such -as denial-of-service or remote code execution.

    +as denial of service or remote code execution.

    diff --git a/csharp/ql/src/Security Features/CWE-502/UnsafeDeserialization.ql b/csharp/ql/src/Security Features/CWE-502/UnsafeDeserialization.ql index edd0e15c247..40022d40573 100644 --- a/csharp/ql/src/Security Features/CWE-502/UnsafeDeserialization.ql +++ b/csharp/ql/src/Security Features/CWE-502/UnsafeDeserialization.ql @@ -5,16 +5,13 @@ * @kind problem * @id cs/unsafe-deserialization * @problem.severity warning + * @precision low * @tags security * external/cwe/cwe-502 */ -/* - * consider: @precision low - */ - import csharp -import UnsafeDeserialization::UnsafeDeserialization +import semmle.code.csharp.security.dataflow.UnsafeDeserialization::UnsafeDeserialization from Call deserializeCall, Sink sink where deserializeCall.getAnArgument() = sink.asExpr() diff --git a/csharp/ql/src/Security Features/CWE-502/UnsafeDeserializationUntrustedInput.qhelp b/csharp/ql/src/Security Features/CWE-502/UnsafeDeserializationUntrustedInput.qhelp index ef946f40136..3ba934ba391 100644 --- a/csharp/ql/src/Security Features/CWE-502/UnsafeDeserializationUntrustedInput.qhelp +++ b/csharp/ql/src/Security Features/CWE-502/UnsafeDeserializationUntrustedInput.qhelp @@ -5,7 +5,7 @@

    Deserializing an object from untrusted input may result in security problems, such -as denial-of-service or remote code execution.

    +as denial of service or remote code execution.

    diff --git a/csharp/ql/src/Security Features/CWE-502/UnsafeDeserializationUntrustedInput.ql b/csharp/ql/src/Security Features/CWE-502/UnsafeDeserializationUntrustedInput.ql index b0b659857ab..80a3762a8bc 100644 --- a/csharp/ql/src/Security Features/CWE-502/UnsafeDeserializationUntrustedInput.ql +++ b/csharp/ql/src/Security Features/CWE-502/UnsafeDeserializationUntrustedInput.ql @@ -5,16 +5,13 @@ * @kind path-problem * @id cs/unsafe-deserialization-untrusted-input * @problem.severity error + * @precision high * @tags security * external/cwe/cwe-502 */ -/* - * consider: @precision high - */ - import csharp -import UnsafeDeserialization::UnsafeDeserialization +import semmle.code.csharp.security.dataflow.UnsafeDeserialization::UnsafeDeserialization import DataFlow::PathGraph from TaintTrackingConfig config, DataFlow::PathNode source, DataFlow::PathNode sink diff --git a/csharp/ql/src/Security Features/CWE-601/UrlRedirect.qhelp b/csharp/ql/src/Security Features/CWE-601/UrlRedirect.qhelp index 989796b6738..3cf3cdaba6e 100644 --- a/csharp/ql/src/Security Features/CWE-601/UrlRedirect.qhelp +++ b/csharp/ql/src/Security Features/CWE-601/UrlRedirect.qhelp @@ -32,7 +32,7 @@ It also shows how to remedy the problem by validating the user input against a k
  • OWASP: -XSS +XSS Unvalidated Redirects and Forwards Cheat Sheet.
  • diff --git a/csharp/ql/src/Security Features/CWE-611/UseXmlSecureResolver.qhelp b/csharp/ql/src/Security Features/CWE-611/UseXmlSecureResolver.qhelp index 2e8e4fcf272..11b1136db4d 100644 --- a/csharp/ql/src/Security Features/CWE-611/UseXmlSecureResolver.qhelp +++ b/csharp/ql/src/Security Features/CWE-611/UseXmlSecureResolver.qhelp @@ -38,7 +38,7 @@ The solution is to set the DtdProcessing property to DtdProce
  • OWASP: -XML External Entity (XXE) Prevention Cheat Sheet. +XML External Entity (XXE) Prevention Cheat Sheet.
  • Microsoft Docs: System.XML: Security considerations. diff --git a/csharp/ql/src/semmle/code/cil/ConsistencyChecks.qll b/csharp/ql/src/semmle/code/cil/ConsistencyChecks.qll index 7c3b751a2de..05bb424ac13 100644 --- a/csharp/ql/src/semmle/code/cil/ConsistencyChecks.qll +++ b/csharp/ql/src/semmle/code/cil/ConsistencyChecks.qll @@ -315,7 +315,7 @@ class InvalidReturn extends InstructionViolation { /** * A throw instruction that does not have a stack size of 0 after it. */ -class InvalidThrow extends InstructionViolation { +class InvalidThrow extends InstructionViolation, DisabledCheck { InvalidThrow() { instruction instanceof Throw and instruction.getStackSizeAfter() != 0 } override string getMessage() { diff --git a/csharp/ql/src/semmle/code/csharp/Caching.qll b/csharp/ql/src/semmle/code/csharp/Caching.qll index cd007d2bc54..83e2dd5e0cb 100644 --- a/csharp/ql/src/semmle/code/csharp/Caching.qll +++ b/csharp/ql/src/semmle/code/csharp/Caching.qll @@ -79,4 +79,21 @@ module Stages { forceCachingInSameStageRev() } } + + cached + module UnificationStage { + private import semmle.code.csharp.Unification + + cached + predicate forceCachingInSameStage() { any() } + + cached + private predicate forceCachingInSameStageRev() { + exists(CompoundTypeKind k) + or + exists(Unification::UnconstrainedTypeParameter utp) + or + forceCachingInSameStageRev() + } + } } diff --git a/csharp/ql/src/semmle/code/csharp/Conversion.qll b/csharp/ql/src/semmle/code/csharp/Conversion.qll index 617badac7d5..0fbabf3d7a8 100644 --- a/csharp/ql/src/semmle/code/csharp/Conversion.qll +++ b/csharp/ql/src/semmle/code/csharp/Conversion.qll @@ -15,29 +15,48 @@ import Type private import semmle.code.csharp.frameworks.System private import semmle.code.csharp.frameworks.system.collections.Generic -/** - * INTERNAL: Do not use. - * - * Holds if there exists an implicit conversion from `fromType` to `toType`. - * - * 6.1: Implicit type conversions. - * - * The following conversions are classified as implicit conversions: - * - * - Identity conversions - * - Implicit numeric conversions - * - Implicit nullable conversions - * - Implicit reference conversions - * - Boxing conversions - * - User-defined implicit conversions - */ cached -predicate implicitConversion(Type fromType, Type toType) { - implicitConversionNonNull(fromType, toType) - or - defaultNullConversion(fromType, toType) +private module Cached { + /** + * INTERNAL: Do not use. + * + * Holds if there exists an implicit conversion from `fromType` to `toType`. + * + * 6.1: Implicit type conversions. + * + * The following conversions are classified as implicit conversions: + * + * - Identity conversions + * - Implicit numeric conversions + * - Implicit nullable conversions + * - Implicit reference conversions + * - Boxing conversions + * - User-defined implicit conversions + */ + cached + predicate implicitConversion(Type fromType, Type toType) { + implicitConversionNonNull(fromType, toType) + or + defaultNullConversion(fromType, toType) + } + + /** + * INTERNAL: Do not use. + * + * Holds if there is a constant expression conversion from `fromType` to `toType`. + * + * 6.1.9: Implicit constant expression conversions. + */ + cached + predicate convConstantExpr(SignedIntegralConstantExpr e, SimpleType toType) { + convConstantIntExpr(e, toType) + or + convConstantLongExpr(e) and toType instanceof ULongType + } } +import Cached + private predicate implicitConversionNonNull(Type fromType, Type toType) { convIdentity(fromType, toType) or @@ -477,7 +496,7 @@ predicate convNullableType(ValueOrRefType fromType, NullableType toType) { // This is a deliberate, small Cartesian product, so we have manually lifted it to force the // evaluator to evaluate it in its entirety, rather than trying to optimize it in context. pragma[noinline] -private predicate defaultNullConversion(Type fromType, Type toType) { +predicate defaultNullConversion(Type fromType, Type toType) { fromType instanceof NullType and convNullType(toType) } @@ -612,19 +631,6 @@ private predicate convBoxingValueType(ValueType fromType, Type toType) { toType = fromType.getABaseInterface+() } -/** - * INTERNAL: Do not use. - * - * Holds if there is a constant expression conversion from `fromType` to `toType`. - * - * 6.1.9: Implicit constant expression conversions. - */ -predicate convConstantExpr(SignedIntegralConstantExpr e, SimpleType toType) { - convConstantIntExpr(e, toType) - or - convConstantLongExpr(e) and toType instanceof ULongType -} - private class SignedIntegralConstantExpr extends Expr { SignedIntegralConstantExpr() { this.getType() instanceof SignedIntegralType and diff --git a/csharp/ql/src/semmle/code/csharp/Implements.qll b/csharp/ql/src/semmle/code/csharp/Implements.qll index bd8b7d24589..2d176e4c300 100644 --- a/csharp/ql/src/semmle/code/csharp/Implements.qll +++ b/csharp/ql/src/semmle/code/csharp/Implements.qll @@ -236,63 +236,13 @@ private Type getArgumentOrReturnType(Method m, int i) { } /** - * INTERNAL: Do not use. - * * Provides an implementation of Global Value Numbering for types * (see https://en.wikipedia.org/wiki/Global_value_numbering), where * types are considered equal modulo identity conversions and method * type parameters (at the same index). */ -module Gvn { - private newtype TCompoundTypeKind = - TPointerTypeKind() or - TNullableTypeKind() or - TArrayTypeKind(int dim, int rnk) { - exists(ArrayType at | dim = at.getDimension() and rnk = at.getRank()) - } or - TConstructedType(UnboundGenericType ugt) - - /** A type kind for a compound type. */ - class CompoundTypeKind extends TCompoundTypeKind { - int getNumberOfTypeParameters() { - this = TPointerTypeKind() and result = 1 - or - this = TNullableTypeKind() and result = 1 - or - this = TArrayTypeKind(_, _) and result = 1 - or - exists(UnboundGenericType ugt | this = TConstructedType(ugt) | - result = ugt.getNumberOfTypeParameters() - ) - } - - string toString() { - this = TPointerTypeKind() and result = "*" - or - this = TNullableTypeKind() and result = "?" - or - exists(int dim, int rnk | this = TArrayTypeKind(dim, rnk) | - result = "[" + dim + ", " + rnk + "]" - ) - or - exists(UnboundGenericType ugt | this = TConstructedType(ugt) | - result = ugt.getNameWithoutBrackets() - ) - } - - Location getLocation() { result instanceof EmptyLocation } - } - - /** Gets the type kind for type `t`, if any. */ - CompoundTypeKind getTypeKind(Type t) { - result = TPointerTypeKind() and t instanceof PointerType - or - result = TNullableTypeKind() and t instanceof NullableType - or - t = any(ArrayType at | result = TArrayTypeKind(at.getDimension(), at.getRank())) - or - result = TConstructedType(t.(ConstructedType).getUnboundGeneric()) - } +private module Gvn { + private import semmle.code.csharp.Unification private class MethodTypeParameter extends TypeParameter { MethodTypeParameter() { this = any(UnboundGenericMethod ugm).getATypeParameter() } @@ -310,38 +260,47 @@ module Gvn { private newtype TGvnType = TLeafGvnType(int i) { id(_, i) } or TMethodTypeParameterGvnType(int i) { i = any(MethodTypeParameter p).getIndex() } or - TConstructedGvnType(TConstructedGvnType0 t) + TConstructedGvnType(ConstructedGvnTypeList l) - private newtype TConstructedGvnType0 = + private newtype TConstructedGvnTypeList = TConstructedGvnTypeNil(CompoundTypeKind k) or - TConstructedGvnTypeCons(TGvnType head, TConstructedGvnType0 tail) { - gvnConstructedCons(_, _, head, tail) + TConstructedGvnTypeCons(GvnType head, ConstructedGvnTypeList tail) { + gvnConstructedCons(_, _, _, head, tail) } - private TConstructedGvnType0 gvnConstructed(Type t, int i) { - result = TConstructedGvnTypeNil(getTypeKind(t)) and i = -1 + private ConstructedGvnTypeList gvnConstructed(Type t, CompoundTypeKind k, int i) { + result = TConstructedGvnTypeNil(k) and + i = -1 and + k = getTypeKind(t) or - exists(TGvnType head, TConstructedGvnType0 tail | gvnConstructedCons(t, i, head, tail) | + exists(GvnType head, ConstructedGvnTypeList tail | gvnConstructedCons(t, k, i, head, tail) | result = TConstructedGvnTypeCons(head, tail) ) } pragma[noinline] - private TGvnType gvnTypeChild(Type t, int i) { result = getGlobalValueNumber(t.getChild(i)) } + private GvnType gvnTypeChild(Type t, int i) { result = getGlobalValueNumber(t.getChild(i)) } pragma[noinline] - private predicate gvnConstructedCons(Type t, int i, TGvnType head, TConstructedGvnType0 tail) { - tail = gvnConstructed(t, i - 1) and + private predicate gvnConstructedCons( + Type t, CompoundTypeKind k, int i, GvnType head, ConstructedGvnTypeList tail + ) { + tail = gvnConstructed(t, k, i - 1) and head = gvnTypeChild(t, i) } /** Gets the global value number for a given type. */ + pragma[nomagic] GvnType getGlobalValueNumber(Type t) { result = TLeafGvnType(any(int i | id(t, i))) or result = TMethodTypeParameterGvnType(t.(MethodTypeParameter).getIndex()) or - result = TConstructedGvnType(gvnConstructed(t, getTypeKind(t).getNumberOfTypeParameters() - 1)) + exists(ConstructedGvnTypeList l, CompoundTypeKind k, int i | + l = gvnConstructed(t, k, i) and + i = k.getNumberOfTypeParameters() - 1 and + result = TConstructedGvnType(l) + ) } /** A global value number for a type. */ @@ -351,40 +310,42 @@ module Gvn { or exists(int i | this = TMethodTypeParameterGvnType(i) | result = "M!" + i) or - exists(GvnConstructedType t | this = TConstructedGvnType(t) | result = t.toString()) + exists(ConstructedGvnTypeList l | this = TConstructedGvnType(l) | result = l.toString()) } Location getLocation() { result instanceof EmptyLocation } } - /** A global value number for a constructed type. */ - class GvnConstructedType extends TConstructedGvnType0 { - private CompoundTypeKind getKind() { - this = TConstructedGvnTypeNil(result) + private class ConstructedGvnTypeList extends TConstructedGvnTypeList { + private int length() { + this = TConstructedGvnTypeNil(_) and result = -1 or - exists(GvnConstructedType tail | this = TConstructedGvnTypeCons(_, tail) | - result = tail.getKind() + exists(ConstructedGvnTypeList tail | this = TConstructedGvnTypeCons(_, tail) | + result = tail.length() + 1 ) } private GvnType getArg(int i) { - this = TConstructedGvnTypeCons(result, TConstructedGvnTypeNil(_)) and - i = 0 - or - exists(GvnConstructedType tail | this = TConstructedGvnTypeCons(result, tail) | - exists(tail.getArg(i - 1)) + exists(GvnType head, ConstructedGvnTypeList tail | + this = TConstructedGvnTypeCons(head, tail) + | + result = head and + i = this.length() + or + result = tail.getArg(i) ) } language[monotonicAggregates] string toString() { - exists(CompoundTypeKind k | k = this.getKind() | - result = k + "<" + - concat(int i | - i in [0 .. k.getNumberOfTypeParameters() - 1] - | - this.getArg(i).toString(), ", " - ) + ">" + exists(CompoundTypeKind k, string args | + this = gvnConstructed(_, k, _) and + args = concat(int i | + i in [0 .. k.getNumberOfTypeParameters() - 1] + | + this.getArg(i).toString(), ", " order by i + ) and + result = k.toString(args) ) } diff --git a/csharp/ql/src/semmle/code/csharp/Type.qll b/csharp/ql/src/semmle/code/csharp/Type.qll index bdd28d8a0af..d16f9eb4130 100644 --- a/csharp/ql/src/semmle/code/csharp/Type.qll +++ b/csharp/ql/src/semmle/code/csharp/Type.qll @@ -941,6 +941,8 @@ class TupleType extends ValueType, @tuple_type { } override string getLabel() { result = getUnderlyingType().getLabel() } + + override Type getChild(int i) { result = this.getUnderlyingType().getChild(i) } } /** diff --git a/csharp/ql/src/semmle/code/csharp/Unification.qll b/csharp/ql/src/semmle/code/csharp/Unification.qll new file mode 100644 index 00000000000..2102e16375e --- /dev/null +++ b/csharp/ql/src/semmle/code/csharp/Unification.qll @@ -0,0 +1,629 @@ +import csharp +private import Conversion +private import Caching + +pragma[noinline] +private Type getAProperSubType(Type t) { + not result instanceof DynamicType and + not result instanceof NullType and + result.isImplicitlyConvertibleTo(t) +} + +/** + * Provides an implementation of Global Value Numbering for types (see + * https://en.wikipedia.org/wiki/Global_value_numbering), where types are considered + * equal modulo identity conversions and type parameters. + */ +private module Gvn { + private class LeafType extends Type { + LeafType() { + not exists(this.getAChild()) and + not this instanceof TypeParameter + } + } + + /** A type kind for a compound type. */ + class CompoundTypeKindImpl extends TCompoundTypeKind { + /** Gets the number of type parameters for this kind. */ + int getNumberOfTypeParameters() { + this = TPointerTypeKind() and result = 1 + or + this = TNullableTypeKind() and result = 1 + or + this = TArrayTypeKind(_, _) and result = 1 + or + exists(UnboundGenericType ugt | this = TConstructedType(ugt) | + result = ugt.getNumberOfTypeParameters() + ) + } + + /** Gets a textual representation of this kind when applied to arguments `args`. */ + bindingset[args] + string toString(string args) { + this = TPointerTypeKind() and result = args + "*" + or + this = TNullableTypeKind() and result = args + "?" + or + exists(int dim, int rnk | this = TArrayTypeKind(dim, rnk) | + result = args + "[" + dim + ", " + rnk + "]" + ) + or + exists(UnboundGenericType ugt | this = TConstructedType(ugt) | + result = ugt.getNameWithoutBrackets() + "<" + args + ">" + ) + } + + /** Gets a textual representation of this kind. */ + string toString() { result = toString("") } + + /** Gets the location of this kind. */ + Location getLocation() { result instanceof EmptyLocation } + } + + /** Gets the type kind for type `t`, if any. */ + CompoundTypeKind getTypeKindImpl(Type t) { + result = TPointerTypeKind() and t instanceof PointerType + or + result = TNullableTypeKind() and t instanceof NullableType + or + t = any(ArrayType at | result = TArrayTypeKind(at.getDimension(), at.getRank())) + or + result = TConstructedType(t.(ConstructedType).getUnboundGeneric()) + or + result = TConstructedType(t.(TupleType).getUnderlyingType().getUnboundGeneric()) + or + result = TConstructedType(t) + } + + /** + * A global value number for a type. Two types have the same GVN when they + * are structurally equal modulo type parameters and identity conversions. + * For example, `Func` and `Func` have the same GVN, but + * `Func` and `Func` do not. + */ + class GvnType extends TGvnType { + /** Gets the compound type kind of this GVN, if any. */ + CompoundTypeKind getKind() { none() } + + /** Gets a textual representation of this GVN. */ + string toString() { + exists(int i | this = TLeafGvnType(i) | result = i.toString()) + or + this instanceof TTypeParameterGvnType and + result = "" + or + exists(ConstructedGvnTypeList l | this = TConstructedGvnType(l) | result = l.toString()) + } + + /** Gets the location of this GVN. */ + Location getLocation() { result instanceof EmptyLocation } + } + + class ConstructedGvnType extends GvnType, TConstructedGvnType { + private ConstructedGvnTypeList l; + + ConstructedGvnType() { this = TConstructedGvnType(l) } + + override CompoundTypeKind getKind() { result = l.getKind() } + } + + private ConstructedGvnTypeList gvnConstructed(Type t, CompoundTypeKind k, int i) { + result = TConstructedGvnTypeNil(k) and + i = -1 and + k = getTypeKind(t) + or + exists(GvnType head, ConstructedGvnTypeList tail | gvnConstructedCons(t, k, i, head, tail) | + result = TConstructedGvnTypeCons(head, tail) + ) + } + + pragma[noinline] + private GvnType gvnTypeChild(Type t, int i) { result = getGlobalValueNumber(t.getChild(i)) } + + pragma[noinline] + private predicate gvnConstructedCons( + Type t, CompoundTypeKind k, int i, GvnType head, ConstructedGvnTypeList tail + ) { + tail = gvnConstructed(t, k, i - 1) and + head = gvnTypeChild(t, i) + } + + private class ConstructedGvnTypeList extends TConstructedGvnTypeList { + CompoundTypeKind getKind() { this = gvnConstructed(_, result, _) } + + private int length() { + this = TConstructedGvnTypeNil(_) and result = -1 + or + exists(ConstructedGvnTypeList tail | this = TConstructedGvnTypeCons(_, tail) | + result = tail.length() + 1 + ) + } + + GvnType getArg(int i) { + exists(GvnType head, ConstructedGvnTypeList tail | + this = TConstructedGvnTypeCons(head, tail) + | + result = head and + i = this.length() + or + result = tail.getArg(i) + ) + } + + language[monotonicAggregates] + string toString() { + exists(CompoundTypeKind k, string args | + k = this.getKind() and + args = concat(int i | + i in [0 .. k.getNumberOfTypeParameters() - 1] + | + this.getArg(i).toString(), ", " order by i + ) and + result = k.toString(args) + ) + } + + Location getLocation() { result instanceof EmptyLocation } + } + + /** A GVN type that is an argument in a constructed type. */ + private class GvnTypeArgument extends GvnType { + GvnTypeArgument() { this = any(ConstructedGvnTypeList l).getArg(_) } + } + + /** Gets the 'i'th type argument of GVN type `t`, which is of kind `k`. */ + private GvnTypeArgument getTypeArgument(CompoundTypeKind k, ConstructedGvnType t, int i) { + exists(ConstructedGvnTypeList l | t = TConstructedGvnType(l) | + result = l.getArg(i) and + k = l.getKind() + ) + } + + pragma[noinline] + private GvnTypeArgument getNonTypeParameterTypeArgument( + CompoundTypeKind k, ConstructedGvnType t, int i + ) { + result = getTypeArgument(k, t, i) and + result != TTypeParameterGvnType() + } + + pragma[noinline] + private predicate typeArgumentIsTypeParameter(CompoundTypeKind k, ConstructedGvnType t, int i) { + getTypeArgument(k, t, i) = TTypeParameterGvnType() + } + + /** + * Hold if (non-type-parameters) `arg1` and `arg2` are unifiable, and both are + * the `i`th type argument of a compound type of kind `k`. + */ + pragma[nomagic] + private predicate unifiableNonTypeParameterTypeArguments( + CompoundTypeKind k, GvnTypeArgument arg1, GvnTypeArgument arg2, int i + ) { + exists(int j | + arg1 = getNonTypeParameterTypeArgument(k, _, i) and + arg2 = getNonTypeParameterTypeArgument(k, _, j) and + i <= j and + j <= i + | + arg1 = arg2 + or + unifiable(arg1, arg2) + ) + } + + /** + * Hold if `arg1` and `arg2` are unifiable, and both are the `i`th type argument + * of a compound type of kind `k`. + */ + pragma[nomagic] + private predicate unifiableTypeArguments( + CompoundTypeKind k, GvnTypeArgument arg1, GvnTypeArgument arg2, int i + ) { + unifiableNonTypeParameterTypeArguments(k, arg1, arg2, i) + or + exists(int j | + arg1 = TTypeParameterGvnType() and + typeArgumentIsTypeParameter(k, _, i) and + arg2 = getTypeArgument(k, _, j) and + i <= j and + j <= i + ) + or + exists(int j | + arg1 = getTypeArgument(k, _, i) and + typeArgumentIsTypeParameter(k, _, j) and + arg2 = TTypeParameterGvnType() and + i <= j and + j <= i + ) + } + + pragma[nomagic] + private predicate unifiableSingle0( + CompoundTypeKind k, ConstructedGvnType t2, GvnTypeArgument arg1, GvnTypeArgument arg2 + ) { + unifiableTypeArguments(k, arg1, arg2, 0) and + arg2 = getTypeArgument(k, t2, 0) and + k.getNumberOfTypeParameters() = 1 + } + + /** + * Holds if the type arguments of types `t1` and `t2` are unifiable, `t1` + * and `t2` are of the same kind, and the number of type arguments is 1. + */ + private predicate unifiableSingle(ConstructedGvnType t1, ConstructedGvnType t2) { + exists(CompoundTypeKind k, GvnTypeArgument arg1, GvnTypeArgument arg2 | + unifiableSingle0(k, t2, arg1, arg2) and + arg1 = getTypeArgument(k, t1, 0) + ) + } + + pragma[nomagic] + private predicate unifiableMultiple01Aux0( + CompoundTypeKind k, ConstructedGvnType t2, GvnTypeArgument arg10, GvnTypeArgument arg21 + ) { + exists(GvnTypeArgument arg20 | + unifiableTypeArguments(k, arg10, arg20, 0) and + arg20 = getTypeArgument(k, t2, 0) and + arg21 = getTypeArgument(k, t2, 1) + ) + } + + pragma[nomagic] + private predicate unifiableMultiple01Aux1( + CompoundTypeKind k, ConstructedGvnType t1, GvnTypeArgument arg10, GvnTypeArgument arg21 + ) { + exists(GvnTypeArgument arg11 | + unifiableTypeArguments(k, arg11, arg21, 1) and + arg10 = getTypeArgument(k, t1, 0) and + arg11 = getTypeArgument(k, t1, 1) + ) + } + + /** + * Holds if the first two type arguments of types `t1` and `t2` are unifiable, + * and both `t1` and `t2` are of kind `k`. + */ + private predicate unifiableMultiple01( + CompoundTypeKind k, ConstructedGvnType t1, ConstructedGvnType t2 + ) { + exists(GvnTypeArgument arg10, GvnTypeArgument arg21 | + unifiableMultiple01Aux0(k, t2, arg10, arg21) and + unifiableMultiple01Aux1(k, t1, arg10, arg21) + ) + } + + pragma[nomagic] + private predicate unifiableMultiple2Aux( + CompoundTypeKind k, ConstructedGvnType t2, int i, GvnTypeArgument arg1, GvnTypeArgument arg2 + ) { + unifiableTypeArguments(k, arg1, arg2, i) and + arg2 = getTypeArgument(k, t2, i) and + i >= 2 + } + + private predicate unifiableMultiple2( + CompoundTypeKind k, ConstructedGvnType t1, ConstructedGvnType t2, int i + ) { + exists(GvnTypeArgument arg1, GvnTypeArgument arg2 | + unifiableMultiple2Aux(k, t2, i, arg1, arg2) and + arg1 = getTypeArgument(k, t1, i) + ) + } + + /** + * Holds if the arguments 0 through `i` (with `i >= 1`) of types + * `t1` and `t2` are unifiable, and both `t1` and `t2` are of kind `k`. + */ + pragma[nomagic] + private predicate unifiableMultiple( + CompoundTypeKind k, ConstructedGvnType t1, ConstructedGvnType t2, int i + ) { + unifiableMultiple01(k, t1, t2) and i = 1 + or + unifiableMultiple(k, t1, t2, i - 1) and + unifiableMultiple2(k, t1, t2, i) + } + + private newtype TTypePath = + TTypePathNil() or + TTypePathCons(int head, TTypePath tail) { exists(getTypeAtCons(_, head, tail)) } + + /** + * Gets the GVN inside GVN `t`, by following the path `path`, if any. + */ + private GvnType getTypeAt(GvnType t, TTypePath path) { + path = TTypePathNil() and + result = t + or + exists(ConstructedGvnTypeList l, int head, TTypePath tail | + t = TConstructedGvnType(l) and + path = TTypePathCons(head, tail) and + result = getTypeAtCons(l, head, tail) + ) + } + + private GvnType getTypeAtCons(ConstructedGvnTypeList l, int head, TTypePath tail) { + result = getTypeAt(l.getArg(head), tail) + } + + /** + * Gets the leaf GVN inside GVN `t`, by following the path `path`, if any. + */ + private GvnType getLeafTypeAt(GvnType t, TTypePath path) { + result = getTypeAt(t, path) and + not result instanceof ConstructedGvnType + } + + private predicate id(LeafType t, int i) = equivalenceRelation(convIdentity/2)(t, i) + + cached + private module Cached { + cached + newtype TCompoundTypeKind = + TPointerTypeKind() { Stages::UnificationStage::forceCachingInSameStage() } or + TNullableTypeKind() or + TArrayTypeKind(int dim, int rnk) { + exists(ArrayType at | dim = at.getDimension() and rnk = at.getRank()) + } or + TConstructedType(UnboundGenericType ugt) + + cached + newtype TGvnType = + TLeafGvnType(int i) { id(_, i) } or + TTypeParameterGvnType() or + TConstructedGvnType(ConstructedGvnTypeList l) + + cached + newtype TConstructedGvnTypeList = + TConstructedGvnTypeNil(CompoundTypeKind k) or + TConstructedGvnTypeCons(GvnType head, ConstructedGvnTypeList tail) { + gvnConstructedCons(_, _, _, head, tail) + } + + /** Gets the GVN for type `t`. */ + cached + GvnType getGlobalValueNumber(Type t) { + result = TLeafGvnType(any(int i | id(t, i))) + or + t instanceof TypeParameter and + result = TTypeParameterGvnType() + or + exists(ConstructedGvnTypeList l, CompoundTypeKind k, int i | + l = gvnConstructed(t, k, i) and + i = k.getNumberOfTypeParameters() - 1 and + result = TConstructedGvnType(l) + ) + } + + /** + * Holds if GVNs `t1` and `t2` can be unified. That is, is it possible to + * replace all type parameters in `t1` and `t2` with some GVNs (possibly + * type parameters themselves) to make the two substituted terms equal. + */ + cached + predicate unifiable(ConstructedGvnType t1, ConstructedGvnType t2) { + unifiableSingle(t1, t2) + or + exists(CompoundTypeKind k | unifiableMultiple(k, t1, t2, k.getNumberOfTypeParameters() - 1)) + } + + /** + * Holds if GVN `t1` subsumes GVN `t2`. That is, is it possible to replace all + * type parameters in `t1` with some GVNs (possibly type parameters themselves) + * to make the two substituted terms equal. + */ + cached + predicate subsumes(ConstructedGvnType t1, ConstructedGvnType t2) { + unifiable(t1, t2) and // subsumption implies unification + forall(TTypePath path, GvnType leaf1 | leaf1 = getLeafTypeAt(t1, path) | + exists(GvnType child2 | child2 = getTypeAt(t2, path) | + leaf1 = TTypeParameterGvnType() + or + leaf1 = child2 + ) + ) + } + } + + import Cached +} + +class CompoundTypeKind = Gvn::CompoundTypeKindImpl; + +predicate getTypeKind = Gvn::getTypeKindImpl/1; + +/** Provides definitions related to type unification. */ +module Unification { + /** A type parameter that is compatible with any type. */ + class UnconstrainedTypeParameter extends TypeParameter { + UnconstrainedTypeParameter() { not exists(getATypeConstraint(this)) } + } + + /** A type parameter that is constrained. */ + class ConstrainedTypeParameter extends TypeParameter { + int constraintCount; + + ConstrainedTypeParameter() { constraintCount = strictcount(getATypeConstraint(this)) } + + /** + * Holds if this type parameter is unifiable with type `t`. + * + * Note: This predicate is inlined. + */ + bindingset[t] + predicate unifiable(Type t) { none() } + + /** + * Holds if this type parameter subsumes type `t` + * + * Note: This predicate is inlined. + */ + bindingset[t] + predicate subsumes(Type t) { none() } + } + + /** A type parameter that has a single constraint. */ + private class SingleConstraintTypeParameter extends ConstrainedTypeParameter { + SingleConstraintTypeParameter() { constraintCount = 1 } + + bindingset[t] + override predicate unifiable(Type t) { + exists(TTypeParameterConstraint ttc | ttc = getATypeConstraint(this) | + ttc = TRefTypeConstraint() and + t.isRefType() + or + ttc = TValueTypeConstraint() and + t.isValueType() + or + typeConstraintUnifiable(ttc, t) + ) + } + + bindingset[t] + override predicate subsumes(Type t) { + exists(TTypeParameterConstraint ttc | ttc = getATypeConstraint(this) | + ttc = TRefTypeConstraint() and + t.isRefType() + or + ttc = TValueTypeConstraint() and + t.isValueType() + or + typeConstraintSubsumes(ttc, t) + ) + } + } + + /** A type parameter that has multiple constraints. */ + private class MultiConstraintTypeParameter extends ConstrainedTypeParameter { + MultiConstraintTypeParameter() { constraintCount > 1 } + + bindingset[t] + override predicate unifiable(Type t) { + forex(TTypeParameterConstraint ttc | ttc = getATypeConstraint(this) | + ttc = TRefTypeConstraint() and + t.isRefType() + or + ttc = TValueTypeConstraint() and + t.isValueType() + or + typeConstraintUnifiable(ttc, t) + ) + } + + bindingset[t] + override predicate subsumes(Type t) { + forex(TTypeParameterConstraint ttc | ttc = getATypeConstraint(this) | + ttc = TRefTypeConstraint() and + t.isRefType() + or + ttc = TValueTypeConstraint() and + t.isValueType() + or + typeConstraintSubsumes(ttc, t) + ) + } + } + + cached + private module Cached { + cached + newtype TTypeParameterConstraint = + TRefTypeConstraint() or + TValueTypeConstraint() or + TTypeConstraint(Type t) { + t = any(TypeParameterConstraints tpc).getATypeConstraint() and + not t instanceof TypeParameter + } + + cached + TTypeParameterConstraint getATypeConstraint(TypeParameter tp) { + exists(TypeParameterConstraints tpc | tpc = tp.getConstraints() | + tpc.hasRefTypeConstraint() and + result = TRefTypeConstraint() + or + tpc.hasNullableRefTypeConstraint() and + result = TRefTypeConstraint() + or + tpc.hasValueTypeConstraint() and + result = TValueTypeConstraint() + or + result = TTypeConstraint(tpc.getATypeConstraint()) + or + result = getATypeConstraint(tpc.getATypeConstraint()) + ) + } + + cached + predicate typeConstraintUnifiable(TTypeConstraint ttc, Type t) { + exists(Type t0 | ttc = TTypeConstraint(t0) | t = getAProperSubType(t0)) + or + exists(Type t0, Type t1 | ttc = TTypeConstraint(t0) and unifiable(t0, t1) | + t = getAProperSubType(t1) + ) + } + + cached + predicate typeConstraintSubsumes(TTypeConstraint ttc, Type t) { + exists(Type t0 | ttc = TTypeConstraint(t0) | t = getAProperSubType(t0)) + or + exists(Type t0, Type t1 | ttc = TTypeConstraint(t0) and subsumes(t0, t1) | + t = getAProperSubType(t1) + ) + } + } + + private import Cached + + /** + * Holds if types `t1` and `t2` are unifiable. That is, is it possible to replace + * all type parameters in `t1` and `t2` with some (other) types to make the two + * substituted terms equal. + * + * This predicate covers only the case when `t1` and `t2` are constructed types; + * the other three cases are: + * + * 1. Neither `t1` nor `t2` are type parameters; in this case `t1` and `t2` must + * be equal. + * 2. `t1` or `t2` is an unconstrained type parameter; in this case `t1` and + * `t2` are always unifiable. + * 3. `t1` or `t2` is a constrained type parameter; in this case the predicate + * `ConstrainedTypeParameter::unifiable()` can be used. + * + * + * For performance reasons, type paramater constraints inside `t1` and `t2` are + * *not* taken into account, and there is also no guarantee that the same type + * parameter can be substituted with two different terms. For example, in + * + * ```csharp + * class C + * { + * void M(C c) where T3 : struct { } + * } + * ``` + * + * the type `C` is considered unifiable with both `C` and + * `C`. + * + * Note: This predicate is inlined. + */ + pragma[inline] + predicate unifiable(Type t1, Type t2) { + Gvn::unifiable(Gvn::getGlobalValueNumber(t1), Gvn::getGlobalValueNumber(t2)) + } + + /** + * Holds if type `t1` subsumes type `t2`. That is, is it possible to replace all + * type parameters in `t1` with some (other) types to make the two types equal. + * + * The same limitations that apply to the predicate `unifiable()` apply to this + * predicate as well. + * + * Note: This predicate is inlined. + */ + pragma[inline] + predicate subsumes(Type t1, Type t2) { + Gvn::subsumes(Gvn::getGlobalValueNumber(t1), Gvn::getGlobalValueNumber(t2)) + } +} diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index d1ca7596f30..e69d5d93bf5 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -86,6 +86,10 @@ module LocalFlow { scope = e2 and isSuccessor = true or + e1 = e2.(NullCoalescingExpr).getAnOperand() and + scope = e2 and + isSuccessor = false + or e1 = e2.(SuppressNullableWarningExpr).getExpr() and scope = e2 and isSuccessor = true diff --git a/csharp/ql/src/semmle/code/csharp/dispatch/Dispatch.qll b/csharp/ql/src/semmle/code/csharp/dispatch/Dispatch.qll index 15420c7fcaf..433f916fb57 100644 --- a/csharp/ql/src/semmle/code/csharp/dispatch/Dispatch.qll +++ b/csharp/ql/src/semmle/code/csharp/dispatch/Dispatch.qll @@ -7,11 +7,6 @@ import csharp private import RuntimeCallable -private import OverridableCallable -private import semmle.code.csharp.Conversion -private import semmle.code.csharp.dataflow.internal.Steps -private import semmle.code.csharp.frameworks.System -private import semmle.code.csharp.frameworks.system.Reflection /** A call. */ class DispatchCall extends Internal::TDispatchCall { @@ -39,7 +34,12 @@ class DispatchCall extends Internal::TDispatchCall { /** Internal implementation details. */ private module Internal { - private import semmle.code.csharp.Implements + private import OverridableCallable + private import semmle.code.csharp.Conversion + private import semmle.code.csharp.Unification + private import semmle.code.csharp.dataflow.internal.Steps + private import semmle.code.csharp.frameworks.System + private import semmle.code.csharp.frameworks.system.Reflection cached private module Cached { @@ -166,7 +166,10 @@ private module Internal { /** A call. */ abstract private class DispatchCallImpl extends TDispatchCall { /** Gets a textual representation of this call. */ - string toString() { none() } + string toString() { result = this.getCall().toString() } + + /** Gets the location of this call. */ + Location getLocation() { result = this.getCall().getLocation() } /** Gets the underlying expression of this call. */ abstract Expr getCall(); @@ -185,56 +188,65 @@ private module Internal { /** Gets a dynamic (run-time) target of this call, if any. */ abstract RuntimeCallable getADynamicTarget(); + } - /** - * Holds if the qualifier of this call has type `qualifierType`. - * `isExactType` indicates whether the type is exact, that is, whether - * the qualifier is guaranteed not to be a subtype of `qualifierType`. - */ - predicate hasQualifierType(Type qualifierType, boolean isExactType) { - exists(Type trackedType | trackedType = getAPossibleType(this.getQualifier(), isExactType) | - qualifierType = trackedType and - not qualifierType instanceof TypeParameter - or - qualifierType = trackedType.(TypeParameter).getAnUltimatelySuppliedType() - ) + pragma[noinline] + private predicate hasCallable(OverridableCallable source, ValueOrRefType t, OverridableCallable c) { + c.getSourceDeclaration() = source and + t.hasCallable(c) and + hasQualifierTypeOverridden0(t, _) and + hasQualifierTypeOverridden1(source, _) + } + + pragma[noinline] + private Unification::ConstrainedTypeParameter getAConstrainedTypeParameterQualifierType( + DispatchMethodOrAccessorCall call + ) { + result = getAPossibleType(call.getQualifier(), false) + } + + pragma[noinline] + private predicate constrainedTypeParameterQualifierTypeSubsumes( + ValueOrRefType t, Unification::ConstrainedTypeParameter tp + ) { + tp = getAConstrainedTypeParameterQualifierType(_) and + tp.subsumes(t) + } + + pragma[noinline] + private predicate hasQualifierTypeOverridden0(ValueOrRefType t, DispatchMethodOrAccessorCall call) { + exists(Type t0 | t0 = getAPossibleType(call.getQualifier(), false) | + t = t0 + or + Unification::subsumes(t0, t) + or + t = t0.(Unification::UnconstrainedTypeParameter).getAnUltimatelySuppliedType() + ) + or + constrainedTypeParameterQualifierTypeSubsumes(t, getAConstrainedTypeParameterQualifierType(call)) + } + + pragma[noinline] + private predicate hasQualifierTypeOverridden1( + OverridableCallable c, DispatchMethodOrAccessorCall call + ) { + exists(OverridableCallable target | call.getAStaticTarget() = target | + c = target.getSourceDeclaration() + or + c = target.getAnUltimateImplementor().getSourceDeclaration() + ) + } + + abstract private class DispatchMethodOrAccessorCall extends DispatchCallImpl { + pragma[nomagic] + predicate hasQualifierTypeInherited(SourceDeclarationType t) { + t = getAPossibleType(this.getQualifier(), _).getSourceDeclaration() } - /** - * Gets a non-exact (see `hasQualifierType()`) qualifier type of this call - * that does not contain type parameters. - */ - private TypeWithoutTypeParameters getANonExactQualifierTypeWithoutTypeParameters() { - exists(Type qualifierType | hasQualifierType(qualifierType, false) | - // Qualifier type contains no type parameters: use it - result = qualifierType - or - // Qualifier type is a constructed type where all type arguments are type - // parameters: use the unbound generic type - exists(ConstructedType ct | - ct = qualifierType and - forex(Type arg | arg = ct.getATypeArgument() | arg instanceof TypeParameter) and - result = ct.getUnboundGeneric() - ) - or - // Qualifier type is a constructed type where some (but not all) type arguments - // are type parameters: consider all potential instantiations - result = qualifierType.(QualifierTypeWithTypeParameters).getAPotentialInstance() - ) - } - - /** - * Gets a non-exact (see `hasQualifierType()`) qualifier type of this call. - */ - ValueOrRefType getANonExactQualifierType() { - exists(TypeWithoutTypeParameters t | - t = this.getANonExactQualifierTypeWithoutTypeParameters() - | - result.(ConstructedType).getUnboundGeneric() = t - or - not t instanceof UnboundGenericType and - result = t - ) + pragma[nomagic] + predicate hasQualifierTypeOverridden(ValueOrRefType t, OverridableCallable c) { + hasQualifierTypeOverridden0(t, this) and + hasCallable(any(OverridableCallable oc | hasQualifierTypeOverridden1(oc, this)), t, c) } } @@ -394,7 +406,7 @@ private module Internal { * The set of viable targets is determined by taking virtual dispatch * into account. */ - private class DispatchMethodCall extends DispatchCallImpl, TDispatchMethodCall { + private class DispatchMethodCall extends DispatchMethodOrAccessorCall, TDispatchMethodCall { override MethodCall getCall() { this = TDispatchMethodCall(result) } override Expr getArgument(int i) { @@ -453,11 +465,14 @@ private module Internal { * `B.M`, and `B.M`, respectively. */ private RuntimeInstanceMethod getViableInherited() { - exists(NonConstructedOverridableMethod m, Type qualifierType, SourceDeclarationType t | - getAStaticTarget() = m.getAConstructingMethodOrSelf() and - hasQualifierType(qualifierType, _) and - t = qualifierType.getSourceDeclaration() and + exists(NonConstructedOverridableMethod m, SourceDeclarationType t | + this.getAStaticTarget() = m.getAConstructingMethodOrSelf() and + this.hasQualifierTypeInherited(t) + | result = m.getInherited(t) + or + t instanceof TypeParameter and + result = m ) } @@ -498,8 +513,7 @@ private module Internal { */ private RuntimeInstanceMethod getAViableOverrider() { exists(ValueOrRefType t, NonConstructedOverridableMethod m | - t = this.getANonExactQualifierType() and - this.getAStaticTarget() = m.getAConstructingMethodOrSelf() and + this.hasQualifierTypeOverridden(t, m.getAConstructingMethodOrSelf()) and result = m.getAnOverrider(t) ) } @@ -514,7 +528,7 @@ private module Internal { * The set of viable targets is determined by taking virtual dispatch * into account. */ - private class DispatchAccessorCall extends DispatchCallImpl, TDispatchAccessorCall { + private class DispatchAccessorCall extends DispatchMethodOrAccessorCall, TDispatchAccessorCall { override AccessorCall getCall() { this = TDispatchAccessorCall(result) } override Expr getArgument(int i) { result = getCall().getArgument(i) } @@ -587,19 +601,11 @@ private module Internal { private RuntimeAccessor getViableInherited() { exists(OverridableAccessor a, SourceDeclarationType t | this.getAStaticTarget() = a and - this.hasQualifierTypeSourceDecl(t) and + this.hasQualifierTypeInherited(t) and result = a.getInherited(t) ) } - pragma[noinline] - private predicate hasQualifierTypeSourceDecl(SourceDeclarationType t) { - exists(Type qualifierType | - this.hasQualifierType(qualifierType, _) and - t = qualifierType.getSourceDeclaration() - ) - } - /** * Gets an accessor that is defined in a subtype of the qualifier type of * this call, and which overrides the static target of this call. @@ -637,110 +643,32 @@ private module Internal { * respectively. */ private RuntimeAccessor getAViableOverrider() { - exists(ValueOrRefType t | t = this.getANonExactQualifierType() | - result = this.getAStaticTarget().(OverridableAccessor).getAnOverrider(t) + exists(ValueOrRefType t, OverridableAccessor a | + this.hasQualifierTypeOverridden(t, a) and + result = a.getAnOverrider(t) ) } } - /** An internal helper class for comparing two types modulo type parameters. */ - abstract private class StructurallyComparedModuloTypeParameters extends Type { - /** Gets a candidate for comparison against this type. */ - abstract Type getACandidate(); - - /** - * Holds if this type equals the type `t` modulo type parameters. - * - * Equality modulo type parameters is a weaker form of type unifiability. - * That is, if constructed types `s` and `t` are unifiable, then `s` and - * `t` are equal modulo type parameters, but the converse does not - * necessarily hold. (For example, `C` and - * `C` are equal modulo type parameters, but not - * unifiable.) - */ - predicate equalsModuloTypeParameters(Type t) { - t = getACandidate() and - sameModuloTypeParameters(this, t) - } - - /** - * Gets a potential instantiation of this type. - * - * A potential instantiation is a type without type parameters that - * is the result of replacing all type parameters in this type with - * non-type parameters. Note: the same type parameter may be replaced - * by different types at different positions. For example, - * `C` is considered a potential instantiation of `C`. - */ - TypeWithoutTypeParameters getAPotentialInstance() { equalsModuloTypeParameters(result) } - } - - private Type candidateInternal(Type t) { - result = t.(StructurallyComparedModuloTypeParameters).getACandidate() - or - exists(Type parent, Type uncle, int i | - uncle = candidateInternal(parent) and - t = parent.getChild(i) and - result = uncle.getChild(i) - ) - } - - /** Holds if types `x` and `y` are equal modulo type parameters. */ - private predicate sameModuloTypeParameters(Type x, Type y) { - y = candidateInternal(x) and - ( - x = y - or - x instanceof TypeParameter - or - y instanceof TypeParameter - or - // All of the children must be structurally equal - sameChildrenModuloTypeParameters(x, y, x.getNumberOfChildren() - 1) - ) - } - - pragma[noinline] - private Type candidateInternalKind(Type t, Gvn::CompoundTypeKind k) { - result = candidateInternal(t) and - k = Gvn::getTypeKind(t) - } - - /** - * Holds if the `i+1` first children of types `x` and `y` are equal - * modulo type parameters. - */ - pragma[nomagic] - private predicate sameChildrenModuloTypeParameters(Type x, Type y, int i) { - i = -1 and - y = candidateInternalKind(x, Gvn::getTypeKind(y)) - or - sameChildrenModuloTypeParameters(x, y, i - 1) and - sameModuloTypeParameters(x.getChild(i), y.getChild(i)) - } - - /** - * A qualifier type containing type parameters for which at - * least one of the type arguments is *not* a type parameter. - */ - private class QualifierTypeWithTypeParameters extends StructurallyComparedModuloTypeParameters { - QualifierTypeWithTypeParameters() { - containsTypeParameters() and - any(DispatchCallImpl dc).hasQualifierType(this, false) and - exists(Type arg | arg = getAChild() | not arg instanceof TypeParameter) - } - - override ConstructedType getACandidate() { - not result.containsTypeParameters() and - this.(ConstructedType).getUnboundGeneric() = result.getUnboundGeneric() - } - } - /** A reflection-based call or a call using dynamic types. */ abstract private class DispatchReflectionOrDynamicCall extends DispatchCallImpl { /** Gets the name of the callable being called in this call. */ abstract string getName(); + pragma[nomagic] + private predicate hasQualifierType(Type qualifierType, boolean isExactType) { + exists(Type t | t = getAPossibleType(this.getQualifier(), isExactType) | + qualifierType = t and + not t instanceof TypeParameter + or + Unification::subsumes(t, qualifierType) + or + t.(Unification::ConstrainedTypeParameter).unifiable(qualifierType) + or + qualifierType = t.(Unification::UnconstrainedTypeParameter).getAnUltimatelySuppliedType() + ) + } + /** * Gets a potential qualifier type of this call. * @@ -779,21 +707,17 @@ private module Internal { this.hasQualifierType(result, true) or // Non-exact qualifier type - exists(Type qualifierType | this.hasNonExactQualifierType(qualifierType) | + exists(Type qualifierType | this.hasQualifierType(qualifierType, false) | result = getANonExactQualifierSubType(qualifierType) ) } - private predicate hasNonExactQualifierType(Type qualifierType) { - this.hasQualifierType(qualifierType, false) - } - /** * Holds if the qualifier type is unknown (it is either `object` or * `dynamic`). */ private predicate hasUnknownQualifierType() { - exists(Type qualifierType | this.hasNonExactQualifierType(qualifierType) | + exists(Type qualifierType | this.hasQualifierType(qualifierType, false) | isUnknownType(qualifierType) ) } @@ -952,10 +876,21 @@ private module Internal { private predicate reflectionOrDynamicArgEqualsParamModuloTypeParameters( Type argumentType, Type parameterType ) { - exists(Type t | reflectionOrDynamicArgumentTypeIsImplicitlyConvertibleTo(argumentType, t) | - t - .(ReflectionOrDynamicCallArgumentWithTypeParameters) - .equalsModuloTypeParameters(parameterType) + exists(Type t | + reflectionOrDynamicArgumentTypeIsImplicitlyConvertibleTo(argumentType, t) and + isReflectionOrDynamicCallArgumentWithTypeParameters(t, parameterType) + | + parameterType = t + or + t instanceof Unification::UnconstrainedTypeParameter + or + parameterType instanceof Unification::UnconstrainedTypeParameter + or + t.(Unification::ConstrainedTypeParameter).unifiable(parameterType) + or + parameterType.(Unification::ConstrainedTypeParameter).unifiable(t) + or + Unification::unifiable(parameterType, t) ) } @@ -999,21 +934,6 @@ private module Internal { ) } - /** - * A type that is the argument type of a reflection-based call or a call using - * dynamic types, where either the type or the relevant parameter type of a - * potential run-time target contains type parameters. - */ - private class ReflectionOrDynamicCallArgumentWithTypeParameters extends StructurallyComparedModuloTypeParameters { - ReflectionOrDynamicCallArgumentWithTypeParameters() { - isReflectionOrDynamicCallArgumentWithTypeParameters(this, _) - } - - override Type getACandidate() { - isReflectionOrDynamicCallArgumentWithTypeParameters(this, result) - } - } - /** A call using reflection. */ private class DispatchReflectionCall extends DispatchReflectionOrDynamicCall, TDispatchReflectionCall { diff --git a/csharp/ql/src/semmle/code/csharp/dispatch/OverridableCallable.qll b/csharp/ql/src/semmle/code/csharp/dispatch/OverridableCallable.qll index 9ea011eb613..e8c717b8e09 100644 --- a/csharp/ql/src/semmle/code/csharp/dispatch/OverridableCallable.qll +++ b/csharp/ql/src/semmle/code/csharp/dispatch/OverridableCallable.qll @@ -185,28 +185,16 @@ class OverridableCallable extends Callable { pragma[noinline] private Callable getAnOverrider0(ValueOrRefType t) { - not this.declaredInTypeWithTypeParameters() and - ( - // A (transitive) overrider - result = this.getAnOverrider+() and - t = result.getDeclaringType() - or - // An interface implementation - result = this.getAnImplementorSubType(t) - or - // A (transitive) overrider of an interface implementation - result = this.getAnOverridingImplementor() and - t = result.getDeclaringType() - ) - } - - private Callable getAnOverrider1(ValueOrRefType t) { - result = this.getAnOverrider0(t) + // A (transitive) overrider + result = this.getAnOverrider+() and + t = result.getDeclaringType() or - exists(ValueOrRefType mid | result = this.getAnOverrider1(mid) | - t = mid.getABaseType() and - this.isDeclaringSubType(t) - ) + // An interface implementation + result = this.getAnImplementorSubType(t) + or + // A (transitive) overrider of an interface implementation + result = this.getAnOverridingImplementor() and + t = result.getDeclaringType() } /** @@ -220,36 +208,12 @@ class OverridableCallable extends Callable { * contains a callable that overrides this callable, then only if `C2` * is ever constructed will the callable in `C2` be considered valid. */ - Callable getAnOverrider(ValueOrRefType t) { result = this.getABoundInstance().getAnOverrider1(t) } - - /** - * Gets a bound instance of this callable. - * - * If this callable is defined in a type that contains type parameters, - * returns an instance defined in a constructed type, otherwise the - * callable itself. - */ - private OverridableCallable getABoundInstance() { - not declaredInTypeWithTypeParameters() and - result = this + Callable getAnOverrider(ValueOrRefType t) { + result = this.getAnOverrider0(t) or - result.getSourceDeclaration() = getSourceDeclarationInTypeWithTypeParameters() - } - - // predicate folding to get proper join order - private OverridableCallable getSourceDeclarationInTypeWithTypeParameters() { - declaredInTypeWithTypeParameters() and - result = getSourceDeclaration() - } - - private predicate declaredInTypeWithTypeParameters() { - exists(ValueOrRefType t | t = getDeclaringType() | - t.containsTypeParameters() - or - // Access to a local callable, `this.M()`, in a generic class - // results in a static target where the declaring type is - // the unbound generic version - t instanceof UnboundGenericType + exists(ValueOrRefType mid | result = this.getAnOverrider(mid) | + t = mid.getABaseType() and + this.isDeclaringSubType(t) ) } } @@ -328,12 +292,7 @@ private int getAccessorKind(Accessor a) { event_accessors(a, -result, _, _, _) } -/** A type not containing type parameters. */ -class TypeWithoutTypeParameters extends Type { - TypeWithoutTypeParameters() { not containsTypeParameters() } -} - /** A source declared type. */ -class SourceDeclarationType extends TypeWithoutTypeParameters { - SourceDeclarationType() { this = getSourceDeclaration() } +class SourceDeclarationType extends Type { + SourceDeclarationType() { this = this.getSourceDeclaration() } } diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/IRType.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/IRType.qll index 0abfa14023d..73cdbd20989 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/IRType.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/IRType.qll @@ -4,6 +4,7 @@ private import internal.IRTypeInternal +cached private newtype TIRType = TIRVoidType() or TIRUnknownType() or @@ -42,6 +43,10 @@ class IRType extends TIRType { * * This will hold for all `IRType` objects except `IRUnknownType`. */ + // This predicate is overridden with `pragma[noinline]` in every leaf subclass. + // This allows callers to ask for things like _the_ floating-point type of + // size 4 without getting a join that first finds all types of size 4 and + // _then_ restricts them to floating-point types. int getByteSize() { none() } /** @@ -104,8 +109,6 @@ private class IRSizedType extends IRType { this = TIRFunctionAddressType(byteSize) or this = TIROpaqueType(_, byteSize) } - - final override int getByteSize() { result = byteSize } } /** @@ -117,6 +120,9 @@ class IRBooleanType extends IRSizedType, TIRBooleanType { final override Language::LanguageType getCanonicalLanguageType() { result = Language::getCanonicalBooleanType(byteSize) } + + pragma[noinline] + final override int getByteSize() { result = byteSize } } /** @@ -141,6 +147,9 @@ class IRSignedIntegerType extends IRNumericType, TIRSignedIntegerType { final override Language::LanguageType getCanonicalLanguageType() { result = Language::getCanonicalSignedIntegerType(byteSize) } + + pragma[noinline] + final override int getByteSize() { result = byteSize } } /** @@ -153,6 +162,9 @@ class IRUnsignedIntegerType extends IRNumericType, TIRUnsignedIntegerType { final override Language::LanguageType getCanonicalLanguageType() { result = Language::getCanonicalUnsignedIntegerType(byteSize) } + + pragma[noinline] + final override int getByteSize() { result = byteSize } } /** @@ -164,6 +176,9 @@ class IRFloatingPointType extends IRNumericType, TIRFloatingPointType { final override Language::LanguageType getCanonicalLanguageType() { result = Language::getCanonicalFloatingPointType(byteSize) } + + pragma[noinline] + final override int getByteSize() { result = byteSize } } /** @@ -178,6 +193,9 @@ class IRAddressType extends IRSizedType, TIRAddressType { final override Language::LanguageType getCanonicalLanguageType() { result = Language::getCanonicalAddressType(byteSize) } + + pragma[noinline] + final override int getByteSize() { result = byteSize } } /** @@ -190,6 +208,9 @@ class IRFunctionAddressType extends IRSizedType, TIRFunctionAddressType { final override Language::LanguageType getCanonicalLanguageType() { result = Language::getCanonicalFunctionAddressType(byteSize) } + + pragma[noinline] + final override int getByteSize() { result = byteSize } } /** @@ -218,6 +239,9 @@ class IROpaqueType extends IRSizedType, TIROpaqueType { * same size. */ final Language::OpaqueTypeTag getTag() { result = tag } + + pragma[noinline] + final override int getByteSize() { result = byteSize } } module IRTypeSanity { diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/MemoryAccessKind.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/MemoryAccessKind.qll index d4f1599d78e..a71608ee855 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/MemoryAccessKind.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/MemoryAccessKind.qll @@ -5,6 +5,7 @@ private newtype TMemoryAccessKind = TBufferMayMemoryAccess() or TEscapedMemoryAccess() or TEscapedMayMemoryAccess() or + TNonLocalMayMemoryAccess() or TPhiMemoryAccess() or TUnmodeledMemoryAccess() or TChiTotalMemoryAccess() or @@ -80,6 +81,14 @@ class EscapedMayMemoryAccess extends MemoryAccessKind, TEscapedMayMemoryAccess { override string toString() { result = "escaped(may)" } } +/** + * The operand or result may access all memory whose address has escaped, other than data on the + * stack frame of the current function. + */ +class NonLocalMayMemoryAccess extends MemoryAccessKind, TNonLocalMayMemoryAccess { + override string toString() { result = "nonlocal(may)" } +} + /** * The operand is a Phi operand, which accesses the same memory as its * definition. diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/Opcode.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/Opcode.qll index 713893f52f7..edbec38d5b9 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/Opcode.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/Opcode.qll @@ -36,7 +36,7 @@ private newtype TOpcode = TPointerSub() or TPointerDiff() or TConvert() or - TConvertToBase() or + TConvertToNonVirtualBase() or TConvertToVirtualBase() or TConvertToDerived() or TCheckedConvertOrNull() or @@ -59,6 +59,7 @@ private newtype TOpcode = TUnmodeledDefinition() or TUnmodeledUse() or TAliasedDefinition() or + TAliasedUse() or TPhi() or TBuiltIn() or TVarArgsStart() or @@ -111,6 +112,8 @@ abstract class RelationalOpcode extends CompareOpcode { } abstract class CopyOpcode extends Opcode { } +abstract class ConvertToBaseOpcode extends UnaryOpcode { } + abstract class MemoryAccessOpcode extends Opcode { } abstract class ReturnOpcode extends Opcode { } @@ -311,11 +314,11 @@ module Opcode { final override string toString() { result = "Convert" } } - class ConvertToBase extends UnaryOpcode, TConvertToBase { - final override string toString() { result = "ConvertToBase" } + class ConvertToNonVirtualBase extends ConvertToBaseOpcode, TConvertToNonVirtualBase { + final override string toString() { result = "ConvertToNonVirtualBase" } } - class ConvertToVirtualBase extends UnaryOpcode, TConvertToVirtualBase { + class ConvertToVirtualBase extends ConvertToBaseOpcode, TConvertToVirtualBase { final override string toString() { result = "ConvertToVirtualBase" } } @@ -403,6 +406,10 @@ module Opcode { final override string toString() { result = "AliasedDefinition" } } + class AliasedUse extends Opcode, TAliasedUse { + final override string toString() { result = "AliasedUse" } + } + class Phi extends Opcode, TPhi { final override string toString() { result = "Phi" } } diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/internal/TIRVariable.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/internal/TIRVariable.qll index fea67ef5ecd..01c135abf13 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/internal/TIRVariable.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/internal/TIRVariable.qll @@ -9,4 +9,10 @@ newtype TIRVariable = Language::Function func, Language::AST ast, TempVariableTag tag, Language::LanguageType type ) { Construction::hasTempVariable(func, ast, tag, type) + } or + TIRStringLiteral( + Language::Function func, Language::AST ast, Language::LanguageType type, + Language::StringLiteral literal + ) { + Construction::hasStringLiteral(func, ast, type, literal) } diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll index 1a607f82c29..e10e266b2ab 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/IRVariable.qll @@ -22,6 +22,12 @@ abstract class IRVariable extends TIRVariable { abstract string toString(); + /** + * Holds if this variable's value cannot be changed within a function. Currently used for string + * literals, but could also apply to `const` global and static variables. + */ + predicate isReadOnly() { none() } + /** * Gets the type of the variable. */ @@ -113,34 +119,43 @@ class IRStaticUserVariable extends IRUserVariable { final override Language::StaticVariable getVariable() { result = var } } +abstract class IRGeneratedVariable extends IRVariable { + Language::AST ast; + Language::LanguageType type; + + final override Language::LanguageType getLanguageType() { result = type } + + final override Language::AST getAST() { result = ast } + + override string toString() { result = getBaseString() + getLocationString() } + + override string getUniqueId() { none() } + + final string getLocationString() { + result = ast.getLocation().getStartLine().toString() + ":" + + ast.getLocation().getStartColumn().toString() + } + + string getBaseString() { none() } +} + IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) { result.getAST() = ast and result.getTag() = tag } -class IRTempVariable extends IRVariable, IRAutomaticVariable, TIRTempVariable { - Language::AST ast; +class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable { TempVariableTag tag; - Language::LanguageType type; IRTempVariable() { this = TIRTempVariable(func, ast, tag, type) } - final override Language::LanguageType getLanguageType() { result = type } - - final override Language::AST getAST() { result = ast } - final override string getUniqueId() { result = "Temp: " + Construction::getTempVariableUniqueId(this) } final TempVariableTag getTag() { result = tag } - override string toString() { - result = getBaseString() + ast.getLocation().getStartLine().toString() + ":" + - ast.getLocation().getStartColumn().toString() - } - - string getBaseString() { result = "#temp" } + override string getBaseString() { result = "#temp" } } class IRReturnVariable extends IRTempVariable { @@ -154,3 +169,19 @@ class IRThrowVariable extends IRTempVariable { override string getBaseString() { result = "#throw" } } + +class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { + Language::StringLiteral literal; + + IRStringLiteral() { this = TIRStringLiteral(func, ast, type, literal) } + + final override predicate isReadOnly() { any() } + + final override string getUniqueId() { + result = "String: " + getLocationString() + "=" + Language::getStringLiteralText(literal) + } + + override string getBaseString() { result = "#string" } + + final Language::StringLiteral getLiteral() { result = literal } +} diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll index a2a39e4d42e..8e785015828 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Instruction.qll @@ -51,7 +51,8 @@ module InstructionSanity { opcode instanceof ReadSideEffectOpcode or opcode instanceof Opcode::InlineAsm or opcode instanceof Opcode::CallSideEffect or - opcode instanceof Opcode::ReturnIndirection + opcode instanceof Opcode::ReturnIndirection or + opcode instanceof Opcode::AliasedUse ) and tag instanceof SideEffectOperandTag ) @@ -124,6 +125,16 @@ module InstructionSanity { ) } + query predicate duplicateChiOperand( + ChiInstruction chi, string message, IRFunction func, string funcText + ) { + chi.getTotal() = chi.getPartial() and + message = "Chi instruction for " + chi.getPartial().toString() + + " has duplicate operands in function $@" and + func = chi.getEnclosingIRFunction() and + funcText = Language::getIdentityString(func.getFunction()) + } + query predicate sideEffectWithoutPrimary( SideEffectInstruction instr, string message, IRFunction func, string funcText ) { @@ -264,6 +275,7 @@ module InstructionSanity { ) { exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex | not useOperand.getUse() instanceof UnmodeledUseInstruction and + not defInstr instanceof UnmodeledDefinitionInstruction and pointOfEvaluation(useOperand, useBlock, useIndex) and defInstr = useOperand.getAnyDef() and ( @@ -827,14 +839,12 @@ class FloatConstantInstruction extends ConstantInstruction { FloatConstantInstruction() { getResultType() instanceof Language::FloatingPointType } } -class StringConstantInstruction extends Instruction { - Language::StringLiteral value; +class StringConstantInstruction extends VariableInstruction { + override IRStringLiteral var; - StringConstantInstruction() { value = Construction::getInstructionStringLiteral(this) } + final override string getImmediateString() { result = Language::getStringLiteralText(getValue()) } - final override string getImmediateString() { result = Language::getStringLiteralText(value) } - - final Language::StringLiteral getValue() { result = value } + final Language::StringLiteral getValue() { result = var.getLiteral() } } class BinaryInstruction extends Instruction { @@ -1002,14 +1012,22 @@ class InheritanceConversionInstruction extends UnaryInstruction { * to the address of a direct non-virtual base class. */ class ConvertToBaseInstruction extends InheritanceConversionInstruction { - ConvertToBaseInstruction() { getOpcode() instanceof Opcode::ConvertToBase } + ConvertToBaseInstruction() { getOpcode() instanceof ConvertToBaseOpcode } +} + +/** + * Represents an instruction that converts from the address of a derived class + * to the address of a direct non-virtual base class. + */ +class ConvertToNonVirtualBaseInstruction extends ConvertToBaseInstruction { + ConvertToNonVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToNonVirtualBase } } /** * Represents an instruction that converts from the address of a derived class * to the address of a virtual base class. */ -class ConvertToVirtualBaseInstruction extends InheritanceConversionInstruction { +class ConvertToVirtualBaseInstruction extends ConvertToBaseInstruction { ConvertToVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToVirtualBase } } @@ -1442,6 +1460,13 @@ class AliasedDefinitionInstruction extends Instruction { final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess } } +/** + * An instruction that consumes all escaped memory on exit from the function. + */ +class AliasedUseInstruction extends Instruction { + AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse } +} + class UnmodeledUseInstruction extends Instruction { UnmodeledUseInstruction() { getOpcode() instanceof Opcode::UnmodeledUse } diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Operand.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Operand.qll index c85d609d200..8042dfa6a69 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Operand.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/Operand.qll @@ -396,6 +396,9 @@ class SideEffectOperand extends TypedOperand { override SideEffectOperandTag tag; override MemoryAccessKind getMemoryAccess() { + useInstr instanceof AliasedUseInstruction and + result instanceof NonLocalMayMemoryAccess + or useInstr instanceof CallSideEffectInstruction and result instanceof EscapedMayMemoryAccess or diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/IRConstruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/IRConstruction.qll index 0d2627e183f..72881a7c720 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/IRConstruction.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/IRConstruction.qll @@ -52,6 +52,15 @@ private module Cached { ) } + cached + predicate hasStringLiteral( + Callable callable, Language::AST ast, CSharpType type, StringLiteral literal + ) { + literal = ast and + literal.getEnclosingCallable() = callable and + getTypeForPRValue(literal.getType()) = type + } + cached predicate hasModeledMemoryResult(Instruction instruction) { none() } @@ -232,8 +241,14 @@ private module Cached { cached IRVariable getInstructionVariable(Instruction instruction) { - result = getInstructionTranslatedElement(instruction) - .getInstructionVariable(getInstructionTag(instruction)) + exists(TranslatedElement element, InstructionTag tag | + element = getInstructionTranslatedElement(instruction) and + tag = getInstructionTag(instruction) and + ( + result = element.getInstructionVariable(tag) or + result.(IRStringLiteral).getAST() = element.getInstructionStringLiteral(tag) + ) + ) } cached @@ -265,12 +280,6 @@ private module Cached { .getInstructionConstantValue(getInstructionTag(instruction)) } - cached - StringLiteral getInstructionStringLiteral(Instruction instruction) { - result = getInstructionTranslatedElement(instruction) - .getInstructionStringLiteral(getInstructionTag(instruction)) - } - cached CSharpType getInstructionExceptionType(Instruction instruction) { result = getInstructionTranslatedElement(instruction) diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/InstructionTag.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/InstructionTag.qll index 4130169b0cf..818d37cf803 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/InstructionTag.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/InstructionTag.qll @@ -32,6 +32,7 @@ newtype TInstructionTag = UnmodeledDefinitionTag() or UnmodeledUseTag() or AliasedDefinitionTag() or + AliasedUseTag() or SwitchBranchTag() or CallTargetTag() or CallTag() or @@ -131,6 +132,8 @@ string getInstructionTagId(TInstructionTag tag) { or tag = AliasedDefinitionTag() and result = "AliasedDef" or + tag = AliasedUseTag() and result = "AliasedUse" + or tag = SwitchBranchTag() and result = "SwitchBranch" or tag = CallTargetTag() and result = "CallTarget" diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/TranslatedFunction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/TranslatedFunction.qll index 5bcb66f7850..9d63f7060e9 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/TranslatedFunction.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/raw/internal/TranslatedFunction.qll @@ -99,6 +99,9 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction { result = this.getInstruction(UnmodeledUseTag()) or tag = UnmodeledUseTag() and + result = getInstruction(AliasedUseTag()) + or + tag = AliasedUseTag() and result = this.getInstruction(ExitFunctionTag()) ) } @@ -172,6 +175,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction { opcode instanceof Opcode::UnmodeledUse and resultType = getVoidType() or + tag = AliasedUseTag() and + opcode instanceof Opcode::AliasedUse and + resultType = getVoidType() + or tag = ExitFunctionTag() and opcode instanceof Opcode::ExitFunction and resultType = getVoidType() @@ -192,6 +199,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction { operandTag instanceof UnmodeledUseOperandTag and result = getUnmodeledDefinitionInstruction() or + tag = AliasedUseTag() and + operandTag instanceof SideEffectOperandTag and + result = getUnmodeledDefinitionInstruction() + or tag = ReturnTag() and not this.getReturnType() instanceof VoidType and ( @@ -208,6 +219,10 @@ class TranslatedFunction extends TranslatedElement, TTranslatedFunction { not this.getReturnType() instanceof VoidType and operandTag instanceof LoadOperandTag and result = getTypeForPRValue(this.getReturnType()) + or + tag = AliasedUseTag() and + operandTag instanceof SideEffectOperandTag and + result = getUnknownType() } final override IRVariable getInstructionVariable(InstructionTag tag) { diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll index 1a607f82c29..e10e266b2ab 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/IRVariable.qll @@ -22,6 +22,12 @@ abstract class IRVariable extends TIRVariable { abstract string toString(); + /** + * Holds if this variable's value cannot be changed within a function. Currently used for string + * literals, but could also apply to `const` global and static variables. + */ + predicate isReadOnly() { none() } + /** * Gets the type of the variable. */ @@ -113,34 +119,43 @@ class IRStaticUserVariable extends IRUserVariable { final override Language::StaticVariable getVariable() { result = var } } +abstract class IRGeneratedVariable extends IRVariable { + Language::AST ast; + Language::LanguageType type; + + final override Language::LanguageType getLanguageType() { result = type } + + final override Language::AST getAST() { result = ast } + + override string toString() { result = getBaseString() + getLocationString() } + + override string getUniqueId() { none() } + + final string getLocationString() { + result = ast.getLocation().getStartLine().toString() + ":" + + ast.getLocation().getStartColumn().toString() + } + + string getBaseString() { none() } +} + IRTempVariable getIRTempVariable(Language::AST ast, TempVariableTag tag) { result.getAST() = ast and result.getTag() = tag } -class IRTempVariable extends IRVariable, IRAutomaticVariable, TIRTempVariable { - Language::AST ast; +class IRTempVariable extends IRGeneratedVariable, IRAutomaticVariable, TIRTempVariable { TempVariableTag tag; - Language::LanguageType type; IRTempVariable() { this = TIRTempVariable(func, ast, tag, type) } - final override Language::LanguageType getLanguageType() { result = type } - - final override Language::AST getAST() { result = ast } - final override string getUniqueId() { result = "Temp: " + Construction::getTempVariableUniqueId(this) } final TempVariableTag getTag() { result = tag } - override string toString() { - result = getBaseString() + ast.getLocation().getStartLine().toString() + ":" + - ast.getLocation().getStartColumn().toString() - } - - string getBaseString() { result = "#temp" } + override string getBaseString() { result = "#temp" } } class IRReturnVariable extends IRTempVariable { @@ -154,3 +169,19 @@ class IRThrowVariable extends IRTempVariable { override string getBaseString() { result = "#throw" } } + +class IRStringLiteral extends IRGeneratedVariable, TIRStringLiteral { + Language::StringLiteral literal; + + IRStringLiteral() { this = TIRStringLiteral(func, ast, type, literal) } + + final override predicate isReadOnly() { any() } + + final override string getUniqueId() { + result = "String: " + getLocationString() + "=" + Language::getStringLiteralText(literal) + } + + override string getBaseString() { result = "#string" } + + final Language::StringLiteral getLiteral() { result = literal } +} diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll index a2a39e4d42e..8e785015828 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Instruction.qll @@ -51,7 +51,8 @@ module InstructionSanity { opcode instanceof ReadSideEffectOpcode or opcode instanceof Opcode::InlineAsm or opcode instanceof Opcode::CallSideEffect or - opcode instanceof Opcode::ReturnIndirection + opcode instanceof Opcode::ReturnIndirection or + opcode instanceof Opcode::AliasedUse ) and tag instanceof SideEffectOperandTag ) @@ -124,6 +125,16 @@ module InstructionSanity { ) } + query predicate duplicateChiOperand( + ChiInstruction chi, string message, IRFunction func, string funcText + ) { + chi.getTotal() = chi.getPartial() and + message = "Chi instruction for " + chi.getPartial().toString() + + " has duplicate operands in function $@" and + func = chi.getEnclosingIRFunction() and + funcText = Language::getIdentityString(func.getFunction()) + } + query predicate sideEffectWithoutPrimary( SideEffectInstruction instr, string message, IRFunction func, string funcText ) { @@ -264,6 +275,7 @@ module InstructionSanity { ) { exists(IRBlock useBlock, int useIndex, Instruction defInstr, IRBlock defBlock, int defIndex | not useOperand.getUse() instanceof UnmodeledUseInstruction and + not defInstr instanceof UnmodeledDefinitionInstruction and pointOfEvaluation(useOperand, useBlock, useIndex) and defInstr = useOperand.getAnyDef() and ( @@ -827,14 +839,12 @@ class FloatConstantInstruction extends ConstantInstruction { FloatConstantInstruction() { getResultType() instanceof Language::FloatingPointType } } -class StringConstantInstruction extends Instruction { - Language::StringLiteral value; +class StringConstantInstruction extends VariableInstruction { + override IRStringLiteral var; - StringConstantInstruction() { value = Construction::getInstructionStringLiteral(this) } + final override string getImmediateString() { result = Language::getStringLiteralText(getValue()) } - final override string getImmediateString() { result = Language::getStringLiteralText(value) } - - final Language::StringLiteral getValue() { result = value } + final Language::StringLiteral getValue() { result = var.getLiteral() } } class BinaryInstruction extends Instruction { @@ -1002,14 +1012,22 @@ class InheritanceConversionInstruction extends UnaryInstruction { * to the address of a direct non-virtual base class. */ class ConvertToBaseInstruction extends InheritanceConversionInstruction { - ConvertToBaseInstruction() { getOpcode() instanceof Opcode::ConvertToBase } + ConvertToBaseInstruction() { getOpcode() instanceof ConvertToBaseOpcode } +} + +/** + * Represents an instruction that converts from the address of a derived class + * to the address of a direct non-virtual base class. + */ +class ConvertToNonVirtualBaseInstruction extends ConvertToBaseInstruction { + ConvertToNonVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToNonVirtualBase } } /** * Represents an instruction that converts from the address of a derived class * to the address of a virtual base class. */ -class ConvertToVirtualBaseInstruction extends InheritanceConversionInstruction { +class ConvertToVirtualBaseInstruction extends ConvertToBaseInstruction { ConvertToVirtualBaseInstruction() { getOpcode() instanceof Opcode::ConvertToVirtualBase } } @@ -1442,6 +1460,13 @@ class AliasedDefinitionInstruction extends Instruction { final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess } } +/** + * An instruction that consumes all escaped memory on exit from the function. + */ +class AliasedUseInstruction extends Instruction { + AliasedUseInstruction() { getOpcode() instanceof Opcode::AliasedUse } +} + class UnmodeledUseInstruction extends Instruction { UnmodeledUseInstruction() { getOpcode() instanceof Opcode::UnmodeledUse } diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Operand.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Operand.qll index c85d609d200..8042dfa6a69 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Operand.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/Operand.qll @@ -396,6 +396,9 @@ class SideEffectOperand extends TypedOperand { override SideEffectOperandTag tag; override MemoryAccessKind getMemoryAccess() { + useInstr instanceof AliasedUseInstruction and + result instanceof NonLocalMayMemoryAccess + or useInstr instanceof CallSideEffectInstruction and result instanceof EscapedMayMemoryAccess or diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll index 1f5064f6766..a90eec8c17c 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll @@ -105,7 +105,7 @@ private predicate operandIsPropagated(Operand operand, IntValue bitOffset) { ( // REVIEW: See the REVIEW comment bellow // // Converting to a non-virtual base class adds the offset of the base class. - // exists(ConvertToBaseInstruction convert | + // exists(ConvertToNonVirtualBaseInstruction convert | // convert = instr and // bitOffset = Ints::mul(convert.getDerivation().getByteOffset(), 8) // ) diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll index 7152dec5c4a..a789edc7590 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll @@ -341,11 +341,6 @@ private module Cached { result = getOldInstruction(instruction).(OldIR::ConstantValueInstruction).getValue() } - cached - Language::StringLiteral getInstructionStringLiteral(Instruction instruction) { - result = getOldInstruction(instruction).(OldIR::StringConstantInstruction).getValue() - } - cached Language::BuiltInOperation getInstructionBuiltInOperation(Instruction instruction) { result = getOldInstruction(instruction) @@ -401,7 +396,11 @@ private predicate hasChiNode(Alias::VirtualVariable vvar, OldInstruction def) { defLocation.getVirtualVariable() = vvar and // If the definition totally (or exactly) overlaps the virtual variable, then there's no need for a `Chi` // instruction. - Alias::getOverlap(defLocation, vvar) instanceof MayPartiallyOverlap + ( + Alias::getOverlap(defLocation, vvar) instanceof MayPartiallyOverlap or + def.getResultMemoryAccess() instanceof IndirectMayMemoryAccess or + def.getResultMemoryAccess() instanceof BufferMayMemoryAccess + ) ) } @@ -714,7 +713,10 @@ module DefUse { defLocation = Alias::getResultMemoryLocation(def) and block.getInstruction(index) = def and overlap = Alias::getOverlap(defLocation, useLocation) and - if overlap instanceof MayPartiallyOverlap + if + overlap instanceof MayPartiallyOverlap or + def.getResultMemoryAccess() instanceof IndirectMayMemoryAccess or + def.getResultMemoryAccess() instanceof BufferMayMemoryAccess then offset = (index * 2) + 1 // The use will be connected to the definition on the `Chi` instruction. else offset = index * 2 // The use will be connected to the definition on the original instruction. ) diff --git a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll index 5925631b67c..49bb908265c 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/internal/SimpleSSA.qll @@ -30,7 +30,11 @@ private predicate isVariableModeled(IRVariable var) { hasResultMemoryAccess(instr, var, type, bitOffset) | bitOffset = 0 and - type.getIRType() = var.getIRType() + type.getIRType() = var.getIRType() and + not ( + instr.getResultMemoryAccess() instanceof IndirectMayMemoryAccess or + instr.getResultMemoryAccess() instanceof BufferMayMemoryAccess + ) ) and forall(MemoryOperand operand, Language::LanguageType type, IntValue bitOffset | hasOperandMemoryAccess(operand, var, type, bitOffset) diff --git a/csharp/ql/src/semmle/code/csharp/ir/internal/CSharpType.qll b/csharp/ql/src/semmle/code/csharp/ir/internal/CSharpType.qll index ac400b210a5..36b1285f9e0 100644 --- a/csharp/ql/src/semmle/code/csharp/ir/internal/CSharpType.qll +++ b/csharp/ql/src/semmle/code/csharp/ir/internal/CSharpType.qll @@ -144,6 +144,7 @@ private IRType getIRTypeForPRValue(Type type) { string getOpaqueTagIdentityString(Type tag) { result = tag.getQualifiedName() } +cached private newtype TCSharpType = TPRValueType(Type type) { exists(getIRTypeForPRValue(type)) } or TGLValueAddressType(Type type) { any() } or @@ -163,6 +164,7 @@ class CSharpType extends TCSharpType { * Gets the `IRType` that represents this `CSharpType`. Many different `CSharpType`s can map to a * single `IRType`. */ + cached abstract IRType getIRType(); /** diff --git a/csharp/ql/src/Security Features/CWE-502/UnsafeDeserialization.qll b/csharp/ql/src/semmle/code/csharp/security/dataflow/UnsafeDeserialization.qll similarity index 97% rename from csharp/ql/src/Security Features/CWE-502/UnsafeDeserialization.qll rename to csharp/ql/src/semmle/code/csharp/security/dataflow/UnsafeDeserialization.qll index 4e401eb4804..57b3a78485b 100644 --- a/csharp/ql/src/Security Features/CWE-502/UnsafeDeserialization.qll +++ b/csharp/ql/src/semmle/code/csharp/security/dataflow/UnsafeDeserialization.qll @@ -6,7 +6,6 @@ import csharp module UnsafeDeserialization { - private import semmle.code.csharp.dataflow.flowsources.Remote private import semmle.code.csharp.dataflow.flowsources.Remote private import semmle.code.csharp.serialization.Deserializers diff --git a/csharp/ql/test/library-tests/cil/consistency/consistency.expected b/csharp/ql/test/library-tests/cil/consistency/consistency.expected index 5adb77d40a2..d80b9543a10 100644 --- a/csharp/ql/test/library-tests/cil/consistency/consistency.expected +++ b/csharp/ql/test/library-tests/cil/consistency/consistency.expected @@ -1,6 +1 @@ -| System.Guid System.Guid.ParseExact(System.String,System.String): 11: throw, 0: ldarg.0 [push: 1, pop: 0]; 1: brtrue.s 5: [push: 0, pop: 1]; 2: ldstr "input" [push: 1, pop: 0]; 3: newobj System.ArgumentNullException..ctor [push: 1, pop: 1]; 4: throw [push: 0, pop: 1]; 5: ldarg.0 [push: 1, pop: 0]; 6: call System.String.op_Implicit [push: 1, pop: 1]; 7: ldarg.1 [push: 1, pop: 0]; 8: brtrue.s 12: [push: 0, pop: 1]; 9: ldstr "format" [push: 1, pop: 0]; 10: newobj System.ArgumentNullException..ctor [push: 1, pop: 1]; 11: throw [push: 0, pop: 1] | Throw has invalid stack size: 1 | | System.Runtime.CompilerServices.AsyncTaskMethodBuilder.DebugFinalizableAsyncStateMachineBox.Finalize | Overridden method from System.Object is not in a base type | -| System.Threading.CancellationTokenRegistration System.Threading.CancellationToken.Register(System.Action): 8: throw, 0: ldarg.0 [push: 1, pop: 0]; 1: ldsfld s_actionToActionObjShunt [push: 1, pop: 0]; 2: ldarg.1 [push: 1, pop: 0]; 3: dup [push: 2, pop: 1]; 4: brtrue.s 9: [push: 0, pop: 1]; 5: pop [push: 0, pop: 1]; 6: ldstr "callback" [push: 1, pop: 0]; 7: newobj System.ArgumentNullException..ctor [push: 1, pop: 1]; 8: throw [push: 0, pop: 1] | Throw has invalid stack size: 2 | -| System.Threading.CancellationTokenRegistration System.Threading.CancellationToken.Register(System.Action,System.Boolean): 8: throw, 0: ldarg.0 [push: 1, pop: 0]; 1: ldsfld s_actionToActionObjShunt [push: 1, pop: 0]; 2: ldarg.1 [push: 1, pop: 0]; 3: dup [push: 2, pop: 1]; 4: brtrue.s 9: [push: 0, pop: 1]; 5: pop [push: 0, pop: 1]; 6: ldstr "callback" [push: 1, pop: 0]; 7: newobj System.ArgumentNullException..ctor [push: 1, pop: 1]; 8: throw [push: 0, pop: 1] | Throw has invalid stack size: 2 | -| System.Void System.Guid..ctor(System.Byte[]): 7: throw, 0: ldarg.0 [push: 1, pop: 0]; 1: ldarg.1 [push: 1, pop: 0]; 2: dup [push: 2, pop: 1]; 3: brtrue.s 8: [push: 0, pop: 1]; 4: pop [push: 0, pop: 1]; 5: ldstr "b" [push: 1, pop: 0]; 6: newobj System.ArgumentNullException..ctor [push: 1, pop: 1]; 7: throw [push: 0, pop: 1] | Throw has invalid stack size: 1 | -| System.Void System.TermInfo.Database..ctor(System.String,System.Byte[]): 33: throw, 0: ldarg.0 [push: 1, pop: 0]; 1: call System.Object..ctor [push: 0, pop: 1]; 2: ldarg.0 [push: 1, pop: 0]; 3: ldarg.1 [push: 1, pop: 0]; 4: stfld _term [push: 0, pop: 2]; 5: ldarg.0 [push: 1, pop: 0]; 6: ldarg.2 [push: 1, pop: 0]; 7: stfld _data [push: 0, pop: 2]; 8: ldarg.2 [push: 1, pop: 0]; 9: ldc.i4.0 [push: 1, pop: 0]; 10: call System.TermInfo.Database.ReadInt16 [push: 1, pop: 2]; 11: stloc.0 L0 [push: 0, pop: 1]; 12: ldarg.0 [push: 1, pop: 0]; 13: ldloc.0 [push: 1, pop: 0]; 14: ldc.i4 72224 [push: 1, pop: 0]; 15: beq.s 36: [push: 0, pop: 2]; 16: ldloc.0 [push: 1, pop: 0]; 17: ldc.i4 138784 [push: 1, pop: 0]; 18: beq.s 34: [push: 0, pop: 2]; 19: call System.SR.get_IO_TermInfoInvalidMagicNumber [push: 1, pop: 0]; 20: ldc.i4.1 [push: 1, pop: 0]; 21: newarr System.String [push: 1, pop: 1]; 22: dup [push: 2, pop: 1]; 23: ldc.i4.0 [push: 1, pop: 0]; 24: ldstr "O" [push: 1, pop: 0]; 25: ldloc.0 [push: 1, pop: 0]; 26: ldc.i4.8 [push: 1, pop: 0]; 27: call System.Convert.ToString [push: 1, pop: 2]; 28: call System.String.Concat [push: 1, pop: 2]; 29: stelem.ref [push: 0, pop: 3]; 30: call System.String.Concat [push: 1, pop: 1]; 31: call System.SR.Format [push: 1, pop: 2]; 32: newobj System.InvalidOperationException..ctor [push: 1, pop: 1]; 33: throw [push: 0, pop: 1] | Throw has invalid stack size: 1 | diff --git a/csharp/ql/test/library-tests/cil/dataflow/CallableReturns.expected b/csharp/ql/test/library-tests/cil/dataflow/CallableReturns.expected index 6274315a905..7f25ad7f245 100644 --- a/csharp/ql/test/library-tests/cil/dataflow/CallableReturns.expected +++ b/csharp/ql/test/library-tests/cil/dataflow/CallableReturns.expected @@ -9,16 +9,11 @@ alwaysNull | System.Object System.Collections.EmptyReadOnlyDictionaryInternal.get_Item(System.Object) | 0: ldarg.1, 1: brtrue.s 6:, 2: ldstr "key", 3: call System.SR.get_ArgumentNull_Key, 4: newobj System.ArgumentNullException..ctor, 5: throw, 6: ldnull, 7: ret | alwaysNonNull | System.ArgumentException System.ThrowHelper.GetAddingDuplicateWithKeyArgumentException(System.Object) | -| System.ArgumentException System.ThrowHelper.GetArgumentException(System.ExceptionResource) | -| System.ArgumentException System.ThrowHelper.GetArgumentException(System.ExceptionResource,System.ExceptionArgument) | | System.ArgumentException System.ThrowHelper.GetWrongKeyTypeArgumentException(System.Object,System.Type) | | System.ArgumentException System.ThrowHelper.GetWrongValueTypeArgumentException(System.Object,System.Type) | | System.ArgumentNullException System.ThrowHelper.GetArgumentNullException(System.ExceptionArgument) | -| System.ArgumentOutOfRangeException System.ThrowHelper.GetArgumentOutOfRangeException(System.ExceptionArgument,System.ExceptionResource) | -| System.ArgumentOutOfRangeException System.ThrowHelper.GetArgumentOutOfRangeException(System.ExceptionArgument,System.Int32,System.ExceptionResource) | | System.Collections.Generic.KeyNotFoundException System.ThrowHelper.GetKeyNotFoundException(System.Object) | | System.Exception System.ThrowHelper.GetArraySegmentCtorValidationFailedException(System.Array,System.Int32,System.Int32) | -| System.InvalidOperationException System.ThrowHelper.GetInvalidOperationException(System.ExceptionResource) | | System.InvalidOperationException System.ThrowHelper.GetInvalidOperationException_EnumCurrent(System.Int32) | | System.Object Dataflow.NonNullMethods.ReturnsNonNull2() | | System.Object Dataflow.NonNullMethods.ReturnsNonNull() | @@ -41,25 +36,18 @@ alwaysThrows | System.Object System.ValueTuple.get_Item(System.Int32) | System.IndexOutOfRangeException | 0: newobj System.IndexOutOfRangeException..ctor, 1: throw | | System.Void System.ThrowHelper.ThrowAddingDuplicateWithKeyArgumentException`1(!0) | System.ArgumentException | 0: ldarg.0, 1: box, 2: call System.ThrowHelper.GetAddingDuplicateWithKeyArgumentException, 3: throw | | System.Void System.ThrowHelper.ThrowAggregateException(System.Collections.Generic.List) | System.AggregateException | 0: ldarg.0, 1: newobj System.AggregateException..ctor, 2: throw | -| System.Void System.ThrowHelper.ThrowArgumentException(System.ExceptionResource) | System.ArgumentException | 0: ldarg.0, 1: call System.ThrowHelper.GetArgumentException, 2: throw | -| System.Void System.ThrowHelper.ThrowArgumentException(System.ExceptionResource,System.ExceptionArgument) | System.ArgumentException | 0: ldarg.0, 1: ldarg.1, 2: call System.ThrowHelper.GetArgumentException, 3: throw | | System.Void System.ThrowHelper.ThrowArgumentException_Argument_InvalidArrayType() | System.ArgumentException | 0: ldc.i4.s 31, 1: call System.ThrowHelper.GetArgumentException, 2: throw | | System.Void System.ThrowHelper.ThrowArgumentException_DestinationTooShort() | System.ArgumentException | 0: call System.SR.get_Argument_DestinationTooShort, 1: newobj System.ArgumentException..ctor, 2: throw | | System.Void System.ThrowHelper.ThrowArgumentException_OverlapAlignmentMismatch() | System.ArgumentException | 0: call System.SR.get_Argument_OverlapAlignmentMismatch, 1: newobj System.ArgumentException..ctor, 2: throw | | System.Void System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument) | System.ArgumentNullException | 0: ldarg.0, 1: call System.ThrowHelper.GetArgumentNullException, 2: throw | -| System.Void System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument,System.ExceptionResource) | System.ArgumentNullException | 0: ldarg.0, 1: call System.ThrowHelper.GetArgumentName, 2: ldarg.1, 3: call System.ThrowHelper.GetResourceString, 4: newobj System.ArgumentNullException..ctor, 5: throw | | System.Void System.ThrowHelper.ThrowArgumentOutOfRangeException() | System.ArgumentOutOfRangeException | 0: newobj System.ArgumentOutOfRangeException..ctor, 1: throw | | System.Void System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument) | System.ArgumentOutOfRangeException | 0: ldarg.0, 1: call System.ThrowHelper.GetArgumentName, 2: newobj System.ArgumentOutOfRangeException..ctor, 3: throw | -| System.Void System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument,System.ExceptionResource) | System.ArgumentOutOfRangeException | 0: ldarg.0, 1: ldarg.1, 2: call System.ThrowHelper.GetArgumentOutOfRangeException, 3: throw | -| System.Void System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument,System.Int32,System.ExceptionResource) | System.ArgumentOutOfRangeException | 0: ldarg.0, 1: ldarg.1, 2: ldarg.2, 3: call System.ThrowHelper.GetArgumentOutOfRangeException, 4: throw | | System.Void System.ThrowHelper.ThrowArgumentOutOfRange_IndexException() | System.ArgumentOutOfRangeException | 0: ldc.i4.s 31, 1: ldc.i4.s 31, 2: call System.ThrowHelper.GetArgumentOutOfRangeException, 3: throw | | System.Void System.ThrowHelper.ThrowArraySegmentCtorValidationFailedExceptions(System.Array,System.Int32,System.Int32) | System.Exception | 0: ldarg.0, 1: ldarg.1, 2: ldarg.2, 3: call System.ThrowHelper.GetArraySegmentCtorValidationFailedException, 4: throw | | System.Void System.ThrowHelper.ThrowArrayTypeMismatchException() | System.ArrayTypeMismatchException | 0: newobj System.ArrayTypeMismatchException..ctor, 1: throw | | System.Void System.ThrowHelper.ThrowCountArgumentOutOfRange_ArgumentOutOfRange_Count() | System.ArgumentOutOfRangeException | 0: ldc.i4.s 31, 1: ldc.i4.s 31, 2: call System.ThrowHelper.GetArgumentOutOfRangeException, 3: throw | | System.Void System.ThrowHelper.ThrowIndexArgumentOutOfRange_NeedNonNegNumException() | System.ArgumentOutOfRangeException | 0: ldc.i4.s 31, 1: ldc.i4.4, 2: call System.ThrowHelper.GetArgumentOutOfRangeException, 3: throw | | System.Void System.ThrowHelper.ThrowIndexOutOfRangeException() | System.IndexOutOfRangeException | 0: newobj System.IndexOutOfRangeException..ctor, 1: throw | -| System.Void System.ThrowHelper.ThrowInvalidOperationException(System.ExceptionResource) | System.InvalidOperationException | 0: ldarg.0, 1: call System.ThrowHelper.GetInvalidOperationException, 2: throw | -| System.Void System.ThrowHelper.ThrowInvalidOperationException(System.ExceptionResource,System.Exception) | System.InvalidOperationException | 0: ldarg.0, 1: call System.ThrowHelper.GetResourceString, 2: ldarg.1, 3: newobj System.InvalidOperationException..ctor, 4: throw | | System.Void System.ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported() | System.InvalidOperationException | 0: ldc.i4.s 31, 1: call System.ThrowHelper.GetInvalidOperationException, 2: throw | | System.Void System.ThrowHelper.ThrowInvalidOperationException_EnumCurrent(System.Int32) | System.InvalidOperationException | 0: ldarg.0, 1: call System.ThrowHelper.GetInvalidOperationException_EnumCurrent, 2: throw | | System.Void System.ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumEnded() | System.InvalidOperationException | 0: ldc.i4.s 31, 1: call System.ThrowHelper.GetInvalidOperationException, 2: throw | @@ -71,11 +59,7 @@ alwaysThrows | System.Void System.ThrowHelper.ThrowKeyNotFoundException`1(!0) | System.Collections.Generic.KeyNotFoundException | 0: ldarg.0, 1: box, 2: call System.ThrowHelper.GetKeyNotFoundException, 3: throw | | System.Void System.ThrowHelper.ThrowLengthArgumentOutOfRange_ArgumentOutOfRange_NeedNonNegNum() | System.ArgumentOutOfRangeException | 0: ldc.i4.s 31, 1: ldc.i4.4, 2: call System.ThrowHelper.GetArgumentOutOfRangeException, 3: throw | | System.Void System.ThrowHelper.ThrowNotSupportedException() | System.NotSupportedException | 0: newobj System.NotSupportedException..ctor, 1: throw | -| System.Void System.ThrowHelper.ThrowNotSupportedException(System.ExceptionResource) | System.NotSupportedException | 0: ldarg.0, 1: call System.ThrowHelper.GetResourceString, 2: newobj System.NotSupportedException..ctor, 3: throw | -| System.Void System.ThrowHelper.ThrowObjectDisposedException(System.ExceptionResource) | System.ObjectDisposedException | 0: ldnull, 1: ldarg.0, 2: call System.ThrowHelper.GetResourceString, 3: newobj System.ObjectDisposedException..ctor, 4: throw | | System.Void System.ThrowHelper.ThrowOutOfMemoryException() | System.OutOfMemoryException | 0: newobj System.OutOfMemoryException..ctor, 1: throw | -| System.Void System.ThrowHelper.ThrowRankException(System.ExceptionResource) | System.RankException | 0: ldarg.0, 1: call System.ThrowHelper.GetResourceString, 2: newobj System.RankException..ctor, 3: throw | -| System.Void System.ThrowHelper.ThrowSerializationException(System.ExceptionResource) | System.Runtime.Serialization.SerializationException | 0: ldarg.0, 1: call System.ThrowHelper.GetResourceString, 2: newobj System.Runtime.Serialization.SerializationException..ctor, 3: throw | | System.Void System.ThrowHelper.ThrowStartIndexArgumentOutOfRange_ArgumentOutOfRange_Index() | System.ArgumentOutOfRangeException | 0: ldc.i4.s 31, 1: ldc.i4.s 31, 2: call System.ThrowHelper.GetArgumentOutOfRangeException, 3: throw | | System.Void System.ThrowHelper.ThrowWrongKeyTypeArgumentException`1(!0,System.Type) | System.ArgumentException | 0: ldarg.0, 1: box, 2: ldarg.1, 3: call System.ThrowHelper.GetWrongKeyTypeArgumentException, 4: throw | | System.Void System.ThrowHelper.ThrowWrongValueTypeArgumentException`1(!0,System.Type) | System.ArgumentException | 0: ldarg.0, 1: box, 2: ldarg.1, 3: call System.ThrowHelper.GetWrongValueTypeArgumentException, 4: throw | diff --git a/csharp/ql/test/library-tests/cil/dataflow/CallableReturns.ql b/csharp/ql/test/library-tests/cil/dataflow/CallableReturns.ql index 6aaca97ddde..8e32dd08514 100644 --- a/csharp/ql/test/library-tests/cil/dataflow/CallableReturns.ql +++ b/csharp/ql/test/library-tests/cil/dataflow/CallableReturns.ql @@ -6,7 +6,8 @@ predicate relevantMethod(CIL::Method m) { or m.getName() = "get_Item" or - m.getDeclaringType().getName() = "ThrowHelper" + m.getDeclaringType().getName() = "ThrowHelper" and + not m.getParameter(_).getType().getName() = "ExceptionResource" or m.getLocation().(CIL::Assembly).getName().matches("DataFlow%") } diff --git a/csharp/ql/test/library-tests/cil/dataflow/DataFlow.expected b/csharp/ql/test/library-tests/cil/dataflow/DataFlow.expected index 65e04f8d48c..d82ff134b35 100644 --- a/csharp/ql/test/library-tests/cil/dataflow/DataFlow.expected +++ b/csharp/ql/test/library-tests/cil/dataflow/DataFlow.expected @@ -12,6 +12,8 @@ | dataflow.cs:46:35:46:39 | "t1b" | dataflow.cs:46:18:46:40 | call to method Taint1 | | dataflow.cs:49:35:49:38 | "t6" | dataflow.cs:49:18:49:45 | call to method TaintIndirect | | dataflow.cs:49:41:49:44 | "t6" | dataflow.cs:49:18:49:45 | call to method TaintIndirect | +| dataflow.cs:102:30:102:33 | null | dataflow.cs:74:21:74:52 | ... ?? ... | | dataflow.cs:102:30:102:33 | null | dataflow.cs:89:24:89:51 | ... ? ... : ... | | dataflow.cs:102:30:102:33 | null | dataflow.cs:108:20:108:33 | call to method IndirectNull | +| dataflow.cs:109:23:109:26 | null | dataflow.cs:74:21:74:52 | ... ?? ... | | dataflow.cs:109:23:109:26 | null | dataflow.cs:89:24:89:51 | ... ? ... : ... | diff --git a/csharp/ql/test/library-tests/commons/Disposal/Class1.cs_ b/csharp/ql/test/library-tests/commons/Disposal/Class1.cs_ new file mode 100644 index 00000000000..ed948c053d0 --- /dev/null +++ b/csharp/ql/test/library-tests/commons/Disposal/Class1.cs_ @@ -0,0 +1,42 @@ +๏ปฟusing System; + +namespace DisposalTests +{ + public class MyType : IDisposable + { + public void Dispose() + { + } + } + + public class Class1 : IDisposable + { + public void DisposesParameter(IDisposable p1, IDisposable p2) + { + p1.Dispose(); + } + + public void CapturesDisposable(MyType p1, MyType p2) + { + field1 = p1; + field2 = p2; + } + + public void DisposesSelf() + { + Dispose(); + } + + MyType field1, field2; + + public void Dispose() + { + field1.Dispose(); + } + + public static void Dispose(IDisposable d) + { + d.Dispose(); + } + } +} diff --git a/csharp/ql/test/library-tests/commons/Disposal/Disposal.cs b/csharp/ql/test/library-tests/commons/Disposal/Disposal.cs index 08fcbfd1e20..8082bc50f09 100644 --- a/csharp/ql/test/library-tests/commons/Disposal/Disposal.cs +++ b/csharp/ql/test/library-tests/commons/Disposal/Disposal.cs @@ -21,6 +21,6 @@ class Disposal : IDisposable field1 = p1; if(p2 is IDisposable d) d.Dispose(); - Console.SetOut(fs); + DisposalTests.Class1.Dispose(fs); } } diff --git a/csharp/ql/test/library-tests/commons/Disposal/DisposalTests.dll b/csharp/ql/test/library-tests/commons/Disposal/DisposalTests.dll new file mode 100644 index 00000000000..f731c5af9e1 Binary files /dev/null and b/csharp/ql/test/library-tests/commons/Disposal/DisposalTests.dll differ diff --git a/csharp/ql/test/library-tests/commons/Disposal/DisposedFields.expected b/csharp/ql/test/library-tests/commons/Disposal/DisposedFields.expected index 4228710ca86..d3d33271d45 100644 --- a/csharp/ql/test/library-tests/commons/Disposal/DisposedFields.expected +++ b/csharp/ql/test/library-tests/commons/Disposal/DisposedFields.expected @@ -1,49 +1 @@ -| System.IO.BufferedStream._stream | -| System.IO.Stream.SyncStream._stream | -| System.IO.SyncTextReader._in | -| System.IO.SyncTextWriter._out | -| System.IO.UnmanagedMemoryStreamWrapper._unmanagedStream | -| System.Net.Http.DecompressionHandler.DecompressedContent._originalContent | -| System.Net.Http.DecompressionHandler._innerHandler | -| System.Net.Http.DelegatingHandler._innerHandler | -| System.Net.Http.DelegatingStream._innerStream | -| System.Net.Http.HttpAuthenticatedConnectionHandler._poolManager | -| System.Net.Http.HttpClient._pendingRequestsCts | -| System.Net.Http.HttpConnection.HttpConnectionResponseContent._stream | -| System.Net.Http.HttpConnection._stream | -| System.Net.Http.HttpConnectionHandler._poolManager | -| System.Net.Http.HttpConnectionPool.CachedConnection._connection | -| System.Net.Http.HttpConnectionPool.ConnectionWaiter._cancellationTokenRegistration | -| System.Net.Http.HttpConnectionPoolManager._cleaningTimer | -| System.Net.Http.HttpContent._bufferedContent | -| System.Net.Http.HttpContentStream._connection | -| System.Net.Http.HttpMessageInvoker._handler | -| System.Net.Http.HttpRequestMessage._content | -| System.Net.Http.HttpResponseMessage._content | -| System.Net.Http.NoWriteNoSeekStreamContent._content | -| System.Net.Http.RedirectHandler._initialInnerHandler | -| System.Net.Http.RedirectHandler._redirectInnerHandler | -| System.Net.Http.SocketsHttpHandler._handler | -| System.Net.Http.StreamContent._content | -| System.Net.NTAuthentication._credentialsHandle | -| System.Net.NTAuthentication._securityContext | -| System.Net.Security.SafeDeleteNegoContext._context | -| System.Net.Security.SafeDeleteNegoContext._targetName | -| System.Security.SecureString._buffer | -| System.Threading.CancellationTokenSource.Linked1CancellationTokenSource._reg1 | -| System.Threading.CancellationTokenSource.Linked2CancellationTokenSource._reg1 | -| System.Threading.CancellationTokenSource.Linked2CancellationTokenSource._reg2 | -| System.Threading.CancellationTokenSource._timer | -| System.Threading.ReaderWriterLockSlim._readEvent | -| System.Threading.ReaderWriterLockSlim._upgradeEvent | -| System.Threading.ReaderWriterLockSlim._waitUpgradeEvent | -| System.Threading.ReaderWriterLockSlim._writeEvent | -| System.Xml.Serialization.XmlCountingReader._innerReader | -| System.Xml.XmlAsyncCheckReader._coreReader | -| System.Xml.XmlAsyncCheckWriter._coreWriter | -| System.Xml.XmlAutoDetectWriter._strm | -| System.Xml.XmlAutoDetectWriter._textWriter | -| System.Xml.XmlAutoDetectWriter._wrapped | -| System.Xml.XmlSqlBinaryReader._inStrm | -| System.Xml.XmlTextWriter._textWriter | -| System.Xml.Xsl.Runtime.XmlRawWriterWrapper._wrapped | +| DisposalTests.Class1.field1 | diff --git a/csharp/ql/test/library-tests/commons/Disposal/DisposedFields.ql b/csharp/ql/test/library-tests/commons/Disposal/DisposedFields.ql index c9cf46facf4..6df087748d4 100644 --- a/csharp/ql/test/library-tests/commons/Disposal/DisposedFields.ql +++ b/csharp/ql/test/library-tests/commons/Disposal/DisposedFields.ql @@ -1,10 +1,8 @@ import cil import semmle.code.csharp.commons.Disposal -import Whitelist from CIL::Field field where mayBeDisposed(field) and - field.getName().charAt(0) = "_" and // Filter the results a little - not whitelistedType(field.getDeclaringType()) + field.getDeclaringType().getQualifiedName() = "DisposalTests.Class1" select field.getQualifiedName() diff --git a/csharp/ql/test/library-tests/commons/Disposal/DisposedParameter.expected b/csharp/ql/test/library-tests/commons/Disposal/DisposedParameter.expected index 917ea971094..33bd2568eca 100644 --- a/csharp/ql/test/library-tests/commons/Disposal/DisposedParameter.expected +++ b/csharp/ql/test/library-tests/commons/Disposal/DisposedParameter.expected @@ -1,348 +1,6 @@ -| BufferedStream(Stream) | 0 | -| BufferedStream(Stream, int) | 0 | -| CachedConnection(HttpConnection) | 0 | -| ChunkedEncodingReadStream(HttpConnection) | 0 | -| ChunkedEncodingWriteStream(HttpConnection) | 0 | -| ConnectionCloseReadStream(HttpConnection) | 0 | -| ContentLengthReadStream(HttpConnection, ulong) | 0 | -| ContentLengthWriteStream(HttpConnection) | 0 | -| CopyAsync(Stream, Stream, int, bool, CancellationToken) | 0 | -| CopyToWriter(XmlWriter) | 0 | -| Create(Stream) | 0 | -| Create(Stream, XmlReaderSettings) | 0 | -| Create(Stream, XmlReaderSettings, XmlParserContext) | 0 | -| Create(Stream, XmlReaderSettings, string) | 0 | -| Create(Stream, XmlWriterSettings) | 0 | -| Create(TextReader) | 0 | -| Create(TextReader, XmlReaderSettings) | 0 | -| Create(TextReader, XmlReaderSettings, XmlParserContext) | 0 | -| Create(TextReader, XmlReaderSettings, string) | 0 | -| Create(TextWriter) | 0 | -| Create(TextWriter, XmlWriterSettings) | 0 | -| Create(XmlWriter) | 0 | -| Create(XmlWriter, XmlWriterSettings) | 0 | -| CreateAsyncCheckWrapper(XmlReader) | 0 | -| CreateReader(Stream, string) | 0 | -| DecompressedContent(HttpContent) | 0 | -| DeflateDecompressedContent(HttpContent) | 0 | -| DelegatingHandler(HttpMessageHandler) | 0 | -| DelegatingStream(Stream) | 0 | -| Deserialize(Stream) | 0 | -| Deserialize(TextReader) | 0 | -| Deserialize(XmlReader) | 0 | -| Deserialize(XmlReader, XmlDeserializationEvents) | 0 | -| Deserialize(XmlReader, string) | 0 | -| Deserialize(XmlReader, string, XmlDeserializationEvents) | 0 | -| DiagnosticsHandler(HttpMessageHandler) | 0 | -| Disposal(IDisposable, object, TextWriter) | 0 | -| Disposal(IDisposable, object, TextWriter) | 1 | -| Disposal(IDisposable, object, TextWriter) | 2 | -| DrainResponseAsync(HttpResponseMessage) | 0 | -| EventsToWriter(XmlWriter) | 0 | -| Execute(object, XmlResolver, XsltArgumentList, XmlWriter) | 3 | -| GZipDecompressedContent(HttpContent) | 0 | -| GetSynchronizedTextReader(TextReader) | 0 | -| HtmlEncodedRawTextWriter(Stream, XmlWriterSettings) | 0 | -| HtmlEncodedRawTextWriter(TextWriter, XmlWriterSettings) | 0 | -| HtmlEncodedRawTextWriterIndent(Stream, XmlWriterSettings) | 0 | -| HtmlEncodedRawTextWriterIndent(TextWriter, XmlWriterSettings) | 0 | -| HtmlUtf8RawTextWriter(Stream, XmlWriterSettings) | 0 | -| HtmlUtf8RawTextWriterIndent(Stream, XmlWriterSettings) | 0 | -| HttpAuthenticatedConnectionHandler(HttpConnectionPoolManager) | 0 | -| HttpClient(HttpMessageHandler) | 0 | -| HttpClient(HttpMessageHandler, bool) | 0 | -| HttpConnectionHandler(HttpConnectionPoolManager) | 0 | -| HttpContentDuplexStream(HttpConnection) | 0 | -| HttpContentReadStream(HttpConnection) | 0 | -| HttpContentStream(HttpConnection) | 0 | -| HttpContentWriteStream(HttpConnection) | 0 | -| HttpMessageInvoker(HttpMessageHandler) | 0 | -| HttpMessageInvoker(HttpMessageHandler, bool) | 0 | -| Load(Stream) | 0 | -| Load(TextReader) | 0 | -| MessageProcessingHandler(HttpMessageHandler) | 0 | -| PatchAsync(string, HttpContent) | 1 | -| PatchAsync(string, HttpContent, CancellationToken) | 1 | -| PostAsync(string, HttpContent) | 1 | -| PostAsync(string, HttpContent, CancellationToken) | 1 | -| PutAsync(string, HttpContent) | 1 | -| PutAsync(string, HttpContent, CancellationToken) | 1 | -| RawConnectionStream(HttpConnection) | 0 | -| Read(Stream, ValidationEventHandler) | 0 | -| Read(TextReader, ValidationEventHandler) | 0 | -| ReadOnlyStream(Stream) | 0 | -| RedirectHandler(int, HttpMessageHandler, HttpMessageHandler) | 1 | -| RedirectHandler(int, HttpMessageHandler, HttpMessageHandler) | 2 | -| ReflectionXmlSerializationReader(XmlMapping, XmlReader, XmlDeserializationEvents, string) | 1 | -| ReturnConnection(HttpConnection) | 0 | -| Save(TextWriter) | 0 | -| SendWithNtProxyAuthAsync(HttpConnection, HttpRequestMessage, CancellationToken) | 0 | -| Serialize(TextWriter, object) | 0 | -| Serialize(TextWriter, object, XmlSerializerNamespaces) | 0 | -| SetError(TextWriter) | 0 | -| SetGssContext(SafeGssContextHandle) | 0 | -| SetIn(TextReader) | 0 | -| SetOut(TextWriter) | 0 | -| SetStream(HttpContentStream) | 0 | -| StreamContent(Stream) | 0 | -| StreamContent(Stream, int) | 0 | -| Synchronized(Stream) | 0 | -| System.IO.Stream System.IO.Stream.Synchronized(System.IO.Stream) | 0 | -| System.IO.SyncTextReader System.IO.SyncTextReader.GetSynchronizedTextReader(System.IO.TextReader) | 0 | -| System.IO.SyncTextWriter System.IO.SyncTextWriter.GetSynchronizedTextWriter(System.IO.TextWriter) | 0 | -| System.Int32 System.Net.Http.HttpConnection.ChunkedEncodingReadStream.ReadChunksFromConnectionBuffer(System.Span,System.Threading.CancellationTokenRegistration) | 1 | -| System.Object System.Xml.Serialization.TempAssembly.InvokeReader(System.Xml.Serialization.XmlMapping,System.Xml.XmlReader,System.Xml.Serialization.XmlDeserializationEvents,System.String) | 1 | -| System.Object System.Xml.Serialization.XmlSerializer.Deserialize(System.IO.Stream) | 0 | -| System.Object System.Xml.Serialization.XmlSerializer.Deserialize(System.IO.TextReader) | 0 | -| System.Object System.Xml.Serialization.XmlSerializer.Deserialize(System.Xml.XmlReader) | 0 | -| System.Object System.Xml.Serialization.XmlSerializer.Deserialize(System.Xml.XmlReader,System.String) | 0 | -| System.Object System.Xml.Serialization.XmlSerializer.Deserialize(System.Xml.XmlReader,System.String,System.Xml.Serialization.XmlDeserializationEvents) | 0 | -| System.Object System.Xml.Serialization.XmlSerializer.Deserialize(System.Xml.XmlReader,System.Xml.Serialization.XmlDeserializationEvents) | 0 | -| System.Object System.Xml.Serialization.XmlSerializer.DeserializePrimitive(System.Xml.XmlReader,System.Xml.Serialization.XmlDeserializationEvents) | 0 | -| System.Object System.Xml.Serialization.XmlSerializer.DeserializeUsingReflection(System.Xml.XmlReader,System.String,System.Xml.Serialization.XmlDeserializationEvents) | 0 | -| System.ReadOnlyMemory System.Net.Http.HttpConnection.ChunkedEncodingReadStream.ReadChunkFromConnectionBuffer(System.Int32,System.Threading.CancellationTokenRegistration) | 1 | -| System.Threading.Tasks.Task System.Net.Http.HttpConnection.DrainResponseAsync(System.Net.Http.HttpResponseMessage) | 0 | -| System.Threading.Tasks.Task System.Net.Http.HttpConnection.SendRequestContentWithExpect100ContinueAsync(System.Net.Http.HttpRequestMessage,System.Threading.Tasks.Task,System.Net.Http.HttpConnection.HttpContentWriteStream,System.Threading.Timer,System.Threading.CancellationToken) | 3 | -| System.Threading.Tasks.Task System.Net.Http.HttpContent.LoadIntoBufferAsyncCore(System.Threading.Tasks.Task,System.IO.MemoryStream) | 1 | -| System.Threading.Tasks.Task System.Net.Http.StreamToStreamCopy.CopyAsync(System.IO.Stream,System.IO.Stream,System.Int32,System.Boolean,System.Threading.CancellationToken) | 0 | -| System.Threading.Tasks.Task System.Net.Http.StreamToStreamCopy.DisposeSourceWhenCompleteAsync(System.Threading.Tasks.Task,System.IO.Stream) | 1 | -| System.Threading.Tasks.Task System.Xml.XmlTextReaderImpl.InitStreamInputAsync(System.Uri,System.IO.Stream,System.Text.Encoding) | 1 | -| System.Threading.Tasks.Task System.Xml.XmlTextReaderImpl.InitStreamInputAsync(System.Uri,System.String,System.IO.Stream,System.Byte[],System.Int32,System.Text.Encoding) | 2 | -| System.Threading.Tasks.Task System.Xml.XmlTextReaderImpl.InitTextReaderInputAsync(System.String,System.IO.TextReader) | 1 | -| System.Threading.Tasks.Task System.Xml.XmlTextReaderImpl.InitTextReaderInputAsync(System.String,System.Uri,System.IO.TextReader) | 2 | -| System.Threading.Tasks.Task System.Net.Http.AuthenticationHelper.InnerSendAsync(System.Net.Http.HttpRequestMessage,System.Boolean,System.Net.Http.HttpConnectionPool,System.Net.Http.HttpConnection,System.Threading.CancellationToken) | 3 | -| System.Threading.Tasks.Task System.Net.Http.AuthenticationHelper.SendWithNtAuthAsync(System.Net.Http.HttpRequestMessage,System.Uri,System.Net.ICredentials,System.Boolean,System.Net.Http.HttpConnection,System.Net.Http.HttpConnectionPool,System.Threading.CancellationToken) | 4 | -| System.Threading.Tasks.Task System.Net.Http.AuthenticationHelper.SendWithNtConnectionAuthAsync(System.Net.Http.HttpRequestMessage,System.Net.ICredentials,System.Net.Http.HttpConnection,System.Net.Http.HttpConnectionPool,System.Threading.CancellationToken) | 2 | -| System.Threading.Tasks.Task System.Net.Http.AuthenticationHelper.SendWithNtProxyAuthAsync(System.Net.Http.HttpRequestMessage,System.Uri,System.Net.ICredentials,System.Net.Http.HttpConnection,System.Net.Http.HttpConnectionPool,System.Threading.CancellationToken) | 3 | -| System.Threading.Tasks.Task System.Net.Http.HttpClient.FinishSendAsyncBuffered(System.Threading.Tasks.Task,System.Net.Http.HttpRequestMessage,System.Threading.CancellationTokenSource,System.Boolean) | 2 | -| System.Threading.Tasks.Task System.Net.Http.HttpClient.FinishSendAsyncUnbuffered(System.Threading.Tasks.Task,System.Net.Http.HttpRequestMessage,System.Threading.CancellationTokenSource,System.Boolean) | 2 | -| System.Threading.Tasks.Task System.Net.Http.HttpClient.PatchAsync(System.String,System.Net.Http.HttpContent) | 1 | -| System.Threading.Tasks.Task System.Net.Http.HttpClient.PatchAsync(System.String,System.Net.Http.HttpContent,System.Threading.CancellationToken) | 1 | -| System.Threading.Tasks.Task System.Net.Http.HttpClient.PatchAsync(System.Uri,System.Net.Http.HttpContent) | 1 | -| System.Threading.Tasks.Task System.Net.Http.HttpClient.PatchAsync(System.Uri,System.Net.Http.HttpContent,System.Threading.CancellationToken) | 1 | -| System.Threading.Tasks.Task System.Net.Http.HttpClient.PostAsync(System.String,System.Net.Http.HttpContent) | 1 | -| System.Threading.Tasks.Task System.Net.Http.HttpClient.PostAsync(System.String,System.Net.Http.HttpContent,System.Threading.CancellationToken) | 1 | -| System.Threading.Tasks.Task System.Net.Http.HttpClient.PostAsync(System.Uri,System.Net.Http.HttpContent) | 1 | -| System.Threading.Tasks.Task System.Net.Http.HttpClient.PostAsync(System.Uri,System.Net.Http.HttpContent,System.Threading.CancellationToken) | 1 | -| System.Threading.Tasks.Task System.Net.Http.HttpClient.PutAsync(System.String,System.Net.Http.HttpContent) | 1 | -| System.Threading.Tasks.Task System.Net.Http.HttpClient.PutAsync(System.String,System.Net.Http.HttpContent,System.Threading.CancellationToken) | 1 | -| System.Threading.Tasks.Task System.Net.Http.HttpClient.PutAsync(System.Uri,System.Net.Http.HttpContent) | 1 | -| System.Threading.Tasks.Task System.Net.Http.HttpClient.PutAsync(System.Uri,System.Net.Http.HttpContent,System.Threading.CancellationToken) | 1 | -| System.Threading.Tasks.Task System.Net.Http.HttpConnectionPool.SendWithNtConnectionAuthAsync(System.Net.Http.HttpConnection,System.Net.Http.HttpRequestMessage,System.Boolean,System.Threading.CancellationToken) | 0 | -| System.Threading.Tasks.Task System.Net.Http.HttpConnectionPool.SendWithNtProxyAuthAsync(System.Net.Http.HttpConnection,System.Net.Http.HttpRequestMessage,System.Threading.CancellationToken) | 0 | -| System.Void System.Console.SetError(System.IO.TextWriter) | 0 | -| System.Void System.Console.SetIn(System.IO.TextReader) | 0 | -| System.Void System.Console.SetOut(System.IO.TextWriter) | 0 | -| System.Void System.IO.BufferedStream..ctor(System.IO.Stream) | 0 | -| System.Void System.IO.BufferedStream..ctor(System.IO.Stream,System.Int32) | 0 | -| System.Void System.IO.Stream.SyncStream..ctor(System.IO.Stream) | 0 | -| System.Void System.IO.SyncTextReader..ctor(System.IO.TextReader) | 0 | -| System.Void System.IO.SyncTextWriter..ctor(System.IO.TextWriter) | 0 | -| System.Void System.IO.UnmanagedMemoryStreamWrapper..ctor(System.IO.UnmanagedMemoryStream) | 0 | -| System.Void System.Net.Http.DecompressionHandler..ctor(System.Net.DecompressionMethods,System.Net.Http.HttpMessageHandler) | 1 | -| System.Void System.Net.Http.DecompressionHandler.DecompressedContent..ctor(System.Net.Http.HttpContent) | 0 | -| System.Void System.Net.Http.DecompressionHandler.DeflateDecompressedContent..ctor(System.Net.Http.HttpContent) | 0 | -| System.Void System.Net.Http.DecompressionHandler.GZipDecompressedContent..ctor(System.Net.Http.HttpContent) | 0 | -| System.Void System.Net.Http.DelegatingHandler..ctor(System.Net.Http.HttpMessageHandler) | 0 | -| System.Void System.Net.Http.DelegatingHandler.set_InnerHandler(System.Net.Http.HttpMessageHandler) | 0 | -| System.Void System.Net.Http.DelegatingStream..ctor(System.IO.Stream) | 0 | -| System.Void System.Net.Http.DiagnosticsHandler..ctor(System.Net.Http.HttpMessageHandler) | 0 | -| System.Void System.Net.Http.HttpAuthenticatedConnectionHandler..ctor(System.Net.Http.HttpConnectionPoolManager) | 0 | -| System.Void System.Net.Http.HttpClient..ctor(System.Net.Http.HttpMessageHandler) | 0 | -| System.Void System.Net.Http.HttpClient..ctor(System.Net.Http.HttpMessageHandler,System.Boolean) | 0 | -| System.Void System.Net.Http.HttpClient.HandleFinishSendAsyncCleanup(System.Threading.CancellationTokenSource,System.Boolean) | 0 | -| System.Void System.Net.Http.HttpConnection..ctor(System.Net.Http.HttpConnectionPool,System.Net.Sockets.Socket,System.IO.Stream,System.Net.TransportContext) | 2 | -| System.Void System.Net.Http.HttpConnection.ChunkedEncodingReadStream..ctor(System.Net.Http.HttpConnection) | 0 | -| System.Void System.Net.Http.HttpConnection.ChunkedEncodingWriteStream..ctor(System.Net.Http.HttpConnection) | 0 | -| System.Void System.Net.Http.HttpConnection.ConnectionCloseReadStream..ctor(System.Net.Http.HttpConnection) | 0 | -| System.Void System.Net.Http.HttpConnection.ContentLengthReadStream..ctor(System.Net.Http.HttpConnection,System.UInt64) | 0 | -| System.Void System.Net.Http.HttpConnection.ContentLengthWriteStream..ctor(System.Net.Http.HttpConnection) | 0 | -| System.Void System.Net.Http.HttpConnection.HttpConnectionResponseContent.SetStream(System.Net.Http.HttpContentStream) | 0 | -| System.Void System.Net.Http.HttpConnection.HttpContentReadStream..ctor(System.Net.Http.HttpConnection) | 0 | -| System.Void System.Net.Http.HttpConnection.HttpContentWriteStream..ctor(System.Net.Http.HttpConnection) | 0 | -| System.Void System.Net.Http.HttpConnection.RawConnectionStream..ctor(System.Net.Http.HttpConnection) | 0 | -| System.Void System.Net.Http.HttpConnectionHandler..ctor(System.Net.Http.HttpConnectionPoolManager) | 0 | -| System.Void System.Net.Http.HttpConnectionPool.<>c.b__55_0(System.Net.Http.HttpConnection) | 0 | -| System.Void System.Net.Http.HttpConnectionPool.CachedConnection..ctor(System.Net.Http.HttpConnection) | 0 | -| System.Void System.Net.Http.HttpConnectionPool.ReturnConnection(System.Net.Http.HttpConnection) | 0 | -| System.Void System.Net.Http.HttpConnectionWithFinalizer..ctor(System.Net.Http.HttpConnectionPool,System.Net.Sockets.Socket,System.IO.Stream,System.Net.TransportContext) | 2 | -| System.Void System.Net.Http.HttpContentDuplexStream..ctor(System.Net.Http.HttpConnection) | 0 | -| System.Void System.Net.Http.HttpContentStream..ctor(System.Net.Http.HttpConnection) | 0 | -| System.Void System.Net.Http.HttpMessageInvoker..ctor(System.Net.Http.HttpMessageHandler) | 0 | -| System.Void System.Net.Http.HttpMessageInvoker..ctor(System.Net.Http.HttpMessageHandler,System.Boolean) | 0 | -| System.Void System.Net.Http.HttpRequestMessage.set_Content(System.Net.Http.HttpContent) | 0 | -| System.Void System.Net.Http.HttpResponseMessage.set_Content(System.Net.Http.HttpContent) | 0 | -| System.Void System.Net.Http.MessageProcessingHandler..ctor(System.Net.Http.HttpMessageHandler) | 0 | -| System.Void System.Net.Http.NoWriteNoSeekStreamContent..ctor(System.IO.Stream) | 0 | -| System.Void System.Net.Http.RedirectHandler..ctor(System.Int32,System.Net.Http.HttpMessageHandler,System.Net.Http.HttpMessageHandler) | 1 | -| System.Void System.Net.Http.RedirectHandler..ctor(System.Int32,System.Net.Http.HttpMessageHandler,System.Net.Http.HttpMessageHandler) | 2 | -| System.Void System.Net.Http.StreamContent..ctor(System.IO.Stream) | 0 | -| System.Void System.Net.Http.StreamContent..ctor(System.IO.Stream,System.Int32) | 0 | -| System.Void System.Net.Http.StreamContent.InitializeContent(System.IO.Stream,System.Int32) | 0 | -| System.Void System.Net.Http.StreamContent.ReadOnlyStream..ctor(System.IO.Stream) | 0 | -| System.Void System.Net.Http.StreamToStreamCopy.DisposeSource(System.IO.Stream) | 0 | -| System.Void System.Net.Security.SafeDeleteNegoContext.SetGssContext(Microsoft.Win32.SafeHandles.SafeGssContextHandle) | 0 | -| System.Void System.TypeNameParser..ctor(System.SafeTypeNameParserHandle) | 0 | -| System.Void System.Xml.HtmlEncodedRawTextWriter..ctor(System.IO.Stream,System.Xml.XmlWriterSettings) | 0 | -| System.Void System.Xml.HtmlEncodedRawTextWriter..ctor(System.IO.TextWriter,System.Xml.XmlWriterSettings) | 0 | -| System.Void System.Xml.HtmlEncodedRawTextWriterIndent..ctor(System.IO.Stream,System.Xml.XmlWriterSettings) | 0 | -| System.Void System.Xml.HtmlEncodedRawTextWriterIndent..ctor(System.IO.TextWriter,System.Xml.XmlWriterSettings) | 0 | -| System.Void System.Xml.HtmlUtf8RawTextWriter..ctor(System.IO.Stream,System.Xml.XmlWriterSettings) | 0 | -| System.Void System.Xml.HtmlUtf8RawTextWriterIndent..ctor(System.IO.Stream,System.Xml.XmlWriterSettings) | 0 | -| System.Void System.Xml.Schema.XmlSchema.Write(System.IO.TextWriter) | 0 | -| System.Void System.Xml.Schema.XmlSchema.Write(System.IO.TextWriter,System.Xml.XmlNamespaceManager) | 0 | -| System.Void System.Xml.Serialization.ReflectionXmlSerializationReader..ctor(System.Xml.Serialization.XmlMapping,System.Xml.XmlReader,System.Xml.Serialization.XmlDeserializationEvents,System.String) | 1 | -| System.Void System.Xml.Serialization.XmlCountingReader..ctor(System.Xml.XmlReader) | 0 | -| System.Void System.Xml.Serialization.XmlSerializationReader.Init(System.Xml.XmlReader,System.Xml.Serialization.XmlDeserializationEvents,System.String,System.Xml.Serialization.TempAssembly) | 0 | -| System.Void System.Xml.Serialization.XmlSerializer.Serialize(System.IO.TextWriter,System.Object) | 0 | -| System.Void System.Xml.Serialization.XmlSerializer.Serialize(System.IO.TextWriter,System.Object,System.Xml.Serialization.XmlSerializerNamespaces) | 0 | -| System.Void System.Xml.TextEncodedRawTextWriter..ctor(System.IO.Stream,System.Xml.XmlWriterSettings) | 0 | -| System.Void System.Xml.TextEncodedRawTextWriter..ctor(System.IO.TextWriter,System.Xml.XmlWriterSettings) | 0 | -| System.Void System.Xml.TextUtf8RawTextWriter..ctor(System.IO.Stream,System.Xml.XmlWriterSettings) | 0 | -| System.Void System.Xml.XPath.XPathDocument..ctor(System.IO.Stream) | 0 | -| System.Void System.Xml.XPath.XPathDocument..ctor(System.IO.TextReader) | 0 | -| System.Void System.Xml.XmlAsyncCheckReader..ctor(System.Xml.XmlReader) | 0 | -| System.Void System.Xml.XmlAsyncCheckReaderWithLineInfo..ctor(System.Xml.XmlReader) | 0 | -| System.Void System.Xml.XmlAsyncCheckReaderWithLineInfoNS..ctor(System.Xml.XmlReader) | 0 | -| System.Void System.Xml.XmlAsyncCheckReaderWithLineInfoNSSchema..ctor(System.Xml.XmlReader) | 0 | -| System.Void System.Xml.XmlAsyncCheckReaderWithNS..ctor(System.Xml.XmlReader) | 0 | -| System.Void System.Xml.XmlAsyncCheckWriter..ctor(System.Xml.XmlWriter) | 0 | -| System.Void System.Xml.XmlAutoDetectWriter..ctor(System.IO.Stream,System.Xml.XmlWriterSettings) | 0 | -| System.Void System.Xml.XmlAutoDetectWriter..ctor(System.IO.TextWriter,System.Xml.XmlWriterSettings) | 0 | -| System.Void System.Xml.XmlCharCheckingWriter..ctor(System.Xml.XmlWriter,System.Boolean,System.Boolean,System.Boolean,System.String) | 0 | -| System.Void System.Xml.XmlDOMTextWriter..ctor(System.IO.TextWriter) | 0 | -| System.Void System.Xml.XmlDocument.Load(System.IO.Stream) | 0 | -| System.Void System.Xml.XmlDocument.Load(System.IO.TextReader) | 0 | -| System.Void System.Xml.XmlDocument.Save(System.IO.TextWriter) | 0 | -| System.Void System.Xml.XmlEncodedRawTextWriter..ctor(System.IO.Stream,System.Xml.XmlWriterSettings) | 0 | -| System.Void System.Xml.XmlEncodedRawTextWriter..ctor(System.IO.TextWriter,System.Xml.XmlWriterSettings) | 0 | -| System.Void System.Xml.XmlEncodedRawTextWriterIndent..ctor(System.IO.Stream,System.Xml.XmlWriterSettings) | 0 | -| System.Void System.Xml.XmlEncodedRawTextWriterIndent..ctor(System.IO.TextWriter,System.Xml.XmlWriterSettings) | 0 | -| System.Void System.Xml.XmlEventCache.EventsToWriter(System.Xml.XmlWriter) | 0 | -| System.Void System.Xml.XmlSqlBinaryReader..ctor(System.IO.Stream,System.Byte[],System.Int32,System.String,System.Boolean,System.Xml.XmlReaderSettings) | 0 | -| System.Void System.Xml.XmlTextReader..ctor(System.IO.Stream) | 0 | -| System.Void System.Xml.XmlTextReader..ctor(System.IO.Stream,System.Xml.XmlNameTable) | 0 | -| System.Void System.Xml.XmlTextReader..ctor(System.IO.Stream,System.Xml.XmlNodeType,System.Xml.XmlParserContext) | 0 | -| System.Void System.Xml.XmlTextReader..ctor(System.IO.TextReader) | 0 | -| System.Void System.Xml.XmlTextReader..ctor(System.IO.TextReader,System.Xml.XmlNameTable) | 0 | -| System.Void System.Xml.XmlTextReader..ctor(System.String,System.IO.Stream) | 1 | -| System.Void System.Xml.XmlTextReader..ctor(System.String,System.IO.Stream,System.Xml.XmlNameTable) | 1 | -| System.Void System.Xml.XmlTextReader..ctor(System.String,System.IO.TextReader) | 1 | -| System.Void System.Xml.XmlTextReader..ctor(System.String,System.IO.TextReader,System.Xml.XmlNameTable) | 1 | -| System.Void System.Xml.XmlTextReaderImpl..ctor(System.IO.Stream) | 0 | -| System.Void System.Xml.XmlTextReaderImpl..ctor(System.IO.Stream,System.Byte[],System.Int32,System.Xml.XmlReaderSettings,System.Uri,System.String,System.Xml.XmlParserContext,System.Boolean) | 0 | -| System.Void System.Xml.XmlTextReaderImpl..ctor(System.IO.Stream,System.Xml.XmlNameTable) | 0 | -| System.Void System.Xml.XmlTextReaderImpl..ctor(System.IO.Stream,System.Xml.XmlNodeType,System.Xml.XmlParserContext) | 0 | -| System.Void System.Xml.XmlTextReaderImpl..ctor(System.IO.TextReader) | 0 | -| System.Void System.Xml.XmlTextReaderImpl..ctor(System.IO.TextReader,System.Xml.XmlNameTable) | 0 | -| System.Void System.Xml.XmlTextReaderImpl..ctor(System.IO.TextReader,System.Xml.XmlReaderSettings,System.String,System.Xml.XmlParserContext) | 0 | -| System.Void System.Xml.XmlTextReaderImpl..ctor(System.String,System.IO.Stream) | 1 | -| System.Void System.Xml.XmlTextReaderImpl..ctor(System.String,System.IO.Stream,System.Xml.XmlNameTable) | 1 | -| System.Void System.Xml.XmlTextReaderImpl..ctor(System.String,System.IO.TextReader) | 1 | -| System.Void System.Xml.XmlTextReaderImpl..ctor(System.String,System.IO.TextReader,System.Xml.XmlNameTable) | 1 | -| System.Void System.Xml.XmlTextReaderImpl.InitStreamInput(System.IO.Stream,System.Text.Encoding) | 0 | -| System.Void System.Xml.XmlTextReaderImpl.InitStreamInput(System.String,System.IO.Stream,System.Text.Encoding) | 1 | -| System.Void System.Xml.XmlTextReaderImpl.InitStreamInput(System.Uri,System.IO.Stream,System.Text.Encoding) | 1 | -| System.Void System.Xml.XmlTextReaderImpl.InitStreamInput(System.Uri,System.String,System.IO.Stream,System.Byte[],System.Int32,System.Text.Encoding) | 2 | -| System.Void System.Xml.XmlTextReaderImpl.InitStreamInput(System.Uri,System.String,System.IO.Stream,System.Text.Encoding) | 2 | -| System.Void System.Xml.XmlTextReaderImpl.InitTextReaderInput(System.String,System.IO.TextReader) | 1 | -| System.Void System.Xml.XmlTextReaderImpl.InitTextReaderInput(System.String,System.Uri,System.IO.TextReader) | 2 | -| System.Void System.Xml.XmlTextWriter..ctor(System.IO.TextWriter) | 0 | -| System.Void System.Xml.XmlUtf8RawTextWriter..ctor(System.IO.Stream,System.Xml.XmlWriterSettings) | 0 | -| System.Void System.Xml.XmlUtf8RawTextWriterIndent..ctor(System.IO.Stream,System.Xml.XmlWriterSettings) | 0 | -| System.Void System.Xml.XmlValidatingReader..ctor(System.IO.Stream,System.Xml.XmlNodeType,System.Xml.XmlParserContext) | 0 | -| System.Void System.Xml.XmlValidatingReaderImpl..ctor(System.IO.Stream,System.Xml.XmlNodeType,System.Xml.XmlParserContext) | 0 | -| System.Void System.Xml.XmlWrappingWriter..ctor(System.Xml.XmlWriter) | 0 | -| System.Void System.Xml.Xsl.Runtime.RtfTreeNavigator.CopyToWriter(System.Xml.XmlWriter) | 0 | -| System.Void System.Xml.Xsl.Runtime.XmlRawWriterWrapper..ctor(System.Xml.XmlWriter) | 0 | -| System.Void System.Xml.Xsl.XmlILCommand.Execute(System.Object,System.Xml.XmlResolver,System.Xml.Xsl.XsltArgumentList,System.Xml.XmlWriter) | 3 | -| System.Void System.Xml.Xsl.XslCompiledTransform.Transform(System.String,System.Xml.XmlWriter) | 1 | -| System.Void System.Xml.Xsl.XslCompiledTransform.Transform(System.String,System.Xml.Xsl.XsltArgumentList,System.IO.Stream) | 2 | -| System.Void System.Xml.Xsl.XslCompiledTransform.Transform(System.String,System.Xml.Xsl.XsltArgumentList,System.IO.TextWriter) | 2 | -| System.Void System.Xml.Xsl.XslCompiledTransform.Transform(System.String,System.Xml.Xsl.XsltArgumentList,System.Xml.XmlWriter) | 2 | -| System.Void System.Xml.Xsl.XslCompiledTransform.Transform(System.String,System.Xml.Xsl.XsltArgumentList,System.Xml.XmlWriter,System.Xml.XmlResolver) | 2 | -| System.Void System.Xml.Xsl.XslCompiledTransform.Transform(System.Xml.XPath.IXPathNavigable,System.Xml.XmlWriter) | 1 | -| System.Void System.Xml.Xsl.XslCompiledTransform.Transform(System.Xml.XPath.IXPathNavigable,System.Xml.Xsl.XsltArgumentList,System.IO.Stream) | 2 | -| System.Void System.Xml.Xsl.XslCompiledTransform.Transform(System.Xml.XPath.IXPathNavigable,System.Xml.Xsl.XsltArgumentList,System.IO.TextWriter) | 2 | -| System.Void System.Xml.Xsl.XslCompiledTransform.Transform(System.Xml.XPath.IXPathNavigable,System.Xml.Xsl.XsltArgumentList,System.Xml.XmlWriter) | 2 | -| System.Void System.Xml.Xsl.XslCompiledTransform.Transform(System.Xml.XPath.IXPathNavigable,System.Xml.Xsl.XsltArgumentList,System.Xml.XmlWriter,System.Xml.XmlResolver) | 2 | -| System.Void System.Xml.Xsl.XslCompiledTransform.Transform(System.Xml.XmlReader,System.Xml.XmlWriter) | 1 | -| System.Void System.Xml.Xsl.XslCompiledTransform.Transform(System.Xml.XmlReader,System.Xml.Xsl.XsltArgumentList,System.IO.Stream) | 2 | -| System.Void System.Xml.Xsl.XslCompiledTransform.Transform(System.Xml.XmlReader,System.Xml.Xsl.XsltArgumentList,System.IO.TextWriter) | 2 | -| System.Void System.Xml.Xsl.XslCompiledTransform.Transform(System.Xml.XmlReader,System.Xml.Xsl.XsltArgumentList,System.Xml.XmlWriter) | 2 | -| System.Void System.Xml.Xsl.XslCompiledTransform.Transform(System.Xml.XmlReader,System.Xml.Xsl.XsltArgumentList,System.Xml.XmlWriter,System.Xml.XmlResolver) | 2 | -| System.Xml.Schema.XmlSchema System.Xml.Schema.XmlSchema.Read(System.IO.Stream,System.Xml.Schema.ValidationEventHandler) | 0 | -| System.Xml.Schema.XmlSchema System.Xml.Schema.XmlSchema.Read(System.IO.TextReader,System.Xml.Schema.ValidationEventHandler) | 0 | -| System.Xml.XmlAsyncCheckReader System.Xml.XmlAsyncCheckReader.CreateAsyncCheckWrapper(System.Xml.XmlReader) | 0 | -| System.Xml.XmlReader System.Xml.XmlReader.Create(System.IO.Stream) | 0 | -| System.Xml.XmlReader System.Xml.XmlReader.Create(System.IO.Stream,System.Xml.XmlReaderSettings) | 0 | -| System.Xml.XmlReader System.Xml.XmlReader.Create(System.IO.Stream,System.Xml.XmlReaderSettings,System.String) | 0 | -| System.Xml.XmlReader System.Xml.XmlReader.Create(System.IO.Stream,System.Xml.XmlReaderSettings,System.Xml.XmlParserContext) | 0 | -| System.Xml.XmlReader System.Xml.XmlReader.Create(System.IO.TextReader) | 0 | -| System.Xml.XmlReader System.Xml.XmlReader.Create(System.IO.TextReader,System.Xml.XmlReaderSettings) | 0 | -| System.Xml.XmlReader System.Xml.XmlReader.Create(System.IO.TextReader,System.Xml.XmlReaderSettings,System.String) | 0 | -| System.Xml.XmlReader System.Xml.XmlReader.Create(System.IO.TextReader,System.Xml.XmlReaderSettings,System.Xml.XmlParserContext) | 0 | -| System.Xml.XmlReader System.Xml.XmlReader.CreateSqlReader(System.IO.Stream,System.Xml.XmlReaderSettings,System.Xml.XmlParserContext) | 0 | -| System.Xml.XmlReader System.Xml.XmlReaderSettings.CreateReader(System.IO.Stream,System.Uri,System.String,System.Xml.XmlParserContext) | 0 | -| System.Xml.XmlReader System.Xml.XmlReaderSettings.CreateReader(System.IO.TextReader,System.String,System.Xml.XmlParserContext) | 0 | -| System.Xml.XmlReader System.Xml.Xsl.QueryReaderSettings.CreateReader(System.IO.Stream,System.String) | 0 | -| System.Xml.XmlWriter System.Xml.XmlReader.CreateWriterForInnerOuterXml(System.IO.StringWriter) | 0 | -| System.Xml.XmlWriter System.Xml.XmlWriter.Create(System.IO.Stream) | 0 | -| System.Xml.XmlWriter System.Xml.XmlWriter.Create(System.IO.Stream,System.Xml.XmlWriterSettings) | 0 | -| System.Xml.XmlWriter System.Xml.XmlWriter.Create(System.IO.TextWriter) | 0 | -| System.Xml.XmlWriter System.Xml.XmlWriter.Create(System.IO.TextWriter,System.Xml.XmlWriterSettings) | 0 | -| System.Xml.XmlWriter System.Xml.XmlWriter.Create(System.Xml.XmlWriter) | 0 | -| System.Xml.XmlWriter System.Xml.XmlWriter.Create(System.Xml.XmlWriter,System.Xml.XmlWriterSettings) | 0 | -| System.Xml.XmlWriter System.Xml.XmlWriterSettings.AddConformanceWrapper(System.Xml.XmlWriter) | 0 | -| System.Xml.XmlWriter System.Xml.XmlWriterSettings.CreateWriter(System.IO.Stream) | 0 | -| System.Xml.XmlWriter System.Xml.XmlWriterSettings.CreateWriter(System.IO.TextWriter) | 0 | -| System.Xml.XmlWriter System.Xml.XmlWriterSettings.CreateWriter(System.Xml.XmlWriter) | 0 | -| TextEncodedRawTextWriter(Stream, XmlWriterSettings) | 0 | -| TextEncodedRawTextWriter(TextWriter, XmlWriterSettings) | 0 | -| TextUtf8RawTextWriter(Stream, XmlWriterSettings) | 0 | -| Transform(IXPathNavigable, XmlWriter) | 1 | -| Transform(IXPathNavigable, XsltArgumentList, Stream) | 2 | -| Transform(IXPathNavigable, XsltArgumentList, TextWriter) | 2 | -| Transform(IXPathNavigable, XsltArgumentList, XmlWriter) | 2 | -| Transform(IXPathNavigable, XsltArgumentList, XmlWriter, XmlResolver) | 2 | -| Transform(XmlReader, XmlWriter) | 1 | -| Transform(XmlReader, XsltArgumentList, Stream) | 2 | -| Transform(XmlReader, XsltArgumentList, TextWriter) | 2 | -| Transform(XmlReader, XsltArgumentList, XmlWriter) | 2 | -| Transform(XmlReader, XsltArgumentList, XmlWriter, XmlResolver) | 2 | -| Transform(string, XmlWriter) | 1 | -| Transform(string, XsltArgumentList, Stream) | 2 | -| Transform(string, XsltArgumentList, TextWriter) | 2 | -| Transform(string, XsltArgumentList, XmlWriter) | 2 | -| Write(TextWriter) | 0 | -| Write(TextWriter, XmlNamespaceManager) | 0 | -| XPathDocument(Stream) | 0 | -| XPathDocument(TextReader) | 0 | -| XmlAsyncCheckReader(XmlReader) | 0 | -| XmlAsyncCheckReaderWithLineInfo(XmlReader) | 0 | -| XmlAsyncCheckReaderWithLineInfoNS(XmlReader) | 0 | -| XmlAsyncCheckReaderWithLineInfoNSSchema(XmlReader) | 0 | -| XmlAsyncCheckReaderWithNS(XmlReader) | 0 | -| XmlAsyncCheckWriter(XmlWriter) | 0 | -| XmlAutoDetectWriter(Stream, XmlWriterSettings) | 0 | -| XmlAutoDetectWriter(TextWriter, XmlWriterSettings) | 0 | -| XmlDOMTextWriter(TextWriter) | 0 | -| XmlEncodedRawTextWriter(Stream, XmlWriterSettings) | 0 | -| XmlEncodedRawTextWriter(TextWriter, XmlWriterSettings) | 0 | -| XmlEncodedRawTextWriterIndent(Stream, XmlWriterSettings) | 0 | -| XmlEncodedRawTextWriterIndent(TextWriter, XmlWriterSettings) | 0 | -| XmlRawWriterWrapper(XmlWriter) | 0 | -| XmlSqlBinaryReader(Stream, byte[], int, string, bool, XmlReaderSettings) | 0 | -| XmlTextReader(Stream) | 0 | -| XmlTextReader(Stream, XmlNameTable) | 0 | -| XmlTextReader(Stream, XmlNodeType, XmlParserContext) | 0 | -| XmlTextReader(TextReader) | 0 | -| XmlTextReader(TextReader, XmlNameTable) | 0 | -| XmlTextReader(string, Stream) | 1 | -| XmlTextReader(string, Stream, XmlNameTable) | 1 | -| XmlTextReader(string, TextReader) | 1 | -| XmlTextReader(string, TextReader, XmlNameTable) | 1 | -| XmlTextWriter(TextWriter) | 0 | -| XmlUtf8RawTextWriter(Stream, XmlWriterSettings) | 0 | -| XmlUtf8RawTextWriterIndent(Stream, XmlWriterSettings) | 0 | -| XmlValidatingReader(Stream, XmlNodeType, XmlParserContext) | 0 | +| CapturesDisposable(MyType, MyType) | 0 | +| Dispose(IDisposable) | 0 | +| DisposesParameter(IDisposable, IDisposable) | 0 | +| System.Void DisposalTests.Class1.CapturesDisposable(DisposalTests.MyType,DisposalTests.MyType) | 0 | +| System.Void DisposalTests.Class1.Dispose(System.IDisposable) | 0 | +| System.Void DisposalTests.Class1.DisposesParameter(System.IDisposable,System.IDisposable) | 0 | diff --git a/csharp/ql/test/library-tests/commons/Disposal/DisposedParameter.ql b/csharp/ql/test/library-tests/commons/Disposal/DisposedParameter.ql index c9df810b220..97ca1ba7f2c 100644 --- a/csharp/ql/test/library-tests/commons/Disposal/DisposedParameter.ql +++ b/csharp/ql/test/library-tests/commons/Disposal/DisposedParameter.ql @@ -1,10 +1,9 @@ import dotnet import semmle.code.csharp.commons.Disposal -import Whitelist from DotNet::Callable c, DotNet::Parameter param, int p where mayBeDisposed(param) and param = c.getParameter(p) and - not whitelistedType(c.getDeclaringType()) + c.getDeclaringType().getQualifiedName() = "DisposalTests.Class1" select c.toStringWithTypes(), p diff --git a/csharp/ql/test/library-tests/commons/Disposal/UndisposedParameter.expected b/csharp/ql/test/library-tests/commons/Disposal/UndisposedParameter.expected index 469de559397..fb648f8e6f8 100644 --- a/csharp/ql/test/library-tests/commons/Disposal/UndisposedParameter.expected +++ b/csharp/ql/test/library-tests/commons/Disposal/UndisposedParameter.expected @@ -1,33 +1,4 @@ -| Execute(TextWriter) | 0 | -| HtmlDecode(string, TextWriter) | 1 | -| HtmlEncode(string, TextWriter) | 1 | -| IndentedTextWriter(TextWriter) | 0 | -| IndentedTextWriter(TextWriter, string) | 0 | -| Synchronized(TextWriter) | 0 | -| System.IO.TextWriter System.Console.EnsureInitialized(System.IO.TextWriter,System.Func) | 0 | -| System.IO.TextWriter System.IO.TextWriter.Synchronized(System.IO.TextWriter) | 0 | -| System.IO.TextWriter System.Threading.Volatile.Read(System.IO.TextWriter) | 0 | -| System.Tuple> System.Tuple.Create>(System.IO.TextWriter,System.ReadOnlyMemory) | 0 | -| System.Void System.CodeDom.Compiler.IndentedTextWriter..ctor(System.IO.TextWriter) | 0 | -| System.Void System.CodeDom.Compiler.IndentedTextWriter..ctor(System.IO.TextWriter,System.String) | 0 | -| System.Void System.IO.TextWriter.SyncTextWriter..ctor(System.IO.TextWriter) | 0 | -| System.Void System.Net.WebUtility.HtmlDecode(System.String,System.IO.TextWriter) | 1 | -| System.Void System.Net.WebUtility.HtmlEncode(System.String,System.IO.TextWriter) | 1 | -| System.Void System.Threading.Volatile.Write(System.IO.TextWriter,System.IO.TextWriter) | 0 | -| System.Void System.Threading.Volatile.Write(System.IO.TextWriter,System.IO.TextWriter) | 1 | -| System.Void System.Tuple..ctor(System.IO.TextWriter,System.Char) | 0 | -| System.Void System.Tuple..ctor(System.IO.TextWriter,System.Char[],System.Int32,System.Int32) | 0 | -| System.Void System.Tuple..ctor(System.IO.TextWriter,System.String) | 0 | -| System.Void System.Xml.Serialization.IndentedWriter..ctor(System.IO.TextWriter,System.Boolean) | 0 | -| System.Void System.Xml.XmlTextEncoder..ctor(System.IO.TextWriter) | 0 | -| System.Void System.Xml.Xsl.XslTransform.Transform(System.Xml.XPath.IXPathNavigable,System.Xml.Xsl.XsltArgumentList,System.IO.TextWriter) | 2 | -| System.Void System.Xml.Xsl.XslTransform.Transform(System.Xml.XPath.IXPathNavigable,System.Xml.Xsl.XsltArgumentList,System.IO.TextWriter,System.Xml.XmlResolver) | 2 | -| System.Void System.Xml.Xsl.XslTransform.Transform(System.Xml.XPath.XPathNavigator,System.Xml.Xsl.XsltArgumentList,System.IO.TextWriter) | 2 | -| System.Void System.Xml.Xsl.XslTransform.Transform(System.Xml.XPath.XPathNavigator,System.Xml.Xsl.XsltArgumentList,System.IO.TextWriter,System.Xml.XmlResolver) | 2 | -| System.Void System.Xml.Xsl.XsltOld.Processor.Execute(System.IO.TextWriter) | 0 | -| System.Void System.Xml.Xsl.XsltOld.TextOnlyOutput..ctor(System.Xml.Xsl.XsltOld.Processor,System.IO.TextWriter) | 1 | -| System.Void System.Xml.Xsl.XsltOld.TextOutput..ctor(System.Xml.Xsl.XsltOld.Processor,System.IO.TextWriter) | 1 | -| Transform(IXPathNavigable, XsltArgumentList, TextWriter) | 2 | -| Transform(IXPathNavigable, XsltArgumentList, TextWriter, XmlResolver) | 2 | -| Transform(XPathNavigator, XsltArgumentList, TextWriter) | 2 | -| Transform(XPathNavigator, XsltArgumentList, TextWriter, XmlResolver) | 2 | +| CapturesDisposable(MyType, MyType) | 1 | +| DisposesParameter(IDisposable, IDisposable) | 1 | +| System.Void DisposalTests.Class1.CapturesDisposable(DisposalTests.MyType,DisposalTests.MyType) | 1 | +| System.Void DisposalTests.Class1.DisposesParameter(System.IDisposable,System.IDisposable) | 1 | diff --git a/csharp/ql/test/library-tests/commons/Disposal/UndisposedParameter.ql b/csharp/ql/test/library-tests/commons/Disposal/UndisposedParameter.ql index ef9933fc4c4..9125fcd3d28 100644 --- a/csharp/ql/test/library-tests/commons/Disposal/UndisposedParameter.ql +++ b/csharp/ql/test/library-tests/commons/Disposal/UndisposedParameter.ql @@ -5,6 +5,6 @@ import cil from DotNet::Callable c, DotNet::Parameter param, int p where not mayBeDisposed(param) and - param.getType().hasName("TextWriter") and - param = c.getParameter(p) + param = c.getParameter(p) and + c.getDeclaringType().getQualifiedName() = "DisposalTests.Class1" select c.toStringWithTypes(), p diff --git a/csharp/ql/test/library-tests/commons/Disposal/Whitelist.qll b/csharp/ql/test/library-tests/commons/Disposal/Whitelist.qll deleted file mode 100644 index 4fd1f8eaf9e..00000000000 --- a/csharp/ql/test/library-tests/commons/Disposal/Whitelist.qll +++ /dev/null @@ -1,18 +0,0 @@ -/** Provides a simple whitelist for ignoring results. */ - -import dotnet - -/** Holds if `type` is platform-specific. */ -predicate whitelistedType(DotNet::Type type) { - exists(string qn | qn = type.getQualifiedName() | - qn = "System.Net.Http.WinHttpHandler" or - qn.matches("Microsoft.Win32%") or - qn = "System.ConsolePal.UnixConsoleStream" or - qn = "System.Globalization.CompareInfo" or - qn = "System.IO.FileSystemEnumerableIterator" or - qn.matches("System.IO.FileStream%") or - qn.matches("System.Net.Http.CurlHandler%") or - qn = "System.Net.Http.HttpClientHandler" or - qn.matches("System.Net.Http.WinHttp%") - ) -} diff --git a/csharp/ql/test/library-tests/dataflow/local/DataFlow.expected b/csharp/ql/test/library-tests/dataflow/local/DataFlow.expected index 63462bbad86..78c0204ed20 100644 --- a/csharp/ql/test/library-tests/dataflow/local/DataFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/local/DataFlow.expected @@ -8,7 +8,9 @@ | LocalDataFlow.cs:412:15:412:20 | access to local variable sink70 | | LocalDataFlow.cs:420:19:420:24 | access to local variable sink71 | | LocalDataFlow.cs:430:23:430:28 | access to local variable sink72 | -| LocalDataFlow.cs:466:15:466:21 | access to parameter tainted | +| LocalDataFlow.cs:445:15:445:20 | access to local variable sink73 | +| LocalDataFlow.cs:446:15:446:20 | access to local variable sink74 | +| LocalDataFlow.cs:472:15:472:21 | access to parameter tainted | | SSA.cs:9:15:9:22 | access to local variable ssaSink0 | | SSA.cs:25:15:25:22 | access to local variable ssaSink1 | | SSA.cs:43:15:43:22 | access to local variable ssaSink2 | diff --git a/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected index d38e1f02215..1b93aded791 100644 --- a/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -545,7 +545,10 @@ | LocalDataFlow.cs:408:15:408:22 | access to local variable nonSink0 | LocalDataFlow.cs:415:31:415:38 | access to local variable nonSink0 | | LocalDataFlow.cs:411:13:411:34 | SSA def(sink70) | LocalDataFlow.cs:412:15:412:20 | access to local variable sink70 | | LocalDataFlow.cs:411:22:411:34 | ... = ... | LocalDataFlow.cs:411:13:411:34 | SSA def(sink70) | +| LocalDataFlow.cs:411:22:411:34 | SSA def(sink0) | LocalDataFlow.cs:443:34:443:38 | access to local variable sink0 | +| LocalDataFlow.cs:411:22:411:34 | SSA def(sink0) | LocalDataFlow.cs:444:22:444:26 | access to local variable sink0 | | LocalDataFlow.cs:411:30:411:34 | access to local variable sink0 | LocalDataFlow.cs:411:22:411:34 | ... = ... | +| LocalDataFlow.cs:411:30:411:34 | access to local variable sink0 | LocalDataFlow.cs:411:22:411:34 | SSA def(sink0) | | LocalDataFlow.cs:412:15:412:20 | [post] access to local variable sink70 | LocalDataFlow.cs:419:13:419:18 | access to local variable sink70 | | LocalDataFlow.cs:412:15:412:20 | access to local variable sink70 | LocalDataFlow.cs:419:13:419:18 | access to local variable sink70 | | LocalDataFlow.cs:415:9:415:38 | SSA def(nonSink0) | LocalDataFlow.cs:416:15:416:22 | access to local variable nonSink0 | @@ -562,12 +565,23 @@ | LocalDataFlow.cs:427:17:427:22 | access to local variable sink70 | LocalDataFlow.cs:429:18:429:30 | SSA def(sink72) | | LocalDataFlow.cs:429:18:429:30 | SSA def(sink72) | LocalDataFlow.cs:430:23:430:28 | access to local variable sink72 | | LocalDataFlow.cs:435:17:435:24 | access to local variable nonSink0 | LocalDataFlow.cs:437:18:437:33 | SSA def(nonSink17) | +| LocalDataFlow.cs:435:17:435:24 | access to local variable nonSink0 | LocalDataFlow.cs:443:22:443:29 | access to local variable nonSink0 | | LocalDataFlow.cs:437:18:437:33 | SSA def(nonSink17) | LocalDataFlow.cs:438:23:438:31 | access to local variable nonSink17 | -| LocalDataFlow.cs:458:28:458:30 | this | LocalDataFlow.cs:458:41:458:45 | this access | -| LocalDataFlow.cs:458:50:458:52 | this | LocalDataFlow.cs:458:56:458:60 | this access | -| LocalDataFlow.cs:458:50:458:52 | value | LocalDataFlow.cs:458:64:458:68 | access to parameter value | -| LocalDataFlow.cs:464:41:464:47 | tainted | LocalDataFlow.cs:466:15:466:21 | access to parameter tainted | -| LocalDataFlow.cs:469:44:469:53 | nonTainted | LocalDataFlow.cs:471:15:471:24 | access to parameter nonTainted | +| LocalDataFlow.cs:443:13:443:38 | SSA def(sink73) | LocalDataFlow.cs:445:15:445:20 | access to local variable sink73 | +| LocalDataFlow.cs:443:22:443:29 | access to local variable nonSink0 | LocalDataFlow.cs:443:22:443:38 | ... ?? ... | +| LocalDataFlow.cs:443:22:443:29 | access to local variable nonSink0 | LocalDataFlow.cs:444:31:444:38 | access to local variable nonSink0 | +| LocalDataFlow.cs:443:22:443:38 | ... ?? ... | LocalDataFlow.cs:443:13:443:38 | SSA def(sink73) | +| LocalDataFlow.cs:443:34:443:38 | access to local variable sink0 | LocalDataFlow.cs:443:22:443:38 | ... ?? ... | +| LocalDataFlow.cs:443:34:443:38 | access to local variable sink0 | LocalDataFlow.cs:444:22:444:26 | access to local variable sink0 | +| LocalDataFlow.cs:444:13:444:38 | SSA def(sink74) | LocalDataFlow.cs:446:15:446:20 | access to local variable sink74 | +| LocalDataFlow.cs:444:22:444:26 | access to local variable sink0 | LocalDataFlow.cs:444:22:444:38 | ... ?? ... | +| LocalDataFlow.cs:444:22:444:38 | ... ?? ... | LocalDataFlow.cs:444:13:444:38 | SSA def(sink74) | +| LocalDataFlow.cs:444:31:444:38 | access to local variable nonSink0 | LocalDataFlow.cs:444:22:444:38 | ... ?? ... | +| LocalDataFlow.cs:464:28:464:30 | this | LocalDataFlow.cs:464:41:464:45 | this access | +| LocalDataFlow.cs:464:50:464:52 | this | LocalDataFlow.cs:464:56:464:60 | this access | +| LocalDataFlow.cs:464:50:464:52 | value | LocalDataFlow.cs:464:64:464:68 | access to parameter value | +| LocalDataFlow.cs:470:41:470:47 | tainted | LocalDataFlow.cs:472:15:472:21 | access to parameter tainted | +| LocalDataFlow.cs:475:44:475:53 | nonTainted | LocalDataFlow.cs:477:15:477:24 | access to parameter nonTainted | | SSA.cs:5:17:5:17 | SSA entry def(this.S) | SSA.cs:67:9:67:14 | access to field S | | SSA.cs:5:17:5:17 | this | SSA.cs:67:9:67:12 | this access | | SSA.cs:5:26:5:32 | tainted | SSA.cs:8:24:8:30 | access to parameter tainted | diff --git a/csharp/ql/test/library-tests/dataflow/local/LocalDataFlow.cs b/csharp/ql/test/library-tests/dataflow/local/LocalDataFlow.cs index 154b4d5fcb9..65de9fc65fe 100644 --- a/csharp/ql/test/library-tests/dataflow/local/LocalDataFlow.cs +++ b/csharp/ql/test/library-tests/dataflow/local/LocalDataFlow.cs @@ -438,6 +438,12 @@ public class LocalDataFlow Check(nonSink17); break; } + + // Null-coalescing expressions + var sink73 = nonSink0 ?? sink0; + var sink74 = sink0 ?? nonSink0; + Check(sink73); + Check(sink74); } static void Check(T x) { } diff --git a/csharp/ql/test/library-tests/dataflow/local/TaintTracking.expected b/csharp/ql/test/library-tests/dataflow/local/TaintTracking.expected index ba3d91130f2..756d79333c1 100644 --- a/csharp/ql/test/library-tests/dataflow/local/TaintTracking.expected +++ b/csharp/ql/test/library-tests/dataflow/local/TaintTracking.expected @@ -62,7 +62,9 @@ | LocalDataFlow.cs:412:15:412:20 | access to local variable sink70 | | LocalDataFlow.cs:420:19:420:24 | access to local variable sink71 | | LocalDataFlow.cs:430:23:430:28 | access to local variable sink72 | -| LocalDataFlow.cs:466:15:466:21 | access to parameter tainted | +| LocalDataFlow.cs:445:15:445:20 | access to local variable sink73 | +| LocalDataFlow.cs:446:15:446:20 | access to local variable sink74 | +| LocalDataFlow.cs:472:15:472:21 | access to parameter tainted | | SSA.cs:9:15:9:22 | access to local variable ssaSink0 | | SSA.cs:25:15:25:22 | access to local variable ssaSink1 | | SSA.cs:43:15:43:22 | access to local variable ssaSink2 | diff --git a/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected b/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected index f9511969108..f320c87cb8b 100644 --- a/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected +++ b/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected @@ -690,7 +690,10 @@ | LocalDataFlow.cs:408:15:408:22 | access to local variable nonSink0 | LocalDataFlow.cs:415:31:415:38 | access to local variable nonSink0 | | LocalDataFlow.cs:411:13:411:34 | SSA def(sink70) | LocalDataFlow.cs:412:15:412:20 | access to local variable sink70 | | LocalDataFlow.cs:411:22:411:34 | ... = ... | LocalDataFlow.cs:411:13:411:34 | SSA def(sink70) | +| LocalDataFlow.cs:411:22:411:34 | SSA def(sink0) | LocalDataFlow.cs:443:34:443:38 | access to local variable sink0 | +| LocalDataFlow.cs:411:22:411:34 | SSA def(sink0) | LocalDataFlow.cs:444:22:444:26 | access to local variable sink0 | | LocalDataFlow.cs:411:30:411:34 | access to local variable sink0 | LocalDataFlow.cs:411:22:411:34 | ... = ... | +| LocalDataFlow.cs:411:30:411:34 | access to local variable sink0 | LocalDataFlow.cs:411:22:411:34 | SSA def(sink0) | | LocalDataFlow.cs:412:15:412:20 | [post] access to local variable sink70 | LocalDataFlow.cs:419:13:419:18 | access to local variable sink70 | | LocalDataFlow.cs:412:15:412:20 | access to local variable sink70 | LocalDataFlow.cs:419:13:419:18 | access to local variable sink70 | | LocalDataFlow.cs:415:9:415:38 | SSA def(nonSink0) | LocalDataFlow.cs:416:15:416:22 | access to local variable nonSink0 | @@ -707,15 +710,26 @@ | LocalDataFlow.cs:427:17:427:22 | access to local variable sink70 | LocalDataFlow.cs:429:18:429:30 | SSA def(sink72) | | LocalDataFlow.cs:429:18:429:30 | SSA def(sink72) | LocalDataFlow.cs:430:23:430:28 | access to local variable sink72 | | LocalDataFlow.cs:435:17:435:24 | access to local variable nonSink0 | LocalDataFlow.cs:437:18:437:33 | SSA def(nonSink17) | +| LocalDataFlow.cs:435:17:435:24 | access to local variable nonSink0 | LocalDataFlow.cs:443:22:443:29 | access to local variable nonSink0 | | LocalDataFlow.cs:437:18:437:33 | SSA def(nonSink17) | LocalDataFlow.cs:438:23:438:31 | access to local variable nonSink17 | -| LocalDataFlow.cs:458:28:458:30 | this | LocalDataFlow.cs:458:41:458:45 | this access | -| LocalDataFlow.cs:458:50:458:52 | this | LocalDataFlow.cs:458:56:458:60 | this access | -| LocalDataFlow.cs:458:50:458:52 | value | LocalDataFlow.cs:458:50:458:52 | value | -| LocalDataFlow.cs:458:50:458:52 | value | LocalDataFlow.cs:458:64:458:68 | access to parameter value | -| LocalDataFlow.cs:464:41:464:47 | tainted | LocalDataFlow.cs:464:41:464:47 | tainted | -| LocalDataFlow.cs:464:41:464:47 | tainted | LocalDataFlow.cs:466:15:466:21 | access to parameter tainted | -| LocalDataFlow.cs:469:44:469:53 | nonTainted | LocalDataFlow.cs:469:44:469:53 | nonTainted | -| LocalDataFlow.cs:469:44:469:53 | nonTainted | LocalDataFlow.cs:471:15:471:24 | access to parameter nonTainted | +| LocalDataFlow.cs:443:13:443:38 | SSA def(sink73) | LocalDataFlow.cs:445:15:445:20 | access to local variable sink73 | +| LocalDataFlow.cs:443:22:443:29 | access to local variable nonSink0 | LocalDataFlow.cs:443:22:443:38 | ... ?? ... | +| LocalDataFlow.cs:443:22:443:29 | access to local variable nonSink0 | LocalDataFlow.cs:444:31:444:38 | access to local variable nonSink0 | +| LocalDataFlow.cs:443:22:443:38 | ... ?? ... | LocalDataFlow.cs:443:13:443:38 | SSA def(sink73) | +| LocalDataFlow.cs:443:34:443:38 | access to local variable sink0 | LocalDataFlow.cs:443:22:443:38 | ... ?? ... | +| LocalDataFlow.cs:443:34:443:38 | access to local variable sink0 | LocalDataFlow.cs:444:22:444:26 | access to local variable sink0 | +| LocalDataFlow.cs:444:13:444:38 | SSA def(sink74) | LocalDataFlow.cs:446:15:446:20 | access to local variable sink74 | +| LocalDataFlow.cs:444:22:444:26 | access to local variable sink0 | LocalDataFlow.cs:444:22:444:38 | ... ?? ... | +| LocalDataFlow.cs:444:22:444:38 | ... ?? ... | LocalDataFlow.cs:444:13:444:38 | SSA def(sink74) | +| LocalDataFlow.cs:444:31:444:38 | access to local variable nonSink0 | LocalDataFlow.cs:444:22:444:38 | ... ?? ... | +| LocalDataFlow.cs:464:28:464:30 | this | LocalDataFlow.cs:464:41:464:45 | this access | +| LocalDataFlow.cs:464:50:464:52 | this | LocalDataFlow.cs:464:56:464:60 | this access | +| LocalDataFlow.cs:464:50:464:52 | value | LocalDataFlow.cs:464:50:464:52 | value | +| LocalDataFlow.cs:464:50:464:52 | value | LocalDataFlow.cs:464:64:464:68 | access to parameter value | +| LocalDataFlow.cs:470:41:470:47 | tainted | LocalDataFlow.cs:470:41:470:47 | tainted | +| LocalDataFlow.cs:470:41:470:47 | tainted | LocalDataFlow.cs:472:15:472:21 | access to parameter tainted | +| LocalDataFlow.cs:475:44:475:53 | nonTainted | LocalDataFlow.cs:475:44:475:53 | nonTainted | +| LocalDataFlow.cs:475:44:475:53 | nonTainted | LocalDataFlow.cs:477:15:477:24 | access to parameter nonTainted | | SSA.cs:5:17:5:17 | SSA entry def(this.S) | SSA.cs:67:9:67:14 | access to field S | | SSA.cs:5:17:5:17 | this | SSA.cs:67:9:67:12 | this access | | SSA.cs:5:26:5:32 | tainted | SSA.cs:5:26:5:32 | tainted | diff --git a/csharp/ql/test/library-tests/dispatch/CallGraph.expected b/csharp/ql/test/library-tests/dispatch/CallGraph.expected index a0c105c1c78..21bbe4e0267 100644 --- a/csharp/ql/test/library-tests/dispatch/CallGraph.expected +++ b/csharp/ql/test/library-tests/dispatch/CallGraph.expected @@ -41,21 +41,28 @@ | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:241:23:241:27 | M | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:241:23:241:27 | M | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:241:23:241:27 | M | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:241:23:241:27 | M | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:242:35:242:37 | get_Prop | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:242:35:242:37 | get_Prop | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:242:35:242:37 | get_Prop | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:242:35:242:37 | get_Prop | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:242:40:242:42 | set_Prop | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:242:40:242:42 | set_Prop | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:242:40:242:42 | set_Prop | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:242:40:242:42 | set_Prop | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:243:40:243:42 | get_Item | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:243:40:243:42 | get_Item | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:243:40:243:42 | get_Item | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:243:40:243:42 | get_Item | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:243:71:243:73 | set_Item | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:243:71:243:73 | set_Item | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:243:71:243:73 | set_Item | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:243:71:243:73 | set_Item | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:244:56:244:58 | add_Event | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:244:56:244:58 | add_Event | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:244:56:244:58 | add_Event | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:244:56:244:58 | add_Event | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:244:64:244:69 | remove_Event | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:244:64:244:69 | remove_Event | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:244:64:244:69 | remove_Event | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:244:64:244:69 | remove_Event | @@ -67,11 +74,18 @@ | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:252:56:252:58 | add_Event | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:252:64:252:69 | remove_Event | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:257:26:257:30 | M | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:257:26:257:30 | M | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:258:32:258:34 | get_Prop | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:258:32:258:34 | get_Prop | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:258:37:258:39 | set_Prop | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:258:37:258:39 | set_Prop | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:259:40:259:42 | get_Item | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:259:40:259:42 | get_Item | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:259:71:259:73 | set_Item | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:259:71:259:73 | set_Item | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:260:53:260:55 | add_Event | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:260:53:260:55 | add_Event | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:260:61:260:66 | remove_Event | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:260:61:260:66 | remove_Event | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:265:26:265:30 | M | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:266:24:266:24 | M | @@ -91,6 +105,11 @@ | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:276:24:276:28 | M | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:276:24:276:28 | M | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:276:24:276:28 | M | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:276:24:276:28 | M | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:276:24:276:28 | M | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:277:31:277:33 | get_Prop | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:277:31:277:33 | get_Prop | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:277:31:277:33 | get_Prop | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:277:31:277:33 | get_Prop | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:277:31:277:33 | get_Prop | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:277:31:277:33 | get_Prop | @@ -103,6 +122,12 @@ | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:277:36:277:38 | set_Prop | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:277:36:277:38 | set_Prop | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:277:36:277:38 | set_Prop | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:277:36:277:38 | set_Prop | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:277:36:277:38 | set_Prop | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:277:36:277:38 | set_Prop | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:278:37:278:39 | get_Item | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:278:37:278:39 | get_Item | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:278:37:278:39 | get_Item | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:278:37:278:39 | get_Item | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:278:37:278:39 | get_Item | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:278:37:278:39 | get_Item | @@ -115,12 +140,21 @@ | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:278:68:278:70 | set_Item | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:278:68:278:70 | set_Item | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:278:68:278:70 | set_Item | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:278:68:278:70 | set_Item | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:278:68:278:70 | set_Item | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:278:68:278:70 | set_Item | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:279:52:279:54 | add_Event | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:279:52:279:54 | add_Event | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:279:52:279:54 | add_Event | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:279:52:279:54 | add_Event | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:279:52:279:54 | add_Event | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:279:52:279:54 | add_Event | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:279:52:279:54 | add_Event | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:279:52:279:54 | add_Event | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:279:52:279:54 | add_Event | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:279:60:279:65 | remove_Event | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:279:60:279:65 | remove_Event | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:279:60:279:65 | remove_Event | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:279:60:279:65 | remove_Event | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:279:60:279:65 | remove_Event | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:279:60:279:65 | remove_Event | @@ -128,11 +162,18 @@ | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:279:60:279:65 | remove_Event | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:279:60:279:65 | remove_Event | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:293:26:293:30 | M | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:293:26:293:30 | M | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:294:31:294:33 | get_Prop | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:294:31:294:33 | get_Prop | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:294:36:294:38 | set_Prop | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:294:36:294:38 | set_Prop | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:295:39:295:41 | get_Item | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:295:39:295:41 | get_Item | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:295:70:295:72 | set_Item | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:295:70:295:72 | set_Item | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:296:52:296:54 | add_Event | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:296:52:296:54 | add_Event | +| ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:296:60:296:65 | remove_Event | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:296:60:296:65 | remove_Event | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:313:25:313:25 | M | | ViableCallable.cs:9:17:9:31 | Run | ViableCallable.cs:314:24:314:28 | M2 | @@ -152,17 +193,25 @@ | ViableCallable.cs:232:17:232:19 | Run | ViableCallable.cs:241:23:241:27 | M | | ViableCallable.cs:232:17:232:19 | Run | ViableCallable.cs:241:23:241:27 | M | | ViableCallable.cs:232:17:232:19 | Run | ViableCallable.cs:241:23:241:27 | M | +| ViableCallable.cs:232:17:232:19 | Run | ViableCallable.cs:241:23:241:27 | M | | ViableCallable.cs:232:17:232:19 | Run | ViableCallable.cs:249:29:249:33 | M | | ViableCallable.cs:232:17:232:19 | Run | ViableCallable.cs:257:26:257:30 | M | +| ViableCallable.cs:232:17:232:19 | Run | ViableCallable.cs:257:26:257:30 | M | | ViableCallable.cs:232:17:232:19 | Run | ViableCallable.cs:265:26:265:30 | M | | ViableCallable.cs:232:17:232:19 | Run | ViableCallable.cs:276:24:276:28 | M | | ViableCallable.cs:232:17:232:19 | Run | ViableCallable.cs:276:24:276:28 | M | | ViableCallable.cs:232:17:232:19 | Run | ViableCallable.cs:276:24:276:28 | M | | ViableCallable.cs:232:17:232:19 | Run | ViableCallable.cs:276:24:276:28 | M | | ViableCallable.cs:232:17:232:19 | Run | ViableCallable.cs:276:24:276:28 | M | +| ViableCallable.cs:232:17:232:19 | Run | ViableCallable.cs:276:24:276:28 | M | +| ViableCallable.cs:232:17:232:19 | Run | ViableCallable.cs:276:24:276:28 | M | +| ViableCallable.cs:232:17:232:19 | Run | ViableCallable.cs:276:24:276:28 | M | +| ViableCallable.cs:232:17:232:19 | Run | ViableCallable.cs:276:24:276:28 | M | +| ViableCallable.cs:232:17:232:19 | Run | ViableCallable.cs:293:26:293:30 | M | | ViableCallable.cs:232:17:232:19 | Run | ViableCallable.cs:293:26:293:30 | M | | ViableCallable.cs:281:17:281:19 | Run | ViableCallable.cs:276:24:276:28 | M | | ViableCallable.cs:281:17:281:19 | Run | ViableCallable.cs:293:26:293:30 | M | +| ViableCallable.cs:281:17:281:19 | Run | ViableCallable.cs:293:26:293:30 | M | | ViableCallable.cs:298:17:298:19 | Run | ViableCallable.cs:276:24:276:28 | M | | ViableCallable.cs:298:17:298:19 | Run | ViableCallable.cs:293:26:293:30 | M | | ViableCallable.cs:348:17:348:19 | Run | ViableCallable.cs:346:10:346:10 | M | @@ -174,6 +223,16 @@ | ViableCallable.cs:409:10:409:12 | Run | ViableCallable.cs:397:36:397:40 | M | | ViableCallable.cs:409:10:409:12 | Run | ViableCallable.cs:403:53:403:57 | M | | ViableCallable.cs:409:10:409:12 | Run | ViableCallable.cs:405:42:405:46 | M | -| ViableCallable.cs:431:25:431:29 | M2 | ViableCallable.cs:442:17:442:23 | (...) => ... | -| ViableCallable.cs:436:10:436:10 | M | ViableCallable.cs:430:23:430:24 | M1 | -| ViableCallable.cs:436:10:436:10 | M | ViableCallable.cs:431:25:431:29 | M2 | +| ViableCallable.cs:431:22:431:26 | M2 | ViableCallable.cs:456:14:456:29 | (...) => ... | +| ViableCallable.cs:431:22:431:26 | M2 | ViableCallable.cs:462:14:462:29 | (...) => ... | +| ViableCallable.cs:436:10:436:11 | M1 | ViableCallable.cs:430:23:430:24 | M1 | +| ViableCallable.cs:436:10:436:11 | M1 | ViableCallable.cs:445:23:445:27 | M2 | +| ViableCallable.cs:445:23:445:27 | M2 | ViableCallable.cs:442:17:442:23 | (...) => ... | +| ViableCallable.cs:445:23:445:27 | M2 | ViableCallable.cs:450:14:450:20 | (...) => ... | +| ViableCallable.cs:445:23:445:27 | M2 | ViableCallable.cs:456:14:456:29 | (...) => ... | +| ViableCallable.cs:445:23:445:27 | M2 | ViableCallable.cs:462:14:462:29 | (...) => ... | +| ViableCallable.cs:447:10:447:14 | M3 | ViableCallable.cs:445:23:445:27 | M2 | +| ViableCallable.cs:453:10:453:14 | M4 | ViableCallable.cs:431:22:431:26 | M2 | +| ViableCallable.cs:453:10:453:14 | M4 | ViableCallable.cs:445:23:445:27 | M2 | +| ViableCallable.cs:459:10:459:14 | M5 | ViableCallable.cs:431:22:431:26 | M2 | +| ViableCallable.cs:459:10:459:14 | M5 | ViableCallable.cs:445:23:445:27 | M2 | diff --git a/csharp/ql/test/library-tests/dispatch/GetADynamicTarget.expected b/csharp/ql/test/library-tests/dispatch/GetADynamicTarget.expected index fb766901ed5..72eb9275f8b 100644 --- a/csharp/ql/test/library-tests/dispatch/GetADynamicTarget.expected +++ b/csharp/ql/test/library-tests/dispatch/GetADynamicTarget.expected @@ -66,102 +66,151 @@ | TypeFlow.cs:33:9:33:18 | call to method Method | TypeFlow.C2.Method() | | TypeFlow.cs:37:11:37:26 | call to method Method | TypeFlow.C2.Method() | | TypeFlow.cs:40:9:40:18 | call to method Method | TypeFlow.C2.Method() | +| ViableCallable.cs:12:9:12:28 | call to method M | C2<>.M(string, T3) | | ViableCallable.cs:12:9:12:28 | call to method M | C2.M(string, T3) | | ViableCallable.cs:12:9:12:28 | call to method M | C2.M(string, T3) | | ViableCallable.cs:12:9:12:28 | call to method M | C2.M(string, T3) | | ViableCallable.cs:12:9:12:28 | call to method M | C3.M(string, T3) | +| ViableCallable.cs:12:9:12:28 | call to method M | C4<>.M(T[], T3) | | ViableCallable.cs:12:9:12:28 | call to method M | C4.M(int[], T3) | | ViableCallable.cs:12:9:12:28 | call to method M | C5.M(string, T3) | +| ViableCallable.cs:12:9:12:28 | call to method M | C6<,>.M(T1, T3) | | ViableCallable.cs:12:9:12:28 | call to method M | C6.M(bool, T3) | | ViableCallable.cs:12:9:12:28 | call to method M | C6.M(int[], T3) | | ViableCallable.cs:12:9:12:28 | call to method M | C6.M(string, T3) | | ViableCallable.cs:12:9:12:28 | call to method M | C6.M(string, T3) | | ViableCallable.cs:12:9:12:28 | call to method M | C6.M(string, T3) | +| ViableCallable.cs:12:9:12:28 | call to method M | C6.M(T1, T3) | +| ViableCallable.cs:12:9:12:28 | call to method M | C6.M(T1, T3) | +| ViableCallable.cs:12:9:12:28 | call to method M | C7<>.M(T1, T3) | | ViableCallable.cs:12:9:12:28 | call to method M | C7.M(bool, T3) | +| ViableCallable.cs:14:9:14:15 | access to property Prop | C2<>.set_Prop(string) | | ViableCallable.cs:14:9:14:15 | access to property Prop | C2.set_Prop(string) | | ViableCallable.cs:14:9:14:15 | access to property Prop | C2.set_Prop(string) | | ViableCallable.cs:14:9:14:15 | access to property Prop | C2.set_Prop(string) | | ViableCallable.cs:14:9:14:15 | access to property Prop | C3.set_Prop(string) | +| ViableCallable.cs:14:9:14:15 | access to property Prop | C4<>.set_Prop(T[]) | | ViableCallable.cs:14:9:14:15 | access to property Prop | C4.set_Prop(int[]) | | ViableCallable.cs:14:9:14:15 | access to property Prop | C5.set_Prop(string) | +| ViableCallable.cs:14:9:14:15 | access to property Prop | C6<,>.set_Prop(T1) | | ViableCallable.cs:14:9:14:15 | access to property Prop | C6.set_Prop(bool) | | ViableCallable.cs:14:9:14:15 | access to property Prop | C6.set_Prop(int[]) | | ViableCallable.cs:14:9:14:15 | access to property Prop | C6.set_Prop(string) | | ViableCallable.cs:14:9:14:15 | access to property Prop | C6.set_Prop(string) | | ViableCallable.cs:14:9:14:15 | access to property Prop | C6.set_Prop(string) | +| ViableCallable.cs:14:9:14:15 | access to property Prop | C6.set_Prop(T1) | +| ViableCallable.cs:14:9:14:15 | access to property Prop | C6.set_Prop(T1) | +| ViableCallable.cs:14:9:14:15 | access to property Prop | C7<>.set_Prop(T1) | | ViableCallable.cs:14:9:14:15 | access to property Prop | C7.set_Prop(bool) | +| ViableCallable.cs:14:19:14:25 | access to property Prop | C2<>.get_Prop() | | ViableCallable.cs:14:19:14:25 | access to property Prop | C2.get_Prop() | | ViableCallable.cs:14:19:14:25 | access to property Prop | C2.get_Prop() | | ViableCallable.cs:14:19:14:25 | access to property Prop | C2.get_Prop() | | ViableCallable.cs:14:19:14:25 | access to property Prop | C3.get_Prop() | +| ViableCallable.cs:14:19:14:25 | access to property Prop | C4<>.get_Prop() | | ViableCallable.cs:14:19:14:25 | access to property Prop | C4.get_Prop() | | ViableCallable.cs:14:19:14:25 | access to property Prop | C5.get_Prop() | +| ViableCallable.cs:14:19:14:25 | access to property Prop | C6<,>.get_Prop() | | ViableCallable.cs:14:19:14:25 | access to property Prop | C6.get_Prop() | | ViableCallable.cs:14:19:14:25 | access to property Prop | C6.get_Prop() | | ViableCallable.cs:14:19:14:25 | access to property Prop | C6.get_Prop() | | ViableCallable.cs:14:19:14:25 | access to property Prop | C6.get_Prop() | | ViableCallable.cs:14:19:14:25 | access to property Prop | C6.get_Prop() | +| ViableCallable.cs:14:19:14:25 | access to property Prop | C6.get_Prop() | +| ViableCallable.cs:14:19:14:25 | access to property Prop | C6.get_Prop() | +| ViableCallable.cs:14:19:14:25 | access to property Prop | C7<>.get_Prop() | | ViableCallable.cs:14:19:14:25 | access to property Prop | C7.get_Prop() | +| ViableCallable.cs:16:9:16:23 | access to indexer | C2<>.set_Item(T, string) | | ViableCallable.cs:16:9:16:23 | access to indexer | C2.set_Item(bool, string) | | ViableCallable.cs:16:9:16:23 | access to indexer | C2.set_Item(decimal, string) | | ViableCallable.cs:16:9:16:23 | access to indexer | C2.set_Item(int, string) | | ViableCallable.cs:16:9:16:23 | access to indexer | C3.set_Item(decimal, string) | +| ViableCallable.cs:16:9:16:23 | access to indexer | C4<>.set_Item(bool, T[]) | | ViableCallable.cs:16:9:16:23 | access to indexer | C4.set_Item(bool, int[]) | | ViableCallable.cs:16:9:16:23 | access to indexer | C5.set_Item(bool, string) | +| ViableCallable.cs:16:9:16:23 | access to indexer | C6<,>.set_Item(T2, T1) | | ViableCallable.cs:16:9:16:23 | access to indexer | C6.set_Item(byte, bool) | | ViableCallable.cs:16:9:16:23 | access to indexer | C6.set_Item(bool, int[]) | | ViableCallable.cs:16:9:16:23 | access to indexer | C6.set_Item(bool, string) | | ViableCallable.cs:16:9:16:23 | access to indexer | C6.set_Item(decimal, string) | | ViableCallable.cs:16:9:16:23 | access to indexer | C6.set_Item(int, string) | +| ViableCallable.cs:16:9:16:23 | access to indexer | C6.set_Item(bool, T1) | +| ViableCallable.cs:16:9:16:23 | access to indexer | C6.set_Item(byte, T1) | +| ViableCallable.cs:16:9:16:23 | access to indexer | C7<>.set_Item(byte, T1) | | ViableCallable.cs:16:9:16:23 | access to indexer | C7.set_Item(byte, bool) | +| ViableCallable.cs:16:27:16:41 | access to indexer | C2<>.get_Item(T) | | ViableCallable.cs:16:27:16:41 | access to indexer | C2.get_Item(bool) | | ViableCallable.cs:16:27:16:41 | access to indexer | C2.get_Item(decimal) | | ViableCallable.cs:16:27:16:41 | access to indexer | C2.get_Item(int) | | ViableCallable.cs:16:27:16:41 | access to indexer | C3.get_Item(decimal) | +| ViableCallable.cs:16:27:16:41 | access to indexer | C4<>.get_Item(bool) | | ViableCallable.cs:16:27:16:41 | access to indexer | C4.get_Item(bool) | | ViableCallable.cs:16:27:16:41 | access to indexer | C5.get_Item(bool) | +| ViableCallable.cs:16:27:16:41 | access to indexer | C6<,>.get_Item(T2) | | ViableCallable.cs:16:27:16:41 | access to indexer | C6.get_Item(byte) | | ViableCallable.cs:16:27:16:41 | access to indexer | C6.get_Item(bool) | | ViableCallable.cs:16:27:16:41 | access to indexer | C6.get_Item(bool) | | ViableCallable.cs:16:27:16:41 | access to indexer | C6.get_Item(decimal) | | ViableCallable.cs:16:27:16:41 | access to indexer | C6.get_Item(int) | +| ViableCallable.cs:16:27:16:41 | access to indexer | C6.get_Item(bool) | +| ViableCallable.cs:16:27:16:41 | access to indexer | C6.get_Item(byte) | +| ViableCallable.cs:16:27:16:41 | access to indexer | C7<>.get_Item(byte) | | ViableCallable.cs:16:27:16:41 | access to indexer | C7.get_Item(byte) | +| ViableCallable.cs:18:9:18:16 | access to event Event | C2<>.add_Event(EventHandler) | | ViableCallable.cs:18:9:18:16 | access to event Event | C2.add_Event(EventHandler) | | ViableCallable.cs:18:9:18:16 | access to event Event | C2.add_Event(EventHandler) | | ViableCallable.cs:18:9:18:16 | access to event Event | C2.add_Event(EventHandler) | | ViableCallable.cs:18:9:18:16 | access to event Event | C3.add_Event(EventHandler) | +| ViableCallable.cs:18:9:18:16 | access to event Event | C4<>.add_Event(EventHandler) | | ViableCallable.cs:18:9:18:16 | access to event Event | C4.add_Event(EventHandler) | | ViableCallable.cs:18:9:18:16 | access to event Event | C5.add_Event(EventHandler) | +| ViableCallable.cs:18:9:18:16 | access to event Event | C6<,>.add_Event(EventHandler) | | ViableCallable.cs:18:9:18:16 | access to event Event | C6.add_Event(EventHandler) | | ViableCallable.cs:18:9:18:16 | access to event Event | C6.add_Event(EventHandler) | | ViableCallable.cs:18:9:18:16 | access to event Event | C6.add_Event(EventHandler) | | ViableCallable.cs:18:9:18:16 | access to event Event | C6.add_Event(EventHandler) | | ViableCallable.cs:18:9:18:16 | access to event Event | C6.add_Event(EventHandler) | +| ViableCallable.cs:18:9:18:16 | access to event Event | C6.add_Event(EventHandler) | +| ViableCallable.cs:18:9:18:16 | access to event Event | C6.add_Event(EventHandler) | +| ViableCallable.cs:18:9:18:16 | access to event Event | C7<>.add_Event(EventHandler) | | ViableCallable.cs:18:9:18:16 | access to event Event | C7.add_Event(EventHandler) | +| ViableCallable.cs:19:9:19:16 | access to event Event | C2<>.remove_Event(EventHandler) | | ViableCallable.cs:19:9:19:16 | access to event Event | C2.remove_Event(EventHandler) | | ViableCallable.cs:19:9:19:16 | access to event Event | C2.remove_Event(EventHandler) | | ViableCallable.cs:19:9:19:16 | access to event Event | C2.remove_Event(EventHandler) | | ViableCallable.cs:19:9:19:16 | access to event Event | C3.remove_Event(EventHandler) | +| ViableCallable.cs:19:9:19:16 | access to event Event | C4<>.remove_Event(EventHandler) | | ViableCallable.cs:19:9:19:16 | access to event Event | C4.remove_Event(EventHandler) | | ViableCallable.cs:19:9:19:16 | access to event Event | C5.remove_Event(EventHandler) | +| ViableCallable.cs:19:9:19:16 | access to event Event | C6<,>.remove_Event(EventHandler) | | ViableCallable.cs:19:9:19:16 | access to event Event | C6.remove_Event(EventHandler) | | ViableCallable.cs:19:9:19:16 | access to event Event | C6.remove_Event(EventHandler) | | ViableCallable.cs:19:9:19:16 | access to event Event | C6.remove_Event(EventHandler) | | ViableCallable.cs:19:9:19:16 | access to event Event | C6.remove_Event(EventHandler) | | ViableCallable.cs:19:9:19:16 | access to event Event | C6.remove_Event(EventHandler) | +| ViableCallable.cs:19:9:19:16 | access to event Event | C6.remove_Event(EventHandler) | +| ViableCallable.cs:19:9:19:16 | access to event Event | C6.remove_Event(EventHandler) | +| ViableCallable.cs:19:9:19:16 | access to event Event | C7<>.remove_Event(EventHandler) | | ViableCallable.cs:19:9:19:16 | access to event Event | C7.remove_Event(EventHandler) | +| ViableCallable.cs:22:9:22:30 | call to method M | C4<>.M(T[], T3) | | ViableCallable.cs:22:9:22:30 | call to method M | C4.M(int[], T3) | | ViableCallable.cs:22:9:22:30 | call to method M | C6.M(int[], T3) | +| ViableCallable.cs:24:9:24:15 | access to property Prop | C4<>.set_Prop(T[]) | | ViableCallable.cs:24:9:24:15 | access to property Prop | C4.set_Prop(int[]) | | ViableCallable.cs:24:9:24:15 | access to property Prop | C6.set_Prop(int[]) | +| ViableCallable.cs:24:19:24:25 | access to property Prop | C4<>.get_Prop() | | ViableCallable.cs:24:19:24:25 | access to property Prop | C4.get_Prop() | | ViableCallable.cs:24:19:24:25 | access to property Prop | C6.get_Prop() | +| ViableCallable.cs:26:9:26:23 | access to indexer | C4<>.set_Item(bool, T[]) | | ViableCallable.cs:26:9:26:23 | access to indexer | C4.set_Item(bool, int[]) | | ViableCallable.cs:26:9:26:23 | access to indexer | C6.set_Item(bool, int[]) | +| ViableCallable.cs:26:27:26:41 | access to indexer | C4<>.get_Item(bool) | | ViableCallable.cs:26:27:26:41 | access to indexer | C4.get_Item(bool) | | ViableCallable.cs:26:27:26:41 | access to indexer | C6.get_Item(bool) | +| ViableCallable.cs:28:9:28:16 | access to event Event | C4<>.add_Event(EventHandler) | | ViableCallable.cs:28:9:28:16 | access to event Event | C4.add_Event(EventHandler) | | ViableCallable.cs:28:9:28:16 | access to event Event | C6.add_Event(EventHandler) | +| ViableCallable.cs:29:9:29:16 | access to event Event | C4<>.remove_Event(EventHandler) | | ViableCallable.cs:29:9:29:16 | access to event Event | C4.remove_Event(EventHandler) | | ViableCallable.cs:29:9:29:16 | access to event Event | C6.remove_Event(EventHandler) | | ViableCallable.cs:32:30:32:52 | call to method Mock | ViableCallable.Mock>() | @@ -264,10 +313,15 @@ | ViableCallable.cs:106:9:106:17 | access to event Event2 | C5.remove_Event2(EventHandler) | | ViableCallable.cs:120:9:120:25 | dynamic call to method M2 | C8.M2(decimal[]) | | ViableCallable.cs:124:9:124:24 | dynamic call to method M2 | C8.M2(string[]) | +| ViableCallable.cs:132:9:132:28 | dynamic call to method M | C6.M(bool, T3) | | ViableCallable.cs:132:9:132:28 | dynamic call to method M | C6.M(T1, T3) | +| ViableCallable.cs:134:9:134:14 | dynamic access to member Prop | C6.set_Prop(bool) | | ViableCallable.cs:134:9:134:14 | dynamic access to member Prop | C6.set_Prop(T1) | +| ViableCallable.cs:134:18:134:23 | dynamic access to member Prop | C6.get_Prop() | | ViableCallable.cs:134:18:134:23 | dynamic access to member Prop | C6.get_Prop() | +| ViableCallable.cs:136:9:136:18 | dynamic access to element | C6.set_Item(byte, bool) | | ViableCallable.cs:136:9:136:18 | dynamic access to element | C6.set_Item(byte, T1) | +| ViableCallable.cs:136:22:136:31 | dynamic access to element | C6.get_Item(byte) | | ViableCallable.cs:136:22:136:31 | dynamic access to element | C6.get_Item(byte) | | ViableCallable.cs:138:9:138:52 | ... += ... | C6.add_Event(EventHandler) | | ViableCallable.cs:139:9:139:52 | ... -= ... | C6.remove_Event(EventHandler) | @@ -368,21 +422,29 @@ | ViableCallable.cs:195:9:195:152 | call to method InvokeMember | C10.set_Item(int, bool) | | ViableCallable.cs:199:9:199:147 | call to method InvokeMember | C10.add_Event(EventHandler) | | ViableCallable.cs:200:9:200:150 | call to method InvokeMember | C10.remove_Event(EventHandler) | +| ViableCallable.cs:235:9:235:15 | call to method M | C2<>.M(string, T3) | | ViableCallable.cs:235:9:235:15 | call to method M | C2.M(string, T3) | | ViableCallable.cs:235:9:235:15 | call to method M | C2.M(string, T3) | | ViableCallable.cs:235:9:235:15 | call to method M | C2.M(string, T3) | | ViableCallable.cs:235:9:235:15 | call to method M | C3.M(string, T3) | +| ViableCallable.cs:235:9:235:15 | call to method M | C4<>.M(T[], T3) | | ViableCallable.cs:235:9:235:15 | call to method M | C4.M(int[], T3) | | ViableCallable.cs:235:9:235:15 | call to method M | C5.M(string, T3) | +| ViableCallable.cs:235:9:235:15 | call to method M | C6<,>.M(T1, T3) | | ViableCallable.cs:235:9:235:15 | call to method M | C6.M(bool, T3) | | ViableCallable.cs:235:9:235:15 | call to method M | C6.M(int[], T3) | | ViableCallable.cs:235:9:235:15 | call to method M | C6.M(string, T3) | | ViableCallable.cs:235:9:235:15 | call to method M | C6.M(string, T3) | | ViableCallable.cs:235:9:235:15 | call to method M | C6.M(string, T3) | +| ViableCallable.cs:235:9:235:15 | call to method M | C6.M(T1, T3) | +| ViableCallable.cs:235:9:235:15 | call to method M | C6.M(T1, T3) | +| ViableCallable.cs:235:9:235:15 | call to method M | C7<>.M(T1, T3) | | ViableCallable.cs:235:9:235:15 | call to method M | C7.M(bool, T3) | | ViableCallable.cs:284:9:284:15 | call to method M | C6<,>.M(T1, T3) | +| ViableCallable.cs:284:9:284:15 | call to method M | C7<>.M(T1, T3) | | ViableCallable.cs:284:9:284:15 | call to method M | C7.M(bool, T3) | | ViableCallable.cs:287:9:287:20 | call to method M | C6<,>.M(T1, T3) | +| ViableCallable.cs:287:9:287:20 | call to method M | C7<>.M(T1, T3) | | ViableCallable.cs:287:9:287:20 | call to method M | C7.M(bool, T3) | | ViableCallable.cs:301:9:301:15 | call to method M | C7<>.M(T1, T3) | | ViableCallable.cs:304:9:304:20 | call to method M | C7<>.M(T1, T3) | @@ -401,4 +463,9 @@ | ViableCallable.cs:424:9:424:21 | call to method M | C15.A4.M() | | ViableCallable.cs:424:9:424:21 | call to method M | C15.A5.M() | | ViableCallable.cs:439:9:439:19 | call to method M1 | C16.M1(string) | -| ViableCallable.cs:442:9:442:24 | call to method M2 | C16.M2(Func) | +| ViableCallable.cs:442:9:442:24 | call to method M2 | C17.M2(Func) | +| ViableCallable.cs:450:9:450:21 | call to method M2 | C17.M2(Func) | +| ViableCallable.cs:456:9:456:30 | call to method M2 | C16.M2(Func) | +| ViableCallable.cs:456:9:456:30 | call to method M2 | C17.M2(Func) | +| ViableCallable.cs:462:9:462:30 | call to method M2 | C16.M2(Func) | +| ViableCallable.cs:462:9:462:30 | call to method M2 | C17.M2(Func) | diff --git a/csharp/ql/test/library-tests/dispatch/ViableCallable.cs b/csharp/ql/test/library-tests/dispatch/ViableCallable.cs index e51c9c4b625..bcc68034b71 100644 --- a/csharp/ql/test/library-tests/dispatch/ViableCallable.cs +++ b/csharp/ql/test/library-tests/dispatch/ViableCallable.cs @@ -428,12 +428,12 @@ public class C15 abstract class C16 { public virtual T2 M1(T1 x) => throw null; - protected virtual T M2(Func x) => x(); + public virtual T M2(Func x) => x(); } class C17 : C16 { - void M(int i) + void M1(int i) { // Viable callables: C16.M1() this.M1(""); @@ -441,4 +441,24 @@ class C17 : C16 // Viable callables: C16.M2() this.M2(() => i); } + + public override T M2(Func x) => x(); + + void M3(T t, string s) where T : C17 + { + // Viable callable: C17.M2() + t.M2(() => s); + } + + void M4(C16 c) where T : struct + { + // Viable callable: C16.M2() [also reports C17.M2(); false positive] + c.M2(() => default(T)); + } + + void M5(C16 c) where T : class + { + // Viable callables: {C16,C17}.M1() + c.M2(() => default(T)); + } } diff --git a/csharp/ql/test/library-tests/ir/ir/raw_ir.expected b/csharp/ql/test/library-tests/ir/ir/raw_ir.expected index 9cac1b9d31e..5e3701a4c5a 100644 --- a/csharp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/csharp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -53,7 +53,8 @@ array.cs: # 10| mu0_49(Int32) = Store : &:r0_48, r0_43 # 2| v0_50(Void) = ReturnVoid : # 2| v0_51(Void) = UnmodeledUse : mu* -# 2| v0_52(Void) = ExitFunction : +# 2| v0_52(Void) = AliasedUse : ~mu0_2 +# 2| v0_53(Void) = ExitFunction : # 13| System.Void ArrayTest.twod_and_init_acc() # 13| Block 0 @@ -144,7 +145,8 @@ array.cs: # 20| mu0_84(Int32) = Store : &:r0_83, r0_76 # 13| v0_85(Void) = ReturnVoid : # 13| v0_86(Void) = UnmodeledUse : mu* -# 13| v0_87(Void) = ExitFunction : +# 13| v0_87(Void) = AliasedUse : ~mu0_2 +# 13| v0_88(Void) = ExitFunction : assignop.cs: # 4| System.Void AssignOp.Main() @@ -215,7 +217,8 @@ assignop.cs: # 17| mu0_63(Int32) = Store : &:r0_60, r0_62 # 4| v0_64(Void) = ReturnVoid : # 4| v0_65(Void) = UnmodeledUse : mu* -# 4| v0_66(Void) = ExitFunction : +# 4| v0_66(Void) = AliasedUse : ~mu0_2 +# 4| v0_67(Void) = ExitFunction : casts.cs: # 11| System.Void Casts.Main() @@ -241,7 +244,8 @@ casts.cs: # 15| mu0_18(Casts_B) = Store : &:r0_14, r0_17 # 11| v0_19(Void) = ReturnVoid : # 11| v0_20(Void) = UnmodeledUse : mu* -# 11| v0_21(Void) = ExitFunction : +# 11| v0_21(Void) = AliasedUse : ~mu0_2 +# 11| v0_22(Void) = ExitFunction : collections.cs: # 11| System.Void Collections.Main() @@ -285,7 +289,8 @@ collections.cs: # 13| mu0_36(Dictionary) = Store : &:r0_3, r0_4 # 11| v0_37(Void) = ReturnVoid : # 11| v0_38(Void) = UnmodeledUse : mu* -# 11| v0_39(Void) = ExitFunction : +# 11| v0_39(Void) = AliasedUse : ~mu0_2 +# 11| v0_40(Void) = ExitFunction : constructor_init.cs: # 5| System.Void BaseClass..ctor() @@ -297,7 +302,8 @@ constructor_init.cs: # 6| v0_4(Void) = NoOp : # 5| v0_5(Void) = ReturnVoid : # 5| v0_6(Void) = UnmodeledUse : mu* -# 5| v0_7(Void) = ExitFunction : +# 5| v0_7(Void) = AliasedUse : ~mu0_2 +# 5| v0_8(Void) = ExitFunction : # 9| System.Void BaseClass..ctor(System.Int32) # 9| Block 0 @@ -314,7 +320,8 @@ constructor_init.cs: # 11| mu0_10(Int32) = Store : &:r0_9, r0_7 # 9| v0_11(Void) = ReturnVoid : # 9| v0_12(Void) = UnmodeledUse : mu* -# 9| v0_13(Void) = ExitFunction : +# 9| v0_13(Void) = AliasedUse : ~mu0_2 +# 9| v0_14(Void) = ExitFunction : # 17| System.Void DerivedClass..ctor() # 17| Block 0 @@ -329,7 +336,8 @@ constructor_init.cs: # 18| v0_8(Void) = NoOp : # 17| v0_9(Void) = ReturnVoid : # 17| v0_10(Void) = UnmodeledUse : mu* -# 17| v0_11(Void) = ExitFunction : +# 17| v0_11(Void) = AliasedUse : ~mu0_2 +# 17| v0_12(Void) = ExitFunction : # 21| System.Void DerivedClass..ctor(System.Int32) # 21| Block 0 @@ -348,7 +356,8 @@ constructor_init.cs: # 22| v0_12(Void) = NoOp : # 21| v0_13(Void) = ReturnVoid : # 21| v0_14(Void) = UnmodeledUse : mu* -# 21| v0_15(Void) = ExitFunction : +# 21| v0_15(Void) = AliasedUse : ~mu0_2 +# 21| v0_16(Void) = ExitFunction : # 25| System.Void DerivedClass..ctor(System.Int32,System.Int32) # 25| Block 0 @@ -368,7 +377,8 @@ constructor_init.cs: # 26| v0_13(Void) = NoOp : # 25| v0_14(Void) = ReturnVoid : # 25| v0_15(Void) = UnmodeledUse : mu* -# 25| v0_16(Void) = ExitFunction : +# 25| v0_16(Void) = AliasedUse : ~mu0_2 +# 25| v0_17(Void) = ExitFunction : # 29| System.Void DerivedClass.Main() # 29| Block 0 @@ -398,7 +408,8 @@ constructor_init.cs: # 33| mu0_23(DerivedClass) = Store : &:r0_16, r0_17 # 29| v0_24(Void) = ReturnVoid : # 29| v0_25(Void) = UnmodeledUse : mu* -# 29| v0_26(Void) = ExitFunction : +# 29| v0_26(Void) = AliasedUse : ~mu0_2 +# 29| v0_27(Void) = ExitFunction : crement.cs: # 3| System.Void CrementOpsTest.Main() @@ -439,7 +450,8 @@ crement.cs: # 9| mu0_33(Int32) = Store : &:r0_32, r0_28 # 3| v0_34(Void) = ReturnVoid : # 3| v0_35(Void) = UnmodeledUse : mu* -# 3| v0_36(Void) = ExitFunction : +# 3| v0_36(Void) = AliasedUse : ~mu0_2 +# 3| v0_37(Void) = ExitFunction : delegates.cs: # 6| System.Int32 Delegates.returns(System.Int32) @@ -456,7 +468,8 @@ delegates.cs: # 6| r0_9(glval) = VariableAddress[#return] : # 6| v0_10(Void) = ReturnValue : &:r0_9, ~mu0_2 # 6| v0_11(Void) = UnmodeledUse : mu* -# 6| v0_12(Void) = ExitFunction : +# 6| v0_12(Void) = AliasedUse : ~mu0_2 +# 6| v0_13(Void) = ExitFunction : # 11| System.Void Delegates.Main() # 11| Block 0 @@ -478,7 +491,8 @@ delegates.cs: # 13| mu0_15() = ^CallSideEffect : ~mu0_2 # 11| v0_16(Void) = ReturnVoid : # 11| v0_17(Void) = UnmodeledUse : mu* -# 11| v0_18(Void) = ExitFunction : +# 11| v0_18(Void) = AliasedUse : ~mu0_2 +# 11| v0_19(Void) = ExitFunction : events.cs: # 8| System.Void Events..ctor() @@ -497,7 +511,8 @@ events.cs: # 10| mu0_11(MyDel) = Store : &:r0_10, r0_4 # 8| v0_12(Void) = ReturnVoid : # 8| v0_13(Void) = UnmodeledUse : mu* -# 8| v0_14(Void) = ExitFunction : +# 8| v0_14(Void) = AliasedUse : ~mu0_2 +# 8| v0_15(Void) = ExitFunction : # 13| System.Void Events.AddEvent() # 13| Block 0 @@ -514,7 +529,8 @@ events.cs: # 15| mu0_10() = ^CallSideEffect : ~mu0_2 # 13| v0_11(Void) = ReturnVoid : # 13| v0_12(Void) = UnmodeledUse : mu* -# 13| v0_13(Void) = ExitFunction : +# 13| v0_13(Void) = AliasedUse : ~mu0_2 +# 13| v0_14(Void) = ExitFunction : # 18| System.Void Events.RemoveEvent() # 18| Block 0 @@ -531,7 +547,8 @@ events.cs: # 20| mu0_10() = ^CallSideEffect : ~mu0_2 # 18| v0_11(Void) = ReturnVoid : # 18| v0_12(Void) = UnmodeledUse : mu* -# 18| v0_13(Void) = ExitFunction : +# 18| v0_13(Void) = AliasedUse : ~mu0_2 +# 18| v0_14(Void) = ExitFunction : # 23| System.String Events.Fun(System.String) # 23| Block 0 @@ -548,7 +565,8 @@ events.cs: # 23| r0_10(glval) = VariableAddress[#return] : # 23| v0_11(Void) = ReturnValue : &:r0_10, ~mu0_2 # 23| v0_12(Void) = UnmodeledUse : mu* -# 23| v0_13(Void) = ExitFunction : +# 23| v0_13(Void) = AliasedUse : ~mu0_2 +# 23| v0_14(Void) = ExitFunction : # 28| System.Void Events.Main(System.String[]) # 28| Block 0 @@ -583,7 +601,8 @@ events.cs: # 33| mu0_28() = ^CallSideEffect : ~mu0_2 # 28| v0_29(Void) = ReturnVoid : # 28| v0_30(Void) = UnmodeledUse : mu* -# 28| v0_31(Void) = ExitFunction : +# 28| v0_31(Void) = AliasedUse : ~mu0_2 +# 28| v0_32(Void) = ExitFunction : foreach.cs: # 4| System.Void ForEach.Main() @@ -662,7 +681,8 @@ foreach.cs: # 7| mu3_4() = ^CallSideEffect : ~mu0_2 # 4| v3_5(Void) = ReturnVoid : # 4| v3_6(Void) = UnmodeledUse : mu* -# 4| v3_7(Void) = ExitFunction : +# 4| v3_7(Void) = AliasedUse : ~mu0_2 +# 4| v3_8(Void) = ExitFunction : func_with_param_call.cs: # 5| System.Int32 test_call_with_param.f(System.Int32,System.Int32) @@ -684,7 +704,8 @@ func_with_param_call.cs: # 5| r0_14(glval) = VariableAddress[#return] : # 5| v0_15(Void) = ReturnValue : &:r0_14, ~mu0_2 # 5| v0_16(Void) = UnmodeledUse : mu* -# 5| v0_17(Void) = ExitFunction : +# 5| v0_17(Void) = AliasedUse : ~mu0_2 +# 5| v0_18(Void) = ExitFunction : # 10| System.Int32 test_call_with_param.g() # 10| Block 0 @@ -701,7 +722,8 @@ func_with_param_call.cs: # 10| r0_10(glval) = VariableAddress[#return] : # 10| v0_11(Void) = ReturnValue : &:r0_10, ~mu0_2 # 10| v0_12(Void) = UnmodeledUse : mu* -# 10| v0_13(Void) = ExitFunction : +# 10| v0_13(Void) = AliasedUse : ~mu0_2 +# 10| v0_14(Void) = ExitFunction : indexers.cs: # 8| System.String Indexers.MyClass.get_Item(System.Int32) @@ -724,7 +746,8 @@ indexers.cs: # 8| r0_15(glval) = VariableAddress[#return] : # 8| v0_16(Void) = ReturnValue : &:r0_15, ~mu0_2 # 8| v0_17(Void) = UnmodeledUse : mu* -# 8| v0_18(Void) = ExitFunction : +# 8| v0_18(Void) = AliasedUse : ~mu0_2 +# 8| v0_19(Void) = ExitFunction : # 12| System.Void Indexers.MyClass.set_Item(System.Int32,System.String) # 12| Block 0 @@ -747,7 +770,8 @@ indexers.cs: # 14| mu0_16(String) = Store : &:r0_15, r0_9 # 12| v0_17(Void) = ReturnVoid : # 12| v0_18(Void) = UnmodeledUse : mu* -# 12| v0_19(Void) = ExitFunction : +# 12| v0_19(Void) = AliasedUse : ~mu0_2 +# 12| v0_20(Void) = ExitFunction : # 19| System.Void Indexers.Main() # 19| Block 0 @@ -788,7 +812,8 @@ indexers.cs: # 24| mu0_34() = ^CallSideEffect : ~mu0_2 # 19| v0_35(Void) = ReturnVoid : # 19| v0_36(Void) = UnmodeledUse : mu* -# 19| v0_37(Void) = ExitFunction : +# 19| v0_37(Void) = AliasedUse : ~mu0_2 +# 19| v0_38(Void) = ExitFunction : inheritance_polymorphism.cs: # 3| System.Int32 A.function() @@ -803,7 +828,8 @@ inheritance_polymorphism.cs: # 3| r0_7(glval) = VariableAddress[#return] : # 3| v0_8(Void) = ReturnValue : &:r0_7, ~mu0_2 # 3| v0_9(Void) = UnmodeledUse : mu* -# 3| v0_10(Void) = ExitFunction : +# 3| v0_10(Void) = AliasedUse : ~mu0_2 +# 3| v0_11(Void) = ExitFunction : # 15| System.Int32 C.function() # 15| Block 0 @@ -817,7 +843,8 @@ inheritance_polymorphism.cs: # 15| r0_7(glval) = VariableAddress[#return] : # 15| v0_8(Void) = ReturnValue : &:r0_7, ~mu0_2 # 15| v0_9(Void) = UnmodeledUse : mu* -# 15| v0_10(Void) = ExitFunction : +# 15| v0_10(Void) = AliasedUse : ~mu0_2 +# 15| v0_11(Void) = ExitFunction : # 23| System.Void Program.Main() # 23| Block 0 @@ -861,7 +888,8 @@ inheritance_polymorphism.cs: # 34| mu0_37() = ^CallSideEffect : ~mu0_2 # 23| v0_38(Void) = ReturnVoid : # 23| v0_39(Void) = UnmodeledUse : mu* -# 23| v0_40(Void) = ExitFunction : +# 23| v0_40(Void) = AliasedUse : ~mu0_2 +# 23| v0_41(Void) = ExitFunction : inoutref.cs: # 11| System.Void InOutRef.set(MyClass,MyClass) @@ -880,7 +908,8 @@ inoutref.cs: # 13| mu0_11(MyClass) = Store : &:r0_10, r0_8 # 11| v0_12(Void) = ReturnVoid : # 11| v0_13(Void) = UnmodeledUse : mu* -# 11| v0_14(Void) = ExitFunction : +# 11| v0_14(Void) = AliasedUse : ~mu0_2 +# 11| v0_15(Void) = ExitFunction : # 16| System.Void InOutRef.F(System.Int32,MyStruct,MyStruct,MyClass,MyClass) # 16| Block 0 @@ -939,7 +968,8 @@ inoutref.cs: # 26| mu0_52() = ^CallSideEffect : ~mu0_2 # 16| v0_53(Void) = ReturnVoid : # 16| v0_54(Void) = UnmodeledUse : mu* -# 16| v0_55(Void) = ExitFunction : +# 16| v0_55(Void) = AliasedUse : ~mu0_2 +# 16| v0_56(Void) = ExitFunction : # 29| System.Void InOutRef.Main() # 29| Block 0 @@ -977,7 +1007,8 @@ inoutref.cs: # 36| mu0_31(Int32) = Store : &:r0_27, r0_30 # 29| v0_32(Void) = ReturnVoid : # 29| v0_33(Void) = UnmodeledUse : mu* -# 29| v0_34(Void) = ExitFunction : +# 29| v0_34(Void) = AliasedUse : ~mu0_2 +# 29| v0_35(Void) = ExitFunction : isexpr.cs: # 8| System.Void IsExpr.Main() @@ -1008,7 +1039,8 @@ isexpr.cs: # 8| Block 1 # 8| v1_0(Void) = ReturnVoid : # 8| v1_1(Void) = UnmodeledUse : mu* -# 8| v1_2(Void) = ExitFunction : +# 8| v1_2(Void) = AliasedUse : ~mu0_2 +# 8| v1_3(Void) = ExitFunction : # 13| Block 2 # 13| v2_0(Void) = ConditionalBranch : r0_18 @@ -1214,7 +1246,8 @@ jumps.cs: # 38| mu22_4() = ^CallSideEffect : ~mu0_2 # 5| v22_5(Void) = ReturnVoid : # 5| v22_6(Void) = UnmodeledUse : mu* -# 5| v22_7(Void) = ExitFunction : +# 5| v22_7(Void) = AliasedUse : ~mu0_2 +# 5| v22_8(Void) = ExitFunction : lock.cs: # 5| System.Void LockTest.A() @@ -1258,7 +1291,8 @@ lock.cs: # 5| Block 1 # 5| v1_0(Void) = ReturnVoid : # 5| v1_1(Void) = UnmodeledUse : mu* -# 5| v1_2(Void) = ExitFunction : +# 5| v1_2(Void) = AliasedUse : ~mu0_2 +# 5| v1_3(Void) = ExitFunction : # 8| Block 2 # 8| r2_0() = FunctionAddress[Exit] : @@ -1278,7 +1312,8 @@ obj_creation.cs: # 8| v0_4(Void) = NoOp : # 7| v0_5(Void) = ReturnVoid : # 7| v0_6(Void) = UnmodeledUse : mu* -# 7| v0_7(Void) = ExitFunction : +# 7| v0_7(Void) = AliasedUse : ~mu0_2 +# 7| v0_8(Void) = ExitFunction : # 11| System.Void ObjCreation.MyClass..ctor(System.Int32) # 11| Block 0 @@ -1295,7 +1330,8 @@ obj_creation.cs: # 13| mu0_10(Int32) = Store : &:r0_9, r0_7 # 11| v0_11(Void) = ReturnVoid : # 11| v0_12(Void) = UnmodeledUse : mu* -# 11| v0_13(Void) = ExitFunction : +# 11| v0_13(Void) = AliasedUse : ~mu0_2 +# 11| v0_14(Void) = ExitFunction : # 17| System.Void ObjCreation.SomeFun(ObjCreation.MyClass) # 17| Block 0 @@ -1307,7 +1343,8 @@ obj_creation.cs: # 18| v0_5(Void) = NoOp : # 17| v0_6(Void) = ReturnVoid : # 17| v0_7(Void) = UnmodeledUse : mu* -# 17| v0_8(Void) = ExitFunction : +# 17| v0_8(Void) = AliasedUse : ~mu0_2 +# 17| v0_9(Void) = ExitFunction : # 21| System.Void ObjCreation.Main() # 21| Block 0 @@ -1346,7 +1383,8 @@ obj_creation.cs: # 27| mu0_32() = ^CallSideEffect : ~mu0_2 # 21| v0_33(Void) = ReturnVoid : # 21| v0_34(Void) = UnmodeledUse : mu* -# 21| v0_35(Void) = ExitFunction : +# 21| v0_35(Void) = AliasedUse : ~mu0_2 +# 21| v0_36(Void) = ExitFunction : pointers.cs: # 3| System.Void Pointers.addone(System.Int32[]) @@ -1380,7 +1418,8 @@ pointers.cs: # 3| Block 1 # 3| v1_0(Void) = ReturnVoid : # 3| v1_1(Void) = UnmodeledUse : mu* -# 3| v1_2(Void) = ExitFunction : +# 3| v1_2(Void) = AliasedUse : ~mu0_2 +# 3| v1_3(Void) = ExitFunction : # 9| Block 2 # 9| r2_0(glval) = VariableAddress[i] : @@ -1475,7 +1514,8 @@ pointers.cs: # 40| mu0_61() = ^CallSideEffect : ~mu0_2 # 25| v0_62(Void) = ReturnVoid : # 25| v0_63(Void) = UnmodeledUse : mu* -# 25| v0_64(Void) = ExitFunction : +# 25| v0_64(Void) = AliasedUse : ~mu0_2 +# 25| v0_65(Void) = ExitFunction : prop.cs: # 7| System.Int32 PropClass.get_Prop() @@ -1493,7 +1533,8 @@ prop.cs: # 7| r0_10(glval) = VariableAddress[#return] : # 7| v0_11(Void) = ReturnValue : &:r0_10, ~mu0_2 # 7| v0_12(Void) = UnmodeledUse : mu* -# 7| v0_13(Void) = ExitFunction : +# 7| v0_13(Void) = AliasedUse : ~mu0_2 +# 7| v0_14(Void) = ExitFunction : # 12| System.Void PropClass.set_Prop(System.Int32) # 12| Block 0 @@ -1509,7 +1550,8 @@ prop.cs: # 14| mu0_9(Int32) = Store : &:r0_8, r0_7 # 12| v0_10(Void) = ReturnVoid : # 12| v0_11(Void) = UnmodeledUse : mu* -# 12| v0_12(Void) = ExitFunction : +# 12| v0_12(Void) = AliasedUse : ~mu0_2 +# 12| v0_13(Void) = ExitFunction : # 18| System.Int32 PropClass.func() # 18| Block 0 @@ -1523,7 +1565,8 @@ prop.cs: # 18| r0_7(glval) = VariableAddress[#return] : # 18| v0_8(Void) = ReturnValue : &:r0_7, ~mu0_2 # 18| v0_9(Void) = UnmodeledUse : mu* -# 18| v0_10(Void) = ExitFunction : +# 18| v0_10(Void) = AliasedUse : ~mu0_2 +# 18| v0_11(Void) = ExitFunction : # 26| System.Void Prog.Main() # 26| Block 0 @@ -1551,7 +1594,8 @@ prop.cs: # 30| mu0_21(Int32) = Store : &:r0_15, r0_19 # 26| v0_22(Void) = ReturnVoid : # 26| v0_23(Void) = UnmodeledUse : mu* -# 26| v0_24(Void) = ExitFunction : +# 26| v0_24(Void) = AliasedUse : ~mu0_2 +# 26| v0_25(Void) = ExitFunction : simple_call.cs: # 5| System.Int32 test_simple_call.f() @@ -1565,7 +1609,8 @@ simple_call.cs: # 5| r0_6(glval) = VariableAddress[#return] : # 5| v0_7(Void) = ReturnValue : &:r0_6, ~mu0_2 # 5| v0_8(Void) = UnmodeledUse : mu* -# 5| v0_9(Void) = ExitFunction : +# 5| v0_9(Void) = AliasedUse : ~mu0_2 +# 5| v0_10(Void) = ExitFunction : # 10| System.Int32 test_simple_call.g() # 10| Block 0 @@ -1581,7 +1626,8 @@ simple_call.cs: # 10| r0_9(glval) = VariableAddress[#return] : # 10| v0_10(Void) = ReturnValue : &:r0_9, ~mu0_2 # 10| v0_11(Void) = UnmodeledUse : mu* -# 10| v0_12(Void) = ExitFunction : +# 10| v0_12(Void) = AliasedUse : ~mu0_2 +# 10| v0_13(Void) = ExitFunction : simple_function.cs: # 5| System.Int32 test_simple_function.f() @@ -1595,7 +1641,8 @@ simple_function.cs: # 5| r0_6(glval) = VariableAddress[#return] : # 5| v0_7(Void) = ReturnValue : &:r0_6, ~mu0_2 # 5| v0_8(Void) = UnmodeledUse : mu* -# 5| v0_9(Void) = ExitFunction : +# 5| v0_9(Void) = AliasedUse : ~mu0_2 +# 5| v0_10(Void) = ExitFunction : stmts.cs: # 5| System.Int32 test_stmts.ifStmt(System.Int32) @@ -1617,7 +1664,8 @@ stmts.cs: # 5| r1_0(glval) = VariableAddress[#return] : # 5| v1_1(Void) = ReturnValue : &:r1_0, ~mu0_2 # 5| v1_2(Void) = UnmodeledUse : mu* -# 5| v1_3(Void) = ExitFunction : +# 5| v1_3(Void) = AliasedUse : ~mu0_2 +# 5| v1_4(Void) = ExitFunction : # 10| Block 2 # 10| r2_0(glval) = VariableAddress[#return] : @@ -1646,7 +1694,8 @@ stmts.cs: # 13| Block 1 # 13| v1_0(Void) = ReturnVoid : # 13| v1_1(Void) = UnmodeledUse : mu* -# 13| v1_2(Void) = ExitFunction : +# 13| v1_2(Void) = AliasedUse : ~mu0_2 +# 13| v1_3(Void) = ExitFunction : # 16| Block 2 # 16| r2_0(glval) = VariableAddress[i] : @@ -1693,7 +1742,8 @@ stmts.cs: # 22| r1_0(glval) = VariableAddress[#return] : # 22| v1_1(Void) = ReturnValue : &:r1_0, ~mu0_2 # 22| v1_2(Void) = UnmodeledUse : mu* -# 22| v1_3(Void) = ExitFunction : +# 22| v1_3(Void) = AliasedUse : ~mu0_2 +# 22| v1_4(Void) = ExitFunction : # 29| Block 2 # 29| v2_0(Void) = NoOp : @@ -1750,7 +1800,8 @@ stmts.cs: # 46| Block 1 # 46| v1_0(Void) = UnmodeledUse : mu* -# 46| v1_1(Void) = ExitFunction : +# 46| v1_1(Void) = AliasedUse : ~mu0_2 +# 46| v1_2(Void) = ExitFunction : # 46| Block 2 # 46| v2_0(Void) = Unwind : @@ -1816,7 +1867,8 @@ stmts.cs: # 69| Block 1 # 69| v1_0(Void) = ReturnVoid : # 69| v1_1(Void) = UnmodeledUse : mu* -# 69| v1_2(Void) = ExitFunction : +# 69| v1_2(Void) = AliasedUse : ~mu0_2 +# 69| v1_3(Void) = ExitFunction : # 72| Block 2 # 72| r2_0(glval) = VariableAddress[i] : @@ -1893,7 +1945,8 @@ stmts.cs: # 89| Block 1 # 89| v1_0(Void) = ReturnVoid : # 89| v1_1(Void) = UnmodeledUse : mu* -# 89| v1_2(Void) = ExitFunction : +# 89| v1_2(Void) = AliasedUse : ~mu0_2 +# 89| v1_3(Void) = ExitFunction : # 94| Block 2 # 94| r2_0(glval) = VariableAddress[x] : @@ -1933,7 +1986,8 @@ stmts.cs: # 108| mu0_18(Int32) = Store : &:r0_17, r0_16 # 99| v0_19(Void) = ReturnVoid : # 99| v0_20(Void) = UnmodeledUse : mu* -# 99| v0_21(Void) = ExitFunction : +# 99| v0_21(Void) = AliasedUse : ~mu0_2 +# 99| v0_22(Void) = ExitFunction : using.cs: # 7| System.Void UsingStmt.MyDisposable..ctor() @@ -1945,7 +1999,8 @@ using.cs: # 7| v0_4(Void) = NoOp : # 7| v0_5(Void) = ReturnVoid : # 7| v0_6(Void) = UnmodeledUse : mu* -# 7| v0_7(Void) = ExitFunction : +# 7| v0_7(Void) = AliasedUse : ~mu0_2 +# 7| v0_8(Void) = ExitFunction : # 8| System.Void UsingStmt.MyDisposable.DoSomething() # 8| Block 0 @@ -1956,7 +2011,8 @@ using.cs: # 8| v0_4(Void) = NoOp : # 8| v0_5(Void) = ReturnVoid : # 8| v0_6(Void) = UnmodeledUse : mu* -# 8| v0_7(Void) = ExitFunction : +# 8| v0_7(Void) = AliasedUse : ~mu0_2 +# 8| v0_8(Void) = ExitFunction : # 9| System.Void UsingStmt.MyDisposable.Dispose() # 9| Block 0 @@ -1967,7 +2023,8 @@ using.cs: # 9| v0_4(Void) = NoOp : # 9| v0_5(Void) = ReturnVoid : # 9| v0_6(Void) = UnmodeledUse : mu* -# 9| v0_7(Void) = ExitFunction : +# 9| v0_7(Void) = AliasedUse : ~mu0_2 +# 9| v0_8(Void) = ExitFunction : # 12| System.Void UsingStmt.Main() # 12| Block 0 @@ -2009,7 +2066,8 @@ using.cs: # 26| mu0_35() = ^CallSideEffect : ~mu0_2 # 12| v0_36(Void) = ReturnVoid : # 12| v0_37(Void) = UnmodeledUse : mu* -# 12| v0_38(Void) = ExitFunction : +# 12| v0_38(Void) = AliasedUse : ~mu0_2 +# 12| v0_39(Void) = ExitFunction : variables.cs: # 5| System.Void test_variables.f() @@ -2035,4 +2093,5 @@ variables.cs: # 10| mu0_18(Int32) = Store : &:r0_15, r0_17 # 5| v0_19(Void) = ReturnVoid : # 5| v0_20(Void) = UnmodeledUse : mu* -# 5| v0_21(Void) = ExitFunction : +# 5| v0_21(Void) = AliasedUse : ~mu0_2 +# 5| v0_22(Void) = ExitFunction : diff --git a/csharp/ql/test/library-tests/ir/ir/raw_ir_sanity.expected b/csharp/ql/test/library-tests/ir/ir/raw_ir_sanity.expected index c709a73f5e3..9f132fa6f28 100644 --- a/csharp/ql/test/library-tests/ir/ir/raw_ir_sanity.expected +++ b/csharp/ql/test/library-tests/ir/ir/raw_ir_sanity.expected @@ -3,6 +3,7 @@ unexpectedOperand duplicateOperand missingPhiOperand missingOperandType +duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor ambiguousSuccessors diff --git a/csharp/ql/test/library-tests/ir/ir/unaliased_ssa_sanity.expected b/csharp/ql/test/library-tests/ir/ir/unaliased_ssa_sanity.expected index c709a73f5e3..9f132fa6f28 100644 --- a/csharp/ql/test/library-tests/ir/ir/unaliased_ssa_sanity.expected +++ b/csharp/ql/test/library-tests/ir/ir/unaliased_ssa_sanity.expected @@ -3,6 +3,7 @@ unexpectedOperand duplicateOperand missingPhiOperand missingOperandType +duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor ambiguousSuccessors diff --git a/csharp/ql/test/library-tests/unification/Unification.cs b/csharp/ql/test/library-tests/unification/Unification.cs new file mode 100644 index 00000000000..38c069599d4 --- /dev/null +++ b/csharp/ql/test/library-tests/unification/Unification.cs @@ -0,0 +1,33 @@ +interface I1 { } + +struct S1 { } struct S2 { } + +class C0 { } +class C1 { } +class C2 : C1, I1 where T2 : struct { } +class C3 where T3 : class { } +class C4 where T4 : C1 { } +class C5 where T5 : C1, I1 { } +class C6 where T6a : C1 where T6b : T6a, I1 where T6c : C3 where T6d : struct { } + +class ConstructSomeTypes +{ + C1 f1; + C2 f2; + C3> f3; + C3> f4; + C4> f5; + C5> f6; + C6, C2, C3>, S1> f7; + + void M(C6, Tm, C3, S2> x, C6, C2, C3>, S2> y) where Tm : C2 { } +} + +class Tuples +{ + static (T8, int) t1; + static (string, int) t2; + static (string, T9) t3; + static (T8, T9) t4; + static (T8 a, T9 b) t5 = t4; +} diff --git a/csharp/ql/test/library-tests/unification/Unification.expected b/csharp/ql/test/library-tests/unification/Unification.expected new file mode 100644 index 00000000000..6c173661a19 --- /dev/null +++ b/csharp/ql/test/library-tests/unification/Unification.expected @@ -0,0 +1,298 @@ +constrainedTypeParameterSubsumes +| Unification.cs:7:10:7:11 | T2 | Unification.cs:3:8:3:9 | S1 | +| Unification.cs:7:10:7:11 | T2 | Unification.cs:3:22:3:23 | S2 | +| Unification.cs:7:10:7:11 | T2 | Unification.cs:7:10:7:11 | T2 | +| Unification.cs:7:10:7:11 | T2 | Unification.cs:11:25:11:27 | T6d | +| Unification.cs:7:10:7:11 | T2 | Unification.cs:28:12:28:20 | (T8,Int32) | +| Unification.cs:7:10:7:11 | T2 | Unification.cs:29:12:29:24 | (String,Int32) | +| Unification.cs:7:10:7:11 | T2 | Unification.cs:30:12:30:23 | (String,T9) | +| Unification.cs:7:10:7:11 | T2 | Unification.cs:31:12:31:19 | (T8,T9) | +| Unification.cs:7:10:7:11 | T2 | Unification.cs:32:12:32:23 | (T8,T9) | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:1:11:1:12 | I1 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:5:7:5:8 | C0 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1<> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:7:7:7:12 | C2<> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:7:7:7:12 | C2 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:7:7:7:12 | C2 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3<> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:10:8:11 | T3 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:9:7:9:12 | C4<> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:9:7:9:12 | C4> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:9:10:9:11 | T4 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:10:7:10:12 | C5<> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:10:7:10:12 | C5> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:10:10:10:11 | T5 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:7:11:28 | C6<,,,> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:7:11:28 | C6,C2,C3>,S1> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:7:11:28 | C6,C2,C3>,S2> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:7:11:28 | C6,Tm,C3,S2> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:10:11:12 | T6a | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:15:11:17 | T6b | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:20:11:22 | T6c | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:13:7:13:24 | ConstructSomeTypes | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:23:12:23:13 | Tm | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:26:7:26:20 | Tuples<,> | +| Unification.cs:9:10:9:11 | T4 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:9:10:9:11 | T4 | Unification.cs:9:10:9:11 | T4 | +| Unification.cs:10:10:10:11 | T5 | Unification.cs:7:7:7:12 | C2 | +| Unification.cs:10:10:10:11 | T5 | Unification.cs:10:10:10:11 | T5 | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1<> | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:7:7:7:12 | C2<> | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:7:7:7:12 | C2 | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:7:7:7:12 | C2 | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:9:10:9:11 | T4 | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:10:10:10:11 | T5 | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:11:10:11:12 | T6a | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:11:15:11:17 | T6b | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:23:12:23:13 | Tm | +| Unification.cs:11:15:11:17 | T6b | Unification.cs:7:7:7:12 | C2<> | +| Unification.cs:11:15:11:17 | T6b | Unification.cs:7:7:7:12 | C2 | +| Unification.cs:11:15:11:17 | T6b | Unification.cs:7:7:7:12 | C2 | +| Unification.cs:11:15:11:17 | T6b | Unification.cs:10:10:10:11 | T5 | +| Unification.cs:11:15:11:17 | T6b | Unification.cs:11:15:11:17 | T6b | +| Unification.cs:11:15:11:17 | T6b | Unification.cs:23:12:23:13 | Tm | +| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3<> | +| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3 | +| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3 | +| Unification.cs:11:20:11:22 | T6c | Unification.cs:11:20:11:22 | T6c | +| Unification.cs:11:25:11:27 | T6d | Unification.cs:3:8:3:9 | S1 | +| Unification.cs:11:25:11:27 | T6d | Unification.cs:3:22:3:23 | S2 | +| Unification.cs:11:25:11:27 | T6d | Unification.cs:7:10:7:11 | T2 | +| Unification.cs:11:25:11:27 | T6d | Unification.cs:11:25:11:27 | T6d | +| Unification.cs:11:25:11:27 | T6d | Unification.cs:28:12:28:20 | (T8,Int32) | +| Unification.cs:11:25:11:27 | T6d | Unification.cs:29:12:29:24 | (String,Int32) | +| Unification.cs:11:25:11:27 | T6d | Unification.cs:30:12:30:23 | (String,T9) | +| Unification.cs:11:25:11:27 | T6d | Unification.cs:31:12:31:19 | (T8,T9) | +| Unification.cs:11:25:11:27 | T6d | Unification.cs:32:12:32:23 | (T8,T9) | +| Unification.cs:23:12:23:13 | Tm | Unification.cs:7:7:7:12 | C2 | +| Unification.cs:23:12:23:13 | Tm | Unification.cs:23:12:23:13 | Tm | +constrainedTypeParameterSubsumptionImpliesUnification +constrainedTypeParameterUnifiable +| Unification.cs:7:10:7:11 | T2 | Unification.cs:3:8:3:9 | S1 | +| Unification.cs:7:10:7:11 | T2 | Unification.cs:3:22:3:23 | S2 | +| Unification.cs:7:10:7:11 | T2 | Unification.cs:7:10:7:11 | T2 | +| Unification.cs:7:10:7:11 | T2 | Unification.cs:11:25:11:27 | T6d | +| Unification.cs:7:10:7:11 | T2 | Unification.cs:28:12:28:20 | (T8,Int32) | +| Unification.cs:7:10:7:11 | T2 | Unification.cs:29:12:29:24 | (String,Int32) | +| Unification.cs:7:10:7:11 | T2 | Unification.cs:30:12:30:23 | (String,T9) | +| Unification.cs:7:10:7:11 | T2 | Unification.cs:31:12:31:19 | (T8,T9) | +| Unification.cs:7:10:7:11 | T2 | Unification.cs:32:12:32:23 | (T8,T9) | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:1:11:1:12 | I1 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:5:7:5:8 | C0 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1<> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:7:7:7:12 | C2<> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:7:7:7:12 | C2 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:7:7:7:12 | C2 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3<> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:7:8:12 | C3 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:8:10:8:11 | T3 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:9:7:9:12 | C4<> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:9:7:9:12 | C4> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:9:10:9:11 | T4 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:10:7:10:12 | C5<> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:10:7:10:12 | C5> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:10:10:10:11 | T5 | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:7:11:28 | C6<,,,> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:7:11:28 | C6,C2,C3>,S1> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:7:11:28 | C6,C2,C3>,S2> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:7:11:28 | C6,Tm,C3,S2> | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:10:11:12 | T6a | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:15:11:17 | T6b | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:11:20:11:22 | T6c | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:13:7:13:24 | ConstructSomeTypes | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:23:12:23:13 | Tm | +| Unification.cs:8:10:8:11 | T3 | Unification.cs:26:7:26:20 | Tuples<,> | +| Unification.cs:9:10:9:11 | T4 | Unification.cs:6:7:6:12 | C1<> | +| Unification.cs:9:10:9:11 | T4 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:9:10:9:11 | T4 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:9:10:9:11 | T4 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:9:10:9:11 | T4 | Unification.cs:7:7:7:12 | C2<> | +| Unification.cs:9:10:9:11 | T4 | Unification.cs:9:10:9:11 | T4 | +| Unification.cs:9:10:9:11 | T4 | Unification.cs:11:10:11:12 | T6a | +| Unification.cs:9:10:9:11 | T4 | Unification.cs:11:15:11:17 | T6b | +| Unification.cs:10:10:10:11 | T5 | Unification.cs:7:7:7:12 | C2<> | +| Unification.cs:10:10:10:11 | T5 | Unification.cs:7:7:7:12 | C2 | +| Unification.cs:10:10:10:11 | T5 | Unification.cs:10:10:10:11 | T5 | +| Unification.cs:10:10:10:11 | T5 | Unification.cs:11:15:11:17 | T6b | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1<> | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:7:7:7:12 | C2<> | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:7:7:7:12 | C2 | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:7:7:7:12 | C2 | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:9:10:9:11 | T4 | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:10:10:10:11 | T5 | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:11:10:11:12 | T6a | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:11:15:11:17 | T6b | +| Unification.cs:11:10:11:12 | T6a | Unification.cs:23:12:23:13 | Tm | +| Unification.cs:11:15:11:17 | T6b | Unification.cs:7:7:7:12 | C2<> | +| Unification.cs:11:15:11:17 | T6b | Unification.cs:7:7:7:12 | C2 | +| Unification.cs:11:15:11:17 | T6b | Unification.cs:7:7:7:12 | C2 | +| Unification.cs:11:15:11:17 | T6b | Unification.cs:10:10:10:11 | T5 | +| Unification.cs:11:15:11:17 | T6b | Unification.cs:11:15:11:17 | T6b | +| Unification.cs:11:15:11:17 | T6b | Unification.cs:23:12:23:13 | Tm | +| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3<> | +| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3 | +| Unification.cs:11:20:11:22 | T6c | Unification.cs:8:7:8:12 | C3 | +| Unification.cs:11:20:11:22 | T6c | Unification.cs:11:20:11:22 | T6c | +| Unification.cs:11:25:11:27 | T6d | Unification.cs:3:8:3:9 | S1 | +| Unification.cs:11:25:11:27 | T6d | Unification.cs:3:22:3:23 | S2 | +| Unification.cs:11:25:11:27 | T6d | Unification.cs:7:10:7:11 | T2 | +| Unification.cs:11:25:11:27 | T6d | Unification.cs:11:25:11:27 | T6d | +| Unification.cs:11:25:11:27 | T6d | Unification.cs:28:12:28:20 | (T8,Int32) | +| Unification.cs:11:25:11:27 | T6d | Unification.cs:29:12:29:24 | (String,Int32) | +| Unification.cs:11:25:11:27 | T6d | Unification.cs:30:12:30:23 | (String,T9) | +| Unification.cs:11:25:11:27 | T6d | Unification.cs:31:12:31:19 | (T8,T9) | +| Unification.cs:11:25:11:27 | T6d | Unification.cs:32:12:32:23 | (T8,T9) | +| Unification.cs:23:12:23:13 | Tm | Unification.cs:7:7:7:12 | C2<> | +| Unification.cs:23:12:23:13 | Tm | Unification.cs:7:7:7:12 | C2 | +| Unification.cs:23:12:23:13 | Tm | Unification.cs:23:12:23:13 | Tm | +subsumes +| Unification.cs:6:7:6:12 | C1<> | Unification.cs:6:7:6:12 | C1<> | +| Unification.cs:6:7:6:12 | C1<> | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1<> | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1<> | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1<> | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1<> | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1<> | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1<> | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:7:7:7:12 | C2<> | Unification.cs:7:7:7:12 | C2<> | +| Unification.cs:7:7:7:12 | C2<> | Unification.cs:7:7:7:12 | C2 | +| Unification.cs:7:7:7:12 | C2<> | Unification.cs:7:7:7:12 | C2 | +| Unification.cs:7:7:7:12 | C2 | Unification.cs:7:7:7:12 | C2 | +| Unification.cs:7:7:7:12 | C2 | Unification.cs:7:7:7:12 | C2 | +| Unification.cs:8:7:8:12 | C3<> | Unification.cs:8:7:8:12 | C3<> | +| Unification.cs:8:7:8:12 | C3<> | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:8:7:8:12 | C3<> | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:8:7:8:12 | C3<> | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:8:7:8:12 | C3<> | Unification.cs:8:7:8:12 | C3 | +| Unification.cs:8:7:8:12 | C3<> | Unification.cs:8:7:8:12 | C3 | +| Unification.cs:8:7:8:12 | C3> | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:8:7:8:12 | C3> | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:8:7:8:12 | C3> | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:8:7:8:12 | C3 | Unification.cs:8:7:8:12 | C3<> | +| Unification.cs:8:7:8:12 | C3 | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:8:7:8:12 | C3 | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:8:7:8:12 | C3 | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:8:7:8:12 | C3 | Unification.cs:8:7:8:12 | C3 | +| Unification.cs:8:7:8:12 | C3 | Unification.cs:8:7:8:12 | C3 | +| Unification.cs:8:7:8:12 | C3 | Unification.cs:8:7:8:12 | C3<> | +| Unification.cs:8:7:8:12 | C3 | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:8:7:8:12 | C3 | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:8:7:8:12 | C3 | Unification.cs:8:7:8:12 | C3> | +| Unification.cs:8:7:8:12 | C3 | Unification.cs:8:7:8:12 | C3 | +| Unification.cs:8:7:8:12 | C3 | Unification.cs:8:7:8:12 | C3 | +| Unification.cs:9:7:9:12 | C4<> | Unification.cs:9:7:9:12 | C4<> | +| Unification.cs:9:7:9:12 | C4<> | Unification.cs:9:7:9:12 | C4> | +| Unification.cs:9:7:9:12 | C4> | Unification.cs:9:7:9:12 | C4> | +| Unification.cs:10:7:10:12 | C5<> | Unification.cs:10:7:10:12 | C5<> | +| Unification.cs:10:7:10:12 | C5<> | Unification.cs:10:7:10:12 | C5> | +| Unification.cs:10:7:10:12 | C5> | Unification.cs:10:7:10:12 | C5> | +| Unification.cs:11:7:11:28 | C6<,,,> | Unification.cs:11:7:11:28 | C6<,,,> | +| Unification.cs:11:7:11:28 | C6<,,,> | Unification.cs:11:7:11:28 | C6,C2,C3>,S1> | +| Unification.cs:11:7:11:28 | C6<,,,> | Unification.cs:11:7:11:28 | C6,C2,C3>,S2> | +| Unification.cs:11:7:11:28 | C6<,,,> | Unification.cs:11:7:11:28 | C6,Tm,C3,S2> | +| Unification.cs:11:7:11:28 | C6,C2,C3>,S1> | Unification.cs:11:7:11:28 | C6,C2,C3>,S1> | +| Unification.cs:11:7:11:28 | C6,C2,C3>,S2> | Unification.cs:11:7:11:28 | C6,C2,C3>,S2> | +| Unification.cs:11:7:11:28 | C6,Tm,C3,S2> | Unification.cs:11:7:11:28 | C6,C2,C3>,S2> | +| Unification.cs:11:7:11:28 | C6,Tm,C3,S2> | Unification.cs:11:7:11:28 | C6,Tm,C3,S2> | +| Unification.cs:26:7:26:20 | Tuples<,> | Unification.cs:26:7:26:20 | Tuples<,> | +| Unification.cs:28:12:28:20 | (T8,Int32) | Unification.cs:28:12:28:20 | (T8,Int32) | +| Unification.cs:28:12:28:20 | (T8,Int32) | Unification.cs:29:12:29:24 | (String,Int32) | +| Unification.cs:29:12:29:24 | (String,Int32) | Unification.cs:29:12:29:24 | (String,Int32) | +| Unification.cs:30:12:30:23 | (String,T9) | Unification.cs:29:12:29:24 | (String,Int32) | +| Unification.cs:30:12:30:23 | (String,T9) | Unification.cs:30:12:30:23 | (String,T9) | +| Unification.cs:31:12:31:19 | (T8,T9) | Unification.cs:28:12:28:20 | (T8,Int32) | +| Unification.cs:31:12:31:19 | (T8,T9) | Unification.cs:29:12:29:24 | (String,Int32) | +| Unification.cs:31:12:31:19 | (T8,T9) | Unification.cs:30:12:30:23 | (String,T9) | +| Unification.cs:31:12:31:19 | (T8,T9) | Unification.cs:31:12:31:19 | (T8,T9) | +| Unification.cs:31:12:31:19 | (T8,T9) | Unification.cs:32:12:32:23 | (T8,T9) | +| Unification.cs:32:12:32:23 | (T8,T9) | Unification.cs:28:12:28:20 | (T8,Int32) | +| Unification.cs:32:12:32:23 | (T8,T9) | Unification.cs:29:12:29:24 | (String,Int32) | +| Unification.cs:32:12:32:23 | (T8,T9) | Unification.cs:30:12:30:23 | (String,T9) | +| Unification.cs:32:12:32:23 | (T8,T9) | Unification.cs:31:12:31:19 | (T8,T9) | +| Unification.cs:32:12:32:23 | (T8,T9) | Unification.cs:32:12:32:23 | (T8,T9) | +subsumptionImpliesUnification +unifiable +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1<> | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1<> | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1<> | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:6:7:6:12 | C1 | Unification.cs:6:7:6:12 | C1 | +| Unification.cs:7:7:7:12 | C2 | Unification.cs:7:7:7:12 | C2<> | +| Unification.cs:7:7:7:12 | C2 | Unification.cs:7:7:7:12 | C2<> | +| Unification.cs:8:7:8:12 | C3> | Unification.cs:8:7:8:12 | C3<> | +| Unification.cs:8:7:8:12 | C3> | Unification.cs:8:7:8:12 | C3 | +| Unification.cs:8:7:8:12 | C3> | Unification.cs:8:7:8:12 | C3 | +| Unification.cs:8:7:8:12 | C3> | Unification.cs:8:7:8:12 | C3<> | +| Unification.cs:8:7:8:12 | C3> | Unification.cs:8:7:8:12 | C3 | +| Unification.cs:8:7:8:12 | C3> | Unification.cs:8:7:8:12 | C3 | +| Unification.cs:8:7:8:12 | C3> | Unification.cs:8:7:8:12 | C3<> | +| Unification.cs:8:7:8:12 | C3> | Unification.cs:8:7:8:12 | C3 | +| Unification.cs:8:7:8:12 | C3> | Unification.cs:8:7:8:12 | C3 | +| Unification.cs:9:7:9:12 | C4> | Unification.cs:9:7:9:12 | C4<> | +| Unification.cs:10:7:10:12 | C5> | Unification.cs:10:7:10:12 | C5<> | +| Unification.cs:11:7:11:28 | C6,C2,C3>,S1> | Unification.cs:11:7:11:28 | C6<,,,> | +| Unification.cs:11:7:11:28 | C6,C2,C3>,S2> | Unification.cs:11:7:11:28 | C6<,,,> | +| Unification.cs:11:7:11:28 | C6,C2,C3>,S2> | Unification.cs:11:7:11:28 | C6,Tm,C3,S2> | +| Unification.cs:11:7:11:28 | C6,Tm,C3,S2> | Unification.cs:11:7:11:28 | C6<,,,> | +| Unification.cs:28:12:28:20 | (T8,Int32) | Unification.cs:30:12:30:23 | (String,T9) | +| Unification.cs:28:12:28:20 | (T8,Int32) | Unification.cs:31:12:31:19 | (T8,T9) | +| Unification.cs:28:12:28:20 | (T8,Int32) | Unification.cs:32:12:32:23 | (T8,T9) | +| Unification.cs:29:12:29:24 | (String,Int32) | Unification.cs:28:12:28:20 | (T8,Int32) | +| Unification.cs:29:12:29:24 | (String,Int32) | Unification.cs:30:12:30:23 | (String,T9) | +| Unification.cs:29:12:29:24 | (String,Int32) | Unification.cs:31:12:31:19 | (T8,T9) | +| Unification.cs:29:12:29:24 | (String,Int32) | Unification.cs:32:12:32:23 | (T8,T9) | +| Unification.cs:30:12:30:23 | (String,T9) | Unification.cs:28:12:28:20 | (T8,Int32) | +| Unification.cs:30:12:30:23 | (String,T9) | Unification.cs:31:12:31:19 | (T8,T9) | +| Unification.cs:30:12:30:23 | (String,T9) | Unification.cs:32:12:32:23 | (T8,T9) | diff --git a/csharp/ql/test/library-tests/unification/Unification.ql b/csharp/ql/test/library-tests/unification/Unification.ql new file mode 100644 index 00000000000..7b1dcd26b1c --- /dev/null +++ b/csharp/ql/test/library-tests/unification/Unification.ql @@ -0,0 +1,37 @@ +import semmle.code.csharp.Unification + +class InterestingType extends Type { + InterestingType() { + this.fromSource() or + this.(TupleType).getAChild() instanceof InterestingType + } +} + +query predicate constrainedTypeParameterSubsumes(InterestingType tp, InterestingType t) { + tp.(Unification::ConstrainedTypeParameter).subsumes(t) +} + +// Should be empty +query predicate constrainedTypeParameterSubsumptionImpliesUnification( + InterestingType tp, InterestingType t +) { + tp.(Unification::ConstrainedTypeParameter).subsumes(t) and + not tp.(Unification::ConstrainedTypeParameter).unifiable(t) +} + +query predicate constrainedTypeParameterUnifiable(InterestingType tp, InterestingType t) { + tp.(Unification::ConstrainedTypeParameter).unifiable(t) +} + +query predicate subsumes(InterestingType t1, InterestingType t2) { Unification::subsumes(t1, t2) } + +// Should be empty +query predicate subsumptionImpliesUnification(Type t1, Type t2) { + Unification::subsumes(t1, t2) and + not Unification::unifiable(t1, t2) +} + +query predicate unifiable(InterestingType t1, InterestingType t2) { + Unification::unifiable(t1, t2) and + not Unification::subsumes(t1, t2) +} diff --git a/csharp/ql/test/qlpack.yml b/csharp/ql/test/qlpack.yml new file mode 100644 index 00000000000..20f6e83ee30 --- /dev/null +++ b/csharp/ql/test/qlpack.yml @@ -0,0 +1,3 @@ +name: codeql-csharp-tests +version: 0.0.0 +libraryPathDependencies: codeql-csharp diff --git a/csharp/ql/test/query-tests/API Abuse/NoDisposeCallOnLocalIDisposable/NoDisposeCallOnLocalIDisposable.cs b/csharp/ql/test/query-tests/API Abuse/NoDisposeCallOnLocalIDisposable/NoDisposeCallOnLocalIDisposable.cs index 45caec0022d..82a33086144 100644 --- a/csharp/ql/test/query-tests/API Abuse/NoDisposeCallOnLocalIDisposable/NoDisposeCallOnLocalIDisposable.cs +++ b/csharp/ql/test/query-tests/API Abuse/NoDisposeCallOnLocalIDisposable/NoDisposeCallOnLocalIDisposable.cs @@ -83,6 +83,11 @@ class Test // GOOD: Disposed automatically. using var c2 = new Timer(TimerProc); + // GOOD: ownership taken via ?? + StringReader source = null; + using(XmlReader.Create(source ?? new StringReader("xml"), null)) + ; + return null; } diff --git a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/AspInline.ql b/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/AspInline.ql index 48b40897f2a..f28295c8f5e 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/AspInline.ql +++ b/csharp/ql/test/query-tests/Security Features/CWE-079/StoredXSS/AspInline.ql @@ -1,10 +1,10 @@ import csharp import semmle.code.csharp.security.dataflow.XSS -string tweakMemberLocation(XSS::AspInlineMember inline, Member member) { +string tweakMemberLocation(Member member) { exists(Location loc | loc = member.getLocation() and - if loc.getFile().getParentContainer() = inline.getLocation().getFile().getParentContainer() + if loc instanceof SourceLocation then result = loc.toString() else result = "" ) @@ -14,4 +14,4 @@ from XSS::AspInlineMember inline, Member member where member = inline.getMember() // some members, such as ASP members inherited from DLLs, are outside the test directory, // so we select them specially using a modified location and the normal toString -select inline, tweakMemberLocation(inline, member), member.toString() +select inline, tweakMemberLocation(member), member.toString() diff --git a/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserialization/ExtractorOptions.cs b/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserialization/ExtractorOptions.cs index 11f05a14a00..bd796aa9f51 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserialization/ExtractorOptions.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserialization/ExtractorOptions.cs @@ -1 +1 @@ -// semmle-extractor-options: /r:System.Runtime.Extensions.dll /r:System.IO.FileSystem.dll +// semmle-extractor-options: /r:System.Runtime.Extensions.dll /r:System.IO.FileSystem.dll /r:System.Collections.Specialized.dll ${testdir}/../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserialization/SystemWebStub.cs b/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserialization/SystemWebStub.cs deleted file mode 100644 index 48c74335f6f..00000000000 --- a/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserialization/SystemWebStub.cs +++ /dev/null @@ -1,34 +0,0 @@ -// This file contains auto-generated code. -// original-extractor-options: /r:System.Runtime.Extensions.dll /r:System.IO.FileSystem.dll - -namespace System -{ - namespace Web - { - namespace Script - { - namespace Serialization - { - // Generated from `System.Web.Script.Serialization.JavaScriptSerializer` in `System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35` - public class JavaScriptSerializer - { - public JavaScriptSerializer() => throw null; - public JavaScriptSerializer(System.Web.Script.Serialization.JavaScriptTypeResolver resolver) => throw null; - public object DeserializeObject(string input) => throw null; - } - - // Generated from `System.Web.Script.Serialization.JavaScriptTypeResolver` in `System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35` - abstract public class JavaScriptTypeResolver - { - } - - // Generated from `System.Web.Script.Serialization.SimpleTypeResolver` in `System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35` - public class SimpleTypeResolver : System.Web.Script.Serialization.JavaScriptTypeResolver - { - public SimpleTypeResolver() => throw null; - } - - } - } - } -} diff --git a/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserializationUntrustedInput/ExtractorOptions.cs b/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserializationUntrustedInput/ExtractorOptions.cs index 11f05a14a00..bd796aa9f51 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserializationUntrustedInput/ExtractorOptions.cs +++ b/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserializationUntrustedInput/ExtractorOptions.cs @@ -1 +1 @@ -// semmle-extractor-options: /r:System.Runtime.Extensions.dll /r:System.IO.FileSystem.dll +// semmle-extractor-options: /r:System.Runtime.Extensions.dll /r:System.IO.FileSystem.dll /r:System.Collections.Specialized.dll ${testdir}/../../../../resources/stubs/System.Web.cs diff --git a/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserializationUntrustedInput/SystemWebStub.cs b/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserializationUntrustedInput/SystemWebStub.cs deleted file mode 100644 index 293c0cdf355..00000000000 --- a/csharp/ql/test/query-tests/Security Features/CWE-502/UnsafeDeserializationUntrustedInput/SystemWebStub.cs +++ /dev/null @@ -1,45 +0,0 @@ -// This file contains auto-generated code. -// original-extractor-options: /r:System.Runtime.Extensions.dll /r:System.IO.FileSystem.dll - -namespace System -{ - namespace Web - { - namespace UI - { - namespace WebControls - { - public class TextBox - { - public string Text { get; set; } - } - } - } - - namespace Script - { - namespace Serialization - { - // Generated from `System.Web.Script.Serialization.JavaScriptSerializer` in `System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35` - public class JavaScriptSerializer - { - public JavaScriptSerializer() => throw null; - public JavaScriptSerializer(System.Web.Script.Serialization.JavaScriptTypeResolver resolver) => throw null; - public object DeserializeObject(string input) => throw null; - } - - // Generated from `System.Web.Script.Serialization.JavaScriptTypeResolver` in `System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35` - abstract public class JavaScriptTypeResolver - { - } - - // Generated from `System.Web.Script.Serialization.SimpleTypeResolver` in `System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35` - public class SimpleTypeResolver : System.Web.Script.Serialization.JavaScriptTypeResolver - { - public SimpleTypeResolver() => throw null; - } - - } - } - } -} diff --git a/csharp/ql/test/resources/stubs/System.Web.cs b/csharp/ql/test/resources/stubs/System.Web.cs index eb08326b794..13ebaf316d7 100644 --- a/csharp/ql/test/resources/stubs/System.Web.cs +++ b/csharp/ql/test/resources/stubs/System.Web.cs @@ -346,3 +346,25 @@ namespace System.Web.Helpers public static void Validate() { } } } + +namespace System.Web.Script.Serialization +{ + // Generated from `System.Web.Script.Serialization.JavaScriptSerializer` in `System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35` + public class JavaScriptSerializer + { + public JavaScriptSerializer() => throw null; + public JavaScriptSerializer(System.Web.Script.Serialization.JavaScriptTypeResolver resolver) => throw null; + public object DeserializeObject(string input) => throw null; + } + + // Generated from `System.Web.Script.Serialization.JavaScriptTypeResolver` in `System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35` + abstract public class JavaScriptTypeResolver + { + } + + // Generated from `System.Web.Script.Serialization.SimpleTypeResolver` in `System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35` + public class SimpleTypeResolver : System.Web.Script.Serialization.JavaScriptTypeResolver + { + public SimpleTypeResolver() => throw null; + } +} diff --git a/csharp/upgrades/qlpack.yml b/csharp/upgrades/qlpack.yml new file mode 100644 index 00000000000..8ad3718778d --- /dev/null +++ b/csharp/upgrades/qlpack.yml @@ -0,0 +1,2 @@ +name: codeql-csharp-upgrades +upgrades: . diff --git a/docs/language/global-sphinx-files/_templates/layout.html b/docs/language/global-sphinx-files/_templates/layout.html index 6aa09b5fb38..7faadbefbe8 100644 --- a/docs/language/global-sphinx-files/_templates/layout.html +++ b/docs/language/global-sphinx-files/_templates/layout.html @@ -61,9 +61,9 @@
  • OWASP: -XSS +XSS (Cross Site Scripting) Prevention Cheat Sheet.
  • diff --git a/java/ql/src/Security/CWE/CWE-089/SqlTainted.qhelp b/java/ql/src/Security/CWE/CWE-089/SqlTainted.qhelp index cab60173a62..f1ba450d4a0 100644 --- a/java/ql/src/Security/CWE/CWE-089/SqlTainted.qhelp +++ b/java/ql/src/Security/CWE/CWE-089/SqlTainted.qhelp @@ -67,7 +67,7 @@ in the environment variable or user-supplied value are not given any special tre
  • OWASP: -SQL +SQL Injection Prevention Cheat Sheet.
  • The CERT Oracle Secure Coding Standard for Java: diff --git a/java/ql/src/Security/CWE/CWE-089/SqlUnescaped.qhelp b/java/ql/src/Security/CWE/CWE-089/SqlUnescaped.qhelp index 7415235610c..e469415d683 100644 --- a/java/ql/src/Security/CWE/CWE-089/SqlUnescaped.qhelp +++ b/java/ql/src/Security/CWE/CWE-089/SqlUnescaped.qhelp @@ -39,7 +39,7 @@ treatment.

  • OWASP: -SQL +SQL Injection Prevention Cheat Sheet.
  • The CERT Oracle Secure Coding Standard for Java: diff --git a/java/ql/src/Security/CWE/CWE-319/HttpsUrls.qhelp b/java/ql/src/Security/CWE/CWE-319/HttpsUrls.qhelp index 8b8b0eff847..2cfdca624fb 100644 --- a/java/ql/src/Security/CWE/CWE-319/HttpsUrls.qhelp +++ b/java/ql/src/Security/CWE/CWE-319/HttpsUrls.qhelp @@ -37,7 +37,7 @@ connection is a secure SSL connection.

    Class HttpsURLConnection.
  • OWASP: -Transport Layer Protection Cheat Sheet. +Transport Layer Protection Cheat Sheet.
  • diff --git a/java/ql/src/Security/CWE/CWE-319/UseSSL.qhelp b/java/ql/src/Security/CWE/CWE-319/UseSSL.qhelp index 5856086330f..cec4937c8f7 100644 --- a/java/ql/src/Security/CWE/CWE-319/UseSSL.qhelp +++ b/java/ql/src/Security/CWE/CWE-319/UseSSL.qhelp @@ -38,7 +38,7 @@ Class HttpsURLConnection. Class SSLSocket.
  • OWASP: -Transport Layer Protection Cheat Sheet. +Transport Layer Protection Cheat Sheet.
  • diff --git a/java/ql/src/Security/CWE/CWE-319/UseSSLSocketFactories.qhelp b/java/ql/src/Security/CWE/CWE-319/UseSSLSocketFactories.qhelp index 56e9be97345..bf0dbc0bcac 100644 --- a/java/ql/src/Security/CWE/CWE-319/UseSSLSocketFactories.qhelp +++ b/java/ql/src/Security/CWE/CWE-319/UseSSLSocketFactories.qhelp @@ -33,7 +33,7 @@ uses explicit SSL factories, which are preferable.

    Class SSLSocketFactory.
  • OWASP: -Transport Layer Protection Cheat Sheet. +Transport Layer Protection Cheat Sheet.
  • diff --git a/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.qhelp b/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.qhelp index 4fb0ad88b45..61b50a986e3 100644 --- a/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.qhelp +++ b/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.qhelp @@ -58,7 +58,7 @@ OWASP vulnerability description:
  • OWASP guidance on deserializing objects: -Deserialization Cheat Sheet. +Deserialization Cheat Sheet.
  • Talks by Chris Frohoff & Gabriel Lawrence: diff --git a/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.ql b/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.ql index 18cf624375f..bb4df03cd4f 100644 --- a/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.ql +++ b/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.ql @@ -12,7 +12,7 @@ import java import semmle.code.java.dataflow.FlowSources -import UnsafeDeserialization +import semmle.code.java.security.UnsafeDeserialization import DataFlow::PathGraph class UnsafeDeserializationConfig extends TaintTracking::Configuration { diff --git a/java/ql/src/Security/CWE/CWE-611/XXE.qhelp b/java/ql/src/Security/CWE/CWE-611/XXE.qhelp index 75c5a2d4d7a..93d420f7495 100644 --- a/java/ql/src/Security/CWE/CWE-611/XXE.qhelp +++ b/java/ql/src/Security/CWE/CWE-611/XXE.qhelp @@ -52,7 +52,7 @@ OWASP vulnerability description:
  • OWASP guidance on parsing xml files: -XXE Prevention Cheat Sheet. +XXE Prevention Cheat Sheet.
  • Paper by Timothy Morgen: diff --git a/java/ql/src/config/semmlecode.dbscheme b/java/ql/src/config/semmlecode.dbscheme index 886aec63fb9..e7706df98aa 100755 --- a/java/ql/src/config/semmlecode.dbscheme +++ b/java/ql/src/config/semmlecode.dbscheme @@ -494,6 +494,7 @@ case @stmt.kind of | 20 = @superconstructorinvocationstmt | 21 = @case | 22 = @catchclause +| 23 = @yieldstmt ; #keyset[parent,idx] diff --git a/java/ql/src/config/semmlecode.dbscheme.stats b/java/ql/src/config/semmlecode.dbscheme.stats index 621bfff8b15..22e7ff7e830 100644 --- a/java/ql/src/config/semmlecode.dbscheme.stats +++ b/java/ql/src/config/semmlecode.dbscheme.stats @@ -189,6 +189,10 @@ 28672 +@yieldstmt +100 + + @arrayaccess 53561 diff --git a/java/ql/src/semmle/code/java/Completion.qll b/java/ql/src/semmle/code/java/Completion.qll index a6195bcf600..c8b4f966a3b 100644 --- a/java/ql/src/semmle/code/java/Completion.qll +++ b/java/ql/src/semmle/code/java/Completion.qll @@ -52,13 +52,13 @@ newtype Completion = (innerValue = true or innerValue = false) } or /** - * The expression or statement completes via a `break` statement without a value. + * The expression or statement completes via a `break` statement. */ BreakCompletion(MaybeLabel l) or /** - * The expression or statement completes via a value `break` statement. + * The expression or statement completes via a `yield` statement. */ - ValueBreakCompletion(NormalOrBooleanCompletion c) or + YieldCompletion(NormalOrBooleanCompletion c) or /** * The expression or statement completes via a `continue` statement. */ diff --git a/java/ql/src/semmle/code/java/ControlFlowGraph.qll b/java/ql/src/semmle/code/java/ControlFlowGraph.qll index 45f96a36c9d..9c7cc976d46 100644 --- a/java/ql/src/semmle/code/java/ControlFlowGraph.qll +++ b/java/ql/src/semmle/code/java/ControlFlowGraph.qll @@ -804,23 +804,23 @@ private module ControlFlowGraphImpl { or // handle `switch` expression exists(SwitchExpr switch | switch = n | - // value `break` terminates the `switch` - last(switch.getAStmt(), last, ValueBreakCompletion(completion)) + // `yield` terminates the `switch` + last(switch.getAStmt(), last, YieldCompletion(completion)) or // any other abnormal completion is propagated last(switch.getAStmt(), last, completion) and - not completion instanceof ValueBreakCompletion and + not completion instanceof YieldCompletion and completion != NormalCompletion() ) or // the last node in a case rule is the last node in the right-hand side last(n.(SwitchCase).getRuleStatement(), last, completion) or - // ...and if the rhs is an expression we wrap the completion as a value break + // ...and if the rhs is an expression we wrap the completion as a yield exists(Completion caseCompletion | last(n.(SwitchCase).getRuleExpression(), last, caseCompletion) and if caseCompletion instanceof NormalOrBooleanCompletion - then completion = ValueBreakCompletion(caseCompletion) + then completion = YieldCompletion(caseCompletion) else completion = caseCompletion ) or @@ -833,18 +833,18 @@ private module ControlFlowGraphImpl { // `throw` statements or throwing calls give rise to ` Throw` completion exists(ThrowableType tt | mayThrow(n, tt) | last = n and completion = ThrowCompletion(tt)) or - // `break` statements without value give rise to a `Break` completion - exists(BreakStmt break | break = n and last = n and not break.hasValue() | + // `break` statements give rise to a `Break` completion + exists(BreakStmt break | break = n and last = n | completion = labelledBreakCompletion(MkLabel(break.getLabel())) or not exists(break.getLabel()) and completion = anonymousBreakCompletion() ) or - // value break statements get their completion wrapped as a value break + // yield statements get their completion wrapped as a yield exists(Completion caseCompletion | - last(n.(BreakStmt).getValue(), last, caseCompletion) and + last(n.(YieldStmt).getValue(), last, caseCompletion) and if caseCompletion instanceof NormalOrBooleanCompletion - then completion = ValueBreakCompletion(caseCompletion) + then completion = YieldCompletion(caseCompletion) else completion = caseCompletion ) or @@ -1112,9 +1112,9 @@ private module ControlFlowGraphImpl { n = case and result = first(case.getRuleStatement()) ) or - // Value break - exists(BreakStmt break | completion = NormalCompletion() | - n = break and result = first(break.getValue()) + // Yield + exists(YieldStmt yield | completion = NormalCompletion() | + n = yield and result = first(yield.getValue()) ) or // Synchronized statements execute their expression _before_ synchronization, so the CFG reflects that. diff --git a/java/ql/src/semmle/code/java/Expr.qll b/java/ql/src/semmle/code/java/Expr.qll index 0ab25628e47..313a8eb6aa8 100755 --- a/java/ql/src/semmle/code/java/Expr.qll +++ b/java/ql/src/semmle/code/java/Expr.qll @@ -1084,7 +1084,7 @@ class ConditionalExpr extends Expr, @conditionalexpr { } /** - * PREVIEW FEATURE in Java 12. Subject to removal in a future release. + * PREVIEW FEATURE in Java 13. Subject to removal in a future release. * * A `switch` expression. */ @@ -1117,7 +1117,7 @@ class SwitchExpr extends Expr, @switchexpr { Expr getAResult() { result = getACase().getRuleExpression() or - exists(BreakStmt break | break.(JumpStmt).getTarget() = this and result = break.getValue()) + exists(YieldStmt yield | yield.(JumpStmt).getTarget() = this and result = yield.getValue()) } /** Gets a printable representation of this expression. */ diff --git a/java/ql/src/semmle/code/java/Statement.qll b/java/ql/src/semmle/code/java/Statement.qll index 2f98615b243..2a5f94ef781 100755 --- a/java/ql/src/semmle/code/java/Statement.qll +++ b/java/ql/src/semmle/code/java/Statement.qll @@ -417,7 +417,7 @@ class SwitchCase extends Stmt, @case { SwitchStmt getSwitch() { result.getACase() = this } /** - * PREVIEW FEATURE in Java 12. Subject to removal in a future release. + * PREVIEW FEATURE in Java 13. Subject to removal in a future release. * * Gets the switch expression to which this case belongs, if any. */ @@ -432,7 +432,7 @@ class SwitchCase extends Stmt, @case { } /** - * PREVIEW FEATURE in Java 12. Subject to removal in a future release. + * PREVIEW FEATURE in Java 13. Subject to removal in a future release. * * Holds if this `case` is a switch labeled rule of the form `... -> ...`. */ @@ -443,14 +443,14 @@ class SwitchCase extends Stmt, @case { } /** - * PREVIEW FEATURE in Java 12. Subject to removal in a future release. + * PREVIEW FEATURE in Java 13. Subject to removal in a future release. * * Gets the expression on the right-hand side of the arrow, if any. */ Expr getRuleExpression() { result.getParent() = this and result.getIndex() = -1 } /** - * PREVIEW FEATURE in Java 12. Subject to removal in a future release. + * PREVIEW FEATURE in Java 13. Subject to removal in a future release. * * Gets the statement on the right-hand side of the arrow, if any. */ @@ -465,7 +465,7 @@ class ConstCase extends SwitchCase { Expr getValue() { result.getParent() = this and result.getIndex() = 0 } /** - * PREVIEW FEATURE in Java 12. Subject to removal in a future release. + * PREVIEW FEATURE in Java 13. Subject to removal in a future release. * * Gets the `case` constant at the specified index. */ @@ -558,10 +558,11 @@ class ThrowStmt extends Stmt, @throwstmt { } } -/** A `break` or `continue` statement. */ +/** A `break`, `yield` or `continue` statement. */ class JumpStmt extends Stmt { JumpStmt() { this instanceof BreakStmt or + this instanceof YieldStmt or this instanceof ContinueStmt } @@ -585,9 +586,7 @@ class JumpStmt extends Stmt { ) } - private SwitchExpr getSwitchExprTarget() { - this.(BreakStmt).hasValue() and result = this.getParent+() - } + private SwitchExpr getSwitchExprTarget() { result = this.(YieldStmt).getParent+() } private StmtParent getEnclosingTarget() { result = getSwitchExprTarget() @@ -598,7 +597,7 @@ class JumpStmt extends Stmt { } /** - * Gets the statement or `switch` expression that this `break` or `continue` jumps to. + * Gets the statement or `switch` expression that this `break`, `yield` or `continue` jumps to. */ StmtParent getTarget() { result = getLabelTarget() @@ -615,34 +614,31 @@ class BreakStmt extends Stmt, @breakstmt { /** Holds if this `break` statement has an explicit label. */ predicate hasLabel() { exists(string s | s = this.getLabel()) } - /** - * PREVIEW FEATURE in Java 12. Subject to removal in a future release. - * - * Gets the value of this `break` statement, if any. - */ - Expr getValue() { result.getParent() = this } - - /** - * PREVIEW FEATURE in Java 12. Subject to removal in a future release. - * - * Holds if this `break` statement has a value. - */ - predicate hasValue() { exists(Expr e | e.getParent() = this) } - /** Gets a printable representation of this statement. May include more detail than `toString()`. */ override string pp() { - if this.hasLabel() - then result = "break " + this.getLabel() - else - if this.hasValue() - then result = "break ..." - else result = "break" + if this.hasLabel() then result = "break " + this.getLabel() else result = "break" } /** This statement's Halstead ID (used to compute Halstead metrics). */ override string getHalsteadID() { result = "BreakStmt" } } +/** + * PREVIEW FEATURE in Java 13. Subject to removal in a future release. + * + * A `yield` statement. + */ +class YieldStmt extends Stmt, @yieldstmt { + /** + * Gets the value of this `yield` statement. + */ + Expr getValue() { result.getParent() = this } + + override string pp() { result = "yield ..." } + + override string getHalsteadID() { result = "YieldStmt" } +} + /** A `continue` statement. */ class ContinueStmt extends Stmt, @continuestmt { /** Gets the label targeted by this `continue` statement, if any. */ diff --git a/java/ql/src/semmle/code/java/dataflow/RangeAnalysis.qll b/java/ql/src/semmle/code/java/dataflow/RangeAnalysis.qll index 41ed735b752..f8384245073 100644 --- a/java/ql/src/semmle/code/java/dataflow/RangeAnalysis.qll +++ b/java/ql/src/semmle/code/java/dataflow/RangeAnalysis.qll @@ -298,10 +298,11 @@ private predicate boundFlowStepSsa( ) } -/** Holds if `v != e + delta` at `pos`. */ -private predicate unequalFlowStepSsa( +/** Holds if `v != e + delta` at `pos` and `v` is of integral type. */ +private predicate unequalFlowStepIntegralSsa( SsaVariable v, SsaReadPosition pos, Expr e, int delta, Reason reason ) { + v.getSourceVariable().getType() instanceof IntegralType and exists(Guard guard, boolean testIsTrue | pos.hasReadOfVar(v) and guard = eqFlowCond(v, e, delta, false, testIsTrue) and @@ -555,7 +556,7 @@ private predicate boundedSsa( boundedSsa(v, pos, b, d, upper, fromBackEdge, origdelta, r2) or boundedPhi(v, b, d, upper, fromBackEdge, origdelta, r2) | - unequalSsa(v, pos, b, d, r1) and + unequalIntegralSsa(v, pos, b, d, r1) and ( upper = true and delta = d - 1 or @@ -570,11 +571,13 @@ private predicate boundedSsa( } /** - * Holds if `v != b + delta` at `pos`. + * Holds if `v != b + delta` at `pos` and `v` is of integral type. */ -private predicate unequalSsa(SsaVariable v, SsaReadPosition pos, Bound b, int delta, Reason reason) { +private predicate unequalIntegralSsa( + SsaVariable v, SsaReadPosition pos, Bound b, int delta, Reason reason +) { exists(Expr e, int d1, int d2 | - unequalFlowStepSsa(v, pos, e, d1, reason) and + unequalFlowStepIntegralSsa(v, pos, e, d1, reason) and bounded(e, b, d2, true, _, _, _) and bounded(e, b, d2, false, _, _, _) and delta = d2 + d1 diff --git a/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.qll b/java/ql/src/semmle/code/java/security/UnsafeDeserialization.qll similarity index 100% rename from java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.qll rename to java/ql/src/semmle/code/java/security/UnsafeDeserialization.qll diff --git a/java/ql/src/semmle/code/java/security/XmlParsers.qll b/java/ql/src/semmle/code/java/security/XmlParsers.qll index 37a72f8128e..1f582489497 100644 --- a/java/ql/src/semmle/code/java/security/XmlParsers.qll +++ b/java/ql/src/semmle/code/java/security/XmlParsers.qll @@ -49,7 +49,7 @@ abstract class ParserConfig extends MethodAccess { } /* - * https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#DocumentBuilder + * https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#jaxp-documentbuilderfactory-saxparserfactory-and-dom4j */ /** The class `javax.xml.parsers.DocumentBuilderFactory`. */ @@ -227,7 +227,7 @@ class SafeDocumentBuilder extends DocumentBuilderConstruction { } /* - * https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#XMLInputFactory_.28a_StAX_parser.29 + * https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#xmlinputfactory-a-stax-parser */ /** The class `javax.xml.stream.XMLInputFactory`. */ @@ -353,7 +353,7 @@ class SafeXmlInputFactory extends VarAccess { } /* - * https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#SAXBuilder + * https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#saxbuilder */ /** @@ -429,7 +429,7 @@ class SafeSAXBuilder extends VarAccess { /* * The case in - * https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#Unmarshaller + * https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#jaxb-unmarshaller * will be split into two, one covers a SAXParser as a sink, the other the SAXSource as a sink. */ @@ -545,7 +545,7 @@ class SafeSAXParser extends MethodAccess { } } -/* SAXReader: https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#SAXReader */ +/* SAXReader: https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#saxreader */ /** * The class `org.dom4j.io.SAXReader`. */ @@ -621,7 +621,7 @@ class SafeSAXReader extends VarAccess { } } -/* https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#XMLReader */ +/* https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#xmlreader */ /** The class `org.xml.sax.XMLReader`. */ class XMLReader extends RefType { XMLReader() { this.hasQualifiedName("org.xml.sax", "XMLReader") } @@ -756,7 +756,7 @@ class CreatedSafeXMLReader extends Call { /* * SAXSource in - * https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#Unmarshaller + * https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#jaxb-unmarshaller */ /** The class `javax.xml.transform.sax.SAXSource` */ @@ -811,7 +811,7 @@ class SafeSAXSource extends Expr { } } -/* Transformer: https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#TransformerFactory */ +/* Transformer: https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#transformerfactory */ /** An access to a method use for configuring a transformer or schema. */ abstract class TransformerConfig extends MethodAccess { /** Holds if the configuration is disabled */ @@ -975,7 +975,7 @@ class SafeTransformer extends MethodAccess { } /* - * SAXTransformer: https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#SAXTransformerFactory + * SAXTransformer: https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#saxtransformerfactory * Has an extra method called newFilter. */ @@ -996,7 +996,7 @@ class SAXTransformerFactoryNewXMLFilter extends XmlParserCall { } } -/* Schema: https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#SchemaFactory */ +/* Schema: https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#schemafactory */ /** The class `javax.xml.validation.SchemaFactory`. */ class SchemaFactory extends RefType { SchemaFactory() { this.hasQualifiedName("javax.xml.validation", "SchemaFactory") } @@ -1060,7 +1060,7 @@ class SafeSchemaFactory extends VarAccess { } } -/* Unmarshaller: https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#Unmarshaller */ +/* Unmarshaller: https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#jaxb-unmarshaller */ /** The class `javax.xml.bind.Unmarshaller`. */ class XmlUnmarshaller extends RefType { XmlUnmarshaller() { this.hasQualifiedName("javax.xml.bind", "Unmarshaller") } @@ -1081,7 +1081,7 @@ class XmlUnmarshal extends XmlParserCall { override predicate isSafe() { none() } } -/* XPathExpression: https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#XPathExpression */ +/* XPathExpression: https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#xpathexpression */ /** The class `javax.xml.xpath.XPathExpression`. */ class XPathExpression extends RefType { XPathExpression() { this.hasQualifiedName("javax.xml.xpath", "XPathExpression") } diff --git a/java/ql/test/library-tests/guards12/options b/java/ql/test/library-tests/guards12/options index 33d712034f9..99827347b32 100644 --- a/java/ql/test/library-tests/guards12/options +++ b/java/ql/test/library-tests/guards12/options @@ -1 +1 @@ -//semmle-extractor-options: --javac-args --enable-preview -source 12 -target 12 +//semmle-extractor-options: --javac-args --enable-preview -source 13 -target 13 diff --git a/java/ql/test/qlpack.yml b/java/ql/test/qlpack.yml new file mode 100644 index 00000000000..d4b46d7d2b0 --- /dev/null +++ b/java/ql/test/qlpack.yml @@ -0,0 +1,3 @@ +name: codeql-java-tests +version: 0.0.0 +libraryPathDependencies: codeql-java diff --git a/java/ql/test/query-tests/UselessComparisonTest/A.java b/java/ql/test/query-tests/UselessComparisonTest/A.java index f2b473c2ee3..abc525ff20d 100644 --- a/java/ql/test/query-tests/UselessComparisonTest/A.java +++ b/java/ql/test/query-tests/UselessComparisonTest/A.java @@ -121,6 +121,11 @@ public class A { } } + void overflowTests2(int[] a, boolean b) { + int newlen = b ? (a.length + 1) << 1 : (a.length >> 1) + a.length; + if (newlen < 0) overflow(); + } + static final long VAL = 100L; long overflowAwareIncrease(long x) { diff --git a/java/ql/test/query-tests/UselessComparisonTest/C.java b/java/ql/test/query-tests/UselessComparisonTest/C.java new file mode 100644 index 00000000000..c1ca8261eb2 --- /dev/null +++ b/java/ql/test/query-tests/UselessComparisonTest/C.java @@ -0,0 +1,6 @@ +public class C { + double m1(double x) { + return (x < 0 || x > 1 || Double.isNaN(x)) ? Double.NaN : + x == 0 ? 0 : x == 1 ? 1 : 0.5; + } +} diff --git a/javascript/config/suites/javascript/correctness-core b/javascript/config/suites/javascript/correctness-core index 6a53405e1c3..d6b91e83a07 100644 --- a/javascript/config/suites/javascript/correctness-core +++ b/javascript/config/suites/javascript/correctness-core @@ -37,5 +37,6 @@ + semmlecode-javascript-queries/RegExp/UnboundBackref.ql: /Correctness/Regular Expressions + semmlecode-javascript-queries/RegExp/UnmatchableCaret.ql: /Correctness/Regular Expressions + semmlecode-javascript-queries/RegExp/UnmatchableDollar.ql: /Correctness/Regular Expressions ++ semmlecode-javascript-queries/Statements/IgnoreArrayResult.ql: /Correctness/Statements + semmlecode-javascript-queries/Statements/InconsistentLoopOrientation.ql: /Correctness/Statements + semmlecode-javascript-queries/Statements/UnreachableStatement.ql: /Correctness/Statements diff --git a/javascript/extractor/lib/typescript/package.json b/javascript/extractor/lib/typescript/package.json index fd440415096..3b3360158d3 100644 --- a/javascript/extractor/lib/typescript/package.json +++ b/javascript/extractor/lib/typescript/package.json @@ -2,7 +2,7 @@ "name": "typescript-parser-wrapper", "private": true, "dependencies": { - "typescript": "3.6.3" + "typescript": "^3.7.2" }, "scripts": { "build": "tsc --project tsconfig.json", diff --git a/javascript/extractor/lib/typescript/src/main.ts b/javascript/extractor/lib/typescript/src/main.ts index f0f847fd29a..bce59fc79d3 100644 --- a/javascript/extractor/lib/typescript/src/main.ts +++ b/javascript/extractor/lib/typescript/src/main.ts @@ -126,7 +126,7 @@ function checkCycle(root: any) { function isBlacklistedProperty(k: string) { return k === "parent" || k === "pos" || k === "end" || k === "symbol" || k === "localSymbol" - || k === "flowNode" || k === "returnFlowNode" + || k === "flowNode" || k === "returnFlowNode" || k === "endFlowNode" || k === "nextContainer" || k === "locals" || k === "bindDiagnostics" || k === "bindSuggestionDiagnostics"; } diff --git a/javascript/extractor/lib/typescript/src/type_table.ts b/javascript/extractor/lib/typescript/src/type_table.ts index 553afcf2e41..19eb64a8f10 100644 --- a/javascript/extractor/lib/typescript/src/type_table.ts +++ b/javascript/extractor/lib/typescript/src/type_table.ts @@ -597,7 +597,7 @@ export class TypeTable { let tupleType = tupleReference.target; let minLength = tupleType.minLength != null ? tupleType.minLength - : tupleReference.typeArguments.length; + : this.typeChecker.getTypeArguments(tupleReference).length; let hasRestElement = tupleType.hasRestElement ? 't' : 'f'; let prefix = `tuple;${minLength};${hasRestElement}`; return this.makeTypeStringVectorFromTypeReferenceArguments(prefix, type); @@ -714,11 +714,12 @@ export class TypeTable { // There can be an extra type argument at the end, denoting an explicit 'this' type argument. // We discard the extra argument in our model. let target = type.target; - if (type.typeArguments == null) return tag; + let typeArguments = this.typeChecker.getTypeArguments(type); + if (typeArguments == null) return tag; if (target.typeParameters != null) { - return this.makeTypeStringVector(tag, type.typeArguments, target.typeParameters.length); + return this.makeTypeStringVector(tag, typeArguments, target.typeParameters.length); } else { - return this.makeTypeStringVector(tag, type.typeArguments); + return this.makeTypeStringVector(tag, typeArguments); } } @@ -992,7 +993,7 @@ export class TypeTable { * `T` is the type parameter declared on the `Promise` interface. */ private getSelfType(type: ts.Type): ts.TypeReference { - if (isTypeReference(type) && type.typeArguments != null && type.typeArguments.length > 0) { + if (isTypeReference(type) && this.typeChecker.getTypeArguments(type).length > 0) { return type.target; } return null; @@ -1181,8 +1182,9 @@ export class TypeTable { if (isTypeReference(type)) { // Note that this case also handles tuple types, since a tuple type is represented as // a reference to a synthetic generic interface. - if (type.typeArguments != null) { - type.typeArguments.forEach(callback); + let typeArguments = this.typeChecker.getTypeArguments(type); + if (typeArguments != null) { + typeArguments.forEach(callback); } } else if (type.flags & ts.TypeFlags.UnionOrIntersection) { (type as ts.UnionOrIntersectionType).types.forEach(callback); diff --git a/javascript/extractor/lib/typescript/yarn.lock b/javascript/extractor/lib/typescript/yarn.lock index 62205cc17f4..5116c7eb5c3 100644 --- a/javascript/extractor/lib/typescript/yarn.lock +++ b/javascript/extractor/lib/typescript/yarn.lock @@ -225,9 +225,9 @@ tsutils@^2.12.1: dependencies: tslib "^1.8.1" -typescript@3.6.3: - version "3.6.3" - resolved "typescript-3.6.3.tgz#fea942fabb20f7e1ca7164ff626f1a9f3f70b4da" +typescript@^3.7.2: + version "3.7.2" + resolved "typescript-3.7.2.tgz" wrappy@1: version "1.0.2" diff --git a/javascript/extractor/src/com/semmle/jcorn/CustomParser.java b/javascript/extractor/src/com/semmle/jcorn/CustomParser.java index a77548ed21f..888a0aec639 100644 --- a/javascript/extractor/src/com/semmle/jcorn/CustomParser.java +++ b/javascript/extractor/src/com/semmle/jcorn/CustomParser.java @@ -7,6 +7,7 @@ import com.semmle.js.ast.AssignmentExpression; import com.semmle.js.ast.BlockStatement; import com.semmle.js.ast.CallExpression; import com.semmle.js.ast.CatchClause; +import com.semmle.js.ast.Chainable; import com.semmle.js.ast.ClassExpression; import com.semmle.js.ast.ComprehensionBlock; import com.semmle.js.ast.ComprehensionExpression; @@ -470,7 +471,8 @@ public class CustomParser extends FlowParser { Expression property = this.parsePropertyIdentifierOrIdentifier(); MemberExpression node = - new MemberExpression(start, base, property, false, false, isOnOptionalChain(false, base)); + new MemberExpression( + start, base, property, false, false, Chainable.isOnOptionalChain(false, base)); return Pair.make(this.finishNode(node), true); } else if (this.eat(doubleDot)) { SourceLocation start = new SourceLocation(startLoc); diff --git a/javascript/extractor/src/com/semmle/jcorn/Parser.java b/javascript/extractor/src/com/semmle/jcorn/Parser.java index 013f8e57181..f0e3c0d004f 100644 --- a/javascript/extractor/src/com/semmle/jcorn/Parser.java +++ b/javascript/extractor/src/com/semmle/jcorn/Parser.java @@ -1520,10 +1520,6 @@ public class Parser { } } - protected boolean isOnOptionalChain(boolean optional, Expression base) { - return optional || base instanceof Chainable && ((Chainable) base).isOnOptionalChain(); - } - /** * Parse a single subscript {@code s}; if more subscripts could follow, return {@code Pair.make(s, * true}, otherwise return {@code Pair.make(s, false)}. @@ -1544,7 +1540,7 @@ public class Parser { this.parseExpression(false, null), true, optional, - isOnOptionalChain(optional, base)); + Chainable.isOnOptionalChain(optional, base)); this.expect(TokenType.bracketR); return Pair.make(this.finishNode(node), true); } else if (!noCalls && this.eat(TokenType.parenL)) { @@ -1572,10 +1568,10 @@ public class Parser { new ArrayList<>(), exprList, optional, - isOnOptionalChain(optional, base)); + Chainable.isOnOptionalChain(optional, base)); return Pair.make(this.finishNode(node), true); } else if (this.type == TokenType.backQuote) { - if (isOnOptionalChain(optional, base)) { + if (Chainable.isOnOptionalChain(optional, base)) { this.raise(base, "An optional chain may not be used in a tagged template expression."); } TaggedTemplateExpression node = @@ -1590,7 +1586,7 @@ public class Parser { this.parseIdent(true), false, optional, - isOnOptionalChain(optional, base)); + Chainable.isOnOptionalChain(optional, base)); return Pair.make(this.finishNode(node), true); } else { return Pair.make(base, false); @@ -1832,7 +1828,7 @@ public class Parser { Expression callee = this.parseSubscripts(this.parseExprAtom(null), innerStartPos, innerStartLoc, true); - if (isOnOptionalChain(false, callee)) + if (Chainable.isOnOptionalChain(false, callee)) this.raise(callee, "An optional chain may not be used in a `new` expression."); return parseNewArguments(startLoc, callee); @@ -2314,7 +2310,7 @@ public class Parser { } if (node instanceof MemberExpression) { - if (isOnOptionalChain(false, (MemberExpression) node)) + if (Chainable.isOnOptionalChain(false, (MemberExpression) node)) this.raise(node, "Invalid left-hand side in assignment"); if (!isBinding) return node; } diff --git a/javascript/extractor/src/com/semmle/js/ast/Chainable.java b/javascript/extractor/src/com/semmle/js/ast/Chainable.java index a6efe38d1eb..7d6e17d360b 100644 --- a/javascript/extractor/src/com/semmle/js/ast/Chainable.java +++ b/javascript/extractor/src/com/semmle/js/ast/Chainable.java @@ -7,4 +7,14 @@ public interface Chainable { /** Is this on an optional chain? */ abstract boolean isOnOptionalChain(); + + /** + * Returns true if a chainable node is on an optional chain. + * + * @param optional true if the node in question is itself optional (has the ?. token) + * @param base the calle or base of the optional access + */ + public static boolean isOnOptionalChain(boolean optional, Expression base) { + return optional || base instanceof Chainable && ((Chainable) base).isOnOptionalChain(); + } } diff --git a/javascript/extractor/src/com/semmle/js/ast/DeclarationFlags.java b/javascript/extractor/src/com/semmle/js/ast/DeclarationFlags.java index 2a936bcc3b7..8a6921cb20b 100644 --- a/javascript/extractor/src/com/semmle/js/ast/DeclarationFlags.java +++ b/javascript/extractor/src/com/semmle/js/ast/DeclarationFlags.java @@ -17,9 +17,10 @@ public class DeclarationFlags { public static final int protected_ = 1 << 6; public static final int optional = 1 << 7; public static final int definiteAssignmentAssertion = 1 << 8; + public static final int declareKeyword = 1 << 9; public static final int none = 0; - public static final int numberOfFlags = 9; + public static final int numberOfFlags = 10; public static final List names = Arrays.asList( @@ -31,7 +32,8 @@ public class DeclarationFlags { "private", "protected", "optional", - "definiteAssignmentAssertion"); + "definiteAssignmentAssertion", + "declare"); public static final List relationNames = Arrays.asList( @@ -43,7 +45,8 @@ public class DeclarationFlags { "hasPrivateKeyword", "hasProtectedKeyword", "isOptionalMember", - "hasDefiniteAssignmentAssertion"); + "hasDefiniteAssignmentAssertion", + "hasDeclareKeyword"); public static boolean isComputed(int flags) { return (flags & computed) != 0; @@ -81,6 +84,10 @@ public class DeclarationFlags { return (flags & definiteAssignmentAssertion) != 0; } + public static boolean hasDeclareKeyword(int flags) { + return (flags & declareKeyword) != 0; + } + /** Returns a mask with the computed bit set to the value of enable. */ public static int getComputed(boolean enable) { return enable ? computed : 0; @@ -128,6 +135,11 @@ public class DeclarationFlags { return enable ? definiteAssignmentAssertion : 0; } + /** Returns a mask with the declare keyword bit set to the value of enable. */ + public static int getDeclareKeyword(boolean enable) { + return enable ? declareKeyword : 0; + } + /** Returns true if the nth bit is set in flags. */ public static boolean hasNthFlag(int flags, int n) { return (flags & (1 << n)) != 0; diff --git a/javascript/extractor/src/com/semmle/js/ast/DefaultVisitor.java b/javascript/extractor/src/com/semmle/js/ast/DefaultVisitor.java index d6779fdaa3b..cb11b9376ea 100644 --- a/javascript/extractor/src/com/semmle/js/ast/DefaultVisitor.java +++ b/javascript/extractor/src/com/semmle/js/ast/DefaultVisitor.java @@ -34,13 +34,13 @@ import com.semmle.ts.ast.InferTypeExpr; import com.semmle.ts.ast.InterfaceDeclaration; import com.semmle.ts.ast.InterfaceTypeExpr; import com.semmle.ts.ast.IntersectionTypeExpr; -import com.semmle.ts.ast.IsTypeExpr; import com.semmle.ts.ast.KeywordTypeExpr; import com.semmle.ts.ast.MappedTypeExpr; import com.semmle.ts.ast.NamespaceDeclaration; import com.semmle.ts.ast.NonNullAssertion; import com.semmle.ts.ast.OptionalTypeExpr; import com.semmle.ts.ast.ParenthesizedTypeExpr; +import com.semmle.ts.ast.PredicateTypeExpr; import com.semmle.ts.ast.RestTypeExpr; import com.semmle.ts.ast.TupleTypeExpr; import com.semmle.ts.ast.TypeAliasDeclaration; @@ -634,7 +634,7 @@ public class DefaultVisitor implements Visitor { } @Override - public R visit(IsTypeExpr nd, C c) { + public R visit(PredicateTypeExpr nd, C c) { return visit((TypeExpression) nd, c); } diff --git a/javascript/extractor/src/com/semmle/js/ast/MemberDefinition.java b/javascript/extractor/src/com/semmle/js/ast/MemberDefinition.java index bfd0f62462f..c04b79fa366 100644 --- a/javascript/extractor/src/com/semmle/js/ast/MemberDefinition.java +++ b/javascript/extractor/src/com/semmle/js/ast/MemberDefinition.java @@ -75,6 +75,11 @@ public abstract class MemberDefinition extends Node { return DeclarationFlags.isReadonly(flags); } + /** Returns true if this has the declare modifier. */ + public boolean hasDeclareKeyword() { + return DeclarationFlags.hasDeclareKeyword(flags); + } + /** * Returns the expression denoting the name of the member, or {@code null} if this is a * call/construct signature. diff --git a/javascript/extractor/src/com/semmle/js/ast/NodeCopier.java b/javascript/extractor/src/com/semmle/js/ast/NodeCopier.java index cdfc0441a57..9c61ca081df 100644 --- a/javascript/extractor/src/com/semmle/js/ast/NodeCopier.java +++ b/javascript/extractor/src/com/semmle/js/ast/NodeCopier.java @@ -30,13 +30,13 @@ import com.semmle.ts.ast.InferTypeExpr; import com.semmle.ts.ast.InterfaceDeclaration; import com.semmle.ts.ast.InterfaceTypeExpr; import com.semmle.ts.ast.IntersectionTypeExpr; -import com.semmle.ts.ast.IsTypeExpr; import com.semmle.ts.ast.KeywordTypeExpr; import com.semmle.ts.ast.MappedTypeExpr; import com.semmle.ts.ast.NamespaceDeclaration; import com.semmle.ts.ast.NonNullAssertion; import com.semmle.ts.ast.OptionalTypeExpr; import com.semmle.ts.ast.ParenthesizedTypeExpr; +import com.semmle.ts.ast.PredicateTypeExpr; import com.semmle.ts.ast.RestTypeExpr; import com.semmle.ts.ast.TupleTypeExpr; import com.semmle.ts.ast.TypeAliasDeclaration; @@ -717,8 +717,12 @@ public class NodeCopier implements Visitor { } @Override - public INode visit(IsTypeExpr nd, Void c) { - return new IsTypeExpr(visit(nd.getLoc()), copy(nd.getLeft()), copy(nd.getRight())); + public INode visit(PredicateTypeExpr nd, Void c) { + return new PredicateTypeExpr( + visit(nd.getLoc()), + copy(nd.getExpression()), + copy(nd.getTypeExpr()), + nd.hasAssertsKeyword()); } @Override diff --git a/javascript/extractor/src/com/semmle/js/ast/Visitor.java b/javascript/extractor/src/com/semmle/js/ast/Visitor.java index f825d448719..97a0dd73118 100644 --- a/javascript/extractor/src/com/semmle/js/ast/Visitor.java +++ b/javascript/extractor/src/com/semmle/js/ast/Visitor.java @@ -30,13 +30,13 @@ import com.semmle.ts.ast.InferTypeExpr; import com.semmle.ts.ast.InterfaceDeclaration; import com.semmle.ts.ast.InterfaceTypeExpr; import com.semmle.ts.ast.IntersectionTypeExpr; -import com.semmle.ts.ast.IsTypeExpr; import com.semmle.ts.ast.KeywordTypeExpr; import com.semmle.ts.ast.MappedTypeExpr; import com.semmle.ts.ast.NamespaceDeclaration; import com.semmle.ts.ast.NonNullAssertion; import com.semmle.ts.ast.OptionalTypeExpr; import com.semmle.ts.ast.ParenthesizedTypeExpr; +import com.semmle.ts.ast.PredicateTypeExpr; import com.semmle.ts.ast.RestTypeExpr; import com.semmle.ts.ast.TupleTypeExpr; import com.semmle.ts.ast.TypeAliasDeclaration; @@ -256,7 +256,7 @@ public interface Visitor { public R visit(TypeofTypeExpr nd, C c); - public R visit(IsTypeExpr nd, C c); + public R visit(PredicateTypeExpr nd, C c); public R visit(InterfaceTypeExpr nd, C c); diff --git a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java index c2a3ee70cb8..af15c7ad51c 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java @@ -125,13 +125,13 @@ import com.semmle.ts.ast.InferTypeExpr; import com.semmle.ts.ast.InterfaceDeclaration; import com.semmle.ts.ast.InterfaceTypeExpr; import com.semmle.ts.ast.IntersectionTypeExpr; -import com.semmle.ts.ast.IsTypeExpr; import com.semmle.ts.ast.KeywordTypeExpr; import com.semmle.ts.ast.MappedTypeExpr; import com.semmle.ts.ast.NamespaceDeclaration; import com.semmle.ts.ast.NonNullAssertion; import com.semmle.ts.ast.OptionalTypeExpr; import com.semmle.ts.ast.ParenthesizedTypeExpr; +import com.semmle.ts.ast.PredicateTypeExpr; import com.semmle.ts.ast.RestTypeExpr; import com.semmle.ts.ast.TupleTypeExpr; import com.semmle.ts.ast.TypeAliasDeclaration; @@ -1410,6 +1410,10 @@ public class ASTExtractor { } } + if (nd.hasDeclareKeyword()) { + trapwriter.addTuple("hasDeclareKeyword", methkey); + } + return methkey; } @@ -1707,10 +1711,13 @@ public class ASTExtractor { } @Override - public Label visit(IsTypeExpr nd, Context c) { + public Label visit(PredicateTypeExpr nd, Context c) { Label key = super.visit(nd, c); - visit(nd.getLeft(), key, 0, IdContext.varInTypeBind); - visit(nd.getRight(), key, 1, IdContext.typeBind); + visit(nd.getExpression(), key, 0, IdContext.varInTypeBind); + visit(nd.getTypeExpr(), key, 1, IdContext.typeBind); + if (nd.hasAssertsKeyword()) { + trapwriter.addTuple("hasAssertsKeyword", key); + } return key; } diff --git a/javascript/extractor/src/com/semmle/js/extractor/FileExtractor.java b/javascript/extractor/src/com/semmle/js/extractor/FileExtractor.java index d80ddeaf303..308713c0c1a 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/FileExtractor.java +++ b/javascript/extractor/src/com/semmle/js/extractor/FileExtractor.java @@ -1,5 +1,16 @@ package com.semmle.js.extractor; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileReader; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.regex.Pattern; + import com.semmle.js.extractor.ExtractionMetrics.ExtractionPhase; import com.semmle.js.extractor.trapcache.CachingTrapWriter; import com.semmle.js.extractor.trapcache.ITrapCache; @@ -10,15 +21,6 @@ import com.semmle.util.files.FileUtil; import com.semmle.util.io.WholeIO; import com.semmle.util.trap.TrapWriter; import com.semmle.util.trap.TrapWriter.Label; -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileReader; -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.LinkedHashSet; -import java.util.Set; -import java.util.regex.Pattern; /** * The file extractor extracts a single file and handles source archive population and TRAP caching; @@ -154,6 +156,9 @@ public class FileExtractor { byte[] bytes = new byte[fileHeaderSize]; int length = fis.read(bytes); + if (length == -1) + return false; + // Avoid invalid or unprintable UTF-8 files. if (config.getDefaultEncoding().equals("UTF-8") && hasUnprintableUtf8(bytes, length)) { return true; @@ -167,6 +172,9 @@ public class FileExtractor { return true; } + // Avoid Touchstone files + if (isTouchstone(bytes, length)) return true; + return false; } catch (IOException e) { Exceptions.ignore(e, "Let extractor handle this one."); @@ -198,6 +206,11 @@ public class FileExtractor { return false; } + private boolean isTouchstone(byte[] bytes, int length) { + String s = new String(bytes, 0, length, StandardCharsets.US_ASCII); + return s.startsWith("! TOUCHSTONE file ") || s.startsWith("[Version] 2.0"); + } + /** * Returns true if the byte sequence contains invalid UTF-8 or unprintable ASCII characters. */ diff --git a/javascript/extractor/src/com/semmle/js/extractor/ScopeManager.java b/javascript/extractor/src/com/semmle/js/extractor/ScopeManager.java index 1270b0a9409..3bffa4ad3ae 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/ScopeManager.java +++ b/javascript/extractor/src/com/semmle/js/extractor/ScopeManager.java @@ -46,9 +46,9 @@ import com.semmle.ts.ast.InferTypeExpr; import com.semmle.ts.ast.InterfaceDeclaration; import com.semmle.ts.ast.InterfaceTypeExpr; import com.semmle.ts.ast.IntersectionTypeExpr; -import com.semmle.ts.ast.IsTypeExpr; import com.semmle.ts.ast.NamespaceDeclaration; import com.semmle.ts.ast.ParenthesizedTypeExpr; +import com.semmle.ts.ast.PredicateTypeExpr; import com.semmle.ts.ast.TupleTypeExpr; import com.semmle.ts.ast.TypeAliasDeclaration; import com.semmle.ts.ast.UnionTypeExpr; @@ -660,8 +660,8 @@ public class ScopeManager { } @Override - public Void visit(IsTypeExpr nd, Void c) { - return nd.getRight().accept(this, c); + public Void visit(PredicateTypeExpr nd, Void c) { + return nd.getTypeExpr().accept(this, c); } @Override diff --git a/javascript/extractor/src/com/semmle/js/extractor/TypeExprKinds.java b/javascript/extractor/src/com/semmle/js/extractor/TypeExprKinds.java index 78b901da475..6c9263a5360 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/TypeExprKinds.java +++ b/javascript/extractor/src/com/semmle/js/extractor/TypeExprKinds.java @@ -16,11 +16,11 @@ import com.semmle.ts.ast.IndexedAccessTypeExpr; import com.semmle.ts.ast.InferTypeExpr; import com.semmle.ts.ast.InterfaceTypeExpr; import com.semmle.ts.ast.IntersectionTypeExpr; -import com.semmle.ts.ast.IsTypeExpr; import com.semmle.ts.ast.KeywordTypeExpr; import com.semmle.ts.ast.MappedTypeExpr; import com.semmle.ts.ast.OptionalTypeExpr; import com.semmle.ts.ast.ParenthesizedTypeExpr; +import com.semmle.ts.ast.PredicateTypeExpr; import com.semmle.ts.ast.RestTypeExpr; import com.semmle.ts.ast.TupleTypeExpr; import com.semmle.ts.ast.TypeParameter; @@ -159,7 +159,7 @@ public class TypeExprKinds { } @Override - public Integer visit(IsTypeExpr nd, Void c) { + public Integer visit(PredicateTypeExpr nd, Void c) { return isTypeExpr; } diff --git a/javascript/extractor/src/com/semmle/js/parser/TypeScriptASTConverter.java b/javascript/extractor/src/com/semmle/js/parser/TypeScriptASTConverter.java index 33d131cbf00..4912b5577f8 100644 --- a/javascript/extractor/src/com/semmle/js/parser/TypeScriptASTConverter.java +++ b/javascript/extractor/src/com/semmle/js/parser/TypeScriptASTConverter.java @@ -17,6 +17,7 @@ import com.semmle.js.ast.BlockStatement; import com.semmle.js.ast.BreakStatement; import com.semmle.js.ast.CallExpression; import com.semmle.js.ast.CatchClause; +import com.semmle.js.ast.Chainable; import com.semmle.js.ast.ClassBody; import com.semmle.js.ast.ClassDeclaration; import com.semmle.js.ast.ClassExpression; @@ -126,13 +127,13 @@ import com.semmle.ts.ast.InferTypeExpr; import com.semmle.ts.ast.InterfaceDeclaration; import com.semmle.ts.ast.InterfaceTypeExpr; import com.semmle.ts.ast.IntersectionTypeExpr; -import com.semmle.ts.ast.IsTypeExpr; import com.semmle.ts.ast.KeywordTypeExpr; import com.semmle.ts.ast.MappedTypeExpr; import com.semmle.ts.ast.NamespaceDeclaration; import com.semmle.ts.ast.NonNullAssertion; import com.semmle.ts.ast.OptionalTypeExpr; import com.semmle.ts.ast.ParenthesizedTypeExpr; +import com.semmle.ts.ast.PredicateTypeExpr; import com.semmle.ts.ast.RestTypeExpr; import com.semmle.ts.ast.TupleTypeExpr; import com.semmle.ts.ast.TypeAliasDeclaration; @@ -877,7 +878,10 @@ public class TypeScriptASTConverter { } Expression callee = convertChild(node, "expression"); List typeArguments = convertChildrenAsTypes(node, "typeArguments"); - CallExpression call = new CallExpression(loc, callee, typeArguments, arguments, false, false); + boolean optional = node.has("questionDotToken"); + boolean onOptionalChain = Chainable.isOnOptionalChain(optional, callee); + CallExpression call = + new CallExpression(loc, callee, typeArguments, arguments, optional, onOptionalChain); attachResolvedSignature(call, node); return call; } @@ -1108,7 +1112,9 @@ public class TypeScriptASTConverter { throws ParseError { Expression object = convertChild(node, "expression"); Expression property = convertChild(node, "argumentExpression"); - return new MemberExpression(loc, object, property, true, false, false); + boolean optional = node.has("questionDotToken"); + boolean onOptionalChain = Chainable.isOnOptionalChain(optional, object); + return new MemberExpression(loc, object, property, true, optional, onOptionalChain); } private Node convertEmptyStatement(SourceLocation loc) { @@ -1584,10 +1590,14 @@ public class TypeScriptASTConverter { private Node convertMetaProperty(JsonObject node, SourceLocation loc) throws ParseError { Position metaStart = loc.getStart(); - String keywordKind = syntaxKinds.get(node.getAsJsonPrimitive("keywordToken").getAsInt() + "").getAsString(); + String keywordKind = + syntaxKinds.get(node.getAsJsonPrimitive("keywordToken").getAsInt() + "").getAsString(); String identifier = keywordKind.equals("ImportKeyword") ? "import" : "new"; Position metaEnd = - new Position(metaStart.getLine(), metaStart.getColumn() + identifier.length(), metaStart.getOffset() + identifier.length()); + new Position( + metaStart.getLine(), + metaStart.getColumn() + identifier.length(), + metaStart.getOffset() + identifier.length()); SourceLocation metaLoc = new SourceLocation(identifier, metaStart, metaEnd); Identifier meta = new Identifier(metaLoc, identifier); return new MetaProperty(loc, meta, convertChild(node, "name")); @@ -1967,8 +1977,11 @@ public class TypeScriptASTConverter { private Node convertPropertyAccessExpression(JsonObject node, SourceLocation loc) throws ParseError { + Expression base = convertChild(node, "expression"); + boolean optional = node.has("questionDotToken"); + boolean onOptionalChain = Chainable.isOnOptionalChain(optional, base); return new MemberExpression( - loc, convertChild(node, "expression"), convertChild(node, "name"), false, false, false); + loc, base, convertChild(node, "name"), false, optional, onOptionalChain); } private Node convertPropertyAssignment(JsonObject node, SourceLocation loc) throws ParseError { @@ -1996,6 +2009,9 @@ public class TypeScriptASTConverter { if (node.get("exclamationToken") != null) { flags |= DeclarationFlags.definiteAssignmentAssertion; } + if (hasModifier(node, "DeclareKeyword")) { + flags |= DeclarationFlags.declareKeyword; + } FieldDefinition fieldDefinition = new FieldDefinition( loc, @@ -2186,8 +2202,11 @@ public class TypeScriptASTConverter { } private Node convertTypePredicate(JsonObject node, SourceLocation loc) throws ParseError { - return new IsTypeExpr( - loc, convertChildAsType(node, "parameterName"), convertChildAsType(node, "type")); + return new PredicateTypeExpr( + loc, + convertChildAsType(node, "parameterName"), + convertChildAsType(node, "type"), + node.has("assertsModifier")); } private Node convertTypeReference(JsonObject node, SourceLocation loc) throws ParseError { diff --git a/javascript/extractor/src/com/semmle/ts/ast/IsTypeExpr.java b/javascript/extractor/src/com/semmle/ts/ast/IsTypeExpr.java deleted file mode 100644 index a64fdb83650..00000000000 --- a/javascript/extractor/src/com/semmle/ts/ast/IsTypeExpr.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.semmle.ts.ast; - -import com.semmle.js.ast.SourceLocation; -import com.semmle.js.ast.Visitor; - -/** - * A type of form E is T where E is a parameter name or this and - * T is a type. - */ -public class IsTypeExpr extends TypeExpression { - private final ITypeExpression left; // Always Identifier or KeywordTypeExpr (in case of 'this') - private final ITypeExpression right; - - public IsTypeExpr(SourceLocation loc, ITypeExpression left, ITypeExpression right) { - super("IsTypeExpr", loc); - this.left = left; - this.right = right; - } - - public ITypeExpression getLeft() { - return left; - } - - public ITypeExpression getRight() { - return right; - } - - @Override - public R accept(Visitor v, C c) { - return v.visit(this, c); - } -} diff --git a/javascript/extractor/src/com/semmle/ts/ast/PredicateTypeExpr.java b/javascript/extractor/src/com/semmle/ts/ast/PredicateTypeExpr.java new file mode 100644 index 00000000000..27bd3c1718c --- /dev/null +++ b/javascript/extractor/src/com/semmle/ts/ast/PredicateTypeExpr.java @@ -0,0 +1,44 @@ +package com.semmle.ts.ast; + +import com.semmle.js.ast.SourceLocation; +import com.semmle.js.ast.Visitor; + +/** + * A type of form E is T, asserts E is T or asserts E where E is + * a parameter name or this and T is a type. + */ +public class PredicateTypeExpr extends TypeExpression { + private final ITypeExpression expression; + private final ITypeExpression type; + private final boolean hasAssertsKeyword; + + public PredicateTypeExpr( + SourceLocation loc, + ITypeExpression expression, + ITypeExpression type, + boolean hasAssertsKeyword) { + super("PredicateTypeExpr", loc); + this.expression = expression; + this.type = type; + this.hasAssertsKeyword = hasAssertsKeyword; + } + + /** Returns the E in E is T. */ + public ITypeExpression getExpression() { + return expression; + } + + /** Returns the T in E is T. */ + public ITypeExpression getTypeExpr() { + return type; + } + + public boolean hasAssertsKeyword() { + return hasAssertsKeyword; + } + + @Override + public R accept(Visitor v, C c) { + return v.visit(this, c); + } +} diff --git a/javascript/extractor/tests/ts/input/optionalChaining.ts b/javascript/extractor/tests/ts/input/optionalChaining.ts new file mode 100644 index 00000000000..5070e38ab24 --- /dev/null +++ b/javascript/extractor/tests/ts/input/optionalChaining.ts @@ -0,0 +1,3 @@ +base?.x.y; +base?.(x).y; +base?.[z].y; diff --git a/javascript/extractor/tests/ts/input/touchstone-file.ts b/javascript/extractor/tests/ts/input/touchstone-file.ts new file mode 100644 index 00000000000..a72a1dc56af --- /dev/null +++ b/javascript/extractor/tests/ts/input/touchstone-file.ts @@ -0,0 +1,2 @@ +! TOUCHSTONE file generated by me +[Version] 2.0 diff --git a/javascript/extractor/tests/ts/input/touchstone-file2.ts b/javascript/extractor/tests/ts/input/touchstone-file2.ts new file mode 100644 index 00000000000..d642e0260b1 --- /dev/null +++ b/javascript/extractor/tests/ts/input/touchstone-file2.ts @@ -0,0 +1 @@ +[Version] 2.0 diff --git a/javascript/extractor/tests/ts/output/trap/optionalChaining.ts.trap b/javascript/extractor/tests/ts/output/trap/optionalChaining.ts.trap new file mode 100644 index 00000000000..0a414c9da57 --- /dev/null +++ b/javascript/extractor/tests/ts/output/trap/optionalChaining.ts.trap @@ -0,0 +1,303 @@ +#10000=@"/optionalChaining.ts;sourcefile" +files(#10000,"/optionalChaining.ts","optionalChaining","ts",0) +#10001=@"/;folder" +folders(#10001,"/","") +containerparent(#10001,#10000) +#10002=@"loc,{#10000},0,0,0,0" +locations_default(#10002,#10000,0,0,0,0) +hasLocation(#10000,#10002) +#20000=@"global_scope" +scopes(#20000,0) +#20001=@"script;{#10000},1,1" +#20002=* +lines(#20002,#20001,"base?.x.y;"," +") +#20003=@"loc,{#10000},1,1,1,10" +locations_default(#20003,#10000,1,1,1,10) +hasLocation(#20002,#20003) +#20004=* +lines(#20004,#20001,"base?.(x).y;"," +") +#20005=@"loc,{#10000},2,1,2,12" +locations_default(#20005,#10000,2,1,2,12) +hasLocation(#20004,#20005) +#20006=* +lines(#20006,#20001,"base?.[z].y;"," +") +#20007=@"loc,{#10000},3,1,3,12" +locations_default(#20007,#10000,3,1,3,12) +hasLocation(#20006,#20007) +numlines(#20001,3,3,0) +#20008=* +tokeninfo(#20008,6,#20001,0,"base") +#20009=@"loc,{#10000},1,1,1,4" +locations_default(#20009,#10000,1,1,1,4) +hasLocation(#20008,#20009) +#20010=* +tokeninfo(#20010,8,#20001,1,"?.") +#20011=@"loc,{#10000},1,5,1,6" +locations_default(#20011,#10000,1,5,1,6) +hasLocation(#20010,#20011) +#20012=* +tokeninfo(#20012,6,#20001,2,"x") +#20013=@"loc,{#10000},1,7,1,7" +locations_default(#20013,#10000,1,7,1,7) +hasLocation(#20012,#20013) +#20014=* +tokeninfo(#20014,8,#20001,3,".") +#20015=@"loc,{#10000},1,8,1,8" +locations_default(#20015,#10000,1,8,1,8) +hasLocation(#20014,#20015) +#20016=* +tokeninfo(#20016,6,#20001,4,"y") +#20017=@"loc,{#10000},1,9,1,9" +locations_default(#20017,#10000,1,9,1,9) +hasLocation(#20016,#20017) +#20018=* +tokeninfo(#20018,8,#20001,5,";") +#20019=@"loc,{#10000},1,10,1,10" +locations_default(#20019,#10000,1,10,1,10) +hasLocation(#20018,#20019) +#20020=* +tokeninfo(#20020,6,#20001,6,"base") +#20021=@"loc,{#10000},2,1,2,4" +locations_default(#20021,#10000,2,1,2,4) +hasLocation(#20020,#20021) +#20022=* +tokeninfo(#20022,8,#20001,7,"?.") +#20023=@"loc,{#10000},2,5,2,6" +locations_default(#20023,#10000,2,5,2,6) +hasLocation(#20022,#20023) +#20024=* +tokeninfo(#20024,8,#20001,8,"(") +#20025=@"loc,{#10000},2,7,2,7" +locations_default(#20025,#10000,2,7,2,7) +hasLocation(#20024,#20025) +#20026=* +tokeninfo(#20026,6,#20001,9,"x") +#20027=@"loc,{#10000},2,8,2,8" +locations_default(#20027,#10000,2,8,2,8) +hasLocation(#20026,#20027) +#20028=* +tokeninfo(#20028,8,#20001,10,")") +#20029=@"loc,{#10000},2,9,2,9" +locations_default(#20029,#10000,2,9,2,9) +hasLocation(#20028,#20029) +#20030=* +tokeninfo(#20030,8,#20001,11,".") +#20031=@"loc,{#10000},2,10,2,10" +locations_default(#20031,#10000,2,10,2,10) +hasLocation(#20030,#20031) +#20032=* +tokeninfo(#20032,6,#20001,12,"y") +#20033=@"loc,{#10000},2,11,2,11" +locations_default(#20033,#10000,2,11,2,11) +hasLocation(#20032,#20033) +#20034=* +tokeninfo(#20034,8,#20001,13,";") +#20035=@"loc,{#10000},2,12,2,12" +locations_default(#20035,#10000,2,12,2,12) +hasLocation(#20034,#20035) +#20036=* +tokeninfo(#20036,6,#20001,14,"base") +#20037=@"loc,{#10000},3,1,3,4" +locations_default(#20037,#10000,3,1,3,4) +hasLocation(#20036,#20037) +#20038=* +tokeninfo(#20038,8,#20001,15,"?.") +#20039=@"loc,{#10000},3,5,3,6" +locations_default(#20039,#10000,3,5,3,6) +hasLocation(#20038,#20039) +#20040=* +tokeninfo(#20040,8,#20001,16,"[") +#20041=@"loc,{#10000},3,7,3,7" +locations_default(#20041,#10000,3,7,3,7) +hasLocation(#20040,#20041) +#20042=* +tokeninfo(#20042,6,#20001,17,"z") +#20043=@"loc,{#10000},3,8,3,8" +locations_default(#20043,#10000,3,8,3,8) +hasLocation(#20042,#20043) +#20044=* +tokeninfo(#20044,8,#20001,18,"]") +#20045=@"loc,{#10000},3,9,3,9" +locations_default(#20045,#10000,3,9,3,9) +hasLocation(#20044,#20045) +#20046=* +tokeninfo(#20046,8,#20001,19,".") +#20047=@"loc,{#10000},3,10,3,10" +locations_default(#20047,#10000,3,10,3,10) +hasLocation(#20046,#20047) +#20048=* +tokeninfo(#20048,6,#20001,20,"y") +#20049=@"loc,{#10000},3,11,3,11" +locations_default(#20049,#10000,3,11,3,11) +hasLocation(#20048,#20049) +#20050=* +tokeninfo(#20050,8,#20001,21,";") +#20051=@"loc,{#10000},3,12,3,12" +locations_default(#20051,#10000,3,12,3,12) +hasLocation(#20050,#20051) +#20052=* +tokeninfo(#20052,0,#20001,22,"") +#20053=@"loc,{#10000},4,1,4,0" +locations_default(#20053,#10000,4,1,4,0) +hasLocation(#20052,#20053) +toplevels(#20001,0) +#20054=@"loc,{#10000},1,1,4,0" +locations_default(#20054,#10000,1,1,4,0) +hasLocation(#20001,#20054) +#20055=* +stmts(#20055,2,#20001,0,"base?.x.y;") +hasLocation(#20055,#20003) +stmtContainers(#20055,#20001) +#20056=* +exprs(#20056,14,#20055,0,"base?.x.y") +#20057=@"loc,{#10000},1,1,1,9" +locations_default(#20057,#10000,1,1,1,9) +hasLocation(#20056,#20057) +enclosingStmt(#20056,#20055) +exprContainers(#20056,#20001) +#20058=* +exprs(#20058,14,#20056,0,"base?.x") +#20059=@"loc,{#10000},1,1,1,7" +locations_default(#20059,#10000,1,1,1,7) +hasLocation(#20058,#20059) +enclosingStmt(#20058,#20055) +exprContainers(#20058,#20001) +#20060=* +exprs(#20060,79,#20058,0,"base") +hasLocation(#20060,#20009) +enclosingStmt(#20060,#20055) +exprContainers(#20060,#20001) +literals("base","base",#20060) +#20061=@"var;{base};{#20000}" +variables(#20061,"base",#20000) +bind(#20060,#20061) +#20062=* +exprs(#20062,0,#20058,1,"x") +hasLocation(#20062,#20013) +enclosingStmt(#20062,#20055) +exprContainers(#20062,#20001) +literals("x","x",#20062) +isOptionalChaining(#20058) +#20063=* +exprs(#20063,0,#20056,1,"y") +hasLocation(#20063,#20017) +enclosingStmt(#20063,#20055) +exprContainers(#20063,#20001) +literals("y","y",#20063) +#20064=* +stmts(#20064,2,#20001,1,"base?.(x).y;") +hasLocation(#20064,#20005) +stmtContainers(#20064,#20001) +#20065=* +exprs(#20065,14,#20064,0,"base?.(x).y") +#20066=@"loc,{#10000},2,1,2,11" +locations_default(#20066,#10000,2,1,2,11) +hasLocation(#20065,#20066) +enclosingStmt(#20065,#20064) +exprContainers(#20065,#20001) +#20067=* +exprs(#20067,13,#20065,0,"base?.(x)") +#20068=@"loc,{#10000},2,1,2,9" +locations_default(#20068,#10000,2,1,2,9) +hasLocation(#20067,#20068) +enclosingStmt(#20067,#20064) +exprContainers(#20067,#20001) +#20069=* +exprs(#20069,79,#20067,-1,"base") +hasLocation(#20069,#20021) +enclosingStmt(#20069,#20064) +exprContainers(#20069,#20001) +literals("base","base",#20069) +bind(#20069,#20061) +#20070=* +exprs(#20070,79,#20067,0,"x") +hasLocation(#20070,#20027) +enclosingStmt(#20070,#20064) +exprContainers(#20070,#20001) +literals("x","x",#20070) +#20071=@"var;{x};{#20000}" +variables(#20071,"x",#20000) +bind(#20070,#20071) +isOptionalChaining(#20067) +#20072=* +exprs(#20072,0,#20065,1,"y") +hasLocation(#20072,#20033) +enclosingStmt(#20072,#20064) +exprContainers(#20072,#20001) +literals("y","y",#20072) +#20073=* +stmts(#20073,2,#20001,2,"base?.[z].y;") +hasLocation(#20073,#20007) +stmtContainers(#20073,#20001) +#20074=* +exprs(#20074,14,#20073,0,"base?.[z].y") +#20075=@"loc,{#10000},3,1,3,11" +locations_default(#20075,#10000,3,1,3,11) +hasLocation(#20074,#20075) +enclosingStmt(#20074,#20073) +exprContainers(#20074,#20001) +#20076=* +exprs(#20076,15,#20074,0,"base?.[z]") +#20077=@"loc,{#10000},3,1,3,9" +locations_default(#20077,#10000,3,1,3,9) +hasLocation(#20076,#20077) +enclosingStmt(#20076,#20073) +exprContainers(#20076,#20001) +#20078=* +exprs(#20078,79,#20076,0,"base") +hasLocation(#20078,#20037) +enclosingStmt(#20078,#20073) +exprContainers(#20078,#20001) +literals("base","base",#20078) +bind(#20078,#20061) +#20079=* +exprs(#20079,79,#20076,1,"z") +hasLocation(#20079,#20043) +enclosingStmt(#20079,#20073) +exprContainers(#20079,#20001) +literals("z","z",#20079) +#20080=@"var;{z};{#20000}" +variables(#20080,"z",#20000) +bind(#20079,#20080) +isOptionalChaining(#20076) +#20081=* +exprs(#20081,0,#20074,1,"y") +hasLocation(#20081,#20049) +enclosingStmt(#20081,#20073) +exprContainers(#20081,#20001) +literals("y","y",#20081) +#20082=* +entry_cfg_node(#20082,#20001) +#20083=@"loc,{#10000},1,1,1,0" +locations_default(#20083,#10000,1,1,1,0) +hasLocation(#20082,#20083) +#20084=* +exit_cfg_node(#20084,#20001) +hasLocation(#20084,#20053) +successor(#20073,#20078) +successor(#20081,#20074) +successor(#20079,#20076) +successor(#20078,#20079) +successor(#20076,#20081) +successor(#20078,#20084) +successor(#20074,#20084) +successor(#20064,#20069) +successor(#20072,#20065) +successor(#20070,#20067) +successor(#20069,#20070) +successor(#20067,#20072) +successor(#20069,#20073) +successor(#20065,#20073) +successor(#20055,#20060) +successor(#20063,#20056) +successor(#20062,#20058) +successor(#20060,#20062) +successor(#20058,#20063) +successor(#20060,#20064) +successor(#20056,#20064) +successor(#20082,#20055) +numlines(#10000,3,3,0) +filetype(#10000,"typescript") diff --git a/javascript/ql/src/Expressions/ExprHasNoEffect.ql b/javascript/ql/src/Expressions/ExprHasNoEffect.ql index 14024ec8f38..917ab81a3e7 100644 --- a/javascript/ql/src/Expressions/ExprHasNoEffect.ql +++ b/javascript/ql/src/Expressions/ExprHasNoEffect.ql @@ -13,122 +13,10 @@ */ import javascript -import DOMProperties -import semmle.javascript.frameworks.xUnit -import semmle.javascript.RestrictedLocations import ExprHasNoEffect +import semmle.javascript.RestrictedLocations -/** - * Holds if `e` is of the form `x;` or `e.p;` and has a JSDoc comment containing a tag. - * In that case, it is probably meant as a declaration and shouldn't be flagged by this query. - * - * This will still flag cases where the JSDoc comment contains no tag at all (and hence carries - * no semantic information), and expression statements with an ordinary (non-JSDoc) comment - * attached to them. - */ -predicate isDeclaration(Expr e) { - (e instanceof VarAccess or e instanceof PropAccess) and - exists(e.getParent().(ExprStmt).getDocumentation().getATag()) -} - -/** - * Holds if there exists a getter for a property called `name` anywhere in the program. - */ -predicate isGetterProperty(string name) { - // there is a call of the form `Object.defineProperty(..., name, descriptor)` ... - exists(CallToObjectDefineProperty defProp | name = defProp.getPropertyName() | - // ... where `descriptor` defines a getter - defProp.hasPropertyAttributeWrite("get", _) - or - // ... where `descriptor` may define a getter - exists(DataFlow::SourceNode descriptor | descriptor.flowsTo(defProp.getPropertyDescriptor()) | - descriptor.isIncomplete(_) - or - // minimal escape analysis for the descriptor - exists(DataFlow::InvokeNode invk | - not invk = defProp and - descriptor.flowsTo(invk.getAnArgument()) - ) - ) - ) - or - // there is an object expression with a getter property `name` - exists(ObjectExpr obj | obj.getPropertyByName(name) instanceof PropertyGetter) -} - -/** - * A property access that may invoke a getter. - */ -class GetterPropertyAccess extends PropAccess { - override predicate isImpure() { isGetterProperty(getPropertyName()) } -} - -/** - * Holds if `c` is an indirect eval call of the form `(dummy, eval)(...)`, where - * `dummy` is some expression whose value is discarded, and which simply - * exists to prevent the call from being interpreted as a direct eval. - */ -predicate isIndirectEval(CallExpr c, Expr dummy) { - exists(SeqExpr seq | seq = c.getCallee().stripParens() | - dummy = seq.getOperand(0) and - seq.getOperand(1).(GlobalVarAccess).getName() = "eval" and - seq.getNumOperands() = 2 - ) -} - -/** - * Holds if `c` is a call of the form `(dummy, e[p])(...)`, where `dummy` is - * some expression whose value is discarded, and which simply exists - * to prevent the call from being interpreted as a method call. - */ -predicate isReceiverSuppressingCall(CallExpr c, Expr dummy, PropAccess callee) { - exists(SeqExpr seq | seq = c.getCallee().stripParens() | - dummy = seq.getOperand(0) and - seq.getOperand(1) = callee and - seq.getNumOperands() = 2 - ) -} - -/** - * Holds if evaluating `e` has no side effects (except potentially allocating - * and initializing a new object). - * - * For calls, we do not check whether their arguments have any side effects: - * even if they do, the call itself is useless and should be flagged by this - * query. - */ -predicate noSideEffects(Expr e) { - e.isPure() - or - // `new Error(...)`, `new SyntaxError(...)`, etc. - forex(Function f | f = e.flow().(DataFlow::NewNode).getACallee() | - f.(ExternalType).getASupertype*().getName() = "Error" - ) -} from Expr e -where - noSideEffects(e) and - inVoidContext(e) and - // disregard pure expressions wrapped in a void(...) - not e instanceof VoidExpr and - // filter out directives (unknown directives are handled by UnknownDirective.ql) - not exists(Directive d | e = d.getExpr()) and - // or about externs - not e.inExternsFile() and - // don't complain about declarations - not isDeclaration(e) and - // exclude DOM properties, which sometimes have magical auto-update properties - not isDOMProperty(e.(PropAccess).getPropertyName()) and - // exclude xUnit.js annotations - not e instanceof XUnitAnnotation and - // exclude common patterns that are most likely intentional - not isIndirectEval(_, e) and - not isReceiverSuppressingCall(_, e, _) and - // exclude anonymous function expressions as statements; these can only arise - // from a syntax error we already flag - not exists(FunctionExpr fe, ExprStmt es | fe = e | - fe = es.getExpr() and - not exists(fe.getName()) - ) +where hasNoEffect(e) select e.(FirstLineOf), "This expression has no effect." diff --git a/javascript/ql/src/Expressions/ExprHasNoEffect.qll b/javascript/ql/src/Expressions/ExprHasNoEffect.qll index 858f719ba0a..bee980e5fd8 100644 --- a/javascript/ql/src/Expressions/ExprHasNoEffect.qll +++ b/javascript/ql/src/Expressions/ExprHasNoEffect.qll @@ -3,6 +3,8 @@ */ import javascript +import DOMProperties +import semmle.javascript.frameworks.xUnit /** * Holds if `e` appears in a syntactic context where its value is discarded. @@ -37,3 +39,121 @@ predicate inVoidContext(Expr e) { or exists(LogicalBinaryExpr logical | e = logical.getRightOperand() and inVoidContext(logical)) } + + +/** + * Holds if `e` is of the form `x;` or `e.p;` and has a JSDoc comment containing a tag. + * In that case, it is probably meant as a declaration and shouldn't be flagged by this query. + * + * This will still flag cases where the JSDoc comment contains no tag at all (and hence carries + * no semantic information), and expression statements with an ordinary (non-JSDoc) comment + * attached to them. + */ +predicate isDeclaration(Expr e) { + (e instanceof VarAccess or e instanceof PropAccess) and + exists(e.getParent().(ExprStmt).getDocumentation().getATag()) +} + +/** + * Holds if there exists a getter for a property called `name` anywhere in the program. + */ +predicate isGetterProperty(string name) { + // there is a call of the form `Object.defineProperty(..., name, descriptor)` ... + exists(CallToObjectDefineProperty defProp | name = defProp.getPropertyName() | + // ... where `descriptor` defines a getter + defProp.hasPropertyAttributeWrite("get", _) + or + // ... where `descriptor` may define a getter + exists(DataFlow::SourceNode descriptor | descriptor.flowsTo(defProp.getPropertyDescriptor()) | + descriptor.isIncomplete(_) + or + // minimal escape analysis for the descriptor + exists(DataFlow::InvokeNode invk | + not invk = defProp and + descriptor.flowsTo(invk.getAnArgument()) + ) + ) + ) + or + // there is an object expression with a getter property `name` + exists(ObjectExpr obj | obj.getPropertyByName(name) instanceof PropertyGetter) +} + +/** + * A property access that may invoke a getter. + */ +class GetterPropertyAccess extends PropAccess { + override predicate isImpure() { isGetterProperty(getPropertyName()) } +} + +/** + * Holds if `c` is an indirect eval call of the form `(dummy, eval)(...)`, where + * `dummy` is some expression whose value is discarded, and which simply + * exists to prevent the call from being interpreted as a direct eval. + */ +predicate isIndirectEval(CallExpr c, Expr dummy) { + exists(SeqExpr seq | seq = c.getCallee().stripParens() | + dummy = seq.getOperand(0) and + seq.getOperand(1).(GlobalVarAccess).getName() = "eval" and + seq.getNumOperands() = 2 + ) +} + +/** + * Holds if `c` is a call of the form `(dummy, e[p])(...)`, where `dummy` is + * some expression whose value is discarded, and which simply exists + * to prevent the call from being interpreted as a method call. + */ +predicate isReceiverSuppressingCall(CallExpr c, Expr dummy, PropAccess callee) { + exists(SeqExpr seq | seq = c.getCallee().stripParens() | + dummy = seq.getOperand(0) and + seq.getOperand(1) = callee and + seq.getNumOperands() = 2 + ) +} + +/** + * Holds if evaluating `e` has no side effects (except potentially allocating + * and initializing a new object). + * + * For calls, we do not check whether their arguments have any side effects: + * even if they do, the call itself is useless and should be flagged by this + * query. + */ +predicate noSideEffects(Expr e) { + e.isPure() + or + // `new Error(...)`, `new SyntaxError(...)`, etc. + forex(Function f | f = e.flow().(DataFlow::NewNode).getACallee() | + f.(ExternalType).getASupertype*().getName() = "Error" + ) +} + +/** + * Holds if the expression `e` should be reported as having no effect. + */ +predicate hasNoEffect(Expr e) { + noSideEffects(e) and + inVoidContext(e) and + // disregard pure expressions wrapped in a void(...) + not e instanceof VoidExpr and + // filter out directives (unknown directives are handled by UnknownDirective.ql) + not exists(Directive d | e = d.getExpr()) and + // or about externs + not e.inExternsFile() and + // don't complain about declarations + not isDeclaration(e) and + // exclude DOM properties, which sometimes have magical auto-update properties + not isDOMProperty(e.(PropAccess).getPropertyName()) and + // exclude xUnit.js annotations + not e instanceof XUnitAnnotation and + // exclude common patterns that are most likely intentional + not isIndirectEval(_, e) and + not isReceiverSuppressingCall(_, e, _) and + // exclude anonymous function expressions as statements; these can only arise + // from a syntax error we already flag + not exists(FunctionExpr fe, ExprStmt es | fe = e | + fe = es.getExpr() and + not exists(fe.getName()) + ) +} \ No newline at end of file diff --git a/javascript/ql/src/Expressions/UnknownDirective.ql b/javascript/ql/src/Expressions/UnknownDirective.ql index 61cda697cc3..4f027db6bbc 100644 --- a/javascript/ql/src/Expressions/UnknownDirective.ql +++ b/javascript/ql/src/Expressions/UnknownDirective.ql @@ -13,6 +13,8 @@ import javascript from Directive d where not d instanceof KnownDirective and + // ignore ":" pseudo-directive sometimes seen in dual-use shell/node.js scripts + not d.getExpr().getStringValue() = ":" and // but exclude attribute top-levels: `` not d.getParent() instanceof CodeInAttribute select d, "Unknown directive: '" + truncate(d.getDirectiveText(), 20, " ... (truncated)") + "'." diff --git a/javascript/ql/src/Security/CWE-020/IncompleteHostnameRegExp.qhelp b/javascript/ql/src/Security/CWE-020/IncompleteHostnameRegExp.qhelp index 771c446c66f..a5e0a78b8cc 100644 --- a/javascript/ql/src/Security/CWE-020/IncompleteHostnameRegExp.qhelp +++ b/javascript/ql/src/Security/CWE-020/IncompleteHostnameRegExp.qhelp @@ -68,6 +68,6 @@
  • MDN: Regular Expressions
  • OWASP: SSRF
  • -
  • OWASP: XSS Unvalidated Redirects and Forwards Cheat Sheet.
  • +
  • OWASP: XSS Unvalidated Redirects and Forwards Cheat Sheet.
  • diff --git a/javascript/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.qhelp b/javascript/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.qhelp index b23557aa557..90e6f2762e2 100644 --- a/javascript/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.qhelp +++ b/javascript/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.qhelp @@ -83,6 +83,6 @@
  • OWASP: SSRF
  • -
  • OWASP: XSS Unvalidated Redirects and Forwards Cheat Sheet.
  • +
  • OWASP: XSS Unvalidated Redirects and Forwards Cheat Sheet.
  • diff --git a/javascript/ql/src/Security/CWE-020/MissingRegExpAnchor.qhelp b/javascript/ql/src/Security/CWE-020/MissingRegExpAnchor.qhelp index 807574c5898..015e510f0fb 100644 --- a/javascript/ql/src/Security/CWE-020/MissingRegExpAnchor.qhelp +++ b/javascript/ql/src/Security/CWE-020/MissingRegExpAnchor.qhelp @@ -71,6 +71,6 @@
  • MDN: Regular Expressions
  • OWASP: SSRF
  • -
  • OWASP: XSS Unvalidated Redirects and Forwards Cheat Sheet.
  • +
  • OWASP: XSS Unvalidated Redirects and Forwards Cheat Sheet.
  • diff --git a/javascript/ql/src/Security/CWE-079/ReflectedXss.qhelp b/javascript/ql/src/Security/CWE-079/ReflectedXss.qhelp index 0502889fba0..dcbf0ba6f07 100644 --- a/javascript/ql/src/Security/CWE-079/ReflectedXss.qhelp +++ b/javascript/ql/src/Security/CWE-079/ReflectedXss.qhelp @@ -37,7 +37,7 @@ Sanitizing the user-controlled data prevents the vulnerability:
  • OWASP: -XSS +XSS (Cross Site Scripting) Prevention Cheat Sheet.
  • diff --git a/javascript/ql/src/Security/CWE-079/StoredXss.qhelp b/javascript/ql/src/Security/CWE-079/StoredXss.qhelp index 1c3fde01798..0e6ed6456c9 100644 --- a/javascript/ql/src/Security/CWE-079/StoredXss.qhelp +++ b/javascript/ql/src/Security/CWE-079/StoredXss.qhelp @@ -48,7 +48,7 @@
  • OWASP: - XSS + XSS (Cross Site Scripting) Prevention Cheat Sheet.
  • diff --git a/javascript/ql/src/Security/CWE-079/Xss.qhelp b/javascript/ql/src/Security/CWE-079/Xss.qhelp index 34ea1d821b6..c974c87b188 100644 --- a/javascript/ql/src/Security/CWE-079/Xss.qhelp +++ b/javascript/ql/src/Security/CWE-079/Xss.qhelp @@ -33,12 +33,12 @@ leaving the website vulnerable to cross-site scripting.
  • OWASP: -DOM based +DOM based XSS Prevention Cheat Sheet.
  • OWASP: -XSS +XSS (Cross Site Scripting) Prevention Cheat Sheet.
  • diff --git a/javascript/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.qhelp b/javascript/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.qhelp index 9b230852919..e0ccf71572f 100644 --- a/javascript/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.qhelp +++ b/javascript/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.qhelp @@ -45,7 +45,7 @@
  • NIST, FIPS 140 Annex a: Approved Security Functions.
  • NIST, SP 800-131A: Transitions: Recommendation for Transitioning the Use of Cryptographic Algorithms and Key Lengths.
  • OWASP: Rule + href="https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#rule---use-strong-approved-authenticated-encryption">Rule - Use strong approved cryptographic algorithms.
  • diff --git a/javascript/ql/src/Security/CWE-451/MissingXFrameOptions.qhelp b/javascript/ql/src/Security/CWE-451/MissingXFrameOptions.qhelp index ad659015d67..e73ea063b5d 100644 --- a/javascript/ql/src/Security/CWE-451/MissingXFrameOptions.qhelp +++ b/javascript/ql/src/Security/CWE-451/MissingXFrameOptions.qhelp @@ -67,7 +67,7 @@
  • OWASP: - Clickjacking Defense Cheat Sheet. + Clickjacking Defense Cheat Sheet.
  • Mozilla: diff --git a/javascript/ql/src/Security/CWE-502/UnsafeDeserialization.qhelp b/javascript/ql/src/Security/CWE-502/UnsafeDeserialization.qhelp index e7b956b10f4..5f5b77cbd7d 100644 --- a/javascript/ql/src/Security/CWE-502/UnsafeDeserialization.qhelp +++ b/javascript/ql/src/Security/CWE-502/UnsafeDeserialization.qhelp @@ -41,7 +41,7 @@ OWASP vulnerability description:
  • OWASP guidance on deserializing objects: -Deserialization Cheat Sheet. +Deserialization Cheat Sheet.
  • Neal Poole: diff --git a/javascript/ql/src/Security/CWE-601/ClientSideUrlRedirect.qhelp b/javascript/ql/src/Security/CWE-601/ClientSideUrlRedirect.qhelp index d4d36fe09bc..392df3e6cbd 100644 --- a/javascript/ql/src/Security/CWE-601/ClientSideUrlRedirect.qhelp +++ b/javascript/ql/src/Security/CWE-601/ClientSideUrlRedirect.qhelp @@ -31,7 +31,7 @@ website of their choosing, which facilitates phishing attacks: -
  • OWASP: +
  • OWASP: XSS Unvalidated Redirects and Forwards Cheat Sheet.
  • diff --git a/javascript/ql/src/Security/CWE-601/ServerSideUrlRedirect.qhelp b/javascript/ql/src/Security/CWE-601/ServerSideUrlRedirect.qhelp index cb54477dde5..2052f16146b 100644 --- a/javascript/ql/src/Security/CWE-601/ServerSideUrlRedirect.qhelp +++ b/javascript/ql/src/Security/CWE-601/ServerSideUrlRedirect.qhelp @@ -35,7 +35,7 @@ before doing the redirection: -
  • OWASP: +
  • OWASP: XSS Unvalidated Redirects and Forwards Cheat Sheet.
  • diff --git a/javascript/ql/src/Security/CWE-770/MissingRateLimiting.qhelp b/javascript/ql/src/Security/CWE-770/MissingRateLimiting.qhelp index 1832a803a77..8d4bc0ab5d0 100644 --- a/javascript/ql/src/Security/CWE-770/MissingRateLimiting.qhelp +++ b/javascript/ql/src/Security/CWE-770/MissingRateLimiting.qhelp @@ -36,7 +36,7 @@ can be used:
  • OWASP: -Denial of Service Cheat Sheet. +Denial of Service Cheat Sheet.
  • Wikipedia: Denial-of-service attack. diff --git a/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.qhelp b/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.qhelp index 2b1d2b02a31..1efdbe694b1 100644 --- a/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.qhelp +++ b/javascript/ql/src/Security/CWE-916/InsufficientPasswordHash.qhelp @@ -50,6 +50,6 @@ -
  • OWASP: Password storage.
  • +
  • OWASP: Password storage.
  • diff --git a/javascript/ql/src/Security/Summaries/ExtractFlowStepSummaries.ql b/javascript/ql/src/Security/Summaries/ExtractFlowStepSummaries.ql index e63900f16ba..1a3670013ed 100644 --- a/javascript/ql/src/Security/Summaries/ExtractFlowStepSummaries.ql +++ b/javascript/ql/src/Security/Summaries/ExtractFlowStepSummaries.ql @@ -14,17 +14,19 @@ import PortalExitSource import PortalEntrySink from - TaintTracking::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, Portal p1, - Portal p2, DataFlow::FlowLabel lbl1, DataFlow::FlowLabel lbl2 + TaintTracking::Configuration cfg, DataFlow::SourcePathNode source, DataFlow::SinkPathNode sink, Portal p1, + Portal p2, DataFlow::FlowLabel lbl1, DataFlow::FlowLabel lbl2, DataFlow::MidPathNode last where - cfg.hasFlowPath(source, sink) and + cfg = source.getConfiguration() and + last = source.getASuccessor*() and + sink = last.getASuccessor() and p1 = source.getNode().(PortalExitSource).getPortal() and p2 = sink.getNode().(PortalEntrySink).getPortal() and - lbl1 = sink.getPathSummary().getStartLabel() and - lbl2 = sink.getPathSummary().getEndLabel() and + lbl1 = last.getPathSummary().getStartLabel() and + lbl2 = last.getPathSummary().getEndLabel() and // avoid constructing infeasible paths - sink.getPathSummary().hasCall() = false and - sink.getPathSummary().hasReturn() = false and + last.getPathSummary().hasCall() = false and + last.getPathSummary().hasReturn() = false and // restrict to steps flow function parameters to returns p1.(ParameterPortal).getBasePortal() = p2.(ReturnPortal).getBasePortal() and // restrict to data/taint flow diff --git a/javascript/ql/src/Security/Summaries/ExtractSinkSummaries.ql b/javascript/ql/src/Security/Summaries/ExtractSinkSummaries.ql index 22ce077743e..588fe796811 100644 --- a/javascript/ql/src/Security/Summaries/ExtractSinkSummaries.ql +++ b/javascript/ql/src/Security/Summaries/ExtractSinkSummaries.ql @@ -11,10 +11,13 @@ import Configurations import PortalExitSource import SinkFromAnnotation -from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, Portal p +from DataFlow::Configuration cfg, DataFlow::SourcePathNode source, DataFlow::SinkPathNode sink, + Portal p, DataFlow::MidPathNode last where - cfg.hasFlowPath(source, sink) and + cfg = source.getConfiguration() and + last = source.getASuccessor*() and + sink = last.getASuccessor() and p = source.getNode().(PortalExitSource).getPortal() and // avoid constructing infeasible paths - sink.getPathSummary().hasReturn() = false -select p.toString(), source.getPathSummary().getStartLabel().toString(), cfg.toString() + last.getPathSummary().hasReturn() = false +select p.toString(), last.getPathSummary().getStartLabel().toString(), cfg.toString() diff --git a/javascript/ql/src/Security/Summaries/ExtractSourceSummaries.ql b/javascript/ql/src/Security/Summaries/ExtractSourceSummaries.ql index 81f52f23533..de7ddf04b3f 100644 --- a/javascript/ql/src/Security/Summaries/ExtractSourceSummaries.ql +++ b/javascript/ql/src/Security/Summaries/ExtractSourceSummaries.ql @@ -11,10 +11,13 @@ import Configurations import PortalEntrySink import SourceFromAnnotation -from DataFlow::Configuration cfg, DataFlow::PathNode source, DataFlow::PathNode sink, Portal p +from DataFlow::Configuration cfg, DataFlow::SourcePathNode source, DataFlow::SinkPathNode sink, + Portal p, DataFlow::MidPathNode last where - cfg.hasFlowPath(source, sink) and + cfg = source.getConfiguration() and + last = source.getASuccessor*() and + sink = last.getASuccessor() and p = sink.getNode().(PortalEntrySink).getPortal() and // avoid constructing infeasible paths - sink.getPathSummary().hasCall() = false -select p.toString(), sink.getPathSummary().getEndLabel().toString(), cfg.toString() + last.getPathSummary().hasCall() = false +select p.toString(), last.getPathSummary().getEndLabel().toString(), cfg.toString() diff --git a/javascript/ql/src/Statements/IgnoreArrayResult.qhelp b/javascript/ql/src/Statements/IgnoreArrayResult.qhelp new file mode 100644 index 00000000000..70e3cb4e5cc --- /dev/null +++ b/javascript/ql/src/Statements/IgnoreArrayResult.qhelp @@ -0,0 +1,48 @@ + + + +

    +The concat, join and slice methods are +pure and do not modify any of the inputs or the array the method is called +on. It is therefore generally an error to ignore the return value from a call +to one of these methods. +

    + +
    + + +

    +Use the returned value from the calls to concat, join +or slice. +

    + +
    + + +

    +A function extend is defined in the following example. The +function uses the concat method to add elements to the +arr array. However, the extend function has no +effect as the return value from concat is ignored: +

    + + + +

    +Assigning the returned value from the call to concat to the +arr variable fixes the error: +

    + + + +
    + + +
  • Mozilla Developer Network: Array concat.
  • +
  • Mozilla Developer Network: Array slice.
  • +
  • Mozilla Developer Network: Array join.
  • + +
    +
    diff --git a/javascript/ql/src/Statements/IgnoreArrayResult.ql b/javascript/ql/src/Statements/IgnoreArrayResult.ql new file mode 100644 index 00000000000..6f6698797f1 --- /dev/null +++ b/javascript/ql/src/Statements/IgnoreArrayResult.ql @@ -0,0 +1,45 @@ +/** + * @name Ignoring result from pure array method + * @description Ignoring the result of an array method that does not modify its receiver is generally an error. + * @kind problem + * @problem.severity warning + * @id js/ignore-array-result + * @tags maintainability + * correctness + * @precision high + */ + +import javascript +import Expressions.ExprHasNoEffect + +DataFlow::SourceNode callsArray(DataFlow::TypeBackTracker t, DataFlow::MethodCallNode call) { + isIgnoredPureArrayCall(call) and + t.start() and + result = call.getReceiver().getALocalSource() + or + exists(DataFlow::TypeBackTracker t2 | result = callsArray(t2, call).backtrack(t2, t)) +} + +DataFlow::SourceNode callsArray(DataFlow::MethodCallNode call) { + result = callsArray(DataFlow::TypeBackTracker::end(), call) +} + +predicate isIgnoredPureArrayCall(DataFlow::MethodCallNode call) { + inVoidContext(call.asExpr()) and + ( + call.getMethodName() = "concat" and + call.getNumArgument() = 1 + or + call.getMethodName() = "join" and + call.getNumArgument() < 2 + or + call.getMethodName() = "slice" and + call.getNumArgument() < 3 + ) +} + +from DataFlow::MethodCallNode call +where + callsArray(call) instanceof DataFlow::ArrayCreationNode and + not call.getReceiver().asExpr().(ArrayExpr).getSize() = 0 +select call, "Result from call to " + call.getMethodName() + " ignored." diff --git a/javascript/ql/src/Statements/UseOfReturnlessFunction.ql b/javascript/ql/src/Statements/UseOfReturnlessFunction.ql index c586cfe2497..0da7ba6fb1f 100644 --- a/javascript/ql/src/Statements/UseOfReturnlessFunction.ql +++ b/javascript/ql/src/Statements/UseOfReturnlessFunction.ql @@ -45,7 +45,7 @@ predicate benignContext(Expr e) { or // weeds out calls inside HTML-attributes. - e.getParent() instanceof CodeInAttribute or + e.getParent().(ExprStmt).getParent() instanceof CodeInAttribute or // and JSX-attributes. e = any(JSXAttribute attr).getValue() or @@ -82,17 +82,138 @@ predicate alwaysThrows(Function f) { ) } -from DataFlow::CallNode call -where - not call.isIndefinite(_) and - forex(Function f | f = call.getACallee() | +/** + * Holds if the last statement in the function is flagged by the js/useless-expression query. + */ +predicate lastStatementHasNoEffect(Function f) { + hasNoEffect(f.getExit().getAPredecessor()) +} + +/** + * Holds if `func` is a callee of `call`, and all possible callees of `call` never return a value. + */ +predicate callToVoidFunction(DataFlow::CallNode call, Function func) { + not call.isIncomplete() and + func = call.getACallee() and + forall(Function f | f = call.getACallee() | returnsVoid(f) and not isStub(f) and not alwaysThrows(f) + ) +} + +/** + * Holds if `name` is the name of a method from `Array.prototype` or Lodash, + * where that method takes a callback as parameter, + * and the callback is expected to return a value. + */ +predicate hasNonVoidCallbackMethod(string name) { + name = "every" or + name = "filter" or + name = "find" or + name = "findIndex" or + name = "flatMap" or + name = "map" or + name = "reduce" or + name = "reduceRight" or + name = "some" or + name = "sort" +} + +DataFlow::SourceNode array(DataFlow::TypeTracker t) { + t.start() and result instanceof DataFlow::ArrayCreationNode + or + exists (DataFlow::TypeTracker t2 | + result = array(t2).track(t2, t) + ) +} + +DataFlow::SourceNode array() { result = array(DataFlow::TypeTracker::end()) } + +/** + * Holds if `call` is an Array or Lodash method accepting a callback `func`, + * where the `call` expects a callback that returns an expression, + * but `func` does not return a value. + */ +predicate voidArrayCallback(DataFlow::CallNode call, Function func) { + hasNonVoidCallbackMethod(call.getCalleeName()) and + exists(int index | + index = min(int i | exists(call.getCallback(i))) and + func = call.getCallback(index).getFunction() ) and - - not benignContext(call.asExpr()) and - + returnsVoid(func) and + not isStub(func) and + not alwaysThrows(func) and + ( + call.getReceiver().getALocalSource() = array() + or + call.getCalleeNode().getALocalSource() instanceof LodashUnderscore::Member + ) +} + + +/** + * Provides classes for working with various Deferred implementations. + * It is a heuristic. The heuristic assume that a class is a promise defintion + * if the class is called "Deferred" and the method `resolve` is called on an instance. + * + * Removes some false positives in the js/use-of-returnless-function query. + */ +module Deferred { + /** + * An instance of a `Deferred` class. + * For example the result from `new Deferred()` or `new $.Deferred()`. + */ + class DeferredInstance extends DataFlow::NewNode { + // Describes both `new Deferred()`, `new $.Deferred` and other variants. + DeferredInstance() { this.getCalleeName() = "Deferred" } + + private DataFlow::SourceNode ref(DataFlow::TypeTracker t) { + t.start() and + result = this + or + exists(DataFlow::TypeTracker t2 | result = ref(t2).track(t2, t)) + } + + DataFlow::SourceNode ref() { result = ref(DataFlow::TypeTracker::end()) } + } + + /** + * A promise object created by a Deferred constructor + */ + private class DeferredPromiseDefinition extends PromiseDefinition, DeferredInstance { + DeferredPromiseDefinition() { + // hardening of the "Deferred" heuristic: a method call to `resolve`. + exists(ref().getAMethodCall("resolve")) + } + + override DataFlow::FunctionNode getExecutor() { result = getCallback(0) } + } + + /** + * A resolved promise created by a `new Deferred().resolve()` call. + */ + class ResolvedDeferredPromiseDefinition extends ResolvedPromiseDefinition { + ResolvedDeferredPromiseDefinition() { + this = any(DeferredPromiseDefinition def).ref().getAMethodCall("resolve") + } + + override DataFlow::Node getValue() { result = getArgument(0) } + } +} + +from DataFlow::CallNode call, Function func, string name, string msg +where + ( + callToVoidFunction(call, func) and + msg = "the $@ does not return anything, yet the return value is used." and + name = func.describe() + or + voidArrayCallback(call, func) and + msg = "the $@ does not return anything, yet the return value from the call to " + call.getCalleeName() + " is used." and + name = "callback function" + ) and + not benignContext(call.getEnclosingExpr()) and + not lastStatementHasNoEffect(func) and // anonymous one-shot closure. Those are used in weird ways and we ignore them. - not oneshotClosure(call.asExpr()) + not oneshotClosure(call.getEnclosingExpr()) select - call, "the function $@ does not return anything, yet the return value is used.", call.getACallee(), call.getCalleeName() - + call, msg, func, name diff --git a/javascript/ql/src/Statements/examples/IgnoreArrayResult.js b/javascript/ql/src/Statements/examples/IgnoreArrayResult.js new file mode 100644 index 00000000000..7137d5261a6 --- /dev/null +++ b/javascript/ql/src/Statements/examples/IgnoreArrayResult.js @@ -0,0 +1,5 @@ +var arr = [1,2,3]; + +function extend(others) { + arr.concat(others); +} \ No newline at end of file diff --git a/javascript/ql/src/Statements/examples/IgnoreArrayResultFixed.js b/javascript/ql/src/Statements/examples/IgnoreArrayResultFixed.js new file mode 100644 index 00000000000..1c7977e9ef0 --- /dev/null +++ b/javascript/ql/src/Statements/examples/IgnoreArrayResultFixed.js @@ -0,0 +1,5 @@ +var arr = [1,2,3]; + +function extend(others) { + arr = arr.concat(others); +} \ No newline at end of file diff --git a/javascript/ql/src/javascript.qll b/javascript/ql/src/javascript.qll index 9e75e032b1c..a6df138c592 100644 --- a/javascript/ql/src/javascript.qll +++ b/javascript/ql/src/javascript.qll @@ -28,6 +28,7 @@ import semmle.javascript.Functions import semmle.javascript.GlobalAccessPaths import semmle.javascript.HTML import semmle.javascript.HtmlSanitizers +import semmle.javascript.InclusionTests import semmle.javascript.JSDoc import semmle.javascript.JSON import semmle.javascript.JsonParsers diff --git a/javascript/ql/src/semmle/javascript/AST.qll b/javascript/ql/src/semmle/javascript/AST.qll index efc9ef53af3..66a5155458c 100644 --- a/javascript/ql/src/semmle/javascript/AST.qll +++ b/javascript/ql/src/semmle/javascript/AST.qll @@ -150,7 +150,7 @@ class TopLevel extends @toplevel, StmtContainer { /** Holds if this toplevel is minified. */ predicate isMinified() { // file name contains 'min' (not as part of a longer word) - getFile().getBaseName().regexpMatch(".*[^-.]*[-.]min([-.].*)?\\.\\w+") + getFile().getBaseName().regexpMatch(".*[^-._]*[-._]min([-._].*)?\\.\\w+") or exists(int numstmt | numstmt = strictcount(Stmt s | s.getTopLevel() = this) | // there are more than two statements per line on average diff --git a/javascript/ql/src/semmle/javascript/Classes.qll b/javascript/ql/src/semmle/javascript/Classes.qll index 5cf94d409f5..793ff5a92e4 100644 --- a/javascript/ql/src/semmle/javascript/Classes.qll +++ b/javascript/ql/src/semmle/javascript/Classes.qll @@ -1059,6 +1059,12 @@ class FieldDeclaration extends MemberDeclaration, @field { /** Holds if this is a TypeScript field marked as definitely assigned with the `!` operator. */ predicate hasDefiniteAssignmentAssertion() { hasDefiniteAssignmentAssertion(this) } + + override predicate isAmbient() { + hasDeclareKeyword(this) + or + getParent().isAmbient() + } } /** diff --git a/javascript/ql/src/semmle/javascript/Closure.qll b/javascript/ql/src/semmle/javascript/Closure.qll index 066f68ca5fa..83b8049d48f 100644 --- a/javascript/ql/src/semmle/javascript/Closure.qll +++ b/javascript/ql/src/semmle/javascript/Closure.qll @@ -230,7 +230,7 @@ module Closure { * Gets the closure namespace path addressed by the given data flow node, if any. */ string getClosureNamespaceFromSourceNode(DataFlow::SourceNode node) { - result = GlobalAccessPath::getAccessPath(node) and + node = AccessPath::getAReferenceOrAssignmentTo(result) and hasClosureNamespacePrefix(result) } @@ -238,7 +238,7 @@ module Closure { * Gets the closure namespace path written to by the given property write, if any. */ string getWrittenClosureNamespace(DataFlow::PropWrite node) { - result = GlobalAccessPath::fromRhs(node.getRhs()) and + node.getRhs() = AccessPath::getAnAssignmentTo(result) and hasClosureNamespacePrefix(result) } diff --git a/javascript/ql/src/semmle/javascript/GeneratedCode.qll b/javascript/ql/src/semmle/javascript/GeneratedCode.qll index b4877f8a8fa..0f8b161e7ae 100644 --- a/javascript/ql/src/semmle/javascript/GeneratedCode.qll +++ b/javascript/ql/src/semmle/javascript/GeneratedCode.qll @@ -137,6 +137,11 @@ private predicate isGeneratedHtml(File f) { e.getAttributeByName("name").getValue() = "generator" ) or + exists(HTML::CommentNode comment | + comment.getText().regexpMatch("\\s*Generated by [\\w-]+ \\d+\\.\\d+\\.\\d+\\s*") and + comment.getFile() = f + ) + or 20 < countStartingHtmlElements(f, _) } diff --git a/javascript/ql/src/semmle/javascript/GlobalAccessPaths.qll b/javascript/ql/src/semmle/javascript/GlobalAccessPaths.qll index 9e089fc9cf0..b19a19482d1 100644 --- a/javascript/ql/src/semmle/javascript/GlobalAccessPaths.qll +++ b/javascript/ql/src/semmle/javascript/GlobalAccessPaths.qll @@ -4,7 +4,55 @@ import javascript +deprecated module GlobalAccessPath { + /** + * DEPRECATED. Instead use `AccessPath::getAReferenceTo` with the result and parameter reversed. + */ + pragma[inline] + string fromReference(DataFlow::Node node) { + node = AccessPath::getAReferenceTo(result) + } + + /** + * DEPRECATED. Instead use `AccessPath::getAnAssignmentTo` with the result and parameter reversed. + */ + pragma[inline] + string fromRhs(DataFlow::Node node) { + node = AccessPath::getAnAssignmentTo(result) + } + + /** + * DEPRECATED. Use `AccessPath::getAReferenceOrAssignmentTo`. + */ + pragma[inline] + string getAccessPath(DataFlow::Node node) { + result = fromReference(node) + or + not exists(fromReference(node)) and + result = fromRhs(node) + } +} + +module AccessPath { + /** + * A source node that can be the root of an access path. + */ + class Root extends DataFlow::SourceNode { + Root() { + not this.accessesGlobal(_) and + not this instanceof DataFlow::PropRead and + not this instanceof PropertyProjection and + not this instanceof Closure::ClosureNamespaceAccess and + not this = DataFlow::parameterNode(any(ImmediatelyInvokedFunctionExpr iife).getAParameter()) + } + + /** Holds if this represents the root of the global access path. */ + predicate isGlobal() { + this = DataFlow::globalAccessPathRootPseudoNode() + } + } + /** * A local variable with exactly one definition, not counting implicit initialization. */ @@ -21,52 +69,68 @@ module GlobalAccessPath { } /** - * Gets the global access path referred to by `node`. + * Appends a single property name onto the access path `base`, where + * the empty string represents the empty access path. + */ + bindingset[base, prop] + private string join(string base, string prop) { + base = "" and result = prop + or + base != "" and + result = base + "." + prop + } + + /** + * Gets the access path relative to `root` referred to by `node`. * * This holds for direct references as well as for aliases * established through local data flow. * * Examples: * ``` - * function f() { - * let v = foo.bar; // reference to 'foo.bar' - * v.baz; // reference to 'foo.bar.baz' + * function f(x) { + * let a = x.f.g; // access path relative to 'x' is 'f.g' + * let b = a.h; // access path relative to 'x' is 'f.g.h' * } - * - * (function(ns) { - * ns.x; // reference to 'NS.x' - * })(NS = NS || {}); * ``` */ cached - string fromReference(DataFlow::Node node) { - result = fromReference(node.getImmediatePredecessor()) + private string fromReference(DataFlow::Node node, Root root) { + root = node and + not root.isGlobal() and + result = "" + or + result = fromReference(node.getImmediatePredecessor(), root) or exists(EffectivelyConstantVariable var | var.isCaptured() and node.asExpr() = var.getAnAccess() and - result = fromReference(var.getValue()) + result = fromReference(var.getValue(), root) ) or node.accessesGlobal(result) and - result != "undefined" + result != "undefined" and + root.isGlobal() or not node.accessesGlobal(_) and exists(DataFlow::PropRead prop | node = prop | - result = fromReference(prop.getBase()) + "." + prop.getPropertyName() + result = join(fromReference(prop.getBase(), root), prop.getPropertyName()) ) or - exists(Closure::ClosureNamespaceAccess acc | node = acc | result = acc.getClosureNamespace()) + exists(Closure::ClosureNamespaceAccess acc | node = acc | + result = acc.getClosureNamespace() and + root.isGlobal() + ) or exists(PropertyProjection proj | node = proj | proj.isSingletonProjection() and - result = fromReference(proj.getObject()) + "." + proj.getASelector() + result = join(fromReference(proj.getObject(), root), proj.getASelector().getStringValue()) ) or // Treat 'e || {}' as having the same name as 'e' exists(LogOrExpr e | node.asExpr() = e | e.getRightOperand().(ObjectExpr).getNumProperty() = 0 and - result = fromReference(e.getLeftOperand().flow()) + result = fromReference(e.getLeftOperand().flow(), root) ) or // Treat 'e && e.f' as having the same name as 'e.f' @@ -84,7 +148,7 @@ module GlobalAccessPath { rhs.getBase().(PropAccess).getQualifiedName() = name ) ) and - result = fromReference(rhs.flow()) + result = fromReference(rhs.flow(), root) ) } @@ -96,15 +160,17 @@ module GlobalAccessPath { * foo = foo || {}; * ``` */ - private predicate isSelfAssignment(DataFlow::Node rhs) { fromRhs(rhs) = fromReference(rhs) } + private predicate isSelfAssignment(DataFlow::Node rhs) { + fromRhs(rhs, DataFlow::globalAccessPathRootPseudoNode()) = fromReference(rhs, DataFlow::globalAccessPathRootPseudoNode()) + } /** - * Holds if there is an assignment to `accessPath` in `file`, not counting + * Holds if there is an assignment to the global `accessPath` in `file`, not counting * self-assignments. */ private predicate isAssignedInFile(string accessPath, File file) { exists(DataFlow::Node rhs | - fromRhs(rhs) = accessPath and + fromRhs(rhs, DataFlow::globalAccessPathRootPseudoNode()) = accessPath and not isSelfAssignment(rhs) and // Note: Avoid unneeded materialization of DataFlow::Node.getFile() rhs.getAstNode().getFile() = file @@ -112,7 +178,7 @@ module GlobalAccessPath { } /** - * Holds if `accessPath` is only assigned to from one file, not counting + * Holds if the global `accessPath` is only assigned to from one file, not counting * self-assignments. */ predicate isAssignedInUniqueFile(string accessPath) { @@ -120,66 +186,179 @@ module GlobalAccessPath { } /** - * Gets the global access path `node` is being assigned to, if any. + * Gets the access path relative to `root`, which `node` is being assigned to, if any. * * Only holds for the immediate right-hand side of an assignment or property, not * for nodes that transitively flow there. * - * For example, the class nodes below all map to `foo.bar`: + * For example, the class nodes below all map to `foo.bar` relative to `x`: + * ``` + * function f(x) { + * x.foo.bar = class {}; + * x.foo = { bar: class() }; + * let alias = x; + * alias.foo.bar = class {}; + * } + * ``` + */ + cached + private string fromRhs(DataFlow::Node node, Root root) { + exists(DataFlow::PropWrite write, string baseName | + node = write.getRhs() and + result = join(baseName, write.getPropertyName()) + | + baseName = fromReference(write.getBase(), root) + or + baseName = fromRhs(write.getBase(), root) + ) + or + exists(GlobalVariable var | + node = var.getAnAssignedExpr().flow() and + result = var.getName() and + root.isGlobal() + ) + or + exists(FunctionDeclStmt fun | + node = DataFlow::valueNode(fun) and + result = fun.getId().(GlobalVarDecl).getName() and + root.isGlobal() + ) + or + exists(ClassDeclStmt cls | + node = DataFlow::valueNode(cls) and + result = cls.getIdentifier().(GlobalVarDecl).getName() and + root.isGlobal() + ) + or + exists(EnumDeclaration decl | + node = DataFlow::valueNode(decl) and + result = decl.getIdentifier().(GlobalVarDecl).getName() and + root.isGlobal() + ) + or + exists(NamespaceDeclaration decl | + node = DataFlow::valueNode(decl) and + result = decl.getId().(GlobalVarDecl).getName() and + root.isGlobal() + ) + } + + /** + * Gets a node that refers to the given access path relative to the given `root` node, + * or `root` itself if the access path is empty. + * + * This works for direct references as well as for aliases established through local data flow. + * + * For example: + * ``` + * function f(x) { + * let a = x.f.g; // reference to (x, "f.g") + * let b = a.h; // reference to (x, "f.g.h") + * } + * ``` + */ + DataFlow::Node getAReferenceTo(Root root, string path) { + path = fromReference(result, root) and + not root.isGlobal() + } + + /** + * Gets a node that refers to the given global access path. + * + * This works for direct references as well as for aliases established through local data flow. + * + * Examples: + * ``` + * function f() { + * let v = foo.bar; // reference to 'foo.bar' + * v.baz; // reference to 'foo.bar.baz' + * } + * + * (function(ns) { + * ns.x; // reference to 'NS.x' + * })(NS = NS || {}); + * ``` + */ + DataFlow::Node getAReferenceTo(string path) { + path = fromReference(result, DataFlow::globalAccessPathRootPseudoNode()) + } + + /** + * Gets a node that is assigned to the given access path relative to the given `root` node. + * + * Only gets the immediate right-hand side of an assignment or property, not + * nodes that transitively flow there. + * + * For example, the class nodes below are all assignments to `(x, "foo.bar")`. + * ``` + * function f(x) { + * x.foo.bar = class {}; + * x.foo = { bar: class() }; + * let alias = x; + * alias.foo.bar = class {}; + * } + * ``` + */ + DataFlow::Node getAnAssignmentTo(Root root, string path) { + path = fromRhs(result, root) and + not root.isGlobal() + } + + /** + * Gets a node that is assigned to the given global access path. + * + * Only gets the immediate right-hand side of an assignment or property or a global declaration, + * not nodes that transitively flow there. + * + * For example, the class nodes below are all assignmetns to `foo.bar`: * ``` * foo.bar = class {}; - * * foo = { bar: class {} }; - * * (function(f) { * f.bar = class {} * })(foo = foo || {}); * ``` */ - cached - string fromRhs(DataFlow::Node node) { - exists(DataFlow::SourceNode base, string baseName, string name | - node = base.getAPropertyWrite(name).getRhs() and - result = baseName + "." + name - | - baseName = fromReference(base) - or - baseName = fromRhs(base) - ) - or - exists(GlobalVariable var | - node = var.getAnAssignedExpr().flow() and - result = var.getName() - ) - or - exists(FunctionDeclStmt fun | - node = DataFlow::valueNode(fun) and - result = fun.getId().(GlobalVarDecl).getName() - ) - or - exists(ClassDeclStmt cls | - node = DataFlow::valueNode(cls) and - result = cls.getIdentifier().(GlobalVarDecl).getName() - ) - or - exists(EnumDeclaration decl | - node = DataFlow::valueNode(decl) and - result = decl.getIdentifier().(GlobalVarDecl).getName() - ) - or - exists(NamespaceDeclaration decl | - node = DataFlow::valueNode(decl) and - result = decl.getId().(GlobalVarDecl).getName() - ) + DataFlow::Node getAnAssignmentTo(string path) { + path = fromRhs(result, DataFlow::globalAccessPathRootPseudoNode()) } /** - * Gets the global access path referenced by or assigned to `node`. + * Gets a node that refers to or is assigned to the given global access path. + * + * See `getAReferenceTo` and `getAnAssignmentTo` for more details. */ - string getAccessPath(DataFlow::Node node) { - result = fromReference(node) + DataFlow::Node getAReferenceOrAssignmentTo(string path) { + result = getAReferenceTo(path) or - not exists(fromReference(node)) and - result = fromRhs(node) + result = getAnAssignmentTo(path) + } + + /** + * Gets a node that refers to or is assigned to the given access path. + * + * See `getAReferenceTo` and `getAnAssignmentTo` for more details. + */ + DataFlow::Node getAReferenceOrAssignmentTo(Root root, string path) { + result = getAReferenceTo(root, path) + or + result = getAnAssignmentTo(root, path) + } + + /** + * Holds if there is a step from `pred` to `succ` through an assignment to an access path. + */ + pragma[inline] + predicate step(DataFlow::Node pred, DataFlow::Node succ) { + exists(string name, Root root | + pred = getAnAssignmentTo(root, name) and + succ = getAReferenceTo(root, name) + ) + or + exists(string name | + pred = getAnAssignmentTo(name) and + succ = getAReferenceTo(name) and + isAssignedInUniqueFile(name) + ) } } diff --git a/javascript/ql/src/semmle/javascript/InclusionTests.qll b/javascript/ql/src/semmle/javascript/InclusionTests.qll new file mode 100644 index 00000000000..7a90dbf1583 --- /dev/null +++ b/javascript/ql/src/semmle/javascript/InclusionTests.qll @@ -0,0 +1,173 @@ +/** + * Contains classes for recognizing array and string inclusion tests. + */ +private import javascript + +/** + * A expression that checks if an element is contained in an array + * or is a substring of another string. + * + * Examples: + * ``` + * A.includes(B) + * A.indexOf(B) !== -1 + * A.indexOf(B) >= 0 + * ~A.indexOf(B) + * ``` + */ +class InclusionTest extends DataFlow::Node { + InclusionTest::Range range; + + InclusionTest() { this = range } + + /** Gets the `A` in `A.includes(B)`. */ + DataFlow::Node getContainerNode() { result = range.getContainerNode() } + + /** Gets the `B` in `A.includes(B)`. */ + DataFlow::Node getContainedNode() { result = range.getContainedNode() } + + /** + * Gets the polarity of the check. + * + * If the polarity is `false` the check returns `true` if the container does not contain + * the given element. + */ + boolean getPolarity() { result = range.getPolarity() } +} + +module InclusionTest { + /** + * A expression that is equivalent to `A.includes(B)` or `!A.includes(B)`. + * + * Note that this also includes calls to the array method named `includes`. + */ + abstract class Range extends DataFlow::Node { + /** Gets the `A` in `A.includes(B)`. */ + abstract DataFlow::Node getContainerNode(); + + /** Gets the `B` in `A.includes(B)`. */ + abstract DataFlow::Node getContainedNode(); + + /** + * Gets the polarity of the check. + * + * If the polarity is `false` the check returns `true` if the container does not contain + * the given element. + */ + boolean getPolarity() { result = true } + } + + /** + * A call to a method named `includes`, assumed to refer to `String.prototype.includes` + * or `Array.prototype.includes`. + */ + private class Includes_Native extends Range, DataFlow::MethodCallNode { + Includes_Native() { + getMethodName() = "includes" and + getNumArgument() = 1 + } + + override DataFlow::Node getContainerNode() { result = getReceiver() } + + override DataFlow::Node getContainedNode() { result = getArgument(0) } + } + + /** + * A call to `_.includes` or similar, assumed to operate on strings. + */ + private class Includes_Library extends Range, DataFlow::CallNode { + Includes_Library() { + exists(string name | + this = LodashUnderscore::member(name).getACall() and + (name = "includes" or name = "include" or name = "contains") + or + this = Closure::moduleImport("goog.string." + name).getACall() and + (name = "contains" or name = "caseInsensitiveContains") + ) + } + + override DataFlow::Node getContainerNode() { result = getArgument(0) } + + override DataFlow::Node getContainedNode() { result = getArgument(1) } + } + + /** + * A check of form `A.indexOf(B) !== -1` or similar. + */ + private class Includes_IndexOfEquals extends Range, DataFlow::ValueNode { + MethodCallExpr indexOf; + override EqualityTest astNode; + + Includes_IndexOfEquals() { + exists(Expr index | astNode.hasOperands(indexOf, index) | + // one operand is of the form `whitelist.indexOf(x)` + indexOf.getMethodName() = "indexOf" and + // and the other one is -1 + index.getIntValue() = -1 + ) + } + + override DataFlow::Node getContainerNode() { result = indexOf.getReceiver().flow() } + + override DataFlow::Node getContainedNode() { result = indexOf.getArgument(0).flow() } + + override boolean getPolarity() { result = astNode.getPolarity().booleanNot() } + } + + /** + * A check of form `A.indexOf(B) >= 0` or similar. + */ + private class Includes_IndexOfRelational extends Range, DataFlow::ValueNode { + MethodCallExpr indexOf; + override RelationalComparison astNode; + boolean polarity; + + Includes_IndexOfRelational() { + exists(Expr lesser, Expr greater | + astNode.getLesserOperand() = lesser and + astNode.getGreaterOperand() = greater and + indexOf.getMethodName() = "indexOf" and + indexOf.getNumArgument() = 1 + | + polarity = true and + greater = indexOf and + ( + lesser.getIntValue() = 0 and astNode.isInclusive() + or + lesser.getIntValue() = -1 and not astNode.isInclusive() + ) + or + polarity = false and + lesser = indexOf and + ( + greater.getIntValue() = -1 and astNode.isInclusive() + or + greater.getIntValue() = 0 and not astNode.isInclusive() + ) + ) + } + + override DataFlow::Node getContainerNode() { result = indexOf.getReceiver().flow() } + + override DataFlow::Node getContainedNode() { result = indexOf.getArgument(0).flow() } + + override boolean getPolarity() { result = polarity } + } + + /** + * An expression of form `~A.indexOf(B)` which, when coerced to a boolean, is equivalent to `A.includes(B)`. + */ + private class Includes_IndexOfBitwise extends Range, DataFlow::ValueNode { + MethodCallExpr indexOf; + override BitNotExpr astNode; + + Includes_IndexOfBitwise() { + astNode.getOperand() = indexOf and + indexOf.getMethodName() = "indexOf" + } + + override DataFlow::Node getContainerNode() { result = indexOf.getReceiver().flow() } + + override DataFlow::Node getContainedNode() { result = indexOf.getArgument(0).flow() } + } +} diff --git a/javascript/ql/src/semmle/javascript/JSDoc.qll b/javascript/ql/src/semmle/javascript/JSDoc.qll index 806a9477ba6..c080061bc7c 100644 --- a/javascript/ql/src/semmle/javascript/JSDoc.qll +++ b/javascript/ql/src/semmle/javascript/JSDoc.qll @@ -582,7 +582,7 @@ module JSDoc { * within this container. */ string resolveAlias(string alias) { - result = GlobalAccessPath::getAccessPath(getNodeFromAlias(alias)) + getNodeFromAlias(alias) = AccessPath::getAReferenceOrAssignmentTo(result) } /** diff --git a/javascript/ql/src/semmle/javascript/StringOps.qll b/javascript/ql/src/semmle/javascript/StringOps.qll index f33dbd9f74d..d916e8e469d 100644 --- a/javascript/ql/src/semmle/javascript/StringOps.qll +++ b/javascript/ql/src/semmle/javascript/StringOps.qll @@ -185,162 +185,15 @@ module StringOps { /** * A expression that is equivalent to `A.includes(B)` or `!A.includes(B)`. * - * Note that this also includes calls to the array method named `includes`. + * Note that this class is equivalent to `InclusionTest`, which also matches + * inclusion tests on array objects. */ - class Includes extends DataFlow::Node { - Includes::Range range; - - Includes() { this = range } - + class Includes extends InclusionTest { /** Gets the `A` in `A.includes(B)`. */ - DataFlow::Node getBaseString() { result = range.getBaseString() } + DataFlow::Node getBaseString() { result = getContainerNode() } /** Gets the `B` in `A.includes(B)`. */ - DataFlow::Node getSubstring() { result = range.getSubstring() } - - /** - * Gets the polarity of the check. - * - * If the polarity is `false` the check returns `true` if the string does not contain - * the given substring. - */ - boolean getPolarity() { result = range.getPolarity() } - } - - module Includes { - /** - * A expression that is equivalent to `A.includes(B)` or `!A.includes(B)`. - * - * Note that this also includes calls to the array method named `includes`. - */ - abstract class Range extends DataFlow::Node { - /** Gets the `A` in `A.includes(B)`. */ - abstract DataFlow::Node getBaseString(); - - /** Gets the `B` in `A.includes(B)`. */ - abstract DataFlow::Node getSubstring(); - - /** - * Gets the polarity of the check. - * - * If the polarity is `false` the check returns `true` if the string does not contain - * the given substring. - */ - boolean getPolarity() { result = true } - } - - /** - * A call to a method named `includes`, assumed to refer to `String.prototype.includes`. - */ - private class Includes_Native extends Range, DataFlow::MethodCallNode { - Includes_Native() { - getMethodName() = "includes" and - getNumArgument() = 1 - } - - override DataFlow::Node getBaseString() { result = getReceiver() } - - override DataFlow::Node getSubstring() { result = getArgument(0) } - } - - /** - * A call to `_.includes` or similar, assumed to operate on strings. - */ - private class Includes_Library extends Range, DataFlow::CallNode { - Includes_Library() { - exists(string name | - this = LodashUnderscore::member(name).getACall() and - (name = "includes" or name = "include" or name = "contains") - or - this = Closure::moduleImport("goog.string." + name).getACall() and - (name = "contains" or name = "caseInsensitiveContains") - ) - } - - override DataFlow::Node getBaseString() { result = getArgument(0) } - - override DataFlow::Node getSubstring() { result = getArgument(1) } - } - - /** - * A check of form `A.indexOf(B) !== -1` or similar. - */ - private class Includes_IndexOfEquals extends Range, DataFlow::ValueNode { - MethodCallExpr indexOf; - override EqualityTest astNode; - - Includes_IndexOfEquals() { - exists(Expr index | astNode.hasOperands(indexOf, index) | - // one operand is of the form `whitelist.indexOf(x)` - indexOf.getMethodName() = "indexOf" and - // and the other one is -1 - index.getIntValue() = -1 - ) - } - - override DataFlow::Node getBaseString() { result = indexOf.getReceiver().flow() } - - override DataFlow::Node getSubstring() { result = indexOf.getArgument(0).flow() } - - override boolean getPolarity() { result = astNode.getPolarity().booleanNot() } - } - - /** - * A check of form `A.indexOf(B) >= 0` or similar. - */ - private class Includes_IndexOfRelational extends Range, DataFlow::ValueNode { - MethodCallExpr indexOf; - override RelationalComparison astNode; - boolean polarity; - - Includes_IndexOfRelational() { - exists(Expr lesser, Expr greater | - astNode.getLesserOperand() = lesser and - astNode.getGreaterOperand() = greater and - indexOf.getMethodName() = "indexOf" and - indexOf.getNumArgument() = 1 - | - polarity = true and - greater = indexOf and - ( - lesser.getIntValue() = 0 and astNode.isInclusive() - or - lesser.getIntValue() = -1 and not astNode.isInclusive() - ) - or - polarity = false and - lesser = indexOf and - ( - greater.getIntValue() = -1 and astNode.isInclusive() - or - greater.getIntValue() = 0 and not astNode.isInclusive() - ) - ) - } - - override DataFlow::Node getBaseString() { result = indexOf.getReceiver().flow() } - - override DataFlow::Node getSubstring() { result = indexOf.getArgument(0).flow() } - - override boolean getPolarity() { result = polarity } - } - - /** - * An expression of form `~A.indexOf(B)` which, when coerced to a boolean, is equivalent to `A.includes(B)`. - */ - private class Includes_IndexOfBitwise extends Range, DataFlow::ValueNode { - MethodCallExpr indexOf; - override BitNotExpr astNode; - - Includes_IndexOfBitwise() { - astNode.getOperand() = indexOf and - indexOf.getMethodName() = "indexOf" - } - - override DataFlow::Node getBaseString() { result = indexOf.getReceiver().flow() } - - override DataFlow::Node getSubstring() { result = indexOf.getArgument(0).flow() } - } + DataFlow::Node getSubstring() { result = getContainedNode() } } /** diff --git a/javascript/ql/src/semmle/javascript/TypeScript.qll b/javascript/ql/src/semmle/javascript/TypeScript.qll index 005f9a5ee12..597c059eb05 100644 --- a/javascript/ql/src/semmle/javascript/TypeScript.qll +++ b/javascript/ql/src/semmle/javascript/TypeScript.qll @@ -914,20 +914,49 @@ class TypeofTypeExpr extends @typeoftypeexpr, TypeExpr { } /** - * A type of form `E is T` where `E` is a parameter name or `this`, and `T` is a type. + * A function return type that refines the type of one of its parameters or `this`. * - * This can only occur as the return type of a function type. + * Examples: + * ```js + * function f(x): x is string {} + * function f(x): asserts x is string {} + * function f(x): asserts x {} + * ``` */ -class IsTypeExpr extends @istypeexpr, TypeExpr { +class PredicateTypeExpr extends @predicatetypeexpr, TypeExpr { /** * Gets the parameter name or `this` token `E` in `E is T`. */ VarTypeAccess getParameterName() { result = this.getChildTypeExpr(0) } /** - * Gets the type `T` in `E is T`. + * Gets the type `T` in `E is T` or `asserts E is T`. + * + * Has no results for types of form `asserts E`. */ TypeExpr getPredicateType() { result = this.getChildTypeExpr(1) } + + /** + * Holds if this is a type of form `asserts E is T` or `asserts E`. + */ + predicate hasAssertsKeyword() { + hasAssertsKeyword(this) + } +} + +/** + * A function return type of form `x is T` or `asserts x is T`. + * + * Examples: + * ```js + * function f(x): x is string {} + * function f(x): asserts x is string {} + * ``` + */ +class IsTypeExpr extends PredicateTypeExpr { + IsTypeExpr() { + exists(getPredicateType()) + } } /** @@ -966,15 +995,16 @@ class ReadonlyTypeExpr extends @readonlytypeexpr, TypeExpr { * * This can occur as * - part of the operand to a `typeof` type, or - * - as the first operand to an `is` type. + * - as the first operand to a predicate type * * For example, it may occur as the `E` in these examples: * ``` * var x : typeof E * function f(...) : E is T {} + * function f(...) : asserts E {} * ``` * - * In the latter case, this may also refer to the pseudo-variable `this`. + * In the latter two cases, this may also refer to the pseudo-variable `this`. */ class VarTypeAccess extends @vartypeaccess, TypeExpr { } diff --git a/javascript/ql/src/semmle/javascript/dataflow/BackwardExploration.qll b/javascript/ql/src/semmle/javascript/dataflow/BackwardExploration.qll new file mode 100644 index 00000000000..caf67e6db7f --- /dev/null +++ b/javascript/ql/src/semmle/javascript/dataflow/BackwardExploration.qll @@ -0,0 +1,44 @@ +/** + * Provides machinery for performing backward data-flow exploration. + * + * Importing this module effectively makes all data-flow and taint-tracking configurations + * ignore their `isSource` predicate. Instead, flow is tracked from any _initial node_ (that is, + * a node without incoming flow) to a sink node. All initial nodes are then treated as source + * nodes. + * + * Data-flow exploration cannot be used with configurations depending on other configurations. + * + * NOTE: This library should only be used for debugging, not in production code. Backward + * exploration in particular does not scale on non-trivial code bases and hence is of limited + * usefulness as it stands. + */ + +import javascript + +private class BackwardExploringConfiguration extends DataFlow::Configuration { + DataFlow::Configuration cfg; + + BackwardExploringConfiguration() { + this = cfg + } + + override predicate isSource(DataFlow::Node node) { any() } + + override predicate isSource(DataFlow::Node node, DataFlow::FlowLabel lbl) { any() } + + override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { + exists(DataFlow::PathNode src, DataFlow::PathNode snk | hasFlowPath(src, snk) | + source = src.getNode() and + sink = snk.getNode() + ) + } + + override predicate hasFlowPath(DataFlow::SourcePathNode source, DataFlow::SinkPathNode sink) { + exists(DataFlow::MidPathNode first | + source.getConfiguration() = this and + source.getASuccessor() = first and + not exists(DataFlow::MidPathNode mid | mid.getASuccessor() = first) and + first.getASuccessor*() = sink + ) + } +} diff --git a/javascript/ql/src/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/src/semmle/javascript/dataflow/Configuration.qll index f8ab42444c4..426a2069fd5 100644 --- a/javascript/ql/src/semmle/javascript/dataflow/Configuration.qll +++ b/javascript/ql/src/semmle/javascript/dataflow/Configuration.qll @@ -147,7 +147,7 @@ abstract class Configuration extends string { */ predicate isBarrier(DataFlow::Node node) { exists(BarrierGuardNode guard | - isBarrierGuard(guard) and + isBarrierGuardInternal(guard) and guard.internalBlocks(node, "") ) } @@ -181,7 +181,7 @@ abstract class Configuration extends string { */ predicate isLabeledBarrier(DataFlow::Node node, FlowLabel lbl) { exists(BarrierGuardNode guard | - isBarrierGuard(guard) and + isBarrierGuardInternal(guard) and guard.internalBlocks(node, lbl) ) or @@ -198,6 +198,12 @@ abstract class Configuration extends string { */ predicate isBarrierGuard(BarrierGuardNode guard) { none() } + private predicate isBarrierGuardInternal(BarrierGuardNode guard) { + isBarrierGuard(guard) + or + guard.(AdditionalBarrierGuardNode).appliesTo(this) + } + /** * Holds if data may flow from `source` to `sink` for this configuration. */ @@ -302,44 +308,22 @@ abstract class BarrierGuardNode extends DataFlow::Node { exists(SsaRefinementNode ref, boolean outcome | nd = DataFlow::ssaDefinitionNode(ref) and forex(SsaVariable input | input = ref.getAnInput() | - asExpr() = ref.getGuard().getTest() and + getEnclosingExpr() = ref.getGuard().getTest() and outcome = ref.getGuard().(ConditionGuardNode).getOutcome() and - internalBlocksExpr(outcome, input.getAUse(), label) + barrierGuardBlocksExpr(this, outcome, input.getAUse(), label) ) ) or // 2) `nd` is an instance of an access path `p`, and dominated by a barrier for `p` exists(AccessPath p, BasicBlock bb, ConditionGuardNode cond, boolean outcome | nd = DataFlow::valueNode(p.getAnInstanceIn(bb)) and - asExpr() = cond.getTest() and + getEnclosingExpr() = cond.getTest() and outcome = cond.getOutcome() and - internalBlocksAccessPath(outcome, p, label) and + barrierGuardBlocksAccessPath(this, outcome, p, label) and cond.dominates(bb) ) } - /** - * Holds if data flow node `nd` acts as a barrier for data flow. - * - * `label` is bound to the blocked label, or the empty string if all labels should be blocked. - */ - private predicate internalBlocksExpr(boolean outcome, Expr test, string label) { - blocks(outcome, test) and label = "" - or - blocks(outcome, test, label) - } - - /** - * Holds if data flow node `nd` acts as a barrier for data flow due to aliasing through - * an access path. - * - * `label` is bound to the blocked label, or the empty string if all labels should be blocked. - */ - pragma[noinline] - private predicate internalBlocksAccessPath(boolean outcome, AccessPath ap, string label) { - internalBlocksExpr(outcome, ap.getAnInstance(), label) - } - /** * Holds if this node blocks expression `e` provided it evaluates to `outcome`. * @@ -353,6 +337,32 @@ abstract class BarrierGuardNode extends DataFlow::Node { predicate blocks(boolean outcome, Expr e, FlowLabel label) { none() } } +/** + * Holds if data flow node `nd` acts as a barrier for data flow. + * + * `label` is bound to the blocked label, or the empty string if all labels should be blocked. + */ +private predicate barrierGuardBlocksExpr(BarrierGuardNode guard, boolean outcome, Expr test, string label) { + guard.blocks(outcome, test) and label = "" + or + guard.blocks(outcome, test, label) + or + // Handle labelled barrier guard functions specially, to avoid negative recursion + // through the non-abstract 3-argument version of blocks(). + guard.(AdditionalBarrierGuardCall).internalBlocksLabel(outcome, test, label) +} + +/** + * Holds if data flow node `nd` acts as a barrier for data flow due to aliasing through + * an access path. + * + * `label` is bound to the blocked label, or the empty string if all labels should be blocked. + */ +pragma[noinline] +private predicate barrierGuardBlocksAccessPath(BarrierGuardNode guard, boolean outcome, AccessPath ap, string label) { + barrierGuardBlocksExpr(guard, outcome, ap.getAnInstance(), label) +} + /** * A guard node that only blocks specific labels. */ @@ -454,6 +464,7 @@ private class FlowStepThroughImport extends AdditionalFlowStep, DataFlow::ValueN private predicate basicFlowStep( DataFlow::Node pred, DataFlow::Node succ, PathSummary summary, DataFlow::Configuration cfg ) { + isLive() and isRelevantForward(pred, cfg) and ( // Local flow @@ -888,9 +899,9 @@ private predicate flowsTo( PathNode flowsource, DataFlow::Node source, SinkPathNode flowsink, DataFlow::Node sink, DataFlow::Configuration cfg ) { - flowsource = MkPathNode(source, cfg, _) and + flowsource.wraps(source, cfg) and flowsink = flowsource.getASuccessor*() and - flowsink = MkPathNode(sink, id(cfg), _) + flowsink.wraps(sink, id(cfg)) } /** @@ -933,19 +944,45 @@ private predicate onPath(DataFlow::Node nd, DataFlow::Configuration cfg, PathSum } /** - * Holds if `cfg` has at least one source and at least one sink. + * Holds if there is a configuration that has at least one source and at least one sink. */ pragma[noinline] -private predicate isLive(DataFlow::Configuration cfg) { isSource(_, cfg, _) and isSink(_, cfg, _) } +private predicate isLive() { exists(DataFlow::Configuration cfg | isSource(_, cfg, _) and isSink(_, cfg, _)) } /** * A data flow node on an inter-procedural path from a source. */ private newtype TPathNode = - MkPathNode(DataFlow::Node nd, DataFlow::Configuration cfg, PathSummary summary) { - isLive(cfg) and + MkSourceNode(DataFlow::Node nd, DataFlow::Configuration cfg) { isSourceNode(nd, cfg, _) } + or + MkMidNode(DataFlow::Node nd, DataFlow::Configuration cfg, PathSummary summary) { + isLive() and onPath(nd, cfg, summary) } + or + MkSinkNode(DataFlow::Node nd, DataFlow::Configuration cfg) { isSinkNode(nd, cfg, _) } + +/** + * Holds if `nd` is a source node for configuration `cfg`, and there is a path from `nd` to a sink + * with the given `summary`. + */ +private predicate isSourceNode(DataFlow::Node nd, DataFlow::Configuration cfg, PathSummary summary) { + exists(FlowLabel lbl | summary = PathSummary::level(lbl) | + isSource(nd, cfg, lbl) and + isLive() and + onPath(nd, cfg, summary) + ) +} + +/** + * Holds if `nd` is a sink node for configuration `cfg`, and there is a path from a source to `nd` + * with the given `summary`. + */ +private predicate isSinkNode(DataFlow::Node nd, DataFlow::Configuration cfg, PathSummary summary) { + isSink(nd, cfg, summary.getEndLabel()) and + isLive() and + onPath(nd, cfg, summary) +} /** * Maps `cfg` to itself. @@ -957,48 +994,46 @@ bindingset[cfg, result] private DataFlow::Configuration id(DataFlow::Configuration cfg) { result >= cfg and cfg >= result } /** - * A data flow node on an inter-procedural path from a source to a sink. + * A data-flow node on an inter-procedural path from a source to a sink. * - * A path node is a triple `(nd, cfg, summary)` where `nd` is a data flow node and `cfg` - * is a data flow tracking configuration such that `nd` is on a path from a source to a - * sink under `cfg` summarized by `summary`. + * A path node wraps a data-flow node `nd` and a data-flow configuration `cfg` such that `nd` is + * on a path from a source to a sink under `cfg`. + * + * There are three kinds of path nodes: + * + * - source nodes: wrapping a source node and a configuration such that there is a path from that + * source to some sink under the configuration; + * - sink nodes: wrapping a sink node and a configuration such that there is a path from some source + * to that sink under the configuration; + * - mid nodes: wrapping a node, a configuration and a path summary such that there is a path from + * some source to the node with the given summary that can be extended to a path to some sink node, + * all under the configuration. */ class PathNode extends TPathNode { DataFlow::Node nd; - DataFlow::Configuration cfg; - PathSummary summary; + Configuration cfg; - PathNode() { this = MkPathNode(nd, cfg, summary) } + PathNode() { + this = MkSourceNode(nd, cfg) or + this = MkMidNode(nd, cfg, _) or + this = MkSinkNode(nd, cfg) + } - /** Gets the underlying data flow node of this path node. */ - DataFlow::Node getNode() { result = nd } + /** Holds if this path node wraps data-flow node `nd` and configuration `c`. */ + predicate wraps(DataFlow::Node n, DataFlow::Configuration c) { + nd = n and cfg = c + } - /** Gets the underlying data flow tracking configuration of this path node. */ + /** Gets the underlying configuration of this path node. */ DataFlow::Configuration getConfiguration() { result = cfg } - /** Gets the summary of the path underlying this path node. */ - PathSummary getPathSummary() { result = summary } - - /** - * Gets a successor node of this path node, including hidden nodes. - */ - private PathNode getASuccessorInternal() { - exists(DataFlow::Node succ, PathSummary newSummary | - flowStep(nd, id(cfg), succ, newSummary) and - result = MkPathNode(succ, id(cfg), summary.append(newSummary)) - ) - } - - /** - * Gets a successor of this path node, if it is a hidden node. - */ - private PathNode getAHiddenSuccessor() { - isHidden() and - result = getASuccessorInternal() - } + /** Gets the underlying data-flow node of this path node. */ + DataFlow::Node getNode() { result = nd } /** Gets a successor node of this path node. */ - PathNode getASuccessor() { result = getASuccessorInternal().getAHiddenSuccessor*() } + final PathNode getASuccessor() { + result = getASuccessor(this) + } /** Gets a textual representation of this path node. */ string toString() { result = nd.toString() } @@ -1015,6 +1050,68 @@ class PathNode extends TPathNode { ) { nd.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) } +} + +/** Gets the mid node corresponding to `src`. */ +private MidPathNode initialMidNode(SourcePathNode src) { + exists(DataFlow::Node nd, Configuration cfg, PathSummary summary | + result.wraps(nd, cfg, summary) and + src = MkSourceNode(nd, cfg) and + isSourceNode(nd, cfg, summary) + ) +} + +/** Gets the mid node corresponding to `snk`. */ +private MidPathNode finalMidNode(SinkPathNode snk) { + exists(DataFlow::Node nd, Configuration cfg, PathSummary summary | + result.wraps(nd, cfg, summary) and + snk = MkSinkNode(nd, cfg) and + isSinkNode(nd, cfg, summary) + ) +} + +/** + * Gets a node to which data from `nd` may flow in one step. + */ +private PathNode getASuccessor(PathNode nd) { + // source node to mid node + result = initialMidNode(nd) + or + // mid node to mid node + exists(Configuration cfg, DataFlow::Node predNd, PathSummary summary, DataFlow::Node succNd, PathSummary newSummary | + nd = MkMidNode(predNd, cfg, summary) and + flowStep(predNd, id(cfg), succNd, newSummary) and + result = MkMidNode(succNd, id(cfg), summary.append(newSummary)) + ) + or + // mid node to sink node + nd = finalMidNode(result) +} + +private PathNode getASuccessorIfHidden(PathNode nd) { + nd.(MidPathNode).isHidden() and + result = getASuccessor(nd) +} + +/** + * A path node corresponding to an intermediate node on a path from a source to a sink. + * + * A mid node is a triple `(nd, cfg, summary)` where `nd` is a data-flow node and `cfg` + * is a configuration such that `nd` is on a path from a source to a sink under `cfg` + * summarized by `summary`. + */ +class MidPathNode extends PathNode, MkMidNode { + PathSummary summary; + + MidPathNode() { this = MkMidNode(nd, cfg, summary) } + + /** Gets the summary of the path underlying this path node. */ + PathSummary getPathSummary() { result = summary } + + /** Holds if this path node wraps data-flow node `nd`, configuration `c` and summary `s`. */ + predicate wraps(DataFlow::Node n, DataFlow::Configuration c, PathSummary s) { + nd = n and cfg = c and summary = s + } /** * Holds if this node is hidden from paths in path explanation queries, except @@ -1034,20 +1131,15 @@ class PathNode extends TPathNode { /** * A path node corresponding to a flow source. */ -class SourcePathNode extends PathNode { - SourcePathNode() { - exists(FlowLabel lbl | - summary = PathSummary::level(lbl) and - isSource(nd, cfg, lbl) - ) - } +class SourcePathNode extends PathNode, MkSourceNode { + SourcePathNode() { this = MkSourceNode(nd, cfg) } } /** * A path node corresponding to a flow sink. */ -class SinkPathNode extends PathNode { - SinkPathNode() { isSink(nd, cfg, summary.getEndLabel()) } +class SinkPathNode extends PathNode, MkSinkNode { + SinkPathNode() { this = MkSinkNode(nd, cfg) } } /** @@ -1056,11 +1148,158 @@ class SinkPathNode extends PathNode { module PathGraph { /** Holds if `nd` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode nd) { - not nd.isHidden() or - nd instanceof SourcePathNode or - nd instanceof SinkPathNode + not nd.(MidPathNode).isHidden() + } + + /** + * Gets a node to which data from `nd` may flow in one step, skipping over hidden nodes. + */ + private PathNode succ0(PathNode nd) { + result = getASuccessorIfHidden*(nd.getASuccessor()) and + // skip hidden nodes + nodes(nd) and nodes(result) + } + + /** + * Gets a node to which data from `nd` may flow in one step, where outgoing edges from intermediate + * nodes are merged with any incoming edge from a corresponding source node. + * + * For example, assume that `src` is a source node for `nd1`, which has `nd2` as its direct + * successor. Then `succ0` will yield two edges `src` → `nd1` and `nd1` → `nd2`, + * to which `succ1` will add the edge `src` → `nd2`. + */ + private PathNode succ1(PathNode nd) { + result = succ0(nd) + or + result = succ0(initialMidNode(nd)) + } + + /** + * Gets a node to which data from `nd` may flow in one step, where incoming edges into intermediate + * nodes are merged with any outgoing edge to a corresponding sink node. + * + * For example, assume that `snk` is a source node for `nd2`, which has `nd1` as its direct + * predecessor. Then `succ1` will yield two edges `nd1` → `nd2` and `nd2` → `snk`, + * while `succ2` will yield just one edge `nd1` → `snk`. + */ + private PathNode succ2(PathNode nd) { + result = succ1(nd) + or + succ1(nd) = finalMidNode(result) } /** Holds if `pred` → `succ` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode pred, PathNode succ) { pred.getASuccessor() = succ } + query predicate edges(PathNode pred, PathNode succ) { + succ = succ2(pred) and + // skip over uninteresting edges + not succ = initialMidNode(pred) and + not pred = finalMidNode(succ) + } +} + + + +/** + * Gets an operand of the given `&&` operator. + * + * We use this to construct the transitive closure over a relation + * that does not include all of `BinaryExpr.getAnOperand`. + */ +private Expr getALogicalAndOperand(LogAndExpr e) { + result = e.getAnOperand() +} + +/** + * Gets an operand of the given `||` operator. + * + * We use this to construct the transitive closure over a relation + * that does not include all of `BinaryExpr.getAnOperand`. + */ +private Expr getALogicalOrOperand(LogOrExpr e) { + result = e.getAnOperand() +} + +/** + * A `BarrierGuardNode` that controls which data flow + * configurations it is used in. + * + * Note: For performance reasons, all subclasses of this class should be part + * of the standard library. Override `Configuration::isBarrierGuard` + * for analysis-specific barrier guards. + */ +abstract class AdditionalBarrierGuardNode extends BarrierGuardNode { + abstract predicate appliesTo(Configuration cfg); +} + +/** + * A function that returns the result of a barrier guard. + */ +private class BarrierGuardFunction extends Function { + DataFlow::ParameterNode sanitizedParameter; + BarrierGuardNode guard; + boolean guardOutcome; + string label; + + BarrierGuardFunction() { + exists(Expr e | + exists(Expr returnExpr | + returnExpr = guard.asExpr() + or + // ad hoc support for conjunctions: + getALogicalAndOperand+(returnExpr) = guard.asExpr() and guardOutcome = true + or + // ad hoc support for disjunctions: + getALogicalOrOperand+(returnExpr) = guard.asExpr() and guardOutcome = false + | + exists(SsaExplicitDefinition ssa | + ssa.getDef().getSource() = returnExpr and + ssa.getVariable().getAUse() = getAReturnedExpr() + ) + or + returnExpr = getAReturnedExpr() + ) and + sanitizedParameter.flowsToExpr(e) and + barrierGuardBlocksExpr(guard, guardOutcome, e, label) + ) and + getNumParameter() = 1 and + sanitizedParameter.getParameter() = getParameter(0) + } + + /** + * Holds if this function sanitizes argument `e` of call `call`, provided the call evaluates to `outcome`. + */ + predicate isBarrierCall(DataFlow::CallNode call, Expr e, boolean outcome, string lbl) { + exists(DataFlow::Node arg | + arg.asExpr() = e and + arg = call.getArgument(0) and + call.getNumArgument() = 1 and + argumentPassing(call, arg, this, sanitizedParameter) and + outcome = guardOutcome and + lbl = label + ) + } + + /** + * Holds if this function applies to the flow in `cfg`. + */ + predicate appliesTo(Configuration cfg) { cfg.isBarrierGuard(guard) } +} + +/** + * A call that sanitizes an argument. + */ +private class AdditionalBarrierGuardCall extends AdditionalBarrierGuardNode, DataFlow::CallNode { + BarrierGuardFunction f; + + AdditionalBarrierGuardCall() { f.isBarrierCall(this, _, _, _) } + + override predicate blocks(boolean outcome, Expr e) { + f.isBarrierCall(this, e, outcome, "") + } + + predicate internalBlocksLabel(boolean outcome, Expr e, DataFlow::FlowLabel label) { + f.isBarrierCall(this, e, outcome, label) + } + + override predicate appliesTo(Configuration cfg) { f.appliesTo(cfg) } } diff --git a/javascript/ql/src/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/src/semmle/javascript/dataflow/DataFlow.qll index 8798df6cc37..74bcc428393 100644 --- a/javascript/ql/src/semmle/javascript/dataflow/DataFlow.qll +++ b/javascript/ql/src/semmle/javascript/dataflow/DataFlow.qll @@ -85,6 +85,18 @@ module DataFlow { /** Gets the expression corresponding to this data flow node, if any. */ Expr asExpr() { this = TValueNode(result) } + /** + * Gets the expression enclosing this data flow node. + * In most cases the result is the same as `asExpr()`, however this method + * additionally the `InvokeExpr` corresponding to reflective calls, and the `Parameter` + * for a `DataFlow::ParameterNode`. + */ + Expr getEnclosingExpr() { + result = asExpr() or + this = DataFlow::reflectiveCallNode(result) or + result = this.(ParameterNode).getParameter() + } + /** Gets the AST node corresponding to this data flow node, if any. */ ASTNode getAstNode() { none() } @@ -188,11 +200,7 @@ module DataFlow { lvalueFlowStep(result, this) and not lvalueDefaultFlowStep(_, this) or - // Use of variable -> definition of variable - exists(SsaVariable var | - this = valueNode(var.getAUse()) and - result = TSsaDefNode(var) - ) + immediateFlowStep(result, this) or // Refinement of variable -> original definition of variable exists(SsaRefinementNode refinement | @@ -269,6 +277,14 @@ module DataFlow { /** * An expression or a declaration of a function, class, namespace or enum, * viewed as a node in the data flow graph. + * + * Examples: + * ```js + * x + y + * Math.abs(x) + * class C {} + * function f(x, y) {} + * ``` */ class ValueNode extends Node, TValueNode { AST::ValueNode astNode; @@ -482,6 +498,8 @@ module DataFlow { * * The default subclasses do not model global variable references or variable * references inside `with` statements as property references. + * + * See `PropWrite` and `PropRead` for concrete syntax examples. */ abstract class PropRef extends Node { /** @@ -516,6 +534,22 @@ module DataFlow { /** * A data flow node that writes to an object property. + * + * For example, all of the following are property writes: + * ```js + * obj.f = value; // assignment to a property + * obj[e] = value; // assignment to a computed property + * { f: value } // property initializer + * { g() {} } // object literal method + * { get g() {}, set g(v) {} } // accessor methods (have no rhs value) + * class C { + * constructor(public x: number); // parameter field (TypeScript only) + * static m() {} // static method + * g() {} // instance method + * } + * Object.defineProperty(obj, 'f', { value: 5} ) // call to defineProperty + * // JSX attribute + * ``` */ abstract class PropWrite extends PropRef { /** @@ -728,6 +762,17 @@ module DataFlow { /** * A data flow node that reads an object property. + * + * For example, all the following are property reads: + * ```js + * obj.f // property access + * obj[e] // computed property access + * let { f } = obj; // destructuring object pattern + * let [x, y] = array; // destructuring array pattern + * function f({ f }) {} // destructuring pattern (in parameter) + * for (let elm of array) {} // element access in for..of loop + * import { join } from 'path'; // named import specifier + * ``` */ abstract class PropRead extends PropRef, SourceNode { } @@ -741,7 +786,8 @@ module DataFlow { PropReadAsSourceNode() { this = TPropNode(any(PropertyPattern p)) or this instanceof RestPatternNode or - this instanceof ElementPatternNode + this instanceof ElementPatternNode or + this = lvalueNode(any(ForOfStmt stmt).getLValue()) } } @@ -826,6 +872,24 @@ module DataFlow { override string getPropertyName() { result = astNode.getImportedName() } } + /** + * The left-hand side of a `for..of` statement, seen as a property read + * on the object being iterated over. + */ + private class ForOfLvalueAsPropRead extends PropRead { + ForOfStmt stmt; + + ForOfLvalueAsPropRead() { + this = lvalueNode(stmt.getLValue()) + } + + override Node getBase() { result = stmt.getIterationDomain().flow() } + + override Expr getPropertyNameExpr() { none() } + + override string getPropertyName() { none() } + } + /** * A data flow node representing an unused parameter. * @@ -931,6 +995,15 @@ module DataFlow { * Gets a pseudo-node representing the root of a global access path. */ DataFlow::Node globalAccessPathRootPseudoNode() { result instanceof TGlobalAccessPathRoot } + + /** + * Gets a data flow node representing the underlying call performed by the given + * call to `Function.prototype.call` or `Function.prototype.apply`. + * + * For example, for an expression `fn.call(x, y)`, this gets a call node with `fn` as the + * callee, `x` as the receiver, and `y` as the first argument. + */ + DataFlow::InvokeNode reflectiveCallNode(InvokeExpr expr) { result = TReflectiveCallNode(expr, _) } /** * Provides classes representing various kinds of calls. @@ -1299,6 +1372,44 @@ module DataFlow { ) } + /** + * Flow steps shared between `getImmediatePredecessor` and `localFlowStep`. + * + * Inlining is forced because the two relations are indexed differently. + */ + pragma[inline] + private predicate immediateFlowStep(Node pred, Node succ) { + exists(SsaVariable v | + pred = TSsaDefNode(v.getDefinition()) and + succ = valueNode(v.getAUse()) + ) + or + exists(Expr predExpr, Expr succExpr | + pred = valueNode(predExpr) and succ = valueNode(succExpr) + | + predExpr = succExpr.(ParExpr).getExpression() + or + predExpr = succExpr.(SeqExpr).getLastOperand() + or + predExpr = succExpr.(AssignExpr).getRhs() + or + predExpr = succExpr.(TypeAssertion).getExpression() + or + predExpr = succExpr.(NonNullAssertion).getExpression() + or + predExpr = succExpr.(ExpressionWithTypeArguments).getExpression() + ) + or + // flow from 'this' parameter into 'this' expressions + exists(ThisExpr thiz | + pred = TThisNode(thiz.getBindingContainer()) and + succ = valueNode(thiz) + ) + or + // `f.call(...)` and `f.apply(...)` evaluate to the result of the reflective call they perform + pred = TReflectiveCallNode(succ.asExpr(), _) + } + /** * Holds if data can flow from `pred` to `succ` in one local step. */ @@ -1309,6 +1420,8 @@ module DataFlow { or lvalueDefaultFlowStep(pred, succ) or + immediateFlowStep(pred, succ) + or // Flow through implicit SSA nodes exists(SsaImplicitDefinition ssa | succ = TSsaDefNode(ssa) | // from any explicit definition or implicit init of a captured variable into @@ -1326,45 +1439,18 @@ module DataFlow { pred = TSsaDefNode(ssa.(SsaPseudoDefinition).getAnInput().getDefinition()) ) or - // flow out of local variables - exists(SsaVariable v | - pred = TSsaDefNode(v.getDefinition()) and - succ = valueNode(v.getAUse()) - ) - or exists(Expr predExpr, Expr succExpr | pred = valueNode(predExpr) and succ = valueNode(succExpr) | - predExpr = succExpr.(ParExpr).getExpression() - or - predExpr = succExpr.(SeqExpr).getLastOperand() - or predExpr = succExpr.(LogicalBinaryExpr).getAnOperand() or - predExpr = succExpr.(AssignExpr).getRhs() - or predExpr = succExpr.(ConditionalExpr).getABranch() or - predExpr = succExpr.(TypeAssertion).getExpression() - or - predExpr = succExpr.(NonNullAssertion).getExpression() - or - predExpr = succExpr.(ExpressionWithTypeArguments).getExpression() - or exists(Function f | predExpr = f.getAReturnedExpr() and localCall(succExpr, f) ) ) - or - // flow from 'this' parameter into 'this' expressions - exists(ThisExpr thiz | - pred = TThisNode(thiz.getBindingContainer()) and - succ = valueNode(thiz) - ) - or - // `f.call(...)` and `f.apply(...)` evaluate to the result of the reflective call they perform - pred = TReflectiveCallNode(succ.asExpr(), _) } /** diff --git a/javascript/ql/src/semmle/javascript/dataflow/ForwardExploration.qll b/javascript/ql/src/semmle/javascript/dataflow/ForwardExploration.qll new file mode 100644 index 00000000000..0e3a7ae91c2 --- /dev/null +++ b/javascript/ql/src/semmle/javascript/dataflow/ForwardExploration.qll @@ -0,0 +1,42 @@ +/** + * Provides machinery for performing forward data-flow exploration. + * + * Importing this module effectively makes all data-flow and taint-tracking configurations + * ignore their `isSink` predicate. Instead, flow is tracked from source nodes as far as + * possible, until a _terminal node_ (that is, a node without any outgoing flow) is reached. + * All terminal nodes are then treated as sink nodes. + * + * Data-flow exploration cannot be used with configurations depending on other configurations. + * + * NOTE: This library should only be used for debugging, not in production code. + */ + +import javascript + +private class ForwardExploringConfiguration extends DataFlow::Configuration { + DataFlow::Configuration cfg; + + ForwardExploringConfiguration() { + this = cfg + } + + override predicate isSink(DataFlow::Node node) { any() } + + override predicate isSink(DataFlow::Node node, DataFlow::FlowLabel lbl) { any() } + + override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { + exists(DataFlow::PathNode src, DataFlow::PathNode snk | hasFlowPath(src, snk) | + source = src.getNode() and + sink = snk.getNode() + ) + } + + override predicate hasFlowPath(DataFlow::SourcePathNode source, DataFlow::SinkPathNode sink) { + exists(DataFlow::MidPathNode last | + source.getConfiguration() = this and + source.getASuccessor*() = last and + not last.getASuccessor() instanceof DataFlow::MidPathNode and + last.getASuccessor() = sink + ) + } +} diff --git a/javascript/ql/src/semmle/javascript/dataflow/Nodes.qll b/javascript/ql/src/semmle/javascript/dataflow/Nodes.qll index a44f2909ce0..a9944f357fe 100644 --- a/javascript/ql/src/semmle/javascript/dataflow/Nodes.qll +++ b/javascript/ql/src/semmle/javascript/dataflow/Nodes.qll @@ -8,12 +8,28 @@ private import javascript private import semmle.javascript.dependencies.Dependencies private import internal.CallGraphs -/** A data flow node corresponding to an expression. */ +/** + * A data flow node corresponding to an expression. + * + * Examples: + * ```js + * x + y + * Math.abs(x) + * ``` + */ class ExprNode extends DataFlow::ValueNode { override Expr astNode; } -/** A data flow node corresponding to a parameter. */ +/** + * A data flow node corresponding to a parameter. + * + * For example, `x` is a parameter of `function f(x) {}`. + * + * When a parameter is a destructuring pattern, such as `{x, y}`, there is one + * parameter node representing the entire parameter, and separate `PropRead` nodes + * for the individual property patterns (`x` and `y`). + */ class ParameterNode extends DataFlow::SourceNode { Parameter p; @@ -29,7 +45,15 @@ class ParameterNode extends DataFlow::SourceNode { predicate isRestParameter() { p.isRestParameter() } } -/** A data flow node corresponding to a function invocation (with or without `new`). */ +/** + * A data flow node corresponding to a function invocation (with or without `new`). + * + * Examples: + * ```js + * Math.abs(x) + * new Array(16) + * ``` + */ class InvokeNode extends DataFlow::SourceNode { DataFlow::Impl::InvokeNodeDef impl; @@ -211,7 +235,14 @@ class InvokeNode extends DataFlow::SourceNode { } } -/** A data flow node corresponding to a function call without `new`. */ +/** + * A data flow node corresponding to a function call without `new`. + * + * Examples: + * ```js + * Math.abs(x) + * ``` + */ class CallNode extends InvokeNode { override DataFlow::Impl::CallNodeDef impl; @@ -223,7 +254,16 @@ class CallNode extends InvokeNode { DataFlow::Node getReceiver() { result = impl.getReceiver() } } -/** A data flow node corresponding to a method call. */ +/** + * A data flow node corresponding to a method call, that is, + * a call of form `x.m(...)`. + * + * Examples: + * ```js + * obj.foo() + * Math.abs(x) + * ``` + */ class MethodCallNode extends CallNode { override DataFlow::Impl::MethodCallNodeDef impl; @@ -239,12 +279,23 @@ class MethodCallNode extends CallNode { } } -/** A data flow node corresponding to a `new` expression. */ +/** + * A data flow node corresponding to a `new` expression. + * + * Examples: + * ```js + * new Array(16) + * ``` + */ class NewNode extends InvokeNode { override DataFlow::Impl::NewNodeDef impl; } -/** A data flow node corresponding to the `this` parameter in a function or `this` at the top-level. */ +/** + * A data flow node corresponding to the `this` parameter in a function or `this` at the top-level. + * + * Each function only has one `this` node, even if it references `this` multiple times. + */ class ThisNode extends DataFlow::Node, DataFlow::SourceNode { ThisNode() { DataFlow::thisNode(this, _) } @@ -266,7 +317,21 @@ class ThisNode extends DataFlow::Node, DataFlow::SourceNode { StmtContainer getBindingContainer() { DataFlow::thisNode(this, result) } } -/** A data flow node corresponding to a global variable access. */ +/** + * A data flow node corresponding to a global variable access through a simple identifier. + * + * For example, this includes `document` but not `window.document`. + * To recognize global variable access more generally, instead use `DataFlow::globalVarRef` + * or the member predicate `accessesGlobal`. + * + * Examples: + * ```js + * document + * Math + * NaN + * undefined + * ``` + */ class GlobalVarRefNode extends DataFlow::ValueNode, DataFlow::SourceNode { override GlobalVarAccess astNode; @@ -278,6 +343,17 @@ class GlobalVarRefNode extends DataFlow::ValueNode, DataFlow::SourceNode { * Gets a data flow node corresponding to an access to the global object, including * `this` expressions outside functions, references to global variables `window` * and `global`, and uses of the `global` npm package. + * + * Examples: + * ```js + * window + * window.window + * global + * globalThis + * this + * self + * require('global/window') + * ``` */ DataFlow::SourceNode globalObjectRef() { // top-level `this` @@ -308,6 +384,15 @@ DataFlow::SourceNode globalObjectRef() { /** * Gets a data flow node corresponding to an access to global variable `name`, * either directly, through `window` or `global`, or through the `global` npm package. + * + * Examples: + * ```js + * document + * Math + * window.document + * window.Math + * require('global/document') + * ``` */ pragma[nomagic] DataFlow::SourceNode globalVarRef(string name) { @@ -320,7 +405,40 @@ DataFlow::SourceNode globalVarRef(string name) { result = moduleImport("global/" + name) } -/** A data flow node corresponding to a function definition. */ +/** + * A data flow node corresponding to a function definition. + * + * Examples: + * + * ``` + * function greet() { // function declaration + * console.log("Hi"); + * } + * + * var greet = + * function() { // function expression + * console.log("Hi"); + * }; + * + * var greet2 = + * () => console.log("Hi") // arrow function expression + * + * var o = { + * m() { // function expression in a method definition in an object literal + * return 0; + * }, + * get x() { // function expression in a getter method definition in an object literal + * return 1 + * } + * }; + * + * class C { + * m() { // function expression in a method definition in a class + * return 0; + * } + * } + * ``` + */ class FunctionNode extends DataFlow::ValueNode, DataFlow::SourceNode { override Function astNode; @@ -373,12 +491,32 @@ class FunctionNode extends DataFlow::ValueNode, DataFlow::SourceNode { } } -/** A data flow node corresponding to an object literal expression. */ +/** + * A data flow node corresponding to an object literal expression. + * + * Example: + * ```js + * var p = { // object literal containing five property definitions + * x: 1, + * y: 1, + * diag: function() { return this.x - this.y; }, + * get area() { return this.x * this.y; }, + * set area(a) { this.x = Math.sqrt(a); this.y = Math.sqrt(a); } + * }; + * ``` + */ class ObjectLiteralNode extends DataFlow::ValueNode, DataFlow::SourceNode { override ObjectExpr astNode; } -/** A data flow node corresponding to an array literal expression. */ +/** + * A data flow node corresponding to an array literal expression. + * + * Example: + * ``` + * [ 1, , [ 3, 4 ] ] + * ``` + */ class ArrayLiteralNode extends DataFlow::ValueNode, DataFlow::SourceNode { override ArrayExpr astNode; @@ -392,7 +530,17 @@ class ArrayLiteralNode extends DataFlow::ValueNode, DataFlow::SourceNode { int getSize() { result = astNode.getSize() } } -/** A data flow node corresponding to a `new Array()` or `Array()` invocation. */ +/** + * A data flow node corresponding to a `new Array()` or `Array()` invocation. + * + * Examples: + * ```js + * Array('apple', 'orange') // two initial elements + * new Array('apple', 'orange') + * Array(16) // size 16 but no initial elements + * new Array(16) + * ``` + */ class ArrayConstructorInvokeNode extends DataFlow::InvokeNode { ArrayConstructorInvokeNode() { getCalleeNode() = DataFlow::globalVarRef("Array") } @@ -420,6 +568,16 @@ class ArrayConstructorInvokeNode extends DataFlow::InvokeNode { /** * A data flow node corresponding to the creation or a new array, either through an array literal * or an invocation of the `Array` constructor. + * + * + * Examples: + * ```js + * ['apple', 'orange']; + * Array('apple', 'orange') + * new Array('apple', 'orange') + * Array(16) + * new Array(16) + * ``` */ class ArrayCreationNode extends DataFlow::ValueNode, DataFlow::SourceNode { ArrayCreationNode() { @@ -444,13 +602,22 @@ class ArrayCreationNode extends DataFlow::ValueNode, DataFlow::SourceNode { } /** - * A data flow node corresponding to a `default` import from a module, or a - * (AMD or CommonJS) `require` of a module. + * A data flow node representing an import of a module, either through + * an `import` declaration, a call to `require`, or an AMD dependency parameter. * - * For compatibility with old transpilers, we treat `import * from '...'` - * as a default import as well. + * For compatibility with old transpilers, we treat both `import * as x from '...'` and + * `import x from '...'` as module import nodes. * * Additional import nodes can be added by subclassing `ModuleImportNode::Range`. + * + * Examples: + * ```js + * require('fs'); + * import * as fs from 'fs'; + * import fs from 'fs'; + * import { readDir } from 'fs'; // Note: 'readDir' is a PropRead with a ModuleImportNode as base + * define(["fs"], function(fs) { ... }); // AMD module + * ``` */ class ModuleImportNode extends DataFlow::SourceNode { ModuleImportNode::Range range; @@ -771,11 +938,7 @@ class ClassNode extends DataFlow::SourceNode { */ pragma[noinline] predicate hasQualifiedName(string name) { - exists(DataFlow::Node rhs | - getAClassReference().flowsTo(rhs) and - name = GlobalAccessPath::fromRhs(rhs) and - GlobalAccessPath::isAssignedInUniqueFile(name) - ) + getAClassReference().flowsTo(AccessPath::getAnAssignmentTo(name)) } } @@ -883,7 +1046,7 @@ module ClassNode { } private DataFlow::PropRef getAPrototypeReferenceInFile(string name, File f) { - GlobalAccessPath::getAccessPath(result.getBase()) = name and + result.getBase() = AccessPath::getAReferenceOrAssignmentTo(name) and result.getPropertyName() = "prototype" and result.getFile() = f } @@ -904,7 +1067,7 @@ module ClassNode { ) or exists(string name | - name = GlobalAccessPath::fromRhs(this) and + this = AccessPath::getAnAssignmentTo(name) and exists(getAPrototypeReferenceInFile(name, getFile())) ) ) @@ -969,7 +1132,7 @@ module ClassNode { ) or exists(string name | - GlobalAccessPath::fromRhs(this) = name and + this = AccessPath::getAnAssignmentTo(name) and result = getAPrototypeReferenceInFile(name, getFile()) ) or diff --git a/javascript/ql/src/semmle/javascript/dataflow/Sources.qll b/javascript/ql/src/semmle/javascript/dataflow/Sources.qll index 6b179f726c4..1fe799eac85 100644 --- a/javascript/ql/src/semmle/javascript/dataflow/Sources.qll +++ b/javascript/ql/src/semmle/javascript/dataflow/Sources.qll @@ -12,9 +12,25 @@ private import semmle.javascript.dataflow.TypeTracking /** * A source node for local data flow, that is, a node from which local data flow is tracked. * - * Examples include function parameters, imports and property accesses; see - * `DataFlow::SourceNode::DefaultRange` for details. You can introduce new kinds of - * source nodes by defining new subclasses of `DataFlow::SourceNode::Range`. + * This includes function invocations, parameters, object creation, and references to a property or global variable. + * + * You can introduce new kinds of source nodes by defining new subclasses of `DataFlow::SourceNode::Range`. + * + * Examples: + * ```js + * obj.f // property access + * Math.abs(x) // function calls + * { f: 12, g: 45 }; // object expressions + * function fn(x) {} // functions and parameters + * class C {} // classes + * document // global variable access + * // JSX literals + * /[a-z]+/g; // regular expression literal + * await x // await expression + * import * as fs from 'fs'; + * import { readDir } from 'fs'; + * import("fs") + * ``` */ class SourceNode extends DataFlow::Node { SourceNode() { this instanceof SourceNode::Range } diff --git a/javascript/ql/src/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/src/semmle/javascript/dataflow/TaintTracking.qll index 06a0d904261..24892805242 100644 --- a/javascript/ql/src/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/src/semmle/javascript/dataflow/TaintTracking.qll @@ -133,8 +133,8 @@ module TaintTracking { * configurations it is used in. * * Note: For performance reasons, all subclasses of this class should be part - * of the standard library. Override `Configuration::isSanitizer` - * for analysis-specific taint steps. + * of the standard library. Override `Configuration::isSanitizerGuard` + * for analysis-specific taint sanitizer guards. */ abstract class AdditionalSanitizerGuardNode extends SanitizerGuardNode { /** @@ -781,15 +781,18 @@ module TaintTracking { override predicate appliesTo(Configuration cfg) { any() } } - /** A check of the form `whitelist.includes(x)` or equivalent, which sanitizes `x` in its "then" branch. */ - class StringInclusionSanitizer extends AdditionalSanitizerGuardNode { - StringOps::Includes includes; + /** DEPRECATED. This class has been renamed to `InclusionSanitizer`. */ + deprecated class StringInclusionSanitizer = InclusionSanitizer; - StringInclusionSanitizer() { this = includes } + /** A check of the form `whitelist.includes(x)` or equivalent, which sanitizes `x` in its "then" branch. */ + class InclusionSanitizer extends AdditionalSanitizerGuardNode { + InclusionTest inclusion; + + InclusionSanitizer() { this = inclusion } override predicate sanitizes(boolean outcome, Expr e) { - outcome = includes.getPolarity() and - e = includes.getSubstring().asExpr() + outcome = inclusion.getPolarity() and + e = inclusion.getContainedNode().asExpr() } override predicate appliesTo(Configuration cfg) { any() } @@ -846,71 +849,6 @@ module TaintTracking { override predicate appliesTo(Configuration cfg) { any() } } - /** - * A function that returns the result of a sanitizer check. - */ - private class SanitizingFunction extends Function { - DataFlow::ParameterNode sanitizedParameter; - SanitizerGuardNode sanitizer; - boolean sanitizerOutcome; - - SanitizingFunction() { - exists(Expr e | - exists(Expr returnExpr | - returnExpr = sanitizer.asExpr() - or - // ad hoc support for conjunctions: - returnExpr.(LogAndExpr).getAnOperand() = sanitizer.asExpr() and sanitizerOutcome = true - or - // ad hoc support for disjunctions: - returnExpr.(LogOrExpr).getAnOperand() = sanitizer.asExpr() and sanitizerOutcome = false - | - exists(SsaExplicitDefinition ssa | - ssa.getDef().getSource() = returnExpr and - ssa.getVariable().getAUse() = getAReturnedExpr() - ) - or - returnExpr = getAReturnedExpr() - ) and - sanitizedParameter.flowsToExpr(e) and - sanitizer.sanitizes(sanitizerOutcome, e) - ) and - getNumParameter() = 1 and - sanitizedParameter.getParameter() = getParameter(0) - } - - /** - * Holds if this function sanitizes argument `e` of call `call`, provided the call evaluates to `outcome`. - */ - predicate isSanitizingCall(DataFlow::CallNode call, Expr e, boolean outcome) { - exists(DataFlow::Node arg | - arg.asExpr() = e and - arg = call.getArgument(0) and - call.getNumArgument() = 1 and - FlowSteps::argumentPassing(call, arg, this, sanitizedParameter) and - outcome = sanitizerOutcome - ) - } - - /** - * Holds if this function applies to the flow in `cfg`. - */ - predicate appliesTo(Configuration cfg) { cfg.isBarrierGuard(sanitizer) } - } - - /** - * A call that sanitizes an argument. - */ - private class AdditionalSanitizingCall extends AdditionalSanitizerGuardNode, DataFlow::CallNode { - SanitizingFunction f; - - AdditionalSanitizingCall() { f.isSanitizingCall(this, _, _) } - - override predicate sanitizes(boolean outcome, Expr e) { f.isSanitizingCall(this, e, outcome) } - - override predicate appliesTo(Configuration cfg) { f.appliesTo(cfg) } - } - /** * An equality test on `e.origin` or `e.source` where `e` is a `postMessage` event object, * considered as a sanitizer for `e`. diff --git a/javascript/ql/src/semmle/javascript/dataflow/TypeTracking.qll b/javascript/ql/src/semmle/javascript/dataflow/TypeTracking.qll index ef639d99ad4..ecbb3187728 100644 --- a/javascript/ql/src/semmle/javascript/dataflow/TypeTracking.qll +++ b/javascript/ql/src/semmle/javascript/dataflow/TypeTracking.qll @@ -13,7 +13,9 @@ private class PropertyName extends string { PropertyName() { this = any(DataFlow::PropRef pr).getPropertyName() or - GlobalAccessPath::isAssignedInUniqueFile(this) + AccessPath::isAssignedInUniqueFile(this) + or + exists(AccessPath::getAnAssignmentTo(_, this)) } } @@ -95,20 +97,35 @@ module StepSummary { any(AdditionalTypeTrackingStep st).step(pred, succ) and summary = LevelStep() or + // Store to global access path exists(string name | - name = GlobalAccessPath::fromRhs(pred) and - GlobalAccessPath::isAssignedInUniqueFile(name) and + pred = AccessPath::getAnAssignmentTo(name) and + AccessPath::isAssignedInUniqueFile(name) and succ = DataFlow::globalAccessPathRootPseudoNode() and summary = StoreStep(name) ) or + // Load from global access path exists(string name | - name = GlobalAccessPath::fromReference(succ) and - GlobalAccessPath::isAssignedInUniqueFile(name) and + succ = AccessPath::getAReferenceTo(name) and + AccessPath::isAssignedInUniqueFile(name) and pred = DataFlow::globalAccessPathRootPseudoNode() and summary = LoadStep(name) ) or + // Store to non-global access path + exists(string name | + pred = AccessPath::getAnAssignmentTo(succ, name) and + summary = StoreStep(name) + ) + or + // Load from non-global access path + exists(string name | + succ = AccessPath::getAReferenceTo(pred, name) and + summary = LoadStep(name) and + name != "" + ) + or // Summarize calls with flow directly from a parameter to a return. exists(DataFlow::ParameterNode param, DataFlow::FunctionNode fun | ( diff --git a/javascript/ql/src/semmle/javascript/dataflow/internal/CallGraphs.qll b/javascript/ql/src/semmle/javascript/dataflow/internal/CallGraphs.qll index a5e140734a4..d58a83fa0bd 100644 --- a/javascript/ql/src/semmle/javascript/dataflow/internal/CallGraphs.qll +++ b/javascript/ql/src/semmle/javascript/dataflow/internal/CallGraphs.qll @@ -43,11 +43,7 @@ module CallGraph { or imprecision = 0 and t.start() and - exists(string name | - GlobalAccessPath::isAssignedInUniqueFile(name) and - GlobalAccessPath::fromRhs(function) = name and - GlobalAccessPath::fromReference(result) = name - ) + AccessPath::step(function, result) or imprecision = 0 and exists(DataFlow::ClassNode cls | diff --git a/javascript/ql/src/semmle/javascript/dataflow/internal/PropertyTypeInference.qll b/javascript/ql/src/semmle/javascript/dataflow/internal/PropertyTypeInference.qll index 54e98769964..0f6b816daeb 100644 --- a/javascript/ql/src/semmle/javascript/dataflow/internal/PropertyTypeInference.qll +++ b/javascript/ql/src/semmle/javascript/dataflow/internal/PropertyTypeInference.qll @@ -50,17 +50,17 @@ abstract class AnalyzedPropertyRead extends DataFlow::AnalyzedNode { } /** - * Flow analysis for (non-numeric) property read accesses. + * Flow analysis for non-numeric property read accesses. */ -private class AnalyzedPropertyAccess extends AnalyzedPropertyRead, DataFlow::ValueNode { - override PropAccess astNode; +private class AnalyzedNonNumericPropertyRead extends AnalyzedPropertyRead { + DataFlow::PropRead self; DataFlow::AnalyzedNode baseNode; string propName; - AnalyzedPropertyAccess() { - astNode.accesses(baseNode.asExpr(), propName) and - isNonNumericPropertyName(propName) and - astNode instanceof RValue + AnalyzedNonNumericPropertyRead() { + this = self and + self.accesses(baseNode, propName) and + isNonNumericPropertyName(propName) } override predicate reads(AbstractValue base, string prop) { @@ -148,7 +148,7 @@ private predicate explicitPropertyWrite( * Flow analysis for `arguments.callee`. We assume it is never redefined, * which is unsound in practice, but pragmatically useful. */ -private class AnalyzedArgumentsCallee extends AnalyzedPropertyAccess { +private class AnalyzedArgumentsCallee extends AnalyzedNonNumericPropertyRead { AnalyzedArgumentsCallee() { propName = "callee" } override AbstractValue getALocalValue() { @@ -156,18 +156,18 @@ private class AnalyzedArgumentsCallee extends AnalyzedPropertyAccess { result = TAbstractFunction(baseVal.getFunction()) ) or - hasNonArgumentsBase(astNode) and result = super.getALocalValue() + hasNonArgumentsBase(self) and result = super.getALocalValue() } } /** - * Holds if `pacc` is of the form `e.callee` where `e` could evaluate to some + * Holds if `pr` is of the form `e.callee` where `e` could evaluate to some * value that is not an arguments object. */ -private predicate hasNonArgumentsBase(PropAccess pacc) { - pacc.getPropertyName() = "callee" and +private predicate hasNonArgumentsBase(DataFlow::PropRead pr) { + pr.getPropertyName() = "callee" and exists(AbstractValue baseVal | - baseVal = pacc.getBase().analyze().getALocalValue() and + baseVal = pr.getBase().analyze().getALocalValue() and not baseVal instanceof AbstractArguments ) } diff --git a/javascript/ql/src/semmle/javascript/dataflow/internal/VariableTypeInference.qll b/javascript/ql/src/semmle/javascript/dataflow/internal/VariableTypeInference.qll index 63d9c8e9563..3a26ab234c1 100644 --- a/javascript/ql/src/semmle/javascript/dataflow/internal/VariableTypeInference.qll +++ b/javascript/ql/src/semmle/javascript/dataflow/internal/VariableTypeInference.qll @@ -223,7 +223,11 @@ abstract class AnalyzedSsaDefinition extends SsaDefinition { * Flow analysis for SSA definitions corresponding to `VarDef`s. */ private class AnalyzedExplicitDefinition extends AnalyzedSsaDefinition, SsaExplicitDefinition { - override AbstractValue getAnRhsValue() { result = getDef().(AnalyzedVarDef).getAnAssignedValue() } + override AbstractValue getAnRhsValue() { + result = getDef().(AnalyzedVarDef).getAnAssignedValue() + or + result = getRhsNode().analyze().getALocalValue() + } } /** @@ -241,6 +245,8 @@ private class AnalyzedVariableCapture extends AnalyzedSsaDefinition, SsaVariable exists(LocalVariable v | v = getSourceVariable() | result = v.(AnalyzedCapturedVariable).getALocalValue() or + result = any(AnalyzedExplicitDefinition def | def.getSourceVariable() = v).getAnRhsValue() + or not guaranteedToBeInitialized(v) and result = getImplicitInitValue(v) ) } diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/IndirectCommandArgument.qll b/javascript/ql/src/semmle/javascript/security/dataflow/IndirectCommandArgument.qll index f509d9f8c6c..9f62ad7ccc8 100644 --- a/javascript/ql/src/semmle/javascript/security/dataflow/IndirectCommandArgument.qll +++ b/javascript/ql/src/semmle/javascript/security/dataflow/IndirectCommandArgument.qll @@ -10,7 +10,7 @@ import javascript * That is, either `shell` is a Unix shell (`sh` or similar) and * `arg` is `"-c"`, or `shell` is `cmd.exe` and `arg` is `"/c"`. */ -private predicate shellCmd(ConstantString shell, string arg) { +private predicate shellCmd(Expr shell, string arg) { exists(string s | s = shell.getStringValue() | (s = "sh" or s = "bash" or s = "/bin/sh" or s = "/bin/bash") and arg = "-c" @@ -23,25 +23,29 @@ private predicate shellCmd(ConstantString shell, string arg) { } /** - * Data flow configuration for tracking string literals that look like they - * may refer to an operating-system shell, and array literals that may end up being - * interpreted as argument lists for system commands. + * Gets a data-flow node whose value ends up being interpreted as the command argument in `sys` + * after a flow summarized by `t`. */ -private class ArgumentListTracking extends DataFlow::Configuration { - ArgumentListTracking() { this = "ArgumentListTracking" } +private DataFlow::Node commandArgument(SystemCommandExecution sys, DataFlow::TypeBackTracker t) { + t.start() and + result = sys.getACommandArgument() + or + exists(DataFlow::TypeBackTracker t2 | + t = t2.smallstep(result, commandArgument(sys, t2)) + ) +} - override predicate isSource(DataFlow::Node nd) { - nd instanceof DataFlow::ArrayCreationNode - or - exists(ConstantString shell | shellCmd(shell, _) | nd = DataFlow::valueNode(shell)) - } - - override predicate isSink(DataFlow::Node nd) { - exists(SystemCommandExecution sys | - nd = sys.getACommandArgument() or - nd = sys.getArgumentList() - ) - } +/** + * Gets a data-flow node whose value ends up being interpreted as the argument list in `sys` + * after a flow summarized by `t`. + */ +private DataFlow::SourceNode argumentList(SystemCommandExecution sys, DataFlow::TypeBackTracker t) { + t.start() and + result = sys.getArgumentList().getALocalSource() + or + exists(DataFlow::TypeBackTracker t2 | + result = argumentList(sys, t2).backtrack(t2, t) + ) } /** @@ -60,11 +64,11 @@ private class ArgumentListTracking extends DataFlow::Configuration { */ predicate isIndirectCommandArgument(DataFlow::Node source, SystemCommandExecution sys) { exists( - ArgumentListTracking cfg, DataFlow::ArrayCreationNode args, ConstantString shell, string dashC + DataFlow::ArrayCreationNode args, DataFlow::Node shell, string dashC | - shellCmd(shell, dashC) and - cfg.hasFlow(DataFlow::valueNode(shell), sys.getACommandArgument()) and - cfg.hasFlow(args, sys.getArgumentList()) and + shellCmd(shell.asExpr(), dashC) and + shell = commandArgument(sys, DataFlow::TypeBackTracker::end()) and + args = argumentList(sys, DataFlow::TypeBackTracker::end()) and args.getAPropertyWrite().getRhs().mayHaveStringValue(dashC) and source = args.getAPropertyWrite().getRhs() ) diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/Xss.qll b/javascript/ql/src/semmle/javascript/security/dataflow/Xss.qll index fbea366ed93..52c4a9b9332 100644 --- a/javascript/ql/src/semmle/javascript/security/dataflow/Xss.qll +++ b/javascript/ql/src/semmle/javascript/security/dataflow/Xss.qll @@ -39,6 +39,18 @@ module Shared { ) } } + + /** + * A call to `encodeURI` or `encodeURIComponent`, viewed as a sanitizer for + * XSS vulnerabilities. + */ + class UriEncodingSanitizer extends Sanitizer, DataFlow::CallNode { + UriEncodingSanitizer() { + exists(string name | this = DataFlow::globalVarRef(name).getACall() | + name = "encodeURI" or name = "encodeURIComponent" + ) + } + } } /** Provides classes and predicates for the DOM-based XSS query. */ @@ -251,6 +263,8 @@ module DomBasedXss { * so any such replacement stops taint propagation. */ private class MetacharEscapeSanitizer extends Sanitizer, Shared::MetacharEscapeSanitizer { } + + private class UriEncodingSanitizer extends Sanitizer, Shared::UriEncodingSanitizer { } } /** Provides classes and predicates for the reflected XSS query. */ @@ -294,6 +308,8 @@ module ReflectedXss { * so any such replacement stops taint propagation. */ private class MetacharEscapeSanitizer extends Sanitizer, Shared::MetacharEscapeSanitizer { } + + private class UriEncodingSanitizer extends Sanitizer, Shared::UriEncodingSanitizer { } } /** Provides classes and predicates for the stored XSS query. */ @@ -320,4 +336,6 @@ module StoredXss { * so any such replacement stops taint propagation. */ private class MetacharEscapeSanitizer extends Sanitizer, Shared::MetacharEscapeSanitizer { } + + private class UriEncodingSanitizer extends Sanitizer, Shared::UriEncodingSanitizer { } } diff --git a/javascript/ql/src/semmlecode.javascript.dbscheme b/javascript/ql/src/semmlecode.javascript.dbscheme index 874ebfcd4d2..5a5adbf98dc 100644 --- a/javascript/ql/src/semmlecode.javascript.dbscheme +++ b/javascript/ql/src/semmlecode.javascript.dbscheme @@ -200,8 +200,8 @@ case @stmt.kind of isInstantiated(unique int decl: @namespacedeclaration ref); -@declarablestmt = @declstmt | @namespacedeclaration | @classdeclstmt | @functiondeclstmt | @enumdeclaration | @externalmoduledeclaration | @globalaugmentationdeclaration; -hasDeclareKeyword(unique int stmt: @declarablestmt ref); +@declarablenode = @declstmt | @namespacedeclaration | @classdeclstmt | @functiondeclstmt | @enumdeclaration | @externalmoduledeclaration | @globalaugmentationdeclaration | @field; +hasDeclareKeyword(unique int stmt: @declarablenode ref); isForAwaitOf(unique int forof: @forofstmt ref); @@ -559,7 +559,7 @@ case @typeexpr.kind of | 17 = @localvartypeaccess | 18 = @qualifiedvartypeaccess | 19 = @thisvartypeaccess -| 20 = @istypeexpr +| 20 = @predicatetypeexpr | 21 = @interfacetypeexpr | 22 = @typeparameter | 23 = @plainfunctiontypeexpr @@ -637,6 +637,8 @@ case @type.kind of @unionorintersectiontype = @uniontype | @intersectiontype; @typevariabletype = @canonicaltypevariabletype | @lexicaltypevariabletype; +hasAssertsKeyword(int node: @predicatetypeexpr ref); + @typed_ast_node = @expr | @typeexpr | @function; ast_node_type( unique int node: @typed_ast_node ref, diff --git a/javascript/ql/src/semmlecode.javascript.dbscheme.stats b/javascript/ql/src/semmlecode.javascript.dbscheme.stats index 146950b5be7..f7d36078a5a 100644 --- a/javascript/ql/src/semmlecode.javascript.dbscheme.stats +++ b/javascript/ql/src/semmlecode.javascript.dbscheme.stats @@ -850,7 +850,7 @@ 20 -@istypeexpr +@predicatetypeexpr 86 @@ -7918,6 +7918,17 @@ +hasAssertsKeyword +66 + + +node +66 + + + + + isAbstractMember 66 diff --git a/javascript/ql/test/library-tests/CFG/CFG.expected b/javascript/ql/test/library-tests/CFG/CFG.expected index 7904099cb44..a41f1c4999a 100644 --- a/javascript/ql/test/library-tests/CFG/CFG.expected +++ b/javascript/ql/test/library-tests/CFG/CFG.expected @@ -546,7 +546,7 @@ | classes | 39 | static x = 5; | 39 | t = cla ... () {} } | | classes | 39 | t | 39 | A | | classes | 39 | t = cla ... () {} } | 39 | t | -| classes | 39 | t = cla ... () {} } | 42 | exit node of | +| classes | 39 | t = cla ... () {} } | 40 | exit node of | | classes | 39 | x | 39 | 5 | | classes | 39 | {} | 39 | exit node of () {} | | decorated_parameter | 1 | C | 2 | foo | @@ -625,7 +625,7 @@ | fields | 8 | {} | 8 | exit node of () {} | | fields | 11 | A | 12 | constructor | | fields | 11 | B | 11 | A | -| fields | 11 | class B ... \\n z;\\n} | 21 | exit node of | +| fields | 11 | class B ... \\n z;\\n} | 19 | exit node of | | fields | 12 | constru ... er;\\n } | 11 | class B ... \\n z;\\n} | | fields | 12 | constructor | 12 | function in constru ... er;\\n } | | fields | 12 | entry node of () {\\n ... er;\\n } | 12 | {\\n b ... er;\\n } | @@ -680,7 +680,7 @@ | globals | 19 | h | 20 | {\\n} | | globals | 20 | {\\n} | 21 | exit node of function\\n h()\\n{\\n} | | mixedMembers | 1 | Mixed | 3 | constructor | -| mixedMembers | 1 | class M ... z) {}\\n} | 7 | exit node of | +| mixedMembers | 1 | class M ... z) {}\\n} | 6 | exit node of | | mixedMembers | 1 | entry node of | 1 | Mixed | | mixedMembers | 2 | 3 | 2 | x = 3 | | mixedMembers | 2 | x | 2 | 3 | @@ -746,7 +746,7 @@ | staticFields | 2 | C | 2 | new C() | | staticFields | 2 | instance | 2 | C | | staticFields | 2 | new C() | 2 | static ... ew C(); | -| staticFields | 2 | static ... ew C(); | 7 | exit node of | +| staticFields | 2 | static ... ew C(); | 4 | exit node of | | staticFieldsTS | 1 | C | 1 | constructor | | staticFieldsTS | 1 | class C ... C();\\n} | 2 | instance | | staticFieldsTS | 1 | constructor | 1 | function in constructor() {} | diff --git a/javascript/ql/test/library-tests/CFG/classes.js b/javascript/ql/test/library-tests/CFG/classes.js index cf4bedc2a3b..fa35da77f32 100644 --- a/javascript/ql/test/library-tests/CFG/classes.js +++ b/javascript/ql/test/library-tests/CFG/classes.js @@ -37,5 +37,3 @@ t = class extends A { f() {} } t = class extends A { x = 5; f() {} } t = class extends A { static x = 5; f() {} } t = class extends A { static x = 5; f() {} constructor() {} } - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/CFG/fields.js b/javascript/ql/test/library-tests/CFG/fields.js index ef4b105c9ff..e93c13eaa18 100644 --- a/javascript/ql/test/library-tests/CFG/fields.js +++ b/javascript/ql/test/library-tests/CFG/fields.js @@ -16,5 +16,3 @@ class B extends A { } z; } - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/CFG/mixedMembers.js b/javascript/ql/test/library-tests/CFG/mixedMembers.js index 33de7b7ff4a..8ff3721d61c 100644 --- a/javascript/ql/test/library-tests/CFG/mixedMembers.js +++ b/javascript/ql/test/library-tests/CFG/mixedMembers.js @@ -3,5 +3,3 @@ class Mixed { constructor(y) {} method(z) {} } - -// semmle-extractor-options: --experimental \ No newline at end of file diff --git a/javascript/ql/test/library-tests/CFG/options b/javascript/ql/test/library-tests/CFG/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/library-tests/CFG/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/CFG/staticFields.js b/javascript/ql/test/library-tests/CFG/staticFields.js index 5d8fc7605a2..fa3070ab19f 100644 --- a/javascript/ql/test/library-tests/CFG/staticFields.js +++ b/javascript/ql/test/library-tests/CFG/staticFields.js @@ -1,6 +1,3 @@ class C { static instance = new C(); } - -// semmle-extractor-options: --experimental - diff --git a/javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/access-path.js b/javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/access-path.js new file mode 100644 index 00000000000..f320d3ae8f4 --- /dev/null +++ b/javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/access-path.js @@ -0,0 +1,39 @@ +function foo() { + let self = this; + + /** name:direct */ + self.foo.bar.direct = function() {}; + + /** calls:direct */ + self.foo.bar.direct(); + + self.foo.bar = { + /** name:baz */ + baz() {}, + bong() { + /** calls:baz */ + self.foo.bar.baz(); + } + } + + /** calls:baz */ + self.foo.bar.baz(); + + self.foo.bar.Class = class { + /** name:m */ + m() {} + } + + self.foo.bar.instance = new self.foo.bar.Class(); + + /** calls:m */ + self.foo.bar.instance.m(); + + let unknownObject = unknownCall(); + + /** name:direct2 */ + unknownObject.bar.baz.direct = function() {}; + + /** calls:direct2 */ + unknownObject.bar.baz.direct(); +} diff --git a/javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/client.js b/javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/client.js new file mode 100644 index 00000000000..f1308447c22 --- /dev/null +++ b/javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/client.js @@ -0,0 +1,12 @@ +const lib = require("./lib"), + { f } = require("./lib"); + +/** calls:lib.f */ +lib.f(); +/** calls:lib.f */ +f(); + +(function() { + /** calls:lib.f */ + f(); +})(); diff --git a/javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/lib.js b/javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/lib.js new file mode 100644 index 00000000000..37b8606ab1d --- /dev/null +++ b/javascript/ql/test/library-tests/CallGraphs/AnnotatedTest/lib.js @@ -0,0 +1,3 @@ +module.exports.f = + /** name:lib.f */ + function() {}; diff --git a/javascript/ql/test/library-tests/Classes/fields.js b/javascript/ql/test/library-tests/Classes/fields.js index 63b701e48ac..f71520fc1f8 100644 --- a/javascript/ql/test/library-tests/Classes/fields.js +++ b/javascript/ql/test/library-tests/Classes/fields.js @@ -2,5 +2,3 @@ class C { x; y = 42 } - -// semmle-extractor-options: --experimental \ No newline at end of file diff --git a/javascript/ql/test/library-tests/Classes/options b/javascript/ql/test/library-tests/Classes/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/library-tests/Classes/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/Comprehensions/comprehensions.js b/javascript/ql/test/library-tests/Comprehensions/comprehensions.js index 5194bcc9ddd..32b649bfdae 100644 --- a/javascript/ql/test/library-tests/Comprehensions/comprehensions.js +++ b/javascript/ql/test/library-tests/Comprehensions/comprehensions.js @@ -8,5 +8,3 @@ year; year; (for (i of numbers) for (j of letters) i+j); (for (i of numbers) for (j of letters) if (i x) | sources.js:1:1:1:12 | new (x => x) | +| sources.js:1:5:1:12 | (x => x) | sources.js:1:5:1:12 | (x => x) | +| sources.js:1:6:1:6 | x | sources.js:1:6:1:6 | x | +| sources.js:1:6:1:6 | x | sources.js:1:6:1:6 | x | +| sources.js:1:6:1:11 | x => x | sources.js:1:6:1:11 | x => x | +| sources.js:1:11:1:11 | x | sources.js:1:11:1:11 | x | +| sources.js:3:1:5:2 | (functi ... +19;\\n}) | sources.js:3:1:5:2 | (functi ... +19;\\n}) | +| sources.js:3:1:5:6 | (functi ... \\n})(23) | sources.js:3:1:5:6 | (functi ... \\n})(23) | +| sources.js:3:2:5:1 | functio ... x+19;\\n} | sources.js:3:2:5:1 | functio ... x+19;\\n} | +| sources.js:3:11:3:11 | x | sources.js:3:11:3:11 | x | +| sources.js:3:11:3:11 | x | sources.js:3:11:3:11 | x | +| sources.js:4:10:4:10 | x | sources.js:4:10:4:10 | x | +| sources.js:4:10:4:13 | x+19 | sources.js:4:10:4:13 | x+19 | +| sources.js:4:12:4:13 | 19 | sources.js:4:12:4:13 | 19 | +| sources.js:5:4:5:5 | 23 | sources.js:5:4:5:5 | 23 | +| sources.js:7:1:7:3 | /x/ | sources.js:7:1:7:3 | /x/ | +| sources.js:9:10:9:12 | foo | sources.js:9:10:9:12 | foo | +| sources.js:9:14:9:18 | array | sources.js:9:14:9:18 | array | +| sources.js:9:14:9:18 | array | sources.js:9:14:9:18 | array | +| sources.js:10:12:10:14 | key | sources.js:10:12:10:14 | key | +| sources.js:10:12:10:14 | key | sources.js:10:12:10:14 | key | +| sources.js:10:19:10:23 | array | sources.js:10:19:10:23 | array | +| sources.js:10:28:10:30 | key | sources.js:10:28:10:30 | key | +| sources.js:11:12:11:18 | { key } | sources.js:11:12:11:18 | { key } | +| sources.js:11:12:11:18 | { key } | sources.js:11:12:11:18 | { key } | +| sources.js:11:14:11:16 | key | sources.js:11:14:11:16 | key | +| sources.js:11:14:11:16 | key | sources.js:11:14:11:16 | key | +| sources.js:11:23:11:27 | array | sources.js:11:23:11:27 | array | +| sources.js:11:32:11:34 | key | sources.js:11:32:11:34 | key | +| tst.js:1:10:1:11 | fs | tst.js:1:10:1:11 | fs | +| tst.js:1:10:1:11 | fs | tst.js:1:10:1:11 | fs | +| tst.js:1:10:1:11 | fs | tst.js:1:10:1:11 | fs | +| tst.js:1:20:1:23 | 'fs' | tst.js:1:20:1:23 | 'fs' | +| tst.js:3:5:3:5 | x | tst.js:3:5:3:5 | x | +| tst.js:3:5:3:10 | x = 42 | tst.js:3:5:3:10 | x = 42 | +| tst.js:3:9:3:10 | 42 | tst.js:3:9:3:10 | 42 | +| tst.js:4:5:4:5 | y | tst.js:4:5:4:5 | y | +| tst.js:4:5:4:12 | y = "hi" | tst.js:4:5:4:12 | y = "hi" | +| tst.js:4:9:4:12 | "hi" | tst.js:4:9:4:12 | "hi" | +| tst.js:5:5:5:5 | z | tst.js:5:5:5:5 | z | +| tst.js:5:5:5:5 | z | tst.js:5:5:5:5 | z | +| tst.js:7:1:7:2 | fs | tst.js:7:1:7:2 | fs | +| tst.js:8:1:8:1 | x | tst.js:8:1:8:1 | x | +| tst.js:9:1:9:3 | (x) | tst.js:9:1:9:3 | (x) | +| tst.js:9:2:9:2 | x | tst.js:9:2:9:2 | x | +| tst.js:10:1:10:1 | x | tst.js:10:1:10:1 | x | +| tst.js:10:1:10:4 | x, y | tst.js:10:1:10:4 | x, y | +| tst.js:10:4:10:4 | y | tst.js:10:4:10:4 | y | +| tst.js:11:1:11:1 | x | tst.js:11:1:11:1 | x | +| tst.js:11:1:11:6 | x && y | tst.js:11:1:11:6 | x && y | +| tst.js:11:6:11:6 | y | tst.js:11:6:11:6 | y | +| tst.js:12:1:12:1 | x | tst.js:12:1:12:1 | x | +| tst.js:12:1:12:6 | x \|\| y | tst.js:12:1:12:6 | x \|\| y | +| tst.js:12:6:12:6 | y | tst.js:12:6:12:6 | y | +| tst.js:13:1:13:1 | z | tst.js:13:1:13:1 | z | +| tst.js:13:1:13:5 | z = y | tst.js:13:1:13:5 | z = y | +| tst.js:13:5:13:5 | y | tst.js:13:5:13:5 | y | +| tst.js:14:1:14:1 | z | tst.js:14:1:14:1 | z | +| tst.js:14:1:14:9 | z ? x : y | tst.js:14:1:14:9 | z ? x : y | +| tst.js:14:5:14:5 | x | tst.js:14:5:14:5 | x | +| tst.js:14:9:14:9 | y | tst.js:14:9:14:9 | y | +| tst.js:16:1:20:2 | (functi ... "";\\n}) | tst.js:16:1:20:2 | (functi ... "";\\n}) | +| tst.js:16:1:20:9 | (functi ... ("arg") | tst.js:16:1:20:9 | (functi ... ("arg") | +| tst.js:16:2:20:1 | functio ... n "";\\n} | tst.js:16:2:20:1 | functio ... n "";\\n} | +| tst.js:16:11:16:11 | f | tst.js:16:11:16:11 | f | +| tst.js:16:13:16:13 | a | tst.js:16:13:16:13 | a | +| tst.js:16:13:16:13 | a | tst.js:16:13:16:13 | a | +| tst.js:17:7:17:10 | Math | tst.js:17:7:17:10 | Math | +| tst.js:17:7:17:17 | Math.random | tst.js:17:7:17:17 | Math.random | +| tst.js:17:7:17:19 | Math.random() | tst.js:17:7:17:19 | Math.random() | +| tst.js:17:7:17:25 | Math.random() > 0.5 | tst.js:17:7:17:25 | Math.random() > 0.5 | +| tst.js:17:12:17:17 | random | tst.js:17:12:17:17 | random | +| tst.js:17:23:17:25 | 0.5 | tst.js:17:23:17:25 | 0.5 | +| tst.js:18:12:18:12 | a | tst.js:18:12:18:12 | a | +| tst.js:19:10:19:11 | "" | tst.js:19:10:19:11 | "" | +| tst.js:20:4:20:8 | "arg" | tst.js:20:4:20:8 | "arg" | +| tst.js:22:5:22:20 | { readFileSync } | tst.js:22:5:22:20 | { readFileSync } | +| tst.js:22:5:22:25 | { readF ... } = fs | tst.js:22:5:22:25 | { readF ... } = fs | +| tst.js:22:7:22:18 | readFileSync | tst.js:22:7:22:18 | readFileSync | +| tst.js:22:7:22:18 | readFileSync | tst.js:22:7:22:18 | readFileSync | +| tst.js:22:24:22:25 | fs | tst.js:22:24:22:25 | fs | +| tst.js:23:1:23:12 | readFileSync | tst.js:23:1:23:12 | readFileSync | +| tst.js:25:1:25:3 | ++x | tst.js:25:1:25:3 | ++x | +| tst.js:25:3:25:3 | x | tst.js:25:3:25:3 | x | +| tst.js:26:1:26:1 | x | tst.js:26:1:26:1 | x | +| tst.js:28:1:30:1 | (() =>\\n ... ables\\n) | tst.js:28:1:30:1 | (() =>\\n ... ables\\n) | +| tst.js:28:1:30:3 | (() =>\\n ... les\\n)() | tst.js:28:1:30:3 | (() =>\\n ... les\\n)() | +| tst.js:28:2:29:3 | () =>\\n x | tst.js:28:2:29:3 | () =>\\n x | +| tst.js:29:3:29:3 | x | tst.js:29:3:29:3 | x | +| tst.js:32:10:32:10 | g | tst.js:32:10:32:10 | g | +| tst.js:32:12:32:12 | b | tst.js:32:12:32:12 | b | +| tst.js:32:12:32:12 | b | tst.js:32:12:32:12 | b | +| tst.js:33:10:33:10 | x | tst.js:33:10:33:10 | x | +| tst.js:35:1:35:1 | g | tst.js:35:1:35:1 | g | +| tst.js:35:1:35:7 | g(true) | tst.js:35:1:35:7 | g(true) | +| tst.js:35:3:35:6 | true | tst.js:35:3:35:6 | true | +| tst.js:37:5:37:5 | o | tst.js:37:5:37:5 | o | +| tst.js:37:5:42:1 | o = {\\n ... ;\\n }\\n} | tst.js:37:5:42:1 | o = {\\n ... ;\\n }\\n} | +| tst.js:37:9:42:1 | {\\n x: ... ;\\n }\\n} | tst.js:37:9:42:1 | {\\n x: ... ;\\n }\\n} | +| tst.js:38:3:38:3 | x | tst.js:38:3:38:3 | x | +| tst.js:38:6:38:9 | null | tst.js:38:6:38:9 | null | +| tst.js:39:3:39:3 | m | tst.js:39:3:39:3 | m | +| tst.js:39:4:41:3 | () {\\n this;\\n } | tst.js:39:4:41:3 | () {\\n this;\\n } | +| tst.js:40:5:40:8 | this | tst.js:40:5:40:8 | this | +| tst.js:43:1:43:1 | o | tst.js:43:1:43:1 | o | +| tst.js:43:1:43:3 | o.x | tst.js:43:1:43:3 | o.x | +| tst.js:43:3:43:3 | x | tst.js:43:3:43:3 | x | +| tst.js:44:1:44:1 | o | tst.js:44:1:44:1 | o | +| tst.js:44:1:44:3 | o.m | tst.js:44:1:44:3 | o.m | +| tst.js:44:1:44:5 | o.m() | tst.js:44:1:44:5 | o.m() | +| tst.js:44:3:44:3 | m | tst.js:44:3:44:3 | m | +| tst.js:46:1:46:6 | global | tst.js:46:1:46:6 | global | +| tst.js:46:1:46:11 | global = "" | tst.js:46:1:46:11 | global = "" | +| tst.js:46:10:46:11 | "" | tst.js:46:10:46:11 | "" | +| tst.js:47:1:47:6 | global | tst.js:47:1:47:6 | global | +| tst.js:49:7:49:7 | A | tst.js:49:7:49:7 | A | +| tst.js:49:17:49:17 | B | tst.js:49:17:49:17 | B | +| tst.js:50:3:50:13 | constructor | tst.js:50:3:50:13 | constructor | +| tst.js:50:14:53:3 | () {\\n ... et`\\n } | tst.js:50:14:53:3 | () {\\n ... et`\\n } | +| tst.js:51:5:51:9 | super | tst.js:51:5:51:9 | super | +| tst.js:51:5:51:13 | super(42) | tst.js:51:5:51:13 | super(42) | +| tst.js:51:11:51:12 | 42 | tst.js:51:11:51:12 | 42 | +| tst.js:52:5:52:14 | new.target | tst.js:52:5:52:14 | new.target | +| tst.js:55:1:55:1 | A | tst.js:55:1:55:1 | A | +| tst.js:57:1:57:9 | `x: ${x}` | tst.js:57:1:57:9 | `x: ${x}` | +| tst.js:57:2:57:4 | x: | tst.js:57:2:57:4 | x: | +| tst.js:57:7:57:7 | x | tst.js:57:7:57:7 | x | +| tst.js:58:1:58:3 | tag | tst.js:58:1:58:3 | tag | +| tst.js:58:1:58:13 | tag `x: ${x}` | tst.js:58:1:58:13 | tag `x: ${x}` | +| tst.js:58:5:58:13 | `x: ${x}` | tst.js:58:5:58:13 | `x: ${x}` | +| tst.js:58:6:58:8 | x: | tst.js:58:6:58:8 | x: | +| tst.js:58:11:58:11 | x | tst.js:58:11:58:11 | x | +| tst.js:60:1:60:1 | g | tst.js:60:1:60:1 | g | +| tst.js:61:1:61:5 | ::o.m | tst.js:61:1:61:5 | ::o.m | +| tst.js:61:3:61:3 | o | tst.js:61:3:61:3 | o | +| tst.js:61:3:61:5 | o.m | tst.js:61:3:61:5 | o.m | +| tst.js:61:5:61:5 | m | tst.js:61:5:61:5 | m | +| tst.js:62:1:62:1 | o | tst.js:62:1:62:1 | o | +| tst.js:62:1:62:4 | o::g | tst.js:62:1:62:4 | o::g | +| tst.js:62:4:62:4 | g | tst.js:62:4:62:4 | g | +| tst.js:64:11:64:11 | h | tst.js:64:11:64:11 | h | +| tst.js:65:3:65:10 | yield 42 | tst.js:65:3:65:10 | yield 42 | +| tst.js:65:9:65:10 | 42 | tst.js:65:9:65:10 | 42 | +| tst.js:66:7:66:9 | tmp | tst.js:66:7:66:9 | tmp | +| tst.js:66:7:66:25 | tmp = function.sent | tst.js:66:7:66:25 | tmp = function.sent | +| tst.js:66:13:66:25 | function.sent | tst.js:66:13:66:25 | function.sent | +| tst.js:68:5:68:8 | iter | tst.js:68:5:68:8 | iter | +| tst.js:68:5:68:14 | iter = h() | tst.js:68:5:68:14 | iter = h() | +| tst.js:68:12:68:12 | h | tst.js:68:12:68:12 | h | +| tst.js:68:12:68:14 | h() | tst.js:68:12:68:14 | h() | +| tst.js:69:1:69:4 | iter | tst.js:69:1:69:4 | iter | +| tst.js:69:1:69:9 | iter.next | tst.js:69:1:69:9 | iter.next | +| tst.js:69:1:69:13 | iter.next(23) | tst.js:69:1:69:13 | iter.next(23) | +| tst.js:69:6:69:9 | next | tst.js:69:6:69:9 | next | +| tst.js:69:11:69:12 | 23 | tst.js:69:11:69:12 | 23 | +| tst.js:71:16:71:16 | k | tst.js:71:16:71:16 | k | +| tst.js:72:3:72:11 | await p() | tst.js:72:3:72:11 | await p() | +| tst.js:72:9:72:9 | p | tst.js:72:9:72:9 | p | +| tst.js:72:9:72:11 | p() | tst.js:72:9:72:11 | p() | +| tst.js:75:5:75:5 | m | tst.js:75:5:75:5 | m | +| tst.js:75:5:75:21 | m = import('foo') | tst.js:75:5:75:21 | m = import('foo') | +| tst.js:75:9:75:21 | import('foo') | tst.js:75:9:75:21 | import('foo') | +| tst.js:75:16:75:20 | 'foo' | tst.js:75:16:75:20 | 'foo' | +| tst.js:77:10:77:10 | i | tst.js:77:10:77:10 | i | +| tst.js:77:10:77:10 | i | tst.js:77:10:77:10 | i | +| tst.js:77:15:77:15 | o | tst.js:77:15:77:15 | o | +| tst.js:78:3:78:3 | i | tst.js:78:3:78:3 | i | +| tst.js:80:10:80:10 | v | tst.js:80:10:80:10 | v | +| tst.js:80:10:80:10 | v | tst.js:80:10:80:10 | v | +| tst.js:80:15:80:15 | o | tst.js:80:15:80:15 | o | +| tst.js:81:3:81:3 | v | tst.js:81:3:81:3 | v | +| tst.js:83:5:83:7 | vs1 | tst.js:83:5:83:7 | vs1 | +| tst.js:83:5:83:28 | vs1 = [ ... o) v ] | tst.js:83:5:83:28 | vs1 = [ ... o) v ] | +| tst.js:83:11:83:28 | [ for (v of o) v ] | tst.js:83:11:83:28 | [ for (v of o) v ] | +| tst.js:83:13:83:24 | for (v of o) | tst.js:83:13:83:24 | for (v of o) | +| tst.js:83:18:83:18 | v | tst.js:83:18:83:18 | v | +| tst.js:83:23:83:23 | o | tst.js:83:23:83:23 | o | +| tst.js:83:26:83:26 | v | tst.js:83:26:83:26 | v | +| tst.js:85:5:85:7 | vs2 | tst.js:85:5:85:7 | vs2 | +| tst.js:85:5:85:28 | vs2 = ( ... o) v ) | tst.js:85:5:85:28 | vs2 = ( ... o) v ) | +| tst.js:85:11:85:28 | ( for (v of o) v ) | tst.js:85:11:85:28 | ( for (v of o) v ) | +| tst.js:85:13:85:24 | for (v of o) | tst.js:85:13:85:24 | for (v of o) | +| tst.js:85:18:85:18 | v | tst.js:85:18:85:18 | v | +| tst.js:85:23:85:23 | o | tst.js:85:23:85:23 | o | +| tst.js:85:26:85:26 | v | tst.js:85:26:85:26 | v | +| tst.js:87:1:92:2 | (functi ... + z;\\n}) | tst.js:87:1:92:2 | (functi ... + z;\\n}) | +| tst.js:87:1:96:2 | (functi ... r: 0\\n}) | tst.js:87:1:96:2 | (functi ... r: 0\\n}) | +| tst.js:87:2:92:1 | functio ... + z;\\n} | tst.js:87:2:92:1 | functio ... + z;\\n} | +| tst.js:87:11:87:24 | { p: x, ...o } | tst.js:87:11:87:24 | { p: x, ...o } | +| tst.js:87:11:87:24 | { p: x, ...o } | tst.js:87:11:87:24 | { p: x, ...o } | +| tst.js:87:13:87:13 | p | tst.js:87:13:87:13 | p | +| tst.js:87:16:87:16 | x | tst.js:87:16:87:16 | x | +| tst.js:87:22:87:22 | o | tst.js:87:22:87:22 | o | +| tst.js:88:7:88:14 | { q: y } | tst.js:88:7:88:14 | { q: y } | +| tst.js:88:7:88:18 | { q: y } = o | tst.js:88:7:88:18 | { q: y } = o | +| tst.js:88:9:88:9 | q | tst.js:88:9:88:9 | q | +| tst.js:88:12:88:12 | y | tst.js:88:12:88:12 | y | +| tst.js:88:18:88:18 | o | tst.js:88:18:88:18 | o | +| tst.js:89:7:89:7 | z | tst.js:89:7:89:7 | z | +| tst.js:89:7:89:7 | z | tst.js:89:7:89:7 | z | +| tst.js:90:3:90:16 | ({ r: z } = o) | tst.js:90:3:90:16 | ({ r: z } = o) | +| tst.js:90:4:90:11 | { r: z } | tst.js:90:4:90:11 | { r: z } | +| tst.js:90:4:90:15 | { r: z } = o | tst.js:90:4:90:15 | { r: z } = o | +| tst.js:90:6:90:6 | r | tst.js:90:6:90:6 | r | +| tst.js:90:9:90:9 | z | tst.js:90:9:90:9 | z | +| tst.js:90:15:90:15 | o | tst.js:90:15:90:15 | o | +| tst.js:91:10:91:10 | x | tst.js:91:10:91:10 | x | +| tst.js:91:10:91:14 | x + y | tst.js:91:10:91:14 | x + y | +| tst.js:91:10:91:18 | x + y + z | tst.js:91:10:91:18 | x + y + z | +| tst.js:91:14:91:14 | y | tst.js:91:14:91:14 | y | +| tst.js:91:18:91:18 | z | tst.js:91:18:91:18 | z | +| tst.js:92:4:96:1 | {\\n p: ... r: 0\\n} | tst.js:92:4:96:1 | {\\n p: ... r: 0\\n} | +| tst.js:93:3:93:3 | p | tst.js:93:3:93:3 | p | +| tst.js:93:6:93:7 | 19 | tst.js:93:6:93:7 | 19 | +| tst.js:94:3:94:3 | q | tst.js:94:3:94:3 | q | +| tst.js:94:6:94:7 | 23 | tst.js:94:6:94:7 | 23 | +| tst.js:95:3:95:3 | r | tst.js:95:3:95:3 | r | +| tst.js:95:6:95:6 | 0 | tst.js:95:6:95:6 | 0 | +| tst.js:98:1:103:2 | (functi ... + z;\\n}) | tst.js:98:1:103:2 | (functi ... + z;\\n}) | +| tst.js:98:1:103:17 | (functi ... 3, 0 ]) | tst.js:98:1:103:17 | (functi ... 3, 0 ]) | +| tst.js:98:2:103:1 | functio ... + z;\\n} | tst.js:98:2:103:1 | functio ... + z;\\n} | +| tst.js:98:11:98:24 | [ x, ...rest ] | tst.js:98:11:98:24 | [ x, ...rest ] | +| tst.js:98:11:98:24 | [ x, ...rest ] | tst.js:98:11:98:24 | [ x, ...rest ] | +| tst.js:98:13:98:13 | x | tst.js:98:13:98:13 | x | +| tst.js:98:19:98:22 | rest | tst.js:98:19:98:22 | rest | +| tst.js:99:7:99:11 | [ y ] | tst.js:99:7:99:11 | [ y ] | +| tst.js:99:7:99:18 | [ y ] = rest | tst.js:99:7:99:18 | [ y ] = rest | +| tst.js:99:9:99:9 | y | tst.js:99:9:99:9 | y | +| tst.js:99:15:99:18 | rest | tst.js:99:15:99:18 | rest | +| tst.js:100:7:100:7 | z | tst.js:100:7:100:7 | z | +| tst.js:100:7:100:7 | z | tst.js:100:7:100:7 | z | +| tst.js:101:3:101:9 | [ , z ] | tst.js:101:3:101:9 | [ , z ] | +| tst.js:101:3:101:16 | [ , z ] = rest | tst.js:101:3:101:16 | [ , z ] = rest | +| tst.js:101:7:101:7 | z | tst.js:101:7:101:7 | z | +| tst.js:101:13:101:16 | rest | tst.js:101:13:101:16 | rest | +| tst.js:102:10:102:10 | x | tst.js:102:10:102:10 | x | +| tst.js:102:10:102:14 | x + y | tst.js:102:10:102:14 | x + y | +| tst.js:102:10:102:18 | x + y + z | tst.js:102:10:102:18 | x + y + z | +| tst.js:102:14:102:14 | y | tst.js:102:14:102:14 | y | +| tst.js:102:18:102:18 | z | tst.js:102:18:102:18 | z | +| tst.js:103:4:103:16 | [ 19, 23, 0 ] | tst.js:103:4:103:16 | [ 19, 23, 0 ] | +| tst.js:103:6:103:7 | 19 | tst.js:103:6:103:7 | 19 | +| tst.js:103:10:103:11 | 23 | tst.js:103:10:103:11 | 23 | +| tst.js:103:14:103:14 | 0 | tst.js:103:14:103:14 | 0 | +| tst.js:105:1:105:1 | x | tst.js:105:1:105:1 | x | +| tst.js:105:1:105:6 | x ?? y | tst.js:105:1:105:6 | x ?? y | +| tst.js:105:6:105:6 | y | tst.js:105:6:105:6 | y | +| tst.js:107:1:113:2 | (functi ... v2c;\\n}) | tst.js:107:1:113:2 | (functi ... v2c;\\n}) | +| tst.js:107:2:113:1 | functio ... v2c;\\n} | tst.js:107:2:113:1 | functio ... v2c;\\n} | +| tst.js:108:6:108:32 | {v1a, v ... = o1c} | tst.js:108:6:108:32 | {v1a, v ... = o1c} | +| tst.js:108:6:108:38 | {v1a, v ... } = o1d | tst.js:108:6:108:38 | {v1a, v ... } = o1d | +| tst.js:108:7:108:9 | v1a | tst.js:108:7:108:9 | v1a | +| tst.js:108:7:108:9 | v1a | tst.js:108:7:108:9 | v1a | +| tst.js:108:12:108:14 | v1b | tst.js:108:12:108:14 | v1b | +| tst.js:108:12:108:14 | v1b | tst.js:108:12:108:14 | v1b | +| tst.js:108:18:108:20 | o1b | tst.js:108:18:108:20 | o1b | +| tst.js:108:23:108:25 | v1c | tst.js:108:23:108:25 | v1c | +| tst.js:108:23:108:25 | v1c | tst.js:108:23:108:25 | v1c | +| tst.js:108:29:108:31 | o1c | tst.js:108:29:108:31 | o1c | +| tst.js:108:36:108:38 | o1d | tst.js:108:36:108:38 | o1d | +| tst.js:109:2:109:4 | v1a | tst.js:109:2:109:4 | v1a | +| tst.js:109:2:109:10 | v1a + v1b | tst.js:109:2:109:10 | v1a + v1b | +| tst.js:109:2:109:16 | v1a + v1b + v1c | tst.js:109:2:109:16 | v1a + v1b + v1c | +| tst.js:109:8:109:10 | v1b | tst.js:109:8:109:10 | v1b | +| tst.js:109:14:109:16 | v1c | tst.js:109:14:109:16 | v1c | +| tst.js:111:6:111:32 | [v2a, v ... = o2c] | tst.js:111:6:111:32 | [v2a, v ... = o2c] | +| tst.js:111:6:111:38 | [v2a, v ... ] = o2d | tst.js:111:6:111:38 | [v2a, v ... ] = o2d | +| tst.js:111:7:111:9 | v2a | tst.js:111:7:111:9 | v2a | +| tst.js:111:12:111:14 | v2b | tst.js:111:12:111:14 | v2b | +| tst.js:111:18:111:20 | o2b | tst.js:111:18:111:20 | o2b | +| tst.js:111:23:111:25 | v2c | tst.js:111:23:111:25 | v2c | +| tst.js:111:29:111:31 | o2c | tst.js:111:29:111:31 | o2c | +| tst.js:111:36:111:38 | o2d | tst.js:111:36:111:38 | o2d | +| tst.js:112:2:112:4 | v2a | tst.js:112:2:112:4 | v2a | +| tst.js:112:2:112:10 | v2a + v2b | tst.js:112:2:112:10 | v2a + v2b | +| tst.js:112:2:112:16 | v2a + v2b + v2c | tst.js:112:2:112:16 | v2a + v2b + v2c | +| tst.js:112:8:112:10 | v2b | tst.js:112:8:112:10 | v2b | +| tst.js:112:14:112:16 | v2c | tst.js:112:14:112:16 | v2c | +| tst.js:115:1:115:5 | Array | tst.js:115:1:115:5 | Array | +| tst.js:115:1:115:10 | Array.call | tst.js:115:1:115:10 | Array.call | +| tst.js:115:1:115:12 | Array.call() | tst.js:115:1:115:12 | Array.call() | +| tst.js:115:1:115:12 | reflective call | tst.js:115:1:115:12 | Array.call() | +| tst.js:115:7:115:10 | call | tst.js:115:7:115:10 | call | +| tst.ts:1:18:1:18 | A | tst.ts:1:18:1:18 | A | +| tst.ts:2:14:2:14 | x | tst.ts:2:14:2:14 | x | +| tst.ts:2:14:2:19 | x = 42 | tst.ts:2:14:2:19 | x = 42 | +| tst.ts:2:18:2:19 | 42 | tst.ts:2:18:2:19 | 42 | +| tst.ts:3:3:3:6 | setX | tst.ts:3:3:3:6 | setX | +| tst.ts:3:3:3:8 | setX() | tst.ts:3:3:3:8 | setX() | +| tst.ts:4:3:4:3 | x | tst.ts:4:3:4:3 | x | +| tst.ts:7:10:7:13 | setX | tst.ts:7:10:7:13 | setX | +| tst.ts:8:3:8:3 | A | tst.ts:8:3:8:3 | A | +| tst.ts:8:3:8:5 | A.x | tst.ts:8:3:8:5 | A.x | +| tst.ts:8:3:8:10 | A.x = 23 | tst.ts:8:3:8:10 | A.x = 23 | +| tst.ts:8:5:8:5 | x | tst.ts:8:5:8:5 | x | +| tst.ts:8:9:8:10 | 23 | tst.ts:8:9:8:10 | 23 | +| tst.ts:11:5:11:7 | nd2 | tst.ts:11:5:11:7 | nd2 | +| tst.ts:11:5:11:23 | nd2 = A.x as number | tst.ts:11:5:11:23 | nd2 = A.x as number | +| tst.ts:11:11:11:11 | A | tst.ts:11:11:11:11 | A | +| tst.ts:11:11:11:13 | A.x | tst.ts:11:11:11:13 | A.x | +| tst.ts:11:11:11:23 | A.x as number | tst.ts:11:11:11:23 | A.x as number | +| tst.ts:11:13:11:13 | x | tst.ts:11:13:11:13 | x | +| tst.ts:13:7:13:16 | StringList | tst.ts:13:7:13:16 | StringList | +| tst.ts:13:26:13:29 | List | tst.ts:13:26:13:29 | List | +| tst.ts:13:26:13:37 | List | tst.ts:13:26:13:37 | List | +| tst.ts:13:39:13:38 | (...arg ... rgs); } | tst.ts:13:39:13:38 | (...arg ... rgs); } | +| tst.ts:13:39:13:38 | ...args | tst.ts:13:39:13:38 | ...args | +| tst.ts:13:39:13:38 | args | tst.ts:13:39:13:38 | args | +| tst.ts:13:39:13:38 | args | tst.ts:13:39:13:38 | args | +| tst.ts:13:39:13:38 | args | tst.ts:13:39:13:38 | args | +| tst.ts:13:39:13:38 | constructor | tst.ts:13:39:13:38 | constructor | +| tst.ts:13:39:13:38 | super | tst.ts:13:39:13:38 | super | +| tst.ts:13:39:13:38 | super(...args) | tst.ts:13:39:13:38 | super(...args) | diff --git a/javascript/ql/test/library-tests/DataFlow/enclosingExpr.ql b/javascript/ql/test/library-tests/DataFlow/enclosingExpr.ql new file mode 100644 index 00000000000..6b0a506ce79 --- /dev/null +++ b/javascript/ql/test/library-tests/DataFlow/enclosingExpr.ql @@ -0,0 +1,4 @@ +import javascript + +from DataFlow::Node node +select node, node.getEnclosingExpr() diff --git a/javascript/ql/test/library-tests/DataFlow/flowStep.expected b/javascript/ql/test/library-tests/DataFlow/flowStep.expected index a6446732fbe..31e11c60b74 100644 --- a/javascript/ql/test/library-tests/DataFlow/flowStep.expected +++ b/javascript/ql/test/library-tests/DataFlow/flowStep.expected @@ -7,6 +7,11 @@ | sources.js:3:11:3:11 | x | sources.js:4:10:4:10 | x | | sources.js:4:10:4:13 | x+19 | sources.js:3:1:5:6 | (functi ... \\n})(23) | | sources.js:5:4:5:5 | 23 | sources.js:3:11:3:11 | x | +| sources.js:9:14:9:18 | array | sources.js:10:19:10:23 | array | +| sources.js:9:14:9:18 | array | sources.js:11:23:11:27 | array | +| sources.js:10:12:10:14 | key | sources.js:10:28:10:30 | key | +| sources.js:11:12:11:18 | key | sources.js:11:32:11:34 | key | +| sources.js:11:14:11:16 | key | sources.js:11:12:11:18 | key | | tst.js:1:1:1:1 | x | tst.js:28:2:28:1 | x | | tst.js:1:1:1:1 | x | tst.js:32:1:32:0 | x | | tst.js:1:10:1:11 | fs | tst.js:1:10:1:11 | fs | @@ -142,11 +147,11 @@ | tst.js:111:29:111:31 | o2c | tst.js:111:6:111:38 | v2c | | tst.js:111:36:111:38 | o2d | tst.js:111:6:111:32 | [v2a, v ... = o2c] | | tst.js:115:1:115:12 | reflective call | tst.js:115:1:115:12 | Array.call() | -| tst.ts:1:1:1:1 | A | tst.ts:1:11:1:11 | A | +| tst.ts:1:1:1:1 | A | tst.ts:1:18:1:18 | A | | tst.ts:1:1:1:1 | A | tst.ts:7:1:7:0 | A | -| tst.ts:1:1:5:1 | A | tst.ts:7:1:7:0 | A | -| tst.ts:1:1:5:1 | A | tst.ts:11:11:11:11 | A | -| tst.ts:1:1:5:1 | namespa ... lysed\\n} | tst.ts:1:1:5:1 | A | +| tst.ts:1:8:5:1 | A | tst.ts:7:1:7:0 | A | +| tst.ts:1:8:5:1 | A | tst.ts:11:11:11:11 | A | +| tst.ts:1:8:5:1 | namespa ... lysed\\n} | tst.ts:1:8:5:1 | A | | tst.ts:2:14:2:19 | x | tst.ts:4:3:4:3 | x | | tst.ts:2:18:2:19 | 42 | tst.ts:2:14:2:19 | x | | tst.ts:7:1:7:0 | A | tst.ts:8:3:8:3 | A | diff --git a/javascript/ql/test/library-tests/DataFlow/incomplete.expected b/javascript/ql/test/library-tests/DataFlow/incomplete.expected index aee8fd44421..35413033fe7 100644 --- a/javascript/ql/test/library-tests/DataFlow/incomplete.expected +++ b/javascript/ql/test/library-tests/DataFlow/incomplete.expected @@ -8,6 +8,11 @@ | sources.js:1:6:1:11 | exceptional return of anonymous function | call | | sources.js:3:1:5:6 | exceptional return of (functi ... \\n})(23) | call | | sources.js:3:2:5:1 | exceptional return of anonymous function | call | +| sources.js:9:1:12:1 | exceptional return of function foo | call | +| sources.js:9:14:9:18 | array | call | +| sources.js:10:12:10:14 | key | heap | +| sources.js:11:12:11:18 | key | heap | +| sources.js:11:14:11:16 | key | heap | | tst.js:1:10:1:11 | fs | import | | tst.js:16:1:20:9 | exceptional return of (functi ... ("arg") | call | | tst.js:16:2:20:1 | exceptional return of function f | call | diff --git a/javascript/ql/test/library-tests/DataFlow/options b/javascript/ql/test/library-tests/DataFlow/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/library-tests/DataFlow/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/DataFlow/parameters.expected b/javascript/ql/test/library-tests/DataFlow/parameters.expected index b7746f41c8a..31bab07c4e2 100644 --- a/javascript/ql/test/library-tests/DataFlow/parameters.expected +++ b/javascript/ql/test/library-tests/DataFlow/parameters.expected @@ -1,5 +1,6 @@ | sources.js:1:6:1:6 | x | | sources.js:3:11:3:11 | x | +| sources.js:9:14:9:18 | array | | tst.js:16:13:16:13 | a | | tst.js:32:12:32:12 | b | | tst.js:87:11:87:24 | { p: x, ...o } | diff --git a/javascript/ql/test/library-tests/DataFlow/sources.expected b/javascript/ql/test/library-tests/DataFlow/sources.expected index 185cc89e4ad..37a54027371 100644 --- a/javascript/ql/test/library-tests/DataFlow/sources.expected +++ b/javascript/ql/test/library-tests/DataFlow/sources.expected @@ -13,6 +13,12 @@ | sources.js:3:2:5:1 | functio ... x+19;\\n} | | sources.js:3:11:3:11 | x | | sources.js:7:1:7:3 | /x/ | +| sources.js:9:1:9:0 | this | +| sources.js:9:1:12:1 | functio ... ey; }\\n} | +| sources.js:9:14:9:18 | array | +| sources.js:10:12:10:14 | key | +| sources.js:11:12:11:18 | { key } | +| sources.js:11:14:11:16 | key | | tst.js:1:1:1:0 | this | | tst.js:1:1:1:24 | import ... m 'fs'; | | tst.js:1:10:1:11 | fs | @@ -60,6 +66,7 @@ | tst.js:72:9:72:9 | p | | tst.js:72:9:72:11 | p() | | tst.js:75:9:75:21 | import('foo') | +| tst.js:80:10:80:10 | v | | tst.js:83:11:83:28 | [ for (v of o) v ] | | tst.js:85:11:85:28 | ( for (v of o) v ) | | tst.js:87:1:96:2 | (functi ... r: 0\\n}) | diff --git a/javascript/ql/test/library-tests/DataFlow/sources.js b/javascript/ql/test/library-tests/DataFlow/sources.js index 653c5fc129c..7a5bb869efe 100644 --- a/javascript/ql/test/library-tests/DataFlow/sources.js +++ b/javascript/ql/test/library-tests/DataFlow/sources.js @@ -5,3 +5,8 @@ new (x => x); })(23); /x/; + +function foo(array) { + for (let key of array) { key; } + for (let { key } of array) { key; } +} diff --git a/javascript/ql/test/library-tests/DataFlow/tst.js b/javascript/ql/test/library-tests/DataFlow/tst.js index 5de8e4e8688..319ca7fcb45 100644 --- a/javascript/ql/test/library-tests/DataFlow/tst.js +++ b/javascript/ql/test/library-tests/DataFlow/tst.js @@ -113,5 +113,3 @@ x ?? y; // flow through short-circuiting operator }); Array.call() // flow from implicit call to `Array` to `Array.call` - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/DataFlow/tst.ts b/javascript/ql/test/library-tests/DataFlow/tst.ts index dca2ee632b7..29c85cba933 100644 --- a/javascript/ql/test/library-tests/DataFlow/tst.ts +++ b/javascript/ql/test/library-tests/DataFlow/tst.ts @@ -1,4 +1,4 @@ -namespace A { +export namespace A { export let x = 42; setX(); x; // global namespace exports are incompletely analysed @@ -11,5 +11,3 @@ function setX() { var nd2 = A.x as number; // flow through type assertions class StringList extends List {} // flow through expressions with type arguments - -// semmle-extractor-options: --source-type module diff --git a/javascript/ql/test/library-tests/Decorators/options b/javascript/ql/test/library-tests/Decorators/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/library-tests/Decorators/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/Decorators/tst.js b/javascript/ql/test/library-tests/Decorators/tst.js index 5b3f6432a00..d2135995168 100644 --- a/javascript/ql/test/library-tests/Decorators/tst.js +++ b/javascript/ql/test/library-tests/Decorators/tst.js @@ -7,5 +7,3 @@ var o = { get bar() { return 42 }, set bar(v) { } }; - -// semmle-extractor-options: --experimental \ No newline at end of file diff --git a/javascript/ql/test/library-tests/DefUse/es2015.js b/javascript/ql/test/library-tests/DefUse/es2015.js index 7bc60b605fc..2264f76cecc 100644 --- a/javascript/ql/test/library-tests/DefUse/es2015.js +++ b/javascript/ql/test/library-tests/DefUse/es2015.js @@ -4,5 +4,3 @@ for (let fn in fns) function getSquares() { return [for (i of [0, 1, 2]) i*i]; } - -//semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/DefUse/options b/javascript/ql/test/library-tests/DefUse/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/library-tests/DefUse/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/Errors/options b/javascript/ql/test/library-tests/Errors/options new file mode 100644 index 00000000000..13f987b19ca --- /dev/null +++ b/javascript/ql/test/library-tests/Errors/options @@ -0,0 +1 @@ +semmle-extractor-options: --tolerate-parse-errors diff --git a/javascript/ql/test/library-tests/Errors/setters.js b/javascript/ql/test/library-tests/Errors/setters.js index 50865e9f0c9..a8d40c45d2f 100644 --- a/javascript/ql/test/library-tests/Errors/setters.js +++ b/javascript/ql/test/library-tests/Errors/setters.js @@ -8,5 +8,3 @@ var o = { set y(...ys) {}, set z(z, ...zs) {} }; - -// semmle-extractor-options: --tolerate-parse-errors diff --git a/javascript/ql/test/library-tests/Errors/tst.js b/javascript/ql/test/library-tests/Errors/tst.js index baf2fbf4711..f0931ee0e49 100644 --- a/javascript/ql/test/library-tests/Errors/tst.js +++ b/javascript/ql/test/library-tests/Errors/tst.js @@ -1,4 +1,2 @@ while } - -// semmle-extractor-options: --tolerate-parse-errors diff --git a/javascript/ql/test/library-tests/Expr/legacyletexpr.js b/javascript/ql/test/library-tests/Expr/legacyletexpr.js index d5d121d8a79..6e7eedff052 100644 --- a/javascript/ql/test/library-tests/Expr/legacyletexpr.js +++ b/javascript/ql/test/library-tests/Expr/legacyletexpr.js @@ -1,3 +1 @@ console.log(let (x = 23, y = 19) x + y); - -//semmle-extractor-options: --experimental \ No newline at end of file diff --git a/javascript/ql/test/library-tests/Expr/mozextensions.js b/javascript/ql/test/library-tests/Expr/mozextensions.js index 5c44146b42f..bab58100c65 100644 --- a/javascript/ql/test/library-tests/Expr/mozextensions.js +++ b/javascript/ql/test/library-tests/Expr/mozextensions.js @@ -1,3 +1 @@ array.map(function(x) x+1); - -//semmle-extractor-options: --experimental \ No newline at end of file diff --git a/javascript/ql/test/library-tests/Expr/options b/javascript/ql/test/library-tests/Expr/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/library-tests/Expr/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/Expr/tests.expected b/javascript/ql/test/library-tests/Expr/tests.expected index 9757957cc39..1c3963b50ea 100644 --- a/javascript/ql/test/library-tests/Expr/tests.expected +++ b/javascript/ql/test/library-tests/Expr/tests.expected @@ -682,29 +682,29 @@ test_getTopLevel | functions.js:7:4:7:4 | x | functions.js:1:1:10:7 | | | functions.js:7:7:7:16 | in_f_again | functions.js:1:1:10:7 | | | functions.js:10:1:10:6 | global | functions.js:1:1:10:7 | | -| legacyletexpr.js:1:1:1:7 | console | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:1:1:11 | console.log | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:1:1:39 | console ... x + y) | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:9:1:11 | log | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:13:1:38 | let (x ... ) x + y | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:18:1:18 | x | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:18:1:23 | x = 23 | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:22:1:23 | 23 | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:26:1:26 | y | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:26:1:31 | y = 19 | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:30:1:31 | 19 | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:34:1:34 | x | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:34:1:38 | x + y | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:38:1:38 | y | legacyletexpr.js:1:1:3:42 | | -| mozextensions.js:1:1:1:5 | array | mozextensions.js:1:1:3:42 | | -| mozextensions.js:1:1:1:9 | array.map | mozextensions.js:1:1:3:42 | | -| mozextensions.js:1:1:1:26 | array.m ... x) x+1) | mozextensions.js:1:1:3:42 | | -| mozextensions.js:1:7:1:9 | map | mozextensions.js:1:1:3:42 | | -| mozextensions.js:1:11:1:25 | function(x) x+1 | mozextensions.js:1:1:3:42 | | -| mozextensions.js:1:20:1:20 | x | mozextensions.js:1:1:3:42 | | -| mozextensions.js:1:23:1:23 | x | mozextensions.js:1:1:3:42 | | -| mozextensions.js:1:23:1:25 | x+1 | mozextensions.js:1:1:3:42 | | -| mozextensions.js:1:25:1:25 | 1 | mozextensions.js:1:1:3:42 | | +| legacyletexpr.js:1:1:1:7 | console | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:1:1:11 | console.log | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:1:1:39 | console ... x + y) | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:9:1:11 | log | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:13:1:38 | let (x ... ) x + y | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:18:1:18 | x | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:18:1:23 | x = 23 | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:22:1:23 | 23 | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:26:1:26 | y | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:26:1:31 | y = 19 | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:30:1:31 | 19 | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:34:1:34 | x | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:34:1:38 | x + y | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:38:1:38 | y | legacyletexpr.js:1:1:2:0 | | +| mozextensions.js:1:1:1:5 | array | mozextensions.js:1:1:2:0 | | +| mozextensions.js:1:1:1:9 | array.map | mozextensions.js:1:1:2:0 | | +| mozextensions.js:1:1:1:26 | array.m ... x) x+1) | mozextensions.js:1:1:2:0 | | +| mozextensions.js:1:7:1:9 | map | mozextensions.js:1:1:2:0 | | +| mozextensions.js:1:11:1:25 | function(x) x+1 | mozextensions.js:1:1:2:0 | | +| mozextensions.js:1:20:1:20 | x | mozextensions.js:1:1:2:0 | | +| mozextensions.js:1:23:1:23 | x | mozextensions.js:1:1:2:0 | | +| mozextensions.js:1:23:1:25 | x+1 | mozextensions.js:1:1:2:0 | | +| mozextensions.js:1:25:1:25 | 1 | mozextensions.js:1:1:2:0 | | | nullSensitiveContexts.js:7:1:7:3 | foo | nullSensitiveContexts.js:1:1:61:0 | | | nullSensitiveContexts.js:7:1:7:8 | foo[bar] | nullSensitiveContexts.js:1:1:61:0 | | | nullSensitiveContexts.js:7:5:7:7 | bar | nullSensitiveContexts.js:1:1:61:0 | | @@ -1922,25 +1922,25 @@ test_getContainer | functions.js:7:4:7:4 | x | functions.js:1:1:9:1 | functio ... \\t\\t});\\n} | | functions.js:7:7:7:16 | in_f_again | functions.js:1:1:9:1 | functio ... \\t\\t});\\n} | | functions.js:10:1:10:6 | global | functions.js:1:1:10:7 | | -| legacyletexpr.js:1:1:1:7 | console | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:1:1:11 | console.log | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:1:1:39 | console ... x + y) | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:9:1:11 | log | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:13:1:38 | let (x ... ) x + y | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:18:1:18 | x | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:18:1:23 | x = 23 | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:22:1:23 | 23 | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:26:1:26 | y | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:26:1:31 | y = 19 | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:30:1:31 | 19 | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:34:1:34 | x | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:34:1:38 | x + y | legacyletexpr.js:1:1:3:42 | | -| legacyletexpr.js:1:38:1:38 | y | legacyletexpr.js:1:1:3:42 | | -| mozextensions.js:1:1:1:5 | array | mozextensions.js:1:1:3:42 | | -| mozextensions.js:1:1:1:9 | array.map | mozextensions.js:1:1:3:42 | | -| mozextensions.js:1:1:1:26 | array.m ... x) x+1) | mozextensions.js:1:1:3:42 | | -| mozextensions.js:1:7:1:9 | map | mozextensions.js:1:1:3:42 | | -| mozextensions.js:1:11:1:25 | function(x) x+1 | mozextensions.js:1:1:3:42 | | +| legacyletexpr.js:1:1:1:7 | console | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:1:1:11 | console.log | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:1:1:39 | console ... x + y) | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:9:1:11 | log | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:13:1:38 | let (x ... ) x + y | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:18:1:18 | x | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:18:1:23 | x = 23 | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:22:1:23 | 23 | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:26:1:26 | y | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:26:1:31 | y = 19 | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:30:1:31 | 19 | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:34:1:34 | x | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:34:1:38 | x + y | legacyletexpr.js:1:1:2:0 | | +| legacyletexpr.js:1:38:1:38 | y | legacyletexpr.js:1:1:2:0 | | +| mozextensions.js:1:1:1:5 | array | mozextensions.js:1:1:2:0 | | +| mozextensions.js:1:1:1:9 | array.map | mozextensions.js:1:1:2:0 | | +| mozextensions.js:1:1:1:26 | array.m ... x) x+1) | mozextensions.js:1:1:2:0 | | +| mozextensions.js:1:7:1:9 | map | mozextensions.js:1:1:2:0 | | +| mozextensions.js:1:11:1:25 | function(x) x+1 | mozextensions.js:1:1:2:0 | | | mozextensions.js:1:20:1:20 | x | mozextensions.js:1:11:1:25 | function(x) x+1 | | mozextensions.js:1:23:1:23 | x | mozextensions.js:1:11:1:25 | function(x) x+1 | | mozextensions.js:1:23:1:25 | x+1 | mozextensions.js:1:11:1:25 | function(x) x+1 | diff --git a/javascript/ql/test/library-tests/Externs/Point.js b/javascript/ql/test/library-tests/Externs/Point.js index a811a482009..ea4c950e7d2 100644 --- a/javascript/ql/test/library-tests/Externs/Point.js +++ b/javascript/ql/test/library-tests/Externs/Point.js @@ -17,4 +17,4 @@ Point.prototype['final']; /** @type {!Point} */ var aPoint; -//semmle-extractor-options: --externs \ No newline at end of file +/** @externs */ diff --git a/javascript/ql/test/library-tests/Flow/AbstractValues.expected b/javascript/ql/test/library-tests/Flow/AbstractValues.expected index f172a33c000..531faf562bd 100644 --- a/javascript/ql/test/library-tests/Flow/AbstractValues.expected +++ b/javascript/ql/test/library-tests/Flow/AbstractValues.expected @@ -194,8 +194,8 @@ | n.js:2:1:2:15 | function g | | n.js:2:1:2:15 | instance of function g | | n.js:3:16:3:23 | object literal | -| namespace-reexport.js:1:1:4:0 | exports object of module namespace-reexport | -| namespace-reexport.js:1:1:4:0 | module object of module namespace-reexport | +| namespace-reexport.js:1:1:2:0 | exports object of module namespace-reexport | +| namespace-reexport.js:1:1:2:0 | module object of module namespace-reexport | | nestedImport.js:1:1:13:0 | exports object of module nestedImport | | nestedImport.js:1:1:13:0 | module object of module nestedImport | | nestedImport.js:9:1:12:1 | function tst | @@ -208,6 +208,8 @@ | nodeJsLib.js:1:18:1:43 | instance of function nodeJsModule | | nodeJsLib.js:3:15:3:37 | function nodeJsFoo | | nodeJsLib.js:3:15:3:37 | instance of function nodeJsFoo | +| nullish-coalescing-op.ts:1:1:3:1 | function test | +| nullish-coalescing-op.ts:1:1:3:1 | instance of function test | | o.js:1:1:2:0 | exports object of module o | | o.js:1:1:2:0 | module object of module o | | objlit.js:1:14:1:15 | object literal | @@ -233,14 +235,14 @@ | objlit.js:43:12:45:3 | object literal | | reexport-d.js:1:1:2:0 | exports object of module reexport-d | | reexport-d.js:1:1:2:0 | module object of module reexport-d | -| reexport-mixins.js:1:1:4:0 | exports object of module reexport-mixins | -| reexport-mixins.js:1:1:4:0 | module object of module reexport-mixins | +| reexport-mixins.js:1:1:2:0 | exports object of module reexport-mixins | +| reexport-mixins.js:1:1:2:0 | module object of module reexport-mixins | | reexport-unknown.js:1:1:2:0 | exports object of module reexport-unknown | | reexport-unknown.js:1:1:2:0 | module object of module reexport-unknown | | reexport/client/src/index.js:1:1:3:0 | exports object of module index | | reexport/client/src/index.js:1:1:3:0 | module object of module index | -| reexport/lib/index.js:1:1:4:0 | exports object of module index | -| reexport/lib/index.js:1:1:4:0 | module object of module index | +| reexport/lib/index.js:1:1:2:0 | exports object of module index | +| reexport/lib/index.js:1:1:2:0 | module object of module index | | reexport/lib/src/utils/util.js:1:1:3:0 | exports object of module util | | reexport/lib/src/utils/util.js:1:1:3:0 | module object of module util | | refinements.js:1:1:8:1 | function f1 | @@ -339,8 +341,8 @@ | tst.js:174:1:183:1 | function awaitFlow | | tst.mjs:1:1:4:0 | exports object of module tst | | tst.mjs:1:1:4:0 | module object of module tst | -| tst.ts:1:1:15:0 | exports object of module tst | -| tst.ts:1:1:15:0 | module object of module tst | +| tst.ts:1:1:13:0 | exports object of module tst | +| tst.ts:1:1:13:0 | module object of module tst | | tst.ts:8:1:10:1 | function setX | | tst.ts:8:1:10:1 | instance of function setX | | with.js:1:1:17:1 | function f | diff --git a/javascript/ql/test/library-tests/Flow/abseval.expected b/javascript/ql/test/library-tests/Flow/abseval.expected index a856e3ec474..00d7f27da89 100644 --- a/javascript/ql/test/library-tests/Flow/abseval.expected +++ b/javascript/ql/test/library-tests/Flow/abseval.expected @@ -80,6 +80,7 @@ | classAccessors.js:12:9:12:11 | myZ | classAccessors.js:12:15:12:20 | this.z | file://:0:0:0:0 | indefinite value (call) | | classAccessors.js:12:9:12:11 | myZ | classAccessors.js:12:15:12:20 | this.z | file://:0:0:0:0 | indefinite value (heap) | | destructuring.js:2:7:2:24 | { x, y = (z = x) } | destructuring.js:2:28:2:28 | o | file://:0:0:0:0 | indefinite value (call) | +| destructuring.js:3:7:3:8 | z1 | destructuring.js:3:12:3:12 | z | file://:0:0:0:0 | indefinite value (call) | | destructuring.js:3:7:3:8 | z1 | destructuring.js:3:12:3:12 | z | file://:0:0:0:0 | indefinite value (heap) | | es2015.js:1:5:1:7 | Sup | es2015.js:1:11:6:1 | class { ... ;\\n }\\n} | es2015.js:1:11:6:1 | class Sup | | es2015.js:4:9:4:12 | ctor | es2015.js:4:16:4:25 | new.target | file://:0:0:0:0 | indefinite value (call) | @@ -203,6 +204,8 @@ | nodeJsClient.js:5:5:5:6 | x2 | nodeJsClient.js:5:10:5:15 | es.foo | esLib.js:3:8:3:24 | function foo | | nodeJsClient.js:5:5:5:6 | x2 | nodeJsClient.js:5:10:5:15 | es.foo | file://:0:0:0:0 | indefinite value (call) | | nodeJsClient.js:5:5:5:6 | x2 | nodeJsClient.js:5:10:5:15 | es.foo | file://:0:0:0:0 | indefinite value (heap) | +| nullish-coalescing-op.ts:2:7:2:7 | y | nullish-coalescing-op.ts:2:11:2:18 | x ?? 0.5 | file://:0:0:0:0 | indefinite value (call) | +| nullish-coalescing-op.ts:2:7:2:7 | y | nullish-coalescing-op.ts:2:11:2:18 | x ?? 0.5 | file://:0:0:0:0 | non-zero value | | objlit.js:1:5:1:5 | A | objlit.js:1:9:1:15 | A \|\| {} | file://:0:0:0:0 | indefinite value (global) | | objlit.js:1:5:1:5 | A | objlit.js:1:9:1:15 | A \|\| {} | objlit.js:1:14:1:15 | object literal | | objlit.js:7:5:7:5 | B | objlit.js:7:9:7:10 | {} | objlit.js:7:9:7:10 | object literal | diff --git a/javascript/ql/test/library-tests/Flow/getAPrototype.expected b/javascript/ql/test/library-tests/Flow/getAPrototype.expected index e8825515715..07ff1f76b24 100644 --- a/javascript/ql/test/library-tests/Flow/getAPrototype.expected +++ b/javascript/ql/test/library-tests/Flow/getAPrototype.expected @@ -40,6 +40,7 @@ | nestedImport.js:9:1:12:1 | instance of function tst | nestedImport.js:9:1:12:1 | instance of function tst | | nodeJsLib.js:1:18:1:43 | instance of function nodeJsModule | nodeJsLib.js:1:18:1:43 | instance of function nodeJsModule | | nodeJsLib.js:3:15:3:37 | instance of function nodeJsFoo | nodeJsLib.js:3:15:3:37 | instance of function nodeJsFoo | +| nullish-coalescing-op.ts:1:1:3:1 | instance of function test | nullish-coalescing-op.ts:1:1:3:1 | instance of function test | | objlit.js:2:9:2:21 | instance of anonymous function | objlit.js:2:9:2:21 | instance of anonymous function | | objlit.js:4:8:4:20 | instance of method baz | objlit.js:4:8:4:20 | instance of method baz | | objlit.js:10:2:12:1 | instance of anonymous function | objlit.js:10:2:12:1 | instance of anonymous function | diff --git a/javascript/ql/test/library-tests/Flow/namespace-reexport.js b/javascript/ql/test/library-tests/Flow/namespace-reexport.js index 0a1e70c5abe..021a140061a 100644 --- a/javascript/ql/test/library-tests/Flow/namespace-reexport.js +++ b/javascript/ql/test/library-tests/Flow/namespace-reexport.js @@ -1,3 +1 @@ export * as h from './h'; - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/Flow/nullish-coalescing-op.ts b/javascript/ql/test/library-tests/Flow/nullish-coalescing-op.ts new file mode 100644 index 00000000000..9fb2e4c1312 --- /dev/null +++ b/javascript/ql/test/library-tests/Flow/nullish-coalescing-op.ts @@ -0,0 +1,3 @@ +function test(x) { + let y = x ?? 0.5; +} diff --git a/javascript/ql/test/library-tests/Flow/options b/javascript/ql/test/library-tests/Flow/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/library-tests/Flow/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/Flow/reexport-mixins.js b/javascript/ql/test/library-tests/Flow/reexport-mixins.js index f38cd783b9b..ff303ad3432 100644 --- a/javascript/ql/test/library-tests/Flow/reexport-mixins.js +++ b/javascript/ql/test/library-tests/Flow/reexport-mixins.js @@ -1,3 +1 @@ export default from './mixins'; - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/Flow/reexport/lib/index.js b/javascript/ql/test/library-tests/Flow/reexport/lib/index.js index 5ffc9d62bc4..e20cf1a083e 100644 --- a/javascript/ql/test/library-tests/Flow/reexport/lib/index.js +++ b/javascript/ql/test/library-tests/Flow/reexport/lib/index.js @@ -1,3 +1 @@ export data from './src/utils/util' - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/Flow/reexport/lib/options b/javascript/ql/test/library-tests/Flow/reexport/lib/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/library-tests/Flow/reexport/lib/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/Flow/tst.ts b/javascript/ql/test/library-tests/Flow/tst.ts index 615efbb7103..63e329f75c0 100644 --- a/javascript/ql/test/library-tests/Flow/tst.ts +++ b/javascript/ql/test/library-tests/Flow/tst.ts @@ -1,4 +1,4 @@ -namespace A { +export namespace A { export let x = 42; setX(); let x2 = x; @@ -10,5 +10,3 @@ function setX() { } let a = A; - -// semmle-extractor-options: --source-type module diff --git a/javascript/ql/test/library-tests/Flow/types.expected b/javascript/ql/test/library-tests/Flow/types.expected index ba7aca62b08..9b13b469bed 100644 --- a/javascript/ql/test/library-tests/Flow/types.expected +++ b/javascript/ql/test/library-tests/Flow/types.expected @@ -113,6 +113,7 @@ | nodeJsClient.js:2:5:2:6 | es | nodeJsClient.js:2:10:2:27 | require('./esLib') | boolean, class, date, function, null, number, object, regular expression,string or undefined | | nodeJsClient.js:4:5:4:6 | x1 | nodeJsClient.js:4:10:4:15 | nj.foo | boolean, class, date, function, null, number, object, regular expression,string or undefined | | nodeJsClient.js:5:5:5:6 | x2 | nodeJsClient.js:5:10:5:15 | es.foo | boolean, class, date, function, null, number, object, regular expression,string or undefined | +| nullish-coalescing-op.ts:2:7:2:7 | y | nullish-coalescing-op.ts:2:11:2:18 | x ?? 0.5 | boolean, class, date, function, null, number, object, regular expression,string or undefined | | objlit.js:1:5:1:5 | A | objlit.js:1:9:1:15 | A \|\| {} | boolean, class, date, function, null, number, object, regular expression,string or undefined | | objlit.js:7:5:7:5 | B | objlit.js:7:9:7:10 | {} | object | | objlit.js:14:5:14:6 | x1 | objlit.js:14:10:14:10 | A | boolean, class, date, function, null, number, object, regular expression,string or undefined | diff --git a/javascript/ql/test/library-tests/Functions/exprclosures.js b/javascript/ql/test/library-tests/Functions/exprclosures.js index 66e0f855744..dd6a10086bd 100644 --- a/javascript/ql/test/library-tests/Functions/exprclosures.js +++ b/javascript/ql/test/library-tests/Functions/exprclosures.js @@ -1,3 +1 @@ a.map(function(x) x+1); - -//semmle-extractor-options: --experimental \ No newline at end of file diff --git a/javascript/ql/test/library-tests/Functions/options b/javascript/ql/test/library-tests/Functions/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/library-tests/Functions/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/GlobalAccessPaths/GlobalAccessPaths.expected b/javascript/ql/test/library-tests/GlobalAccessPaths/GlobalAccessPaths.expected index a54916e0142..414252881a2 100644 --- a/javascript/ql/test/library-tests/GlobalAccessPaths/GlobalAccessPaths.expected +++ b/javascript/ql/test/library-tests/GlobalAccessPaths/GlobalAccessPaths.expected @@ -1,4 +1,4 @@ -test_fromReference +test_getAReferenceTo | other_ns.js:2:11:2:12 | ns | NS | | other_ns.js:3:3:3:4 | ns | NS | | other_ns.js:3:3:3:8 | ns.foo | NS.foo | @@ -39,6 +39,7 @@ test_fromReference | test.js:12:19:12:25 | foo.bar | foo.bar | | test.js:13:7:13:15 | something | something | | test.js:14:5:14:23 | notUnique | bar.baz | +| test.js:14:5:14:23 | notUnique = bar.baz | bar.baz | | test.js:14:17:14:19 | bar | bar | | test.js:14:17:14:23 | bar.baz | bar.baz | | test.js:22:11:22:12 | ns | NS | @@ -54,10 +55,11 @@ test_fromReference | test.js:33:9:33:16 | bar = {} | foo.bar | | test.js:33:22:33:24 | foo | foo | | test.js:39:3:39:20 | lazyInit | foo.bar | +| test.js:39:3:39:20 | lazyInit = foo.bar | foo.bar | | test.js:39:14:39:16 | foo | foo | | test.js:39:14:39:20 | foo.bar | foo.bar | | test.js:40:3:40:10 | lazyInit | foo.bar | -test_fromRhs +test_getAnAssignmentTo | other_ns.js:4:9:4:16 | NS \|\| {} | NS | | other_ns.js:6:12:6:13 | {} | Conflict | | test.js:1:1:20:1 | functio ... ss {}\\n} | f | diff --git a/javascript/ql/test/library-tests/GlobalAccessPaths/GlobalAccessPaths.ql b/javascript/ql/test/library-tests/GlobalAccessPaths/GlobalAccessPaths.ql index 4a233f3947b..8412511df8d 100644 --- a/javascript/ql/test/library-tests/GlobalAccessPaths/GlobalAccessPaths.ql +++ b/javascript/ql/test/library-tests/GlobalAccessPaths/GlobalAccessPaths.ql @@ -1,9 +1,11 @@ import javascript -query string test_fromReference(DataFlow::Node node) { - result = GlobalAccessPath::fromReference(node) +query string test_getAReferenceTo(DataFlow::Node node) { + node = AccessPath::getAReferenceTo(result) } -query string test_fromRhs(DataFlow::Node node) { result = GlobalAccessPath::fromRhs(node) } +query string test_getAnAssignmentTo(DataFlow::Node node) { + node = AccessPath::getAnAssignmentTo(result) +} -query string test_assignedUnique() { GlobalAccessPath::isAssignedInUniqueFile(result) } +query string test_assignedUnique() { AccessPath::isAssignedInUniqueFile(result) } diff --git a/javascript/ql/test/library-tests/HTML/HtmlText/HtmlText.html b/javascript/ql/test/library-tests/HTML/HtmlText/HtmlText.html index 6cf4bfc564f..0b571650c40 100644 --- a/javascript/ql/test/library-tests/HTML/HtmlText/HtmlText.html +++ b/javascript/ql/test/library-tests/HTML/HtmlText/HtmlText.html @@ -1,4 +1,4 @@ -// semmle-extractor-options: --html all + (1) as child #0 diff --git a/javascript/ql/test/library-tests/HTML/HtmlText/options b/javascript/ql/test/library-tests/HTML/HtmlText/options new file mode 100644 index 00000000000..46bf0192945 --- /dev/null +++ b/javascript/ql/test/library-tests/HTML/HtmlText/options @@ -0,0 +1 @@ +semmle-extractor-options: --html all diff --git a/javascript/ql/test/library-tests/InterProceduralFlow/callback.js b/javascript/ql/test/library-tests/InterProceduralFlow/callback.js index 8ba9bd12fee..1e4d7aed2e8 100644 --- a/javascript/ql/test/library-tests/InterProceduralFlow/callback.js +++ b/javascript/ql/test/library-tests/InterProceduralFlow/callback.js @@ -28,4 +28,4 @@ let source3 = "source3"; call2(source3, store); call2(source3, confounder); -// semmle-extractor-options: --source-type module +export default 0; diff --git a/javascript/ql/test/library-tests/InterProceduralFlow/properties2.js b/javascript/ql/test/library-tests/InterProceduralFlow/properties2.js index 849516d57bb..9f1b0c9ba07 100644 --- a/javascript/ql/test/library-tests/InterProceduralFlow/properties2.js +++ b/javascript/ql/test/library-tests/InterProceduralFlow/properties2.js @@ -42,4 +42,4 @@ var o5 = {}; setP(o5, "not a source"); var sink10 = getP(o5); -// semmle-extractor-options: --source-type module +export default 0; diff --git a/javascript/ql/test/library-tests/JSON/JSONError.expected b/javascript/ql/test/library-tests/JSON/JSONError.expected index 37d5aabfd08..e63d3862491 100644 --- a/javascript/ql/test/library-tests/JSON/JSONError.expected +++ b/javascript/ql/test/library-tests/JSON/JSONError.expected @@ -1,2 +1 @@ | invalid.json:3:1:3:1 | Error: Comments are not legal in JSON. | -| invalid.json:4:1:4:1 | Error: Comments are not legal in JSON. | diff --git a/javascript/ql/test/library-tests/JSON/invalid.json b/javascript/ql/test/library-tests/JSON/invalid.json index 54c870bb907..03f76948f63 100644 --- a/javascript/ql/test/library-tests/JSON/invalid.json +++ b/javascript/ql/test/library-tests/JSON/invalid.json @@ -1,4 +1,3 @@ "hi" // JSON doesn't have comments -// semmle-extractor-options: --tolerate-parse-errors diff --git a/javascript/ql/test/library-tests/JSON/options b/javascript/ql/test/library-tests/JSON/options new file mode 100644 index 00000000000..13f987b19ca --- /dev/null +++ b/javascript/ql/test/library-tests/JSON/options @@ -0,0 +1 @@ +semmle-extractor-options: --tolerate-parse-errors diff --git a/javascript/ql/test/library-tests/Lines/Lines.expected b/javascript/ql/test/library-tests/Lines/Lines.expected index 552c1b8ff0e..e3c7973c9b8 100644 --- a/javascript/ql/test/library-tests/Lines/Lines.expected +++ b/javascript/ql/test/library-tests/Lines/Lines.expected @@ -1,4 +1,4 @@ -| tst1.js:1:1:1:55 | abc // semmle-extractor-options: --extract-program-text | abc // semmle-extractor-options: --extract-program-text | \n | +| tst1.js:1:1:1:3 | abc | abc | \n | | tst1.js:2:1:2:3 | def | def | \r | | tst1.js:3:1:3:3 | ghi | ghi | \r\n | | tst1.js:4:1:4:3 | jkl | jkl | \n | @@ -6,13 +6,13 @@ | tst1.js:6:1:6:3 | mno | mno | \u2028 | | tst1.js:7:1:7:0 | | | \n | | tst1.js:8:1:8:3 | pqr | pqr | \u2029 | -| tst1.js:9:1:9:3 | stu | stu | | -| tst2.js:1:1:1:63 | first_line // semmle-extractor-options: --extract-program-text | first_line // semmle-extractor-options: --extract-program-text | \n | -| tst3.js:1:1:1:56 | 42; // semmle-extractor-options: --extract-program-text | 42; // semmle-extractor-options: --extract-program-text | \n | +| tst1.js:9:1:9:3 | stu | stu | \n | +| tst2.js:1:1:1:10 | first_line | first_line | \n | +| tst3.js:1:1:1:3 | 42; | 42; | \n | | tst3.js:2:1:2:4 | \t42; | \t42; | \n | | tst3.js:3:1:3:5 | \t\t42; | \t\t42; | \n | | tst3.js:4:1:4:6 | \t\t\t42; | \t\t\t42; | \n | | tst3.js:5:1:5:6 | \t\t 42; | \t\t 42; | \n | | tst3.js:6:1:6:6 | \t \t42; | \t \t42; | \n | | tst3.js:7:1:7:7 | 42; | 42; | \n | -| tst3.js:8:1:8:5 | 42; | 42; | | +| tst3.js:8:1:8:5 | 42; | 42; | \n | diff --git a/javascript/ql/test/library-tests/Lines/options b/javascript/ql/test/library-tests/Lines/options new file mode 100644 index 00000000000..d51f2d49be2 --- /dev/null +++ b/javascript/ql/test/library-tests/Lines/options @@ -0,0 +1 @@ +semmle-extractor-options: --extract-program-text diff --git a/javascript/ql/test/library-tests/Lines/tst1.js b/javascript/ql/test/library-tests/Lines/tst1.js index f10f44a7440..d5fa50c5f3a 100644 --- a/javascript/ql/test/library-tests/Lines/tst1.js +++ b/javascript/ql/test/library-tests/Lines/tst1.js @@ -1,5 +1,5 @@ -abc // semmle-extractor-options: --extract-program-text +abc def ghi jkl mnoโ€จ -pqrโ€ฉstu \ No newline at end of file +pqrโ€ฉstu diff --git a/javascript/ql/test/library-tests/Lines/tst2.js b/javascript/ql/test/library-tests/Lines/tst2.js index d3c77609145..c380edd400c 100644 --- a/javascript/ql/test/library-tests/Lines/tst2.js +++ b/javascript/ql/test/library-tests/Lines/tst2.js @@ -1 +1 @@ -first_line // semmle-extractor-options: --extract-program-text +first_line diff --git a/javascript/ql/test/library-tests/Lines/tst3.js b/javascript/ql/test/library-tests/Lines/tst3.js index ad0059d91ea..8c8468ffab2 100644 --- a/javascript/ql/test/library-tests/Lines/tst3.js +++ b/javascript/ql/test/library-tests/Lines/tst3.js @@ -1,8 +1,8 @@ -42; // semmle-extractor-options: --extract-program-text +42; 42; 42; 42; 42; 42; 42; - 42; \ No newline at end of file + 42; diff --git a/javascript/ql/test/library-tests/LocalObjects/options b/javascript/ql/test/library-tests/LocalObjects/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/library-tests/LocalObjects/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/LocalObjects/tst.js b/javascript/ql/test/library-tests/LocalObjects/tst.js index dee138c0f27..a02a29776c0 100644 --- a/javascript/ql/test/library-tests/LocalObjects/tst.js +++ b/javascript/ql/test/library-tests/LocalObjects/tst.js @@ -89,5 +89,3 @@ let bound = {}; bound::unknown(); }); - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/Modules/b.js b/javascript/ql/test/library-tests/Modules/b.js index 4b58c09c31b..835bd1abbf6 100644 --- a/javascript/ql/test/library-tests/Modules/b.js +++ b/javascript/ql/test/library-tests/Modules/b.js @@ -5,5 +5,3 @@ f(); export { f as g }; export f2 from './a'; - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/Modules/m/c.js b/javascript/ql/test/library-tests/Modules/m/c.js index 6c3645f382d..8192ccc9b45 100644 --- a/javascript/ql/test/library-tests/Modules/m/c.js +++ b/javascript/ql/test/library-tests/Modules/m/c.js @@ -3,5 +3,3 @@ import * as b from '../b'; b.g(); export { g as h } from '../b'; - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/Modules/m/options b/javascript/ql/test/library-tests/Modules/m/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/library-tests/Modules/m/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/Modules/options b/javascript/ql/test/library-tests/Modules/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/library-tests/Modules/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/Modules/tests.expected b/javascript/ql/test/library-tests/Modules/tests.expected index 8cdd45f9066..39d24b09700 100644 --- a/javascript/ql/test/library-tests/Modules/tests.expected +++ b/javascript/ql/test/library-tests/Modules/tests.expected @@ -104,15 +104,15 @@ test_Module_exports | a.js:1:1:5:32 | | default | a.js:1:1:3:1 | export ... n 23;\\n} | | a.js:1:1:5:32 | | x | a.js:5:1:5:32 | export ... } = o; | | a.js:1:1:5:32 | | y | a.js:5:1:5:32 | export ... } = o; | -| b.js:1:1:10:0 | | f2 | b.js:7:1:7:21 | export ... './a'; | -| b.js:1:1:10:0 | | g | b.js:5:1:5:18 | export { f as g }; | +| b.js:1:1:8:0 | | f2 | b.js:7:1:7:21 | export ... './a'; | +| b.js:1:1:8:0 | | g | b.js:5:1:5:18 | export { f as g }; | | e.js:1:1:4:0 | | g | e.js:3:1:3:35 | export ... './a'; | | e.js:1:1:4:0 | | x | e.js:2:1:2:16 | export { x, y }; | | e.js:1:1:4:0 | | y | e.js:2:1:2:16 | export { x, y }; | | es2015_require.js:1:1:3:25 | | default | es2015_require.js:3:1:3:25 | export ... ss C {} | | export-in-mjs.mjs:1:1:1:34 | | exported_from_mjs | export-in-mjs.mjs:1:1:1:34 | export ... s = 42; | | f.ts:1:1:6:0 | | foo | f.ts:5:1:5:24 | export ... oo() {} | -| m/c.js:1:1:8:0 | | h | m/c.js:5:1:5:30 | export ... '../b'; | +| m/c.js:1:1:6:0 | | h | m/c.js:5:1:5:30 | export ... '../b'; | | tst.html:4:23:8:0 | | y | tst.html:7:3:7:22 | export const y = 42; | test_ExportDefaultDeclarations | a.js:1:1:3:1 | export ... n 23;\\n} | diff --git a/javascript/ql/test/library-tests/NPM/ImportedModule.expected b/javascript/ql/test/library-tests/NPM/ImportedModule.expected index 2a89dfeb394..ce2a65d591f 100644 --- a/javascript/ql/test/library-tests/NPM/ImportedModule.expected +++ b/javascript/ql/test/library-tests/NPM/ImportedModule.expected @@ -1,6 +1,6 @@ -| src/lib/tst2.js:1:1:1:13 | require("..") | src/index.js:1:1:5:0 | | -| src/node_modules/nested/tst3.js:1:1:1:29 | require ... odule') | src/node_modules/third-party-module/fancy.js:1:1:5:0 | | +| src/lib/tst2.js:1:1:1:13 | require("..") | src/index.js:1:1:4:0 | | +| src/node_modules/nested/tst3.js:1:1:1:29 | require ... odule') | src/node_modules/third-party-module/fancy.js:1:1:4:0 | | | src/node_modules/nested/tst3.js:2:1:2:12 | require('a') | src/node_modules/nested/node_modules/a/index.js:1:1:1:25 | | -| src/node_modules/tst2.js:1:1:1:38 | require ... cy.js') | src/node_modules/third-party-module/fancy.js:1:1:5:0 | | -| src/tst2.js:1:1:1:12 | require(".") | src/index.js:1:1:5:0 | | -| src/tst.js:1:1:1:38 | require ... cy.js') | src/node_modules/third-party-module/fancy.js:1:1:5:0 | | +| src/node_modules/tst2.js:1:1:1:38 | require ... cy.js') | src/node_modules/third-party-module/fancy.js:1:1:4:0 | | +| src/tst2.js:1:1:1:12 | require(".") | src/index.js:1:1:4:0 | | +| src/tst.js:1:1:1:38 | require ... cy.js') | src/node_modules/third-party-module/fancy.js:1:1:4:0 | | diff --git a/javascript/ql/test/library-tests/NPM/Modules.expected b/javascript/ql/test/library-tests/NPM/Modules.expected index 4d0dde9c33e..e7fa54d6f9a 100644 --- a/javascript/ql/test/library-tests/NPM/Modules.expected +++ b/javascript/ql/test/library-tests/NPM/Modules.expected @@ -1,9 +1,9 @@ | b | src/node_modules/b/lib/index.js:1:1:2:0 | | | b | src/node_modules/b/lib/index.ts:1:1:2:0 | | | c | src/node_modules/c/src/index.js:1:1:2:0 | | -| test-package | src/index.js:1:1:5:0 | | +| test-package | src/index.js:1:1:4:0 | | | test-package | src/lib/tst2.js:1:1:1:14 | | -| test-package | src/lib/tst.js:1:1:5:0 | | +| test-package | src/lib/tst.js:1:1:4:0 | | | test-package | src/tst2.js:1:1:1:13 | | | test-package | src/tst.js:1:1:2:38 | | -| third-party-module | src/node_modules/third-party-module/fancy.js:1:1:5:0 | | +| third-party-module | src/node_modules/third-party-module/fancy.js:1:1:4:0 | | diff --git a/javascript/ql/test/library-tests/NPM/NPMPackage_getMainModule.expected b/javascript/ql/test/library-tests/NPM/NPMPackage_getMainModule.expected index 67fd1880bf0..a8b7753abae 100644 --- a/javascript/ql/test/library-tests/NPM/NPMPackage_getMainModule.expected +++ b/javascript/ql/test/library-tests/NPM/NPMPackage_getMainModule.expected @@ -1,4 +1,4 @@ | b | src/node_modules/b/lib/index.ts:1:1:2:0 | | | c | src/node_modules/c/src/index.js:1:1:2:0 | | -| test-package | src/index.js:1:1:5:0 | | -| third-party-module | src/node_modules/third-party-module/fancy.js:1:1:5:0 | | +| test-package | src/index.js:1:1:4:0 | | +| third-party-module | src/node_modules/third-party-module/fancy.js:1:1:4:0 | | diff --git a/javascript/ql/test/library-tests/NPM/src/index.js b/javascript/ql/test/library-tests/NPM/src/index.js index b875bfd3a10..e99778b633f 100644 --- a/javascript/ql/test/library-tests/NPM/src/index.js +++ b/javascript/ql/test/library-tests/NPM/src/index.js @@ -1,4 +1,3 @@ alert("Hello"); -// semmle-extractor-options: --platform -// semmle-extractor-options: node +require("process"); diff --git a/javascript/ql/test/library-tests/NPM/src/lib/tst.js b/javascript/ql/test/library-tests/NPM/src/lib/tst.js index 840fb76057b..d8fc422959c 100644 --- a/javascript/ql/test/library-tests/NPM/src/lib/tst.js +++ b/javascript/ql/test/library-tests/NPM/src/lib/tst.js @@ -1,4 +1,3 @@ alert("world"); -// semmle-extractor-options: --platform -// semmle-extractor-options: node +require("process"); diff --git a/javascript/ql/test/library-tests/NPM/src/node_modules/third-party-module/fancy.js b/javascript/ql/test/library-tests/NPM/src/node_modules/third-party-module/fancy.js index f53610fe05c..7dfe5aea1d2 100644 --- a/javascript/ql/test/library-tests/NPM/src/node_modules/third-party-module/fancy.js +++ b/javascript/ql/test/library-tests/NPM/src/node_modules/third-party-module/fancy.js @@ -1,4 +1,3 @@ ('alert' in this ? alert : console.log)("Hello"); -// semmle-extractor-options: --platform -// semmle-extractor-options: node +require("process"); diff --git a/javascript/ql/test/library-tests/NodeJS/Module_getAnImport.expected b/javascript/ql/test/library-tests/NodeJS/Module_getAnImport.expected index 9f2e4dba88e..d1cc2576141 100644 --- a/javascript/ql/test/library-tests/NodeJS/Module_getAnImport.expected +++ b/javascript/ql/test/library-tests/NodeJS/Module_getAnImport.expected @@ -9,6 +9,7 @@ | b.js:1:1:8:0 | | b.js:1:1:1:18 | require('./sub/c') | | d.js:1:1:7:15 | | d.js:1:1:1:38 | require ... s/ini') | | d.js:1:1:7:15 | | d.js:7:1:7:14 | require('foo') | +| e.js:1:1:6:0 | | e.js:5:1:5:18 | require("process") | | index.js:1:1:3:0 | | index.js:1:12:1:26 | require('path') | | index.js:1:1:3:0 | | index.js:2:1:2:41 | require ... b.js")) | | mjs-files/require-from-js.js:1:1:4:0 | | mjs-files/require-from-js.js:1:12:1:36 | require ... on-me') | diff --git a/javascript/ql/test/library-tests/NodeJS/Module_getAnImportedModule.expected b/javascript/ql/test/library-tests/NodeJS/Module_getAnImportedModule.expected index c038d8f9031..0fa0e65f359 100644 --- a/javascript/ql/test/library-tests/NodeJS/Module_getAnImportedModule.expected +++ b/javascript/ql/test/library-tests/NodeJS/Module_getAnImportedModule.expected @@ -1,6 +1,6 @@ | a.js:1:1:14:0 | | b.js:1:1:8:0 | | | a.js:1:1:14:0 | | d.js:1:1:7:15 | | -| a.js:1:1:14:0 | | e.js:1:1:7:0 | | +| a.js:1:1:14:0 | | e.js:1:1:6:0 | | | a.js:1:1:14:0 | | index.js:1:1:3:0 | | | a.js:1:1:14:0 | | sub/c.js:1:1:4:0 | | | b.js:1:1:8:0 | | sub/c.js:1:1:4:0 | | diff --git a/javascript/ql/test/library-tests/NodeJS/Modules.expected b/javascript/ql/test/library-tests/NodeJS/Modules.expected index 05306ec82c5..1ef82d0328e 100644 --- a/javascript/ql/test/library-tests/NodeJS/Modules.expected +++ b/javascript/ql/test/library-tests/NodeJS/Modules.expected @@ -1,7 +1,7 @@ | a.js:1:1:14:0 | | a.js:0:0:0:0 | a.js | a.js | a | | b.js:1:1:8:0 | | b.js:0:0:0:0 | b.js | b.js | b | | d.js:1:1:7:15 | | d.js:0:0:0:0 | d.js | d.js | d | -| e.js:1:1:7:0 | | e.js:0:0:0:0 | e.js | e.js | e | +| e.js:1:1:6:0 | | e.js:0:0:0:0 | e.js | e.js | e | | index.js:1:1:3:0 | | index.js:0:0:0:0 | index.js | index.js | index | | mjs-files/require-from-js.js:1:1:4:0 | | mjs-files/require-from-js.js:0:0:0:0 | mjs-files/require-from-js.js | mjs-files/require-from-js.js | require-from-js | | sub/c.js:1:1:4:0 | | sub/c.js:0:0:0:0 | sub/c.js | sub/c.js | c | diff --git a/javascript/ql/test/library-tests/NodeJS/Require.expected b/javascript/ql/test/library-tests/NodeJS/Require.expected index 491c80a9a87..7e9a50685ab 100644 --- a/javascript/ql/test/library-tests/NodeJS/Require.expected +++ b/javascript/ql/test/library-tests/NodeJS/Require.expected @@ -9,6 +9,7 @@ | b.js:1:1:1:18 | require('./sub/c') | | d.js:1:1:1:38 | require ... s/ini') | | d.js:7:1:7:14 | require('foo') | +| e.js:5:1:5:18 | require("process") | | f.js:2:1:2:7 | r("fs") | | index.js:1:12:1:26 | require('path') | | index.js:2:1:2:41 | require ... b.js")) | diff --git a/javascript/ql/test/library-tests/NodeJS/RequireImport.expected b/javascript/ql/test/library-tests/NodeJS/RequireImport.expected index a7ec65d67a2..e01527d2784 100644 --- a/javascript/ql/test/library-tests/NodeJS/RequireImport.expected +++ b/javascript/ql/test/library-tests/NodeJS/RequireImport.expected @@ -3,7 +3,7 @@ | a.js:4:6:4:29 | require ... /d.js') | ./sub/../d.js | d.js:1:1:7:15 | | | a.js:7:1:7:18 | require('./sub/c') | ./sub/c | sub/c.js:1:1:4:0 | | | a.js:10:1:10:18 | require(__dirname) | | index.js:1:1:3:0 | | -| a.js:11:1:11:25 | require ... + '/e') | /e | e.js:1:1:7:0 | | +| a.js:11:1:11:25 | require ... + '/e') | /e | e.js:1:1:6:0 | | | a.js:12:1:12:28 | require ... + 'c') | ./sub/c | sub/c.js:1:1:4:0 | | | b.js:1:1:1:18 | require('./sub/c') | ./sub/c | sub/c.js:1:1:4:0 | | | d.js:7:1:7:14 | require('foo') | foo | sub/f.js:1:1:4:17 | | diff --git a/javascript/ql/test/library-tests/NodeJS/e.js b/javascript/ql/test/library-tests/NodeJS/e.js index 0a3f338f7d0..22254c56326 100644 --- a/javascript/ql/test/library-tests/NodeJS/e.js +++ b/javascript/ql/test/library-tests/NodeJS/e.js @@ -2,5 +2,4 @@ require('./a.js'); })(); -// semmle-extractor-options: --platform -// semmle-extractor-options: node +require("process"); diff --git a/javascript/ql/test/library-tests/OptionalChaining/OptionalChainRoot.expected b/javascript/ql/test/library-tests/OptionalChaining/OptionalChainRoot.expected index 5ec86ee7462..1ff8c71d6db 100644 --- a/javascript/ql/test/library-tests/OptionalChaining/OptionalChainRoot.expected +++ b/javascript/ql/test/library-tests/OptionalChaining/OptionalChainRoot.expected @@ -1,7 +1,25 @@ +| short-circuiting-typescript.ts:3:5:3:18 | x?.(o1 = null) | short-circuiting-typescript.ts:3:5:3:18 | x?.(o1 = null) | +| short-circuiting-typescript.ts:7:5:7:18 | x?.[o2 = null] | short-circuiting-typescript.ts:7:5:7:18 | x?.[o2 = null] | +| short-circuiting-typescript.ts:12:5:12:31 | x?.[o3 ... = null) | short-circuiting-typescript.ts:12:5:12:18 | x?.[o3 = null] | +| short-circuiting-typescript.ts:12:5:12:31 | x?.[o3 ... = null) | short-circuiting-typescript.ts:12:5:12:31 | x?.[o3 ... = null) | | short-circuiting.js:3:5:3:18 | x?.(o1 = null) | short-circuiting.js:3:5:3:18 | x?.(o1 = null) | | short-circuiting.js:7:5:7:18 | x?.[o2 = null] | short-circuiting.js:7:5:7:18 | x?.[o2 = null] | | short-circuiting.js:12:5:12:31 | x?.[o3 ... = null) | short-circuiting.js:12:5:12:18 | x?.[o3 = null] | | short-circuiting.js:12:5:12:31 | x?.[o3 ... = null) | short-circuiting.js:12:5:12:31 | x?.[o3 ... = null) | +| tst-typescript.ts:2:1:2:6 | a?.b.c | tst-typescript.ts:2:1:2:4 | a?.b | +| tst-typescript.ts:3:1:3:6 | a.b?.c | tst-typescript.ts:3:1:3:6 | a.b?.c | +| tst-typescript.ts:4:1:4:7 | a?.b?.c | tst-typescript.ts:4:1:4:4 | a?.b | +| tst-typescript.ts:4:1:4:7 | a?.b?.c | tst-typescript.ts:4:1:4:7 | a?.b?.c | +| tst-typescript.ts:7:1:7:7 | f?.()() | tst-typescript.ts:7:1:7:5 | f?.() | +| tst-typescript.ts:8:1:8:7 | f()?.() | tst-typescript.ts:8:1:8:7 | f()?.() | +| tst-typescript.ts:9:1:9:9 | f?.()?.() | tst-typescript.ts:9:1:9:5 | f?.() | +| tst-typescript.ts:9:1:9:9 | f?.()?.() | tst-typescript.ts:9:1:9:9 | f?.()?.() | +| tst-typescript.ts:12:1:12:8 | a?.m().b | tst-typescript.ts:12:1:12:4 | a?.m | +| tst-typescript.ts:13:1:13:9 | a.m?.().b | tst-typescript.ts:13:1:13:7 | a.m?.() | +| tst-typescript.ts:14:1:14:8 | a.m()?.b | tst-typescript.ts:14:1:14:8 | a.m()?.b | +| tst-typescript.ts:15:1:15:11 | a?.m?.()?.b | tst-typescript.ts:15:1:15:4 | a?.m | +| tst-typescript.ts:15:1:15:11 | a?.m?.()?.b | tst-typescript.ts:15:1:15:8 | a?.m?.() | +| tst-typescript.ts:15:1:15:11 | a?.m?.()?.b | tst-typescript.ts:15:1:15:11 | a?.m?.()?.b | | tst.js:2:1:2:6 | a?.b.c | tst.js:2:1:2:4 | a?.b | | tst.js:3:1:3:6 | a.b?.c | tst.js:3:1:3:6 | a.b?.c | | tst.js:4:1:4:7 | a?.b?.c | tst.js:4:1:4:4 | a?.b | diff --git a/javascript/ql/test/library-tests/OptionalChaining/OptionalUse.expected b/javascript/ql/test/library-tests/OptionalChaining/OptionalUse.expected index 430d4d52299..8358bb0ecde 100644 --- a/javascript/ql/test/library-tests/OptionalChaining/OptionalUse.expected +++ b/javascript/ql/test/library-tests/OptionalChaining/OptionalUse.expected @@ -1,7 +1,25 @@ +| short-circuiting-typescript.ts:3:5:3:18 | x?.(o1 = null) | +| short-circuiting-typescript.ts:7:5:7:18 | x?.[o2 = null] | +| short-circuiting-typescript.ts:12:5:12:18 | x?.[o3 = null] | +| short-circuiting-typescript.ts:12:5:12:31 | x?.[o3 ... = null) | | short-circuiting.js:3:5:3:18 | x?.(o1 = null) | | short-circuiting.js:7:5:7:18 | x?.[o2 = null] | | short-circuiting.js:12:5:12:18 | x?.[o3 = null] | | short-circuiting.js:12:5:12:31 | x?.[o3 ... = null) | +| tst-typescript.ts:2:1:2:4 | a?.b | +| tst-typescript.ts:3:1:3:6 | a.b?.c | +| tst-typescript.ts:4:1:4:4 | a?.b | +| tst-typescript.ts:4:1:4:7 | a?.b?.c | +| tst-typescript.ts:7:1:7:5 | f?.() | +| tst-typescript.ts:8:1:8:7 | f()?.() | +| tst-typescript.ts:9:1:9:5 | f?.() | +| tst-typescript.ts:9:1:9:9 | f?.()?.() | +| tst-typescript.ts:12:1:12:4 | a?.m | +| tst-typescript.ts:13:1:13:7 | a.m?.() | +| tst-typescript.ts:14:1:14:8 | a.m()?.b | +| tst-typescript.ts:15:1:15:4 | a?.m | +| tst-typescript.ts:15:1:15:8 | a?.m?.() | +| tst-typescript.ts:15:1:15:11 | a?.m?.()?.b | | tst.js:2:1:2:4 | a?.b | | tst.js:3:1:3:6 | a.b?.c | | tst.js:4:1:4:4 | a?.b | diff --git a/javascript/ql/test/library-tests/OptionalChaining/ShortCircuiting.expected b/javascript/ql/test/library-tests/OptionalChaining/ShortCircuiting.expected index d61dccc8c5a..6711c704828 100644 --- a/javascript/ql/test/library-tests/OptionalChaining/ShortCircuiting.expected +++ b/javascript/ql/test/library-tests/OptionalChaining/ShortCircuiting.expected @@ -1,3 +1,11 @@ +| short-circuiting-typescript.ts:4:10:4:11 | o1 | file://:0:0:0:0 | null | +| short-circuiting-typescript.ts:4:10:4:11 | o1 | short-circuiting-typescript.ts:2:14:2:15 | object literal | +| short-circuiting-typescript.ts:8:10:8:11 | o2 | file://:0:0:0:0 | null | +| short-circuiting-typescript.ts:8:10:8:11 | o2 | short-circuiting-typescript.ts:6:14:6:15 | object literal | +| short-circuiting-typescript.ts:13:10:13:11 | o3 | file://:0:0:0:0 | null | +| short-circuiting-typescript.ts:13:10:13:11 | o3 | short-circuiting-typescript.ts:10:14:10:15 | object literal | +| short-circuiting-typescript.ts:14:10:14:11 | o4 | file://:0:0:0:0 | null | +| short-circuiting-typescript.ts:14:10:14:11 | o4 | short-circuiting-typescript.ts:11:14:11:15 | object literal | | short-circuiting.js:4:10:4:11 | o1 | file://:0:0:0:0 | null | | short-circuiting.js:4:10:4:11 | o1 | short-circuiting.js:2:14:2:15 | object literal | | short-circuiting.js:8:10:8:11 | o2 | file://:0:0:0:0 | null | diff --git a/javascript/ql/test/library-tests/OptionalChaining/ShortCirtuiting.expected b/javascript/ql/test/library-tests/OptionalChaining/ShortCirtuiting.expected deleted file mode 100644 index d61dccc8c5a..00000000000 --- a/javascript/ql/test/library-tests/OptionalChaining/ShortCirtuiting.expected +++ /dev/null @@ -1,8 +0,0 @@ -| short-circuiting.js:4:10:4:11 | o1 | file://:0:0:0:0 | null | -| short-circuiting.js:4:10:4:11 | o1 | short-circuiting.js:2:14:2:15 | object literal | -| short-circuiting.js:8:10:8:11 | o2 | file://:0:0:0:0 | null | -| short-circuiting.js:8:10:8:11 | o2 | short-circuiting.js:6:14:6:15 | object literal | -| short-circuiting.js:13:10:13:11 | o3 | file://:0:0:0:0 | null | -| short-circuiting.js:13:10:13:11 | o3 | short-circuiting.js:10:14:10:15 | object literal | -| short-circuiting.js:14:10:14:11 | o4 | file://:0:0:0:0 | null | -| short-circuiting.js:14:10:14:11 | o4 | short-circuiting.js:11:14:11:15 | object literal | diff --git a/javascript/ql/test/library-tests/OptionalChaining/ShortCirtuiting.ql b/javascript/ql/test/library-tests/OptionalChaining/ShortCirtuiting.ql deleted file mode 100644 index e14838bd3ed..00000000000 --- a/javascript/ql/test/library-tests/OptionalChaining/ShortCirtuiting.ql +++ /dev/null @@ -1,7 +0,0 @@ -import javascript - -from CallExpr c, Expr arg -where - c.getCalleeName() = "DUMP" and - arg = c.getArgument(0) -select arg, arg.analyze().getAValue() diff --git a/javascript/ql/test/library-tests/OptionalChaining/options b/javascript/ql/test/library-tests/OptionalChaining/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/library-tests/OptionalChaining/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/OptionalChaining/short-circuiting-typescript.ts b/javascript/ql/test/library-tests/OptionalChaining/short-circuiting-typescript.ts new file mode 100644 index 00000000000..7367e64dd4c --- /dev/null +++ b/javascript/ql/test/library-tests/OptionalChaining/short-circuiting-typescript.ts @@ -0,0 +1,15 @@ +(function() { + var o1 = {}; + x?.(o1 = null); + DUMP(o1); + + var o2 = {}; + x?.[o2 = null]; + DUMP(o2); + + var o3 = {}, + o4 = {}; + x?.[o3 = null]?.(o4 = null); + DUMP(o3); + DUMP(o4); +}); diff --git a/javascript/ql/test/library-tests/OptionalChaining/short-circuiting.js b/javascript/ql/test/library-tests/OptionalChaining/short-circuiting.js index 97576676994..7367e64dd4c 100644 --- a/javascript/ql/test/library-tests/OptionalChaining/short-circuiting.js +++ b/javascript/ql/test/library-tests/OptionalChaining/short-circuiting.js @@ -13,4 +13,3 @@ DUMP(o3); DUMP(o4); }); -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/OptionalChaining/tst-typescript.ts b/javascript/ql/test/library-tests/OptionalChaining/tst-typescript.ts new file mode 100644 index 00000000000..39389024d6d --- /dev/null +++ b/javascript/ql/test/library-tests/OptionalChaining/tst-typescript.ts @@ -0,0 +1,15 @@ +a.b.c; +a?.b.c; +a.b?.c; +a?.b?.c; + +f()(); +f?.()(); +f()?.(); +f?.()?.(); + +a.m().b; +a?.m().b; +a.m?.().b; +a.m()?.b; +a?.m?.()?.b; diff --git a/javascript/ql/test/library-tests/OptionalChaining/tst.js b/javascript/ql/test/library-tests/OptionalChaining/tst.js index b0ee7435722..39389024d6d 100644 --- a/javascript/ql/test/library-tests/OptionalChaining/tst.js +++ b/javascript/ql/test/library-tests/OptionalChaining/tst.js @@ -13,5 +13,3 @@ a?.m().b; a.m?.().b; a.m()?.b; a?.m?.()?.b; - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/PropWrite/tests.expected b/javascript/ql/test/library-tests/PropWrite/tests.expected index 33eff9b0628..beb4916f397 100644 --- a/javascript/ql/test/library-tests/PropWrite/tests.expected +++ b/javascript/ql/test/library-tests/PropWrite/tests.expected @@ -1,55 +1,55 @@ test_getAPropertyRead -| tst.js:1:1:1:0 | this | tst.js:23:15:23:29 | this.someMethod | -| tst.js:1:1:1:0 | this | tst.js:24:36:24:45 | this.state | -| tst.js:14:5:14:11 | console | tst.js:14:5:14:15 | console.log | -| tst.js:17:5:17:11 | console | tst.js:17:5:17:15 | console.log | -| tst.js:23:15:23:29 | this.someMethod | tst.js:23:15:23:34 | this.someMethod.bind | -| tst.js:24:36:24:45 | this.state | tst.js:24:36:24:50 | this.state.name | -| tst.js:34:6:34:7 | vv | tst.js:34:6:34:10 | vv.pp | -| tst.js:35:6:35:8 | vvv | tst.js:35:6:35:12 | vvv.ppp | -| tst.js:35:6:35:12 | vvv.ppp | tst.js:35:6:35:16 | vvv.ppp.qqq | -| tst.js:45:3:45:9 | console | tst.js:45:3:45:13 | console.log | -| tst.js:45:15:45:17 | obj | tst.js:45:15:45:20 | obj[p] | +| tst.js:1:1:1:0 | this | tst.js:22:15:22:29 | this.someMethod | +| tst.js:1:1:1:0 | this | tst.js:23:36:23:45 | this.state | +| tst.js:13:5:13:11 | console | tst.js:13:5:13:15 | console.log | +| tst.js:16:5:16:11 | console | tst.js:16:5:16:15 | console.log | +| tst.js:22:15:22:29 | this.someMethod | tst.js:22:15:22:34 | this.someMethod.bind | +| tst.js:23:36:23:45 | this.state | tst.js:23:36:23:50 | this.state.name | +| tst.js:33:6:33:7 | vv | tst.js:33:6:33:10 | vv.pp | +| tst.js:34:6:34:8 | vvv | tst.js:34:6:34:12 | vvv.ppp | +| tst.js:34:6:34:12 | vvv.ppp | tst.js:34:6:34:16 | vvv.ppp.qqq | +| tst.js:44:3:44:9 | console | tst.js:44:3:44:13 | console.log | +| tst.js:44:15:44:17 | obj | tst.js:44:15:44:20 | obj[p] | test_getAPropertyReference | classes.ts:3:21:3:20 | this | classes.ts:4:3:4:24 | instanc ... foo(); | | classes.ts:8:3:8:2 | this | classes.ts:8:15:8:35 | public ... erField | | classes.ts:12:5:12:4 | this | classes.ts:12:17:12:37 | public ... erField | | classes.ts:16:5:16:4 | this | classes.ts:16:17:16:37 | public ... erField | -| tst.js:1:1:1:0 | this | tst.js:23:15:23:29 | this.someMethod | -| tst.js:1:1:1:0 | this | tst.js:24:36:24:45 | this.state | -| tst.js:2:11:10:1 | {\\n x ... }\\n} | tst.js:3:5:3:8 | x: 4 | -| tst.js:2:11:10:1 | {\\n x ... }\\n} | tst.js:4:5:6:5 | func: f ... ;\\n } | -| tst.js:2:11:10:1 | {\\n x ... }\\n} | tst.js:7:5:9:5 | f() {\\n ... ;\\n } | -| tst.js:12:1:19:1 | class C ... ;\\n }\\n} | tst.js:13:3:15:3 | static ... x);\\n } | -| tst.js:14:5:14:11 | console | tst.js:14:5:14:15 | console.log | -| tst.js:17:5:17:11 | console | tst.js:17:5:17:15 | console.log | -| tst.js:21:1:21:1 | C | tst.js:21:1:21:6 | C.prop | -| tst.js:23:15:23:29 | this.someMethod | tst.js:23:15:23:34 | this.someMethod.bind | -| tst.js:24:8:24:57 |
    | tst.js:24:13:24:27 | onClick={click} | -| tst.js:24:36:24:45 | this.state | tst.js:24:36:24:50 | this.state.name | -| tst.js:26:2:29:1 | {\\n get ... v) {}\\n} | tst.js:27:3:27:26 | get x() ... null; } | -| tst.js:26:2:29:1 | {\\n get ... v) {}\\n} | tst.js:28:3:28:13 | set y(v) {} | -| tst.js:31:2:36:1 | {\\n n ... q]: 4\\n} | tst.js:32:5:32:8 | n: 1 | -| tst.js:31:2:36:1 | {\\n n ... q]: 4\\n} | tst.js:33:5:33:10 | [v]: 2 | -| tst.js:31:2:36:1 | {\\n n ... q]: 4\\n} | tst.js:34:5:34:14 | [vv.pp]: 3 | -| tst.js:31:2:36:1 | {\\n n ... q]: 4\\n} | tst.js:35:5:35:20 | [vvv.ppp.qqq]: 4 | -| tst.js:34:6:34:7 | vv | tst.js:34:6:34:10 | vv.pp | -| tst.js:35:6:35:8 | vvv | tst.js:35:6:35:12 | vvv.ppp | -| tst.js:35:6:35:12 | vvv.ppp | tst.js:35:6:35:16 | vvv.ppp.qqq | -| tst.js:38:12:38:26 | ["a", "b", "c"] | tst.js:38:13:38:15 | "a" | -| tst.js:38:12:38:26 | ["a", "b", "c"] | tst.js:38:18:38:20 | "b" | -| tst.js:38:12:38:26 | ["a", "b", "c"] | tst.js:38:23:38:25 | "c" | -| tst.js:39:12:39:23 | ["a", , "c"] | tst.js:39:13:39:15 | "a" | -| tst.js:39:12:39:23 | ["a", , "c"] | tst.js:39:20:39:22 | "c" | -| tst.js:40:12:40:23 | [, "b", "c"] | tst.js:40:15:40:17 | "b" | -| tst.js:40:12:40:23 | [, "b", "c"] | tst.js:40:20:40:22 | "c" | -| tst.js:41:12:41:22 | ["a", "b",] | tst.js:41:13:41:15 | "a" | -| tst.js:41:12:41:22 | ["a", "b",] | tst.js:41:18:41:20 | "b" | -| tst.js:42:12:42:30 | ["a", ...arr3, "d"] | tst.js:42:13:42:15 | "a" | -| tst.js:42:12:42:30 | ["a", ...arr3, "d"] | tst.js:42:18:42:24 | ...arr3 | -| tst.js:42:12:42:30 | ["a", ...arr3, "d"] | tst.js:42:27:42:29 | "d" | -| tst.js:45:3:45:9 | console | tst.js:45:3:45:13 | console.log | -| tst.js:45:15:45:17 | obj | tst.js:45:15:45:20 | obj[p] | +| tst.js:1:1:1:0 | this | tst.js:22:15:22:29 | this.someMethod | +| tst.js:1:1:1:0 | this | tst.js:23:36:23:45 | this.state | +| tst.js:1:11:9:1 | {\\n x ... }\\n} | tst.js:2:5:2:8 | x: 4 | +| tst.js:1:11:9:1 | {\\n x ... }\\n} | tst.js:3:5:5:5 | func: f ... ;\\n } | +| tst.js:1:11:9:1 | {\\n x ... }\\n} | tst.js:6:5:8:5 | f() {\\n ... ;\\n } | +| tst.js:11:1:18:1 | class C ... ;\\n }\\n} | tst.js:12:3:14:3 | static ... x);\\n } | +| tst.js:13:5:13:11 | console | tst.js:13:5:13:15 | console.log | +| tst.js:16:5:16:11 | console | tst.js:16:5:16:15 | console.log | +| tst.js:20:1:20:1 | C | tst.js:20:1:20:6 | C.prop | +| tst.js:22:15:22:29 | this.someMethod | tst.js:22:15:22:34 | this.someMethod.bind | +| tst.js:23:8:23:57 |
    | tst.js:23:13:23:27 | onClick={click} | +| tst.js:23:36:23:45 | this.state | tst.js:23:36:23:50 | this.state.name | +| tst.js:25:2:28:1 | {\\n get ... v) {}\\n} | tst.js:26:3:26:26 | get x() ... null; } | +| tst.js:25:2:28:1 | {\\n get ... v) {}\\n} | tst.js:27:3:27:13 | set y(v) {} | +| tst.js:30:2:35:1 | {\\n n ... q]: 4\\n} | tst.js:31:5:31:8 | n: 1 | +| tst.js:30:2:35:1 | {\\n n ... q]: 4\\n} | tst.js:32:5:32:10 | [v]: 2 | +| tst.js:30:2:35:1 | {\\n n ... q]: 4\\n} | tst.js:33:5:33:14 | [vv.pp]: 3 | +| tst.js:30:2:35:1 | {\\n n ... q]: 4\\n} | tst.js:34:5:34:20 | [vvv.ppp.qqq]: 4 | +| tst.js:33:6:33:7 | vv | tst.js:33:6:33:10 | vv.pp | +| tst.js:34:6:34:8 | vvv | tst.js:34:6:34:12 | vvv.ppp | +| tst.js:34:6:34:12 | vvv.ppp | tst.js:34:6:34:16 | vvv.ppp.qqq | +| tst.js:37:12:37:26 | ["a", "b", "c"] | tst.js:37:13:37:15 | "a" | +| tst.js:37:12:37:26 | ["a", "b", "c"] | tst.js:37:18:37:20 | "b" | +| tst.js:37:12:37:26 | ["a", "b", "c"] | tst.js:37:23:37:25 | "c" | +| tst.js:38:12:38:23 | ["a", , "c"] | tst.js:38:13:38:15 | "a" | +| tst.js:38:12:38:23 | ["a", , "c"] | tst.js:38:20:38:22 | "c" | +| tst.js:39:12:39:23 | [, "b", "c"] | tst.js:39:15:39:17 | "b" | +| tst.js:39:12:39:23 | [, "b", "c"] | tst.js:39:20:39:22 | "c" | +| tst.js:40:12:40:22 | ["a", "b",] | tst.js:40:13:40:15 | "a" | +| tst.js:40:12:40:22 | ["a", "b",] | tst.js:40:18:40:20 | "b" | +| tst.js:41:12:41:30 | ["a", ...arr3, "d"] | tst.js:41:13:41:15 | "a" | +| tst.js:41:12:41:30 | ["a", ...arr3, "d"] | tst.js:41:18:41:24 | ...arr3 | +| tst.js:41:12:41:30 | ["a", ...arr3, "d"] | tst.js:41:27:41:29 | "d" | +| tst.js:44:3:44:9 | console | tst.js:44:3:44:13 | console.log | +| tst.js:44:15:44:17 | obj | tst.js:44:15:44:20 | obj[p] | test_getAPropertySource | classes.ts:3:21:3:20 | this | instanceField | classes.ts:4:19:4:23 | foo() | | classes.ts:8:3:8:2 | this | parameterField | classes.ts:8:22:8:35 | parameterField | @@ -57,10 +57,10 @@ test_getAPropertySource | classes.ts:12:5:12:4 | this | parameterField | classes.ts:12:41:12:42 | {} | | classes.ts:16:5:16:4 | this | parameterField | classes.ts:16:24:16:37 | parameterField | | classes.ts:16:5:16:4 | this | parameterField | classes.ts:16:41:16:42 | {} | -| tst.js:2:11:10:1 | {\\n x ... }\\n} | f | tst.js:7:6:9:5 | () {\\n ... ;\\n } | -| tst.js:2:11:10:1 | {\\n x ... }\\n} | func | tst.js:4:11:6:5 | functio ... ;\\n } | -| tst.js:12:1:19:1 | class C ... ;\\n }\\n} | func | tst.js:13:14:15:3 | (x) {\\n ... x);\\n } | -| tst.js:24:8:24:57 |
    | onClick | tst.js:24:22:24:26 | click | +| tst.js:1:11:9:1 | {\\n x ... }\\n} | f | tst.js:6:6:8:5 | () {\\n ... ;\\n } | +| tst.js:1:11:9:1 | {\\n x ... }\\n} | func | tst.js:3:11:5:5 | functio ... ;\\n } | +| tst.js:11:1:18:1 | class C ... ;\\n }\\n} | func | tst.js:12:14:14:3 | (x) {\\n ... x);\\n } | +| tst.js:23:8:23:57 |
    | onClick | tst.js:23:22:23:26 | click | test_PropWritePropName | classes.ts:3:21:3:20 | constructor() {} | constructor | | classes.ts:4:3:4:24 | instanc ... foo(); | instanceField | @@ -70,123 +70,123 @@ test_PropWritePropName | classes.ts:12:17:12:37 | public ... erField | parameterField | | classes.ts:16:5:16:46 | constru ... {}) {} | constructor | | classes.ts:16:17:16:37 | public ... erField | parameterField | -| tst.js:3:5:3:8 | x: 4 | x | -| tst.js:4:5:6:5 | func: f ... ;\\n } | func | -| tst.js:7:5:9:5 | f() {\\n ... ;\\n } | f | -| tst.js:12:9:12:8 | constructor() {} | constructor | -| tst.js:13:3:15:3 | static ... x);\\n } | func | -| tst.js:16:3:18:3 | f(x) {\\n ... x);\\n } | f | -| tst.js:21:1:21:6 | C.prop | prop | -| tst.js:24:13:24:27 | onClick={click} | onClick | -| tst.js:27:3:27:26 | get x() ... null; } | x | -| tst.js:28:3:28:13 | set y(v) {} | y | -| tst.js:32:5:32:8 | n: 1 | n | +| tst.js:2:5:2:8 | x: 4 | x | +| tst.js:3:5:5:5 | func: f ... ;\\n } | func | +| tst.js:6:5:8:5 | f() {\\n ... ;\\n } | f | +| tst.js:11:9:11:8 | constructor() {} | constructor | +| tst.js:12:3:14:3 | static ... x);\\n } | func | +| tst.js:15:3:17:3 | f(x) {\\n ... x);\\n } | f | +| tst.js:20:1:20:6 | C.prop | prop | +| tst.js:23:13:23:27 | onClick={click} | onClick | +| tst.js:26:3:26:26 | get x() ... null; } | x | +| tst.js:27:3:27:13 | set y(v) {} | y | +| tst.js:31:5:31:8 | n: 1 | n | test_getAPropertyRead2 -| tst.js:1:1:1:0 | this | someMethod | tst.js:23:15:23:29 | this.someMethod | -| tst.js:1:1:1:0 | this | state | tst.js:24:36:24:45 | this.state | -| tst.js:14:5:14:11 | console | log | tst.js:14:5:14:15 | console.log | -| tst.js:17:5:17:11 | console | log | tst.js:17:5:17:15 | console.log | -| tst.js:23:15:23:29 | this.someMethod | bind | tst.js:23:15:23:34 | this.someMethod.bind | -| tst.js:24:36:24:45 | this.state | name | tst.js:24:36:24:50 | this.state.name | -| tst.js:34:6:34:7 | vv | pp | tst.js:34:6:34:10 | vv.pp | -| tst.js:35:6:35:8 | vvv | ppp | tst.js:35:6:35:12 | vvv.ppp | -| tst.js:35:6:35:12 | vvv.ppp | qqq | tst.js:35:6:35:16 | vvv.ppp.qqq | -| tst.js:45:3:45:9 | console | log | tst.js:45:3:45:13 | console.log | +| tst.js:1:1:1:0 | this | someMethod | tst.js:22:15:22:29 | this.someMethod | +| tst.js:1:1:1:0 | this | state | tst.js:23:36:23:45 | this.state | +| tst.js:13:5:13:11 | console | log | tst.js:13:5:13:15 | console.log | +| tst.js:16:5:16:11 | console | log | tst.js:16:5:16:15 | console.log | +| tst.js:22:15:22:29 | this.someMethod | bind | tst.js:22:15:22:34 | this.someMethod.bind | +| tst.js:23:36:23:45 | this.state | name | tst.js:23:36:23:50 | this.state.name | +| tst.js:33:6:33:7 | vv | pp | tst.js:33:6:33:10 | vv.pp | +| tst.js:34:6:34:8 | vvv | ppp | tst.js:34:6:34:12 | vvv.ppp | +| tst.js:34:6:34:12 | vvv.ppp | qqq | tst.js:34:6:34:16 | vvv.ppp.qqq | +| tst.js:44:3:44:9 | console | log | tst.js:44:3:44:13 | console.log | test_getAPropertyReference2 | classes.ts:3:21:3:20 | this | instanceField | classes.ts:4:3:4:24 | instanc ... foo(); | | classes.ts:8:3:8:2 | this | parameterField | classes.ts:8:15:8:35 | public ... erField | | classes.ts:12:5:12:4 | this | parameterField | classes.ts:12:17:12:37 | public ... erField | | classes.ts:16:5:16:4 | this | parameterField | classes.ts:16:17:16:37 | public ... erField | -| tst.js:1:1:1:0 | this | someMethod | tst.js:23:15:23:29 | this.someMethod | -| tst.js:1:1:1:0 | this | state | tst.js:24:36:24:45 | this.state | -| tst.js:2:11:10:1 | {\\n x ... }\\n} | f | tst.js:7:5:9:5 | f() {\\n ... ;\\n } | -| tst.js:2:11:10:1 | {\\n x ... }\\n} | func | tst.js:4:5:6:5 | func: f ... ;\\n } | -| tst.js:2:11:10:1 | {\\n x ... }\\n} | x | tst.js:3:5:3:8 | x: 4 | -| tst.js:12:1:19:1 | class C ... ;\\n }\\n} | func | tst.js:13:3:15:3 | static ... x);\\n } | -| tst.js:14:5:14:11 | console | log | tst.js:14:5:14:15 | console.log | -| tst.js:17:5:17:11 | console | log | tst.js:17:5:17:15 | console.log | -| tst.js:21:1:21:1 | C | prop | tst.js:21:1:21:6 | C.prop | -| tst.js:23:15:23:29 | this.someMethod | bind | tst.js:23:15:23:34 | this.someMethod.bind | -| tst.js:24:8:24:57 |
    | onClick | tst.js:24:13:24:27 | onClick={click} | -| tst.js:24:36:24:45 | this.state | name | tst.js:24:36:24:50 | this.state.name | -| tst.js:26:2:29:1 | {\\n get ... v) {}\\n} | x | tst.js:27:3:27:26 | get x() ... null; } | -| tst.js:26:2:29:1 | {\\n get ... v) {}\\n} | y | tst.js:28:3:28:13 | set y(v) {} | -| tst.js:31:2:36:1 | {\\n n ... q]: 4\\n} | n | tst.js:32:5:32:8 | n: 1 | -| tst.js:34:6:34:7 | vv | pp | tst.js:34:6:34:10 | vv.pp | -| tst.js:35:6:35:8 | vvv | ppp | tst.js:35:6:35:12 | vvv.ppp | -| tst.js:35:6:35:12 | vvv.ppp | qqq | tst.js:35:6:35:16 | vvv.ppp.qqq | -| tst.js:45:3:45:9 | console | log | tst.js:45:3:45:13 | console.log | +| tst.js:1:1:1:0 | this | someMethod | tst.js:22:15:22:29 | this.someMethod | +| tst.js:1:1:1:0 | this | state | tst.js:23:36:23:45 | this.state | +| tst.js:1:11:9:1 | {\\n x ... }\\n} | f | tst.js:6:5:8:5 | f() {\\n ... ;\\n } | +| tst.js:1:11:9:1 | {\\n x ... }\\n} | func | tst.js:3:5:5:5 | func: f ... ;\\n } | +| tst.js:1:11:9:1 | {\\n x ... }\\n} | x | tst.js:2:5:2:8 | x: 4 | +| tst.js:11:1:18:1 | class C ... ;\\n }\\n} | func | tst.js:12:3:14:3 | static ... x);\\n } | +| tst.js:13:5:13:11 | console | log | tst.js:13:5:13:15 | console.log | +| tst.js:16:5:16:11 | console | log | tst.js:16:5:16:15 | console.log | +| tst.js:20:1:20:1 | C | prop | tst.js:20:1:20:6 | C.prop | +| tst.js:22:15:22:29 | this.someMethod | bind | tst.js:22:15:22:34 | this.someMethod.bind | +| tst.js:23:8:23:57 |
    | onClick | tst.js:23:13:23:27 | onClick={click} | +| tst.js:23:36:23:45 | this.state | name | tst.js:23:36:23:50 | this.state.name | +| tst.js:25:2:28:1 | {\\n get ... v) {}\\n} | x | tst.js:26:3:26:26 | get x() ... null; } | +| tst.js:25:2:28:1 | {\\n get ... v) {}\\n} | y | tst.js:27:3:27:13 | set y(v) {} | +| tst.js:30:2:35:1 | {\\n n ... q]: 4\\n} | n | tst.js:31:5:31:8 | n: 1 | +| tst.js:33:6:33:7 | vv | pp | tst.js:33:6:33:10 | vv.pp | +| tst.js:34:6:34:8 | vvv | ppp | tst.js:34:6:34:12 | vvv.ppp | +| tst.js:34:6:34:12 | vvv.ppp | qqq | tst.js:34:6:34:16 | vvv.ppp.qqq | +| tst.js:44:3:44:9 | console | log | tst.js:44:3:44:13 | console.log | test_hasPropertyWrite | classes.ts:3:21:3:20 | this | instanceField | classes.ts:4:19:4:23 | foo() | | classes.ts:8:3:8:2 | this | parameterField | classes.ts:8:22:8:35 | parameterField | | classes.ts:12:5:12:4 | this | parameterField | classes.ts:12:24:12:37 | parameterField | | classes.ts:16:5:16:4 | this | parameterField | classes.ts:16:24:16:37 | parameterField | | classes.ts:16:5:16:4 | this | parameterField | classes.ts:16:41:16:42 | {} | -| tst.js:2:11:10:1 | {\\n x ... }\\n} | f | tst.js:7:6:9:5 | () {\\n ... ;\\n } | -| tst.js:2:11:10:1 | {\\n x ... }\\n} | func | tst.js:4:11:6:5 | functio ... ;\\n } | -| tst.js:2:11:10:1 | {\\n x ... }\\n} | x | tst.js:3:8:3:8 | 4 | -| tst.js:12:1:19:1 | class C ... ;\\n }\\n} | func | tst.js:13:14:15:3 | (x) {\\n ... x);\\n } | -| tst.js:21:1:21:1 | C | prop | tst.js:21:10:21:11 | 56 | -| tst.js:24:8:24:57 |
    | onClick | tst.js:24:22:24:26 | click | -| tst.js:31:2:36:1 | {\\n n ... q]: 4\\n} | n | tst.js:32:8:32:8 | 1 | +| tst.js:1:11:9:1 | {\\n x ... }\\n} | f | tst.js:6:6:8:5 | () {\\n ... ;\\n } | +| tst.js:1:11:9:1 | {\\n x ... }\\n} | func | tst.js:3:11:5:5 | functio ... ;\\n } | +| tst.js:1:11:9:1 | {\\n x ... }\\n} | x | tst.js:2:8:2:8 | 4 | +| tst.js:11:1:18:1 | class C ... ;\\n }\\n} | func | tst.js:12:14:14:3 | (x) {\\n ... x);\\n } | +| tst.js:20:1:20:1 | C | prop | tst.js:20:10:20:11 | 56 | +| tst.js:23:8:23:57 |
    | onClick | tst.js:23:22:23:26 | click | +| tst.js:30:2:35:1 | {\\n n ... q]: 4\\n} | n | tst.js:31:8:31:8 | 1 | test_PropWriteBase | classes.ts:4:3:4:24 | instanc ... foo(); | classes.ts:3:21:3:20 | this | | classes.ts:8:15:8:35 | public ... erField | classes.ts:8:3:8:2 | this | | classes.ts:12:17:12:37 | public ... erField | classes.ts:12:5:12:4 | this | | classes.ts:16:17:16:37 | public ... erField | classes.ts:16:5:16:4 | this | -| tst.js:3:5:3:8 | x: 4 | tst.js:2:11:10:1 | {\\n x ... }\\n} | -| tst.js:4:5:6:5 | func: f ... ;\\n } | tst.js:2:11:10:1 | {\\n x ... }\\n} | -| tst.js:7:5:9:5 | f() {\\n ... ;\\n } | tst.js:2:11:10:1 | {\\n x ... }\\n} | -| tst.js:13:3:15:3 | static ... x);\\n } | tst.js:12:1:19:1 | class C ... ;\\n }\\n} | -| tst.js:21:1:21:6 | C.prop | tst.js:21:1:21:1 | C | -| tst.js:24:13:24:27 | onClick={click} | tst.js:24:8:24:57 |
    | -| tst.js:27:3:27:26 | get x() ... null; } | tst.js:26:2:29:1 | {\\n get ... v) {}\\n} | -| tst.js:28:3:28:13 | set y(v) {} | tst.js:26:2:29:1 | {\\n get ... v) {}\\n} | -| tst.js:32:5:32:8 | n: 1 | tst.js:31:2:36:1 | {\\n n ... q]: 4\\n} | -| tst.js:33:5:33:10 | [v]: 2 | tst.js:31:2:36:1 | {\\n n ... q]: 4\\n} | -| tst.js:34:5:34:14 | [vv.pp]: 3 | tst.js:31:2:36:1 | {\\n n ... q]: 4\\n} | -| tst.js:35:5:35:20 | [vvv.ppp.qqq]: 4 | tst.js:31:2:36:1 | {\\n n ... q]: 4\\n} | -| tst.js:38:13:38:15 | "a" | tst.js:38:12:38:26 | ["a", "b", "c"] | -| tst.js:38:18:38:20 | "b" | tst.js:38:12:38:26 | ["a", "b", "c"] | -| tst.js:38:23:38:25 | "c" | tst.js:38:12:38:26 | ["a", "b", "c"] | -| tst.js:39:13:39:15 | "a" | tst.js:39:12:39:23 | ["a", , "c"] | -| tst.js:39:20:39:22 | "c" | tst.js:39:12:39:23 | ["a", , "c"] | -| tst.js:40:15:40:17 | "b" | tst.js:40:12:40:23 | [, "b", "c"] | -| tst.js:40:20:40:22 | "c" | tst.js:40:12:40:23 | [, "b", "c"] | -| tst.js:41:13:41:15 | "a" | tst.js:41:12:41:22 | ["a", "b",] | -| tst.js:41:18:41:20 | "b" | tst.js:41:12:41:22 | ["a", "b",] | -| tst.js:42:13:42:15 | "a" | tst.js:42:12:42:30 | ["a", ...arr3, "d"] | -| tst.js:42:18:42:24 | ...arr3 | tst.js:42:12:42:30 | ["a", ...arr3, "d"] | -| tst.js:42:27:42:29 | "d" | tst.js:42:12:42:30 | ["a", ...arr3, "d"] | +| tst.js:2:5:2:8 | x: 4 | tst.js:1:11:9:1 | {\\n x ... }\\n} | +| tst.js:3:5:5:5 | func: f ... ;\\n } | tst.js:1:11:9:1 | {\\n x ... }\\n} | +| tst.js:6:5:8:5 | f() {\\n ... ;\\n } | tst.js:1:11:9:1 | {\\n x ... }\\n} | +| tst.js:12:3:14:3 | static ... x);\\n } | tst.js:11:1:18:1 | class C ... ;\\n }\\n} | +| tst.js:20:1:20:6 | C.prop | tst.js:20:1:20:1 | C | +| tst.js:23:13:23:27 | onClick={click} | tst.js:23:8:23:57 |
    | +| tst.js:26:3:26:26 | get x() ... null; } | tst.js:25:2:28:1 | {\\n get ... v) {}\\n} | +| tst.js:27:3:27:13 | set y(v) {} | tst.js:25:2:28:1 | {\\n get ... v) {}\\n} | +| tst.js:31:5:31:8 | n: 1 | tst.js:30:2:35:1 | {\\n n ... q]: 4\\n} | +| tst.js:32:5:32:10 | [v]: 2 | tst.js:30:2:35:1 | {\\n n ... q]: 4\\n} | +| tst.js:33:5:33:14 | [vv.pp]: 3 | tst.js:30:2:35:1 | {\\n n ... q]: 4\\n} | +| tst.js:34:5:34:20 | [vvv.ppp.qqq]: 4 | tst.js:30:2:35:1 | {\\n n ... q]: 4\\n} | +| tst.js:37:13:37:15 | "a" | tst.js:37:12:37:26 | ["a", "b", "c"] | +| tst.js:37:18:37:20 | "b" | tst.js:37:12:37:26 | ["a", "b", "c"] | +| tst.js:37:23:37:25 | "c" | tst.js:37:12:37:26 | ["a", "b", "c"] | +| tst.js:38:13:38:15 | "a" | tst.js:38:12:38:23 | ["a", , "c"] | +| tst.js:38:20:38:22 | "c" | tst.js:38:12:38:23 | ["a", , "c"] | +| tst.js:39:15:39:17 | "b" | tst.js:39:12:39:23 | [, "b", "c"] | +| tst.js:39:20:39:22 | "c" | tst.js:39:12:39:23 | [, "b", "c"] | +| tst.js:40:13:40:15 | "a" | tst.js:40:12:40:22 | ["a", "b",] | +| tst.js:40:18:40:20 | "b" | tst.js:40:12:40:22 | ["a", "b",] | +| tst.js:41:13:41:15 | "a" | tst.js:41:12:41:30 | ["a", ...arr3, "d"] | +| tst.js:41:18:41:24 | ...arr3 | tst.js:41:12:41:30 | ["a", ...arr3, "d"] | +| tst.js:41:27:41:29 | "d" | tst.js:41:12:41:30 | ["a", ...arr3, "d"] | test_getAPropertyWrite | classes.ts:3:21:3:20 | this | classes.ts:4:3:4:24 | instanc ... foo(); | | classes.ts:8:3:8:2 | this | classes.ts:8:15:8:35 | public ... erField | | classes.ts:12:5:12:4 | this | classes.ts:12:17:12:37 | public ... erField | | classes.ts:16:5:16:4 | this | classes.ts:16:17:16:37 | public ... erField | -| tst.js:2:11:10:1 | {\\n x ... }\\n} | tst.js:3:5:3:8 | x: 4 | -| tst.js:2:11:10:1 | {\\n x ... }\\n} | tst.js:4:5:6:5 | func: f ... ;\\n } | -| tst.js:2:11:10:1 | {\\n x ... }\\n} | tst.js:7:5:9:5 | f() {\\n ... ;\\n } | -| tst.js:12:1:19:1 | class C ... ;\\n }\\n} | tst.js:13:3:15:3 | static ... x);\\n } | -| tst.js:21:1:21:1 | C | tst.js:21:1:21:6 | C.prop | -| tst.js:24:8:24:57 |
    | tst.js:24:13:24:27 | onClick={click} | -| tst.js:26:2:29:1 | {\\n get ... v) {}\\n} | tst.js:27:3:27:26 | get x() ... null; } | -| tst.js:26:2:29:1 | {\\n get ... v) {}\\n} | tst.js:28:3:28:13 | set y(v) {} | -| tst.js:31:2:36:1 | {\\n n ... q]: 4\\n} | tst.js:32:5:32:8 | n: 1 | -| tst.js:31:2:36:1 | {\\n n ... q]: 4\\n} | tst.js:33:5:33:10 | [v]: 2 | -| tst.js:31:2:36:1 | {\\n n ... q]: 4\\n} | tst.js:34:5:34:14 | [vv.pp]: 3 | -| tst.js:31:2:36:1 | {\\n n ... q]: 4\\n} | tst.js:35:5:35:20 | [vvv.ppp.qqq]: 4 | -| tst.js:38:12:38:26 | ["a", "b", "c"] | tst.js:38:13:38:15 | "a" | -| tst.js:38:12:38:26 | ["a", "b", "c"] | tst.js:38:18:38:20 | "b" | -| tst.js:38:12:38:26 | ["a", "b", "c"] | tst.js:38:23:38:25 | "c" | -| tst.js:39:12:39:23 | ["a", , "c"] | tst.js:39:13:39:15 | "a" | -| tst.js:39:12:39:23 | ["a", , "c"] | tst.js:39:20:39:22 | "c" | -| tst.js:40:12:40:23 | [, "b", "c"] | tst.js:40:15:40:17 | "b" | -| tst.js:40:12:40:23 | [, "b", "c"] | tst.js:40:20:40:22 | "c" | -| tst.js:41:12:41:22 | ["a", "b",] | tst.js:41:13:41:15 | "a" | -| tst.js:41:12:41:22 | ["a", "b",] | tst.js:41:18:41:20 | "b" | -| tst.js:42:12:42:30 | ["a", ...arr3, "d"] | tst.js:42:13:42:15 | "a" | -| tst.js:42:12:42:30 | ["a", ...arr3, "d"] | tst.js:42:18:42:24 | ...arr3 | -| tst.js:42:12:42:30 | ["a", ...arr3, "d"] | tst.js:42:27:42:29 | "d" | +| tst.js:1:11:9:1 | {\\n x ... }\\n} | tst.js:2:5:2:8 | x: 4 | +| tst.js:1:11:9:1 | {\\n x ... }\\n} | tst.js:3:5:5:5 | func: f ... ;\\n } | +| tst.js:1:11:9:1 | {\\n x ... }\\n} | tst.js:6:5:8:5 | f() {\\n ... ;\\n } | +| tst.js:11:1:18:1 | class C ... ;\\n }\\n} | tst.js:12:3:14:3 | static ... x);\\n } | +| tst.js:20:1:20:1 | C | tst.js:20:1:20:6 | C.prop | +| tst.js:23:8:23:57 |
    | tst.js:23:13:23:27 | onClick={click} | +| tst.js:25:2:28:1 | {\\n get ... v) {}\\n} | tst.js:26:3:26:26 | get x() ... null; } | +| tst.js:25:2:28:1 | {\\n get ... v) {}\\n} | tst.js:27:3:27:13 | set y(v) {} | +| tst.js:30:2:35:1 | {\\n n ... q]: 4\\n} | tst.js:31:5:31:8 | n: 1 | +| tst.js:30:2:35:1 | {\\n n ... q]: 4\\n} | tst.js:32:5:32:10 | [v]: 2 | +| tst.js:30:2:35:1 | {\\n n ... q]: 4\\n} | tst.js:33:5:33:14 | [vv.pp]: 3 | +| tst.js:30:2:35:1 | {\\n n ... q]: 4\\n} | tst.js:34:5:34:20 | [vvv.ppp.qqq]: 4 | +| tst.js:37:12:37:26 | ["a", "b", "c"] | tst.js:37:13:37:15 | "a" | +| tst.js:37:12:37:26 | ["a", "b", "c"] | tst.js:37:18:37:20 | "b" | +| tst.js:37:12:37:26 | ["a", "b", "c"] | tst.js:37:23:37:25 | "c" | +| tst.js:38:12:38:23 | ["a", , "c"] | tst.js:38:13:38:15 | "a" | +| tst.js:38:12:38:23 | ["a", , "c"] | tst.js:38:20:38:22 | "c" | +| tst.js:39:12:39:23 | [, "b", "c"] | tst.js:39:15:39:17 | "b" | +| tst.js:39:12:39:23 | [, "b", "c"] | tst.js:39:20:39:22 | "c" | +| tst.js:40:12:40:22 | ["a", "b",] | tst.js:40:13:40:15 | "a" | +| tst.js:40:12:40:22 | ["a", "b",] | tst.js:40:18:40:20 | "b" | +| tst.js:41:12:41:30 | ["a", ...arr3, "d"] | tst.js:41:13:41:15 | "a" | +| tst.js:41:12:41:30 | ["a", ...arr3, "d"] | tst.js:41:18:41:24 | ...arr3 | +| tst.js:41:12:41:30 | ["a", ...arr3, "d"] | tst.js:41:27:41:29 | "d" | test_PropWrite | classes.ts:3:21:3:20 | constructor() {} | | classes.ts:4:3:4:24 | instanc ... foo(); | @@ -196,46 +196,46 @@ test_PropWrite | classes.ts:12:17:12:37 | public ... erField | | classes.ts:16:5:16:46 | constru ... {}) {} | | classes.ts:16:17:16:37 | public ... erField | -| tst.js:3:5:3:8 | x: 4 | -| tst.js:4:5:6:5 | func: f ... ;\\n } | -| tst.js:7:5:9:5 | f() {\\n ... ;\\n } | -| tst.js:12:9:12:8 | constructor() {} | -| tst.js:13:3:15:3 | static ... x);\\n } | -| tst.js:16:3:18:3 | f(x) {\\n ... x);\\n } | -| tst.js:21:1:21:6 | C.prop | -| tst.js:24:13:24:27 | onClick={click} | -| tst.js:27:3:27:26 | get x() ... null; } | -| tst.js:28:3:28:13 | set y(v) {} | -| tst.js:32:5:32:8 | n: 1 | -| tst.js:33:5:33:10 | [v]: 2 | -| tst.js:34:5:34:14 | [vv.pp]: 3 | -| tst.js:35:5:35:20 | [vvv.ppp.qqq]: 4 | +| tst.js:2:5:2:8 | x: 4 | +| tst.js:3:5:5:5 | func: f ... ;\\n } | +| tst.js:6:5:8:5 | f() {\\n ... ;\\n } | +| tst.js:11:9:11:8 | constructor() {} | +| tst.js:12:3:14:3 | static ... x);\\n } | +| tst.js:15:3:17:3 | f(x) {\\n ... x);\\n } | +| tst.js:20:1:20:6 | C.prop | +| tst.js:23:13:23:27 | onClick={click} | +| tst.js:26:3:26:26 | get x() ... null; } | +| tst.js:27:3:27:13 | set y(v) {} | +| tst.js:31:5:31:8 | n: 1 | +| tst.js:32:5:32:10 | [v]: 2 | +| tst.js:33:5:33:14 | [vv.pp]: 3 | +| tst.js:34:5:34:20 | [vvv.ppp.qqq]: 4 | +| tst.js:37:13:37:15 | "a" | +| tst.js:37:18:37:20 | "b" | +| tst.js:37:23:37:25 | "c" | | tst.js:38:13:38:15 | "a" | -| tst.js:38:18:38:20 | "b" | -| tst.js:38:23:38:25 | "c" | -| tst.js:39:13:39:15 | "a" | +| tst.js:38:20:38:22 | "c" | +| tst.js:39:15:39:17 | "b" | | tst.js:39:20:39:22 | "c" | -| tst.js:40:15:40:17 | "b" | -| tst.js:40:20:40:22 | "c" | +| tst.js:40:13:40:15 | "a" | +| tst.js:40:18:40:20 | "b" | | tst.js:41:13:41:15 | "a" | -| tst.js:41:18:41:20 | "b" | -| tst.js:42:13:42:15 | "a" | -| tst.js:42:18:42:24 | ...arr3 | -| tst.js:42:27:42:29 | "d" | +| tst.js:41:18:41:24 | ...arr3 | +| tst.js:41:27:41:29 | "d" | test_getAPropertyWrite2 | classes.ts:3:21:3:20 | this | instanceField | classes.ts:4:3:4:24 | instanc ... foo(); | | classes.ts:8:3:8:2 | this | parameterField | classes.ts:8:15:8:35 | public ... erField | | classes.ts:12:5:12:4 | this | parameterField | classes.ts:12:17:12:37 | public ... erField | | classes.ts:16:5:16:4 | this | parameterField | classes.ts:16:17:16:37 | public ... erField | -| tst.js:2:11:10:1 | {\\n x ... }\\n} | f | tst.js:7:5:9:5 | f() {\\n ... ;\\n } | -| tst.js:2:11:10:1 | {\\n x ... }\\n} | func | tst.js:4:5:6:5 | func: f ... ;\\n } | -| tst.js:2:11:10:1 | {\\n x ... }\\n} | x | tst.js:3:5:3:8 | x: 4 | -| tst.js:12:1:19:1 | class C ... ;\\n }\\n} | func | tst.js:13:3:15:3 | static ... x);\\n } | -| tst.js:21:1:21:1 | C | prop | tst.js:21:1:21:6 | C.prop | -| tst.js:24:8:24:57 |
    | onClick | tst.js:24:13:24:27 | onClick={click} | -| tst.js:26:2:29:1 | {\\n get ... v) {}\\n} | x | tst.js:27:3:27:26 | get x() ... null; } | -| tst.js:26:2:29:1 | {\\n get ... v) {}\\n} | y | tst.js:28:3:28:13 | set y(v) {} | -| tst.js:31:2:36:1 | {\\n n ... q]: 4\\n} | n | tst.js:32:5:32:8 | n: 1 | +| tst.js:1:11:9:1 | {\\n x ... }\\n} | f | tst.js:6:5:8:5 | f() {\\n ... ;\\n } | +| tst.js:1:11:9:1 | {\\n x ... }\\n} | func | tst.js:3:5:5:5 | func: f ... ;\\n } | +| tst.js:1:11:9:1 | {\\n x ... }\\n} | x | tst.js:2:5:2:8 | x: 4 | +| tst.js:11:1:18:1 | class C ... ;\\n }\\n} | func | tst.js:12:3:14:3 | static ... x);\\n } | +| tst.js:20:1:20:1 | C | prop | tst.js:20:1:20:6 | C.prop | +| tst.js:23:8:23:57 |
    | onClick | tst.js:23:13:23:27 | onClick={click} | +| tst.js:25:2:28:1 | {\\n get ... v) {}\\n} | x | tst.js:26:3:26:26 | get x() ... null; } | +| tst.js:25:2:28:1 | {\\n get ... v) {}\\n} | y | tst.js:27:3:27:13 | set y(v) {} | +| tst.js:30:2:35:1 | {\\n n ... q]: 4\\n} | n | tst.js:31:5:31:8 | n: 1 | test_PropWriteRhs | classes.ts:3:21:3:20 | constructor() {} | classes.ts:3:21:3:20 | () {} | | classes.ts:4:3:4:24 | instanc ... foo(); | classes.ts:4:19:4:23 | foo() | @@ -246,27 +246,27 @@ test_PropWriteRhs | classes.ts:16:5:16:46 | constru ... {}) {} | classes.ts:16:5:16:46 | constru ... {}) {} | | classes.ts:16:17:16:37 | public ... erField | classes.ts:16:24:16:37 | parameterField | | classes.ts:16:17:16:37 | public ... erField | classes.ts:16:41:16:42 | {} | -| tst.js:3:5:3:8 | x: 4 | tst.js:3:8:3:8 | 4 | -| tst.js:4:5:6:5 | func: f ... ;\\n } | tst.js:4:11:6:5 | functio ... ;\\n } | -| tst.js:7:5:9:5 | f() {\\n ... ;\\n } | tst.js:7:6:9:5 | () {\\n ... ;\\n } | -| tst.js:12:9:12:8 | constructor() {} | tst.js:12:9:12:8 | () {} | -| tst.js:13:3:15:3 | static ... x);\\n } | tst.js:13:14:15:3 | (x) {\\n ... x);\\n } | -| tst.js:16:3:18:3 | f(x) {\\n ... x);\\n } | tst.js:16:4:18:3 | (x) {\\n ... x);\\n } | -| tst.js:21:1:21:6 | C.prop | tst.js:21:10:21:11 | 56 | -| tst.js:24:13:24:27 | onClick={click} | tst.js:24:22:24:26 | click | -| tst.js:32:5:32:8 | n: 1 | tst.js:32:8:32:8 | 1 | -| tst.js:33:5:33:10 | [v]: 2 | tst.js:33:10:33:10 | 2 | -| tst.js:34:5:34:14 | [vv.pp]: 3 | tst.js:34:14:34:14 | 3 | -| tst.js:35:5:35:20 | [vvv.ppp.qqq]: 4 | tst.js:35:20:35:20 | 4 | +| tst.js:2:5:2:8 | x: 4 | tst.js:2:8:2:8 | 4 | +| tst.js:3:5:5:5 | func: f ... ;\\n } | tst.js:3:11:5:5 | functio ... ;\\n } | +| tst.js:6:5:8:5 | f() {\\n ... ;\\n } | tst.js:6:6:8:5 | () {\\n ... ;\\n } | +| tst.js:11:9:11:8 | constructor() {} | tst.js:11:9:11:8 | () {} | +| tst.js:12:3:14:3 | static ... x);\\n } | tst.js:12:14:14:3 | (x) {\\n ... x);\\n } | +| tst.js:15:3:17:3 | f(x) {\\n ... x);\\n } | tst.js:15:4:17:3 | (x) {\\n ... x);\\n } | +| tst.js:20:1:20:6 | C.prop | tst.js:20:10:20:11 | 56 | +| tst.js:23:13:23:27 | onClick={click} | tst.js:23:22:23:26 | click | +| tst.js:31:5:31:8 | n: 1 | tst.js:31:8:31:8 | 1 | +| tst.js:32:5:32:10 | [v]: 2 | tst.js:32:10:32:10 | 2 | +| tst.js:33:5:33:14 | [vv.pp]: 3 | tst.js:33:14:33:14 | 3 | +| tst.js:34:5:34:20 | [vvv.ppp.qqq]: 4 | tst.js:34:20:34:20 | 4 | +| tst.js:37:13:37:15 | "a" | tst.js:37:13:37:15 | "a" | +| tst.js:37:18:37:20 | "b" | tst.js:37:18:37:20 | "b" | +| tst.js:37:23:37:25 | "c" | tst.js:37:23:37:25 | "c" | | tst.js:38:13:38:15 | "a" | tst.js:38:13:38:15 | "a" | -| tst.js:38:18:38:20 | "b" | tst.js:38:18:38:20 | "b" | -| tst.js:38:23:38:25 | "c" | tst.js:38:23:38:25 | "c" | -| tst.js:39:13:39:15 | "a" | tst.js:39:13:39:15 | "a" | +| tst.js:38:20:38:22 | "c" | tst.js:38:20:38:22 | "c" | +| tst.js:39:15:39:17 | "b" | tst.js:39:15:39:17 | "b" | | tst.js:39:20:39:22 | "c" | tst.js:39:20:39:22 | "c" | -| tst.js:40:15:40:17 | "b" | tst.js:40:15:40:17 | "b" | -| tst.js:40:20:40:22 | "c" | tst.js:40:20:40:22 | "c" | +| tst.js:40:13:40:15 | "a" | tst.js:40:13:40:15 | "a" | +| tst.js:40:18:40:20 | "b" | tst.js:40:18:40:20 | "b" | | tst.js:41:13:41:15 | "a" | tst.js:41:13:41:15 | "a" | -| tst.js:41:18:41:20 | "b" | tst.js:41:18:41:20 | "b" | -| tst.js:42:13:42:15 | "a" | tst.js:42:13:42:15 | "a" | -| tst.js:42:18:42:24 | ...arr3 | tst.js:42:18:42:24 | ...arr3 | -| tst.js:42:27:42:29 | "d" | tst.js:42:27:42:29 | "d" | +| tst.js:41:18:41:24 | ...arr3 | tst.js:41:18:41:24 | ...arr3 | +| tst.js:41:27:41:29 | "d" | tst.js:41:27:41:29 | "d" | diff --git a/javascript/ql/test/library-tests/PropWrite/tst.js b/javascript/ql/test/library-tests/PropWrite/tst.js index 8b2ad5aa3e2..99e9d5ffb1c 100644 --- a/javascript/ql/test/library-tests/PropWrite/tst.js +++ b/javascript/ql/test/library-tests/PropWrite/tst.js @@ -1,4 +1,3 @@ -// semmle-extractor-options: --experimental var obj = { x: 4, func: function() { diff --git a/javascript/ql/test/library-tests/SpreadRestProperties/tst.js b/javascript/ql/test/library-tests/SpreadRestProperties/tst.js index cbff84ef9b4..faa017a8bd3 100644 --- a/javascript/ql/test/library-tests/SpreadRestProperties/tst.js +++ b/javascript/ql/test/library-tests/SpreadRestProperties/tst.js @@ -1,4 +1,2 @@ var q = { ...o, x: 42, ...p }; let { x, ...r } = q, { z } = {}; - -// semmle-extractor-options: --experimental \ No newline at end of file diff --git a/javascript/ql/test/library-tests/TaintBarriers/SanitizingGuard.expected b/javascript/ql/test/library-tests/TaintBarriers/SanitizingGuard.expected index c58a7c511d1..010375e1ab8 100644 --- a/javascript/ql/test/library-tests/TaintBarriers/SanitizingGuard.expected +++ b/javascript/ql/test/library-tests/TaintBarriers/SanitizingGuard.expected @@ -44,14 +44,11 @@ | tst.js:236:9:236:24 | isWhitelisted(v) | ExampleConfiguration | true | tst.js:236:23:236:23 | v | | tst.js:240:9:240:28 | config.allowValue(v) | ExampleConfiguration | true | tst.js:240:27:240:27 | v | | tst.js:252:16:252:36 | whiteli ... ains(x) | ExampleConfiguration | true | tst.js:252:35:252:35 | x | -| tst.js:254:9:254:12 | f(v) | ExampleConfiguration | true | tst.js:254:11:254:11 | v | | tst.js:261:25:261:45 | whiteli ... ains(y) | ExampleConfiguration | true | tst.js:261:44:261:44 | y | -| tst.js:264:9:264:12 | g(v) | ExampleConfiguration | true | tst.js:264:11:264:11 | v | | tst.js:271:25:271:45 | whiteli ... ains(z) | ExampleConfiguration | true | tst.js:271:44:271:44 | z | | tst.js:281:16:281:25 | x2 != null | ExampleConfiguration | false | tst.js:281:16:281:17 | x2 | | tst.js:281:16:281:25 | x2 != null | ExampleConfiguration | false | tst.js:281:22:281:25 | null | | tst.js:281:30:281:51 | whiteli ... ins(x2) | ExampleConfiguration | true | tst.js:281:49:281:50 | x2 | -| tst.js:283:9:283:13 | f2(v) | ExampleConfiguration | true | tst.js:283:12:283:12 | v | | tst.js:290:16:290:25 | x3 == null | ExampleConfiguration | true | tst.js:290:16:290:17 | x3 | | tst.js:290:16:290:25 | x3 == null | ExampleConfiguration | true | tst.js:290:22:290:25 | null | | tst.js:290:30:290:51 | whiteli ... ins(x3) | ExampleConfiguration | true | tst.js:290:49:290:50 | x3 | @@ -61,7 +58,6 @@ | tst.js:327:25:327:34 | x7 != null | ExampleConfiguration | false | tst.js:327:25:327:26 | x7 | | tst.js:327:25:327:34 | x7 != null | ExampleConfiguration | false | tst.js:327:31:327:34 | null | | tst.js:327:39:327:60 | whiteli ... ins(x7) | ExampleConfiguration | true | tst.js:327:58:327:59 | x7 | -| tst.js:330:9:330:13 | f7(v) | ExampleConfiguration | true | tst.js:330:12:330:12 | v | | tst.js:337:25:337:46 | whiteli ... ins(x8) | ExampleConfiguration | true | tst.js:337:44:337:45 | x8 | | tst.js:338:16:338:25 | x8 != null | ExampleConfiguration | false | tst.js:338:16:338:17 | x8 | | tst.js:338:16:338:25 | x8 != null | ExampleConfiguration | false | tst.js:338:22:338:25 | null | @@ -70,6 +66,5 @@ | tst.js:356:16:356:27 | x10 !== null | ExampleConfiguration | false | tst.js:356:24:356:27 | null | | tst.js:356:32:356:48 | x10 !== undefined | ExampleConfiguration | false | tst.js:356:32:356:34 | x10 | | tst.js:356:32:356:48 | x10 !== undefined | ExampleConfiguration | false | tst.js:356:40:356:48 | undefined | -| tst.js:358:9:358:14 | f10(v) | ExampleConfiguration | false | tst.js:358:13:358:13 | v | | tst.js:370:9:370:29 | o.p == ... listed" | ExampleConfiguration | true | tst.js:370:9:370:11 | o.p | | tst.js:377:11:377:32 | o[p] == ... listed" | ExampleConfiguration | true | tst.js:377:11:377:14 | o[p] | diff --git a/javascript/ql/test/library-tests/TaintBarriers/TaintedSink.expected b/javascript/ql/test/library-tests/TaintBarriers/TaintedSink.expected index 050f80bc071..54b35166b15 100644 --- a/javascript/ql/test/library-tests/TaintBarriers/TaintedSink.expected +++ b/javascript/ql/test/library-tests/TaintBarriers/TaintedSink.expected @@ -53,7 +53,6 @@ | tst.js:333:14:333:14 | v | tst.js:248:13:248:20 | SOURCE() | | tst.js:341:14:341:14 | v | tst.js:248:13:248:20 | SOURCE() | | tst.js:343:14:343:14 | v | tst.js:248:13:248:20 | SOURCE() | -| tst.js:350:14:350:14 | v | tst.js:248:13:248:20 | SOURCE() | | tst.js:352:14:352:14 | v | tst.js:248:13:248:20 | SOURCE() | | tst.js:359:14:359:14 | v | tst.js:248:13:248:20 | SOURCE() | | tst.js:368:10:368:12 | o.p | tst.js:367:13:367:20 | SOURCE() | diff --git a/javascript/ql/test/library-tests/TaintBarriers/isBarrier.expected b/javascript/ql/test/library-tests/TaintBarriers/isBarrier.expected index 50804043f95..f650c93185c 100644 --- a/javascript/ql/test/library-tests/TaintBarriers/isBarrier.expected +++ b/javascript/ql/test/library-tests/TaintBarriers/isBarrier.expected @@ -37,6 +37,7 @@ | tst.js:265:14:265:14 | v | ExampleConfiguration | | tst.js:284:14:284:14 | v | ExampleConfiguration | | tst.js:331:14:331:14 | v | ExampleConfiguration | +| tst.js:350:14:350:14 | v | ExampleConfiguration | | tst.js:356:16:356:27 | x10 | ExampleConfiguration | | tst.js:356:32:356:34 | x10 | ExampleConfiguration | | tst.js:361:14:361:14 | v | ExampleConfiguration | diff --git a/javascript/ql/test/library-tests/TaintBarriers/tst.js b/javascript/ql/test/library-tests/TaintBarriers/tst.js index 78986d6af37..a7a05590540 100644 --- a/javascript/ql/test/library-tests/TaintBarriers/tst.js +++ b/javascript/ql/test/library-tests/TaintBarriers/tst.js @@ -347,7 +347,7 @@ function IndirectSanitizer () { return unknown() && whitelist.contains(x9) && unknown(); } if (f9(v)) { - SINK(v); // SANITIZATION OF THIS IS NOT YET SUPPORTED + SINK(v); } else { SINK(v); } diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected index 2722f67d6fd..93dc5e6e200 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected @@ -69,10 +69,14 @@ typeInferenceMismatch | promise.js:5:25:5:32 | source() | promise.js:5:8:5:33 | bluebir ... urce()) | | promise.js:10:24:10:31 | source() | promise.js:10:8:10:32 | Promise ... urce()) | | promise.js:12:20:12:27 | source() | promise.js:13:8:13:23 | resolver.promise | +| sanitizer-function.js:12:17:12:24 | source() | sanitizer-function.js:14:10:14:14 | taint | +| sanitizer-function.js:12:17:12:24 | source() | sanitizer-function.js:33:14:33:18 | taint | | sanitizer-guards.js:2:11:2:18 | source() | sanitizer-guards.js:4:8:4:8 | x | | sanitizer-guards.js:13:14:13:21 | source() | sanitizer-guards.js:15:10:15:15 | this.x | | sanitizer-guards.js:13:14:13:21 | source() | sanitizer-guards.js:21:14:21:19 | this.x | | sanitizer-guards.js:13:14:13:21 | source() | sanitizer-guards.js:26:9:26:14 | this.x | +| sanitizer-guards.js:43:11:43:18 | source() | sanitizer-guards.js:45:8:45:8 | x | +| sanitizer-guards.js:43:11:43:18 | source() | sanitizer-guards.js:48:10:48:10 | x | | spread.js:2:15:2:22 | source() | spread.js:4:8:4:19 | { ...taint } | | spread.js:2:15:2:22 | source() | spread.js:5:8:5:43 | { f: 'h ... orld' } | | spread.js:2:15:2:22 | source() | spread.js:7:8:7:19 | [ ...taint ] | diff --git a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql index 0b1d5d9da84..26c66a1b4fe 100644 --- a/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql +++ b/javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.ql @@ -1,7 +1,11 @@ import javascript import semmle.javascript.dataflow.InferredTypes -DataFlow::CallNode getACall(string name) { result.getCalleeName() = name } +DataFlow::CallNode getACall(string name) { + result.getCalleeName() = name + or + result.getCalleeNode().getALocalSource() = DataFlow::globalVarRef(name) +} class Sink extends DataFlow::Node { Sink() { this = getACall("sink").getAnArgument() } diff --git a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected index 6a589e3e0d9..f2799d763fd 100644 --- a/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected +++ b/javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected @@ -41,10 +41,18 @@ | partialCalls.js:4:17:4:24 | source() | partialCalls.js:30:14:30:20 | x.value | | partialCalls.js:4:17:4:24 | source() | partialCalls.js:41:10:41:18 | id(taint) | | partialCalls.js:4:17:4:24 | source() | partialCalls.js:51:14:51:14 | x | +| sanitizer-function.js:12:17:12:24 | source() | sanitizer-function.js:14:10:14:14 | taint | +| sanitizer-function.js:12:17:12:24 | source() | sanitizer-function.js:17:14:17:18 | taint | +| sanitizer-function.js:12:17:12:24 | source() | sanitizer-function.js:21:14:21:18 | taint | +| sanitizer-function.js:12:17:12:24 | source() | sanitizer-function.js:25:14:25:18 | taint | +| sanitizer-function.js:12:17:12:24 | source() | sanitizer-function.js:33:14:33:18 | taint | | sanitizer-guards.js:2:11:2:18 | source() | sanitizer-guards.js:4:8:4:8 | x | | sanitizer-guards.js:13:14:13:21 | source() | sanitizer-guards.js:15:10:15:15 | this.x | | sanitizer-guards.js:13:14:13:21 | source() | sanitizer-guards.js:21:14:21:19 | this.x | | sanitizer-guards.js:13:14:13:21 | source() | sanitizer-guards.js:26:9:26:14 | this.x | +| sanitizer-guards.js:43:11:43:18 | source() | sanitizer-guards.js:45:8:45:8 | x | +| sanitizer-guards.js:43:11:43:18 | source() | sanitizer-guards.js:48:10:48:10 | x | +| sanitizer-guards.js:43:11:43:18 | source() | sanitizer-guards.js:52:10:52:10 | x | | thisAssignments.js:4:17:4:24 | source() | thisAssignments.js:5:10:5:18 | obj.field | | thisAssignments.js:7:19:7:26 | source() | thisAssignments.js:8:10:8:20 | this.field2 | | tst.js:2:13:2:20 | source() | tst.js:4:10:4:10 | x | diff --git a/javascript/ql/test/library-tests/TaintTracking/exceptions.js b/javascript/ql/test/library-tests/TaintTracking/exceptions.js index b8946b5603a..98e3e7ce009 100644 --- a/javascript/ql/test/library-tests/TaintTracking/exceptions.js +++ b/javascript/ql/test/library-tests/TaintTracking/exceptions.js @@ -169,5 +169,3 @@ function throwThoughLibrary(xs) { sink(e); // OK - doesn't catch exception from event listener } } - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/TaintTracking/promise.js b/javascript/ql/test/library-tests/TaintTracking/promise.js index cd5351720ba..9714d258df5 100644 --- a/javascript/ql/test/library-tests/TaintTracking/promise.js +++ b/javascript/ql/test/library-tests/TaintTracking/promise.js @@ -11,4 +11,4 @@ function closure() { let resolver = Promise.withResolver(); resolver.resolve(source()); sink(resolver.promise); // NOT OK -} +} \ No newline at end of file diff --git a/javascript/ql/test/library-tests/TaintTracking/sanitizer-function.js b/javascript/ql/test/library-tests/TaintTracking/sanitizer-function.js new file mode 100644 index 00000000000..6df74cf29ee --- /dev/null +++ b/javascript/ql/test/library-tests/TaintTracking/sanitizer-function.js @@ -0,0 +1,35 @@ +function test() { + function myCheck1(x) { + return x === "a" && something() && somethingElse(); + } + function myCheck2(x) { + return something() && x === "a" && somethingElse(); + } + function myCheck3(x) { + return something() && somethingElse() && x === "a"; + } + + let taint = source(); + + sink(taint); // NOT OK + + if (myCheck1(taint)) { + sink(taint); // OK + } + + if (myCheck2(taint)) { + sink(taint); // OK + } + + if (myCheck3(taint)) { + sink(taint); // OK + } + + function badCheck(x) { + return something && x + isSafe(x) != null; + } + + if (badCheck(taint)) { + sink(taint); // NOT OK + } +} diff --git a/javascript/ql/test/library-tests/TaintTracking/sanitizer-guards.js b/javascript/ql/test/library-tests/TaintTracking/sanitizer-guards.js index 494e828460d..03d6a9aedd7 100644 --- a/javascript/ql/test/library-tests/TaintTracking/sanitizer-guards.js +++ b/javascript/ql/test/library-tests/TaintTracking/sanitizer-guards.js @@ -38,3 +38,17 @@ class C { }); } } + +function reflective() { + let x = source(); + + sink(x); // NOT OK + + if (isSafe.call(x)) { + sink(x); // NOT OK - `isSafe` does not sanitize the receiver + } + + if (isSafe.call(null, x)) { + sink(x); // OK + } +} diff --git a/javascript/ql/test/library-tests/Templates/templates-revised.js b/javascript/ql/test/library-tests/Templates/templates-revised.js index 0ca81631fb4..7df488e53f9 100644 --- a/javascript/ql/test/library-tests/Templates/templates-revised.js +++ b/javascript/ql/test/library-tests/Templates/templates-revised.js @@ -1,3 +1 @@ tag `\unvalid escape sequence`; - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/ThisExpr/options b/javascript/ql/test/library-tests/ThisExpr/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/library-tests/ThisExpr/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/ThisExpr/tst.js b/javascript/ql/test/library-tests/ThisExpr/tst.js index 418021624e7..316e3feb1de 100644 --- a/javascript/ql/test/library-tests/ThisExpr/tst.js +++ b/javascript/ql/test/library-tests/ThisExpr/tst.js @@ -146,4 +146,3 @@ class C_lodash { } } -//semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/TrailingFunctionCommas/tst.js b/javascript/ql/test/library-tests/TrailingFunctionCommas/tst.js index 434f0d0ae61..2257a74aa2a 100644 --- a/javascript/ql/test/library-tests/TrailingFunctionCommas/tst.js +++ b/javascript/ql/test/library-tests/TrailingFunctionCommas/tst.js @@ -31,5 +31,3 @@ new h2(23, 42,); x => x; function f4(x = 42,) {} - -// semmle-extractor-options: --experimental \ No newline at end of file diff --git a/javascript/ql/test/library-tests/TypeInference/NullishCoalescing/options b/javascript/ql/test/library-tests/TypeInference/NullishCoalescing/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/library-tests/TypeInference/NullishCoalescing/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/TypeInference/NullishCoalescing/tst.js b/javascript/ql/test/library-tests/TypeInference/NullishCoalescing/tst.js index 6c3458781a1..28d7e45c44e 100644 --- a/javascript/ql/test/library-tests/TypeInference/NullishCoalescing/tst.js +++ b/javascript/ql/test/library-tests/TypeInference/NullishCoalescing/tst.js @@ -21,4 +21,3 @@ v7 = x ?? {}; }); -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/TypeInference/OptionalChaining/options b/javascript/ql/test/library-tests/TypeInference/OptionalChaining/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/library-tests/TypeInference/OptionalChaining/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/TypeInference/OptionalChaining/tst.js b/javascript/ql/test/library-tests/TypeInference/OptionalChaining/tst.js index 4890c8335cc..42747617b6b 100644 --- a/javascript/ql/test/library-tests/TypeInference/OptionalChaining/tst.js +++ b/javascript/ql/test/library-tests/TypeInference/OptionalChaining/tst.js @@ -22,4 +22,3 @@ var v11 = h(); var v12 = h?.(); }); -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/TypeScript/DeclareInClass/test.expected b/javascript/ql/test/library-tests/TypeScript/DeclareInClass/test.expected new file mode 100644 index 00000000000..17658f9c17d --- /dev/null +++ b/javascript/ql/test/library-tests/TypeScript/DeclareInClass/test.expected @@ -0,0 +1 @@ +| tst.ts:2:5:2:22 | declare x: number; | true | diff --git a/javascript/ql/test/library-tests/TypeScript/DeclareInClass/test.ql b/javascript/ql/test/library-tests/TypeScript/DeclareInClass/test.ql new file mode 100644 index 00000000000..b4a528dc9b1 --- /dev/null +++ b/javascript/ql/test/library-tests/TypeScript/DeclareInClass/test.ql @@ -0,0 +1,5 @@ +import javascript + +from FieldDeclaration f, boolean ambient +where if f.isAmbient() then ambient = true else ambient = false +select f, ambient diff --git a/javascript/ql/test/library-tests/TypeScript/DeclareInClass/tst.ts b/javascript/ql/test/library-tests/TypeScript/DeclareInClass/tst.ts new file mode 100644 index 00000000000..0952c23532d --- /dev/null +++ b/javascript/ql/test/library-tests/TypeScript/DeclareInClass/tst.ts @@ -0,0 +1,3 @@ +class C { + declare x: number; +} diff --git a/javascript/ql/test/library-tests/TypeScript/Modifiers/options b/javascript/ql/test/library-tests/TypeScript/Modifiers/options new file mode 100644 index 00000000000..d51f2d49be2 --- /dev/null +++ b/javascript/ql/test/library-tests/TypeScript/Modifiers/options @@ -0,0 +1 @@ +semmle-extractor-options: --extract-program-text diff --git a/javascript/ql/test/library-tests/TypeScript/Modifiers/tst.ts b/javascript/ql/test/library-tests/TypeScript/Modifiers/tst.ts index a56c724cf57..615a36ae6e5 100644 --- a/javascript/ql/test/library-tests/TypeScript/Modifiers/tst.ts +++ b/javascript/ql/test/library-tests/TypeScript/Modifiers/tst.ts @@ -113,5 +113,3 @@ interface InterfaceFields { z?: number; readonly w?: number; } - -// semmle-extractor-options: --extract-program-text \ No newline at end of file diff --git a/javascript/ql/test/library-tests/TypeScript/PromiseType/PromiseType.expected b/javascript/ql/test/library-tests/TypeScript/PromiseType/PromiseType.expected index bd0c467ad14..40c1f30e72a 100644 --- a/javascript/ql/test/library-tests/TypeScript/PromiseType/PromiseType.expected +++ b/javascript/ql/test/library-tests/TypeScript/PromiseType/PromiseType.expected @@ -1,10 +1,8 @@ | p1 | MyPromise | string | | p2 | MyPromise | any | | p3 | Promise | string | -| p4 | PromiseLike | string | | p5 | PromiseLike | string | | p6 | Thenable | string | -| p7 | Thenable | string | | p8 | ThenPromise | string | | p9 | JQueryPromise | string | | p10 | JQueryGenericPromise | string | diff --git a/javascript/ql/test/library-tests/TypeScript/SyntaxErrors/jsdocTypes.ts b/javascript/ql/test/library-tests/TypeScript/SyntaxErrors/jsdocTypes.ts index 6bba445dce4..55716a17a65 100644 --- a/javascript/ql/test/library-tests/TypeScript/SyntaxErrors/jsdocTypes.ts +++ b/javascript/ql/test/library-tests/TypeScript/SyntaxErrors/jsdocTypes.ts @@ -23,5 +23,3 @@ var nns: Array; var dns: Array; var anys: Array<*>; var vars: Array<...number>; - -// semmle-extractor-options: --tolerate-parse-errors diff --git a/javascript/ql/test/library-tests/TypeScript/SyntaxErrors/options b/javascript/ql/test/library-tests/TypeScript/SyntaxErrors/options new file mode 100644 index 00000000000..13f987b19ca --- /dev/null +++ b/javascript/ql/test/library-tests/TypeScript/SyntaxErrors/options @@ -0,0 +1 @@ +semmle-extractor-options: --tolerate-parse-errors diff --git a/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/IsTypeExpr.qll b/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/IsTypeExpr.qll deleted file mode 100644 index a0ff44c2bdd..00000000000 --- a/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/IsTypeExpr.qll +++ /dev/null @@ -1,5 +0,0 @@ -import javascript - -query predicate test_IsTypeExpr(IsTypeExpr type, VarTypeAccess res0, TypeExpr res1) { - res0 = type.getParameterName() and res1 = type.getPredicateType() -} diff --git a/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/PredicateTypeExpr.qll b/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/PredicateTypeExpr.qll new file mode 100644 index 00000000000..c38bf54ad1f --- /dev/null +++ b/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/PredicateTypeExpr.qll @@ -0,0 +1,13 @@ +import javascript + +query predicate test_IsTypeExpr(IsTypeExpr type, VarTypeAccess res0, TypeExpr res1) { + res0 = type.getParameterName() and res1 = type.getPredicateType() +} + +query predicate test_PredicateTypeExpr(PredicateTypeExpr type, VarTypeAccess res0) { + res0 = type.getParameterName() +} + +query predicate test_hasAssertsKeyword(PredicateTypeExpr type) { + type.hasAssertsKeyword() +} diff --git a/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/tests.expected b/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/tests.expected index eb0c717b2db..5db52c2afcd 100644 --- a/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/tests.expected +++ b/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/tests.expected @@ -105,6 +105,9 @@ test_VariableTypes | tst.ts:135:5:135:24 | tupleWithRestElement | tupleWithRestElement | tst.ts:135:27:135:47 | [number ... ring[]] | | tst.ts:136:5:136:36 | tupleWi ... lements | tupleWithOptionalAndRestElements | tst.ts:136:39:136:68 | [number ... mber[]] | | tst.ts:137:5:137:15 | unknownType | unknownType | tst.ts:137:18:137:24 | unknown | +| tst.ts:142:17:142:25 | condition | condition | tst.ts:142:28:142:30 | any | +| tst.ts:142:33:142:35 | msg | msg | tst.ts:142:39:142:44 | string | +| tst.ts:148:25:148:27 | val | val | tst.ts:148:30:148:32 | any | test_QualifiedTypeAccess | tst.ts:63:19:63:21 | N.I | tst.ts:63:19:63:19 | N | tst.ts:63:21:63:21 | I | | tst.ts:64:20:64:24 | N.M.I | tst.ts:64:20:64:22 | N.M | tst.ts:64:24:64:24 | I | @@ -148,6 +151,17 @@ test_IsTypeExpr | tst.ts:76:21:76:32 | that is Leaf | tst.ts:76:21:76:24 | that | tst.ts:76:29:76:32 | Leaf | | tst.ts:80:36:80:55 | x is Generic | tst.ts:80:36:80:36 | x | tst.ts:80:41:80:55 | Generic | | tst.ts:81:38:81:50 | x is typeof x | tst.ts:81:38:81:38 | x | tst.ts:81:43:81:50 | typeof x | +| tst.ts:148:36:148:56 | asserts ... string | tst.ts:148:44:148:46 | val | tst.ts:148:51:148:56 | string | +test_PredicateTypeExpr +| tst.ts:75:17:75:28 | this is Leaf | tst.ts:75:17:75:20 | this | +| tst.ts:76:21:76:32 | that is Leaf | tst.ts:76:21:76:24 | that | +| tst.ts:80:36:80:55 | x is Generic | tst.ts:80:36:80:36 | x | +| tst.ts:81:38:81:50 | x is typeof x | tst.ts:81:38:81:38 | x | +| tst.ts:142:48:142:64 | asserts condition | tst.ts:142:56:142:64 | condition | +| tst.ts:148:36:148:56 | asserts ... string | tst.ts:148:44:148:46 | val | +test_hasAssertsKeyword +| tst.ts:142:48:142:64 | asserts condition | +| tst.ts:148:36:148:56 | asserts ... string | test_ThisParameterTypes | function hasThisParam | tst.ts:116:29:116:32 | void | | method hasThisParam of interface InterfaceWithThisParam | tst.ts:119:22:119:43 | Interfa ... isParam | @@ -254,6 +268,8 @@ test_ReturnTypes | tst.ts:94:1:94:37 | functio ... rn x; } | function f1 | tst.ts:94:23:94:23 | S | | tst.ts:95:1:95:53 | functio ... x,y]; } | function f2 | tst.ts:95:31:95:35 | [S,T] | | tst.ts:96:1:96:52 | functio ... rn x; } | function f3 | tst.ts:96:38:96:38 | S | +| tst.ts:142:1:146:1 | functio ... )\\n }\\n} | function assert | tst.ts:142:48:142:64 | asserts condition | +| tst.ts:148:1:152:1 | functio ... ;\\n }\\n} | function assertIsString | tst.ts:148:36:148:56 | asserts ... string | test_KeyofTypeExpr | tst.ts:49:16:49:30 | keyof Interface | tst.ts:49:22:49:30 | Interface | | tst.ts:113:26:113:35 | keyof Node | tst.ts:113:32:113:35 | Node | diff --git a/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/tests.ql b/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/tests.ql index ff894fb06a5..bdabbc5f533 100644 --- a/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/tests.ql +++ b/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/tests.ql @@ -11,7 +11,7 @@ import GenericTypeExpr import IntersectionTypeExpr import FunctionTypeReturns import InterfaceTypeExpr -import IsTypeExpr +import PredicateTypeExpr import ThisParameterTypes import ChildIndex import TypeArguments diff --git a/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/tst.ts b/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/tst.ts index a9985b42878..faeb9e9c833 100644 --- a/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/tst.ts +++ b/javascript/ql/test/library-tests/TypeScript/TypeAnnotations/tst.ts @@ -138,3 +138,15 @@ let unknownType: unknown; let taggedTemplateLiteralTypeArg1 = someTag`Hello`; let taggedTemplateLiteralTypeArg2 = someTag`Hello`; + +function assert(condition: any, msg?: string): asserts condition { + if (!condition) { + throw new AssertionError(msg) + } +} + +function assertIsString(val: any): asserts val is string { + if (typeof val !== "string") { + throw new AssertionError("Not a string!"); + } +} diff --git a/javascript/ql/test/library-tests/TypeScript/Types/GetExprType.expected b/javascript/ql/test/library-tests/TypeScript/Types/GetExprType.expected index 371cdb05b21..62832265649 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/GetExprType.expected +++ b/javascript/ql/test/library-tests/TypeScript/Types/GetExprType.expected @@ -93,6 +93,30 @@ | tst.ts:43:28:43:30 | foo | "foo" | | tst.ts:43:33:43:37 | "foo" | "foo" | | type_alias.ts:3:5:3:5 | b | boolean | +| type_alias.ts:7:5:7:5 | c | ValueOrArray | +| type_alias.ts:14:9:14:32 | [proper ... ]: Json | any | +| type_alias.ts:14:10:14:17 | property | string | +| type_alias.ts:17:5:17:8 | json | Json | +| type_alias.ts:21:18:21:35 | [key: string]: any | any | +| type_alias.ts:21:19:21:21 | key | string | +| type_alias.ts:23:7:23:12 | myNode | VirtualNode | +| type_alias.ts:24:5:27:5 | ["div", ... ]\\n ] | VirtualNode | +| type_alias.ts:24:6:24:10 | "div" | "div" | +| type_alias.ts:24:13:24:28 | { id: "parent" } | string \| { [key: string]: any; } | +| type_alias.ts:24:15:24:16 | id | string | +| type_alias.ts:24:19:24:26 | "parent" | "parent" | +| type_alias.ts:25:9:25:61 | ["div", ... child"] | VirtualNode | +| type_alias.ts:25:10:25:14 | "div" | "div" | +| type_alias.ts:25:17:25:37 | { id: " ... hild" } | string \| { [key: string]: any; } | +| type_alias.ts:25:19:25:20 | id | string | +| type_alias.ts:25:23:25:35 | "first-child" | "first-child" | +| type_alias.ts:25:40:25:60 | "I'm th ... child" | "I'm the first child" | +| type_alias.ts:26:9:26:63 | ["div", ... child"] | VirtualNode | +| type_alias.ts:26:10:26:14 | "div" | "div" | +| type_alias.ts:26:17:26:38 | { id: " ... hild" } | string \| { [key: string]: any; } | +| type_alias.ts:26:19:26:20 | id | string | +| type_alias.ts:26:23:26:36 | "second-child" | "second-child" | +| type_alias.ts:26:41:26:62 | "I'm th ... child" | "I'm the second child" | | type_definition_objects.ts:1:13:1:17 | dummy | typeof dummy.ts | | type_definition_objects.ts:1:24:1:32 | "./dummy" | any | | type_definition_objects.ts:3:14:3:14 | C | C | @@ -115,4 +139,4 @@ | type_definitions.ts:16:5:16:9 | color | Color | | type_definitions.ts:18:6:18:22 | EnumWithOneMember | EnumWithOneMember | | type_definitions.ts:19:5:19:5 | e | EnumWithOneMember | -| type_definitions.ts:22:5:22:23 | aliasForNumberArray | number[] | +| type_definitions.ts:22:5:22:23 | aliasForNumberArray | Alias | diff --git a/javascript/ql/test/library-tests/TypeScript/Types/GetTypeDefinitionType.expected b/javascript/ql/test/library-tests/TypeScript/Types/GetTypeDefinitionType.expected index 00d2813750e..66c343fd601 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/GetTypeDefinitionType.expected +++ b/javascript/ql/test/library-tests/TypeScript/Types/GetTypeDefinitionType.expected @@ -1,8 +1,11 @@ | type_alias.ts:1:1:1:17 | type B = boolean; | boolean | +| type_alias.ts:5:1:5:50 | type Va ... ay>; | ValueOrArray | +| type_alias.ts:9:1:15:13 | type Js ... Json[]; | Json | +| type_alias.ts:19:1:21:57 | type Vi ... ode[]]; | VirtualNode | | type_definition_objects.ts:3:8:3:17 | class C {} | C | | type_definition_objects.ts:6:8:6:16 | enum E {} | E | | type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} | I | | type_definitions.ts:8:1:10:1 | class C ... x: T\\n} | C | | type_definitions.ts:13:1:15:1 | enum Co ... blue\\n} | Color | | type_definitions.ts:18:1:18:33 | enum En ... ember } | EnumWithOneMember | -| type_definitions.ts:21:1:21:20 | type Alias = T[]; | T[] | +| type_definitions.ts:21:1:21:20 | type Alias = T[]; | Alias | diff --git a/javascript/ql/test/library-tests/TypeScript/Types/GetTypeExprType.expected b/javascript/ql/test/library-tests/TypeScript/Types/GetTypeExprType.expected index 5bd82703bd8..0b9af780186 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/GetTypeExprType.expected +++ b/javascript/ql/test/library-tests/TypeScript/Types/GetTypeExprType.expected @@ -57,20 +57,56 @@ | tst.ts:37:17:37:18 | [] | [] | | tst.ts:38:27:38:47 | [number ... ring[]] | [number, ...string[]] | | tst.ts:38:28:38:33 | number | number | -| tst.ts:38:36:38:46 | ...string[] | string[] | +| tst.ts:38:36:38:46 | ...string[] | string | | tst.ts:38:39:38:44 | string | string | | tst.ts:38:39:38:46 | string[] | string[] | | tst.ts:39:39:39:68 | [number ... mber[]] | [number, string?, ...number[]] | | tst.ts:39:40:39:45 | number | number | | tst.ts:39:48:39:53 | string | string | | tst.ts:39:48:39:54 | string? | string | -| tst.ts:39:57:39:67 | ...number[] | number[] | +| tst.ts:39:57:39:67 | ...number[] | number | | tst.ts:39:60:39:65 | number | number | | tst.ts:39:60:39:67 | number[] | number[] | | tst.ts:40:18:40:24 | unknown | unknown | | type_alias.ts:1:6:1:6 | B | boolean | | type_alias.ts:1:10:1:16 | boolean | boolean | | type_alias.ts:3:8:3:8 | B | boolean | +| type_alias.ts:5:6:5:17 | ValueOrArray | ValueOrArray | +| type_alias.ts:5:19:5:19 | T | T | +| type_alias.ts:5:24:5:24 | T | T | +| type_alias.ts:5:24:5:49 | T \| Arr ... ray> | ValueOrArray | +| type_alias.ts:5:28:5:32 | Array | T[] | +| type_alias.ts:5:28:5:49 | Array> | ValueOrArray[] | +| type_alias.ts:5:34:5:45 | ValueOrArray | ValueOrArray | +| type_alias.ts:5:34:5:48 | ValueOrArray | ValueOrArray | +| type_alias.ts:5:47:5:47 | T | T | +| type_alias.ts:7:8:7:19 | ValueOrArray | ValueOrArray | +| type_alias.ts:7:8:7:27 | ValueOrArray | ValueOrArray | +| type_alias.ts:7:21:7:26 | number | number | +| type_alias.ts:9:6:9:9 | Json | Json | +| type_alias.ts:10:5:15:12 | \| strin ... Json[] | Json | +| type_alias.ts:10:7:10:12 | string | string | +| type_alias.ts:11:7:11:12 | number | number | +| type_alias.ts:12:7:12:13 | boolean | boolean | +| type_alias.ts:13:7:13:10 | null | null | +| type_alias.ts:14:7:14:34 | { [prop ... Json } | { [property: string]: Json; } | +| type_alias.ts:14:20:14:25 | string | string | +| type_alias.ts:14:29:14:32 | Json | Json | +| type_alias.ts:15:7:15:10 | Json | Json | +| type_alias.ts:15:7:15:12 | Json[] | Json[] | +| type_alias.ts:17:11:17:14 | Json | Json | +| type_alias.ts:19:6:19:16 | VirtualNode | VirtualNode | +| type_alias.ts:20:5:21:56 | \| strin ... Node[]] | VirtualNode | +| type_alias.ts:20:7:20:12 | string | string | +| type_alias.ts:21:7:21:56 | [string ... Node[]] | [string, { [key: string]: any; }, ...VirtualNod... | +| type_alias.ts:21:8:21:13 | string | string | +| type_alias.ts:21:16:21:37 | { [key: ... : any } | { [key: string]: any; } | +| type_alias.ts:21:24:21:29 | string | string | +| type_alias.ts:21:33:21:35 | any | any | +| type_alias.ts:21:40:21:55 | ...VirtualNode[] | VirtualNode | +| type_alias.ts:21:43:21:53 | VirtualNode | VirtualNode | +| type_alias.ts:21:43:21:55 | VirtualNode[] | VirtualNode[] | +| type_alias.ts:23:15:23:25 | VirtualNode | VirtualNode | | type_definitions.ts:3:11:3:11 | I | I | | type_definitions.ts:3:13:3:13 | S | S | | type_definitions.ts:4:6:4:6 | S | S | @@ -84,10 +120,10 @@ | type_definitions.ts:11:10:11:15 | number | number | | type_definitions.ts:16:12:16:16 | Color | Color | | type_definitions.ts:19:8:19:24 | EnumWithOneMember | EnumWithOneMember | -| type_definitions.ts:21:6:21:10 | Alias | T[] | +| type_definitions.ts:21:6:21:10 | Alias | Alias | | type_definitions.ts:21:12:21:12 | T | T | | type_definitions.ts:21:17:21:17 | T | T | -| type_definitions.ts:21:17:21:19 | T[] | T[] | -| type_definitions.ts:22:26:22:30 | Alias | T[] | -| type_definitions.ts:22:26:22:38 | Alias | number[] | +| type_definitions.ts:21:17:21:19 | T[] | Alias | +| type_definitions.ts:22:26:22:30 | Alias | Alias | +| type_definitions.ts:22:26:22:38 | Alias | Alias | | type_definitions.ts:22:32:22:37 | number | number | diff --git a/javascript/ql/test/library-tests/TypeScript/Types/ReferenceDefinition.expected b/javascript/ql/test/library-tests/TypeScript/Types/ReferenceDefinition.expected index 9704ac96d53..3426a936189 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/ReferenceDefinition.expected +++ b/javascript/ql/test/library-tests/TypeScript/Types/ReferenceDefinition.expected @@ -1,3 +1,5 @@ +| Alias | type_definitions.ts:21:1:21:20 | type Alias = T[]; | +| Alias | type_definitions.ts:21:1:21:20 | type Alias = T[]; | | C | type_definition_objects.ts:3:8:3:17 | class C {} | | C | type_definitions.ts:8:1:10:1 | class C ... x: T\\n} | | C | type_definitions.ts:8:1:10:1 | class C ... x: T\\n} | @@ -9,3 +11,7 @@ | EnumWithOneMember | type_definitions.ts:18:26:18:31 | member | | I | type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} | | I | type_definitions.ts:3:1:5:1 | interfa ... x: S;\\n} | +| Json | type_alias.ts:9:1:15:13 | type Js ... Json[]; | +| ValueOrArray | type_alias.ts:5:1:5:50 | type Va ... ay>; | +| ValueOrArray | type_alias.ts:5:1:5:50 | type Va ... ay>; | +| VirtualNode | type_alias.ts:19:1:21:57 | type Vi ... ode[]]; | diff --git a/javascript/ql/test/library-tests/TypeScript/Types/type_alias.ts b/javascript/ql/test/library-tests/TypeScript/Types/type_alias.ts index 3a831766991..d13eb159754 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/type_alias.ts +++ b/javascript/ql/test/library-tests/TypeScript/Types/type_alias.ts @@ -1,3 +1,27 @@ type B = boolean; var b: B; + +type ValueOrArray = T | Array>; + +var c: ValueOrArray; + +type Json = + | string + | number + | boolean + | null + | { [property: string]: Json } + | Json[]; + +var json: Json; + +type VirtualNode = + | string + | [string, { [key: string]: any }, ...VirtualNode[]]; + +const myNode: VirtualNode = + ["div", { id: "parent" }, + ["div", { id: "first-child" }, "I'm the first child"], + ["div", { id: "second-child" }, "I'm the second child"] + ]; diff --git a/javascript/ql/test/library-tests/YAML/YAMLError.expected b/javascript/ql/test/library-tests/YAML/YAMLError.expected index 2045e49be51..386d8874ef2 100644 --- a/javascript/ql/test/library-tests/YAML/YAMLError.expected +++ b/javascript/ql/test/library-tests/YAML/YAMLError.expected @@ -1 +1 @@ -| err.yaml:4:1:4:1 | found unexpected end of stream | +| err.yaml:3:1:3:1 | found unexpected end of stream | diff --git a/javascript/ql/test/library-tests/YAML/err.yaml b/javascript/ql/test/library-tests/YAML/err.yaml index f6d3951be96..96d2d75ddc0 100644 --- a/javascript/ql/test/library-tests/YAML/err.yaml +++ b/javascript/ql/test/library-tests/YAML/err.yaml @@ -1,3 +1,2 @@ "unterminated string -# semmle-extractor-options: --tolerate-parse-errors diff --git a/javascript/ql/test/library-tests/YAML/options b/javascript/ql/test/library-tests/YAML/options new file mode 100644 index 00000000000..13f987b19ca --- /dev/null +++ b/javascript/ql/test/library-tests/YAML/options @@ -0,0 +1 @@ +semmle-extractor-options: --tolerate-parse-errors diff --git a/javascript/ql/test/library-tests/frameworks/AngularJS/expressions/scopes/options b/javascript/ql/test/library-tests/frameworks/AngularJS/expressions/scopes/options new file mode 100644 index 00000000000..46bf0192945 --- /dev/null +++ b/javascript/ql/test/library-tests/frameworks/AngularJS/expressions/scopes/options @@ -0,0 +1 @@ +semmle-extractor-options: --html all diff --git a/javascript/ql/test/library-tests/frameworks/AngularJS/expressions/scopes/tst.html b/javascript/ql/test/library-tests/frameworks/AngularJS/expressions/scopes/tst.html index 23449e03c0e..29608f2da53 100644 --- a/javascript/ql/test/library-tests/frameworks/AngularJS/expressions/scopes/tst.html +++ b/javascript/ql/test/library-tests/frameworks/AngularJS/expressions/scopes/tst.html @@ -17,4 +17,3 @@
    -// semmle-extractor-options: --html all diff --git a/javascript/ql/test/library-tests/frameworks/AngularJS/expressions/sources/HtmlText.html b/javascript/ql/test/library-tests/frameworks/AngularJS/expressions/sources/HtmlText.html index 9678f75e0cc..87bb928ac4c 100644 --- a/javascript/ql/test/library-tests/frameworks/AngularJS/expressions/sources/HtmlText.html +++ b/javascript/ql/test/library-tests/frameworks/AngularJS/expressions/sources/HtmlText.html @@ -7,4 +7,3 @@
    {{myExpr3}}
    -semmle-extractor-options: --html all diff --git a/javascript/ql/test/library-tests/frameworks/AngularJS/expressions/sources/options b/javascript/ql/test/library-tests/frameworks/AngularJS/expressions/sources/options new file mode 100644 index 00000000000..46bf0192945 --- /dev/null +++ b/javascript/ql/test/library-tests/frameworks/AngularJS/expressions/sources/options @@ -0,0 +1 @@ +semmle-extractor-options: --html all diff --git a/javascript/ql/test/library-tests/frameworks/Express/options b/javascript/ql/test/library-tests/frameworks/Express/options new file mode 100644 index 00000000000..13f987b19ca --- /dev/null +++ b/javascript/ql/test/library-tests/frameworks/Express/options @@ -0,0 +1 @@ +semmle-extractor-options: --tolerate-parse-errors diff --git a/javascript/ql/test/library-tests/frameworks/ReactJS/options b/javascript/ql/test/library-tests/frameworks/ReactJS/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/library-tests/frameworks/ReactJS/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/frameworks/ReactJS/statePropertyReads.js b/javascript/ql/test/library-tests/frameworks/ReactJS/statePropertyReads.js index df115aac5b8..697bc35c150 100644 --- a/javascript/ql/test/library-tests/frameworks/ReactJS/statePropertyReads.js +++ b/javascript/ql/test/library-tests/frameworks/ReactJS/statePropertyReads.js @@ -11,5 +11,3 @@ class Reads extends React.Component { prevState.p4; } } - -//semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/frameworks/ReactJS/statePropertyWrites.js b/javascript/ql/test/library-tests/frameworks/ReactJS/statePropertyWrites.js index 4f15d9a1b31..692400c7381 100644 --- a/javascript/ql/test/library-tests/frameworks/ReactJS/statePropertyWrites.js +++ b/javascript/ql/test/library-tests/frameworks/ReactJS/statePropertyWrites.js @@ -43,5 +43,3 @@ React.createClass({ }; } }); - -//semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/frameworks/SQL/mssql1.js b/javascript/ql/test/library-tests/frameworks/SQL/mssql1.js index accf4713d71..39a340ccf83 100644 --- a/javascript/ql/test/library-tests/frameworks/SQL/mssql1.js +++ b/javascript/ql/test/library-tests/frameworks/SQL/mssql1.js @@ -10,5 +10,3 @@ async () => { // ... error checks } } - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/library-tests/stmts/conditionals.js b/javascript/ql/test/library-tests/stmts/conditionals.js index 12562b2881f..e21a4299f87 100644 --- a/javascript/ql/test/library-tests/stmts/conditionals.js +++ b/javascript/ql/test/library-tests/stmts/conditionals.js @@ -1,4 +1,4 @@ -if (true) // semmle-extractor-options: --extract-program-text +if (true) ; if (b) ; diff --git a/javascript/ql/test/library-tests/stmts/es2015.js b/javascript/ql/test/library-tests/stmts/es2015.js index 6264c54a04f..09a501be36b 100644 --- a/javascript/ql/test/library-tests/stmts/es2015.js +++ b/javascript/ql/test/library-tests/stmts/es2015.js @@ -1,2 +1,2 @@ -for (var x of [1, 2, 3]) // semmle-extractor-options: --extract-program-text +for (var x of [1, 2, 3]) console.log(x); diff --git a/javascript/ql/test/library-tests/stmts/foreach.js b/javascript/ql/test/library-tests/stmts/foreach.js index ee6fd60e59b..1df30053437 100644 --- a/javascript/ql/test/library-tests/stmts/foreach.js +++ b/javascript/ql/test/library-tests/stmts/foreach.js @@ -6,5 +6,3 @@ for each (var item in obj) { } console.log(sum); // logs "26", which is 5+13+8 - -//semmle-extractor-options: --experimental --extract-program-text diff --git a/javascript/ql/test/library-tests/stmts/functions.js b/javascript/ql/test/library-tests/stmts/functions.js index f1ac615a040..20ecacefad5 100644 --- a/javascript/ql/test/library-tests/stmts/functions.js +++ b/javascript/ql/test/library-tests/stmts/functions.js @@ -1,4 +1,4 @@ -function g(x, y) { // semmle-extractor-options: --extract-program-text +function g(x, y) { return x+y; } diff --git a/javascript/ql/test/library-tests/stmts/guardedCatch.js b/javascript/ql/test/library-tests/stmts/guardedCatch.js index 2c9a24cdb07..0c7b4c2b890 100644 --- a/javascript/ql/test/library-tests/stmts/guardedCatch.js +++ b/javascript/ql/test/library-tests/stmts/guardedCatch.js @@ -7,5 +7,3 @@ function f(g) { console.log("something else!"); } } - -//semmle-extractor-options: --experimental --extract-program-text \ No newline at end of file diff --git a/javascript/ql/test/library-tests/stmts/jscript.js b/javascript/ql/test/library-tests/stmts/jscript.js index 6e281fcec08..0f6a81c8fb3 100644 --- a/javascript/ql/test/library-tests/stmts/jscript.js +++ b/javascript/ql/test/library-tests/stmts/jscript.js @@ -1,5 +1,3 @@ function window::onload() {} window.onload = function onload() {} - -//semmle-extractor-options: --experimental --extract-program-text \ No newline at end of file diff --git a/javascript/ql/test/library-tests/stmts/legacyletstmt.js b/javascript/ql/test/library-tests/stmts/legacyletstmt.js index e88411c12c1..89b5e7505e9 100644 --- a/javascript/ql/test/library-tests/stmts/legacyletstmt.js +++ b/javascript/ql/test/library-tests/stmts/legacyletstmt.js @@ -1,5 +1,3 @@ let (x = 23, y = 19) { console.log(x + y); } - -//semmle-extractor-options: --experimental --extract-program-text \ No newline at end of file diff --git a/javascript/ql/test/library-tests/stmts/loops.js b/javascript/ql/test/library-tests/stmts/loops.js index e2a63b3e3f9..6d424254d74 100644 --- a/javascript/ql/test/library-tests/stmts/loops.js +++ b/javascript/ql/test/library-tests/stmts/loops.js @@ -1,4 +1,4 @@ -while(true) // semmle-extractor-options: --extract-program-text +while(true) ; outer: for(a; b; c) { for(;;) diff --git a/javascript/ql/test/library-tests/stmts/options b/javascript/ql/test/library-tests/stmts/options new file mode 100644 index 00000000000..7b186f72cc5 --- /dev/null +++ b/javascript/ql/test/library-tests/stmts/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental --extract-program-text diff --git a/javascript/ql/test/library-tests/stmts/others.js b/javascript/ql/test/library-tests/stmts/others.js index 58d6c5c1709..3b2a62a47bf 100644 --- a/javascript/ql/test/library-tests/stmts/others.js +++ b/javascript/ql/test/library-tests/stmts/others.js @@ -1,4 +1,4 @@ -with(a) { // semmle-extractor-options: --extract-program-text +with(a) { } debugger; var x = 23, y; \ No newline at end of file diff --git a/javascript/ql/test/library-tests/stmts/tests.expected b/javascript/ql/test/library-tests/stmts/tests.expected index c4632fbc065..75d6f0a24b4 100644 --- a/javascript/ql/test/library-tests/stmts/tests.expected +++ b/javascript/ql/test/library-tests/stmts/tests.expected @@ -4,14 +4,11 @@ test_LetStmt test_LineTerminators | conditionals.js:12:1:12:1 | } | | functions.js:9:1:9:1 | } | -| guardedCatch.js:11:1:11:65 | //semmle-extractor-options: --experimental --extract-program-text | -| jscript.js:5:1:5:65 | //semmle-extractor-options: --experimental --extract-program-text | -| legacyletstmt.js:5:1:5:65 | //semmle-extractor-options: --experimental --extract-program-text | | loops.js:22:1:22:18 | for (x = 0 in xs); | | others.js:4:1:4:14 | var x = 23, y; | | try.js:5:1:5:29 | try {} catch(x) {} finally {} | test_EnclosingStmt -| conditionals.js:1:5:1:8 | true | conditionals.js:1:1:2:5 | if (tru ... t\\n ; | +| conditionals.js:1:5:1:8 | true | conditionals.js:1:1:2:5 | if (true)\\n ; | | conditionals.js:3:5:3:5 | b | conditionals.js:3:1:6:5 | if (b)\\n ... e\\n ; | | conditionals.js:7:9:7:9 | b | conditionals.js:7:1:12:1 | switch ... ault:\\n} | | conditionals.js:8:6:8:7 | 23 | conditionals.js:8:1:8:8 | case 23: | @@ -96,7 +93,7 @@ test_EnclosingStmt | legacyletstmt.js:2:15:2:15 | x | legacyletstmt.js:2:3:2:21 | console.log(x + y); | | legacyletstmt.js:2:15:2:19 | x + y | legacyletstmt.js:2:3:2:21 | console.log(x + y); | | legacyletstmt.js:2:19:2:19 | y | legacyletstmt.js:2:3:2:21 | console.log(x + y); | -| loops.js:1:7:1:10 | true | loops.js:1:1:2:5 | while(t ... t\\n ; | +| loops.js:1:7:1:10 | true | loops.js:1:1:2:5 | while(true)\\n ; | | loops.js:3:1:3:5 | outer | loops.js:3:1:11:1 | outer: ... inue;\\n} | | loops.js:3:12:3:12 | a | loops.js:3:8:11:1 | for(a; ... inue;\\n} | | loops.js:3:15:3:15 | b | loops.js:3:8:11:1 | for(a; ... inue;\\n} | @@ -129,7 +126,7 @@ test_EnclosingStmt | loops.js:22:6:22:6 | x | loops.js:22:1:22:18 | for (x = 0 in xs); | | loops.js:22:10:22:10 | 0 | loops.js:22:1:22:18 | for (x = 0 in xs); | | loops.js:22:15:22:16 | xs | loops.js:22:1:22:18 | for (x = 0 in xs); | -| others.js:1:6:1:6 | a | others.js:1:1:2:1 | with(a) ... -text\\n} | +| others.js:1:6:1:6 | a | others.js:1:1:2:1 | with(a) {\\n} | | others.js:4:5:4:5 | x | others.js:4:1:4:14 | var x = 23, y; | | others.js:4:5:4:10 | x = 23 | others.js:4:1:4:14 | var x = 23, y; | | others.js:4:9:4:10 | 23 | others.js:4:1:4:14 | var x = 23, y; | @@ -140,7 +137,7 @@ test_EnclosingStmt | try.js:5:14:5:14 | x | try.js:5:8:5:18 | catch(x) {} | test_NumCatchClauses | guardedCatch.js:2:2:8:2 | try {\\n\\t ... !");\\n\\t} | 2 | -| try.js:1:1:3:16 | try { / ... ) { ; } | 1 | +| try.js:1:1:3:16 | try {\\n ... ) { ; } | 1 | | try.js:4:1:4:20 | try {} finally { ; } | 0 | | try.js:5:1:5:29 | try {} ... ally {} | 1 | test_DoubleColonMethods @@ -151,7 +148,7 @@ test_SemicolonInsertion test_getGuard | guardedCatch.js:4:4:6:2 | catch ( ... !");\\n\\t} | guardedCatch.js:4:16:4:33 | e instanceof Error | test_Containers -| conditionals.js:1:1:2:5 | if (tru ... t\\n ; | conditionals.js:1:1:12:1 | | +| conditionals.js:1:1:2:5 | if (true)\\n ; | conditionals.js:1:1:12:1 | | | conditionals.js:2:5:2:5 | ; | conditionals.js:1:1:12:1 | | | conditionals.js:3:1:6:5 | if (b)\\n ... e\\n ; | conditionals.js:1:1:12:1 | | | conditionals.js:4:5:4:5 | ; | conditionals.js:1:1:12:1 | | @@ -164,22 +161,22 @@ test_Containers | es2015.js:1:1:2:16 | for (va ... log(x); | es2015.js:1:1:3:0 | | | es2015.js:1:6:1:10 | var x | es2015.js:1:1:3:0 | | | es2015.js:2:2:2:16 | console.log(x); | es2015.js:1:1:3:0 | | -| foreach.js:1:1:1:12 | var sum = 0; | foreach.js:1:1:11:0 | | -| foreach.js:2:1:2:42 | var obj ... p3: 8}; | foreach.js:1:1:11:0 | | -| foreach.js:4:1:6:1 | for eac ... item;\\n} | foreach.js:1:1:11:0 | | -| foreach.js:4:11:4:18 | var item | foreach.js:1:1:11:0 | | -| foreach.js:4:28:6:1 | {\\n sum += item;\\n} | foreach.js:1:1:11:0 | | -| foreach.js:5:3:5:14 | sum += item; | foreach.js:1:1:11:0 | | -| foreach.js:8:1:8:17 | console.log(sum); | foreach.js:1:1:11:0 | | +| foreach.js:1:1:1:12 | var sum = 0; | foreach.js:1:1:9:0 | | +| foreach.js:2:1:2:42 | var obj ... p3: 8}; | foreach.js:1:1:9:0 | | +| foreach.js:4:1:6:1 | for eac ... item;\\n} | foreach.js:1:1:9:0 | | +| foreach.js:4:11:4:18 | var item | foreach.js:1:1:9:0 | | +| foreach.js:4:28:6:1 | {\\n sum += item;\\n} | foreach.js:1:1:9:0 | | +| foreach.js:5:3:5:14 | sum += item; | foreach.js:1:1:9:0 | | +| foreach.js:8:1:8:17 | console.log(sum); | foreach.js:1:1:9:0 | | | functions.js:1:1:3:1 | functio ... x+y;\\n} | functions.js:1:1:9:1 | | -| functions.js:1:18:3:1 | { // se ... x+y;\\n} | functions.js:1:1:3:1 | functio ... x+y;\\n} | +| functions.js:1:18:3:1 | {\\n return x+y;\\n} | functions.js:1:1:3:1 | functio ... x+y;\\n} | | functions.js:2:5:2:15 | return x+y; | functions.js:1:1:3:1 | functio ... x+y;\\n} | | functions.js:5:1:5:15 | function h() {} | functions.js:1:1:9:1 | | | functions.js:5:14:5:15 | {} | functions.js:5:1:5:15 | function h() {} | | functions.js:7:1:9:1 | k = fun ... turn;\\n} | functions.js:1:1:9:1 | | | functions.js:7:16:9:1 | {\\n return;\\n} | functions.js:7:5:9:1 | functio ... turn;\\n} | | functions.js:8:5:8:11 | return; | functions.js:7:5:9:1 | functio ... turn;\\n} | -| guardedCatch.js:1:1:9:1 | functio ... );\\n\\t}\\n} | guardedCatch.js:1:1:11:65 | | +| guardedCatch.js:1:1:9:1 | functio ... );\\n\\t}\\n} | guardedCatch.js:1:1:10:0 | | | guardedCatch.js:1:15:9:1 | {\\n\\ttry ... );\\n\\t}\\n} | guardedCatch.js:1:1:9:1 | functio ... );\\n\\t}\\n} | | guardedCatch.js:2:2:8:2 | try {\\n\\t ... !");\\n\\t} | guardedCatch.js:1:1:9:1 | functio ... );\\n\\t}\\n} | | guardedCatch.js:2:6:4:2 | {\\n\\t\\tg();\\n\\t} | guardedCatch.js:1:1:9:1 | functio ... );\\n\\t}\\n} | @@ -190,14 +187,14 @@ test_Containers | guardedCatch.js:6:4:8:2 | catch ( ... !");\\n\\t} | guardedCatch.js:1:1:9:1 | functio ... );\\n\\t}\\n} | | guardedCatch.js:6:14:8:2 | {\\n\\t\\tcon ... !");\\n\\t} | guardedCatch.js:1:1:9:1 | functio ... );\\n\\t}\\n} | | guardedCatch.js:7:3:7:33 | console ... lse!"); | guardedCatch.js:1:1:9:1 | functio ... );\\n\\t}\\n} | -| jscript.js:1:1:1:28 | functio ... ad() {} | jscript.js:1:1:5:65 | | +| jscript.js:1:1:1:28 | functio ... ad() {} | jscript.js:1:1:4:0 | | | jscript.js:1:27:1:28 | {} | jscript.js:1:1:1:28 | functio ... ad() {} | -| jscript.js:3:1:3:36 | window. ... ad() {} | jscript.js:1:1:5:65 | | +| jscript.js:3:1:3:36 | window. ... ad() {} | jscript.js:1:1:4:0 | | | jscript.js:3:35:3:36 | {} | jscript.js:3:17:3:36 | function onload() {} | -| legacyletstmt.js:1:1:3:1 | let (x ... + y);\\n} | legacyletstmt.js:1:1:5:65 | | -| legacyletstmt.js:1:22:3:1 | {\\n con ... + y);\\n} | legacyletstmt.js:1:1:5:65 | | -| legacyletstmt.js:2:3:2:21 | console.log(x + y); | legacyletstmt.js:1:1:5:65 | | -| loops.js:1:1:2:5 | while(t ... t\\n ; | loops.js:1:1:22:18 | | +| legacyletstmt.js:1:1:3:1 | let (x ... + y);\\n} | legacyletstmt.js:1:1:4:0 | | +| legacyletstmt.js:1:22:3:1 | {\\n con ... + y);\\n} | legacyletstmt.js:1:1:4:0 | | +| legacyletstmt.js:2:3:2:21 | console.log(x + y); | legacyletstmt.js:1:1:4:0 | | +| loops.js:1:1:2:5 | while(true)\\n ; | loops.js:1:1:22:18 | | | loops.js:2:5:2:5 | ; | loops.js:1:1:22:18 | | | loops.js:3:1:11:1 | outer: ... inue;\\n} | loops.js:1:1:22:18 | | | loops.js:3:8:11:1 | for(a; ... inue;\\n} | loops.js:1:1:22:18 | | @@ -223,12 +220,12 @@ test_Containers | loops.js:21:16:21:16 | ; | loops.js:1:1:22:18 | | | loops.js:22:1:22:18 | for (x = 0 in xs); | loops.js:1:1:22:18 | | | loops.js:22:18:22:18 | ; | loops.js:1:1:22:18 | | -| others.js:1:1:2:1 | with(a) ... -text\\n} | others.js:1:1:4:14 | | -| others.js:1:9:2:1 | { // se ... -text\\n} | others.js:1:1:4:14 | | +| others.js:1:1:2:1 | with(a) {\\n} | others.js:1:1:4:14 | | +| others.js:1:9:2:1 | {\\n} | others.js:1:1:4:14 | | | others.js:3:1:3:9 | debugger; | others.js:1:1:4:14 | | | others.js:4:1:4:14 | var x = 23, y; | others.js:1:1:4:14 | | -| try.js:1:1:3:16 | try { / ... ) { ; } | try.js:1:1:5:29 | | -| try.js:1:5:3:1 | { // se ... "!";\\n} | try.js:1:1:5:29 | | +| try.js:1:1:3:16 | try {\\n ... ) { ; } | try.js:1:1:5:29 | | +| try.js:1:5:3:1 | {\\n throw "!";\\n} | try.js:1:1:5:29 | | | try.js:2:5:2:14 | throw "!"; | try.js:1:1:5:29 | | | try.js:3:3:3:16 | catch(x) { ; } | try.js:1:1:5:29 | | | try.js:3:12:3:16 | { ; } | try.js:1:1:5:29 | | diff --git a/javascript/ql/test/library-tests/stmts/try.js b/javascript/ql/test/library-tests/stmts/try.js index 2d82952fbd3..0151114bf84 100644 --- a/javascript/ql/test/library-tests/stmts/try.js +++ b/javascript/ql/test/library-tests/stmts/try.js @@ -1,4 +1,4 @@ -try { // semmle-extractor-options: --extract-program-text +try { throw "!"; } catch(x) { ; } try {} finally { ; } diff --git a/javascript/ql/test/library-tests/variables/getDeclaringContainer.expected b/javascript/ql/test/library-tests/variables/getDeclaringContainer.expected index 158f001459c..bf97e07b559 100644 --- a/javascript/ql/test/library-tests/variables/getDeclaringContainer.expected +++ b/javascript/ql/test/library-tests/variables/getDeclaringContainer.expected @@ -24,7 +24,7 @@ | x | defaultargs.js:3:3:3:25 | functio ... = x) {} | | x | defaultargs.js:4:3:4:51 | functio ... [0]) {} | | x | for.js:1:2:5:1 | functio ... x;\\n} | -| x | legacyletstmt.js:1:1:9:42 | | +| x | legacyletstmt.js:1:1:8:0 | | | x | let.js:1:1:22:0 | | | x | let.js:1:1:22:0 | | | x | let.js:1:1:22:0 | | @@ -36,7 +36,7 @@ | x | variables.js:13:1:23:1 | functio ... z;\\n\\t}\\n} | | y | defaultargs.js:3:3:3:25 | functio ... = x) {} | | y | defaultargs.js:4:3:4:51 | functio ... [0]) {} | -| y | legacyletstmt.js:1:1:9:42 | | +| y | legacyletstmt.js:1:1:8:0 | | | y | let.js:1:1:22:0 | | | y | let.js:14:1:21:1 | functio ... }\\n} | | y | typeoftype.ts:3:3:5:3 | functio ... e x\\n } | diff --git a/javascript/ql/test/library-tests/variables/legacyletstmt.js b/javascript/ql/test/library-tests/variables/legacyletstmt.js index 07531d1cc9c..69beaac8a09 100644 --- a/javascript/ql/test/library-tests/variables/legacyletstmt.js +++ b/javascript/ql/test/library-tests/variables/legacyletstmt.js @@ -5,5 +5,3 @@ let (x = 23, y = 19) { } console.log(x - y); - -//semmle-extractor-options: --experimental \ No newline at end of file diff --git a/javascript/ql/test/library-tests/variables/options b/javascript/ql/test/library-tests/variables/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/library-tests/variables/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/qlpack.yml b/javascript/ql/test/qlpack.yml new file mode 100644 index 00000000000..d40472ed653 --- /dev/null +++ b/javascript/ql/test/qlpack.yml @@ -0,0 +1,3 @@ +name: codeql-javascript-tests +version: 0.0.0 +libraryPathDependencies: codeql-javascript diff --git a/javascript/ql/test/query-tests/AngularJS/DuplicateDependency/options b/javascript/ql/test/query-tests/AngularJS/DuplicateDependency/options new file mode 100644 index 00000000000..13f987b19ca --- /dev/null +++ b/javascript/ql/test/query-tests/AngularJS/DuplicateDependency/options @@ -0,0 +1 @@ +semmle-extractor-options: --tolerate-parse-errors diff --git a/javascript/ql/test/query-tests/DOM/HTML/AmbiguousIdAttribute.html b/javascript/ql/test/query-tests/DOM/HTML/AmbiguousIdAttribute.html index 3277461d787..98a490ec408 100644 --- a/javascript/ql/test/query-tests/DOM/HTML/AmbiguousIdAttribute.html +++ b/javascript/ql/test/query-tests/DOM/HTML/AmbiguousIdAttribute.html @@ -4,5 +4,4 @@
  • First element
  • Second element -semmle-extractor-options: --html elements diff --git a/javascript/ql/test/query-tests/DOM/HTML/AmbiguousIdAttributeGood.html b/javascript/ql/test/query-tests/DOM/HTML/AmbiguousIdAttributeGood.html index 7800cfcd048..bb5969c1f79 100644 --- a/javascript/ql/test/query-tests/DOM/HTML/AmbiguousIdAttributeGood.html +++ b/javascript/ql/test/query-tests/DOM/HTML/AmbiguousIdAttributeGood.html @@ -10,5 +10,4 @@
  • duplicate-class
  • duplicate-class
  • -semmle-extractor-options: --html elements diff --git a/javascript/ql/test/query-tests/DOM/HTML/ConflictingAttributes.html b/javascript/ql/test/query-tests/DOM/HTML/ConflictingAttributes.html index 370337bc7af..92af95c3e3c 100644 --- a/javascript/ql/test/query-tests/DOM/HTML/ConflictingAttributes.html +++ b/javascript/ql/test/query-tests/DOM/HTML/ConflictingAttributes.html @@ -1,2 +1 @@ Semmle -semmle-extractor-options: --html elements diff --git a/javascript/ql/test/query-tests/DOM/HTML/ConflictingAttributesGood.html b/javascript/ql/test/query-tests/DOM/HTML/ConflictingAttributesGood.html index 9b6a94b0e2d..dfe1141a21b 100644 --- a/javascript/ql/test/query-tests/DOM/HTML/ConflictingAttributesGood.html +++ b/javascript/ql/test/query-tests/DOM/HTML/ConflictingAttributesGood.html @@ -1,2 +1 @@ Semmle -semmle-extractor-options: --html elements diff --git a/javascript/ql/test/query-tests/DOM/HTML/DuplicateAttributes.html b/javascript/ql/test/query-tests/DOM/HTML/DuplicateAttributes.html index eedc176211b..a78e3314283 100644 --- a/javascript/ql/test/query-tests/DOM/HTML/DuplicateAttributes.html +++ b/javascript/ql/test/query-tests/DOM/HTML/DuplicateAttributes.html @@ -1,2 +1 @@ Semmle -semmle-extractor-options: --html elements diff --git a/javascript/ql/test/query-tests/DOM/HTML/DuplicateAttributesGood.html b/javascript/ql/test/query-tests/DOM/HTML/DuplicateAttributesGood.html index 9b6a94b0e2d..dfe1141a21b 100644 --- a/javascript/ql/test/query-tests/DOM/HTML/DuplicateAttributesGood.html +++ b/javascript/ql/test/query-tests/DOM/HTML/DuplicateAttributesGood.html @@ -1,2 +1 @@ Semmle -semmle-extractor-options: --html elements diff --git a/javascript/ql/test/query-tests/DOM/HTML/MalformedIdAttribute.html b/javascript/ql/test/query-tests/DOM/HTML/MalformedIdAttribute.html index 666592a7716..9da8fcde502 100644 --- a/javascript/ql/test/query-tests/DOM/HTML/MalformedIdAttribute.html +++ b/javascript/ql/test/query-tests/DOM/HTML/MalformedIdAttribute.html @@ -1,2 +1 @@
    An important heading
    -semmle-extractor-options: --html elements diff --git a/javascript/ql/test/query-tests/DOM/HTML/MalformedIdAttributeGood.html b/javascript/ql/test/query-tests/DOM/HTML/MalformedIdAttributeGood.html index 9a7815efb64..1dfea0491fe 100644 --- a/javascript/ql/test/query-tests/DOM/HTML/MalformedIdAttributeGood.html +++ b/javascript/ql/test/query-tests/DOM/HTML/MalformedIdAttributeGood.html @@ -1,2 +1 @@
    An important heading
    -semmle-extractor-options: --html elements diff --git a/javascript/ql/test/query-tests/DOM/HTML/options b/javascript/ql/test/query-tests/DOM/HTML/options new file mode 100644 index 00000000000..49be7a9261e --- /dev/null +++ b/javascript/ql/test/query-tests/DOM/HTML/options @@ -0,0 +1 @@ +semmle-extractor-options: --html elements diff --git a/javascript/ql/test/query-tests/Declarations/ArgumentsRedefined/externs.js b/javascript/ql/test/query-tests/Declarations/ArgumentsRedefined/externs.js index f91c316b0ed..7824a7ffe02 100644 --- a/javascript/ql/test/query-tests/Declarations/ArgumentsRedefined/externs.js +++ b/javascript/ql/test/query-tests/Declarations/ArgumentsRedefined/externs.js @@ -1,3 +1,3 @@ var arguments; -//semmle-extractor-options: --externs \ No newline at end of file +/** @externs */ \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Declarations/DeadStoreOfGlobal/externs.js b/javascript/ql/test/query-tests/Declarations/DeadStoreOfGlobal/externs.js index d3594220a05..6e79be49a81 100644 --- a/javascript/ql/test/query-tests/Declarations/DeadStoreOfGlobal/externs.js +++ b/javascript/ql/test/query-tests/Declarations/DeadStoreOfGlobal/externs.js @@ -38,4 +38,4 @@ function Worker(opt_arg0) {} */ Worker.prototype.onmessage = function() {}; -//semmle-extractor-options: --externs +/** @externs */ diff --git a/javascript/ql/test/query-tests/Declarations/DeadStoreOfLocal/fields.js b/javascript/ql/test/query-tests/Declarations/DeadStoreOfLocal/fields.js index 6b5cc4cc2d8..22e649c68c6 100644 --- a/javascript/ql/test/query-tests/Declarations/DeadStoreOfLocal/fields.js +++ b/javascript/ql/test/query-tests/Declarations/DeadStoreOfLocal/fields.js @@ -3,5 +3,3 @@ var x = 42; class C { myX = x } - -// semmle-extractor-options: --experimental --source-type module diff --git a/javascript/ql/test/query-tests/Declarations/DeadStoreOfLocal/options b/javascript/ql/test/query-tests/Declarations/DeadStoreOfLocal/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/query-tests/Declarations/DeadStoreOfLocal/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/Declarations/DeadStoreOfProperty/externs.js b/javascript/ql/test/query-tests/Declarations/DeadStoreOfProperty/externs.js index a32e349e56d..11caae4e1b1 100644 --- a/javascript/ql/test/query-tests/Declarations/DeadStoreOfProperty/externs.js +++ b/javascript/ql/test/query-tests/Declarations/DeadStoreOfProperty/externs.js @@ -40,4 +40,4 @@ function Element() {} */ Element.prototype.clientTop; -//semmle-extractor-options: --externs +/** @externs */ diff --git a/javascript/ql/test/query-tests/Declarations/RedeclaredVariable/externs.js b/javascript/ql/test/query-tests/Declarations/RedeclaredVariable/externs.js index 19dd15789e9..0a9eab06996 100644 --- a/javascript/ql/test/query-tests/Declarations/RedeclaredVariable/externs.js +++ b/javascript/ql/test/query-tests/Declarations/RedeclaredVariable/externs.js @@ -2,4 +2,4 @@ var f = function() {}; var f = function(x) {}; -//semmle-extractor-options: --externs \ No newline at end of file +/** @externs */ \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Declarations/RedeclaredVariable/restprops.js b/javascript/ql/test/query-tests/Declarations/RedeclaredVariable/restprops.js index ffab5c80539..44cf825c3cd 100644 --- a/javascript/ql/test/query-tests/Declarations/RedeclaredVariable/restprops.js +++ b/javascript/ql/test/query-tests/Declarations/RedeclaredVariable/restprops.js @@ -1,4 +1,2 @@ var f = ({...p}) => {}; var g = ({...p}) => {}; - -// semmle-extractor-options: --experimental \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Declarations/TooManyParameters/externs.js b/javascript/ql/test/query-tests/Declarations/TooManyParameters/externs.js index a3c8c8999c0..4327b4885f5 100644 --- a/javascript/ql/test/query-tests/Declarations/TooManyParameters/externs.js +++ b/javascript/ql/test/query-tests/Declarations/TooManyParameters/externs.js @@ -1,4 +1,4 @@ // OK: overly long parameter lists in external APIs aren't the fault of the externs definitions function f(a, b, c, d, e, f, g, h) {} -//semmle-extractor-options: --externs \ No newline at end of file +/** @externs */ \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Declarations/UniqueParameterNames/options b/javascript/ql/test/query-tests/Declarations/UniqueParameterNames/options new file mode 100644 index 00000000000..13f987b19ca --- /dev/null +++ b/javascript/ql/test/query-tests/Declarations/UniqueParameterNames/options @@ -0,0 +1 @@ +semmle-extractor-options: --tolerate-parse-errors diff --git a/javascript/ql/test/query-tests/Declarations/UniqueParameterNames/tst.js b/javascript/ql/test/query-tests/Declarations/UniqueParameterNames/tst.js index 2d543e5bf1b..470b14e8300 100644 --- a/javascript/ql/test/query-tests/Declarations/UniqueParameterNames/tst.js +++ b/javascript/ql/test/query-tests/Declarations/UniqueParameterNames/tst.js @@ -12,5 +12,3 @@ this.addPropertyListener(prop.name, function(_, _, _, a) { function f(x, y, x) { 'use strict'; } - -// semmle-extractor-options: --tolerate-parse-errors diff --git a/javascript/ql/test/query-tests/Declarations/UnusedParameter/externs.js b/javascript/ql/test/query-tests/Declarations/UnusedParameter/externs.js index ec8e5c4f6db..9153844b527 100644 --- a/javascript/ql/test/query-tests/Declarations/UnusedParameter/externs.js +++ b/javascript/ql/test/query-tests/Declarations/UnusedParameter/externs.js @@ -1,3 +1,3 @@ function String(str) {} -//semmle-extractor-options: --externs \ No newline at end of file +/** @externs */ \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Declarations/UnusedParameter/restprops.js b/javascript/ql/test/query-tests/Declarations/UnusedParameter/restprops.js index 2a7d8c0b4e5..43b3b2ebfb2 100644 --- a/javascript/ql/test/query-tests/Declarations/UnusedParameter/restprops.js +++ b/javascript/ql/test/query-tests/Declarations/UnusedParameter/restprops.js @@ -1,5 +1,3 @@ function f({ x, ...ys }) { return ys; } - -// semmle-extractor-options: --experimental \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Declarations/UnusedVariable/funbind.js b/javascript/ql/test/query-tests/Declarations/UnusedVariable/funbind.js index b3210a08775..ce0a9ddfd0f 100644 --- a/javascript/ql/test/query-tests/Declarations/UnusedVariable/funbind.js +++ b/javascript/ql/test/query-tests/Declarations/UnusedVariable/funbind.js @@ -2,5 +2,3 @@ function test(bar, e) { let foo = bar; e.target::foo::baz(); } - -// semmle-extractor-options: --experimental \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Declarations/UnusedVariable/options b/javascript/ql/test/query-tests/Declarations/UnusedVariable/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/query-tests/Declarations/UnusedVariable/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/Declarations/UnusedVariable/restprops.js b/javascript/ql/test/query-tests/Declarations/UnusedVariable/restprops.js index d4e6de4b3ba..3f0516d2266 100644 --- a/javascript/ql/test/query-tests/Declarations/UnusedVariable/restprops.js +++ b/javascript/ql/test/query-tests/Declarations/UnusedVariable/restprops.js @@ -2,5 +2,3 @@ function f(o) { let { x, ...ys } = o; return ys; } - -// semmle-extractor-options: --experimental \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/externs.js b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/externs.js index d3fff886259..98a1d68e520 100644 --- a/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/externs.js +++ b/javascript/ql/test/query-tests/Expressions/ExprHasNoEffect/externs.js @@ -53,4 +53,4 @@ function Error() {} */ function SyntaxError() {} -//semmle-extractor-options: --externs +/** @externs */ diff --git a/javascript/ql/test/query-tests/Expressions/HeterogeneousComparison/options b/javascript/ql/test/query-tests/Expressions/HeterogeneousComparison/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/query-tests/Expressions/HeterogeneousComparison/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/Expressions/HeterogeneousComparison/tst.js b/javascript/ql/test/query-tests/Expressions/HeterogeneousComparison/tst.js index 46199104674..f500d4cdafc 100644 --- a/javascript/ql/test/query-tests/Expressions/HeterogeneousComparison/tst.js +++ b/javascript/ql/test/query-tests/Expressions/HeterogeneousComparison/tst.js @@ -232,5 +232,3 @@ function l() { function f(...x) { x === 42 }; - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/Expressions/ImplicitOperandConversion/options b/javascript/ql/test/query-tests/Expressions/ImplicitOperandConversion/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/query-tests/Expressions/ImplicitOperandConversion/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/Expressions/ImplicitOperandConversion/tst.js b/javascript/ql/test/query-tests/Expressions/ImplicitOperandConversion/tst.js index e1ef6f1cdfd..a454ed9bde3 100644 --- a/javascript/ql/test/query-tests/Expressions/ImplicitOperandConversion/tst.js +++ b/javascript/ql/test/query-tests/Expressions/ImplicitOperandConversion/tst.js @@ -107,4 +107,3 @@ function l() { g(); }); -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/Expressions/SelfAssignment/externs.js b/javascript/ql/test/query-tests/Expressions/SelfAssignment/externs.js index 70685e250c1..58b2c99e892 100644 --- a/javascript/ql/test/query-tests/Expressions/SelfAssignment/externs.js +++ b/javascript/ql/test/query-tests/Expressions/SelfAssignment/externs.js @@ -36,4 +36,4 @@ function Element() {} Element.prototype.innerHTML; -// semmle-extractor-options: --externs +/** @externs */ diff --git a/javascript/ql/test/query-tests/Expressions/SelfAssignment/jsdoc.js b/javascript/ql/test/query-tests/Expressions/SelfAssignment/jsdoc.js index 0329cdf038d..03bfc0b5573 100644 --- a/javascript/ql/test/query-tests/Expressions/SelfAssignment/jsdoc.js +++ b/javascript/ql/test/query-tests/Expressions/SelfAssignment/jsdoc.js @@ -11,5 +11,3 @@ class C extends Q { this.arg = this.arg; // NOT OK } } - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/Expressions/ShiftOutOfRange/options b/javascript/ql/test/query-tests/Expressions/ShiftOutOfRange/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/query-tests/Expressions/ShiftOutOfRange/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/Expressions/ShiftOutOfRange/tst.js b/javascript/ql/test/query-tests/Expressions/ShiftOutOfRange/tst.js index 356d0cf57ee..a8cedd993b2 100644 --- a/javascript/ql/test/query-tests/Expressions/ShiftOutOfRange/tst.js +++ b/javascript/ql/test/query-tests/Expressions/ShiftOutOfRange/tst.js @@ -1,4 +1,2 @@ var n = 1<<40; // NOT OK var n2 = BigInt(1) << 40n; // OK - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/Expressions/SuspiciousInvocation/fields.js b/javascript/ql/test/query-tests/Expressions/SuspiciousInvocation/fields.js index 23651d79e6c..01a0c35bc5b 100644 --- a/javascript/ql/test/query-tests/Expressions/SuspiciousInvocation/fields.js +++ b/javascript/ql/test/query-tests/Expressions/SuspiciousInvocation/fields.js @@ -3,5 +3,3 @@ class A { } class B {} - -// semmle-extractor-options: --experimental --source-type module diff --git a/javascript/ql/test/query-tests/Expressions/SuspiciousInvocation/optional-chaining.js b/javascript/ql/test/query-tests/Expressions/SuspiciousInvocation/optional-chaining.js index 2df3535216a..9be73a4dde5 100644 --- a/javascript/ql/test/query-tests/Expressions/SuspiciousInvocation/optional-chaining.js +++ b/javascript/ql/test/query-tests/Expressions/SuspiciousInvocation/optional-chaining.js @@ -7,4 +7,3 @@ b(); b?.(); }); -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/Expressions/SuspiciousInvocation/options b/javascript/ql/test/query-tests/Expressions/SuspiciousInvocation/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/query-tests/Expressions/SuspiciousInvocation/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/Expressions/SuspiciousPropAccess/optional-chaining.js b/javascript/ql/test/query-tests/Expressions/SuspiciousPropAccess/optional-chaining.js index 9f662507227..fa6003ad795 100644 --- a/javascript/ql/test/query-tests/Expressions/SuspiciousPropAccess/optional-chaining.js +++ b/javascript/ql/test/query-tests/Expressions/SuspiciousPropAccess/optional-chaining.js @@ -7,4 +7,3 @@ b.p; b?.p; }); -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/Expressions/SuspiciousPropAccess/options b/javascript/ql/test/query-tests/Expressions/SuspiciousPropAccess/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/query-tests/Expressions/SuspiciousPropAccess/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/Expressions/SuspiciousPropAccess/yield_in_non_generator.js b/javascript/ql/test/query-tests/Expressions/SuspiciousPropAccess/yield_in_non_generator.js index ae0bcba2a23..c0cd2619e81 100644 --- a/javascript/ql/test/query-tests/Expressions/SuspiciousPropAccess/yield_in_non_generator.js +++ b/javascript/ql/test/query-tests/Expressions/SuspiciousPropAccess/yield_in_non_generator.js @@ -4,5 +4,3 @@ function outer() { } inner().next() } - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/Expressions/UnboundEventHandlerReceiver/options b/javascript/ql/test/query-tests/Expressions/UnboundEventHandlerReceiver/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/query-tests/Expressions/UnboundEventHandlerReceiver/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/Expressions/UnboundEventHandlerReceiver/tst.js b/javascript/ql/test/query-tests/Expressions/UnboundEventHandlerReceiver/tst.js index 6733344c3ba..6657556b072 100644 --- a/javascript/ql/test/query-tests/Expressions/UnboundEventHandlerReceiver/tst.js +++ b/javascript/ql/test/query-tests/Expressions/UnboundEventHandlerReceiver/tst.js @@ -172,5 +172,3 @@ class Component4 extends React.Component { this.setState({ }); } } - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/Expressions/UnknownDirective/dual-use.js b/javascript/ql/test/query-tests/Expressions/UnknownDirective/dual-use.js new file mode 100644 index 00000000000..ea0af2e7fd3 --- /dev/null +++ b/javascript/ql/test/query-tests/Expressions/UnknownDirective/dual-use.js @@ -0,0 +1,4 @@ +#!/bin/sh +":" //# ; exec /usr/bin/env node "$0" "$@" + +console.log('javascript'); diff --git a/javascript/ql/test/query-tests/JSDoc/BadParamTag/externs.js b/javascript/ql/test/query-tests/JSDoc/BadParamTag/externs.js index f27d6054e27..433db5a26f4 100644 --- a/javascript/ql/test/query-tests/JSDoc/BadParamTag/externs.js +++ b/javascript/ql/test/query-tests/JSDoc/BadParamTag/externs.js @@ -3,4 +3,4 @@ */ function f(x) {} -//semmle-extractor-options: --externs \ No newline at end of file +/** @externs */ \ No newline at end of file diff --git a/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/foreach.js b/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/foreach.js index 0095642669c..1df30053437 100644 --- a/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/foreach.js +++ b/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/foreach.js @@ -6,5 +6,3 @@ for each (var item in obj) { } console.log(sum); // logs "26", which is 5+13+8 - -//semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/jscript.js b/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/jscript.js index 373939cae64..0f6a81c8fb3 100644 --- a/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/jscript.js +++ b/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/jscript.js @@ -1,5 +1,3 @@ function window::onload() {} window.onload = function onload() {} - -//semmle-extractor-options: --experimental \ No newline at end of file diff --git a/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/letExpr.js b/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/letExpr.js index 51e8fd38fda..a5c7a09b6be 100644 --- a/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/letExpr.js +++ b/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/letExpr.js @@ -3,5 +3,3 @@ var x = 42, y = 19; console.log(let (x = 23, y = 19) x + y); console.log(x - y); - -//semmle-extractor-options: --experimental \ No newline at end of file diff --git a/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/letStmt.js b/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/letStmt.js index 07531d1cc9c..69beaac8a09 100644 --- a/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/letStmt.js +++ b/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/letStmt.js @@ -5,5 +5,3 @@ let (x = 23, y = 19) { } console.log(x - y); - -//semmle-extractor-options: --experimental \ No newline at end of file diff --git a/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/options b/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/postfixComprehension.js b/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/postfixComprehension.js index bb08a86ceec..3cca1b5c615 100644 --- a/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/postfixComprehension.js +++ b/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/postfixComprehension.js @@ -2,5 +2,3 @@ var numbers = [1, 2, 3, 4, 5]; var squares = [i*i for (i of numbers)]; var specialKeyCodes = [for (keyCodeName of Object.keys(SPECIAL_CODES_MAP)) SPECIAL_CODES_MAP[keyCodeName]]; - -//semmle-extractor-options: --experimental \ No newline at end of file diff --git a/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/tst.js b/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/tst.js index dbfeda687e0..202ea2a262a 100644 --- a/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/tst.js +++ b/javascript/ql/test/query-tests/LanguageFeatures/ExpressionClosures/tst.js @@ -6,5 +6,3 @@ // OK [1, 2, 3].map((x) => x * x); - -//semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/LanguageFeatures/ForInComprehensionBlocks/options b/javascript/ql/test/query-tests/LanguageFeatures/ForInComprehensionBlocks/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/query-tests/LanguageFeatures/ForInComprehensionBlocks/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/LanguageFeatures/ForInComprehensionBlocks/tst.js b/javascript/ql/test/query-tests/LanguageFeatures/ForInComprehensionBlocks/tst.js index 30135633974..08542e2be52 100644 --- a/javascript/ql/test/query-tests/LanguageFeatures/ForInComprehensionBlocks/tst.js +++ b/javascript/ql/test/query-tests/LanguageFeatures/ForInComprehensionBlocks/tst.js @@ -1,4 +1,2 @@ var a = [23,,42]; var desc = [for(i in a) i + " = a[" + i + "]"]; - -//semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/LanguageFeatures/IllegalInvocation/tst.js b/javascript/ql/test/query-tests/LanguageFeatures/IllegalInvocation/tst.js index 6a489653379..3ed85a70934 100644 --- a/javascript/ql/test/query-tests/LanguageFeatures/IllegalInvocation/tst.js +++ b/javascript/ql/test/query-tests/LanguageFeatures/IllegalInvocation/tst.js @@ -60,5 +60,3 @@ function invoke(fn) { } invoke(C); invoke(function() {}); - -//semmle-extractor-options: --experimental \ No newline at end of file diff --git a/javascript/ql/test/query-tests/LanguageFeatures/InconsistentNew/externs.js b/javascript/ql/test/query-tests/LanguageFeatures/InconsistentNew/externs.js index c81b555e5aa..0ffbf63dd3f 100644 --- a/javascript/ql/test/query-tests/LanguageFeatures/InconsistentNew/externs.js +++ b/javascript/ql/test/query-tests/LanguageFeatures/InconsistentNew/externs.js @@ -7,4 +7,4 @@ String.prototype.toString = function() {}; function Array() {} Array.prototype.toString = function() {}; -//semmle-extractor-options: --externs \ No newline at end of file +/** @externs */ \ No newline at end of file diff --git a/javascript/ql/test/query-tests/LanguageFeatures/SemicolonInsertion/SemicolonInsertion.expected b/javascript/ql/test/query-tests/LanguageFeatures/SemicolonInsertion/SemicolonInsertion.expected index 81808eb76ba..bab6488e83b 100644 --- a/javascript/ql/test/query-tests/LanguageFeatures/SemicolonInsertion/SemicolonInsertion.expected +++ b/javascript/ql/test/query-tests/LanguageFeatures/SemicolonInsertion/SemicolonInsertion.expected @@ -1,4 +1,4 @@ | export.js:5:8:5:17 | var x = 42 | Avoid automated semicolon insertion (95% of all statements in $@ have an explicit semicolon). | export.js:1:1:29:0 | | the enclosing script | -| jscript.js:3:1:3:36 | window. ... ad() {} | Avoid automated semicolon insertion (95% of all statements in $@ have an explicit semicolon). | jscript.js:1:1:27:42 | | the enclosing script | +| jscript.js:3:1:3:36 | window. ... ad() {} | Avoid automated semicolon insertion (95% of all statements in $@ have an explicit semicolon). | jscript.js:1:1:26:0 | | the enclosing script | | tst.js:5:1:5:3 | var a = ... : 2\\n } | Avoid automated semicolon insertion (91% of all statements in $@ have an explicit semicolon). | tst.js:1:1:42:1 | functio ... oo();\\n} | the enclosing function | | tst.js:7:3:7:10 | return 1 | Avoid automated semicolon insertion (91% of all statements in $@ have an explicit semicolon). | tst.js:1:1:42:1 | functio ... oo();\\n} | the enclosing function | diff --git a/javascript/ql/test/query-tests/LanguageFeatures/SemicolonInsertion/jscript.js b/javascript/ql/test/query-tests/LanguageFeatures/SemicolonInsertion/jscript.js index 66a296a0ae8..5e9b07cf675 100644 --- a/javascript/ql/test/query-tests/LanguageFeatures/SemicolonInsertion/jscript.js +++ b/javascript/ql/test/query-tests/LanguageFeatures/SemicolonInsertion/jscript.js @@ -23,5 +23,3 @@ foo(); foo(); foo(); foo(); - -//semmle-extractor-options: --experimental \ No newline at end of file diff --git a/javascript/ql/test/query-tests/LanguageFeatures/SemicolonInsertion/options b/javascript/ql/test/query-tests/LanguageFeatures/SemicolonInsertion/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/query-tests/LanguageFeatures/SemicolonInsertion/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/LanguageFeatures/SpuriousArguments/externs.js b/javascript/ql/test/query-tests/LanguageFeatures/SpuriousArguments/externs.js index cf8665ea531..c8a88126efb 100644 --- a/javascript/ql/test/query-tests/LanguageFeatures/SpuriousArguments/externs.js +++ b/javascript/ql/test/query-tests/LanguageFeatures/SpuriousArguments/externs.js @@ -39,4 +39,4 @@ function Number() {} Number.parseFloat = function(num) {}; -//semmle-extractor-options: --externs +/** @externs */ diff --git a/javascript/ql/test/query-tests/LanguageFeatures/SyntaxError/options b/javascript/ql/test/query-tests/LanguageFeatures/SyntaxError/options new file mode 100644 index 00000000000..13f987b19ca --- /dev/null +++ b/javascript/ql/test/query-tests/LanguageFeatures/SyntaxError/options @@ -0,0 +1 @@ +semmle-extractor-options: --tolerate-parse-errors diff --git a/javascript/ql/test/query-tests/LanguageFeatures/SyntaxError/tst.js b/javascript/ql/test/query-tests/LanguageFeatures/SyntaxError/tst.js index 2da4e693aeb..e7aaa89f128 100644 --- a/javascript/ql/test/query-tests/LanguageFeatures/SyntaxError/tst.js +++ b/javascript/ql/test/query-tests/LanguageFeatures/SyntaxError/tst.js @@ -1,4 +1,2 @@ function findBox() { return $("box.important - -// semmle-extractor-options: --tolerate-parse-errors diff --git a/javascript/ql/test/query-tests/LanguageFeatures/YieldInNonGenerator/options b/javascript/ql/test/query-tests/LanguageFeatures/YieldInNonGenerator/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/query-tests/LanguageFeatures/YieldInNonGenerator/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/LanguageFeatures/YieldInNonGenerator/tst.js b/javascript/ql/test/query-tests/LanguageFeatures/YieldInNonGenerator/tst.js index 5081e9991d1..a68f3ad35f9 100644 --- a/javascript/ql/test/query-tests/LanguageFeatures/YieldInNonGenerator/tst.js +++ b/javascript/ql/test/query-tests/LanguageFeatures/YieldInNonGenerator/tst.js @@ -4,6 +4,3 @@ function idMaker(){ // NOT OK yield index++; } - -//semmle-extractor-options: --experimental - diff --git a/javascript/ql/test/query-tests/NodeJS/DubiousImport/DubiousImport.expected b/javascript/ql/test/query-tests/NodeJS/DubiousImport/DubiousImport.expected index e28c1641af8..88425eed728 100644 --- a/javascript/ql/test/query-tests/NodeJS/DubiousImport/DubiousImport.expected +++ b/javascript/ql/test/query-tests/NodeJS/DubiousImport/DubiousImport.expected @@ -1,5 +1,5 @@ | a.js:1:11:1:28 | require('./b').foo | Module $@ does not export symbol foo. | b.js:1:1:5:21 | | b | | main.js:5:1:5:5 | b.foo | Module $@ does not export symbol foo. | b.js:1:1:5:21 | | b | | main.js:15:1:15:9 | fs.renmae | Module $@ does not export symbol renmae. | fs.js:1:1:15:0 | | fs | -| main.js:23:1:23:5 | l.bar | Module $@ does not export symbol bar. | l.js:1:1:7:52 | | l | +| main.js:23:1:23:5 | l.bar | Module $@ does not export symbol bar. | l.js:1:1:6:0 | | l | | multi_import.js:16:3:16:10 | mod2.bar | Module $@ does not export symbol bar. | b.js:1:1:5:21 | | b | diff --git a/javascript/ql/test/query-tests/NodeJS/DubiousImport/externs.js b/javascript/ql/test/query-tests/NodeJS/DubiousImport/externs.js index f1cb91159f0..bd8e36c10e3 100644 --- a/javascript/ql/test/query-tests/NodeJS/DubiousImport/externs.js +++ b/javascript/ql/test/query-tests/NodeJS/DubiousImport/externs.js @@ -615,4 +615,4 @@ Array.some = function(arr, callback, opt_context) {}; */ Array.isArray = function(arr) {}; -//semmle-extractor-options: --externs +/** @externs */ diff --git a/javascript/ql/test/query-tests/NodeJS/DubiousImport/f.js b/javascript/ql/test/query-tests/NodeJS/DubiousImport/f.js index 3d097fb8ede..c475ea2262f 100644 --- a/javascript/ql/test/query-tests/NodeJS/DubiousImport/f.js +++ b/javascript/ql/test/query-tests/NodeJS/DubiousImport/f.js @@ -4,5 +4,4 @@ module.exports = me; }(module)); -// semmle-extractor-options: --platform -// semmle-extractor-options: node +require("process"); // ensure this is treated as Node.js code diff --git a/javascript/ql/test/query-tests/NodeJS/DubiousImport/fs-monkeypatch.js b/javascript/ql/test/query-tests/NodeJS/DubiousImport/fs-monkeypatch.js index e4c633ecf31..fefe8f6b2e7 100644 --- a/javascript/ql/test/query-tests/NodeJS/DubiousImport/fs-monkeypatch.js +++ b/javascript/ql/test/query-tests/NodeJS/DubiousImport/fs-monkeypatch.js @@ -2,4 +2,4 @@ var fs = require('fs'); fs.move = fs.rename; -//semmle-extractor-options: --externs +/** @externs */ diff --git a/javascript/ql/test/query-tests/NodeJS/DubiousImport/fs.js b/javascript/ql/test/query-tests/NodeJS/DubiousImport/fs.js index 9fc7f5f1343..7b5e87d891a 100644 --- a/javascript/ql/test/query-tests/NodeJS/DubiousImport/fs.js +++ b/javascript/ql/test/query-tests/NodeJS/DubiousImport/fs.js @@ -11,4 +11,4 @@ fs.rename; module.exports = fs; -//semmle-extractor-options: --externs +/** @externs */ diff --git a/javascript/ql/test/query-tests/NodeJS/DubiousImport/l.js b/javascript/ql/test/query-tests/NodeJS/DubiousImport/l.js index abf7cc4034f..8eb1794ae7b 100644 --- a/javascript/ql/test/query-tests/NodeJS/DubiousImport/l.js +++ b/javascript/ql/test/query-tests/NodeJS/DubiousImport/l.js @@ -3,5 +3,3 @@ class C { } module.exports = C; - -// semmle-extractor-options: --abort-on-parse-errors \ No newline at end of file diff --git a/javascript/ql/test/query-tests/NodeJS/DubiousImport/m.js b/javascript/ql/test/query-tests/NodeJS/DubiousImport/m.js index ac41c9e8511..9e1c24dfecc 100644 --- a/javascript/ql/test/query-tests/NodeJS/DubiousImport/m.js +++ b/javascript/ql/test/query-tests/NodeJS/DubiousImport/m.js @@ -5,5 +5,3 @@ var props = { module.exports = { ...props }; - -// semmle-extractor-options: --experimental \ No newline at end of file diff --git a/javascript/ql/test/query-tests/NodeJS/UnusedDependency/src/other.js b/javascript/ql/test/query-tests/NodeJS/UnusedDependency/src/other.js index 20c9961d626..3b29030a26f 100644 --- a/javascript/ql/test/query-tests/NodeJS/UnusedDependency/src/other.js +++ b/javascript/ql/test/query-tests/NodeJS/UnusedDependency/src/other.js @@ -1,4 +1,2 @@ import hipsterness from 'react'; import curry from 'lodash/function/curry'; - -//semmle-extractor-options: --platform node diff --git a/javascript/ql/test/query-tests/Performance/ReDoS/tst.js b/javascript/ql/test/query-tests/Performance/ReDoS/tst.js index 9d4e7a7b8de..4839b585eb4 100644 --- a/javascript/ql/test/query-tests/Performance/ReDoS/tst.js +++ b/javascript/ql/test/query-tests/Performance/ReDoS/tst.js @@ -84,5 +84,3 @@ var bad16 = /(.|\n)*!/s; // GOOD var good8 = /([\w.]+)*/; - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/React/DirectStateMutation/options b/javascript/ql/test/query-tests/React/DirectStateMutation/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/query-tests/React/DirectStateMutation/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/React/DirectStateMutation/valid9.js b/javascript/ql/test/query-tests/React/DirectStateMutation/valid9.js index f1adc83643f..0d4d465638d 100644 --- a/javascript/ql/test/query-tests/React/DirectStateMutation/valid9.js +++ b/javascript/ql/test/query-tests/React/DirectStateMutation/valid9.js @@ -11,5 +11,3 @@ React.createClass({ }; } }); - -//semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/React/UnusedOrUndefinedStateProperty/issue7506.js b/javascript/ql/test/query-tests/React/UnusedOrUndefinedStateProperty/issue7506.js index 7d5a881389c..f5acdc8d99a 100644 --- a/javascript/ql/test/query-tests/React/UnusedOrUndefinedStateProperty/issue7506.js +++ b/javascript/ql/test/query-tests/React/UnusedOrUndefinedStateProperty/issue7506.js @@ -19,5 +19,3 @@ class C2 extends React.Component { const { p1: p2 } = state } } - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/React/UnusedOrUndefinedStateProperty/options b/javascript/ql/test/query-tests/React/UnusedOrUndefinedStateProperty/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/query-tests/React/UnusedOrUndefinedStateProperty/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/React/UnusedOrUndefinedStateProperty/undefined.js b/javascript/ql/test/query-tests/React/UnusedOrUndefinedStateProperty/undefined.js index dda64bc62e8..6db5702e2fc 100644 --- a/javascript/ql/test/query-tests/React/UnusedOrUndefinedStateProperty/undefined.js +++ b/javascript/ql/test/query-tests/React/UnusedOrUndefinedStateProperty/undefined.js @@ -166,5 +166,3 @@ class C11 extends React.Component { this.state.writeIn_getDerivedStateFromProps; // OK } } - -//semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/React/UnusedOrUndefinedStateProperty/unused.js b/javascript/ql/test/query-tests/React/UnusedOrUndefinedStateProperty/unused.js index e1972ddec1f..d71aa7136da 100644 --- a/javascript/ql/test/query-tests/React/UnusedOrUndefinedStateProperty/unused.js +++ b/javascript/ql/test/query-tests/React/UnusedOrUndefinedStateProperty/unused.js @@ -72,5 +72,3 @@ class C6 extends React.Component { } } - -//semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected index 329d67e627f..ad39e2200be 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected @@ -51,6 +51,8 @@ nodes | TaintedPath-es6.js:7:20:7:26 | req.url | | TaintedPath-es6.js:7:20:7:26 | req.url | | TaintedPath-es6.js:7:20:7:26 | req.url | +| TaintedPath-es6.js:7:20:7:26 | req.url | +| TaintedPath-es6.js:10:26:10:45 | join("public", path) | | TaintedPath-es6.js:10:26:10:45 | join("public", path) | | TaintedPath-es6.js:10:26:10:45 | join("public", path) | | TaintedPath-es6.js:10:26:10:45 | join("public", path) | @@ -135,6 +137,8 @@ nodes | TaintedPath.js:9:24:9:30 | req.url | | TaintedPath.js:9:24:9:30 | req.url | | TaintedPath.js:9:24:9:30 | req.url | +| TaintedPath.js:9:24:9:30 | req.url | +| TaintedPath.js:12:29:12:32 | path | | TaintedPath.js:12:29:12:32 | path | | TaintedPath.js:12:29:12:32 | path | | TaintedPath.js:12:29:12:32 | path | @@ -155,6 +159,7 @@ nodes | TaintedPath.js:15:29:15:48 | "/home/user/" + path | | TaintedPath.js:15:29:15:48 | "/home/user/" + path | | TaintedPath.js:15:29:15:48 | "/home/user/" + path | +| TaintedPath.js:15:29:15:48 | "/home/user/" + path | | TaintedPath.js:15:45:15:48 | path | | TaintedPath.js:15:45:15:48 | path | | TaintedPath.js:15:45:15:48 | path | @@ -171,6 +176,7 @@ nodes | TaintedPath.js:19:33:19:36 | path | | TaintedPath.js:19:33:19:36 | path | | TaintedPath.js:19:33:19:36 | path | +| TaintedPath.js:19:33:19:36 | path | | TaintedPath.js:23:33:23:36 | path | | TaintedPath.js:23:33:23:36 | path | | TaintedPath.js:23:33:23:36 | path | @@ -187,6 +193,8 @@ nodes | TaintedPath.js:23:33:23:36 | path | | TaintedPath.js:23:33:23:36 | path | | TaintedPath.js:23:33:23:36 | path | +| TaintedPath.js:23:33:23:36 | path | +| TaintedPath.js:27:33:27:36 | path | | TaintedPath.js:27:33:27:36 | path | | TaintedPath.js:27:33:27:36 | path | | TaintedPath.js:27:33:27:36 | path | @@ -219,6 +227,7 @@ nodes | TaintedPath.js:31:31:31:34 | path | | TaintedPath.js:31:31:31:34 | path | | TaintedPath.js:31:31:31:34 | path | +| TaintedPath.js:31:31:31:34 | path | | TaintedPath.js:35:31:35:34 | path | | TaintedPath.js:35:31:35:34 | path | | TaintedPath.js:35:31:35:34 | path | @@ -235,6 +244,8 @@ nodes | TaintedPath.js:35:31:35:34 | path | | TaintedPath.js:35:31:35:34 | path | | TaintedPath.js:35:31:35:34 | path | +| TaintedPath.js:35:31:35:34 | path | +| TaintedPath.js:39:31:39:34 | path | | TaintedPath.js:39:31:39:34 | path | | TaintedPath.js:39:31:39:34 | path | | TaintedPath.js:39:31:39:34 | path | @@ -319,6 +330,8 @@ nodes | TaintedPath.js:45:20:45:26 | req.url | | TaintedPath.js:45:20:45:26 | req.url | | TaintedPath.js:45:20:45:26 | req.url | +| TaintedPath.js:45:20:45:26 | req.url | +| TaintedPath.js:49:29:49:52 | pathMod ... e(path) | | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | @@ -359,6 +372,7 @@ nodes | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | +| TaintedPath.js:53:29:53:49 | pathMod ... n(path) | | TaintedPath.js:53:45:53:48 | path | | TaintedPath.js:53:45:53:48 | path | | TaintedPath.js:53:45:53:48 | path | @@ -379,6 +393,7 @@ nodes | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | +| TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | | TaintedPath.js:55:51:55:54 | path | | TaintedPath.js:55:51:55:54 | path | | TaintedPath.js:55:51:55:54 | path | @@ -399,6 +414,7 @@ nodes | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | +| TaintedPath.js:57:29:57:54 | pathMod ... e(path) | | TaintedPath.js:57:50:57:53 | path | | TaintedPath.js:57:50:57:53 | path | | TaintedPath.js:57:50:57:53 | path | @@ -419,6 +435,7 @@ nodes | TaintedPath.js:59:29:59:56 | pathMod ... , path) | | TaintedPath.js:59:29:59:56 | pathMod ... , path) | | TaintedPath.js:59:29:59:56 | pathMod ... , path) | +| TaintedPath.js:59:29:59:56 | pathMod ... , path) | | TaintedPath.js:59:52:59:55 | path | | TaintedPath.js:59:52:59:55 | path | | TaintedPath.js:59:52:59:55 | path | @@ -439,6 +456,7 @@ nodes | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | +| TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | | TaintedPath.js:61:49:61:52 | path | | TaintedPath.js:61:49:61:52 | path | | TaintedPath.js:61:49:61:52 | path | @@ -459,6 +477,7 @@ nodes | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | +| TaintedPath.js:63:29:63:52 | pathMod ... e(path) | | TaintedPath.js:63:48:63:51 | path | | TaintedPath.js:63:48:63:51 | path | | TaintedPath.js:63:48:63:51 | path | @@ -479,6 +498,7 @@ nodes | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | +| TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | | TaintedPath.js:65:54:65:57 | path | | TaintedPath.js:65:54:65:57 | path | | TaintedPath.js:65:54:65:57 | path | @@ -511,6 +531,7 @@ nodes | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | +| TaintedPath.js:67:29:67:61 | pathMod ... h(path) | | TaintedPath.js:67:57:67:60 | path | | TaintedPath.js:67:57:67:60 | path | | TaintedPath.js:67:57:67:60 | path | @@ -531,6 +552,7 @@ nodes | TaintedPath.js:78:26:78:45 | Cookie.get("unsafe") | | TaintedPath.js:78:26:78:45 | Cookie.get("unsafe") | | TaintedPath.js:78:26:78:45 | Cookie.get("unsafe") | +| TaintedPath.js:78:26:78:45 | Cookie.get("unsafe") | | TaintedPath.js:84:31:84:70 | require ... eq.url) | | TaintedPath.js:84:31:84:70 | require ... eq.url) | | TaintedPath.js:84:31:84:70 | require ... eq.url) | @@ -563,6 +585,8 @@ nodes | TaintedPath.js:84:31:84:76 | require ... ).query | | TaintedPath.js:84:31:84:76 | require ... ).query | | TaintedPath.js:84:31:84:76 | require ... ).query | +| TaintedPath.js:84:31:84:76 | require ... ).query | +| TaintedPath.js:84:63:84:69 | req.url | | TaintedPath.js:84:63:84:69 | req.url | | TaintedPath.js:84:63:84:69 | req.url | | TaintedPath.js:84:63:84:69 | req.url | @@ -599,6 +623,8 @@ nodes | TaintedPath.js:85:31:85:74 | require ... ).query | | TaintedPath.js:85:31:85:74 | require ... ).query | | TaintedPath.js:85:31:85:74 | require ... ).query | +| TaintedPath.js:85:31:85:74 | require ... ).query | +| TaintedPath.js:85:61:85:67 | req.url | | TaintedPath.js:85:61:85:67 | req.url | | TaintedPath.js:85:61:85:67 | req.url | | TaintedPath.js:85:61:85:67 | req.url | @@ -635,6 +661,8 @@ nodes | TaintedPath.js:86:31:86:73 | require ... ).query | | TaintedPath.js:86:31:86:73 | require ... ).query | | TaintedPath.js:86:31:86:73 | require ... ).query | +| TaintedPath.js:86:31:86:73 | require ... ).query | +| TaintedPath.js:86:60:86:66 | req.url | | TaintedPath.js:86:60:86:66 | req.url | | TaintedPath.js:86:60:86:66 | req.url | | TaintedPath.js:86:60:86:66 | req.url | @@ -643,6 +671,9 @@ nodes | TaintedPath.js:94:48:94:60 | req.params[0] | | TaintedPath.js:94:48:94:60 | req.params[0] | | TaintedPath.js:94:48:94:60 | req.params[0] | +| TaintedPath.js:94:48:94:60 | req.params[0] | +| TaintedPath.js:94:48:94:60 | req.params[0] | +| TaintedPath.js:102:30:102:31 | ev | | TaintedPath.js:102:30:102:31 | ev | | TaintedPath.js:102:30:102:31 | ev | | TaintedPath.js:102:30:102:31 | ev | @@ -723,6 +754,8 @@ nodes | TaintedPath.js:107:23:107:29 | req.url | | TaintedPath.js:107:23:107:29 | req.url | | TaintedPath.js:107:23:107:29 | req.url | +| TaintedPath.js:107:23:107:29 | req.url | +| TaintedPath.js:109:28:109:48 | fs.real ... c(path) | | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | @@ -767,6 +800,7 @@ nodes | TaintedPath.js:112:45:112:52 | realpath | | TaintedPath.js:112:45:112:52 | realpath | | TaintedPath.js:112:45:112:52 | realpath | +| TaintedPath.js:112:45:112:52 | realpath | | normalizedPaths.js:11:7:11:27 | path | | normalizedPaths.js:11:7:11:27 | path | | normalizedPaths.js:11:7:11:27 | path | @@ -775,10 +809,13 @@ nodes | normalizedPaths.js:11:14:11:27 | req.query.path | | normalizedPaths.js:11:14:11:27 | req.query.path | | normalizedPaths.js:11:14:11:27 | req.query.path | +| normalizedPaths.js:11:14:11:27 | req.query.path | | normalizedPaths.js:13:19:13:22 | path | | normalizedPaths.js:13:19:13:22 | path | | normalizedPaths.js:13:19:13:22 | path | | normalizedPaths.js:13:19:13:22 | path | +| normalizedPaths.js:13:19:13:22 | path | +| normalizedPaths.js:14:19:14:29 | './' + path | | normalizedPaths.js:14:19:14:29 | './' + path | | normalizedPaths.js:14:19:14:29 | './' + path | | normalizedPaths.js:14:19:14:29 | './' + path | @@ -793,6 +830,8 @@ nodes | normalizedPaths.js:15:19:15:38 | path + '/index.html' | | normalizedPaths.js:15:19:15:38 | path + '/index.html' | | normalizedPaths.js:15:19:15:38 | path + '/index.html' | +| normalizedPaths.js:15:19:15:38 | path + '/index.html' | +| normalizedPaths.js:16:19:16:53 | pathMod ... .html') | | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | @@ -804,6 +843,7 @@ nodes | normalizedPaths.js:17:19:17:57 | pathMod ... , path) | | normalizedPaths.js:17:19:17:57 | pathMod ... , path) | | normalizedPaths.js:17:19:17:57 | pathMod ... , path) | +| normalizedPaths.js:17:19:17:57 | pathMod ... , path) | | normalizedPaths.js:17:53:17:56 | path | | normalizedPaths.js:17:53:17:56 | path | | normalizedPaths.js:17:53:17:56 | path | @@ -819,10 +859,13 @@ nodes | normalizedPaths.js:21:35:21:48 | req.query.path | | normalizedPaths.js:21:35:21:48 | req.query.path | | normalizedPaths.js:21:35:21:48 | req.query.path | +| normalizedPaths.js:21:35:21:48 | req.query.path | | normalizedPaths.js:23:19:23:22 | path | | normalizedPaths.js:23:19:23:22 | path | | normalizedPaths.js:23:19:23:22 | path | | normalizedPaths.js:23:19:23:22 | path | +| normalizedPaths.js:23:19:23:22 | path | +| normalizedPaths.js:24:19:24:29 | './' + path | | normalizedPaths.js:24:19:24:29 | './' + path | | normalizedPaths.js:24:19:24:29 | './' + path | | normalizedPaths.js:24:26:24:29 | path | @@ -835,6 +878,8 @@ nodes | normalizedPaths.js:25:19:25:38 | path + '/index.html' | | normalizedPaths.js:25:19:25:38 | path + '/index.html' | | normalizedPaths.js:25:19:25:38 | path + '/index.html' | +| normalizedPaths.js:25:19:25:38 | path + '/index.html' | +| normalizedPaths.js:26:19:26:53 | pathMod ... .html') | | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | @@ -845,6 +890,7 @@ nodes | normalizedPaths.js:26:35:26:38 | path | | normalizedPaths.js:27:19:27:57 | pathMod ... , path) | | normalizedPaths.js:27:19:27:57 | pathMod ... , path) | +| normalizedPaths.js:27:19:27:57 | pathMod ... , path) | | normalizedPaths.js:27:53:27:56 | path | | normalizedPaths.js:27:53:27:56 | path | | normalizedPaths.js:31:7:31:49 | path | @@ -853,8 +899,11 @@ nodes | normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | | normalizedPaths.js:31:35:31:48 | req.query.path | | normalizedPaths.js:31:35:31:48 | req.query.path | +| normalizedPaths.js:31:35:31:48 | req.query.path | | normalizedPaths.js:36:19:36:22 | path | | normalizedPaths.js:36:19:36:22 | path | +| normalizedPaths.js:36:19:36:22 | path | +| normalizedPaths.js:41:21:41:24 | path | | normalizedPaths.js:41:21:41:24 | path | | normalizedPaths.js:41:21:41:24 | path | | normalizedPaths.js:54:7:54:49 | path | @@ -863,12 +912,16 @@ nodes | normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | | normalizedPaths.js:54:35:54:48 | req.query.path | | normalizedPaths.js:54:35:54:48 | req.query.path | +| normalizedPaths.js:54:35:54:48 | req.query.path | +| normalizedPaths.js:59:19:59:22 | path | | normalizedPaths.js:59:19:59:22 | path | | normalizedPaths.js:59:19:59:22 | path | | normalizedPaths.js:63:19:63:22 | path | | normalizedPaths.js:63:19:63:22 | path | | normalizedPaths.js:63:19:63:38 | path + "/index.html" | | normalizedPaths.js:63:19:63:38 | path + "/index.html" | +| normalizedPaths.js:63:19:63:38 | path + "/index.html" | +| normalizedPaths.js:68:21:68:24 | path | | normalizedPaths.js:68:21:68:24 | path | | normalizedPaths.js:68:21:68:24 | path | | normalizedPaths.js:73:7:73:56 | path | @@ -883,6 +936,8 @@ nodes | normalizedPaths.js:73:42:73:55 | req.query.path | | normalizedPaths.js:73:42:73:55 | req.query.path | | normalizedPaths.js:73:42:73:55 | req.query.path | +| normalizedPaths.js:73:42:73:55 | req.query.path | +| normalizedPaths.js:78:22:78:25 | path | | normalizedPaths.js:78:22:78:25 | path | | normalizedPaths.js:78:22:78:25 | path | | normalizedPaths.js:78:22:78:25 | path | @@ -890,8 +945,11 @@ nodes | normalizedPaths.js:82:7:82:27 | path | | normalizedPaths.js:82:14:82:27 | req.query.path | | normalizedPaths.js:82:14:82:27 | req.query.path | +| normalizedPaths.js:82:14:82:27 | req.query.path | | normalizedPaths.js:87:29:87:32 | path | | normalizedPaths.js:87:29:87:32 | path | +| normalizedPaths.js:87:29:87:32 | path | +| normalizedPaths.js:90:31:90:34 | path | | normalizedPaths.js:90:31:90:34 | path | | normalizedPaths.js:94:7:94:49 | path | | normalizedPaths.js:94:7:94:49 | path | @@ -899,6 +957,8 @@ nodes | normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | | normalizedPaths.js:94:35:94:48 | req.query.path | | normalizedPaths.js:94:35:94:48 | req.query.path | +| normalizedPaths.js:94:35:94:48 | req.query.path | +| normalizedPaths.js:99:29:99:32 | path | | normalizedPaths.js:99:29:99:32 | path | | normalizedPaths.js:99:29:99:32 | path | | normalizedPaths.js:117:7:117:44 | path | @@ -913,10 +973,13 @@ nodes | normalizedPaths.js:117:30:117:43 | req.query.path | | normalizedPaths.js:117:30:117:43 | req.query.path | | normalizedPaths.js:117:30:117:43 | req.query.path | +| normalizedPaths.js:117:30:117:43 | req.query.path | | normalizedPaths.js:119:19:119:22 | path | | normalizedPaths.js:119:19:119:22 | path | | normalizedPaths.js:119:19:119:22 | path | | normalizedPaths.js:119:19:119:22 | path | +| normalizedPaths.js:119:19:119:22 | path | +| normalizedPaths.js:120:19:120:53 | pathMod ... .html') | | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | @@ -934,6 +997,8 @@ nodes | normalizedPaths.js:130:35:130:48 | req.query.path | | normalizedPaths.js:130:35:130:48 | req.query.path | | normalizedPaths.js:130:35:130:48 | req.query.path | +| normalizedPaths.js:130:35:130:48 | req.query.path | +| normalizedPaths.js:135:21:135:24 | path | | normalizedPaths.js:135:21:135:24 | path | | normalizedPaths.js:135:21:135:24 | path | | normalizedPaths.js:135:21:135:24 | path | @@ -946,6 +1011,8 @@ nodes | normalizedPaths.js:139:48:139:61 | req.query.path | | normalizedPaths.js:139:48:139:61 | req.query.path | | normalizedPaths.js:139:48:139:61 | req.query.path | +| normalizedPaths.js:139:48:139:61 | req.query.path | +| normalizedPaths.js:144:21:144:24 | path | | normalizedPaths.js:144:21:144:24 | path | | normalizedPaths.js:144:21:144:24 | path | | normalizedPaths.js:144:21:144:24 | path | @@ -957,8 +1024,11 @@ nodes | normalizedPaths.js:148:23:148:58 | pathMod ... y.path) | | normalizedPaths.js:148:44:148:57 | req.query.path | | normalizedPaths.js:148:44:148:57 | req.query.path | +| normalizedPaths.js:148:44:148:57 | req.query.path | | normalizedPaths.js:151:21:151:24 | path | | normalizedPaths.js:151:21:151:24 | path | +| normalizedPaths.js:151:21:151:24 | path | +| normalizedPaths.js:153:21:153:24 | path | | normalizedPaths.js:153:21:153:24 | path | | normalizedPaths.js:153:21:153:24 | path | | normalizedPaths.js:160:7:160:49 | path | @@ -967,8 +1037,11 @@ nodes | normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | | normalizedPaths.js:160:35:160:48 | req.query.path | | normalizedPaths.js:160:35:160:48 | req.query.path | +| normalizedPaths.js:160:35:160:48 | req.query.path | | normalizedPaths.js:165:19:165:22 | path | | normalizedPaths.js:165:19:165:22 | path | +| normalizedPaths.js:165:19:165:22 | path | +| normalizedPaths.js:170:21:170:24 | path | | normalizedPaths.js:170:21:170:24 | path | | normalizedPaths.js:170:21:170:24 | path | | normalizedPaths.js:174:7:174:27 | path | @@ -979,19 +1052,26 @@ nodes | normalizedPaths.js:174:14:174:27 | req.query.path | | normalizedPaths.js:174:14:174:27 | req.query.path | | normalizedPaths.js:174:14:174:27 | req.query.path | +| normalizedPaths.js:174:14:174:27 | req.query.path | +| normalizedPaths.js:184:19:184:22 | path | | normalizedPaths.js:184:19:184:22 | path | | normalizedPaths.js:184:19:184:22 | path | | normalizedPaths.js:184:19:184:22 | path | | normalizedPaths.js:184:19:184:22 | path | | normalizedPaths.js:187:21:187:24 | path | | normalizedPaths.js:187:21:187:24 | path | +| normalizedPaths.js:187:21:187:24 | path | | normalizedPaths.js:189:21:189:24 | path | | normalizedPaths.js:189:21:189:24 | path | +| normalizedPaths.js:189:21:189:24 | path | +| normalizedPaths.js:192:21:192:24 | path | | normalizedPaths.js:192:21:192:24 | path | | normalizedPaths.js:192:21:192:24 | path | | normalizedPaths.js:192:21:192:24 | path | | normalizedPaths.js:192:21:192:24 | path | | normalizedPaths.js:194:21:194:24 | path | +| normalizedPaths.js:194:21:194:24 | path | +| normalizedPaths.js:199:21:199:24 | path | | normalizedPaths.js:199:21:199:24 | path | | normalizedPaths.js:199:21:199:24 | path | | normalizedPaths.js:199:21:199:24 | path | @@ -1012,10 +1092,13 @@ nodes | normalizedPaths.js:205:21:205:34 | normalizedPath | | normalizedPaths.js:205:21:205:34 | normalizedPath | | normalizedPaths.js:205:21:205:34 | normalizedPath | +| normalizedPaths.js:205:21:205:34 | normalizedPath | | normalizedPaths.js:208:21:208:34 | normalizedPath | | normalizedPaths.js:208:21:208:34 | normalizedPath | | normalizedPaths.js:208:21:208:34 | normalizedPath | | normalizedPaths.js:208:21:208:34 | normalizedPath | +| normalizedPaths.js:208:21:208:34 | normalizedPath | +| normalizedPaths.js:210:21:210:34 | normalizedPath | | normalizedPaths.js:210:21:210:34 | normalizedPath | | normalizedPaths.js:210:21:210:34 | normalizedPath | | normalizedPaths.js:210:21:210:34 | normalizedPath | @@ -1032,6 +1115,7 @@ nodes | normalizedPaths.js:214:35:214:48 | req.query.path | | normalizedPaths.js:214:35:214:48 | req.query.path | | normalizedPaths.js:214:35:214:48 | req.query.path | +| normalizedPaths.js:214:35:214:48 | req.query.path | | normalizedPaths.js:219:3:219:33 | path | | normalizedPaths.js:219:3:219:33 | path | | normalizedPaths.js:219:3:219:33 | path | @@ -1048,6 +1132,7 @@ nodes | normalizedPaths.js:222:21:222:24 | path | | normalizedPaths.js:222:21:222:24 | path | | normalizedPaths.js:222:21:222:24 | path | +| normalizedPaths.js:222:21:222:24 | path | | normalizedPaths.js:226:7:226:70 | path | | normalizedPaths.js:226:7:226:70 | path | | normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | @@ -1056,24 +1141,36 @@ nodes | normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | | normalizedPaths.js:226:35:226:48 | req.query.path | | normalizedPaths.js:226:35:226:48 | req.query.path | +| normalizedPaths.js:226:35:226:48 | req.query.path | +| normalizedPaths.js:228:21:228:24 | path | | normalizedPaths.js:228:21:228:24 | path | | normalizedPaths.js:228:21:228:24 | path | | tainted-require.js:7:19:7:37 | req.param("module") | | tainted-require.js:7:19:7:37 | req.param("module") | | tainted-require.js:7:19:7:37 | req.param("module") | | tainted-require.js:7:19:7:37 | req.param("module") | +| tainted-require.js:7:19:7:37 | req.param("module") | +| tainted-require.js:7:19:7:37 | req.param("module") | | tainted-sendFile.js:8:16:8:33 | req.param("gimme") | | tainted-sendFile.js:8:16:8:33 | req.param("gimme") | +| tainted-sendFile.js:8:16:8:33 | req.param("gimme") | +| tainted-sendFile.js:8:16:8:33 | req.param("gimme") | +| tainted-sendFile.js:10:16:10:33 | req.param("gimme") | +| tainted-sendFile.js:10:16:10:33 | req.param("gimme") | | tainted-sendFile.js:10:16:10:33 | req.param("gimme") | | tainted-sendFile.js:10:16:10:33 | req.param("gimme") | | tainted-sendFile.js:18:43:18:58 | req.param("dir") | | tainted-sendFile.js:18:43:18:58 | req.param("dir") | | tainted-sendFile.js:18:43:18:58 | req.param("dir") | | tainted-sendFile.js:18:43:18:58 | req.param("dir") | +| tainted-sendFile.js:18:43:18:58 | req.param("dir") | +| tainted-sendFile.js:18:43:18:58 | req.param("dir") | | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | +| tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | +| tainted-sendFile.js:24:37:24:48 | req.params.x | | tainted-sendFile.js:24:37:24:48 | req.params.x | | tainted-sendFile.js:24:37:24:48 | req.params.x | | tainted-sendFile.js:24:37:24:48 | req.params.x | @@ -1081,9 +1178,13 @@ nodes | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | +| tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | | tainted-sendFile.js:25:34:25:45 | req.params.x | | tainted-sendFile.js:25:34:25:45 | req.params.x | | tainted-sendFile.js:25:34:25:45 | req.params.x | +| tainted-sendFile.js:25:34:25:45 | req.params.x | +| views.js:1:43:1:55 | req.params[0] | +| views.js:1:43:1:55 | req.params[0] | | views.js:1:43:1:55 | req.params[0] | | views.js:1:43:1:55 | req.params[0] | | views.js:1:43:1:55 | req.params[0] | @@ -1149,6 +1250,18 @@ edges | TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | | TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | | TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | +| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | +| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | +| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | +| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | +| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | +| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | +| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | +| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | +| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | +| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | +| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | +| TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:7:14:7:33 | parse(req.url, true) | | TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | | TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | | TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | @@ -1161,6 +1274,34 @@ edges | TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | | TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | | TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | +| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | +| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | +| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | +| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | +| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | +| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | +| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | +| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | +| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | +| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | +| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | +| TaintedPath-es6.js:10:41:10:44 | path | TaintedPath-es6.js:10:26:10:45 | join("public", path) | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:12:29:12:32 | path | @@ -1193,6 +1334,26 @@ edges | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:19:33:19:36 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:19:33:19:36 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:19:33:19:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:19:33:19:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:19:33:19:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:19:33:19:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:19:33:19:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:23:33:23:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:23:33:23:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:23:33:23:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:23:33:23:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:23:33:23:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:23:33:23:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:23:33:23:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:23:33:23:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:23:33:23:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:23:33:23:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:23:33:23:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:23:33:23:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:23:33:23:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:23:33:23:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:23:33:23:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:23:33:23:36 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:23:33:23:36 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:23:33:23:36 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:23:33:23:36 | path | @@ -1225,38 +1386,38 @@ edges | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:27:33:27:36 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:27:33:27:36 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:27:33:27:36 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:30:7:30:24 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:27:33:27:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:27:33:27:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:27:33:27:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:27:33:27:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:27:33:27:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:27:33:27:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:27:33:27:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:27:33:27:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:27:33:27:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:27:33:27:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:27:33:27:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:27:33:27:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:27:33:27:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:27:33:27:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:27:33:27:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:27:33:27:36 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | @@ -1273,102 +1434,6 @@ edges | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:31:31:31:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:5:35:5 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | @@ -1385,102 +1450,38 @@ edges | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:5:39:5 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:35:31:35:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:31:39:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:31:39:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:31:39:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:31:39:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:31:39:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:31:39:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:31:39:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:31:39:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:31:39:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:31:39:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:31:39:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:31:39:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:31:39:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:31:39:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:31:39:34 | path | +| TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:31:39:34 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:31:39:34 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:31:39:34 | path | | TaintedPath.js:9:7:9:48 | path | TaintedPath.js:39:31:39:34 | path | @@ -1561,6 +1562,34 @@ edges | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | +| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | +| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | +| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | +| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | +| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | +| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | +| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | +| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | +| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | +| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | +| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | +| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | +| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | +| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | +| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | +| TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:9:14:9:37 | url.par ... , true) | +| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | +| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | +| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | +| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | +| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | +| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | +| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | +| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | +| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | +| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | +| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | +| TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | | TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | | TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | | TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | @@ -1573,1654 +1602,6 @@ edges | TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | | TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | | TaintedPath.js:15:45:15:48 | path | TaintedPath.js:15:29:15:48 | "/home/user/" + path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:31:31:31:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:31:31:31:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:31:31:31:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:31:31:31:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:31:31:31:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:31:31:31:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:31:31:31:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:31:31:31:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:31:31:31:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:31:31:31:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:31:31:31:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:31:31:31:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:31:31:31:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:31:31:31:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:31:31:31:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:31:31:31:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:3:34:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:30:7:30:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:7:34:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:3:34:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:34:29:34:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:7:34:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:5:35:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:34:29:34:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:35:31:35:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:3:38:3 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:35:5:35:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:7:38:24 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:3:38:3 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:38:29:38:46 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:7:38:24 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:5:39:5 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:38:29:38:46 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:39:5:39:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:39:5:39:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:39:5:39:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:39:5:39:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:39:5:39:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:39:5:39:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:39:5:39:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:39:5:39:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:39:5:39:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:39:5:39:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:39:5:39:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:39:5:39:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:39:5:39:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:39:5:39:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:39:5:39:5 | path | TaintedPath.js:39:31:39:34 | path | -| TaintedPath.js:39:5:39:5 | path | TaintedPath.js:39:31:39:34 | path | | TaintedPath.js:45:3:45:44 | path | TaintedPath.js:49:48:49:51 | path | | TaintedPath.js:45:3:45:44 | path | TaintedPath.js:49:48:49:51 | path | | TaintedPath.js:45:3:45:44 | path | TaintedPath.js:49:48:49:51 | path | @@ -3425,6 +1806,22 @@ edges | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:45:10:45:33 | url.par ... , true) | | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:45:10:45:33 | url.par ... , true) | | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:45:10:45:33 | url.par ... , true) | +| TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:45:10:45:33 | url.par ... , true) | +| TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:45:10:45:33 | url.par ... , true) | +| TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:45:10:45:33 | url.par ... , true) | +| TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:45:10:45:33 | url.par ... , true) | +| TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:45:10:45:33 | url.par ... , true) | +| TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:45:10:45:33 | url.par ... , true) | +| TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:45:10:45:33 | url.par ... , true) | +| TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:45:10:45:33 | url.par ... , true) | +| TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:45:10:45:33 | url.par ... , true) | +| TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:45:10:45:33 | url.par ... , true) | +| TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:45:10:45:33 | url.par ... , true) | +| TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:45:10:45:33 | url.par ... , true) | +| TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:45:10:45:33 | url.par ... , true) | +| TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:45:10:45:33 | url.par ... , true) | +| TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:45:10:45:33 | url.par ... , true) | +| TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:45:10:45:33 | url.par ... , true) | | TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | | TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | | TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | @@ -3441,6 +1838,38 @@ edges | TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | | TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | | TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | +| TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | +| TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | +| TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | +| TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | +| TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | +| TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | +| TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | +| TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | +| TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | +| TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | +| TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | +| TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | +| TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | +| TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | +| TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | +| TaintedPath.js:49:48:49:51 | path | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | +| TaintedPath.js:53:45:53:48 | path | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | +| TaintedPath.js:53:45:53:48 | path | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | +| TaintedPath.js:53:45:53:48 | path | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | +| TaintedPath.js:53:45:53:48 | path | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | +| TaintedPath.js:53:45:53:48 | path | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | +| TaintedPath.js:53:45:53:48 | path | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | +| TaintedPath.js:53:45:53:48 | path | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | +| TaintedPath.js:53:45:53:48 | path | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | +| TaintedPath.js:53:45:53:48 | path | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | +| TaintedPath.js:53:45:53:48 | path | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | +| TaintedPath.js:53:45:53:48 | path | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | +| TaintedPath.js:53:45:53:48 | path | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | +| TaintedPath.js:53:45:53:48 | path | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | +| TaintedPath.js:53:45:53:48 | path | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | +| TaintedPath.js:53:45:53:48 | path | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | +| TaintedPath.js:53:45:53:48 | path | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | | TaintedPath.js:53:45:53:48 | path | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | | TaintedPath.js:53:45:53:48 | path | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | | TaintedPath.js:53:45:53:48 | path | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | @@ -3469,6 +1898,34 @@ edges | TaintedPath.js:55:51:55:54 | path | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | | TaintedPath.js:55:51:55:54 | path | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | | TaintedPath.js:55:51:55:54 | path | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | +| TaintedPath.js:55:51:55:54 | path | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | +| TaintedPath.js:55:51:55:54 | path | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | +| TaintedPath.js:55:51:55:54 | path | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | +| TaintedPath.js:55:51:55:54 | path | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | +| TaintedPath.js:55:51:55:54 | path | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | +| TaintedPath.js:55:51:55:54 | path | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | +| TaintedPath.js:55:51:55:54 | path | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | +| TaintedPath.js:55:51:55:54 | path | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | +| TaintedPath.js:55:51:55:54 | path | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | +| TaintedPath.js:55:51:55:54 | path | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | +| TaintedPath.js:55:51:55:54 | path | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | +| TaintedPath.js:55:51:55:54 | path | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | +| TaintedPath.js:57:50:57:53 | path | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | +| TaintedPath.js:57:50:57:53 | path | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | +| TaintedPath.js:57:50:57:53 | path | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | +| TaintedPath.js:57:50:57:53 | path | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | +| TaintedPath.js:57:50:57:53 | path | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | +| TaintedPath.js:57:50:57:53 | path | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | +| TaintedPath.js:57:50:57:53 | path | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | +| TaintedPath.js:57:50:57:53 | path | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | +| TaintedPath.js:57:50:57:53 | path | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | +| TaintedPath.js:57:50:57:53 | path | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | +| TaintedPath.js:57:50:57:53 | path | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | +| TaintedPath.js:57:50:57:53 | path | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | +| TaintedPath.js:57:50:57:53 | path | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | +| TaintedPath.js:57:50:57:53 | path | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | +| TaintedPath.js:57:50:57:53 | path | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | +| TaintedPath.js:57:50:57:53 | path | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | | TaintedPath.js:57:50:57:53 | path | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | | TaintedPath.js:57:50:57:53 | path | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | | TaintedPath.js:57:50:57:53 | path | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | @@ -3501,6 +1958,38 @@ edges | TaintedPath.js:59:52:59:55 | path | TaintedPath.js:59:29:59:56 | pathMod ... , path) | | TaintedPath.js:59:52:59:55 | path | TaintedPath.js:59:29:59:56 | pathMod ... , path) | | TaintedPath.js:59:52:59:55 | path | TaintedPath.js:59:29:59:56 | pathMod ... , path) | +| TaintedPath.js:59:52:59:55 | path | TaintedPath.js:59:29:59:56 | pathMod ... , path) | +| TaintedPath.js:59:52:59:55 | path | TaintedPath.js:59:29:59:56 | pathMod ... , path) | +| TaintedPath.js:59:52:59:55 | path | TaintedPath.js:59:29:59:56 | pathMod ... , path) | +| TaintedPath.js:59:52:59:55 | path | TaintedPath.js:59:29:59:56 | pathMod ... , path) | +| TaintedPath.js:59:52:59:55 | path | TaintedPath.js:59:29:59:56 | pathMod ... , path) | +| TaintedPath.js:59:52:59:55 | path | TaintedPath.js:59:29:59:56 | pathMod ... , path) | +| TaintedPath.js:59:52:59:55 | path | TaintedPath.js:59:29:59:56 | pathMod ... , path) | +| TaintedPath.js:59:52:59:55 | path | TaintedPath.js:59:29:59:56 | pathMod ... , path) | +| TaintedPath.js:59:52:59:55 | path | TaintedPath.js:59:29:59:56 | pathMod ... , path) | +| TaintedPath.js:59:52:59:55 | path | TaintedPath.js:59:29:59:56 | pathMod ... , path) | +| TaintedPath.js:59:52:59:55 | path | TaintedPath.js:59:29:59:56 | pathMod ... , path) | +| TaintedPath.js:59:52:59:55 | path | TaintedPath.js:59:29:59:56 | pathMod ... , path) | +| TaintedPath.js:59:52:59:55 | path | TaintedPath.js:59:29:59:56 | pathMod ... , path) | +| TaintedPath.js:59:52:59:55 | path | TaintedPath.js:59:29:59:56 | pathMod ... , path) | +| TaintedPath.js:59:52:59:55 | path | TaintedPath.js:59:29:59:56 | pathMod ... , path) | +| TaintedPath.js:59:52:59:55 | path | TaintedPath.js:59:29:59:56 | pathMod ... , path) | +| TaintedPath.js:61:49:61:52 | path | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | +| TaintedPath.js:61:49:61:52 | path | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | +| TaintedPath.js:61:49:61:52 | path | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | +| TaintedPath.js:61:49:61:52 | path | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | +| TaintedPath.js:61:49:61:52 | path | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | +| TaintedPath.js:61:49:61:52 | path | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | +| TaintedPath.js:61:49:61:52 | path | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | +| TaintedPath.js:61:49:61:52 | path | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | +| TaintedPath.js:61:49:61:52 | path | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | +| TaintedPath.js:61:49:61:52 | path | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | +| TaintedPath.js:61:49:61:52 | path | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | +| TaintedPath.js:61:49:61:52 | path | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | +| TaintedPath.js:61:49:61:52 | path | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | +| TaintedPath.js:61:49:61:52 | path | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | +| TaintedPath.js:61:49:61:52 | path | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | +| TaintedPath.js:61:49:61:52 | path | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | | TaintedPath.js:61:49:61:52 | path | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | | TaintedPath.js:61:49:61:52 | path | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | | TaintedPath.js:61:49:61:52 | path | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | @@ -3533,6 +2022,38 @@ edges | TaintedPath.js:63:48:63:51 | path | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | | TaintedPath.js:63:48:63:51 | path | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | | TaintedPath.js:63:48:63:51 | path | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | +| TaintedPath.js:63:48:63:51 | path | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | +| TaintedPath.js:63:48:63:51 | path | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | +| TaintedPath.js:63:48:63:51 | path | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | +| TaintedPath.js:63:48:63:51 | path | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | +| TaintedPath.js:63:48:63:51 | path | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | +| TaintedPath.js:63:48:63:51 | path | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | +| TaintedPath.js:63:48:63:51 | path | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | +| TaintedPath.js:63:48:63:51 | path | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | +| TaintedPath.js:63:48:63:51 | path | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | +| TaintedPath.js:63:48:63:51 | path | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | +| TaintedPath.js:63:48:63:51 | path | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | +| TaintedPath.js:63:48:63:51 | path | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | +| TaintedPath.js:63:48:63:51 | path | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | +| TaintedPath.js:63:48:63:51 | path | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | +| TaintedPath.js:63:48:63:51 | path | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | +| TaintedPath.js:63:48:63:51 | path | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | +| TaintedPath.js:65:54:65:57 | path | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | +| TaintedPath.js:65:54:65:57 | path | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | +| TaintedPath.js:65:54:65:57 | path | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | +| TaintedPath.js:65:54:65:57 | path | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | +| TaintedPath.js:65:54:65:57 | path | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | +| TaintedPath.js:65:54:65:57 | path | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | +| TaintedPath.js:65:54:65:57 | path | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | +| TaintedPath.js:65:54:65:57 | path | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | +| TaintedPath.js:65:54:65:57 | path | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | +| TaintedPath.js:65:54:65:57 | path | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | +| TaintedPath.js:65:54:65:57 | path | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | +| TaintedPath.js:65:54:65:57 | path | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | +| TaintedPath.js:65:54:65:57 | path | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | +| TaintedPath.js:65:54:65:57 | path | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | +| TaintedPath.js:65:54:65:57 | path | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | +| TaintedPath.js:65:54:65:57 | path | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | | TaintedPath.js:65:54:65:57 | path | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | | TaintedPath.js:65:54:65:57 | path | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | | TaintedPath.js:65:54:65:57 | path | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | @@ -3565,6 +2086,38 @@ edges | TaintedPath.js:67:57:67:60 | path | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | | TaintedPath.js:67:57:67:60 | path | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | | TaintedPath.js:67:57:67:60 | path | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | +| TaintedPath.js:67:57:67:60 | path | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | +| TaintedPath.js:67:57:67:60 | path | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | +| TaintedPath.js:67:57:67:60 | path | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | +| TaintedPath.js:67:57:67:60 | path | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | +| TaintedPath.js:67:57:67:60 | path | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | +| TaintedPath.js:67:57:67:60 | path | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | +| TaintedPath.js:67:57:67:60 | path | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | +| TaintedPath.js:67:57:67:60 | path | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | +| TaintedPath.js:67:57:67:60 | path | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | +| TaintedPath.js:67:57:67:60 | path | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | +| TaintedPath.js:67:57:67:60 | path | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | +| TaintedPath.js:67:57:67:60 | path | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | +| TaintedPath.js:67:57:67:60 | path | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | +| TaintedPath.js:67:57:67:60 | path | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | +| TaintedPath.js:67:57:67:60 | path | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | +| TaintedPath.js:67:57:67:60 | path | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | +| TaintedPath.js:84:31:84:70 | require ... eq.url) | TaintedPath.js:84:31:84:76 | require ... ).query | +| TaintedPath.js:84:31:84:70 | require ... eq.url) | TaintedPath.js:84:31:84:76 | require ... ).query | +| TaintedPath.js:84:31:84:70 | require ... eq.url) | TaintedPath.js:84:31:84:76 | require ... ).query | +| TaintedPath.js:84:31:84:70 | require ... eq.url) | TaintedPath.js:84:31:84:76 | require ... ).query | +| TaintedPath.js:84:31:84:70 | require ... eq.url) | TaintedPath.js:84:31:84:76 | require ... ).query | +| TaintedPath.js:84:31:84:70 | require ... eq.url) | TaintedPath.js:84:31:84:76 | require ... ).query | +| TaintedPath.js:84:31:84:70 | require ... eq.url) | TaintedPath.js:84:31:84:76 | require ... ).query | +| TaintedPath.js:84:31:84:70 | require ... eq.url) | TaintedPath.js:84:31:84:76 | require ... ).query | +| TaintedPath.js:84:31:84:70 | require ... eq.url) | TaintedPath.js:84:31:84:76 | require ... ).query | +| TaintedPath.js:84:31:84:70 | require ... eq.url) | TaintedPath.js:84:31:84:76 | require ... ).query | +| TaintedPath.js:84:31:84:70 | require ... eq.url) | TaintedPath.js:84:31:84:76 | require ... ).query | +| TaintedPath.js:84:31:84:70 | require ... eq.url) | TaintedPath.js:84:31:84:76 | require ... ).query | +| TaintedPath.js:84:31:84:70 | require ... eq.url) | TaintedPath.js:84:31:84:76 | require ... ).query | +| TaintedPath.js:84:31:84:70 | require ... eq.url) | TaintedPath.js:84:31:84:76 | require ... ).query | +| TaintedPath.js:84:31:84:70 | require ... eq.url) | TaintedPath.js:84:31:84:76 | require ... ).query | +| TaintedPath.js:84:31:84:70 | require ... eq.url) | TaintedPath.js:84:31:84:76 | require ... ).query | | TaintedPath.js:84:31:84:70 | require ... eq.url) | TaintedPath.js:84:31:84:76 | require ... ).query | | TaintedPath.js:84:31:84:70 | require ... eq.url) | TaintedPath.js:84:31:84:76 | require ... ).query | | TaintedPath.js:84:31:84:70 | require ... eq.url) | TaintedPath.js:84:31:84:76 | require ... ).query | @@ -3597,6 +2150,38 @@ edges | TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:70 | require ... eq.url) | | TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:70 | require ... eq.url) | | TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:70 | require ... eq.url) | +| TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:70 | require ... eq.url) | +| TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:70 | require ... eq.url) | +| TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:70 | require ... eq.url) | +| TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:70 | require ... eq.url) | +| TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:70 | require ... eq.url) | +| TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:70 | require ... eq.url) | +| TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:70 | require ... eq.url) | +| TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:70 | require ... eq.url) | +| TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:70 | require ... eq.url) | +| TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:70 | require ... eq.url) | +| TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:70 | require ... eq.url) | +| TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:70 | require ... eq.url) | +| TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:70 | require ... eq.url) | +| TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:70 | require ... eq.url) | +| TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:70 | require ... eq.url) | +| TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:70 | require ... eq.url) | +| TaintedPath.js:85:31:85:68 | require ... eq.url) | TaintedPath.js:85:31:85:74 | require ... ).query | +| TaintedPath.js:85:31:85:68 | require ... eq.url) | TaintedPath.js:85:31:85:74 | require ... ).query | +| TaintedPath.js:85:31:85:68 | require ... eq.url) | TaintedPath.js:85:31:85:74 | require ... ).query | +| TaintedPath.js:85:31:85:68 | require ... eq.url) | TaintedPath.js:85:31:85:74 | require ... ).query | +| TaintedPath.js:85:31:85:68 | require ... eq.url) | TaintedPath.js:85:31:85:74 | require ... ).query | +| TaintedPath.js:85:31:85:68 | require ... eq.url) | TaintedPath.js:85:31:85:74 | require ... ).query | +| TaintedPath.js:85:31:85:68 | require ... eq.url) | TaintedPath.js:85:31:85:74 | require ... ).query | +| TaintedPath.js:85:31:85:68 | require ... eq.url) | TaintedPath.js:85:31:85:74 | require ... ).query | +| TaintedPath.js:85:31:85:68 | require ... eq.url) | TaintedPath.js:85:31:85:74 | require ... ).query | +| TaintedPath.js:85:31:85:68 | require ... eq.url) | TaintedPath.js:85:31:85:74 | require ... ).query | +| TaintedPath.js:85:31:85:68 | require ... eq.url) | TaintedPath.js:85:31:85:74 | require ... ).query | +| TaintedPath.js:85:31:85:68 | require ... eq.url) | TaintedPath.js:85:31:85:74 | require ... ).query | +| TaintedPath.js:85:31:85:68 | require ... eq.url) | TaintedPath.js:85:31:85:74 | require ... ).query | +| TaintedPath.js:85:31:85:68 | require ... eq.url) | TaintedPath.js:85:31:85:74 | require ... ).query | +| TaintedPath.js:85:31:85:68 | require ... eq.url) | TaintedPath.js:85:31:85:74 | require ... ).query | +| TaintedPath.js:85:31:85:68 | require ... eq.url) | TaintedPath.js:85:31:85:74 | require ... ).query | | TaintedPath.js:85:31:85:68 | require ... eq.url) | TaintedPath.js:85:31:85:74 | require ... ).query | | TaintedPath.js:85:31:85:68 | require ... eq.url) | TaintedPath.js:85:31:85:74 | require ... ).query | | TaintedPath.js:85:31:85:68 | require ... eq.url) | TaintedPath.js:85:31:85:74 | require ... ).query | @@ -3629,6 +2214,38 @@ edges | TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:68 | require ... eq.url) | | TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:68 | require ... eq.url) | | TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:68 | require ... eq.url) | +| TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:68 | require ... eq.url) | +| TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:68 | require ... eq.url) | +| TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:68 | require ... eq.url) | +| TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:68 | require ... eq.url) | +| TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:68 | require ... eq.url) | +| TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:68 | require ... eq.url) | +| TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:68 | require ... eq.url) | +| TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:68 | require ... eq.url) | +| TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:68 | require ... eq.url) | +| TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:68 | require ... eq.url) | +| TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:68 | require ... eq.url) | +| TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:68 | require ... eq.url) | +| TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:68 | require ... eq.url) | +| TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:68 | require ... eq.url) | +| TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:68 | require ... eq.url) | +| TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:68 | require ... eq.url) | +| TaintedPath.js:86:31:86:67 | require ... eq.url) | TaintedPath.js:86:31:86:73 | require ... ).query | +| TaintedPath.js:86:31:86:67 | require ... eq.url) | TaintedPath.js:86:31:86:73 | require ... ).query | +| TaintedPath.js:86:31:86:67 | require ... eq.url) | TaintedPath.js:86:31:86:73 | require ... ).query | +| TaintedPath.js:86:31:86:67 | require ... eq.url) | TaintedPath.js:86:31:86:73 | require ... ).query | +| TaintedPath.js:86:31:86:67 | require ... eq.url) | TaintedPath.js:86:31:86:73 | require ... ).query | +| TaintedPath.js:86:31:86:67 | require ... eq.url) | TaintedPath.js:86:31:86:73 | require ... ).query | +| TaintedPath.js:86:31:86:67 | require ... eq.url) | TaintedPath.js:86:31:86:73 | require ... ).query | +| TaintedPath.js:86:31:86:67 | require ... eq.url) | TaintedPath.js:86:31:86:73 | require ... ).query | +| TaintedPath.js:86:31:86:67 | require ... eq.url) | TaintedPath.js:86:31:86:73 | require ... ).query | +| TaintedPath.js:86:31:86:67 | require ... eq.url) | TaintedPath.js:86:31:86:73 | require ... ).query | +| TaintedPath.js:86:31:86:67 | require ... eq.url) | TaintedPath.js:86:31:86:73 | require ... ).query | +| TaintedPath.js:86:31:86:67 | require ... eq.url) | TaintedPath.js:86:31:86:73 | require ... ).query | +| TaintedPath.js:86:31:86:67 | require ... eq.url) | TaintedPath.js:86:31:86:73 | require ... ).query | +| TaintedPath.js:86:31:86:67 | require ... eq.url) | TaintedPath.js:86:31:86:73 | require ... ).query | +| TaintedPath.js:86:31:86:67 | require ... eq.url) | TaintedPath.js:86:31:86:73 | require ... ).query | +| TaintedPath.js:86:31:86:67 | require ... eq.url) | TaintedPath.js:86:31:86:73 | require ... ).query | | TaintedPath.js:86:31:86:67 | require ... eq.url) | TaintedPath.js:86:31:86:73 | require ... ).query | | TaintedPath.js:86:31:86:67 | require ... eq.url) | TaintedPath.js:86:31:86:73 | require ... ).query | | TaintedPath.js:86:31:86:67 | require ... eq.url) | TaintedPath.js:86:31:86:73 | require ... ).query | @@ -3661,6 +2278,27 @@ edges | TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:67 | require ... eq.url) | | TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:67 | require ... eq.url) | | TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:67 | require ... eq.url) | +| TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:67 | require ... eq.url) | +| TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:67 | require ... eq.url) | +| TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:67 | require ... eq.url) | +| TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:67 | require ... eq.url) | +| TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:67 | require ... eq.url) | +| TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:67 | require ... eq.url) | +| TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:67 | require ... eq.url) | +| TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:67 | require ... eq.url) | +| TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:67 | require ... eq.url) | +| TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:67 | require ... eq.url) | +| TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:67 | require ... eq.url) | +| TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:67 | require ... eq.url) | +| TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:67 | require ... eq.url) | +| TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:67 | require ... eq.url) | +| TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:67 | require ... eq.url) | +| TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:67 | require ... eq.url) | +| TaintedPath.js:94:48:94:60 | req.params[0] | TaintedPath.js:94:48:94:60 | req.params[0] | +| TaintedPath.js:102:30:102:31 | ev | TaintedPath.js:103:24:103:25 | ev | +| TaintedPath.js:102:30:102:31 | ev | TaintedPath.js:103:24:103:25 | ev | +| TaintedPath.js:102:30:102:31 | ev | TaintedPath.js:103:24:103:25 | ev | +| TaintedPath.js:102:30:102:31 | ev | TaintedPath.js:103:24:103:25 | ev | | TaintedPath.js:102:30:102:31 | ev | TaintedPath.js:103:24:103:25 | ev | | TaintedPath.js:102:30:102:31 | ev | TaintedPath.js:103:24:103:25 | ev | | TaintedPath.js:102:30:102:31 | ev | TaintedPath.js:103:24:103:25 | ev | @@ -3673,6 +2311,10 @@ edges | TaintedPath.js:103:24:103:30 | ev.data | TaintedPath.js:78:26:78:45 | Cookie.get("unsafe") | | TaintedPath.js:103:24:103:30 | ev.data | TaintedPath.js:78:26:78:45 | Cookie.get("unsafe") | | TaintedPath.js:103:24:103:30 | ev.data | TaintedPath.js:78:26:78:45 | Cookie.get("unsafe") | +| TaintedPath.js:103:24:103:30 | ev.data | TaintedPath.js:78:26:78:45 | Cookie.get("unsafe") | +| TaintedPath.js:103:24:103:30 | ev.data | TaintedPath.js:78:26:78:45 | Cookie.get("unsafe") | +| TaintedPath.js:103:24:103:30 | ev.data | TaintedPath.js:78:26:78:45 | Cookie.get("unsafe") | +| TaintedPath.js:103:24:103:30 | ev.data | TaintedPath.js:78:26:78:45 | Cookie.get("unsafe") | | TaintedPath.js:107:6:107:47 | path | TaintedPath.js:109:44:109:47 | path | | TaintedPath.js:107:6:107:47 | path | TaintedPath.js:109:44:109:47 | path | | TaintedPath.js:107:6:107:47 | path | TaintedPath.js:109:44:109:47 | path | @@ -3769,6 +2411,38 @@ edges | TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:107:13:107:36 | url.par ... , true) | | TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:107:13:107:36 | url.par ... , true) | | TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:107:13:107:36 | url.par ... , true) | +| TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:107:13:107:36 | url.par ... , true) | +| TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:107:13:107:36 | url.par ... , true) | +| TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:107:13:107:36 | url.par ... , true) | +| TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:107:13:107:36 | url.par ... , true) | +| TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:107:13:107:36 | url.par ... , true) | +| TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:107:13:107:36 | url.par ... , true) | +| TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:107:13:107:36 | url.par ... , true) | +| TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:107:13:107:36 | url.par ... , true) | +| TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:107:13:107:36 | url.par ... , true) | +| TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:107:13:107:36 | url.par ... , true) | +| TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:107:13:107:36 | url.par ... , true) | +| TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:107:13:107:36 | url.par ... , true) | +| TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:107:13:107:36 | url.par ... , true) | +| TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:107:13:107:36 | url.par ... , true) | +| TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:107:13:107:36 | url.par ... , true) | +| TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:107:13:107:36 | url.par ... , true) | +| TaintedPath.js:109:44:109:47 | path | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | +| TaintedPath.js:109:44:109:47 | path | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | +| TaintedPath.js:109:44:109:47 | path | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | +| TaintedPath.js:109:44:109:47 | path | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | +| TaintedPath.js:109:44:109:47 | path | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | +| TaintedPath.js:109:44:109:47 | path | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | +| TaintedPath.js:109:44:109:47 | path | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | +| TaintedPath.js:109:44:109:47 | path | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | +| TaintedPath.js:109:44:109:47 | path | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | +| TaintedPath.js:109:44:109:47 | path | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | +| TaintedPath.js:109:44:109:47 | path | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | +| TaintedPath.js:109:44:109:47 | path | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | +| TaintedPath.js:109:44:109:47 | path | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | +| TaintedPath.js:109:44:109:47 | path | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | +| TaintedPath.js:109:44:109:47 | path | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | +| TaintedPath.js:109:44:109:47 | path | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | | TaintedPath.js:109:44:109:47 | path | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | | TaintedPath.js:109:44:109:47 | path | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | | TaintedPath.js:109:44:109:47 | path | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | @@ -3805,6 +2479,14 @@ edges | TaintedPath.js:111:32:111:39 | realpath | TaintedPath.js:112:45:112:52 | realpath | | TaintedPath.js:111:32:111:39 | realpath | TaintedPath.js:112:45:112:52 | realpath | | TaintedPath.js:111:32:111:39 | realpath | TaintedPath.js:112:45:112:52 | realpath | +| TaintedPath.js:111:32:111:39 | realpath | TaintedPath.js:112:45:112:52 | realpath | +| TaintedPath.js:111:32:111:39 | realpath | TaintedPath.js:112:45:112:52 | realpath | +| TaintedPath.js:111:32:111:39 | realpath | TaintedPath.js:112:45:112:52 | realpath | +| TaintedPath.js:111:32:111:39 | realpath | TaintedPath.js:112:45:112:52 | realpath | +| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path | +| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path | +| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path | +| normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path | | normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path | | normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path | | normalizedPaths.js:11:7:11:27 | path | normalizedPaths.js:13:19:13:22 | path | @@ -3827,6 +2509,13 @@ edges | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:11:7:11:27 | path | | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:11:7:11:27 | path | | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:11:7:11:27 | path | +| normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:11:7:11:27 | path | +| normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:11:7:11:27 | path | +| normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:11:7:11:27 | path | +| normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:11:7:11:27 | path | +| normalizedPaths.js:14:26:14:29 | path | normalizedPaths.js:14:19:14:29 | './' + path | +| normalizedPaths.js:14:26:14:29 | path | normalizedPaths.js:14:19:14:29 | './' + path | +| normalizedPaths.js:14:26:14:29 | path | normalizedPaths.js:14:19:14:29 | './' + path | | normalizedPaths.js:14:26:14:29 | path | normalizedPaths.js:14:19:14:29 | './' + path | | normalizedPaths.js:14:26:14:29 | path | normalizedPaths.js:14:19:14:29 | './' + path | | normalizedPaths.js:14:26:14:29 | path | normalizedPaths.js:14:19:14:29 | './' + path | @@ -3834,6 +2523,14 @@ edges | normalizedPaths.js:15:19:15:22 | path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | | normalizedPaths.js:15:19:15:22 | path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | | normalizedPaths.js:15:19:15:22 | path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | +| normalizedPaths.js:15:19:15:22 | path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | +| normalizedPaths.js:15:19:15:22 | path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | +| normalizedPaths.js:15:19:15:22 | path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | +| normalizedPaths.js:15:19:15:22 | path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | +| normalizedPaths.js:16:35:16:38 | path | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | +| normalizedPaths.js:16:35:16:38 | path | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | +| normalizedPaths.js:16:35:16:38 | path | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | +| normalizedPaths.js:16:35:16:38 | path | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | | normalizedPaths.js:16:35:16:38 | path | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | | normalizedPaths.js:16:35:16:38 | path | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | | normalizedPaths.js:16:35:16:38 | path | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | @@ -3841,6 +2538,13 @@ edges | normalizedPaths.js:17:53:17:56 | path | normalizedPaths.js:17:19:17:57 | pathMod ... , path) | | normalizedPaths.js:17:53:17:56 | path | normalizedPaths.js:17:19:17:57 | pathMod ... , path) | | normalizedPaths.js:17:53:17:56 | path | normalizedPaths.js:17:19:17:57 | pathMod ... , path) | +| normalizedPaths.js:17:53:17:56 | path | normalizedPaths.js:17:19:17:57 | pathMod ... , path) | +| normalizedPaths.js:17:53:17:56 | path | normalizedPaths.js:17:19:17:57 | pathMod ... , path) | +| normalizedPaths.js:17:53:17:56 | path | normalizedPaths.js:17:19:17:57 | pathMod ... , path) | +| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:23:19:23:22 | path | +| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:23:19:23:22 | path | +| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:23:19:23:22 | path | +| normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:23:19:23:22 | path | | normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:23:19:23:22 | path | | normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:23:19:23:22 | path | | normalizedPaths.js:21:7:21:49 | path | normalizedPaths.js:23:19:23:22 | path | @@ -3865,41 +2569,74 @@ edges | normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | | normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | | normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | +| normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | +| normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | +| normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | +| normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:21:14:21:49 | pathMod ... y.path) | +| normalizedPaths.js:24:26:24:29 | path | normalizedPaths.js:24:19:24:29 | './' + path | +| normalizedPaths.js:24:26:24:29 | path | normalizedPaths.js:24:19:24:29 | './' + path | | normalizedPaths.js:24:26:24:29 | path | normalizedPaths.js:24:19:24:29 | './' + path | | normalizedPaths.js:24:26:24:29 | path | normalizedPaths.js:24:19:24:29 | './' + path | | normalizedPaths.js:25:19:25:22 | path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | | normalizedPaths.js:25:19:25:22 | path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | | normalizedPaths.js:25:19:25:22 | path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | | normalizedPaths.js:25:19:25:22 | path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | +| normalizedPaths.js:25:19:25:22 | path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | +| normalizedPaths.js:25:19:25:22 | path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | +| normalizedPaths.js:25:19:25:22 | path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | +| normalizedPaths.js:25:19:25:22 | path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | +| normalizedPaths.js:26:35:26:38 | path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | +| normalizedPaths.js:26:35:26:38 | path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | +| normalizedPaths.js:26:35:26:38 | path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | +| normalizedPaths.js:26:35:26:38 | path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | | normalizedPaths.js:26:35:26:38 | path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | | normalizedPaths.js:26:35:26:38 | path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | | normalizedPaths.js:26:35:26:38 | path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | | normalizedPaths.js:26:35:26:38 | path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | | normalizedPaths.js:27:53:27:56 | path | normalizedPaths.js:27:19:27:57 | pathMod ... , path) | | normalizedPaths.js:27:53:27:56 | path | normalizedPaths.js:27:19:27:57 | pathMod ... , path) | +| normalizedPaths.js:27:53:27:56 | path | normalizedPaths.js:27:19:27:57 | pathMod ... , path) | +| normalizedPaths.js:27:53:27:56 | path | normalizedPaths.js:27:19:27:57 | pathMod ... , path) | | normalizedPaths.js:31:7:31:49 | path | normalizedPaths.js:36:19:36:22 | path | | normalizedPaths.js:31:7:31:49 | path | normalizedPaths.js:36:19:36:22 | path | +| normalizedPaths.js:31:7:31:49 | path | normalizedPaths.js:36:19:36:22 | path | +| normalizedPaths.js:31:7:31:49 | path | normalizedPaths.js:36:19:36:22 | path | +| normalizedPaths.js:31:7:31:49 | path | normalizedPaths.js:41:21:41:24 | path | +| normalizedPaths.js:31:7:31:49 | path | normalizedPaths.js:41:21:41:24 | path | | normalizedPaths.js:31:7:31:49 | path | normalizedPaths.js:41:21:41:24 | path | | normalizedPaths.js:31:7:31:49 | path | normalizedPaths.js:41:21:41:24 | path | | normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | normalizedPaths.js:31:7:31:49 | path | | normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | normalizedPaths.js:31:7:31:49 | path | | normalizedPaths.js:31:35:31:48 | req.query.path | normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | | normalizedPaths.js:31:35:31:48 | req.query.path | normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | +| normalizedPaths.js:31:35:31:48 | req.query.path | normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | +| normalizedPaths.js:31:35:31:48 | req.query.path | normalizedPaths.js:31:14:31:49 | pathMod ... y.path) | +| normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:59:19:59:22 | path | +| normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:59:19:59:22 | path | | normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:59:19:59:22 | path | | normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:59:19:59:22 | path | | normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:63:19:63:22 | path | | normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:63:19:63:22 | path | | normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:68:21:68:24 | path | | normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:68:21:68:24 | path | +| normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:68:21:68:24 | path | +| normalizedPaths.js:54:7:54:49 | path | normalizedPaths.js:68:21:68:24 | path | | normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | normalizedPaths.js:54:7:54:49 | path | | normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | normalizedPaths.js:54:7:54:49 | path | | normalizedPaths.js:54:35:54:48 | req.query.path | normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | | normalizedPaths.js:54:35:54:48 | req.query.path | normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | +| normalizedPaths.js:54:35:54:48 | req.query.path | normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | +| normalizedPaths.js:54:35:54:48 | req.query.path | normalizedPaths.js:54:14:54:49 | pathMod ... y.path) | +| normalizedPaths.js:63:19:63:22 | path | normalizedPaths.js:63:19:63:38 | path + "/index.html" | +| normalizedPaths.js:63:19:63:22 | path | normalizedPaths.js:63:19:63:38 | path + "/index.html" | | normalizedPaths.js:63:19:63:22 | path | normalizedPaths.js:63:19:63:38 | path + "/index.html" | | normalizedPaths.js:63:19:63:22 | path | normalizedPaths.js:63:19:63:38 | path + "/index.html" | | normalizedPaths.js:73:7:73:56 | path | normalizedPaths.js:78:22:78:25 | path | | normalizedPaths.js:73:7:73:56 | path | normalizedPaths.js:78:22:78:25 | path | | normalizedPaths.js:73:7:73:56 | path | normalizedPaths.js:78:22:78:25 | path | +| normalizedPaths.js:73:7:73:56 | path | normalizedPaths.js:78:22:78:25 | path | +| normalizedPaths.js:73:7:73:56 | path | normalizedPaths.js:78:22:78:25 | path | +| normalizedPaths.js:73:7:73:56 | path | normalizedPaths.js:78:22:78:25 | path | | normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | normalizedPaths.js:73:7:73:56 | path | | normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | normalizedPaths.js:73:7:73:56 | path | | normalizedPaths.js:73:14:73:56 | pathMod ... y.path) | normalizedPaths.js:73:7:73:56 | path | @@ -3909,17 +2646,33 @@ edges | normalizedPaths.js:73:42:73:55 | req.query.path | normalizedPaths.js:73:35:73:55 | './' + ... ry.path | | normalizedPaths.js:73:42:73:55 | req.query.path | normalizedPaths.js:73:35:73:55 | './' + ... ry.path | | normalizedPaths.js:73:42:73:55 | req.query.path | normalizedPaths.js:73:35:73:55 | './' + ... ry.path | +| normalizedPaths.js:73:42:73:55 | req.query.path | normalizedPaths.js:73:35:73:55 | './' + ... ry.path | +| normalizedPaths.js:73:42:73:55 | req.query.path | normalizedPaths.js:73:35:73:55 | './' + ... ry.path | +| normalizedPaths.js:73:42:73:55 | req.query.path | normalizedPaths.js:73:35:73:55 | './' + ... ry.path | +| normalizedPaths.js:82:7:82:27 | path | normalizedPaths.js:87:29:87:32 | path | +| normalizedPaths.js:82:7:82:27 | path | normalizedPaths.js:87:29:87:32 | path | | normalizedPaths.js:82:7:82:27 | path | normalizedPaths.js:87:29:87:32 | path | | normalizedPaths.js:82:7:82:27 | path | normalizedPaths.js:87:29:87:32 | path | | normalizedPaths.js:82:7:82:27 | path | normalizedPaths.js:90:31:90:34 | path | +| normalizedPaths.js:82:7:82:27 | path | normalizedPaths.js:90:31:90:34 | path | | normalizedPaths.js:82:14:82:27 | req.query.path | normalizedPaths.js:82:7:82:27 | path | | normalizedPaths.js:82:14:82:27 | req.query.path | normalizedPaths.js:82:7:82:27 | path | +| normalizedPaths.js:82:14:82:27 | req.query.path | normalizedPaths.js:82:7:82:27 | path | +| normalizedPaths.js:82:14:82:27 | req.query.path | normalizedPaths.js:82:7:82:27 | path | +| normalizedPaths.js:94:7:94:49 | path | normalizedPaths.js:99:29:99:32 | path | +| normalizedPaths.js:94:7:94:49 | path | normalizedPaths.js:99:29:99:32 | path | | normalizedPaths.js:94:7:94:49 | path | normalizedPaths.js:99:29:99:32 | path | | normalizedPaths.js:94:7:94:49 | path | normalizedPaths.js:99:29:99:32 | path | | normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | normalizedPaths.js:94:7:94:49 | path | | normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | normalizedPaths.js:94:7:94:49 | path | | normalizedPaths.js:94:35:94:48 | req.query.path | normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | | normalizedPaths.js:94:35:94:48 | req.query.path | normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | +| normalizedPaths.js:94:35:94:48 | req.query.path | normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | +| normalizedPaths.js:94:35:94:48 | req.query.path | normalizedPaths.js:94:14:94:49 | pathMod ... y.path) | +| normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:119:19:119:22 | path | +| normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:119:19:119:22 | path | +| normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:119:19:119:22 | path | +| normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:119:19:119:22 | path | | normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:119:19:119:22 | path | | normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:119:19:119:22 | path | | normalizedPaths.js:117:7:117:44 | path | normalizedPaths.js:119:19:119:22 | path | @@ -3936,10 +2689,21 @@ edges | normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | | normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | | normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | +| normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | +| normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | +| normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | +| normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:117:14:117:44 | fs.real ... y.path) | | normalizedPaths.js:120:35:120:38 | path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | | normalizedPaths.js:120:35:120:38 | path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | | normalizedPaths.js:120:35:120:38 | path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | | normalizedPaths.js:120:35:120:38 | path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | +| normalizedPaths.js:120:35:120:38 | path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | +| normalizedPaths.js:120:35:120:38 | path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | +| normalizedPaths.js:120:35:120:38 | path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | +| normalizedPaths.js:120:35:120:38 | path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | +| normalizedPaths.js:130:7:130:49 | path | normalizedPaths.js:135:21:135:24 | path | +| normalizedPaths.js:130:7:130:49 | path | normalizedPaths.js:135:21:135:24 | path | +| normalizedPaths.js:130:7:130:49 | path | normalizedPaths.js:135:21:135:24 | path | | normalizedPaths.js:130:7:130:49 | path | normalizedPaths.js:135:21:135:24 | path | | normalizedPaths.js:130:7:130:49 | path | normalizedPaths.js:135:21:135:24 | path | | normalizedPaths.js:130:7:130:49 | path | normalizedPaths.js:135:21:135:24 | path | @@ -3949,6 +2713,12 @@ edges | normalizedPaths.js:130:35:130:48 | req.query.path | normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | | normalizedPaths.js:130:35:130:48 | req.query.path | normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | | normalizedPaths.js:130:35:130:48 | req.query.path | normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | +| normalizedPaths.js:130:35:130:48 | req.query.path | normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | +| normalizedPaths.js:130:35:130:48 | req.query.path | normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | +| normalizedPaths.js:130:35:130:48 | req.query.path | normalizedPaths.js:130:14:130:49 | pathMod ... y.path) | +| normalizedPaths.js:139:7:139:62 | path | normalizedPaths.js:144:21:144:24 | path | +| normalizedPaths.js:139:7:139:62 | path | normalizedPaths.js:144:21:144:24 | path | +| normalizedPaths.js:139:7:139:62 | path | normalizedPaths.js:144:21:144:24 | path | | normalizedPaths.js:139:7:139:62 | path | normalizedPaths.js:144:21:144:24 | path | | normalizedPaths.js:139:7:139:62 | path | normalizedPaths.js:144:21:144:24 | path | | normalizedPaths.js:139:7:139:62 | path | normalizedPaths.js:144:21:144:24 | path | @@ -3958,8 +2728,15 @@ edges | normalizedPaths.js:139:48:139:61 | req.query.path | normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | | normalizedPaths.js:139:48:139:61 | req.query.path | normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | | normalizedPaths.js:139:48:139:61 | req.query.path | normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | +| normalizedPaths.js:139:48:139:61 | req.query.path | normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | +| normalizedPaths.js:139:48:139:61 | req.query.path | normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | +| normalizedPaths.js:139:48:139:61 | req.query.path | normalizedPaths.js:139:14:139:62 | pathMod ... y.path) | | normalizedPaths.js:148:7:148:58 | path | normalizedPaths.js:151:21:151:24 | path | | normalizedPaths.js:148:7:148:58 | path | normalizedPaths.js:151:21:151:24 | path | +| normalizedPaths.js:148:7:148:58 | path | normalizedPaths.js:151:21:151:24 | path | +| normalizedPaths.js:148:7:148:58 | path | normalizedPaths.js:151:21:151:24 | path | +| normalizedPaths.js:148:7:148:58 | path | normalizedPaths.js:153:21:153:24 | path | +| normalizedPaths.js:148:7:148:58 | path | normalizedPaths.js:153:21:153:24 | path | | normalizedPaths.js:148:7:148:58 | path | normalizedPaths.js:153:21:153:24 | path | | normalizedPaths.js:148:7:148:58 | path | normalizedPaths.js:153:21:153:24 | path | | normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | normalizedPaths.js:148:7:148:58 | path | @@ -3968,27 +2745,52 @@ edges | normalizedPaths.js:148:23:148:58 | pathMod ... y.path) | normalizedPaths.js:148:14:148:58 | 'foo/' ... y.path) | | normalizedPaths.js:148:44:148:57 | req.query.path | normalizedPaths.js:148:23:148:58 | pathMod ... y.path) | | normalizedPaths.js:148:44:148:57 | req.query.path | normalizedPaths.js:148:23:148:58 | pathMod ... y.path) | +| normalizedPaths.js:148:44:148:57 | req.query.path | normalizedPaths.js:148:23:148:58 | pathMod ... y.path) | +| normalizedPaths.js:148:44:148:57 | req.query.path | normalizedPaths.js:148:23:148:58 | pathMod ... y.path) | | normalizedPaths.js:160:7:160:49 | path | normalizedPaths.js:165:19:165:22 | path | | normalizedPaths.js:160:7:160:49 | path | normalizedPaths.js:165:19:165:22 | path | +| normalizedPaths.js:160:7:160:49 | path | normalizedPaths.js:165:19:165:22 | path | +| normalizedPaths.js:160:7:160:49 | path | normalizedPaths.js:165:19:165:22 | path | +| normalizedPaths.js:160:7:160:49 | path | normalizedPaths.js:170:21:170:24 | path | +| normalizedPaths.js:160:7:160:49 | path | normalizedPaths.js:170:21:170:24 | path | | normalizedPaths.js:160:7:160:49 | path | normalizedPaths.js:170:21:170:24 | path | | normalizedPaths.js:160:7:160:49 | path | normalizedPaths.js:170:21:170:24 | path | | normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | normalizedPaths.js:160:7:160:49 | path | | normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | normalizedPaths.js:160:7:160:49 | path | | normalizedPaths.js:160:35:160:48 | req.query.path | normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | | normalizedPaths.js:160:35:160:48 | req.query.path | normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | +| normalizedPaths.js:160:35:160:48 | req.query.path | normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | +| normalizedPaths.js:160:35:160:48 | req.query.path | normalizedPaths.js:160:14:160:49 | pathMod ... y.path) | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:184:19:184:22 | path | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:184:19:184:22 | path | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:184:19:184:22 | path | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:184:19:184:22 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:184:19:184:22 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:184:19:184:22 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:184:19:184:22 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:184:19:184:22 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:187:21:187:24 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:187:21:187:24 | path | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:187:21:187:24 | path | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:187:21:187:24 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:189:21:189:24 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:189:21:189:24 | path | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:189:21:189:24 | path | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:189:21:189:24 | path | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:192:21:192:24 | path | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:192:21:192:24 | path | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:192:21:192:24 | path | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:192:21:192:24 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:192:21:192:24 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:192:21:192:24 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:192:21:192:24 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:192:21:192:24 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:194:21:194:24 | path | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:194:21:194:24 | path | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:199:21:199:24 | path | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:199:21:199:24 | path | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:199:21:199:24 | path | +| normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:199:21:199:24 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:199:21:199:24 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:199:21:199:24 | path | | normalizedPaths.js:174:7:174:27 | path | normalizedPaths.js:199:21:199:24 | path | @@ -4001,6 +2803,14 @@ edges | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:174:7:174:27 | path | | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:174:7:174:27 | path | | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:174:7:174:27 | path | +| normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:174:7:174:27 | path | +| normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:174:7:174:27 | path | +| normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:174:7:174:27 | path | +| normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:174:7:174:27 | path | +| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:205:21:205:34 | normalizedPath | +| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:205:21:205:34 | normalizedPath | +| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:205:21:205:34 | normalizedPath | +| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:205:21:205:34 | normalizedPath | | normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:205:21:205:34 | normalizedPath | | normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:205:21:205:34 | normalizedPath | | normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:205:21:205:34 | normalizedPath | @@ -4009,6 +2819,14 @@ edges | normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:208:21:208:34 | normalizedPath | | normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:208:21:208:34 | normalizedPath | | normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:208:21:208:34 | normalizedPath | +| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:208:21:208:34 | normalizedPath | +| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:208:21:208:34 | normalizedPath | +| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:208:21:208:34 | normalizedPath | +| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:208:21:208:34 | normalizedPath | +| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:210:21:210:34 | normalizedPath | +| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:210:21:210:34 | normalizedPath | +| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:210:21:210:34 | normalizedPath | +| normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:210:21:210:34 | normalizedPath | | normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:210:21:210:34 | normalizedPath | | normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:210:21:210:34 | normalizedPath | | normalizedPaths.js:201:7:201:49 | normalizedPath | normalizedPaths.js:210:21:210:34 | normalizedPath | @@ -4033,6 +2851,14 @@ edges | normalizedPaths.js:214:35:214:48 | req.query.path | normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | | normalizedPaths.js:214:35:214:48 | req.query.path | normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | | normalizedPaths.js:214:35:214:48 | req.query.path | normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | +| normalizedPaths.js:214:35:214:48 | req.query.path | normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | +| normalizedPaths.js:214:35:214:48 | req.query.path | normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | +| normalizedPaths.js:214:35:214:48 | req.query.path | normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | +| normalizedPaths.js:214:35:214:48 | req.query.path | normalizedPaths.js:214:14:214:49 | pathMod ... y.path) | +| normalizedPaths.js:219:3:219:33 | path | normalizedPaths.js:222:21:222:24 | path | +| normalizedPaths.js:219:3:219:33 | path | normalizedPaths.js:222:21:222:24 | path | +| normalizedPaths.js:219:3:219:33 | path | normalizedPaths.js:222:21:222:24 | path | +| normalizedPaths.js:219:3:219:33 | path | normalizedPaths.js:222:21:222:24 | path | | normalizedPaths.js:219:3:219:33 | path | normalizedPaths.js:222:21:222:24 | path | | normalizedPaths.js:219:3:219:33 | path | normalizedPaths.js:222:21:222:24 | path | | normalizedPaths.js:219:3:219:33 | path | normalizedPaths.js:222:21:222:24 | path | @@ -4047,12 +2873,29 @@ edges | normalizedPaths.js:219:29:219:32 | path | normalizedPaths.js:219:10:219:33 | decodeU ... t(path) | | normalizedPaths.js:226:7:226:70 | path | normalizedPaths.js:228:21:228:24 | path | | normalizedPaths.js:226:7:226:70 | path | normalizedPaths.js:228:21:228:24 | path | +| normalizedPaths.js:226:7:226:70 | path | normalizedPaths.js:228:21:228:24 | path | +| normalizedPaths.js:226:7:226:70 | path | normalizedPaths.js:228:21:228:24 | path | | normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | | normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | | normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | normalizedPaths.js:226:7:226:70 | path | | normalizedPaths.js:226:14:226:70 | pathMod ... g, ' ') | normalizedPaths.js:226:7:226:70 | path | | normalizedPaths.js:226:35:226:48 | req.query.path | normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | | normalizedPaths.js:226:35:226:48 | req.query.path | normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | +| normalizedPaths.js:226:35:226:48 | req.query.path | normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | +| normalizedPaths.js:226:35:226:48 | req.query.path | normalizedPaths.js:226:14:226:49 | pathMod ... y.path) | +| tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | +| tainted-sendFile.js:8:16:8:33 | req.param("gimme") | tainted-sendFile.js:8:16:8:33 | req.param("gimme") | +| tainted-sendFile.js:10:16:10:33 | req.param("gimme") | tainted-sendFile.js:10:16:10:33 | req.param("gimme") | +| tainted-sendFile.js:18:43:18:58 | req.param("dir") | tainted-sendFile.js:18:43:18:58 | req.param("dir") | +| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | +| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | +| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | +| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | +| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | +| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | +| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | +| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | +| tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | | tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | | tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | | tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | @@ -4060,376 +2903,82 @@ edges | tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | | tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | | tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | +| tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | +| tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | +| tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | +| tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | +| tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | +| tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | +| tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | +| views.js:1:43:1:55 | req.params[0] | views.js:1:43:1:55 | req.params[0] | #select | TaintedPath-es6.js:10:26:10:45 | join("public", path) | TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:10:26:10:45 | join("public", path) | This path depends on $@. | TaintedPath-es6.js:7:20:7:26 | req.url | a user-provided value | -| TaintedPath-es6.js:10:26:10:45 | join("public", path) | TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:10:26:10:45 | join("public", path) | This path depends on $@. | TaintedPath-es6.js:7:20:7:26 | req.url | a user-provided value | -| TaintedPath-es6.js:10:26:10:45 | join("public", path) | TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:10:26:10:45 | join("public", path) | This path depends on $@. | TaintedPath-es6.js:7:20:7:26 | req.url | a user-provided value | -| TaintedPath-es6.js:10:26:10:45 | join("public", path) | TaintedPath-es6.js:7:20:7:26 | req.url | TaintedPath-es6.js:10:26:10:45 | join("public", path) | This path depends on $@. | TaintedPath-es6.js:7:20:7:26 | req.url | a user-provided value | -| TaintedPath.js:12:29:12:32 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:12:29:12:32 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:12:29:12:32 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:12:29:12:32 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:12:29:12:32 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:12:29:12:32 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:12:29:12:32 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:12:29:12:32 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:12:29:12:32 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:12:29:12:32 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:12:29:12:32 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:12:29:12:32 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:12:29:12:32 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:12:29:12:32 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:12:29:12:32 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:12:29:12:32 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:12:29:12:32 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:12:29:12:32 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:12:29:12:32 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:12:29:12:32 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:12:29:12:32 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:12:29:12:32 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:12:29:12:32 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:12:29:12:32 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:12:29:12:32 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:12:29:12:32 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:12:29:12:32 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:12:29:12:32 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:12:29:12:32 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:12:29:12:32 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | | TaintedPath.js:12:29:12:32 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:12:29:12:32 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | | TaintedPath.js:15:29:15:48 | "/home/user/" + path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:15:29:15:48 | "/home/user/" + path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:15:29:15:48 | "/home/user/" + path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:15:29:15:48 | "/home/user/" + path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:15:29:15:48 | "/home/user/" + path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:15:29:15:48 | "/home/user/" + path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:15:29:15:48 | "/home/user/" + path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:15:29:15:48 | "/home/user/" + path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:19:33:19:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:19:33:19:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:19:33:19:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:19:33:19:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:19:33:19:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:19:33:19:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | | TaintedPath.js:19:33:19:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:19:33:19:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | | TaintedPath.js:23:33:23:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:23:33:23:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:23:33:23:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:23:33:23:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:23:33:23:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:23:33:23:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:23:33:23:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:23:33:23:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:23:33:23:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:23:33:23:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:23:33:23:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:23:33:23:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:23:33:23:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:23:33:23:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:23:33:23:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:23:33:23:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:23:33:23:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:23:33:23:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:23:33:23:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:23:33:23:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:23:33:23:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:23:33:23:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:23:33:23:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:23:33:23:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:23:33:23:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:23:33:23:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:23:33:23:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:23:33:23:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:23:33:23:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:23:33:23:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:23:33:23:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:23:33:23:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:27:33:27:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:27:33:27:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:27:33:27:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:27:33:27:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:27:33:27:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:27:33:27:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:27:33:27:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:27:33:27:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:27:33:27:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:27:33:27:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:27:33:27:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:27:33:27:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:27:33:27:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:27:33:27:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:27:33:27:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:27:33:27:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:27:33:27:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:27:33:27:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:27:33:27:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:27:33:27:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:27:33:27:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:27:33:27:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:27:33:27:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:27:33:27:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:27:33:27:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:27:33:27:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:27:33:27:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:27:33:27:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:27:33:27:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:27:33:27:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | | TaintedPath.js:27:33:27:36 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:27:33:27:36 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | | TaintedPath.js:31:31:31:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:31:31:31:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:31:31:31:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:31:31:31:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:31:31:31:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:31:31:31:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:31:31:31:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:31:31:31:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:31:31:31:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:31:31:31:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:31:31:31:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:31:31:31:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:31:31:31:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:31:31:31:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:31:31:31:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:31:31:31:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:31:31:31:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:31:31:31:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:31:31:31:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:31:31:31:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:31:31:31:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:31:31:31:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:31:31:31:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:31:31:31:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:31:31:31:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:31:31:31:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:31:31:31:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:31:31:31:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:31:31:31:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:31:31:31:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:31:31:31:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:31:31:31:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:35:31:35:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:35:31:35:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:35:31:35:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:35:31:35:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:35:31:35:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:35:31:35:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:35:31:35:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:35:31:35:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:35:31:35:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:35:31:35:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:35:31:35:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:35:31:35:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:35:31:35:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:35:31:35:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:35:31:35:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:35:31:35:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:35:31:35:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:35:31:35:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:35:31:35:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:35:31:35:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:35:31:35:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:35:31:35:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:35:31:35:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:35:31:35:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:35:31:35:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:35:31:35:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:35:31:35:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:35:31:35:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:35:31:35:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:35:31:35:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | | TaintedPath.js:35:31:35:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:35:31:35:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | | TaintedPath.js:39:31:39:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:39:31:39:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:39:31:39:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:39:31:39:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:39:31:39:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:39:31:39:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:39:31:39:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:39:31:39:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:39:31:39:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:39:31:39:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:39:31:39:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:39:31:39:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:39:31:39:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:39:31:39:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:39:31:39:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:39:31:39:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:39:31:39:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:39:31:39:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:39:31:39:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:39:31:39:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:39:31:39:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:39:31:39:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:39:31:39:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:39:31:39:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:39:31:39:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:39:31:39:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:39:31:39:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:39:31:39:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:39:31:39:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:39:31:39:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | -| TaintedPath.js:39:31:39:34 | path | TaintedPath.js:9:24:9:30 | req.url | TaintedPath.js:39:31:39:34 | path | This path depends on $@. | TaintedPath.js:9:24:9:30 | req.url | a user-provided value | | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:49:29:49:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:49:29:49:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:49:29:49:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:49:29:49:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:49:29:49:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:49:29:49:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:49:29:49:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:49:29:49:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:49:29:49:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:49:29:49:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:49:29:49:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:49:29:49:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:49:29:49:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:49:29:49:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:49:29:49:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:49:29:49:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:53:29:53:49 | pathMod ... n(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:53:29:53:49 | pathMod ... n(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:53:29:53:49 | pathMod ... n(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:53:29:53:49 | pathMod ... n(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:53:29:53:49 | pathMod ... n(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:53:29:53:49 | pathMod ... n(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:53:29:53:49 | pathMod ... n(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:53:29:53:49 | pathMod ... n(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:55:29:55:58 | pathMod ... ath, z) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:57:29:57:54 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:57:29:57:54 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:57:29:57:54 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:57:29:57:54 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:57:29:57:54 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:57:29:57:54 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:57:29:57:54 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:57:29:57:54 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | | TaintedPath.js:59:29:59:56 | pathMod ... , path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:59:29:59:56 | pathMod ... , path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:59:29:59:56 | pathMod ... , path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:59:29:59:56 | pathMod ... , path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:59:29:59:56 | pathMod ... , path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:59:29:59:56 | pathMod ... , path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:59:29:59:56 | pathMod ... , path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:59:29:59:56 | pathMod ... , path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:61:29:61:56 | pathMod ... ath, x) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:63:29:63:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:63:29:63:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:63:29:63:52 | pathMod ... e(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:63:29:63:52 | pathMod ... e(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:65:29:65:61 | pathMod ... ath, z) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:67:29:67:61 | pathMod ... h(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:67:29:67:61 | pathMod ... h(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:67:29:67:61 | pathMod ... h(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:67:29:67:61 | pathMod ... h(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:67:29:67:61 | pathMod ... h(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:67:29:67:61 | pathMod ... h(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:67:29:67:61 | pathMod ... h(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:67:29:67:61 | pathMod ... h(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:67:29:67:61 | pathMod ... h(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:67:29:67:61 | pathMod ... h(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:67:29:67:61 | pathMod ... h(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:67:29:67:61 | pathMod ... h(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:67:29:67:61 | pathMod ... h(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:67:29:67:61 | pathMod ... h(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:67:29:67:61 | pathMod ... h(path) | TaintedPath.js:45:20:45:26 | req.url | TaintedPath.js:67:29:67:61 | pathMod ... h(path) | This path depends on $@. | TaintedPath.js:45:20:45:26 | req.url | a user-provided value | -| TaintedPath.js:78:26:78:45 | Cookie.get("unsafe") | TaintedPath.js:102:30:102:31 | ev | TaintedPath.js:78:26:78:45 | Cookie.get("unsafe") | This path depends on $@. | TaintedPath.js:102:30:102:31 | ev | a user-provided value | -| TaintedPath.js:78:26:78:45 | Cookie.get("unsafe") | TaintedPath.js:102:30:102:31 | ev | TaintedPath.js:78:26:78:45 | Cookie.get("unsafe") | This path depends on $@. | TaintedPath.js:102:30:102:31 | ev | a user-provided value | -| TaintedPath.js:78:26:78:45 | Cookie.get("unsafe") | TaintedPath.js:102:30:102:31 | ev | TaintedPath.js:78:26:78:45 | Cookie.get("unsafe") | This path depends on $@. | TaintedPath.js:102:30:102:31 | ev | a user-provided value | | TaintedPath.js:78:26:78:45 | Cookie.get("unsafe") | TaintedPath.js:102:30:102:31 | ev | TaintedPath.js:78:26:78:45 | Cookie.get("unsafe") | This path depends on $@. | TaintedPath.js:102:30:102:31 | ev | a user-provided value | | TaintedPath.js:84:31:84:76 | require ... ).query | TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:76 | require ... ).query | This path depends on $@. | TaintedPath.js:84:63:84:69 | req.url | a user-provided value | -| TaintedPath.js:84:31:84:76 | require ... ).query | TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:76 | require ... ).query | This path depends on $@. | TaintedPath.js:84:63:84:69 | req.url | a user-provided value | -| TaintedPath.js:84:31:84:76 | require ... ).query | TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:76 | require ... ).query | This path depends on $@. | TaintedPath.js:84:63:84:69 | req.url | a user-provided value | -| TaintedPath.js:84:31:84:76 | require ... ).query | TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:76 | require ... ).query | This path depends on $@. | TaintedPath.js:84:63:84:69 | req.url | a user-provided value | -| TaintedPath.js:84:31:84:76 | require ... ).query | TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:76 | require ... ).query | This path depends on $@. | TaintedPath.js:84:63:84:69 | req.url | a user-provided value | -| TaintedPath.js:84:31:84:76 | require ... ).query | TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:76 | require ... ).query | This path depends on $@. | TaintedPath.js:84:63:84:69 | req.url | a user-provided value | -| TaintedPath.js:84:31:84:76 | require ... ).query | TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:76 | require ... ).query | This path depends on $@. | TaintedPath.js:84:63:84:69 | req.url | a user-provided value | -| TaintedPath.js:84:31:84:76 | require ... ).query | TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:76 | require ... ).query | This path depends on $@. | TaintedPath.js:84:63:84:69 | req.url | a user-provided value | -| TaintedPath.js:84:31:84:76 | require ... ).query | TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:76 | require ... ).query | This path depends on $@. | TaintedPath.js:84:63:84:69 | req.url | a user-provided value | -| TaintedPath.js:84:31:84:76 | require ... ).query | TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:76 | require ... ).query | This path depends on $@. | TaintedPath.js:84:63:84:69 | req.url | a user-provided value | -| TaintedPath.js:84:31:84:76 | require ... ).query | TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:76 | require ... ).query | This path depends on $@. | TaintedPath.js:84:63:84:69 | req.url | a user-provided value | -| TaintedPath.js:84:31:84:76 | require ... ).query | TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:76 | require ... ).query | This path depends on $@. | TaintedPath.js:84:63:84:69 | req.url | a user-provided value | -| TaintedPath.js:84:31:84:76 | require ... ).query | TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:76 | require ... ).query | This path depends on $@. | TaintedPath.js:84:63:84:69 | req.url | a user-provided value | -| TaintedPath.js:84:31:84:76 | require ... ).query | TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:76 | require ... ).query | This path depends on $@. | TaintedPath.js:84:63:84:69 | req.url | a user-provided value | -| TaintedPath.js:84:31:84:76 | require ... ).query | TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:76 | require ... ).query | This path depends on $@. | TaintedPath.js:84:63:84:69 | req.url | a user-provided value | -| TaintedPath.js:84:31:84:76 | require ... ).query | TaintedPath.js:84:63:84:69 | req.url | TaintedPath.js:84:31:84:76 | require ... ).query | This path depends on $@. | TaintedPath.js:84:63:84:69 | req.url | a user-provided value | | TaintedPath.js:85:31:85:74 | require ... ).query | TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:74 | require ... ).query | This path depends on $@. | TaintedPath.js:85:61:85:67 | req.url | a user-provided value | -| TaintedPath.js:85:31:85:74 | require ... ).query | TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:74 | require ... ).query | This path depends on $@. | TaintedPath.js:85:61:85:67 | req.url | a user-provided value | -| TaintedPath.js:85:31:85:74 | require ... ).query | TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:74 | require ... ).query | This path depends on $@. | TaintedPath.js:85:61:85:67 | req.url | a user-provided value | -| TaintedPath.js:85:31:85:74 | require ... ).query | TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:74 | require ... ).query | This path depends on $@. | TaintedPath.js:85:61:85:67 | req.url | a user-provided value | -| TaintedPath.js:85:31:85:74 | require ... ).query | TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:74 | require ... ).query | This path depends on $@. | TaintedPath.js:85:61:85:67 | req.url | a user-provided value | -| TaintedPath.js:85:31:85:74 | require ... ).query | TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:74 | require ... ).query | This path depends on $@. | TaintedPath.js:85:61:85:67 | req.url | a user-provided value | -| TaintedPath.js:85:31:85:74 | require ... ).query | TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:74 | require ... ).query | This path depends on $@. | TaintedPath.js:85:61:85:67 | req.url | a user-provided value | -| TaintedPath.js:85:31:85:74 | require ... ).query | TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:74 | require ... ).query | This path depends on $@. | TaintedPath.js:85:61:85:67 | req.url | a user-provided value | -| TaintedPath.js:85:31:85:74 | require ... ).query | TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:74 | require ... ).query | This path depends on $@. | TaintedPath.js:85:61:85:67 | req.url | a user-provided value | -| TaintedPath.js:85:31:85:74 | require ... ).query | TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:74 | require ... ).query | This path depends on $@. | TaintedPath.js:85:61:85:67 | req.url | a user-provided value | -| TaintedPath.js:85:31:85:74 | require ... ).query | TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:74 | require ... ).query | This path depends on $@. | TaintedPath.js:85:61:85:67 | req.url | a user-provided value | -| TaintedPath.js:85:31:85:74 | require ... ).query | TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:74 | require ... ).query | This path depends on $@. | TaintedPath.js:85:61:85:67 | req.url | a user-provided value | -| TaintedPath.js:85:31:85:74 | require ... ).query | TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:74 | require ... ).query | This path depends on $@. | TaintedPath.js:85:61:85:67 | req.url | a user-provided value | -| TaintedPath.js:85:31:85:74 | require ... ).query | TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:74 | require ... ).query | This path depends on $@. | TaintedPath.js:85:61:85:67 | req.url | a user-provided value | -| TaintedPath.js:85:31:85:74 | require ... ).query | TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:74 | require ... ).query | This path depends on $@. | TaintedPath.js:85:61:85:67 | req.url | a user-provided value | -| TaintedPath.js:85:31:85:74 | require ... ).query | TaintedPath.js:85:61:85:67 | req.url | TaintedPath.js:85:31:85:74 | require ... ).query | This path depends on $@. | TaintedPath.js:85:61:85:67 | req.url | a user-provided value | -| TaintedPath.js:86:31:86:73 | require ... ).query | TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:73 | require ... ).query | This path depends on $@. | TaintedPath.js:86:60:86:66 | req.url | a user-provided value | -| TaintedPath.js:86:31:86:73 | require ... ).query | TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:73 | require ... ).query | This path depends on $@. | TaintedPath.js:86:60:86:66 | req.url | a user-provided value | -| TaintedPath.js:86:31:86:73 | require ... ).query | TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:73 | require ... ).query | This path depends on $@. | TaintedPath.js:86:60:86:66 | req.url | a user-provided value | -| TaintedPath.js:86:31:86:73 | require ... ).query | TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:73 | require ... ).query | This path depends on $@. | TaintedPath.js:86:60:86:66 | req.url | a user-provided value | -| TaintedPath.js:86:31:86:73 | require ... ).query | TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:73 | require ... ).query | This path depends on $@. | TaintedPath.js:86:60:86:66 | req.url | a user-provided value | -| TaintedPath.js:86:31:86:73 | require ... ).query | TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:73 | require ... ).query | This path depends on $@. | TaintedPath.js:86:60:86:66 | req.url | a user-provided value | -| TaintedPath.js:86:31:86:73 | require ... ).query | TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:73 | require ... ).query | This path depends on $@. | TaintedPath.js:86:60:86:66 | req.url | a user-provided value | -| TaintedPath.js:86:31:86:73 | require ... ).query | TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:73 | require ... ).query | This path depends on $@. | TaintedPath.js:86:60:86:66 | req.url | a user-provided value | -| TaintedPath.js:86:31:86:73 | require ... ).query | TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:73 | require ... ).query | This path depends on $@. | TaintedPath.js:86:60:86:66 | req.url | a user-provided value | -| TaintedPath.js:86:31:86:73 | require ... ).query | TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:73 | require ... ).query | This path depends on $@. | TaintedPath.js:86:60:86:66 | req.url | a user-provided value | -| TaintedPath.js:86:31:86:73 | require ... ).query | TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:73 | require ... ).query | This path depends on $@. | TaintedPath.js:86:60:86:66 | req.url | a user-provided value | -| TaintedPath.js:86:31:86:73 | require ... ).query | TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:73 | require ... ).query | This path depends on $@. | TaintedPath.js:86:60:86:66 | req.url | a user-provided value | -| TaintedPath.js:86:31:86:73 | require ... ).query | TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:73 | require ... ).query | This path depends on $@. | TaintedPath.js:86:60:86:66 | req.url | a user-provided value | -| TaintedPath.js:86:31:86:73 | require ... ).query | TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:73 | require ... ).query | This path depends on $@. | TaintedPath.js:86:60:86:66 | req.url | a user-provided value | -| TaintedPath.js:86:31:86:73 | require ... ).query | TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:73 | require ... ).query | This path depends on $@. | TaintedPath.js:86:60:86:66 | req.url | a user-provided value | | TaintedPath.js:86:31:86:73 | require ... ).query | TaintedPath.js:86:60:86:66 | req.url | TaintedPath.js:86:31:86:73 | require ... ).query | This path depends on $@. | TaintedPath.js:86:60:86:66 | req.url | a user-provided value | | TaintedPath.js:94:48:94:60 | req.params[0] | TaintedPath.js:94:48:94:60 | req.params[0] | TaintedPath.js:94:48:94:60 | req.params[0] | This path depends on $@. | TaintedPath.js:94:48:94:60 | req.params[0] | a user-provided value | -| TaintedPath.js:94:48:94:60 | req.params[0] | TaintedPath.js:94:48:94:60 | req.params[0] | TaintedPath.js:94:48:94:60 | req.params[0] | This path depends on $@. | TaintedPath.js:94:48:94:60 | req.params[0] | a user-provided value | -| TaintedPath.js:94:48:94:60 | req.params[0] | TaintedPath.js:94:48:94:60 | req.params[0] | TaintedPath.js:94:48:94:60 | req.params[0] | This path depends on $@. | TaintedPath.js:94:48:94:60 | req.params[0] | a user-provided value | -| TaintedPath.js:94:48:94:60 | req.params[0] | TaintedPath.js:94:48:94:60 | req.params[0] | TaintedPath.js:94:48:94:60 | req.params[0] | This path depends on $@. | TaintedPath.js:94:48:94:60 | req.params[0] | a user-provided value | -| TaintedPath.js:109:28:109:48 | fs.real ... c(path) | TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | This path depends on $@. | TaintedPath.js:107:23:107:29 | req.url | a user-provided value | -| TaintedPath.js:109:28:109:48 | fs.real ... c(path) | TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | This path depends on $@. | TaintedPath.js:107:23:107:29 | req.url | a user-provided value | -| TaintedPath.js:109:28:109:48 | fs.real ... c(path) | TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | This path depends on $@. | TaintedPath.js:107:23:107:29 | req.url | a user-provided value | | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:109:28:109:48 | fs.real ... c(path) | This path depends on $@. | TaintedPath.js:107:23:107:29 | req.url | a user-provided value | | TaintedPath.js:112:45:112:52 | realpath | TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:112:45:112:52 | realpath | This path depends on $@. | TaintedPath.js:107:23:107:29 | req.url | a user-provided value | -| TaintedPath.js:112:45:112:52 | realpath | TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:112:45:112:52 | realpath | This path depends on $@. | TaintedPath.js:107:23:107:29 | req.url | a user-provided value | -| TaintedPath.js:112:45:112:52 | realpath | TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:112:45:112:52 | realpath | This path depends on $@. | TaintedPath.js:107:23:107:29 | req.url | a user-provided value | -| TaintedPath.js:112:45:112:52 | realpath | TaintedPath.js:107:23:107:29 | req.url | TaintedPath.js:112:45:112:52 | realpath | This path depends on $@. | TaintedPath.js:107:23:107:29 | req.url | a user-provided value | -| normalizedPaths.js:13:19:13:22 | path | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:13:19:13:22 | path | This path depends on $@. | normalizedPaths.js:11:14:11:27 | req.query.path | a user-provided value | -| normalizedPaths.js:13:19:13:22 | path | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:13:19:13:22 | path | This path depends on $@. | normalizedPaths.js:11:14:11:27 | req.query.path | a user-provided value | -| normalizedPaths.js:13:19:13:22 | path | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:13:19:13:22 | path | This path depends on $@. | normalizedPaths.js:11:14:11:27 | req.query.path | a user-provided value | | normalizedPaths.js:13:19:13:22 | path | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:13:19:13:22 | path | This path depends on $@. | normalizedPaths.js:11:14:11:27 | req.query.path | a user-provided value | | normalizedPaths.js:14:19:14:29 | './' + path | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:14:19:14:29 | './' + path | This path depends on $@. | normalizedPaths.js:11:14:11:27 | req.query.path | a user-provided value | -| normalizedPaths.js:14:19:14:29 | './' + path | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:14:19:14:29 | './' + path | This path depends on $@. | normalizedPaths.js:11:14:11:27 | req.query.path | a user-provided value | -| normalizedPaths.js:14:19:14:29 | './' + path | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:14:19:14:29 | './' + path | This path depends on $@. | normalizedPaths.js:11:14:11:27 | req.query.path | a user-provided value | | normalizedPaths.js:15:19:15:38 | path + '/index.html' | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | This path depends on $@. | normalizedPaths.js:11:14:11:27 | req.query.path | a user-provided value | -| normalizedPaths.js:15:19:15:38 | path + '/index.html' | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | This path depends on $@. | normalizedPaths.js:11:14:11:27 | req.query.path | a user-provided value | -| normalizedPaths.js:15:19:15:38 | path + '/index.html' | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | This path depends on $@. | normalizedPaths.js:11:14:11:27 | req.query.path | a user-provided value | -| normalizedPaths.js:15:19:15:38 | path + '/index.html' | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:15:19:15:38 | path + '/index.html' | This path depends on $@. | normalizedPaths.js:11:14:11:27 | req.query.path | a user-provided value | -| normalizedPaths.js:16:19:16:53 | pathMod ... .html') | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | This path depends on $@. | normalizedPaths.js:11:14:11:27 | req.query.path | a user-provided value | -| normalizedPaths.js:16:19:16:53 | pathMod ... .html') | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | This path depends on $@. | normalizedPaths.js:11:14:11:27 | req.query.path | a user-provided value | -| normalizedPaths.js:16:19:16:53 | pathMod ... .html') | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | This path depends on $@. | normalizedPaths.js:11:14:11:27 | req.query.path | a user-provided value | | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:16:19:16:53 | pathMod ... .html') | This path depends on $@. | normalizedPaths.js:11:14:11:27 | req.query.path | a user-provided value | | normalizedPaths.js:17:19:17:57 | pathMod ... , path) | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:17:19:17:57 | pathMod ... , path) | This path depends on $@. | normalizedPaths.js:11:14:11:27 | req.query.path | a user-provided value | -| normalizedPaths.js:17:19:17:57 | pathMod ... , path) | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:17:19:17:57 | pathMod ... , path) | This path depends on $@. | normalizedPaths.js:11:14:11:27 | req.query.path | a user-provided value | -| normalizedPaths.js:17:19:17:57 | pathMod ... , path) | normalizedPaths.js:11:14:11:27 | req.query.path | normalizedPaths.js:17:19:17:57 | pathMod ... , path) | This path depends on $@. | normalizedPaths.js:11:14:11:27 | req.query.path | a user-provided value | -| normalizedPaths.js:23:19:23:22 | path | normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:23:19:23:22 | path | This path depends on $@. | normalizedPaths.js:21:35:21:48 | req.query.path | a user-provided value | -| normalizedPaths.js:23:19:23:22 | path | normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:23:19:23:22 | path | This path depends on $@. | normalizedPaths.js:21:35:21:48 | req.query.path | a user-provided value | -| normalizedPaths.js:23:19:23:22 | path | normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:23:19:23:22 | path | This path depends on $@. | normalizedPaths.js:21:35:21:48 | req.query.path | a user-provided value | | normalizedPaths.js:23:19:23:22 | path | normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:23:19:23:22 | path | This path depends on $@. | normalizedPaths.js:21:35:21:48 | req.query.path | a user-provided value | | normalizedPaths.js:24:19:24:29 | './' + path | normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:24:19:24:29 | './' + path | This path depends on $@. | normalizedPaths.js:21:35:21:48 | req.query.path | a user-provided value | -| normalizedPaths.js:24:19:24:29 | './' + path | normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:24:19:24:29 | './' + path | This path depends on $@. | normalizedPaths.js:21:35:21:48 | req.query.path | a user-provided value | | normalizedPaths.js:25:19:25:38 | path + '/index.html' | normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | This path depends on $@. | normalizedPaths.js:21:35:21:48 | req.query.path | a user-provided value | -| normalizedPaths.js:25:19:25:38 | path + '/index.html' | normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | This path depends on $@. | normalizedPaths.js:21:35:21:48 | req.query.path | a user-provided value | -| normalizedPaths.js:25:19:25:38 | path + '/index.html' | normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | This path depends on $@. | normalizedPaths.js:21:35:21:48 | req.query.path | a user-provided value | -| normalizedPaths.js:25:19:25:38 | path + '/index.html' | normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:25:19:25:38 | path + '/index.html' | This path depends on $@. | normalizedPaths.js:21:35:21:48 | req.query.path | a user-provided value | -| normalizedPaths.js:26:19:26:53 | pathMod ... .html') | normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | This path depends on $@. | normalizedPaths.js:21:35:21:48 | req.query.path | a user-provided value | -| normalizedPaths.js:26:19:26:53 | pathMod ... .html') | normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | This path depends on $@. | normalizedPaths.js:21:35:21:48 | req.query.path | a user-provided value | -| normalizedPaths.js:26:19:26:53 | pathMod ... .html') | normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | This path depends on $@. | normalizedPaths.js:21:35:21:48 | req.query.path | a user-provided value | | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:26:19:26:53 | pathMod ... .html') | This path depends on $@. | normalizedPaths.js:21:35:21:48 | req.query.path | a user-provided value | | normalizedPaths.js:27:19:27:57 | pathMod ... , path) | normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:27:19:27:57 | pathMod ... , path) | This path depends on $@. | normalizedPaths.js:21:35:21:48 | req.query.path | a user-provided value | -| normalizedPaths.js:27:19:27:57 | pathMod ... , path) | normalizedPaths.js:21:35:21:48 | req.query.path | normalizedPaths.js:27:19:27:57 | pathMod ... , path) | This path depends on $@. | normalizedPaths.js:21:35:21:48 | req.query.path | a user-provided value | -| normalizedPaths.js:36:19:36:22 | path | normalizedPaths.js:31:35:31:48 | req.query.path | normalizedPaths.js:36:19:36:22 | path | This path depends on $@. | normalizedPaths.js:31:35:31:48 | req.query.path | a user-provided value | | normalizedPaths.js:36:19:36:22 | path | normalizedPaths.js:31:35:31:48 | req.query.path | normalizedPaths.js:36:19:36:22 | path | This path depends on $@. | normalizedPaths.js:31:35:31:48 | req.query.path | a user-provided value | | normalizedPaths.js:41:21:41:24 | path | normalizedPaths.js:31:35:31:48 | req.query.path | normalizedPaths.js:41:21:41:24 | path | This path depends on $@. | normalizedPaths.js:31:35:31:48 | req.query.path | a user-provided value | -| normalizedPaths.js:41:21:41:24 | path | normalizedPaths.js:31:35:31:48 | req.query.path | normalizedPaths.js:41:21:41:24 | path | This path depends on $@. | normalizedPaths.js:31:35:31:48 | req.query.path | a user-provided value | -| normalizedPaths.js:59:19:59:22 | path | normalizedPaths.js:54:35:54:48 | req.query.path | normalizedPaths.js:59:19:59:22 | path | This path depends on $@. | normalizedPaths.js:54:35:54:48 | req.query.path | a user-provided value | | normalizedPaths.js:59:19:59:22 | path | normalizedPaths.js:54:35:54:48 | req.query.path | normalizedPaths.js:59:19:59:22 | path | This path depends on $@. | normalizedPaths.js:54:35:54:48 | req.query.path | a user-provided value | | normalizedPaths.js:63:19:63:38 | path + "/index.html" | normalizedPaths.js:54:35:54:48 | req.query.path | normalizedPaths.js:63:19:63:38 | path + "/index.html" | This path depends on $@. | normalizedPaths.js:54:35:54:48 | req.query.path | a user-provided value | -| normalizedPaths.js:63:19:63:38 | path + "/index.html" | normalizedPaths.js:54:35:54:48 | req.query.path | normalizedPaths.js:63:19:63:38 | path + "/index.html" | This path depends on $@. | normalizedPaths.js:54:35:54:48 | req.query.path | a user-provided value | -| normalizedPaths.js:68:21:68:24 | path | normalizedPaths.js:54:35:54:48 | req.query.path | normalizedPaths.js:68:21:68:24 | path | This path depends on $@. | normalizedPaths.js:54:35:54:48 | req.query.path | a user-provided value | | normalizedPaths.js:68:21:68:24 | path | normalizedPaths.js:54:35:54:48 | req.query.path | normalizedPaths.js:68:21:68:24 | path | This path depends on $@. | normalizedPaths.js:54:35:54:48 | req.query.path | a user-provided value | | normalizedPaths.js:78:22:78:25 | path | normalizedPaths.js:73:42:73:55 | req.query.path | normalizedPaths.js:78:22:78:25 | path | This path depends on $@. | normalizedPaths.js:73:42:73:55 | req.query.path | a user-provided value | -| normalizedPaths.js:78:22:78:25 | path | normalizedPaths.js:73:42:73:55 | req.query.path | normalizedPaths.js:78:22:78:25 | path | This path depends on $@. | normalizedPaths.js:73:42:73:55 | req.query.path | a user-provided value | -| normalizedPaths.js:78:22:78:25 | path | normalizedPaths.js:73:42:73:55 | req.query.path | normalizedPaths.js:78:22:78:25 | path | This path depends on $@. | normalizedPaths.js:73:42:73:55 | req.query.path | a user-provided value | -| normalizedPaths.js:87:29:87:32 | path | normalizedPaths.js:82:14:82:27 | req.query.path | normalizedPaths.js:87:29:87:32 | path | This path depends on $@. | normalizedPaths.js:82:14:82:27 | req.query.path | a user-provided value | | normalizedPaths.js:87:29:87:32 | path | normalizedPaths.js:82:14:82:27 | req.query.path | normalizedPaths.js:87:29:87:32 | path | This path depends on $@. | normalizedPaths.js:82:14:82:27 | req.query.path | a user-provided value | | normalizedPaths.js:90:31:90:34 | path | normalizedPaths.js:82:14:82:27 | req.query.path | normalizedPaths.js:90:31:90:34 | path | This path depends on $@. | normalizedPaths.js:82:14:82:27 | req.query.path | a user-provided value | | normalizedPaths.js:99:29:99:32 | path | normalizedPaths.js:94:35:94:48 | req.query.path | normalizedPaths.js:99:29:99:32 | path | This path depends on $@. | normalizedPaths.js:94:35:94:48 | req.query.path | a user-provided value | -| normalizedPaths.js:99:29:99:32 | path | normalizedPaths.js:94:35:94:48 | req.query.path | normalizedPaths.js:99:29:99:32 | path | This path depends on $@. | normalizedPaths.js:94:35:94:48 | req.query.path | a user-provided value | | normalizedPaths.js:119:19:119:22 | path | normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:119:19:119:22 | path | This path depends on $@. | normalizedPaths.js:117:30:117:43 | req.query.path | a user-provided value | -| normalizedPaths.js:119:19:119:22 | path | normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:119:19:119:22 | path | This path depends on $@. | normalizedPaths.js:117:30:117:43 | req.query.path | a user-provided value | -| normalizedPaths.js:119:19:119:22 | path | normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:119:19:119:22 | path | This path depends on $@. | normalizedPaths.js:117:30:117:43 | req.query.path | a user-provided value | -| normalizedPaths.js:119:19:119:22 | path | normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:119:19:119:22 | path | This path depends on $@. | normalizedPaths.js:117:30:117:43 | req.query.path | a user-provided value | -| normalizedPaths.js:120:19:120:53 | pathMod ... .html') | normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | This path depends on $@. | normalizedPaths.js:117:30:117:43 | req.query.path | a user-provided value | -| normalizedPaths.js:120:19:120:53 | pathMod ... .html') | normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | This path depends on $@. | normalizedPaths.js:117:30:117:43 | req.query.path | a user-provided value | -| normalizedPaths.js:120:19:120:53 | pathMod ... .html') | normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | This path depends on $@. | normalizedPaths.js:117:30:117:43 | req.query.path | a user-provided value | | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | normalizedPaths.js:117:30:117:43 | req.query.path | normalizedPaths.js:120:19:120:53 | pathMod ... .html') | This path depends on $@. | normalizedPaths.js:117:30:117:43 | req.query.path | a user-provided value | | normalizedPaths.js:135:21:135:24 | path | normalizedPaths.js:130:35:130:48 | req.query.path | normalizedPaths.js:135:21:135:24 | path | This path depends on $@. | normalizedPaths.js:130:35:130:48 | req.query.path | a user-provided value | -| normalizedPaths.js:135:21:135:24 | path | normalizedPaths.js:130:35:130:48 | req.query.path | normalizedPaths.js:135:21:135:24 | path | This path depends on $@. | normalizedPaths.js:130:35:130:48 | req.query.path | a user-provided value | -| normalizedPaths.js:135:21:135:24 | path | normalizedPaths.js:130:35:130:48 | req.query.path | normalizedPaths.js:135:21:135:24 | path | This path depends on $@. | normalizedPaths.js:130:35:130:48 | req.query.path | a user-provided value | -| normalizedPaths.js:144:21:144:24 | path | normalizedPaths.js:139:48:139:61 | req.query.path | normalizedPaths.js:144:21:144:24 | path | This path depends on $@. | normalizedPaths.js:139:48:139:61 | req.query.path | a user-provided value | -| normalizedPaths.js:144:21:144:24 | path | normalizedPaths.js:139:48:139:61 | req.query.path | normalizedPaths.js:144:21:144:24 | path | This path depends on $@. | normalizedPaths.js:139:48:139:61 | req.query.path | a user-provided value | | normalizedPaths.js:144:21:144:24 | path | normalizedPaths.js:139:48:139:61 | req.query.path | normalizedPaths.js:144:21:144:24 | path | This path depends on $@. | normalizedPaths.js:139:48:139:61 | req.query.path | a user-provided value | | normalizedPaths.js:151:21:151:24 | path | normalizedPaths.js:148:44:148:57 | req.query.path | normalizedPaths.js:151:21:151:24 | path | This path depends on $@. | normalizedPaths.js:148:44:148:57 | req.query.path | a user-provided value | -| normalizedPaths.js:151:21:151:24 | path | normalizedPaths.js:148:44:148:57 | req.query.path | normalizedPaths.js:151:21:151:24 | path | This path depends on $@. | normalizedPaths.js:148:44:148:57 | req.query.path | a user-provided value | -| normalizedPaths.js:153:21:153:24 | path | normalizedPaths.js:148:44:148:57 | req.query.path | normalizedPaths.js:153:21:153:24 | path | This path depends on $@. | normalizedPaths.js:148:44:148:57 | req.query.path | a user-provided value | | normalizedPaths.js:153:21:153:24 | path | normalizedPaths.js:148:44:148:57 | req.query.path | normalizedPaths.js:153:21:153:24 | path | This path depends on $@. | normalizedPaths.js:148:44:148:57 | req.query.path | a user-provided value | | normalizedPaths.js:165:19:165:22 | path | normalizedPaths.js:160:35:160:48 | req.query.path | normalizedPaths.js:165:19:165:22 | path | This path depends on $@. | normalizedPaths.js:160:35:160:48 | req.query.path | a user-provided value | -| normalizedPaths.js:165:19:165:22 | path | normalizedPaths.js:160:35:160:48 | req.query.path | normalizedPaths.js:165:19:165:22 | path | This path depends on $@. | normalizedPaths.js:160:35:160:48 | req.query.path | a user-provided value | -| normalizedPaths.js:170:21:170:24 | path | normalizedPaths.js:160:35:160:48 | req.query.path | normalizedPaths.js:170:21:170:24 | path | This path depends on $@. | normalizedPaths.js:160:35:160:48 | req.query.path | a user-provided value | | normalizedPaths.js:170:21:170:24 | path | normalizedPaths.js:160:35:160:48 | req.query.path | normalizedPaths.js:170:21:170:24 | path | This path depends on $@. | normalizedPaths.js:160:35:160:48 | req.query.path | a user-provided value | | normalizedPaths.js:184:19:184:22 | path | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:184:19:184:22 | path | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | -| normalizedPaths.js:184:19:184:22 | path | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:184:19:184:22 | path | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | -| normalizedPaths.js:184:19:184:22 | path | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:184:19:184:22 | path | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | -| normalizedPaths.js:184:19:184:22 | path | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:184:19:184:22 | path | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | -| normalizedPaths.js:187:21:187:24 | path | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:187:21:187:24 | path | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | | normalizedPaths.js:187:21:187:24 | path | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:187:21:187:24 | path | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | | normalizedPaths.js:189:21:189:24 | path | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:189:21:189:24 | path | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | -| normalizedPaths.js:189:21:189:24 | path | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:189:21:189:24 | path | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | -| normalizedPaths.js:192:21:192:24 | path | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:192:21:192:24 | path | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | -| normalizedPaths.js:192:21:192:24 | path | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:192:21:192:24 | path | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | -| normalizedPaths.js:192:21:192:24 | path | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:192:21:192:24 | path | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | | normalizedPaths.js:192:21:192:24 | path | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:192:21:192:24 | path | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | | normalizedPaths.js:194:21:194:24 | path | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:194:21:194:24 | path | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | | normalizedPaths.js:199:21:199:24 | path | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:199:21:199:24 | path | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | -| normalizedPaths.js:199:21:199:24 | path | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:199:21:199:24 | path | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | -| normalizedPaths.js:199:21:199:24 | path | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:199:21:199:24 | path | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | -| normalizedPaths.js:199:21:199:24 | path | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:199:21:199:24 | path | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | -| normalizedPaths.js:205:21:205:34 | normalizedPath | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:205:21:205:34 | normalizedPath | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | -| normalizedPaths.js:205:21:205:34 | normalizedPath | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:205:21:205:34 | normalizedPath | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | -| normalizedPaths.js:205:21:205:34 | normalizedPath | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:205:21:205:34 | normalizedPath | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | | normalizedPaths.js:205:21:205:34 | normalizedPath | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:205:21:205:34 | normalizedPath | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | | normalizedPaths.js:208:21:208:34 | normalizedPath | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:208:21:208:34 | normalizedPath | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | -| normalizedPaths.js:208:21:208:34 | normalizedPath | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:208:21:208:34 | normalizedPath | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | -| normalizedPaths.js:208:21:208:34 | normalizedPath | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:208:21:208:34 | normalizedPath | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | -| normalizedPaths.js:208:21:208:34 | normalizedPath | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:208:21:208:34 | normalizedPath | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | | normalizedPaths.js:210:21:210:34 | normalizedPath | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:210:21:210:34 | normalizedPath | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | -| normalizedPaths.js:210:21:210:34 | normalizedPath | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:210:21:210:34 | normalizedPath | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | -| normalizedPaths.js:210:21:210:34 | normalizedPath | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:210:21:210:34 | normalizedPath | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | -| normalizedPaths.js:210:21:210:34 | normalizedPath | normalizedPaths.js:174:14:174:27 | req.query.path | normalizedPaths.js:210:21:210:34 | normalizedPath | This path depends on $@. | normalizedPaths.js:174:14:174:27 | req.query.path | a user-provided value | -| normalizedPaths.js:222:21:222:24 | path | normalizedPaths.js:214:35:214:48 | req.query.path | normalizedPaths.js:222:21:222:24 | path | This path depends on $@. | normalizedPaths.js:214:35:214:48 | req.query.path | a user-provided value | -| normalizedPaths.js:222:21:222:24 | path | normalizedPaths.js:214:35:214:48 | req.query.path | normalizedPaths.js:222:21:222:24 | path | This path depends on $@. | normalizedPaths.js:214:35:214:48 | req.query.path | a user-provided value | -| normalizedPaths.js:222:21:222:24 | path | normalizedPaths.js:214:35:214:48 | req.query.path | normalizedPaths.js:222:21:222:24 | path | This path depends on $@. | normalizedPaths.js:214:35:214:48 | req.query.path | a user-provided value | | normalizedPaths.js:222:21:222:24 | path | normalizedPaths.js:214:35:214:48 | req.query.path | normalizedPaths.js:222:21:222:24 | path | This path depends on $@. | normalizedPaths.js:214:35:214:48 | req.query.path | a user-provided value | | normalizedPaths.js:228:21:228:24 | path | normalizedPaths.js:226:35:226:48 | req.query.path | normalizedPaths.js:228:21:228:24 | path | This path depends on $@. | normalizedPaths.js:226:35:226:48 | req.query.path | a user-provided value | -| normalizedPaths.js:228:21:228:24 | path | normalizedPaths.js:226:35:226:48 | req.query.path | normalizedPaths.js:228:21:228:24 | path | This path depends on $@. | normalizedPaths.js:226:35:226:48 | req.query.path | a user-provided value | -| tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | This path depends on $@. | tainted-require.js:7:19:7:37 | req.param("module") | a user-provided value | -| tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | This path depends on $@. | tainted-require.js:7:19:7:37 | req.param("module") | a user-provided value | -| tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | This path depends on $@. | tainted-require.js:7:19:7:37 | req.param("module") | a user-provided value | | tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | This path depends on $@. | tainted-require.js:7:19:7:37 | req.param("module") | a user-provided value | | tainted-sendFile.js:8:16:8:33 | req.param("gimme") | tainted-sendFile.js:8:16:8:33 | req.param("gimme") | tainted-sendFile.js:8:16:8:33 | req.param("gimme") | This path depends on $@. | tainted-sendFile.js:8:16:8:33 | req.param("gimme") | a user-provided value | -| tainted-sendFile.js:8:16:8:33 | req.param("gimme") | tainted-sendFile.js:8:16:8:33 | req.param("gimme") | tainted-sendFile.js:8:16:8:33 | req.param("gimme") | This path depends on $@. | tainted-sendFile.js:8:16:8:33 | req.param("gimme") | a user-provided value | -| tainted-sendFile.js:10:16:10:33 | req.param("gimme") | tainted-sendFile.js:10:16:10:33 | req.param("gimme") | tainted-sendFile.js:10:16:10:33 | req.param("gimme") | This path depends on $@. | tainted-sendFile.js:10:16:10:33 | req.param("gimme") | a user-provided value | | tainted-sendFile.js:10:16:10:33 | req.param("gimme") | tainted-sendFile.js:10:16:10:33 | req.param("gimme") | tainted-sendFile.js:10:16:10:33 | req.param("gimme") | This path depends on $@. | tainted-sendFile.js:10:16:10:33 | req.param("gimme") | a user-provided value | | tainted-sendFile.js:18:43:18:58 | req.param("dir") | tainted-sendFile.js:18:43:18:58 | req.param("dir") | tainted-sendFile.js:18:43:18:58 | req.param("dir") | This path depends on $@. | tainted-sendFile.js:18:43:18:58 | req.param("dir") | a user-provided value | -| tainted-sendFile.js:18:43:18:58 | req.param("dir") | tainted-sendFile.js:18:43:18:58 | req.param("dir") | tainted-sendFile.js:18:43:18:58 | req.param("dir") | This path depends on $@. | tainted-sendFile.js:18:43:18:58 | req.param("dir") | a user-provided value | -| tainted-sendFile.js:18:43:18:58 | req.param("dir") | tainted-sendFile.js:18:43:18:58 | req.param("dir") | tainted-sendFile.js:18:43:18:58 | req.param("dir") | This path depends on $@. | tainted-sendFile.js:18:43:18:58 | req.param("dir") | a user-provided value | -| tainted-sendFile.js:18:43:18:58 | req.param("dir") | tainted-sendFile.js:18:43:18:58 | req.param("dir") | tainted-sendFile.js:18:43:18:58 | req.param("dir") | This path depends on $@. | tainted-sendFile.js:18:43:18:58 | req.param("dir") | a user-provided value | -| tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | This path depends on $@. | tainted-sendFile.js:24:37:24:48 | req.params.x | a user-provided value | -| tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | This path depends on $@. | tainted-sendFile.js:24:37:24:48 | req.params.x | a user-provided value | -| tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | This path depends on $@. | tainted-sendFile.js:24:37:24:48 | req.params.x | a user-provided value | | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | tainted-sendFile.js:24:37:24:48 | req.params.x | tainted-sendFile.js:24:16:24:49 | path.re ... rams.x) | This path depends on $@. | tainted-sendFile.js:24:37:24:48 | req.params.x | a user-provided value | | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | This path depends on $@. | tainted-sendFile.js:25:34:25:45 | req.params.x | a user-provided value | -| tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | This path depends on $@. | tainted-sendFile.js:25:34:25:45 | req.params.x | a user-provided value | -| tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | tainted-sendFile.js:25:34:25:45 | req.params.x | tainted-sendFile.js:25:16:25:46 | path.jo ... rams.x) | This path depends on $@. | tainted-sendFile.js:25:34:25:45 | req.params.x | a user-provided value | -| views.js:1:43:1:55 | req.params[0] | views.js:1:43:1:55 | req.params[0] | views.js:1:43:1:55 | req.params[0] | This path depends on $@. | views.js:1:43:1:55 | req.params[0] | a user-provided value | -| views.js:1:43:1:55 | req.params[0] | views.js:1:43:1:55 | req.params[0] | views.js:1:43:1:55 | req.params[0] | This path depends on $@. | views.js:1:43:1:55 | req.params[0] | a user-provided value | -| views.js:1:43:1:55 | req.params[0] | views.js:1:43:1:55 | req.params[0] | views.js:1:43:1:55 | req.params[0] | This path depends on $@. | views.js:1:43:1:55 | req.params[0] | a user-provided value | | views.js:1:43:1:55 | req.params[0] | views.js:1:43:1:55 | req.params[0] | views.js:1:43:1:55 | req.params[0] | This path depends on $@. | views.js:1:43:1:55 | req.params[0] | a user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-022/ZipSlip/ZipSlip.expected b/javascript/ql/test/query-tests/Security/CWE-022/ZipSlip/ZipSlip.expected index f9415bcd8ac..3bcb0a5c135 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/ZipSlip/ZipSlip.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/ZipSlip/ZipSlip.expected @@ -1,23 +1,41 @@ nodes | AdmZipBad.js:6:24:6:41 | zipEntry.entryName | +| AdmZipBad.js:6:24:6:41 | zipEntry.entryName | +| AdmZipBad.js:6:24:6:41 | zipEntry.entryName | +| TarSlipBad.js:6:36:6:46 | header.name | +| TarSlipBad.js:6:36:6:46 | header.name | | TarSlipBad.js:6:36:6:46 | header.name | | ZipSlipBad2.js:5:9:5:46 | fileName | | ZipSlipBad2.js:5:20:5:46 | 'output ... ry.path | | ZipSlipBad2.js:5:37:5:46 | entry.path | +| ZipSlipBad2.js:5:37:5:46 | entry.path | +| ZipSlipBad2.js:6:22:6:29 | fileName | | ZipSlipBad2.js:6:22:6:29 | fileName | | ZipSlipBad.js:7:11:7:31 | fileName | | ZipSlipBad.js:7:22:7:31 | entry.path | +| ZipSlipBad.js:7:22:7:31 | entry.path | +| ZipSlipBad.js:8:37:8:44 | fileName | | ZipSlipBad.js:8:37:8:44 | fileName | | ZipSlipBadUnzipper.js:7:9:7:29 | fileName | | ZipSlipBadUnzipper.js:7:20:7:29 | entry.path | +| ZipSlipBadUnzipper.js:7:20:7:29 | entry.path | +| ZipSlipBadUnzipper.js:8:37:8:44 | fileName | | ZipSlipBadUnzipper.js:8:37:8:44 | fileName | edges +| AdmZipBad.js:6:24:6:41 | zipEntry.entryName | AdmZipBad.js:6:24:6:41 | zipEntry.entryName | +| TarSlipBad.js:6:36:6:46 | header.name | TarSlipBad.js:6:36:6:46 | header.name | +| ZipSlipBad2.js:5:9:5:46 | fileName | ZipSlipBad2.js:6:22:6:29 | fileName | | ZipSlipBad2.js:5:9:5:46 | fileName | ZipSlipBad2.js:6:22:6:29 | fileName | | ZipSlipBad2.js:5:20:5:46 | 'output ... ry.path | ZipSlipBad2.js:5:9:5:46 | fileName | | ZipSlipBad2.js:5:37:5:46 | entry.path | ZipSlipBad2.js:5:20:5:46 | 'output ... ry.path | +| ZipSlipBad2.js:5:37:5:46 | entry.path | ZipSlipBad2.js:5:20:5:46 | 'output ... ry.path | +| ZipSlipBad.js:7:11:7:31 | fileName | ZipSlipBad.js:8:37:8:44 | fileName | | ZipSlipBad.js:7:11:7:31 | fileName | ZipSlipBad.js:8:37:8:44 | fileName | | ZipSlipBad.js:7:22:7:31 | entry.path | ZipSlipBad.js:7:11:7:31 | fileName | +| ZipSlipBad.js:7:22:7:31 | entry.path | ZipSlipBad.js:7:11:7:31 | fileName | | ZipSlipBadUnzipper.js:7:9:7:29 | fileName | ZipSlipBadUnzipper.js:8:37:8:44 | fileName | +| ZipSlipBadUnzipper.js:7:9:7:29 | fileName | ZipSlipBadUnzipper.js:8:37:8:44 | fileName | +| ZipSlipBadUnzipper.js:7:20:7:29 | entry.path | ZipSlipBadUnzipper.js:7:9:7:29 | fileName | | ZipSlipBadUnzipper.js:7:20:7:29 | entry.path | ZipSlipBadUnzipper.js:7:9:7:29 | fileName | #select | AdmZipBad.js:6:24:6:41 | zipEntry.entryName | AdmZipBad.js:6:24:6:41 | zipEntry.entryName | AdmZipBad.js:6:24:6:41 | zipEntry.entryName | Unsanitized zip archive $@, which may contain '..', is used in a file system operation. | AdmZipBad.js:6:24:6:41 | zipEntry.entryName | item path | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection.expected b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection.expected index 8b058d2e799..abfab9e262d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/CommandInjection.expected @@ -4,38 +4,30 @@ nodes | child_process-test.js:6:15:6:44 | url.par ... ).query | | child_process-test.js:6:15:6:49 | url.par ... ry.path | | child_process-test.js:6:25:6:31 | req.url | +| child_process-test.js:6:25:6:31 | req.url | +| child_process-test.js:17:13:17:15 | cmd | | child_process-test.js:17:13:17:15 | cmd | | child_process-test.js:18:17:18:19 | cmd | +| child_process-test.js:18:17:18:19 | cmd | +| child_process-test.js:19:17:19:19 | cmd | | child_process-test.js:19:17:19:19 | cmd | | child_process-test.js:20:21:20:23 | cmd | +| child_process-test.js:20:21:20:23 | cmd | +| child_process-test.js:21:14:21:16 | cmd | | child_process-test.js:21:14:21:16 | cmd | | child_process-test.js:22:18:22:20 | cmd | +| child_process-test.js:22:18:22:20 | cmd | +| child_process-test.js:23:13:23:15 | cmd | | child_process-test.js:23:13:23:15 | cmd | | child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" | +| child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" | | child_process-test.js:25:21:25:23 | cmd | -| child_process-test.js:36:7:36:20 | sh | -| child_process-test.js:36:12:36:20 | 'cmd.exe' | -| child_process-test.js:38:7:38:20 | sh | -| child_process-test.js:38:12:38:20 | '/bin/sh' | -| child_process-test.js:39:14:39:15 | sh | -| child_process-test.js:39:18:39:30 | [ flag, cmd ] | | child_process-test.js:39:26:39:28 | cmd | -| child_process-test.js:41:9:41:17 | args | -| child_process-test.js:41:16:41:17 | [] | +| child_process-test.js:39:26:39:28 | cmd | +| child_process-test.js:43:15:43:17 | cmd | | child_process-test.js:43:15:43:17 | cmd | -| child_process-test.js:44:17:44:27 | "/bin/bash" | -| child_process-test.js:44:30:44:33 | args | -| child_process-test.js:46:9:46:12 | "sh" | -| child_process-test.js:46:15:46:18 | args | -| child_process-test.js:48:9:48:17 | args | -| child_process-test.js:48:16:48:17 | [] | | child_process-test.js:50:15:50:17 | cmd | -| child_process-test.js:51:17:51:32 | `/bin` + "/bash" | -| child_process-test.js:51:35:51:38 | args | -| child_process-test.js:55:14:55:16 | cmd | -| child_process-test.js:55:19:55:22 | args | -| child_process-test.js:56:12:56:14 | cmd | -| child_process-test.js:56:17:56:20 | args | +| child_process-test.js:50:15:50:17 | cmd | | execSeries.js:3:20:3:22 | arr | | execSeries.js:6:14:6:16 | arr | | execSeries.js:6:14:6:21 | arr[i++] | @@ -43,11 +35,13 @@ nodes | execSeries.js:14:13:14:20 | commands | | execSeries.js:14:24:14:30 | command | | execSeries.js:14:41:14:47 | command | +| execSeries.js:14:41:14:47 | command | | execSeries.js:18:7:18:58 | cmd | | execSeries.js:18:13:18:47 | require ... , true) | | execSeries.js:18:13:18:53 | require ... ).query | | execSeries.js:18:13:18:58 | require ... ry.path | | execSeries.js:18:34:18:40 | req.url | +| execSeries.js:18:34:18:40 | req.url | | execSeries.js:19:12:19:16 | [cmd] | | execSeries.js:19:13:19:15 | cmd | | other.js:5:9:5:49 | cmd | @@ -55,88 +49,112 @@ nodes | other.js:5:15:5:44 | url.par ... ).query | | other.js:5:15:5:49 | url.par ... ry.path | | other.js:5:25:5:31 | req.url | +| other.js:5:25:5:31 | req.url | +| other.js:7:33:7:35 | cmd | | other.js:7:33:7:35 | cmd | | other.js:8:28:8:30 | cmd | +| other.js:8:28:8:30 | cmd | +| other.js:9:32:9:34 | cmd | | other.js:9:32:9:34 | cmd | | other.js:10:29:10:31 | cmd | +| other.js:10:29:10:31 | cmd | +| other.js:11:29:11:31 | cmd | | other.js:11:29:11:31 | cmd | | other.js:12:27:12:29 | cmd | +| other.js:12:27:12:29 | cmd | +| other.js:14:28:14:30 | cmd | | other.js:14:28:14:30 | cmd | | other.js:15:34:15:36 | cmd | +| other.js:15:34:15:36 | cmd | +| other.js:16:21:16:23 | cmd | | other.js:16:21:16:23 | cmd | | other.js:17:27:17:29 | cmd | +| other.js:17:27:17:29 | cmd | +| other.js:18:22:18:24 | cmd | | other.js:18:22:18:24 | cmd | | other.js:19:36:19:38 | cmd | +| other.js:19:36:19:38 | cmd | +| third-party-command-injection.js:5:20:5:26 | command | | third-party-command-injection.js:5:20:5:26 | command | | third-party-command-injection.js:6:21:6:27 | command | -| tst_shell-command-injection-from-environment.js:4:25:4:61 | ['-rf', ... temp")] | +| third-party-command-injection.js:6:21:6:27 | command | edges | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:17:13:17:15 | cmd | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:17:13:17:15 | cmd | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:18:17:18:19 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:18:17:18:19 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:19:17:19:19 | cmd | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:19:17:19:19 | cmd | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:20:21:20:23 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:20:21:20:23 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:21:14:21:16 | cmd | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:21:14:21:16 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:22:18:22:20 | cmd | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:22:18:22:20 | cmd | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:23:13:23:15 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:23:13:23:15 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:25:21:25:23 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:39:26:39:28 | cmd | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:39:26:39:28 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:43:15:43:17 | cmd | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:43:15:43:17 | cmd | +| child_process-test.js:6:9:6:49 | cmd | child_process-test.js:50:15:50:17 | cmd | | child_process-test.js:6:9:6:49 | cmd | child_process-test.js:50:15:50:17 | cmd | | child_process-test.js:6:15:6:38 | url.par ... , true) | child_process-test.js:6:15:6:44 | url.par ... ).query | | child_process-test.js:6:15:6:44 | url.par ... ).query | child_process-test.js:6:15:6:49 | url.par ... ry.path | | child_process-test.js:6:15:6:49 | url.par ... ry.path | child_process-test.js:6:9:6:49 | cmd | | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:6:15:6:38 | url.par ... , true) | -| child_process-test.js:25:13:25:23 | "foo" + cmd | child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" | -| child_process-test.js:25:21:25:23 | cmd | child_process-test.js:25:13:25:23 | "foo" + cmd | +| child_process-test.js:6:25:6:31 | req.url | child_process-test.js:6:15:6:38 | url.par ... , true) | +| child_process-test.js:25:21:25:23 | cmd | child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" | | child_process-test.js:25:21:25:23 | cmd | child_process-test.js:25:13:25:31 | "foo" + cmd + "bar" | -| child_process-test.js:36:7:36:20 | sh | child_process-test.js:39:5:39:5 | sh | -| child_process-test.js:36:7:36:20 | sh | child_process-test.js:39:14:39:15 | sh | -| child_process-test.js:36:12:36:20 | 'cmd.exe' | child_process-test.js:36:7:36:20 | sh | -| child_process-test.js:38:7:38:20 | sh | child_process-test.js:39:5:39:5 | sh | -| child_process-test.js:38:7:38:20 | sh | child_process-test.js:39:14:39:15 | sh | -| child_process-test.js:38:12:38:20 | '/bin/sh' | child_process-test.js:38:7:38:20 | sh | -| child_process-test.js:39:5:39:5 | sh | child_process-test.js:39:14:39:15 | sh | -| child_process-test.js:41:9:41:17 | args | child_process-test.js:44:30:44:33 | args | -| child_process-test.js:41:9:41:17 | args | child_process-test.js:46:15:46:18 | args | -| child_process-test.js:41:16:41:17 | [] | child_process-test.js:41:9:41:17 | args | -| child_process-test.js:46:9:46:12 | "sh" | child_process-test.js:55:14:55:16 | cmd | -| child_process-test.js:46:15:46:18 | args | child_process-test.js:55:19:55:22 | args | -| child_process-test.js:48:9:48:17 | args | child_process-test.js:51:35:51:38 | args | -| child_process-test.js:48:16:48:17 | [] | child_process-test.js:48:9:48:17 | args | -| child_process-test.js:55:14:55:16 | cmd | child_process-test.js:56:12:56:14 | cmd | -| child_process-test.js:55:19:55:22 | args | child_process-test.js:56:17:56:20 | args | -| execSeries.js:3:20:3:22 | arr | execSeries.js:5:4:5:3 | arr | | execSeries.js:3:20:3:22 | arr | execSeries.js:6:14:6:16 | arr | -| execSeries.js:5:4:5:3 | arr | execSeries.js:6:14:6:16 | arr | | execSeries.js:6:14:6:16 | arr | execSeries.js:6:14:6:21 | arr[i++] | | execSeries.js:6:14:6:21 | arr[i++] | execSeries.js:14:24:14:30 | command | | execSeries.js:13:19:13:26 | commands | execSeries.js:14:13:14:20 | commands | | execSeries.js:14:13:14:20 | commands | execSeries.js:3:20:3:22 | arr | | execSeries.js:14:13:14:20 | commands | execSeries.js:14:24:14:30 | command | | execSeries.js:14:24:14:30 | command | execSeries.js:14:41:14:47 | command | +| execSeries.js:14:24:14:30 | command | execSeries.js:14:41:14:47 | command | | execSeries.js:18:7:18:58 | cmd | execSeries.js:19:13:19:15 | cmd | | execSeries.js:18:13:18:47 | require ... , true) | execSeries.js:18:13:18:53 | require ... ).query | | execSeries.js:18:13:18:53 | require ... ).query | execSeries.js:18:13:18:58 | require ... ry.path | | execSeries.js:18:13:18:58 | require ... ry.path | execSeries.js:18:7:18:58 | cmd | | execSeries.js:18:34:18:40 | req.url | execSeries.js:18:13:18:47 | require ... , true) | +| execSeries.js:18:34:18:40 | req.url | execSeries.js:18:13:18:47 | require ... , true) | | execSeries.js:19:12:19:16 | [cmd] | execSeries.js:13:19:13:26 | commands | | execSeries.js:19:13:19:15 | cmd | execSeries.js:19:12:19:16 | [cmd] | | other.js:5:9:5:49 | cmd | other.js:7:33:7:35 | cmd | +| other.js:5:9:5:49 | cmd | other.js:7:33:7:35 | cmd | +| other.js:5:9:5:49 | cmd | other.js:8:28:8:30 | cmd | | other.js:5:9:5:49 | cmd | other.js:8:28:8:30 | cmd | | other.js:5:9:5:49 | cmd | other.js:9:32:9:34 | cmd | +| other.js:5:9:5:49 | cmd | other.js:9:32:9:34 | cmd | +| other.js:5:9:5:49 | cmd | other.js:10:29:10:31 | cmd | | other.js:5:9:5:49 | cmd | other.js:10:29:10:31 | cmd | | other.js:5:9:5:49 | cmd | other.js:11:29:11:31 | cmd | +| other.js:5:9:5:49 | cmd | other.js:11:29:11:31 | cmd | +| other.js:5:9:5:49 | cmd | other.js:12:27:12:29 | cmd | | other.js:5:9:5:49 | cmd | other.js:12:27:12:29 | cmd | | other.js:5:9:5:49 | cmd | other.js:14:28:14:30 | cmd | +| other.js:5:9:5:49 | cmd | other.js:14:28:14:30 | cmd | +| other.js:5:9:5:49 | cmd | other.js:15:34:15:36 | cmd | | other.js:5:9:5:49 | cmd | other.js:15:34:15:36 | cmd | | other.js:5:9:5:49 | cmd | other.js:16:21:16:23 | cmd | +| other.js:5:9:5:49 | cmd | other.js:16:21:16:23 | cmd | +| other.js:5:9:5:49 | cmd | other.js:17:27:17:29 | cmd | | other.js:5:9:5:49 | cmd | other.js:17:27:17:29 | cmd | | other.js:5:9:5:49 | cmd | other.js:18:22:18:24 | cmd | +| other.js:5:9:5:49 | cmd | other.js:18:22:18:24 | cmd | +| other.js:5:9:5:49 | cmd | other.js:19:36:19:38 | cmd | | other.js:5:9:5:49 | cmd | other.js:19:36:19:38 | cmd | | other.js:5:15:5:38 | url.par ... , true) | other.js:5:15:5:44 | url.par ... ).query | | other.js:5:15:5:44 | url.par ... ).query | other.js:5:15:5:49 | url.par ... ry.path | | other.js:5:15:5:49 | url.par ... ry.path | other.js:5:9:5:49 | cmd | | other.js:5:25:5:31 | req.url | other.js:5:15:5:38 | url.par ... , true) | +| other.js:5:25:5:31 | req.url | other.js:5:15:5:38 | url.par ... , true) | +| third-party-command-injection.js:5:20:5:26 | command | third-party-command-injection.js:6:21:6:27 | command | +| third-party-command-injection.js:5:20:5:26 | command | third-party-command-injection.js:6:21:6:27 | command | +| third-party-command-injection.js:5:20:5:26 | command | third-party-command-injection.js:6:21:6:27 | command | | third-party-command-injection.js:5:20:5:26 | command | third-party-command-injection.js:6:21:6:27 | command | #select | child_process-test.js:17:13:17:15 | cmd | child_process-test.js:6:25:6:31 | req.url | child_process-test.js:17:13:17:15 | cmd | This command depends on $@. | child_process-test.js:6:25:6:31 | req.url | a user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection.expected b/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection.expected index bd142297996..9377069360e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/IndirectCommandInjection.expected @@ -1,33 +1,20 @@ nodes -| child_process-test.js:36:7:36:20 | sh | -| child_process-test.js:36:12:36:20 | 'cmd.exe' | -| child_process-test.js:38:7:38:20 | sh | -| child_process-test.js:38:12:38:20 | '/bin/sh' | -| child_process-test.js:39:14:39:15 | sh | -| child_process-test.js:39:18:39:30 | [ flag, cmd ] | -| child_process-test.js:41:9:41:17 | args | -| child_process-test.js:41:16:41:17 | [] | -| child_process-test.js:44:17:44:27 | "/bin/bash" | -| child_process-test.js:44:30:44:33 | args | -| child_process-test.js:46:9:46:12 | "sh" | -| child_process-test.js:46:15:46:18 | args | -| child_process-test.js:48:9:48:17 | args | -| child_process-test.js:48:16:48:17 | [] | -| child_process-test.js:51:17:51:32 | `/bin` + "/bash" | -| child_process-test.js:51:35:51:38 | args | -| child_process-test.js:55:14:55:16 | cmd | -| child_process-test.js:55:19:55:22 | args | -| child_process-test.js:56:12:56:14 | cmd | -| child_process-test.js:56:17:56:20 | args | +| command-line-parameter-command-injection.js:4:10:4:21 | process.argv | +| command-line-parameter-command-injection.js:4:10:4:21 | process.argv | | command-line-parameter-command-injection.js:4:10:4:21 | process.argv | | command-line-parameter-command-injection.js:8:10:8:36 | "cmd.sh ... argv[2] | +| command-line-parameter-command-injection.js:8:10:8:36 | "cmd.sh ... argv[2] | +| command-line-parameter-command-injection.js:8:22:8:33 | process.argv | | command-line-parameter-command-injection.js:8:22:8:33 | process.argv | | command-line-parameter-command-injection.js:8:22:8:36 | process.argv[2] | | command-line-parameter-command-injection.js:10:6:10:33 | args | | command-line-parameter-command-injection.js:10:13:10:24 | process.argv | +| command-line-parameter-command-injection.js:10:13:10:24 | process.argv | | command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) | | command-line-parameter-command-injection.js:11:14:11:17 | args | | command-line-parameter-command-injection.js:11:14:11:20 | args[0] | +| command-line-parameter-command-injection.js:11:14:11:20 | args[0] | +| command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] | | command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] | | command-line-parameter-command-injection.js:12:26:12:29 | args | | command-line-parameter-command-injection.js:12:26:12:32 | args[0] | @@ -36,6 +23,8 @@ nodes | command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) | | command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs | | command-line-parameter-command-injection.js:15:14:15:25 | fewerArgs[0] | +| command-line-parameter-command-injection.js:15:14:15:25 | fewerArgs[0] | +| command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] | | command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] | | command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs | | command-line-parameter-command-injection.js:16:26:16:37 | fewerArgs[0] | @@ -43,66 +32,67 @@ nodes | command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs | | command-line-parameter-command-injection.js:18:13:18:24 | fewerArgs[0] | | command-line-parameter-command-injection.js:19:14:19:17 | arg0 | +| command-line-parameter-command-injection.js:19:14:19:17 | arg0 | +| command-line-parameter-command-injection.js:20:14:20:29 | "cmd.sh " + arg0 | | command-line-parameter-command-injection.js:20:14:20:29 | "cmd.sh " + arg0 | | command-line-parameter-command-injection.js:20:26:20:29 | arg0 | | command-line-parameter-command-injection.js:24:8:24:35 | args | | command-line-parameter-command-injection.js:24:15:24:26 | process.argv | +| command-line-parameter-command-injection.js:24:15:24:26 | process.argv | | command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) | | command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | +| command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | | command-line-parameter-command-injection.js:26:32:26:35 | args | | command-line-parameter-command-injection.js:26:32:26:38 | args[0] | | command-line-parameter-command-injection.js:27:14:27:57 | `node $ ... ption"` | +| command-line-parameter-command-injection.js:27:14:27:57 | `node $ ... ption"` | | command-line-parameter-command-injection.js:27:32:27:35 | args | | command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | -| tst_shell-command-injection-from-environment.js:4:25:4:61 | ['-rf', ... temp")] | edges -| child_process-test.js:36:7:36:20 | sh | child_process-test.js:39:5:39:5 | sh | -| child_process-test.js:36:7:36:20 | sh | child_process-test.js:39:14:39:15 | sh | -| child_process-test.js:36:12:36:20 | 'cmd.exe' | child_process-test.js:36:7:36:20 | sh | -| child_process-test.js:38:7:38:20 | sh | child_process-test.js:39:5:39:5 | sh | -| child_process-test.js:38:7:38:20 | sh | child_process-test.js:39:14:39:15 | sh | -| child_process-test.js:38:12:38:20 | '/bin/sh' | child_process-test.js:38:7:38:20 | sh | -| child_process-test.js:39:5:39:5 | sh | child_process-test.js:39:14:39:15 | sh | -| child_process-test.js:41:9:41:17 | args | child_process-test.js:44:30:44:33 | args | -| child_process-test.js:41:9:41:17 | args | child_process-test.js:46:15:46:18 | args | -| child_process-test.js:41:16:41:17 | [] | child_process-test.js:41:9:41:17 | args | -| child_process-test.js:46:9:46:12 | "sh" | child_process-test.js:55:14:55:16 | cmd | -| child_process-test.js:46:15:46:18 | args | child_process-test.js:55:19:55:22 | args | -| child_process-test.js:48:9:48:17 | args | child_process-test.js:51:35:51:38 | args | -| child_process-test.js:48:16:48:17 | [] | child_process-test.js:48:9:48:17 | args | -| child_process-test.js:55:14:55:16 | cmd | child_process-test.js:56:12:56:14 | cmd | -| child_process-test.js:55:19:55:22 | args | child_process-test.js:56:17:56:20 | args | +| command-line-parameter-command-injection.js:4:10:4:21 | process.argv | command-line-parameter-command-injection.js:4:10:4:21 | process.argv | | command-line-parameter-command-injection.js:8:22:8:33 | process.argv | command-line-parameter-command-injection.js:8:22:8:36 | process.argv[2] | +| command-line-parameter-command-injection.js:8:22:8:33 | process.argv | command-line-parameter-command-injection.js:8:22:8:36 | process.argv[2] | +| command-line-parameter-command-injection.js:8:22:8:36 | process.argv[2] | command-line-parameter-command-injection.js:8:10:8:36 | "cmd.sh ... argv[2] | | command-line-parameter-command-injection.js:8:22:8:36 | process.argv[2] | command-line-parameter-command-injection.js:8:10:8:36 | "cmd.sh ... argv[2] | | command-line-parameter-command-injection.js:10:6:10:33 | args | command-line-parameter-command-injection.js:11:14:11:17 | args | | command-line-parameter-command-injection.js:10:6:10:33 | args | command-line-parameter-command-injection.js:12:26:12:29 | args | | command-line-parameter-command-injection.js:10:6:10:33 | args | command-line-parameter-command-injection.js:14:18:14:21 | args | | command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) | +| command-line-parameter-command-injection.js:10:13:10:24 | process.argv | command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) | | command-line-parameter-command-injection.js:10:13:10:33 | process ... lice(2) | command-line-parameter-command-injection.js:10:6:10:33 | args | | command-line-parameter-command-injection.js:11:14:11:17 | args | command-line-parameter-command-injection.js:11:14:11:20 | args[0] | +| command-line-parameter-command-injection.js:11:14:11:17 | args | command-line-parameter-command-injection.js:11:14:11:20 | args[0] | | command-line-parameter-command-injection.js:12:26:12:29 | args | command-line-parameter-command-injection.js:12:26:12:32 | args[0] | | command-line-parameter-command-injection.js:12:26:12:32 | args[0] | command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] | +| command-line-parameter-command-injection.js:12:26:12:32 | args[0] | command-line-parameter-command-injection.js:12:14:12:32 | "cmd.sh " + args[0] | | command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs | | command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs | | command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs | | command-line-parameter-command-injection.js:14:18:14:21 | args | command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) | | command-line-parameter-command-injection.js:14:18:14:30 | args.slice(1) | command-line-parameter-command-injection.js:14:6:14:30 | fewerArgs | | command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs | command-line-parameter-command-injection.js:15:14:15:25 | fewerArgs[0] | +| command-line-parameter-command-injection.js:15:14:15:22 | fewerArgs | command-line-parameter-command-injection.js:15:14:15:25 | fewerArgs[0] | | command-line-parameter-command-injection.js:16:26:16:34 | fewerArgs | command-line-parameter-command-injection.js:16:26:16:37 | fewerArgs[0] | | command-line-parameter-command-injection.js:16:26:16:37 | fewerArgs[0] | command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] | +| command-line-parameter-command-injection.js:16:26:16:37 | fewerArgs[0] | command-line-parameter-command-injection.js:16:14:16:37 | "cmd.sh ... Args[0] | +| command-line-parameter-command-injection.js:18:6:18:24 | arg0 | command-line-parameter-command-injection.js:19:14:19:17 | arg0 | | command-line-parameter-command-injection.js:18:6:18:24 | arg0 | command-line-parameter-command-injection.js:19:14:19:17 | arg0 | | command-line-parameter-command-injection.js:18:6:18:24 | arg0 | command-line-parameter-command-injection.js:20:26:20:29 | arg0 | | command-line-parameter-command-injection.js:18:13:18:21 | fewerArgs | command-line-parameter-command-injection.js:18:13:18:24 | fewerArgs[0] | | command-line-parameter-command-injection.js:18:13:18:24 | fewerArgs[0] | command-line-parameter-command-injection.js:18:6:18:24 | arg0 | | command-line-parameter-command-injection.js:20:26:20:29 | arg0 | command-line-parameter-command-injection.js:20:14:20:29 | "cmd.sh " + arg0 | +| command-line-parameter-command-injection.js:20:26:20:29 | arg0 | command-line-parameter-command-injection.js:20:14:20:29 | "cmd.sh " + arg0 | | command-line-parameter-command-injection.js:24:8:24:35 | args | command-line-parameter-command-injection.js:26:32:26:35 | args | | command-line-parameter-command-injection.js:24:8:24:35 | args | command-line-parameter-command-injection.js:27:32:27:35 | args | | command-line-parameter-command-injection.js:24:15:24:26 | process.argv | command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) | +| command-line-parameter-command-injection.js:24:15:24:26 | process.argv | command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) | | command-line-parameter-command-injection.js:24:15:24:35 | process ... lice(2) | command-line-parameter-command-injection.js:24:8:24:35 | args | | command-line-parameter-command-injection.js:26:32:26:35 | args | command-line-parameter-command-injection.js:26:32:26:38 | args[0] | | command-line-parameter-command-injection.js:26:32:26:38 | args[0] | command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | +| command-line-parameter-command-injection.js:26:32:26:38 | args[0] | command-line-parameter-command-injection.js:26:14:26:50 | `node $ ... ption"` | | command-line-parameter-command-injection.js:27:32:27:35 | args | command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | | command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | command-line-parameter-command-injection.js:27:14:27:57 | `node $ ... ption"` | +| command-line-parameter-command-injection.js:27:32:27:45 | args.join(' ') | command-line-parameter-command-injection.js:27:14:27:57 | `node $ ... ption"` | #select | command-line-parameter-command-injection.js:4:10:4:21 | process.argv | command-line-parameter-command-injection.js:4:10:4:21 | process.argv | command-line-parameter-command-injection.js:4:10:4:21 | process.argv | This command depends on an unsanitized $@. | command-line-parameter-command-injection.js:4:10:4:21 | process.argv | command-line argument | | command-line-parameter-command-injection.js:8:10:8:36 | "cmd.sh ... argv[2] | command-line-parameter-command-injection.js:8:22:8:33 | process.argv | command-line-parameter-command-injection.js:8:10:8:36 | "cmd.sh ... argv[2] | This command depends on an unsanitized $@. | command-line-parameter-command-injection.js:8:22:8:33 | process.argv | command-line argument | diff --git a/javascript/ql/test/query-tests/Security/CWE-078/ShellCommandInjectionFromEnvironment.expected b/javascript/ql/test/query-tests/Security/CWE-078/ShellCommandInjectionFromEnvironment.expected index 9015113f9fb..ec3e7c99ecb 100644 --- a/javascript/ql/test/query-tests/Security/CWE-078/ShellCommandInjectionFromEnvironment.expected +++ b/javascript/ql/test/query-tests/Security/CWE-078/ShellCommandInjectionFromEnvironment.expected @@ -1,46 +1,13 @@ nodes -| child_process-test.js:36:7:36:20 | sh | -| child_process-test.js:36:12:36:20 | 'cmd.exe' | -| child_process-test.js:38:7:38:20 | sh | -| child_process-test.js:38:12:38:20 | '/bin/sh' | -| child_process-test.js:39:14:39:15 | sh | -| child_process-test.js:39:18:39:30 | [ flag, cmd ] | -| child_process-test.js:41:9:41:17 | args | -| child_process-test.js:41:16:41:17 | [] | -| child_process-test.js:44:17:44:27 | "/bin/bash" | -| child_process-test.js:44:30:44:33 | args | -| child_process-test.js:46:9:46:12 | "sh" | -| child_process-test.js:46:15:46:18 | args | -| child_process-test.js:48:9:48:17 | args | -| child_process-test.js:48:16:48:17 | [] | -| child_process-test.js:51:17:51:32 | `/bin` + "/bash" | -| child_process-test.js:51:35:51:38 | args | -| child_process-test.js:55:14:55:16 | cmd | -| child_process-test.js:55:19:55:22 | args | -| child_process-test.js:56:12:56:14 | cmd | -| child_process-test.js:56:17:56:20 | args | -| tst_shell-command-injection-from-environment.js:4:25:4:61 | ['-rf', ... temp")] | +| tst_shell-command-injection-from-environment.js:5:14:5:53 | 'rm -rf ... "temp") | | tst_shell-command-injection-from-environment.js:5:14:5:53 | 'rm -rf ... "temp") | | tst_shell-command-injection-from-environment.js:5:26:5:53 | path.jo ... "temp") | | tst_shell-command-injection-from-environment.js:5:36:5:44 | __dirname | +| tst_shell-command-injection-from-environment.js:5:36:5:44 | __dirname | edges -| child_process-test.js:36:7:36:20 | sh | child_process-test.js:39:5:39:5 | sh | -| child_process-test.js:36:7:36:20 | sh | child_process-test.js:39:14:39:15 | sh | -| child_process-test.js:36:12:36:20 | 'cmd.exe' | child_process-test.js:36:7:36:20 | sh | -| child_process-test.js:38:7:38:20 | sh | child_process-test.js:39:5:39:5 | sh | -| child_process-test.js:38:7:38:20 | sh | child_process-test.js:39:14:39:15 | sh | -| child_process-test.js:38:12:38:20 | '/bin/sh' | child_process-test.js:38:7:38:20 | sh | -| child_process-test.js:39:5:39:5 | sh | child_process-test.js:39:14:39:15 | sh | -| child_process-test.js:41:9:41:17 | args | child_process-test.js:44:30:44:33 | args | -| child_process-test.js:41:9:41:17 | args | child_process-test.js:46:15:46:18 | args | -| child_process-test.js:41:16:41:17 | [] | child_process-test.js:41:9:41:17 | args | -| child_process-test.js:46:9:46:12 | "sh" | child_process-test.js:55:14:55:16 | cmd | -| child_process-test.js:46:15:46:18 | args | child_process-test.js:55:19:55:22 | args | -| child_process-test.js:48:9:48:17 | args | child_process-test.js:51:35:51:38 | args | -| child_process-test.js:48:16:48:17 | [] | child_process-test.js:48:9:48:17 | args | -| child_process-test.js:55:14:55:16 | cmd | child_process-test.js:56:12:56:14 | cmd | -| child_process-test.js:55:19:55:22 | args | child_process-test.js:56:17:56:20 | args | | tst_shell-command-injection-from-environment.js:5:26:5:53 | path.jo ... "temp") | tst_shell-command-injection-from-environment.js:5:14:5:53 | 'rm -rf ... "temp") | +| tst_shell-command-injection-from-environment.js:5:26:5:53 | path.jo ... "temp") | tst_shell-command-injection-from-environment.js:5:14:5:53 | 'rm -rf ... "temp") | +| tst_shell-command-injection-from-environment.js:5:36:5:44 | __dirname | tst_shell-command-injection-from-environment.js:5:26:5:53 | path.jo ... "temp") | | tst_shell-command-injection-from-environment.js:5:36:5:44 | __dirname | tst_shell-command-injection-from-environment.js:5:26:5:53 | path.jo ... "temp") | #select | tst_shell-command-injection-from-environment.js:5:14:5:53 | 'rm -rf ... "temp") | tst_shell-command-injection-from-environment.js:5:36:5:44 | __dirname | tst_shell-command-injection-from-environment.js:5:14:5:53 | 'rm -rf ... "temp") | This shell command depends on an uncontrolled $@. | tst_shell-command-injection-from-environment.js:5:36:5:44 | __dirname | absolute path | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected index 7ba39b3f4a9..bcf54b75580 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected @@ -1,88 +1,132 @@ nodes | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | +| ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | +| ReflectedXss.js:8:33:8:45 | req.params.id | | ReflectedXss.js:8:33:8:45 | req.params.id | | etherpad.js:9:5:9:53 | response | | etherpad.js:9:16:9:30 | req.query.jsonp | +| etherpad.js:9:16:9:30 | req.query.jsonp | | etherpad.js:9:16:9:53 | req.que ... e + ")" | | etherpad.js:11:12:11:19 | response | +| etherpad.js:11:12:11:19 | response | | formatting.js:4:9:4:29 | evil | | formatting.js:4:16:4:29 | req.query.evil | +| formatting.js:4:16:4:29 | req.query.evil | +| formatting.js:6:14:6:47 | util.fo ... , evil) | | formatting.js:6:14:6:47 | util.fo ... , evil) | | formatting.js:6:43:6:46 | evil | | formatting.js:7:14:7:53 | require ... , evil) | +| formatting.js:7:14:7:53 | require ... , evil) | | formatting.js:7:49:7:52 | evil | | partial.js:9:25:9:25 | x | | partial.js:10:14:10:14 | x | | partial.js:10:14:10:18 | x + y | +| partial.js:10:14:10:18 | x + y | +| partial.js:13:42:13:48 | req.url | | partial.js:13:42:13:48 | req.url | | partial.js:18:25:18:25 | x | | partial.js:19:14:19:14 | x | | partial.js:19:14:19:18 | x + y | +| partial.js:19:14:19:18 | x + y | +| partial.js:22:51:22:57 | req.url | | partial.js:22:51:22:57 | req.url | | partial.js:27:25:27:25 | x | | partial.js:28:14:28:14 | x | | partial.js:28:14:28:18 | x + y | +| partial.js:28:14:28:18 | x + y | +| partial.js:31:47:31:53 | req.url | | partial.js:31:47:31:53 | req.url | | partial.js:36:25:36:25 | x | | partial.js:37:14:37:14 | x | | partial.js:37:14:37:18 | x + y | +| partial.js:37:14:37:18 | x + y | +| partial.js:40:43:40:49 | req.url | | partial.js:40:43:40:49 | req.url | | promises.js:5:3:5:59 | new Pro ... .data)) | | promises.js:5:44:5:57 | req.query.data | +| promises.js:5:44:5:57 | req.query.data | | promises.js:6:11:6:11 | x | | promises.js:6:11:6:11 | x | | promises.js:6:25:6:25 | x | | promises.js:6:25:6:25 | x | +| promises.js:6:25:6:25 | x | | tst2.js:6:7:6:30 | p | | tst2.js:6:7:6:30 | r | | tst2.js:6:9:6:9 | p | +| tst2.js:6:9:6:9 | p | +| tst2.js:6:12:6:15 | q: r | | tst2.js:6:12:6:15 | q: r | | tst2.js:7:12:7:12 | p | +| tst2.js:7:12:7:12 | p | +| tst2.js:8:12:8:12 | r | | tst2.js:8:12:8:12 | r | | tst2.js:14:7:14:24 | p | | tst2.js:14:9:14:9 | p | +| tst2.js:14:9:14:9 | p | | tst2.js:18:12:18:12 | p | +| tst2.js:18:12:18:12 | p | +| tst2.js:21:14:21:14 | p | | tst2.js:21:14:21:14 | p | edges | ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | -| etherpad.js:9:5:9:53 | response | etherpad.js:11:3:11:3 | response | +| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | +| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | +| ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | +| etherpad.js:9:5:9:53 | response | etherpad.js:11:12:11:19 | response | | etherpad.js:9:5:9:53 | response | etherpad.js:11:12:11:19 | response | -| etherpad.js:9:16:9:30 | req.query.jsonp | etherpad.js:9:16:9:36 | req.que ... p + "(" | -| etherpad.js:9:16:9:30 | req.query.jsonp | etherpad.js:9:16:9:47 | req.que ... esponse | | etherpad.js:9:16:9:30 | req.query.jsonp | etherpad.js:9:16:9:53 | req.que ... e + ")" | -| etherpad.js:9:16:9:36 | req.que ... p + "(" | etherpad.js:9:16:9:47 | req.que ... esponse | -| etherpad.js:9:16:9:36 | req.que ... p + "(" | etherpad.js:9:16:9:53 | req.que ... e + ")" | -| etherpad.js:9:16:9:47 | req.que ... esponse | etherpad.js:9:16:9:53 | req.que ... e + ")" | +| etherpad.js:9:16:9:30 | req.query.jsonp | etherpad.js:9:16:9:53 | req.que ... e + ")" | | etherpad.js:9:16:9:53 | req.que ... e + ")" | etherpad.js:9:5:9:53 | response | -| etherpad.js:11:3:11:3 | response | etherpad.js:11:12:11:19 | response | | formatting.js:4:9:4:29 | evil | formatting.js:6:43:6:46 | evil | | formatting.js:4:9:4:29 | evil | formatting.js:7:49:7:52 | evil | | formatting.js:4:16:4:29 | req.query.evil | formatting.js:4:9:4:29 | evil | +| formatting.js:4:16:4:29 | req.query.evil | formatting.js:4:9:4:29 | evil | | formatting.js:6:43:6:46 | evil | formatting.js:6:14:6:47 | util.fo ... , evil) | +| formatting.js:6:43:6:46 | evil | formatting.js:6:14:6:47 | util.fo ... , evil) | +| formatting.js:7:49:7:52 | evil | formatting.js:7:14:7:53 | require ... , evil) | | formatting.js:7:49:7:52 | evil | formatting.js:7:14:7:53 | require ... , evil) | | partial.js:9:25:9:25 | x | partial.js:10:14:10:14 | x | | partial.js:10:14:10:14 | x | partial.js:10:14:10:18 | x + y | +| partial.js:10:14:10:14 | x | partial.js:10:14:10:18 | x + y | +| partial.js:13:42:13:48 | req.url | partial.js:9:25:9:25 | x | | partial.js:13:42:13:48 | req.url | partial.js:9:25:9:25 | x | | partial.js:18:25:18:25 | x | partial.js:19:14:19:14 | x | | partial.js:19:14:19:14 | x | partial.js:19:14:19:18 | x + y | +| partial.js:19:14:19:14 | x | partial.js:19:14:19:18 | x + y | +| partial.js:22:51:22:57 | req.url | partial.js:18:25:18:25 | x | | partial.js:22:51:22:57 | req.url | partial.js:18:25:18:25 | x | | partial.js:27:25:27:25 | x | partial.js:28:14:28:14 | x | | partial.js:28:14:28:14 | x | partial.js:28:14:28:18 | x + y | +| partial.js:28:14:28:14 | x | partial.js:28:14:28:18 | x + y | +| partial.js:31:47:31:53 | req.url | partial.js:27:25:27:25 | x | | partial.js:31:47:31:53 | req.url | partial.js:27:25:27:25 | x | | partial.js:36:25:36:25 | x | partial.js:37:14:37:14 | x | | partial.js:37:14:37:14 | x | partial.js:37:14:37:18 | x + y | +| partial.js:37:14:37:14 | x | partial.js:37:14:37:18 | x + y | +| partial.js:40:43:40:49 | req.url | partial.js:36:25:36:25 | x | | partial.js:40:43:40:49 | req.url | partial.js:36:25:36:25 | x | | promises.js:5:3:5:59 | new Pro ... .data)) | promises.js:6:11:6:11 | x | | promises.js:5:44:5:57 | req.query.data | promises.js:5:3:5:59 | new Pro ... .data)) | +| promises.js:5:44:5:57 | req.query.data | promises.js:5:3:5:59 | new Pro ... .data)) | +| promises.js:5:44:5:57 | req.query.data | promises.js:6:11:6:11 | x | | promises.js:5:44:5:57 | req.query.data | promises.js:6:11:6:11 | x | | promises.js:6:11:6:11 | x | promises.js:6:25:6:25 | x | | promises.js:6:11:6:11 | x | promises.js:6:25:6:25 | x | +| promises.js:6:11:6:11 | x | promises.js:6:25:6:25 | x | +| promises.js:6:11:6:11 | x | promises.js:6:25:6:25 | x | +| tst2.js:6:7:6:30 | p | tst2.js:7:12:7:12 | p | | tst2.js:6:7:6:30 | p | tst2.js:7:12:7:12 | p | | tst2.js:6:7:6:30 | r | tst2.js:8:12:8:12 | r | +| tst2.js:6:7:6:30 | r | tst2.js:8:12:8:12 | r | +| tst2.js:6:9:6:9 | p | tst2.js:6:7:6:30 | p | | tst2.js:6:9:6:9 | p | tst2.js:6:7:6:30 | p | | tst2.js:6:12:6:15 | q: r | tst2.js:6:7:6:30 | r | +| tst2.js:6:12:6:15 | q: r | tst2.js:6:7:6:30 | r | +| tst2.js:14:7:14:24 | p | tst2.js:18:12:18:12 | p | | tst2.js:14:7:14:24 | p | tst2.js:18:12:18:12 | p | | tst2.js:14:7:14:24 | p | tst2.js:21:14:21:14 | p | +| tst2.js:14:7:14:24 | p | tst2.js:21:14:21:14 | p | +| tst2.js:14:9:14:9 | p | tst2.js:14:7:14:24 | p | | tst2.js:14:9:14:9 | p | tst2.js:14:7:14:24 | p | #select | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | ReflectedXss.js:8:33:8:45 | req.params.id | ReflectedXss.js:8:14:8:45 | "Unknow ... rams.id | Cross-site scripting vulnerability due to $@. | ReflectedXss.js:8:33:8:45 | req.params.id | user-provided value | @@ -94,7 +138,6 @@ edges | partial.js:28:14:28:18 | x + y | partial.js:31:47:31:53 | req.url | partial.js:28:14:28:18 | x + y | Cross-site scripting vulnerability due to $@. | partial.js:31:47:31:53 | req.url | user-provided value | | partial.js:37:14:37:18 | x + y | partial.js:40:43:40:49 | req.url | partial.js:37:14:37:18 | x + y | Cross-site scripting vulnerability due to $@. | partial.js:40:43:40:49 | req.url | user-provided value | | promises.js:6:25:6:25 | x | promises.js:5:44:5:57 | req.query.data | promises.js:6:25:6:25 | x | Cross-site scripting vulnerability due to $@. | promises.js:5:44:5:57 | req.query.data | user-provided value | -| promises.js:6:25:6:25 | x | promises.js:5:44:5:57 | req.query.data | promises.js:6:25:6:25 | x | Cross-site scripting vulnerability due to $@. | promises.js:5:44:5:57 | req.query.data | user-provided value | | tst2.js:7:12:7:12 | p | tst2.js:6:9:6:9 | p | tst2.js:7:12:7:12 | p | Cross-site scripting vulnerability due to $@. | tst2.js:6:9:6:9 | p | user-provided value | | tst2.js:8:12:8:12 | r | tst2.js:6:12:6:15 | q: r | tst2.js:8:12:8:12 | r | Cross-site scripting vulnerability due to $@. | tst2.js:6:12:6:15 | q: r | user-provided value | | tst2.js:18:12:18:12 | p | tst2.js:14:9:14:9 | p | tst2.js:18:12:18:12 | p | Cross-site scripting vulnerability due to $@. | tst2.js:14:9:14:9 | p | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss.expected index 0370cc7e3c0..b0062e70b78 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss.expected @@ -1,7 +1,11 @@ nodes | xss-through-filenames.js:7:43:7:48 | files1 | +| xss-through-filenames.js:7:43:7:48 | files1 | +| xss-through-filenames.js:8:18:8:23 | files1 | | xss-through-filenames.js:8:18:8:23 | files1 | | xss-through-filenames.js:25:43:25:48 | files1 | +| xss-through-filenames.js:25:43:25:48 | files1 | +| xss-through-filenames.js:26:19:26:24 | files1 | | xss-through-filenames.js:26:19:26:24 | files1 | | xss-through-filenames.js:29:13:29:23 | files2 | | xss-through-filenames.js:29:22:29:23 | [] | @@ -9,14 +13,24 @@ nodes | xss-through-filenames.js:30:34:30:37 | file | | xss-through-filenames.js:31:25:31:28 | file | | xss-through-filenames.js:33:19:33:24 | files2 | +| xss-through-filenames.js:33:19:33:24 | files2 | | xss-through-filenames.js:35:13:35:35 | files3 | | xss-through-filenames.js:35:22:35:35 | format(files2) | | xss-through-filenames.js:35:29:35:34 | files2 | | xss-through-filenames.js:37:19:37:24 | files3 | +| xss-through-filenames.js:37:19:37:24 | files3 | edges | xss-through-filenames.js:7:43:7:48 | files1 | xss-through-filenames.js:8:18:8:23 | files1 | +| xss-through-filenames.js:7:43:7:48 | files1 | xss-through-filenames.js:8:18:8:23 | files1 | +| xss-through-filenames.js:7:43:7:48 | files1 | xss-through-filenames.js:8:18:8:23 | files1 | +| xss-through-filenames.js:7:43:7:48 | files1 | xss-through-filenames.js:8:18:8:23 | files1 | +| xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:26:19:26:24 | files1 | +| xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:26:19:26:24 | files1 | +| xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:26:19:26:24 | files1 | | xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:26:19:26:24 | files1 | | xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:30:9:30:14 | files1 | +| xss-through-filenames.js:25:43:25:48 | files1 | xss-through-filenames.js:30:9:30:14 | files1 | +| xss-through-filenames.js:29:13:29:23 | files2 | xss-through-filenames.js:33:19:33:24 | files2 | | xss-through-filenames.js:29:13:29:23 | files2 | xss-through-filenames.js:33:19:33:24 | files2 | | xss-through-filenames.js:29:13:29:23 | files2 | xss-through-filenames.js:35:29:35:34 | files2 | | xss-through-filenames.js:29:22:29:23 | [] | xss-through-filenames.js:29:13:29:23 | files2 | @@ -24,6 +38,7 @@ edges | xss-through-filenames.js:30:34:30:37 | file | xss-through-filenames.js:31:25:31:28 | file | | xss-through-filenames.js:31:25:31:28 | file | xss-through-filenames.js:29:22:29:23 | [] | | xss-through-filenames.js:35:13:35:35 | files3 | xss-through-filenames.js:37:19:37:24 | files3 | +| xss-through-filenames.js:35:13:35:35 | files3 | xss-through-filenames.js:37:19:37:24 | files3 | | xss-through-filenames.js:35:22:35:35 | format(files2) | xss-through-filenames.js:35:13:35:35 | files3 | | xss-through-filenames.js:35:29:35:34 | files2 | xss-through-filenames.js:35:22:35:35 | format(files2) | #select diff --git a/javascript/ql/test/query-tests/Security/CWE-079/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/Xss.expected index 265d8fe40b5..f29d3e5de0f 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/Xss.expected @@ -1,181 +1,292 @@ nodes | addEventListener.js:1:43:1:47 | event | +| addEventListener.js:1:43:1:47 | event | | addEventListener.js:2:20:2:24 | event | | addEventListener.js:2:20:2:29 | event.data | +| addEventListener.js:2:20:2:29 | event.data | | addEventListener.js:5:43:5:48 | data | | addEventListener.js:5:43:5:48 | {data} | +| addEventListener.js:5:43:5:48 | {data} | | addEventListener.js:5:44:5:47 | data | | addEventListener.js:6:20:6:23 | data | +| addEventListener.js:6:20:6:23 | data | +| addEventListener.js:10:21:10:25 | event | | addEventListener.js:10:21:10:25 | event | | addEventListener.js:12:24:12:28 | event | | addEventListener.js:12:24:12:33 | event.data | +| addEventListener.js:12:24:12:33 | event.data | | jquery.js:2:7:2:40 | tainted | | jquery.js:2:17:2:33 | document.location | +| jquery.js:2:17:2:33 | document.location | | jquery.js:2:17:2:40 | documen ... .search | | jquery.js:4:5:4:11 | tainted | +| jquery.js:4:5:4:11 | tainted | +| jquery.js:7:5:7:34 | "
    " | | jquery.js:7:5:7:34 | "
    " | | jquery.js:7:20:7:26 | tainted | | jquery.js:8:18:8:34 | "XSS: " + tainted | +| jquery.js:8:18:8:34 | "XSS: " + tainted | | jquery.js:8:28:8:34 | tainted | | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | +| nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | +| nodemailer.js:13:50:13:66 | req.query.message | | nodemailer.js:13:50:13:66 | req.query.message | | react-native.js:7:7:7:33 | tainted | | react-native.js:7:17:7:33 | req.param("code") | +| react-native.js:7:17:7:33 | req.param("code") | +| react-native.js:8:18:8:24 | tainted | | react-native.js:8:18:8:24 | tainted | | react-native.js:9:27:9:33 | tainted | +| react-native.js:9:27:9:33 | tainted | +| stored-xss.js:2:39:2:55 | document.location | | stored-xss.js:2:39:2:55 | document.location | | stored-xss.js:2:39:2:62 | documen ... .search | | stored-xss.js:3:35:3:51 | document.location | +| stored-xss.js:3:35:3:51 | document.location | | stored-xss.js:3:35:3:58 | documen ... .search | | stored-xss.js:5:20:5:52 | session ... ssion') | +| stored-xss.js:5:20:5:52 | session ... ssion') | +| stored-xss.js:8:20:8:48 | localSt ... local') | | stored-xss.js:8:20:8:48 | localSt ... local') | | string-manipulations.js:3:16:3:32 | document.location | +| string-manipulations.js:3:16:3:32 | document.location | +| string-manipulations.js:3:16:3:32 | document.location | +| string-manipulations.js:4:16:4:32 | document.location | | string-manipulations.js:4:16:4:32 | document.location | | string-manipulations.js:4:16:4:37 | documen ... on.href | +| string-manipulations.js:4:16:4:37 | documen ... on.href | +| string-manipulations.js:5:16:5:32 | document.location | | string-manipulations.js:5:16:5:32 | document.location | | string-manipulations.js:5:16:5:37 | documen ... on.href | | string-manipulations.js:5:16:5:47 | documen ... lueOf() | +| string-manipulations.js:5:16:5:47 | documen ... lueOf() | +| string-manipulations.js:6:16:6:32 | document.location | | string-manipulations.js:6:16:6:32 | document.location | | string-manipulations.js:6:16:6:37 | documen ... on.href | | string-manipulations.js:6:16:6:43 | documen ... f.sup() | +| string-manipulations.js:6:16:6:43 | documen ... f.sup() | +| string-manipulations.js:7:16:7:32 | document.location | | string-manipulations.js:7:16:7:32 | document.location | | string-manipulations.js:7:16:7:37 | documen ... on.href | | string-manipulations.js:7:16:7:51 | documen ... rCase() | +| string-manipulations.js:7:16:7:51 | documen ... rCase() | +| string-manipulations.js:8:16:8:32 | document.location | | string-manipulations.js:8:16:8:32 | document.location | | string-manipulations.js:8:16:8:37 | documen ... on.href | | string-manipulations.js:8:16:8:48 | documen ... mLeft() | +| string-manipulations.js:8:16:8:48 | documen ... mLeft() | | string-manipulations.js:9:16:9:58 | String. ... n.href) | +| string-manipulations.js:9:16:9:58 | String. ... n.href) | +| string-manipulations.js:9:36:9:52 | document.location | | string-manipulations.js:9:36:9:52 | document.location | | string-manipulations.js:9:36:9:57 | documen ... on.href | | string-manipulations.js:10:16:10:45 | String( ... n.href) | +| string-manipulations.js:10:16:10:45 | String( ... n.href) | +| string-manipulations.js:10:23:10:39 | document.location | | string-manipulations.js:10:23:10:39 | document.location | | string-manipulations.js:10:23:10:44 | documen ... on.href | | translate.js:6:7:6:39 | target | | translate.js:6:16:6:32 | document.location | +| translate.js:6:16:6:32 | document.location | | translate.js:6:16:6:39 | documen ... .search | | translate.js:7:42:7:47 | target | | translate.js:7:42:7:60 | target.substring(1) | | translate.js:9:27:9:50 | searchP ... 'term') | +| translate.js:9:27:9:50 | searchP ... 'term') | | tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | | tst3.js:2:23:2:74 | decodeU ... str(1)) | | tst3.js:2:42:2:56 | window.location | +| tst3.js:2:42:2:56 | window.location | | tst3.js:2:42:2:63 | window. ... .search | | tst3.js:2:42:2:73 | window. ... bstr(1) | | tst3.js:4:25:4:28 | data | | tst3.js:4:25:4:32 | data.src | +| tst3.js:4:25:4:32 | data.src | | tst3.js:5:26:5:29 | data | | tst3.js:5:26:5:31 | data.p | +| tst3.js:5:26:5:31 | data.p | | tst3.js:7:32:7:35 | data | | tst3.js:7:32:7:37 | data.p | +| tst3.js:7:32:7:37 | data.p | | tst3.js:9:37:9:40 | data | | tst3.js:9:37:9:42 | data.p | +| tst3.js:9:37:9:42 | data.p | | tst3.js:10:38:10:41 | data | | tst3.js:10:38:10:43 | data.p | +| tst3.js:10:38:10:43 | data.p | | tst.js:2:7:2:39 | target | | tst.js:2:16:2:32 | document.location | +| tst.js:2:16:2:32 | document.location | | tst.js:2:16:2:39 | documen ... .search | | tst.js:5:18:5:23 | target | +| tst.js:5:18:5:23 | target | | tst.js:8:18:8:126 | "" | +| tst.js:8:18:8:126 | "" | +| tst.js:8:37:8:53 | document.location | | tst.js:8:37:8:53 | document.location | | tst.js:8:37:8:58 | documen ... on.href | | tst.js:8:37:8:114 | documen ... t=")+8) | | tst.js:12:5:12:42 | '
    ' | +| tst.js:12:5:12:42 | '
    ' | | tst.js:12:28:12:33 | target | | tst.js:19:25:19:41 | document.location | +| tst.js:19:25:19:41 | document.location | +| tst.js:20:18:20:35 | params.get('name') | | tst.js:20:18:20:35 | params.get('name') | | tst.js:23:42:23:47 | target | | tst.js:23:42:23:60 | target.substring(1) | | tst.js:24:18:24:41 | searchP ... 'name') | +| tst.js:24:18:24:41 | searchP ... 'name') | | tst.js:27:14:27:19 | target | | tst.js:29:18:29:23 | target | +| tst.js:29:18:29:23 | target | +| tst.js:31:5:31:21 | document.location | | tst.js:31:5:31:21 | document.location | | tst.js:31:5:31:28 | documen ... .search | | tst.js:34:10:34:26 | document.location | +| tst.js:34:10:34:26 | document.location | | tst.js:34:10:34:33 | documen ... .search | | tst.js:37:16:37:20 | bar() | +| tst.js:37:16:37:20 | bar() | | tst.js:43:16:43:44 | baz(doc ... search) | +| tst.js:43:16:43:44 | baz(doc ... search) | +| tst.js:43:20:43:36 | document.location | | tst.js:43:20:43:36 | document.location | | tst.js:43:20:43:43 | documen ... .search | | tst.js:49:16:49:45 | wrap(do ... search) | +| tst.js:49:16:49:45 | wrap(do ... search) | +| tst.js:49:21:49:37 | document.location | | tst.js:49:21:49:37 | document.location | | tst.js:49:21:49:44 | documen ... .search | | tst.js:57:16:57:45 | chop(do ... search) | +| tst.js:57:16:57:45 | chop(do ... search) | +| tst.js:57:21:57:37 | document.location | | tst.js:57:21:57:37 | document.location | | tst.js:57:21:57:44 | documen ... .search | | tst.js:59:16:59:45 | chop(do ... search) | +| tst.js:59:16:59:45 | chop(do ... search) | +| tst.js:59:21:59:37 | document.location | | tst.js:59:21:59:37 | document.location | | tst.js:59:21:59:44 | documen ... .search | | tst.js:61:16:61:32 | wrap(chop(bar())) | +| tst.js:61:16:61:32 | wrap(chop(bar())) | | tst.js:61:21:61:31 | chop(bar()) | | tst.js:61:26:61:30 | bar() | | tst.js:63:34:63:34 | s | | tst.js:65:18:65:18 | s | +| tst.js:65:18:65:18 | s | +| tst.js:67:25:67:41 | document.location | | tst.js:67:25:67:41 | document.location | | tst.js:67:25:67:48 | documen ... .search | | tst.js:68:25:68:41 | document.location | +| tst.js:68:25:68:41 | document.location | | tst.js:68:25:68:48 | documen ... .search | | tst.js:71:16:71:20 | bar() | +| tst.js:71:16:71:20 | bar() | | tst.js:73:1:73:27 | [,docum ... search] | | tst.js:73:3:73:19 | document.location | +| tst.js:73:3:73:19 | document.location | | tst.js:73:3:73:26 | documen ... .search | | tst.js:73:46:73:46 | x | | tst.js:76:20:76:20 | x | +| tst.js:76:20:76:20 | x | +| tst.js:80:49:80:65 | document.location | | tst.js:80:49:80:65 | document.location | | tst.js:80:49:80:72 | documen ... .search | +| tst.js:80:49:80:72 | documen ... .search | +| tst.js:84:26:84:42 | document.location | | tst.js:84:26:84:42 | document.location | | tst.js:84:26:84:49 | documen ... .search | +| tst.js:84:26:84:49 | documen ... .search | +| tst.js:85:25:85:41 | document.location | | tst.js:85:25:85:41 | document.location | | tst.js:85:25:85:48 | documen ... .search | +| tst.js:85:25:85:48 | documen ... .search | +| tst.js:87:33:87:49 | document.location | | tst.js:87:33:87:49 | document.location | | tst.js:87:33:87:56 | documen ... .search | +| tst.js:87:33:87:56 | documen ... .search | +| tst.js:88:32:88:48 | document.location | | tst.js:88:32:88:48 | document.location | | tst.js:88:32:88:55 | documen ... .search | +| tst.js:88:32:88:55 | documen ... .search | +| tst.js:93:39:93:55 | document.location | | tst.js:93:39:93:55 | document.location | | tst.js:93:39:93:62 | documen ... .search | +| tst.js:93:39:93:62 | documen ... .search | +| tst.js:99:30:99:46 | document.location | | tst.js:99:30:99:46 | document.location | | tst.js:99:30:99:53 | documen ... .search | +| tst.js:99:30:99:53 | documen ... .search | +| tst.js:105:25:105:41 | document.location | | tst.js:105:25:105:41 | document.location | | tst.js:105:25:105:48 | documen ... .search | +| tst.js:105:25:105:48 | documen ... .search | | tst.js:110:7:110:44 | v | | tst.js:110:11:110:27 | document.location | +| tst.js:110:11:110:27 | document.location | | tst.js:110:11:110:34 | documen ... .search | | tst.js:110:11:110:44 | documen ... bstr(1) | | tst.js:113:18:113:18 | v | +| tst.js:113:18:113:18 | v | +| tst.js:145:29:145:43 | window.location | | tst.js:145:29:145:43 | window.location | | tst.js:145:29:145:50 | window. ... .search | | tst.js:148:29:148:29 | v | | tst.js:148:49:148:49 | v | +| tst.js:148:49:148:49 | v | | tst.js:152:29:152:46 | xssSourceService() | +| tst.js:152:29:152:46 | xssSourceService() | +| tst.js:155:40:155:54 | window.location | | tst.js:155:40:155:54 | window.location | | tst.js:155:40:155:61 | window. ... .search | | tst.js:174:9:174:41 | target | | tst.js:174:18:174:34 | document.location | +| tst.js:174:18:174:34 | document.location | | tst.js:174:18:174:41 | documen ... .search | | tst.js:177:28:177:33 | target | +| tst.js:177:28:177:33 | target | | tst.js:181:9:181:42 | tainted | | tst.js:181:19:181:35 | document.location | +| tst.js:181:19:181:35 | document.location | | tst.js:181:19:181:42 | documen ... .search | | tst.js:183:31:183:37 | tainted | +| tst.js:183:31:183:37 | tainted | +| tst.js:185:42:185:48 | tainted | | tst.js:185:42:185:48 | tainted | | tst.js:186:33:186:39 | tainted | +| tst.js:186:33:186:39 | tainted | | tst.js:188:54:188:60 | tainted | +| tst.js:188:54:188:60 | tainted | +| tst.js:189:45:189:51 | tainted | | tst.js:189:45:189:51 | tainted | | tst.js:194:9:194:42 | tainted | | tst.js:194:19:194:35 | document.location | +| tst.js:194:19:194:35 | document.location | | tst.js:194:19:194:42 | documen ... .search | | tst.js:196:67:196:73 | tainted | +| tst.js:196:67:196:73 | tainted | +| tst.js:197:67:197:73 | tainted | | tst.js:197:67:197:73 | tainted | | tst.js:201:35:201:41 | tainted | | tst.js:203:46:203:52 | tainted | | tst.js:204:38:204:44 | tainted | | tst.js:205:35:205:41 | tainted | | tst.js:209:28:209:46 | this.state.tainted1 | +| tst.js:209:28:209:46 | this.state.tainted1 | +| tst.js:210:28:210:46 | this.state.tainted2 | | tst.js:210:28:210:46 | this.state.tainted2 | | tst.js:211:28:211:46 | this.state.tainted3 | +| tst.js:211:28:211:46 | this.state.tainted3 | +| tst.js:215:32:215:49 | prevState.tainted4 | | tst.js:215:32:215:49 | prevState.tainted4 | | tst.js:222:28:222:46 | this.props.tainted1 | +| tst.js:222:28:222:46 | this.props.tainted1 | +| tst.js:223:28:223:46 | this.props.tainted2 | | tst.js:223:28:223:46 | this.props.tainted2 | | tst.js:224:28:224:46 | this.props.tainted3 | +| tst.js:224:28:224:46 | this.props.tainted3 | +| tst.js:228:32:228:49 | prevProps.tainted4 | | tst.js:228:32:228:49 | prevProps.tainted4 | | tst.js:233:35:233:41 | tainted | | tst.js:235:20:235:26 | tainted | @@ -183,65 +294,119 @@ nodes | tst.js:238:23:238:29 | tainted | | tst.js:244:39:244:55 | props.propTainted | | tst.js:248:60:248:82 | this.st ... Tainted | +| tst.js:248:60:248:82 | this.st ... Tainted | | tst.js:252:23:252:29 | tainted | | tst.js:256:7:256:17 | window.name | +| tst.js:256:7:256:17 | window.name | +| tst.js:256:7:256:17 | window.name | +| tst.js:257:7:257:10 | name | +| tst.js:257:7:257:10 | name | | tst.js:257:7:257:10 | name | | tst.js:261:11:261:21 | window.name | +| tst.js:261:11:261:21 | window.name | +| tst.js:261:11:261:21 | window.name | +| tst.js:277:22:277:29 | location | +| tst.js:277:22:277:29 | location | | tst.js:277:22:277:29 | location | | tst.js:282:9:282:29 | tainted | +| tst.js:282:9:282:29 | tainted | +| tst.js:282:19:282:29 | window.name | | tst.js:282:19:282:29 | window.name | | tst.js:285:59:285:65 | tainted | +| tst.js:285:59:285:65 | tainted | +| tst.js:285:59:285:65 | tainted | +| v-html.vue:2:8:2:23 | v-html=tainted | | v-html.vue:2:8:2:23 | v-html=tainted | | v-html.vue:6:42:6:58 | document.location | +| v-html.vue:6:42:6:58 | document.location | | winjs.js:2:7:2:53 | tainted | | winjs.js:2:17:2:33 | document.location | +| winjs.js:2:17:2:33 | document.location | | winjs.js:2:17:2:40 | documen ... .search | | winjs.js:2:17:2:53 | documen ... ring(1) | | winjs.js:3:43:3:49 | tainted | +| winjs.js:3:43:3:49 | tainted | +| winjs.js:4:43:4:49 | tainted | | winjs.js:4:43:4:49 | tainted | edges | addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:24 | event | +| addEventListener.js:1:43:1:47 | event | addEventListener.js:2:20:2:24 | event | +| addEventListener.js:2:20:2:24 | event | addEventListener.js:2:20:2:29 | event.data | | addEventListener.js:2:20:2:24 | event | addEventListener.js:2:20:2:29 | event.data | | addEventListener.js:5:43:5:48 | data | addEventListener.js:6:20:6:23 | data | +| addEventListener.js:5:43:5:48 | data | addEventListener.js:6:20:6:23 | data | +| addEventListener.js:5:43:5:48 | {data} | addEventListener.js:5:44:5:47 | data | | addEventListener.js:5:43:5:48 | {data} | addEventListener.js:5:44:5:47 | data | | addEventListener.js:5:44:5:47 | data | addEventListener.js:5:43:5:48 | data | | addEventListener.js:10:21:10:25 | event | addEventListener.js:12:24:12:28 | event | +| addEventListener.js:10:21:10:25 | event | addEventListener.js:12:24:12:28 | event | | addEventListener.js:12:24:12:28 | event | addEventListener.js:12:24:12:33 | event.data | +| addEventListener.js:12:24:12:28 | event | addEventListener.js:12:24:12:33 | event.data | +| jquery.js:2:7:2:40 | tainted | jquery.js:4:5:4:11 | tainted | | jquery.js:2:7:2:40 | tainted | jquery.js:4:5:4:11 | tainted | | jquery.js:2:7:2:40 | tainted | jquery.js:7:20:7:26 | tainted | | jquery.js:2:7:2:40 | tainted | jquery.js:8:28:8:34 | tainted | | jquery.js:2:17:2:33 | document.location | jquery.js:2:17:2:40 | documen ... .search | +| jquery.js:2:17:2:33 | document.location | jquery.js:2:17:2:40 | documen ... .search | | jquery.js:2:17:2:40 | documen ... .search | jquery.js:2:7:2:40 | tainted | -| jquery.js:7:5:7:26 | "
    " | -| jquery.js:7:20:7:26 | tainted | jquery.js:7:5:7:26 | "
    " | | jquery.js:7:20:7:26 | tainted | jquery.js:7:5:7:34 | "
    " | | jquery.js:8:28:8:34 | tainted | jquery.js:8:18:8:34 | "XSS: " + tainted | +| jquery.js:8:28:8:34 | tainted | jquery.js:8:18:8:34 | "XSS: " + tainted | +| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | +| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | +| nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | | nodemailer.js:13:50:13:66 | req.query.message | nodemailer.js:13:11:13:69 | `Hi, yo ... sage}.` | | react-native.js:7:7:7:33 | tainted | react-native.js:8:18:8:24 | tainted | +| react-native.js:7:7:7:33 | tainted | react-native.js:8:18:8:24 | tainted | +| react-native.js:7:7:7:33 | tainted | react-native.js:9:27:9:33 | tainted | | react-native.js:7:7:7:33 | tainted | react-native.js:9:27:9:33 | tainted | | react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | +| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | +| stored-xss.js:2:39:2:55 | document.location | stored-xss.js:2:39:2:62 | documen ... .search | | stored-xss.js:2:39:2:55 | document.location | stored-xss.js:2:39:2:62 | documen ... .search | | stored-xss.js:2:39:2:62 | documen ... .search | stored-xss.js:5:20:5:52 | session ... ssion') | +| stored-xss.js:2:39:2:62 | documen ... .search | stored-xss.js:5:20:5:52 | session ... ssion') | +| stored-xss.js:3:35:3:51 | document.location | stored-xss.js:3:35:3:58 | documen ... .search | | stored-xss.js:3:35:3:51 | document.location | stored-xss.js:3:35:3:58 | documen ... .search | | stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:8:20:8:48 | localSt ... local') | +| stored-xss.js:3:35:3:58 | documen ... .search | stored-xss.js:8:20:8:48 | localSt ... local') | +| string-manipulations.js:3:16:3:32 | document.location | string-manipulations.js:3:16:3:32 | document.location | +| string-manipulations.js:4:16:4:32 | document.location | string-manipulations.js:4:16:4:37 | documen ... on.href | +| string-manipulations.js:4:16:4:32 | document.location | string-manipulations.js:4:16:4:37 | documen ... on.href | +| string-manipulations.js:4:16:4:32 | document.location | string-manipulations.js:4:16:4:37 | documen ... on.href | | string-manipulations.js:4:16:4:32 | document.location | string-manipulations.js:4:16:4:37 | documen ... on.href | | string-manipulations.js:5:16:5:32 | document.location | string-manipulations.js:5:16:5:37 | documen ... on.href | +| string-manipulations.js:5:16:5:32 | document.location | string-manipulations.js:5:16:5:37 | documen ... on.href | +| string-manipulations.js:5:16:5:37 | documen ... on.href | string-manipulations.js:5:16:5:47 | documen ... lueOf() | | string-manipulations.js:5:16:5:37 | documen ... on.href | string-manipulations.js:5:16:5:47 | documen ... lueOf() | | string-manipulations.js:6:16:6:32 | document.location | string-manipulations.js:6:16:6:37 | documen ... on.href | +| string-manipulations.js:6:16:6:32 | document.location | string-manipulations.js:6:16:6:37 | documen ... on.href | +| string-manipulations.js:6:16:6:37 | documen ... on.href | string-manipulations.js:6:16:6:43 | documen ... f.sup() | | string-manipulations.js:6:16:6:37 | documen ... on.href | string-manipulations.js:6:16:6:43 | documen ... f.sup() | | string-manipulations.js:7:16:7:32 | document.location | string-manipulations.js:7:16:7:37 | documen ... on.href | +| string-manipulations.js:7:16:7:32 | document.location | string-manipulations.js:7:16:7:37 | documen ... on.href | +| string-manipulations.js:7:16:7:37 | documen ... on.href | string-manipulations.js:7:16:7:51 | documen ... rCase() | | string-manipulations.js:7:16:7:37 | documen ... on.href | string-manipulations.js:7:16:7:51 | documen ... rCase() | | string-manipulations.js:8:16:8:32 | document.location | string-manipulations.js:8:16:8:37 | documen ... on.href | +| string-manipulations.js:8:16:8:32 | document.location | string-manipulations.js:8:16:8:37 | documen ... on.href | +| string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | | string-manipulations.js:8:16:8:37 | documen ... on.href | string-manipulations.js:8:16:8:48 | documen ... mLeft() | | string-manipulations.js:9:36:9:52 | document.location | string-manipulations.js:9:36:9:57 | documen ... on.href | +| string-manipulations.js:9:36:9:52 | document.location | string-manipulations.js:9:36:9:57 | documen ... on.href | +| string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | | string-manipulations.js:9:36:9:57 | documen ... on.href | string-manipulations.js:9:16:9:58 | String. ... n.href) | | string-manipulations.js:10:23:10:39 | document.location | string-manipulations.js:10:23:10:44 | documen ... on.href | +| string-manipulations.js:10:23:10:39 | document.location | string-manipulations.js:10:23:10:44 | documen ... on.href | +| string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | | string-manipulations.js:10:23:10:44 | documen ... on.href | string-manipulations.js:10:16:10:45 | String( ... n.href) | | translate.js:6:7:6:39 | target | translate.js:7:42:7:47 | target | | translate.js:6:16:6:32 | document.location | translate.js:6:16:6:39 | documen ... .search | +| translate.js:6:16:6:32 | document.location | translate.js:6:16:6:39 | documen ... .search | | translate.js:6:16:6:39 | documen ... .search | translate.js:6:7:6:39 | target | | translate.js:7:42:7:47 | target | translate.js:7:42:7:60 | target.substring(1) | | translate.js:7:42:7:60 | target.substring(1) | translate.js:9:27:9:50 | searchP ... 'term') | +| translate.js:7:42:7:60 | target.substring(1) | translate.js:9:27:9:50 | searchP ... 'term') | | tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:4:25:4:28 | data | | tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:5:26:5:29 | data | | tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:7:32:7:35 | data | @@ -249,89 +414,155 @@ edges | tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | tst3.js:10:38:10:41 | data | | tst3.js:2:23:2:74 | decodeU ... str(1)) | tst3.js:2:12:2:75 | JSON.pa ... tr(1))) | | tst3.js:2:42:2:56 | window.location | tst3.js:2:42:2:63 | window. ... .search | +| tst3.js:2:42:2:56 | window.location | tst3.js:2:42:2:63 | window. ... .search | | tst3.js:2:42:2:63 | window. ... .search | tst3.js:2:42:2:73 | window. ... bstr(1) | | tst3.js:2:42:2:73 | window. ... bstr(1) | tst3.js:2:23:2:74 | decodeU ... str(1)) | | tst3.js:4:25:4:28 | data | tst3.js:4:25:4:32 | data.src | +| tst3.js:4:25:4:28 | data | tst3.js:4:25:4:32 | data.src | +| tst3.js:5:26:5:29 | data | tst3.js:5:26:5:31 | data.p | | tst3.js:5:26:5:29 | data | tst3.js:5:26:5:31 | data.p | | tst3.js:7:32:7:35 | data | tst3.js:7:32:7:37 | data.p | +| tst3.js:7:32:7:35 | data | tst3.js:7:32:7:37 | data.p | +| tst3.js:9:37:9:40 | data | tst3.js:9:37:9:42 | data.p | | tst3.js:9:37:9:40 | data | tst3.js:9:37:9:42 | data.p | | tst3.js:10:38:10:41 | data | tst3.js:10:38:10:43 | data.p | +| tst3.js:10:38:10:41 | data | tst3.js:10:38:10:43 | data.p | +| tst.js:2:7:2:39 | target | tst.js:5:18:5:23 | target | | tst.js:2:7:2:39 | target | tst.js:5:18:5:23 | target | | tst.js:2:7:2:39 | target | tst.js:12:28:12:33 | target | | tst.js:2:7:2:39 | target | tst.js:23:42:23:47 | target | | tst.js:2:16:2:32 | document.location | tst.js:2:16:2:39 | documen ... .search | +| tst.js:2:16:2:32 | document.location | tst.js:2:16:2:39 | documen ... .search | | tst.js:2:16:2:39 | documen ... .search | tst.js:2:7:2:39 | target | -| tst.js:8:18:8:114 | "" | +| tst.js:8:37:8:53 | document.location | tst.js:8:37:8:58 | documen ... on.href | | tst.js:8:37:8:53 | document.location | tst.js:8:37:8:58 | documen ... on.href | | tst.js:8:37:8:58 | documen ... on.href | tst.js:8:37:8:114 | documen ... t=")+8) | -| tst.js:8:37:8:114 | documen ... t=")+8) | tst.js:8:18:8:114 | "" | -| tst.js:12:5:12:33 | '
    ' | -| tst.js:12:28:12:33 | target | tst.js:12:5:12:33 | '
    " | | tst.js:12:28:12:33 | target | tst.js:12:5:12:42 | '
    ' | +| tst.js:12:28:12:33 | target | tst.js:12:5:12:42 | '
    ' | +| tst.js:19:25:19:41 | document.location | tst.js:20:18:20:35 | params.get('name') | +| tst.js:19:25:19:41 | document.location | tst.js:20:18:20:35 | params.get('name') | +| tst.js:19:25:19:41 | document.location | tst.js:20:18:20:35 | params.get('name') | | tst.js:19:25:19:41 | document.location | tst.js:20:18:20:35 | params.get('name') | | tst.js:23:42:23:47 | target | tst.js:23:42:23:60 | target.substring(1) | | tst.js:23:42:23:60 | target.substring(1) | tst.js:24:18:24:41 | searchP ... 'name') | +| tst.js:23:42:23:60 | target.substring(1) | tst.js:24:18:24:41 | searchP ... 'name') | | tst.js:27:14:27:19 | target | tst.js:29:18:29:23 | target | +| tst.js:27:14:27:19 | target | tst.js:29:18:29:23 | target | +| tst.js:31:5:31:21 | document.location | tst.js:31:5:31:28 | documen ... .search | | tst.js:31:5:31:21 | document.location | tst.js:31:5:31:28 | documen ... .search | | tst.js:31:5:31:28 | documen ... .search | tst.js:27:14:27:19 | target | | tst.js:34:10:34:26 | document.location | tst.js:34:10:34:33 | documen ... .search | +| tst.js:34:10:34:26 | document.location | tst.js:34:10:34:33 | documen ... .search | +| tst.js:34:10:34:33 | documen ... .search | tst.js:37:16:37:20 | bar() | | tst.js:34:10:34:33 | documen ... .search | tst.js:37:16:37:20 | bar() | | tst.js:34:10:34:33 | documen ... .search | tst.js:61:26:61:30 | bar() | | tst.js:34:10:34:33 | documen ... .search | tst.js:71:16:71:20 | bar() | +| tst.js:34:10:34:33 | documen ... .search | tst.js:71:16:71:20 | bar() | +| tst.js:43:20:43:36 | document.location | tst.js:43:20:43:43 | documen ... .search | | tst.js:43:20:43:36 | document.location | tst.js:43:20:43:43 | documen ... .search | | tst.js:43:20:43:43 | documen ... .search | tst.js:43:16:43:44 | baz(doc ... search) | +| tst.js:43:20:43:43 | documen ... .search | tst.js:43:16:43:44 | baz(doc ... search) | +| tst.js:49:21:49:37 | document.location | tst.js:49:21:49:44 | documen ... .search | | tst.js:49:21:49:37 | document.location | tst.js:49:21:49:44 | documen ... .search | | tst.js:49:21:49:44 | documen ... .search | tst.js:49:16:49:45 | wrap(do ... search) | +| tst.js:49:21:49:44 | documen ... .search | tst.js:49:16:49:45 | wrap(do ... search) | +| tst.js:57:21:57:37 | document.location | tst.js:57:21:57:44 | documen ... .search | | tst.js:57:21:57:37 | document.location | tst.js:57:21:57:44 | documen ... .search | | tst.js:57:21:57:44 | documen ... .search | tst.js:57:16:57:45 | chop(do ... search) | +| tst.js:57:21:57:44 | documen ... .search | tst.js:57:16:57:45 | chop(do ... search) | +| tst.js:59:21:59:37 | document.location | tst.js:59:21:59:44 | documen ... .search | | tst.js:59:21:59:37 | document.location | tst.js:59:21:59:44 | documen ... .search | | tst.js:59:21:59:44 | documen ... .search | tst.js:59:16:59:45 | chop(do ... search) | +| tst.js:59:21:59:44 | documen ... .search | tst.js:59:16:59:45 | chop(do ... search) | +| tst.js:61:21:61:31 | chop(bar()) | tst.js:61:16:61:32 | wrap(chop(bar())) | | tst.js:61:21:61:31 | chop(bar()) | tst.js:61:16:61:32 | wrap(chop(bar())) | | tst.js:61:26:61:30 | bar() | tst.js:61:21:61:31 | chop(bar()) | | tst.js:63:34:63:34 | s | tst.js:65:18:65:18 | s | +| tst.js:63:34:63:34 | s | tst.js:65:18:65:18 | s | +| tst.js:67:25:67:41 | document.location | tst.js:67:25:67:48 | documen ... .search | | tst.js:67:25:67:41 | document.location | tst.js:67:25:67:48 | documen ... .search | | tst.js:67:25:67:48 | documen ... .search | tst.js:63:34:63:34 | s | | tst.js:68:25:68:41 | document.location | tst.js:68:25:68:48 | documen ... .search | +| tst.js:68:25:68:41 | document.location | tst.js:68:25:68:48 | documen ... .search | | tst.js:68:25:68:48 | documen ... .search | tst.js:63:34:63:34 | s | | tst.js:73:1:73:27 | [,docum ... search] | tst.js:73:46:73:46 | x | | tst.js:73:3:73:19 | document.location | tst.js:73:3:73:26 | documen ... .search | +| tst.js:73:3:73:19 | document.location | tst.js:73:3:73:26 | documen ... .search | | tst.js:73:3:73:26 | documen ... .search | tst.js:73:1:73:27 | [,docum ... search] | -| tst.js:73:46:73:46 | x | tst.js:74:7:74:7 | x | | tst.js:73:46:73:46 | x | tst.js:76:20:76:20 | x | -| tst.js:74:7:74:7 | x | tst.js:76:20:76:20 | x | +| tst.js:73:46:73:46 | x | tst.js:76:20:76:20 | x | +| tst.js:80:49:80:65 | document.location | tst.js:80:49:80:72 | documen ... .search | +| tst.js:80:49:80:65 | document.location | tst.js:80:49:80:72 | documen ... .search | +| tst.js:80:49:80:65 | document.location | tst.js:80:49:80:72 | documen ... .search | | tst.js:80:49:80:65 | document.location | tst.js:80:49:80:72 | documen ... .search | | tst.js:84:26:84:42 | document.location | tst.js:84:26:84:49 | documen ... .search | +| tst.js:84:26:84:42 | document.location | tst.js:84:26:84:49 | documen ... .search | +| tst.js:84:26:84:42 | document.location | tst.js:84:26:84:49 | documen ... .search | +| tst.js:84:26:84:42 | document.location | tst.js:84:26:84:49 | documen ... .search | +| tst.js:85:25:85:41 | document.location | tst.js:85:25:85:48 | documen ... .search | +| tst.js:85:25:85:41 | document.location | tst.js:85:25:85:48 | documen ... .search | +| tst.js:85:25:85:41 | document.location | tst.js:85:25:85:48 | documen ... .search | | tst.js:85:25:85:41 | document.location | tst.js:85:25:85:48 | documen ... .search | | tst.js:87:33:87:49 | document.location | tst.js:87:33:87:56 | documen ... .search | +| tst.js:87:33:87:49 | document.location | tst.js:87:33:87:56 | documen ... .search | +| tst.js:87:33:87:49 | document.location | tst.js:87:33:87:56 | documen ... .search | +| tst.js:87:33:87:49 | document.location | tst.js:87:33:87:56 | documen ... .search | +| tst.js:88:32:88:48 | document.location | tst.js:88:32:88:55 | documen ... .search | +| tst.js:88:32:88:48 | document.location | tst.js:88:32:88:55 | documen ... .search | +| tst.js:88:32:88:48 | document.location | tst.js:88:32:88:55 | documen ... .search | | tst.js:88:32:88:48 | document.location | tst.js:88:32:88:55 | documen ... .search | | tst.js:93:39:93:55 | document.location | tst.js:93:39:93:62 | documen ... .search | +| tst.js:93:39:93:55 | document.location | tst.js:93:39:93:62 | documen ... .search | +| tst.js:93:39:93:55 | document.location | tst.js:93:39:93:62 | documen ... .search | +| tst.js:93:39:93:55 | document.location | tst.js:93:39:93:62 | documen ... .search | +| tst.js:99:30:99:46 | document.location | tst.js:99:30:99:53 | documen ... .search | +| tst.js:99:30:99:46 | document.location | tst.js:99:30:99:53 | documen ... .search | +| tst.js:99:30:99:46 | document.location | tst.js:99:30:99:53 | documen ... .search | | tst.js:99:30:99:46 | document.location | tst.js:99:30:99:53 | documen ... .search | | tst.js:105:25:105:41 | document.location | tst.js:105:25:105:48 | documen ... .search | +| tst.js:105:25:105:41 | document.location | tst.js:105:25:105:48 | documen ... .search | +| tst.js:105:25:105:41 | document.location | tst.js:105:25:105:48 | documen ... .search | +| tst.js:105:25:105:41 | document.location | tst.js:105:25:105:48 | documen ... .search | | tst.js:110:7:110:44 | v | tst.js:113:18:113:18 | v | +| tst.js:110:7:110:44 | v | tst.js:113:18:113:18 | v | +| tst.js:110:11:110:27 | document.location | tst.js:110:11:110:34 | documen ... .search | | tst.js:110:11:110:27 | document.location | tst.js:110:11:110:34 | documen ... .search | | tst.js:110:11:110:34 | documen ... .search | tst.js:110:11:110:44 | documen ... bstr(1) | | tst.js:110:11:110:44 | documen ... bstr(1) | tst.js:110:7:110:44 | v | | tst.js:145:29:145:43 | window.location | tst.js:145:29:145:50 | window. ... .search | +| tst.js:145:29:145:43 | window.location | tst.js:145:29:145:50 | window. ... .search | | tst.js:145:29:145:50 | window. ... .search | tst.js:148:29:148:29 | v | | tst.js:148:29:148:29 | v | tst.js:148:49:148:49 | v | +| tst.js:148:29:148:29 | v | tst.js:148:49:148:49 | v | +| tst.js:155:40:155:54 | window.location | tst.js:155:40:155:61 | window. ... .search | | tst.js:155:40:155:54 | window.location | tst.js:155:40:155:61 | window. ... .search | | tst.js:155:40:155:61 | window. ... .search | tst.js:152:29:152:46 | xssSourceService() | +| tst.js:155:40:155:61 | window. ... .search | tst.js:152:29:152:46 | xssSourceService() | | tst.js:174:9:174:41 | target | tst.js:177:28:177:33 | target | +| tst.js:174:9:174:41 | target | tst.js:177:28:177:33 | target | +| tst.js:174:18:174:34 | document.location | tst.js:174:18:174:41 | documen ... .search | | tst.js:174:18:174:34 | document.location | tst.js:174:18:174:41 | documen ... .search | | tst.js:174:18:174:41 | documen ... .search | tst.js:174:9:174:41 | target | | tst.js:181:9:181:42 | tainted | tst.js:183:31:183:37 | tainted | +| tst.js:181:9:181:42 | tainted | tst.js:183:31:183:37 | tainted | +| tst.js:181:9:181:42 | tainted | tst.js:185:42:185:48 | tainted | | tst.js:181:9:181:42 | tainted | tst.js:185:42:185:48 | tainted | | tst.js:181:9:181:42 | tainted | tst.js:186:33:186:39 | tainted | +| tst.js:181:9:181:42 | tainted | tst.js:186:33:186:39 | tainted | +| tst.js:181:9:181:42 | tainted | tst.js:188:54:188:60 | tainted | | tst.js:181:9:181:42 | tainted | tst.js:188:54:188:60 | tainted | | tst.js:181:9:181:42 | tainted | tst.js:189:45:189:51 | tainted | +| tst.js:181:9:181:42 | tainted | tst.js:189:45:189:51 | tainted | +| tst.js:181:19:181:35 | document.location | tst.js:181:19:181:42 | documen ... .search | | tst.js:181:19:181:35 | document.location | tst.js:181:19:181:42 | documen ... .search | | tst.js:181:19:181:42 | documen ... .search | tst.js:181:9:181:42 | tainted | | tst.js:194:9:194:42 | tainted | tst.js:196:67:196:73 | tainted | +| tst.js:194:9:194:42 | tainted | tst.js:196:67:196:73 | tainted | +| tst.js:194:9:194:42 | tainted | tst.js:197:67:197:73 | tainted | | tst.js:194:9:194:42 | tainted | tst.js:197:67:197:73 | tainted | -| tst.js:194:9:194:42 | tainted | tst.js:200:20:200:19 | tainted | | tst.js:194:9:194:42 | tainted | tst.js:201:35:201:41 | tainted | -| tst.js:194:9:194:42 | tainted | tst.js:203:27:203:26 | tainted | | tst.js:194:9:194:42 | tainted | tst.js:203:46:203:52 | tainted | | tst.js:194:9:194:42 | tainted | tst.js:204:38:204:44 | tainted | | tst.js:194:9:194:42 | tainted | tst.js:205:35:205:41 | tainted | @@ -341,26 +572,47 @@ edges | tst.js:194:9:194:42 | tainted | tst.js:238:23:238:29 | tainted | | tst.js:194:9:194:42 | tainted | tst.js:252:23:252:29 | tainted | | tst.js:194:19:194:35 | document.location | tst.js:194:19:194:42 | documen ... .search | +| tst.js:194:19:194:35 | document.location | tst.js:194:19:194:42 | documen ... .search | | tst.js:194:19:194:42 | documen ... .search | tst.js:194:9:194:42 | tainted | -| tst.js:200:20:200:19 | tainted | tst.js:201:35:201:41 | tainted | -| tst.js:200:20:200:19 | tainted | tst.js:204:38:204:44 | tainted | -| tst.js:200:20:200:19 | tainted | tst.js:205:35:205:41 | tainted | | tst.js:201:35:201:41 | tainted | tst.js:209:28:209:46 | this.state.tainted1 | -| tst.js:203:27:203:26 | tainted | tst.js:203:46:203:52 | tainted | +| tst.js:201:35:201:41 | tainted | tst.js:209:28:209:46 | this.state.tainted1 | +| tst.js:203:46:203:52 | tainted | tst.js:210:28:210:46 | this.state.tainted2 | | tst.js:203:46:203:52 | tainted | tst.js:210:28:210:46 | this.state.tainted2 | | tst.js:204:38:204:44 | tainted | tst.js:211:28:211:46 | this.state.tainted3 | +| tst.js:204:38:204:44 | tainted | tst.js:211:28:211:46 | this.state.tainted3 | +| tst.js:205:35:205:41 | tainted | tst.js:215:32:215:49 | prevState.tainted4 | | tst.js:205:35:205:41 | tainted | tst.js:215:32:215:49 | prevState.tainted4 | | tst.js:233:35:233:41 | tainted | tst.js:222:28:222:46 | this.props.tainted1 | +| tst.js:233:35:233:41 | tainted | tst.js:222:28:222:46 | this.props.tainted1 | +| tst.js:235:20:235:26 | tainted | tst.js:223:28:223:46 | this.props.tainted2 | | tst.js:235:20:235:26 | tainted | tst.js:223:28:223:46 | this.props.tainted2 | | tst.js:237:23:237:29 | tainted | tst.js:224:28:224:46 | this.props.tainted3 | +| tst.js:237:23:237:29 | tainted | tst.js:224:28:224:46 | this.props.tainted3 | +| tst.js:238:23:238:29 | tainted | tst.js:228:32:228:49 | prevProps.tainted4 | | tst.js:238:23:238:29 | tainted | tst.js:228:32:228:49 | prevProps.tainted4 | | tst.js:244:39:244:55 | props.propTainted | tst.js:248:60:248:82 | this.st ... Tainted | +| tst.js:244:39:244:55 | props.propTainted | tst.js:248:60:248:82 | this.st ... Tainted | | tst.js:252:23:252:29 | tainted | tst.js:244:39:244:55 | props.propTainted | +| tst.js:256:7:256:17 | window.name | tst.js:256:7:256:17 | window.name | +| tst.js:257:7:257:10 | name | tst.js:257:7:257:10 | name | +| tst.js:261:11:261:21 | window.name | tst.js:261:11:261:21 | window.name | +| tst.js:277:22:277:29 | location | tst.js:277:22:277:29 | location | +| tst.js:282:9:282:29 | tainted | tst.js:285:59:285:65 | tainted | +| tst.js:282:9:282:29 | tainted | tst.js:285:59:285:65 | tainted | +| tst.js:282:9:282:29 | tainted | tst.js:285:59:285:65 | tainted | | tst.js:282:9:282:29 | tainted | tst.js:285:59:285:65 | tainted | | tst.js:282:19:282:29 | window.name | tst.js:282:9:282:29 | tainted | +| tst.js:282:19:282:29 | window.name | tst.js:282:9:282:29 | tainted | +| tst.js:285:59:285:65 | tainted | tst.js:285:59:285:65 | tainted | +| v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted | +| v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted | +| v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted | | v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted | | winjs.js:2:7:2:53 | tainted | winjs.js:3:43:3:49 | tainted | +| winjs.js:2:7:2:53 | tainted | winjs.js:3:43:3:49 | tainted | | winjs.js:2:7:2:53 | tainted | winjs.js:4:43:4:49 | tainted | +| winjs.js:2:7:2:53 | tainted | winjs.js:4:43:4:49 | tainted | +| winjs.js:2:17:2:33 | document.location | winjs.js:2:17:2:40 | documen ... .search | | winjs.js:2:17:2:33 | document.location | winjs.js:2:17:2:40 | documen ... .search | | winjs.js:2:17:2:40 | documen ... .search | winjs.js:2:17:2:53 | documen ... ring(1) | | winjs.js:2:17:2:53 | documen ... ring(1) | winjs.js:2:7:2:53 | tainted | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/encodeuri.js b/javascript/ql/test/query-tests/Security/CWE-079/encodeuri.js new file mode 100644 index 00000000000..a48f720bed1 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-079/encodeuri.js @@ -0,0 +1,4 @@ +function test() { + let loc = window.location.href; + $('click'); // OK +} diff --git a/javascript/ql/test/query-tests/Security/CWE-089/typed/SqlInjection.expected b/javascript/ql/test/query-tests/Security/CWE-089/typed/SqlInjection.expected index d5525ba35f2..f2b2489094c 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/typed/SqlInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-089/typed/SqlInjection.expected @@ -2,14 +2,18 @@ nodes | typedClient.ts:13:7:13:32 | v | | typedClient.ts:13:11:13:32 | JSON.pa ... body.x) | | typedClient.ts:13:22:13:29 | req.body | +| typedClient.ts:13:22:13:29 | req.body | | typedClient.ts:13:22:13:31 | req.body.x | | typedClient.ts:14:24:14:32 | { id: v } | +| typedClient.ts:14:24:14:32 | { id: v } | | typedClient.ts:14:30:14:30 | v | edges | typedClient.ts:13:7:13:32 | v | typedClient.ts:14:30:14:30 | v | | typedClient.ts:13:11:13:32 | JSON.pa ... body.x) | typedClient.ts:13:7:13:32 | v | | typedClient.ts:13:22:13:29 | req.body | typedClient.ts:13:22:13:31 | req.body.x | +| typedClient.ts:13:22:13:29 | req.body | typedClient.ts:13:22:13:31 | req.body.x | | typedClient.ts:13:22:13:31 | req.body.x | typedClient.ts:13:11:13:32 | JSON.pa ... body.x) | | typedClient.ts:14:30:14:30 | v | typedClient.ts:14:24:14:32 | { id: v } | +| typedClient.ts:14:30:14:30 | v | typedClient.ts:14:24:14:32 | { id: v } | #select | typedClient.ts:14:24:14:32 | { id: v } | typedClient.ts:13:22:13:29 | req.body | typedClient.ts:14:24:14:32 | { id: v } | This query depends on $@. | typedClient.ts:13:22:13:29 | req.body | a user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected index 0e3abcdd085..7489f310223 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/SqlInjection.expected @@ -2,159 +2,242 @@ nodes | mongodb.js:12:11:12:20 | query | | mongodb.js:12:19:12:20 | {} | | mongodb.js:13:19:13:26 | req.body | +| mongodb.js:13:19:13:26 | req.body | | mongodb.js:13:19:13:32 | req.body.title | | mongodb.js:18:16:18:20 | query | +| mongodb.js:18:16:18:20 | query | | mongodb.js:26:11:26:32 | title | | mongodb.js:26:19:26:26 | req.body | +| mongodb.js:26:19:26:26 | req.body | | mongodb.js:26:19:26:32 | req.body.title | | mongodb.js:32:18:32:45 | { title ... itle) } | +| mongodb.js:32:18:32:45 | { title ... itle) } | | mongodb.js:32:27:32:43 | JSON.parse(title) | | mongodb.js:32:38:32:42 | title | | mongodb.js:48:11:48:20 | query | | mongodb.js:48:19:48:20 | {} | | mongodb.js:49:19:49:33 | req.query.title | +| mongodb.js:49:19:49:33 | req.query.title | +| mongodb.js:54:16:54:20 | query | | mongodb.js:54:16:54:20 | query | | mongodb_bodySafe.js:23:11:23:20 | query | | mongodb_bodySafe.js:23:19:23:20 | {} | | mongodb_bodySafe.js:24:19:24:33 | req.query.title | +| mongodb_bodySafe.js:24:19:24:33 | req.query.title | +| mongodb_bodySafe.js:29:16:29:20 | query | | mongodb_bodySafe.js:29:16:29:20 | query | | mongoose.js:20:11:20:20 | query | | mongoose.js:20:19:20:20 | {} | | mongoose.js:21:19:21:26 | req.body | +| mongoose.js:21:19:21:26 | req.body | | mongoose.js:21:19:21:32 | req.body.title | | mongoose.js:27:20:27:24 | query | +| mongoose.js:27:20:27:24 | query | +| mongoose.js:30:25:30:29 | query | | mongoose.js:30:25:30:29 | query | | mongoose.js:33:24:33:28 | query | +| mongoose.js:33:24:33:28 | query | +| mongoose.js:36:31:36:35 | query | | mongoose.js:36:31:36:35 | query | | mongoose.js:39:19:39:23 | query | +| mongoose.js:39:19:39:23 | query | +| mongoose.js:42:22:42:26 | query | | mongoose.js:42:22:42:26 | query | | mongoose.js:45:31:45:35 | query | +| mongoose.js:45:31:45:35 | query | +| mongoose.js:48:31:48:35 | query | | mongoose.js:48:31:48:35 | query | | mongoose.js:51:31:51:35 | query | +| mongoose.js:51:31:51:35 | query | +| mongoose.js:54:25:54:29 | query | | mongoose.js:54:25:54:29 | query | | mongoose.js:57:21:57:25 | query | +| mongoose.js:57:21:57:25 | query | | mongoose.js:60:25:60:29 | query | +| mongoose.js:60:25:60:29 | query | +| mongoose.js:63:24:63:28 | query | | mongoose.js:63:24:63:28 | query | | mongooseJsonParse.js:19:11:19:20 | query | | mongooseJsonParse.js:19:19:19:20 | {} | | mongooseJsonParse.js:20:19:20:44 | JSON.pa ... y.data) | | mongooseJsonParse.js:20:19:20:50 | JSON.pa ... ).title | | mongooseJsonParse.js:20:30:20:43 | req.query.data | +| mongooseJsonParse.js:20:30:20:43 | req.query.data | +| mongooseJsonParse.js:23:19:23:23 | query | | mongooseJsonParse.js:23:19:23:23 | query | | mongooseModelClient.js:10:7:10:32 | v | | mongooseModelClient.js:10:11:10:32 | JSON.pa ... body.x) | | mongooseModelClient.js:10:22:10:29 | req.body | +| mongooseModelClient.js:10:22:10:29 | req.body | | mongooseModelClient.js:10:22:10:31 | req.body.x | | mongooseModelClient.js:11:16:11:24 | { id: v } | +| mongooseModelClient.js:11:16:11:24 | { id: v } | | mongooseModelClient.js:11:22:11:22 | v | | mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | +| mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | +| mongooseModelClient.js:12:22:12:29 | req.body | | mongooseModelClient.js:12:22:12:29 | req.body | | mongooseModelClient.js:12:22:12:32 | req.body.id | | socketio.js:10:25:10:30 | handle | +| socketio.js:10:25:10:30 | handle | +| socketio.js:11:12:11:53 | `INSERT ... andle}` | | socketio.js:11:12:11:53 | `INSERT ... andle}` | | socketio.js:11:46:11:51 | handle | | tst2.js:9:27:9:84 | "select ... d + "'" | +| tst2.js:9:27:9:84 | "select ... d + "'" | +| tst2.js:9:66:9:78 | req.params.id | | tst2.js:9:66:9:78 | req.params.id | | tst3.js:8:7:9:55 | query1 | | tst3.js:8:16:9:55 | "SELECT ... PRICE" | | tst3.js:9:16:9:34 | req.params.category | +| tst3.js:9:16:9:34 | req.params.category | +| tst3.js:10:14:10:19 | query1 | | tst3.js:10:14:10:19 | query1 | | tst4.js:8:10:8:66 | 'SELECT ... d + '"' | +| tst4.js:8:10:8:66 | 'SELECT ... d + '"' | +| tst4.js:8:46:8:60 | $routeParams.id | | tst4.js:8:46:8:60 | $routeParams.id | | tst.js:10:10:10:64 | 'SELECT ... d + '"' | +| tst.js:10:10:10:64 | 'SELECT ... d + '"' | +| tst.js:10:46:10:58 | req.params.id | | tst.js:10:46:10:58 | req.params.id | edges -| mongodb.js:12:11:12:20 | query | mongodb.js:14:59:14:58 | query | +| mongodb.js:12:11:12:20 | query | mongodb.js:18:16:18:20 | query | | mongodb.js:12:11:12:20 | query | mongodb.js:18:16:18:20 | query | | mongodb.js:12:19:12:20 | {} | mongodb.js:12:11:12:20 | query | | mongodb.js:13:19:13:26 | req.body | mongodb.js:13:19:13:32 | req.body.title | +| mongodb.js:13:19:13:26 | req.body | mongodb.js:13:19:13:32 | req.body.title | | mongodb.js:13:19:13:32 | req.body.title | mongodb.js:12:11:12:20 | query | | mongodb.js:13:19:13:32 | req.body.title | mongodb.js:12:19:12:20 | {} | -| mongodb.js:13:19:13:32 | req.body.title | mongodb.js:14:59:14:58 | query | | mongodb.js:13:19:13:32 | req.body.title | mongodb.js:18:16:18:20 | query | -| mongodb.js:14:59:14:58 | query | mongodb.js:18:16:18:20 | query | -| mongodb.js:26:11:26:32 | title | mongodb.js:27:11:27:35 | title | +| mongodb.js:13:19:13:32 | req.body.title | mongodb.js:18:16:18:20 | query | | mongodb.js:26:11:26:32 | title | mongodb.js:32:38:32:42 | title | | mongodb.js:26:19:26:26 | req.body | mongodb.js:26:19:26:32 | req.body.title | +| mongodb.js:26:19:26:26 | req.body | mongodb.js:26:19:26:32 | req.body.title | | mongodb.js:26:19:26:32 | req.body.title | mongodb.js:26:11:26:32 | title | -| mongodb.js:27:11:27:35 | title | mongodb.js:32:38:32:42 | title | +| mongodb.js:32:27:32:43 | JSON.parse(title) | mongodb.js:32:18:32:45 | { title ... itle) } | | mongodb.js:32:27:32:43 | JSON.parse(title) | mongodb.js:32:18:32:45 | { title ... itle) } | | mongodb.js:32:38:32:42 | title | mongodb.js:32:27:32:43 | JSON.parse(title) | -| mongodb.js:48:11:48:20 | query | mongodb.js:50:59:50:58 | query | +| mongodb.js:48:11:48:20 | query | mongodb.js:54:16:54:20 | query | | mongodb.js:48:11:48:20 | query | mongodb.js:54:16:54:20 | query | | mongodb.js:48:19:48:20 | {} | mongodb.js:48:11:48:20 | query | | mongodb.js:49:19:49:33 | req.query.title | mongodb.js:48:11:48:20 | query | +| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:48:11:48:20 | query | +| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:48:19:48:20 | {} | | mongodb.js:49:19:49:33 | req.query.title | mongodb.js:48:19:48:20 | {} | -| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:50:59:50:58 | query | | mongodb.js:49:19:49:33 | req.query.title | mongodb.js:54:16:54:20 | query | -| mongodb.js:50:59:50:58 | query | mongodb.js:54:16:54:20 | query | -| mongodb_bodySafe.js:23:11:23:20 | query | mongodb_bodySafe.js:25:59:25:58 | query | +| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:54:16:54:20 | query | +| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:54:16:54:20 | query | +| mongodb.js:49:19:49:33 | req.query.title | mongodb.js:54:16:54:20 | query | +| mongodb_bodySafe.js:23:11:23:20 | query | mongodb_bodySafe.js:29:16:29:20 | query | | mongodb_bodySafe.js:23:11:23:20 | query | mongodb_bodySafe.js:29:16:29:20 | query | | mongodb_bodySafe.js:23:19:23:20 | {} | mongodb_bodySafe.js:23:11:23:20 | query | | mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:23:11:23:20 | query | +| mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:23:11:23:20 | query | +| mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:23:19:23:20 | {} | | mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:23:19:23:20 | {} | -| mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:25:59:25:58 | query | | mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:29:16:29:20 | query | -| mongodb_bodySafe.js:25:59:25:58 | query | mongodb_bodySafe.js:29:16:29:20 | query | +| mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:29:16:29:20 | query | +| mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:29:16:29:20 | query | +| mongodb_bodySafe.js:24:19:24:33 | req.query.title | mongodb_bodySafe.js:29:16:29:20 | query | +| mongoose.js:20:11:20:20 | query | mongoose.js:27:20:27:24 | query | | mongoose.js:20:11:20:20 | query | mongoose.js:27:20:27:24 | query | | mongoose.js:20:11:20:20 | query | mongoose.js:30:25:30:29 | query | +| mongoose.js:20:11:20:20 | query | mongoose.js:30:25:30:29 | query | +| mongoose.js:20:11:20:20 | query | mongoose.js:33:24:33:28 | query | | mongoose.js:20:11:20:20 | query | mongoose.js:33:24:33:28 | query | | mongoose.js:20:11:20:20 | query | mongoose.js:36:31:36:35 | query | +| mongoose.js:20:11:20:20 | query | mongoose.js:36:31:36:35 | query | +| mongoose.js:20:11:20:20 | query | mongoose.js:39:19:39:23 | query | | mongoose.js:20:11:20:20 | query | mongoose.js:39:19:39:23 | query | | mongoose.js:20:11:20:20 | query | mongoose.js:42:22:42:26 | query | +| mongoose.js:20:11:20:20 | query | mongoose.js:42:22:42:26 | query | +| mongoose.js:20:11:20:20 | query | mongoose.js:45:31:45:35 | query | | mongoose.js:20:11:20:20 | query | mongoose.js:45:31:45:35 | query | | mongoose.js:20:11:20:20 | query | mongoose.js:48:31:48:35 | query | +| mongoose.js:20:11:20:20 | query | mongoose.js:48:31:48:35 | query | +| mongoose.js:20:11:20:20 | query | mongoose.js:51:31:51:35 | query | | mongoose.js:20:11:20:20 | query | mongoose.js:51:31:51:35 | query | | mongoose.js:20:11:20:20 | query | mongoose.js:54:25:54:29 | query | +| mongoose.js:20:11:20:20 | query | mongoose.js:54:25:54:29 | query | +| mongoose.js:20:11:20:20 | query | mongoose.js:57:21:57:25 | query | | mongoose.js:20:11:20:20 | query | mongoose.js:57:21:57:25 | query | | mongoose.js:20:11:20:20 | query | mongoose.js:60:25:60:29 | query | +| mongoose.js:20:11:20:20 | query | mongoose.js:60:25:60:29 | query | +| mongoose.js:20:11:20:20 | query | mongoose.js:63:24:63:28 | query | | mongoose.js:20:11:20:20 | query | mongoose.js:63:24:63:28 | query | | mongoose.js:20:19:20:20 | {} | mongoose.js:20:11:20:20 | query | | mongoose.js:21:19:21:26 | req.body | mongoose.js:21:19:21:32 | req.body.title | +| mongoose.js:21:19:21:26 | req.body | mongoose.js:21:19:21:32 | req.body.title | | mongoose.js:21:19:21:32 | req.body.title | mongoose.js:20:11:20:20 | query | | mongoose.js:21:19:21:32 | req.body.title | mongoose.js:20:19:20:20 | {} | | mongoose.js:21:19:21:32 | req.body.title | mongoose.js:27:20:27:24 | query | +| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:27:20:27:24 | query | +| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:30:25:30:29 | query | | mongoose.js:21:19:21:32 | req.body.title | mongoose.js:30:25:30:29 | query | | mongoose.js:21:19:21:32 | req.body.title | mongoose.js:33:24:33:28 | query | +| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:33:24:33:28 | query | +| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:36:31:36:35 | query | | mongoose.js:21:19:21:32 | req.body.title | mongoose.js:36:31:36:35 | query | | mongoose.js:21:19:21:32 | req.body.title | mongoose.js:39:19:39:23 | query | +| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:39:19:39:23 | query | +| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:42:22:42:26 | query | | mongoose.js:21:19:21:32 | req.body.title | mongoose.js:42:22:42:26 | query | | mongoose.js:21:19:21:32 | req.body.title | mongoose.js:45:31:45:35 | query | +| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:45:31:45:35 | query | +| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:48:31:48:35 | query | | mongoose.js:21:19:21:32 | req.body.title | mongoose.js:48:31:48:35 | query | | mongoose.js:21:19:21:32 | req.body.title | mongoose.js:51:31:51:35 | query | +| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:51:31:51:35 | query | +| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:54:25:54:29 | query | | mongoose.js:21:19:21:32 | req.body.title | mongoose.js:54:25:54:29 | query | | mongoose.js:21:19:21:32 | req.body.title | mongoose.js:57:21:57:25 | query | +| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:57:21:57:25 | query | +| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:60:25:60:29 | query | | mongoose.js:21:19:21:32 | req.body.title | mongoose.js:60:25:60:29 | query | | mongoose.js:21:19:21:32 | req.body.title | mongoose.js:63:24:63:28 | query | +| mongoose.js:21:19:21:32 | req.body.title | mongoose.js:63:24:63:28 | query | +| mongooseJsonParse.js:19:11:19:20 | query | mongooseJsonParse.js:23:19:23:23 | query | | mongooseJsonParse.js:19:11:19:20 | query | mongooseJsonParse.js:23:19:23:23 | query | | mongooseJsonParse.js:19:19:19:20 | {} | mongooseJsonParse.js:19:11:19:20 | query | | mongooseJsonParse.js:20:19:20:44 | JSON.pa ... y.data) | mongooseJsonParse.js:20:19:20:50 | JSON.pa ... ).title | | mongooseJsonParse.js:20:19:20:50 | JSON.pa ... ).title | mongooseJsonParse.js:19:11:19:20 | query | | mongooseJsonParse.js:20:19:20:50 | JSON.pa ... ).title | mongooseJsonParse.js:19:19:19:20 | {} | | mongooseJsonParse.js:20:19:20:50 | JSON.pa ... ).title | mongooseJsonParse.js:23:19:23:23 | query | +| mongooseJsonParse.js:20:19:20:50 | JSON.pa ... ).title | mongooseJsonParse.js:23:19:23:23 | query | +| mongooseJsonParse.js:20:30:20:43 | req.query.data | mongooseJsonParse.js:20:19:20:44 | JSON.pa ... y.data) | | mongooseJsonParse.js:20:30:20:43 | req.query.data | mongooseJsonParse.js:20:19:20:44 | JSON.pa ... y.data) | | mongooseModelClient.js:10:7:10:32 | v | mongooseModelClient.js:11:22:11:22 | v | | mongooseModelClient.js:10:11:10:32 | JSON.pa ... body.x) | mongooseModelClient.js:10:7:10:32 | v | | mongooseModelClient.js:10:22:10:29 | req.body | mongooseModelClient.js:10:22:10:31 | req.body.x | +| mongooseModelClient.js:10:22:10:29 | req.body | mongooseModelClient.js:10:22:10:31 | req.body.x | | mongooseModelClient.js:10:22:10:31 | req.body.x | mongooseModelClient.js:10:11:10:32 | JSON.pa ... body.x) | | mongooseModelClient.js:11:22:11:22 | v | mongooseModelClient.js:11:16:11:24 | { id: v } | +| mongooseModelClient.js:11:22:11:22 | v | mongooseModelClient.js:11:16:11:24 | { id: v } | +| mongooseModelClient.js:12:22:12:29 | req.body | mongooseModelClient.js:12:22:12:32 | req.body.id | | mongooseModelClient.js:12:22:12:29 | req.body | mongooseModelClient.js:12:22:12:32 | req.body.id | | mongooseModelClient.js:12:22:12:32 | req.body.id | mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | +| mongooseModelClient.js:12:22:12:32 | req.body.id | mongooseModelClient.js:12:16:12:34 | { id: req.body.id } | +| socketio.js:10:25:10:30 | handle | socketio.js:11:46:11:51 | handle | | socketio.js:10:25:10:30 | handle | socketio.js:11:46:11:51 | handle | | socketio.js:11:46:11:51 | handle | socketio.js:11:12:11:53 | `INSERT ... andle}` | -| tst2.js:9:27:9:78 | "select ... rams.id | tst2.js:9:27:9:84 | "select ... d + "'" | -| tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:78 | "select ... rams.id | +| socketio.js:11:46:11:51 | handle | socketio.js:11:12:11:53 | `INSERT ... andle}` | +| tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:84 | "select ... d + "'" | +| tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:84 | "select ... d + "'" | +| tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:84 | "select ... d + "'" | | tst2.js:9:66:9:78 | req.params.id | tst2.js:9:27:9:84 | "select ... d + "'" | | tst3.js:8:7:9:55 | query1 | tst3.js:10:14:10:19 | query1 | -| tst3.js:8:16:9:34 | "SELECT ... ategory | tst3.js:8:16:9:55 | "SELECT ... PRICE" | +| tst3.js:8:7:9:55 | query1 | tst3.js:10:14:10:19 | query1 | | tst3.js:8:16:9:55 | "SELECT ... PRICE" | tst3.js:8:7:9:55 | query1 | -| tst3.js:9:16:9:34 | req.params.category | tst3.js:8:16:9:34 | "SELECT ... ategory | | tst3.js:9:16:9:34 | req.params.category | tst3.js:8:16:9:55 | "SELECT ... PRICE" | -| tst4.js:8:10:8:60 | 'SELECT ... rams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' | -| tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:60 | 'SELECT ... rams.id | +| tst3.js:9:16:9:34 | req.params.category | tst3.js:8:16:9:55 | "SELECT ... PRICE" | | tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' | -| tst.js:10:10:10:58 | 'SELECT ... rams.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' | -| tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:58 | 'SELECT ... rams.id | +| tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' | +| tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' | +| tst4.js:8:46:8:60 | $routeParams.id | tst4.js:8:10:8:66 | 'SELECT ... d + '"' | +| tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' | +| tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' | +| tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' | | tst.js:10:46:10:58 | req.params.id | tst.js:10:10:10:64 | 'SELECT ... d + '"' | #select | mongodb.js:18:16:18:20 | query | mongodb.js:13:19:13:26 | req.body | mongodb.js:18:16:18:20 | query | This query depends on $@. | mongodb.js:13:19:13:26 | req.body | a user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/tst2.js b/javascript/ql/test/query-tests/Security/CWE-089/untyped/tst2.js index 126745e9444..b28ddabc9ca 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/tst2.js +++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/tst2.js @@ -8,5 +8,3 @@ app.get('/post/:id', async function(req, res) { // NOT OK new sql.Request().query("select * from mytable where id = '" + req.params.id + "'"); }); - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/Security/CWE-089/untyped/tst4.js b/javascript/ql/test/query-tests/Security/CWE-089/untyped/tst4.js index 7df5c6b4f3f..73cddfb3a6a 100644 --- a/javascript/ql/test/query-tests/Security/CWE-089/untyped/tst4.js +++ b/javascript/ql/test/query-tests/Security/CWE-089/untyped/tst4.js @@ -7,5 +7,3 @@ angular.module('myApp', ['ngRoute']) .controller('FindPost', function($routeParams) { db.get('SELECT * FROM Post WHERE id = "' + $routeParams.id + '"'); }); - -// semmle-extractor-options: --platform node diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected index 1a5f6ed778c..3f98240b753 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected @@ -1,99 +1,215 @@ nodes | angularjs.js:10:22:10:29 | location | +| angularjs.js:10:22:10:29 | location | +| angularjs.js:10:22:10:36 | location.search | | angularjs.js:10:22:10:36 | location.search | | angularjs.js:13:23:13:30 | location | +| angularjs.js:13:23:13:30 | location | +| angularjs.js:13:23:13:37 | location.search | | angularjs.js:13:23:13:37 | location.search | | angularjs.js:16:28:16:35 | location | +| angularjs.js:16:28:16:35 | location | +| angularjs.js:16:28:16:42 | location.search | | angularjs.js:16:28:16:42 | location.search | | angularjs.js:19:22:19:29 | location | +| angularjs.js:19:22:19:29 | location | +| angularjs.js:19:22:19:36 | location.search | | angularjs.js:19:22:19:36 | location.search | | angularjs.js:22:27:22:34 | location | +| angularjs.js:22:27:22:34 | location | +| angularjs.js:22:27:22:41 | location.search | | angularjs.js:22:27:22:41 | location.search | | angularjs.js:25:23:25:30 | location | +| angularjs.js:25:23:25:30 | location | +| angularjs.js:25:23:25:37 | location.search | | angularjs.js:25:23:25:37 | location.search | | angularjs.js:28:33:28:40 | location | +| angularjs.js:28:33:28:40 | location | +| angularjs.js:28:33:28:47 | location.search | | angularjs.js:28:33:28:47 | location.search | | angularjs.js:31:28:31:35 | location | +| angularjs.js:31:28:31:35 | location | +| angularjs.js:31:28:31:42 | location.search | | angularjs.js:31:28:31:42 | location.search | | angularjs.js:34:18:34:25 | location | +| angularjs.js:34:18:34:25 | location | +| angularjs.js:34:18:34:32 | location.search | | angularjs.js:34:18:34:32 | location.search | | angularjs.js:40:18:40:25 | location | +| angularjs.js:40:18:40:25 | location | +| angularjs.js:40:18:40:32 | location.search | | angularjs.js:40:18:40:32 | location.search | | angularjs.js:44:17:44:24 | location | +| angularjs.js:44:17:44:24 | location | +| angularjs.js:44:17:44:31 | location.search | | angularjs.js:44:17:44:31 | location.search | | angularjs.js:47:16:47:23 | location | +| angularjs.js:47:16:47:23 | location | +| angularjs.js:47:16:47:30 | location.search | | angularjs.js:47:16:47:30 | location.search | | angularjs.js:50:22:50:29 | location | +| angularjs.js:50:22:50:29 | location | +| angularjs.js:50:22:50:36 | location.search | | angularjs.js:50:22:50:36 | location.search | | angularjs.js:53:32:53:39 | location | +| angularjs.js:53:32:53:39 | location | +| angularjs.js:53:32:53:46 | location.search | | angularjs.js:53:32:53:46 | location.search | | express.js:7:24:7:69 | "return ... + "];" | +| express.js:7:24:7:69 | "return ... + "];" | +| express.js:7:44:7:62 | req.param("wobble") | | express.js:7:44:7:62 | req.param("wobble") | | express.js:9:34:9:79 | "return ... + "];" | +| express.js:9:34:9:79 | "return ... + "];" | +| express.js:9:54:9:72 | req.param("wobble") | | express.js:9:54:9:72 | req.param("wobble") | | express.js:12:8:12:53 | "return ... + "];" | +| express.js:12:8:12:53 | "return ... + "];" | +| express.js:12:28:12:46 | req.param("wobble") | | express.js:12:28:12:46 | req.param("wobble") | | react-native.js:7:7:7:33 | tainted | | react-native.js:7:17:7:33 | req.param("code") | +| react-native.js:7:17:7:33 | req.param("code") | +| react-native.js:8:32:8:38 | tainted | | react-native.js:8:32:8:38 | tainted | | react-native.js:10:23:10:29 | tainted | +| react-native.js:10:23:10:29 | tainted | +| tst.js:2:6:2:22 | document.location | | tst.js:2:6:2:22 | document.location | | tst.js:2:6:2:27 | documen ... on.href | | tst.js:2:6:2:83 | documen ... t=")+8) | +| tst.js:2:6:2:83 | documen ... t=")+8) | +| tst.js:5:12:5:28 | document.location | | tst.js:5:12:5:28 | document.location | | tst.js:5:12:5:33 | documen ... on.hash | +| tst.js:5:12:5:33 | documen ... on.hash | +| tst.js:14:10:14:26 | document.location | | tst.js:14:10:14:26 | document.location | | tst.js:14:10:14:33 | documen ... .search | | tst.js:14:10:14:74 | documen ... , "$1") | +| tst.js:14:10:14:74 | documen ... , "$1") | +| tst.js:17:21:17:37 | document.location | | tst.js:17:21:17:37 | document.location | | tst.js:17:21:17:42 | documen ... on.hash | +| tst.js:17:21:17:42 | documen ... on.hash | +| tst.js:20:30:20:46 | document.location | | tst.js:20:30:20:46 | document.location | | tst.js:20:30:20:51 | documen ... on.hash | +| tst.js:20:30:20:51 | documen ... on.hash | | tst.js:23:6:23:46 | atob(do ... ing(1)) | +| tst.js:23:6:23:46 | atob(do ... ing(1)) | +| tst.js:23:11:23:27 | document.location | | tst.js:23:11:23:27 | document.location | | tst.js:23:11:23:32 | documen ... on.hash | | tst.js:23:11:23:45 | documen ... ring(1) | | tst.js:26:26:26:33 | location | +| tst.js:26:26:26:33 | location | | tst.js:26:26:26:40 | location.search | | tst.js:26:26:26:53 | locatio ... ring(1) | +| tst.js:26:26:26:53 | locatio ... ring(1) | edges | angularjs.js:10:22:10:29 | location | angularjs.js:10:22:10:36 | location.search | +| angularjs.js:10:22:10:29 | location | angularjs.js:10:22:10:36 | location.search | +| angularjs.js:10:22:10:29 | location | angularjs.js:10:22:10:36 | location.search | +| angularjs.js:10:22:10:29 | location | angularjs.js:10:22:10:36 | location.search | +| angularjs.js:13:23:13:30 | location | angularjs.js:13:23:13:37 | location.search | +| angularjs.js:13:23:13:30 | location | angularjs.js:13:23:13:37 | location.search | +| angularjs.js:13:23:13:30 | location | angularjs.js:13:23:13:37 | location.search | | angularjs.js:13:23:13:30 | location | angularjs.js:13:23:13:37 | location.search | | angularjs.js:16:28:16:35 | location | angularjs.js:16:28:16:42 | location.search | +| angularjs.js:16:28:16:35 | location | angularjs.js:16:28:16:42 | location.search | +| angularjs.js:16:28:16:35 | location | angularjs.js:16:28:16:42 | location.search | +| angularjs.js:16:28:16:35 | location | angularjs.js:16:28:16:42 | location.search | +| angularjs.js:19:22:19:29 | location | angularjs.js:19:22:19:36 | location.search | +| angularjs.js:19:22:19:29 | location | angularjs.js:19:22:19:36 | location.search | +| angularjs.js:19:22:19:29 | location | angularjs.js:19:22:19:36 | location.search | | angularjs.js:19:22:19:29 | location | angularjs.js:19:22:19:36 | location.search | | angularjs.js:22:27:22:34 | location | angularjs.js:22:27:22:41 | location.search | +| angularjs.js:22:27:22:34 | location | angularjs.js:22:27:22:41 | location.search | +| angularjs.js:22:27:22:34 | location | angularjs.js:22:27:22:41 | location.search | +| angularjs.js:22:27:22:34 | location | angularjs.js:22:27:22:41 | location.search | +| angularjs.js:25:23:25:30 | location | angularjs.js:25:23:25:37 | location.search | +| angularjs.js:25:23:25:30 | location | angularjs.js:25:23:25:37 | location.search | +| angularjs.js:25:23:25:30 | location | angularjs.js:25:23:25:37 | location.search | | angularjs.js:25:23:25:30 | location | angularjs.js:25:23:25:37 | location.search | | angularjs.js:28:33:28:40 | location | angularjs.js:28:33:28:47 | location.search | +| angularjs.js:28:33:28:40 | location | angularjs.js:28:33:28:47 | location.search | +| angularjs.js:28:33:28:40 | location | angularjs.js:28:33:28:47 | location.search | +| angularjs.js:28:33:28:40 | location | angularjs.js:28:33:28:47 | location.search | +| angularjs.js:31:28:31:35 | location | angularjs.js:31:28:31:42 | location.search | +| angularjs.js:31:28:31:35 | location | angularjs.js:31:28:31:42 | location.search | +| angularjs.js:31:28:31:35 | location | angularjs.js:31:28:31:42 | location.search | | angularjs.js:31:28:31:35 | location | angularjs.js:31:28:31:42 | location.search | | angularjs.js:34:18:34:25 | location | angularjs.js:34:18:34:32 | location.search | +| angularjs.js:34:18:34:25 | location | angularjs.js:34:18:34:32 | location.search | +| angularjs.js:34:18:34:25 | location | angularjs.js:34:18:34:32 | location.search | +| angularjs.js:34:18:34:25 | location | angularjs.js:34:18:34:32 | location.search | +| angularjs.js:40:18:40:25 | location | angularjs.js:40:18:40:32 | location.search | +| angularjs.js:40:18:40:25 | location | angularjs.js:40:18:40:32 | location.search | +| angularjs.js:40:18:40:25 | location | angularjs.js:40:18:40:32 | location.search | | angularjs.js:40:18:40:25 | location | angularjs.js:40:18:40:32 | location.search | | angularjs.js:44:17:44:24 | location | angularjs.js:44:17:44:31 | location.search | +| angularjs.js:44:17:44:24 | location | angularjs.js:44:17:44:31 | location.search | +| angularjs.js:44:17:44:24 | location | angularjs.js:44:17:44:31 | location.search | +| angularjs.js:44:17:44:24 | location | angularjs.js:44:17:44:31 | location.search | +| angularjs.js:47:16:47:23 | location | angularjs.js:47:16:47:30 | location.search | +| angularjs.js:47:16:47:23 | location | angularjs.js:47:16:47:30 | location.search | +| angularjs.js:47:16:47:23 | location | angularjs.js:47:16:47:30 | location.search | | angularjs.js:47:16:47:23 | location | angularjs.js:47:16:47:30 | location.search | | angularjs.js:50:22:50:29 | location | angularjs.js:50:22:50:36 | location.search | +| angularjs.js:50:22:50:29 | location | angularjs.js:50:22:50:36 | location.search | +| angularjs.js:50:22:50:29 | location | angularjs.js:50:22:50:36 | location.search | +| angularjs.js:50:22:50:29 | location | angularjs.js:50:22:50:36 | location.search | +| angularjs.js:53:32:53:39 | location | angularjs.js:53:32:53:46 | location.search | +| angularjs.js:53:32:53:39 | location | angularjs.js:53:32:53:46 | location.search | +| angularjs.js:53:32:53:39 | location | angularjs.js:53:32:53:46 | location.search | | angularjs.js:53:32:53:39 | location | angularjs.js:53:32:53:46 | location.search | -| express.js:7:24:7:62 | "return ... obble") | express.js:7:24:7:69 | "return ... + "];" | -| express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:62 | "return ... obble") | | express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:69 | "return ... + "];" | -| express.js:9:34:9:72 | "return ... obble") | express.js:9:34:9:79 | "return ... + "];" | -| express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:72 | "return ... obble") | +| express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:69 | "return ... + "];" | +| express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:69 | "return ... + "];" | +| express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:69 | "return ... + "];" | | express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:79 | "return ... + "];" | -| express.js:12:8:12:46 | "return ... obble") | express.js:12:8:12:53 | "return ... + "];" | -| express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:46 | "return ... obble") | +| express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:79 | "return ... + "];" | +| express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:79 | "return ... + "];" | +| express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:79 | "return ... + "];" | +| express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:53 | "return ... + "];" | +| express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:53 | "return ... + "];" | +| express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:53 | "return ... + "];" | | express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:53 | "return ... + "];" | | react-native.js:7:7:7:33 | tainted | react-native.js:8:32:8:38 | tainted | +| react-native.js:7:7:7:33 | tainted | react-native.js:8:32:8:38 | tainted | +| react-native.js:7:7:7:33 | tainted | react-native.js:10:23:10:29 | tainted | | react-native.js:7:7:7:33 | tainted | react-native.js:10:23:10:29 | tainted | | react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | +| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | +| tst.js:2:6:2:22 | document.location | tst.js:2:6:2:27 | documen ... on.href | | tst.js:2:6:2:22 | document.location | tst.js:2:6:2:27 | documen ... on.href | | tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | +| tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | +| tst.js:5:12:5:28 | document.location | tst.js:5:12:5:33 | documen ... on.hash | +| tst.js:5:12:5:28 | document.location | tst.js:5:12:5:33 | documen ... on.hash | +| tst.js:5:12:5:28 | document.location | tst.js:5:12:5:33 | documen ... on.hash | | tst.js:5:12:5:28 | document.location | tst.js:5:12:5:33 | documen ... on.hash | | tst.js:14:10:14:26 | document.location | tst.js:14:10:14:33 | documen ... .search | +| tst.js:14:10:14:26 | document.location | tst.js:14:10:14:33 | documen ... .search | +| tst.js:14:10:14:33 | documen ... .search | tst.js:14:10:14:74 | documen ... , "$1") | | tst.js:14:10:14:33 | documen ... .search | tst.js:14:10:14:74 | documen ... , "$1") | | tst.js:17:21:17:37 | document.location | tst.js:17:21:17:42 | documen ... on.hash | +| tst.js:17:21:17:37 | document.location | tst.js:17:21:17:42 | documen ... on.hash | +| tst.js:17:21:17:37 | document.location | tst.js:17:21:17:42 | documen ... on.hash | +| tst.js:17:21:17:37 | document.location | tst.js:17:21:17:42 | documen ... on.hash | | tst.js:20:30:20:46 | document.location | tst.js:20:30:20:51 | documen ... on.hash | +| tst.js:20:30:20:46 | document.location | tst.js:20:30:20:51 | documen ... on.hash | +| tst.js:20:30:20:46 | document.location | tst.js:20:30:20:51 | documen ... on.hash | +| tst.js:20:30:20:46 | document.location | tst.js:20:30:20:51 | documen ... on.hash | +| tst.js:23:11:23:27 | document.location | tst.js:23:11:23:32 | documen ... on.hash | | tst.js:23:11:23:27 | document.location | tst.js:23:11:23:32 | documen ... on.hash | | tst.js:23:11:23:32 | documen ... on.hash | tst.js:23:11:23:45 | documen ... ring(1) | | tst.js:23:11:23:45 | documen ... ring(1) | tst.js:23:6:23:46 | atob(do ... ing(1)) | +| tst.js:23:11:23:45 | documen ... ring(1) | tst.js:23:6:23:46 | atob(do ... ing(1)) | | tst.js:26:26:26:33 | location | tst.js:26:26:26:40 | location.search | +| tst.js:26:26:26:33 | location | tst.js:26:26:26:40 | location.search | +| tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) | | tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) | #select | angularjs.js:10:22:10:36 | location.search | angularjs.js:10:22:10:29 | location | angularjs.js:10:22:10:36 | location.search | $@ flows to here and is interpreted as code. | angularjs.js:10:22:10:29 | location | User-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected index d7dd25fde08..8f91bda7241 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected @@ -1,102 +1,223 @@ nodes | angularjs.js:10:22:10:29 | location | +| angularjs.js:10:22:10:29 | location | +| angularjs.js:10:22:10:36 | location.search | | angularjs.js:10:22:10:36 | location.search | | angularjs.js:13:23:13:30 | location | +| angularjs.js:13:23:13:30 | location | +| angularjs.js:13:23:13:37 | location.search | | angularjs.js:13:23:13:37 | location.search | | angularjs.js:16:28:16:35 | location | +| angularjs.js:16:28:16:35 | location | +| angularjs.js:16:28:16:42 | location.search | | angularjs.js:16:28:16:42 | location.search | | angularjs.js:19:22:19:29 | location | +| angularjs.js:19:22:19:29 | location | +| angularjs.js:19:22:19:36 | location.search | | angularjs.js:19:22:19:36 | location.search | | angularjs.js:22:27:22:34 | location | +| angularjs.js:22:27:22:34 | location | +| angularjs.js:22:27:22:41 | location.search | | angularjs.js:22:27:22:41 | location.search | | angularjs.js:25:23:25:30 | location | +| angularjs.js:25:23:25:30 | location | +| angularjs.js:25:23:25:37 | location.search | | angularjs.js:25:23:25:37 | location.search | | angularjs.js:28:33:28:40 | location | +| angularjs.js:28:33:28:40 | location | +| angularjs.js:28:33:28:47 | location.search | | angularjs.js:28:33:28:47 | location.search | | angularjs.js:31:28:31:35 | location | +| angularjs.js:31:28:31:35 | location | +| angularjs.js:31:28:31:42 | location.search | | angularjs.js:31:28:31:42 | location.search | | angularjs.js:34:18:34:25 | location | +| angularjs.js:34:18:34:25 | location | +| angularjs.js:34:18:34:32 | location.search | | angularjs.js:34:18:34:32 | location.search | | angularjs.js:40:18:40:25 | location | +| angularjs.js:40:18:40:25 | location | +| angularjs.js:40:18:40:32 | location.search | | angularjs.js:40:18:40:32 | location.search | | angularjs.js:44:17:44:24 | location | +| angularjs.js:44:17:44:24 | location | +| angularjs.js:44:17:44:31 | location.search | | angularjs.js:44:17:44:31 | location.search | | angularjs.js:47:16:47:23 | location | +| angularjs.js:47:16:47:23 | location | +| angularjs.js:47:16:47:30 | location.search | | angularjs.js:47:16:47:30 | location.search | | angularjs.js:50:22:50:29 | location | +| angularjs.js:50:22:50:29 | location | +| angularjs.js:50:22:50:36 | location.search | | angularjs.js:50:22:50:36 | location.search | | angularjs.js:53:32:53:39 | location | +| angularjs.js:53:32:53:39 | location | +| angularjs.js:53:32:53:46 | location.search | | angularjs.js:53:32:53:46 | location.search | | eslint-escope-build.js:20:22:20:22 | c | +| eslint-escope-build.js:20:22:20:22 | c | +| eslint-escope-build.js:21:16:21:16 | c | | eslint-escope-build.js:21:16:21:16 | c | | express.js:7:24:7:69 | "return ... + "];" | +| express.js:7:24:7:69 | "return ... + "];" | +| express.js:7:44:7:62 | req.param("wobble") | | express.js:7:44:7:62 | req.param("wobble") | | express.js:9:34:9:79 | "return ... + "];" | +| express.js:9:34:9:79 | "return ... + "];" | +| express.js:9:54:9:72 | req.param("wobble") | | express.js:9:54:9:72 | req.param("wobble") | | express.js:12:8:12:53 | "return ... + "];" | +| express.js:12:8:12:53 | "return ... + "];" | +| express.js:12:28:12:46 | req.param("wobble") | | express.js:12:28:12:46 | req.param("wobble") | | react-native.js:7:7:7:33 | tainted | | react-native.js:7:17:7:33 | req.param("code") | +| react-native.js:7:17:7:33 | req.param("code") | +| react-native.js:8:32:8:38 | tainted | | react-native.js:8:32:8:38 | tainted | | react-native.js:10:23:10:29 | tainted | +| react-native.js:10:23:10:29 | tainted | +| tst.js:2:6:2:22 | document.location | | tst.js:2:6:2:22 | document.location | | tst.js:2:6:2:27 | documen ... on.href | | tst.js:2:6:2:83 | documen ... t=")+8) | +| tst.js:2:6:2:83 | documen ... t=")+8) | +| tst.js:5:12:5:28 | document.location | | tst.js:5:12:5:28 | document.location | | tst.js:5:12:5:33 | documen ... on.hash | +| tst.js:5:12:5:33 | documen ... on.hash | +| tst.js:14:10:14:26 | document.location | | tst.js:14:10:14:26 | document.location | | tst.js:14:10:14:33 | documen ... .search | | tst.js:14:10:14:74 | documen ... , "$1") | +| tst.js:14:10:14:74 | documen ... , "$1") | +| tst.js:17:21:17:37 | document.location | | tst.js:17:21:17:37 | document.location | | tst.js:17:21:17:42 | documen ... on.hash | +| tst.js:17:21:17:42 | documen ... on.hash | +| tst.js:20:30:20:46 | document.location | | tst.js:20:30:20:46 | document.location | | tst.js:20:30:20:51 | documen ... on.hash | +| tst.js:20:30:20:51 | documen ... on.hash | | tst.js:23:6:23:46 | atob(do ... ing(1)) | +| tst.js:23:6:23:46 | atob(do ... ing(1)) | +| tst.js:23:11:23:27 | document.location | | tst.js:23:11:23:27 | document.location | | tst.js:23:11:23:32 | documen ... on.hash | | tst.js:23:11:23:45 | documen ... ring(1) | | tst.js:26:26:26:33 | location | +| tst.js:26:26:26:33 | location | | tst.js:26:26:26:40 | location.search | | tst.js:26:26:26:53 | locatio ... ring(1) | +| tst.js:26:26:26:53 | locatio ... ring(1) | edges | angularjs.js:10:22:10:29 | location | angularjs.js:10:22:10:36 | location.search | +| angularjs.js:10:22:10:29 | location | angularjs.js:10:22:10:36 | location.search | +| angularjs.js:10:22:10:29 | location | angularjs.js:10:22:10:36 | location.search | +| angularjs.js:10:22:10:29 | location | angularjs.js:10:22:10:36 | location.search | +| angularjs.js:13:23:13:30 | location | angularjs.js:13:23:13:37 | location.search | +| angularjs.js:13:23:13:30 | location | angularjs.js:13:23:13:37 | location.search | +| angularjs.js:13:23:13:30 | location | angularjs.js:13:23:13:37 | location.search | | angularjs.js:13:23:13:30 | location | angularjs.js:13:23:13:37 | location.search | | angularjs.js:16:28:16:35 | location | angularjs.js:16:28:16:42 | location.search | +| angularjs.js:16:28:16:35 | location | angularjs.js:16:28:16:42 | location.search | +| angularjs.js:16:28:16:35 | location | angularjs.js:16:28:16:42 | location.search | +| angularjs.js:16:28:16:35 | location | angularjs.js:16:28:16:42 | location.search | +| angularjs.js:19:22:19:29 | location | angularjs.js:19:22:19:36 | location.search | +| angularjs.js:19:22:19:29 | location | angularjs.js:19:22:19:36 | location.search | +| angularjs.js:19:22:19:29 | location | angularjs.js:19:22:19:36 | location.search | | angularjs.js:19:22:19:29 | location | angularjs.js:19:22:19:36 | location.search | | angularjs.js:22:27:22:34 | location | angularjs.js:22:27:22:41 | location.search | +| angularjs.js:22:27:22:34 | location | angularjs.js:22:27:22:41 | location.search | +| angularjs.js:22:27:22:34 | location | angularjs.js:22:27:22:41 | location.search | +| angularjs.js:22:27:22:34 | location | angularjs.js:22:27:22:41 | location.search | +| angularjs.js:25:23:25:30 | location | angularjs.js:25:23:25:37 | location.search | +| angularjs.js:25:23:25:30 | location | angularjs.js:25:23:25:37 | location.search | +| angularjs.js:25:23:25:30 | location | angularjs.js:25:23:25:37 | location.search | | angularjs.js:25:23:25:30 | location | angularjs.js:25:23:25:37 | location.search | | angularjs.js:28:33:28:40 | location | angularjs.js:28:33:28:47 | location.search | +| angularjs.js:28:33:28:40 | location | angularjs.js:28:33:28:47 | location.search | +| angularjs.js:28:33:28:40 | location | angularjs.js:28:33:28:47 | location.search | +| angularjs.js:28:33:28:40 | location | angularjs.js:28:33:28:47 | location.search | +| angularjs.js:31:28:31:35 | location | angularjs.js:31:28:31:42 | location.search | +| angularjs.js:31:28:31:35 | location | angularjs.js:31:28:31:42 | location.search | +| angularjs.js:31:28:31:35 | location | angularjs.js:31:28:31:42 | location.search | | angularjs.js:31:28:31:35 | location | angularjs.js:31:28:31:42 | location.search | | angularjs.js:34:18:34:25 | location | angularjs.js:34:18:34:32 | location.search | +| angularjs.js:34:18:34:25 | location | angularjs.js:34:18:34:32 | location.search | +| angularjs.js:34:18:34:25 | location | angularjs.js:34:18:34:32 | location.search | +| angularjs.js:34:18:34:25 | location | angularjs.js:34:18:34:32 | location.search | +| angularjs.js:40:18:40:25 | location | angularjs.js:40:18:40:32 | location.search | +| angularjs.js:40:18:40:25 | location | angularjs.js:40:18:40:32 | location.search | +| angularjs.js:40:18:40:25 | location | angularjs.js:40:18:40:32 | location.search | | angularjs.js:40:18:40:25 | location | angularjs.js:40:18:40:32 | location.search | | angularjs.js:44:17:44:24 | location | angularjs.js:44:17:44:31 | location.search | +| angularjs.js:44:17:44:24 | location | angularjs.js:44:17:44:31 | location.search | +| angularjs.js:44:17:44:24 | location | angularjs.js:44:17:44:31 | location.search | +| angularjs.js:44:17:44:24 | location | angularjs.js:44:17:44:31 | location.search | +| angularjs.js:47:16:47:23 | location | angularjs.js:47:16:47:30 | location.search | +| angularjs.js:47:16:47:23 | location | angularjs.js:47:16:47:30 | location.search | +| angularjs.js:47:16:47:23 | location | angularjs.js:47:16:47:30 | location.search | | angularjs.js:47:16:47:23 | location | angularjs.js:47:16:47:30 | location.search | | angularjs.js:50:22:50:29 | location | angularjs.js:50:22:50:36 | location.search | +| angularjs.js:50:22:50:29 | location | angularjs.js:50:22:50:36 | location.search | +| angularjs.js:50:22:50:29 | location | angularjs.js:50:22:50:36 | location.search | +| angularjs.js:50:22:50:29 | location | angularjs.js:50:22:50:36 | location.search | +| angularjs.js:53:32:53:39 | location | angularjs.js:53:32:53:46 | location.search | +| angularjs.js:53:32:53:39 | location | angularjs.js:53:32:53:46 | location.search | +| angularjs.js:53:32:53:39 | location | angularjs.js:53:32:53:46 | location.search | | angularjs.js:53:32:53:39 | location | angularjs.js:53:32:53:46 | location.search | | eslint-escope-build.js:20:22:20:22 | c | eslint-escope-build.js:21:16:21:16 | c | -| express.js:7:24:7:62 | "return ... obble") | express.js:7:24:7:69 | "return ... + "];" | -| express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:62 | "return ... obble") | +| eslint-escope-build.js:20:22:20:22 | c | eslint-escope-build.js:21:16:21:16 | c | +| eslint-escope-build.js:20:22:20:22 | c | eslint-escope-build.js:21:16:21:16 | c | +| eslint-escope-build.js:20:22:20:22 | c | eslint-escope-build.js:21:16:21:16 | c | +| express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:69 | "return ... + "];" | +| express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:69 | "return ... + "];" | +| express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:69 | "return ... + "];" | | express.js:7:44:7:62 | req.param("wobble") | express.js:7:24:7:69 | "return ... + "];" | -| express.js:9:34:9:72 | "return ... obble") | express.js:9:34:9:79 | "return ... + "];" | -| express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:72 | "return ... obble") | | express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:79 | "return ... + "];" | -| express.js:12:8:12:46 | "return ... obble") | express.js:12:8:12:53 | "return ... + "];" | -| express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:46 | "return ... obble") | +| express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:79 | "return ... + "];" | +| express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:79 | "return ... + "];" | +| express.js:9:54:9:72 | req.param("wobble") | express.js:9:34:9:79 | "return ... + "];" | +| express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:53 | "return ... + "];" | +| express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:53 | "return ... + "];" | +| express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:53 | "return ... + "];" | | express.js:12:28:12:46 | req.param("wobble") | express.js:12:8:12:53 | "return ... + "];" | | react-native.js:7:7:7:33 | tainted | react-native.js:8:32:8:38 | tainted | +| react-native.js:7:7:7:33 | tainted | react-native.js:8:32:8:38 | tainted | +| react-native.js:7:7:7:33 | tainted | react-native.js:10:23:10:29 | tainted | | react-native.js:7:7:7:33 | tainted | react-native.js:10:23:10:29 | tainted | | react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | +| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | +| tst.js:2:6:2:22 | document.location | tst.js:2:6:2:27 | documen ... on.href | | tst.js:2:6:2:22 | document.location | tst.js:2:6:2:27 | documen ... on.href | | tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | +| tst.js:2:6:2:27 | documen ... on.href | tst.js:2:6:2:83 | documen ... t=")+8) | +| tst.js:5:12:5:28 | document.location | tst.js:5:12:5:33 | documen ... on.hash | +| tst.js:5:12:5:28 | document.location | tst.js:5:12:5:33 | documen ... on.hash | +| tst.js:5:12:5:28 | document.location | tst.js:5:12:5:33 | documen ... on.hash | | tst.js:5:12:5:28 | document.location | tst.js:5:12:5:33 | documen ... on.hash | | tst.js:14:10:14:26 | document.location | tst.js:14:10:14:33 | documen ... .search | +| tst.js:14:10:14:26 | document.location | tst.js:14:10:14:33 | documen ... .search | +| tst.js:14:10:14:33 | documen ... .search | tst.js:14:10:14:74 | documen ... , "$1") | | tst.js:14:10:14:33 | documen ... .search | tst.js:14:10:14:74 | documen ... , "$1") | | tst.js:17:21:17:37 | document.location | tst.js:17:21:17:42 | documen ... on.hash | +| tst.js:17:21:17:37 | document.location | tst.js:17:21:17:42 | documen ... on.hash | +| tst.js:17:21:17:37 | document.location | tst.js:17:21:17:42 | documen ... on.hash | +| tst.js:17:21:17:37 | document.location | tst.js:17:21:17:42 | documen ... on.hash | | tst.js:20:30:20:46 | document.location | tst.js:20:30:20:51 | documen ... on.hash | +| tst.js:20:30:20:46 | document.location | tst.js:20:30:20:51 | documen ... on.hash | +| tst.js:20:30:20:46 | document.location | tst.js:20:30:20:51 | documen ... on.hash | +| tst.js:20:30:20:46 | document.location | tst.js:20:30:20:51 | documen ... on.hash | +| tst.js:23:11:23:27 | document.location | tst.js:23:11:23:32 | documen ... on.hash | | tst.js:23:11:23:27 | document.location | tst.js:23:11:23:32 | documen ... on.hash | | tst.js:23:11:23:32 | documen ... on.hash | tst.js:23:11:23:45 | documen ... ring(1) | | tst.js:23:11:23:45 | documen ... ring(1) | tst.js:23:6:23:46 | atob(do ... ing(1)) | +| tst.js:23:11:23:45 | documen ... ring(1) | tst.js:23:6:23:46 | atob(do ... ing(1)) | | tst.js:26:26:26:33 | location | tst.js:26:26:26:40 | location.search | +| tst.js:26:26:26:33 | location | tst.js:26:26:26:40 | location.search | +| tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) | | tst.js:26:26:26:40 | location.search | tst.js:26:26:26:53 | locatio ... ring(1) | #select | eslint-escope-build.js:21:16:21:16 | c | eslint-escope-build.js:20:22:20:22 | c | eslint-escope-build.js:21:16:21:16 | c | $@ flows to here and is interpreted as code. | eslint-escope-build.js:20:22:20:22 | c | User-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-094/UnsafeDynamicMethodAccess/UnsafeDynamicMethodAccess.expected b/javascript/ql/test/query-tests/Security/CWE-094/UnsafeDynamicMethodAccess/UnsafeDynamicMethodAccess.expected index f3bb67d4ad3..e7c7a4eb681 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/UnsafeDynamicMethodAccess/UnsafeDynamicMethodAccess.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/UnsafeDynamicMethodAccess/UnsafeDynamicMethodAccess.expected @@ -1,41 +1,53 @@ nodes | example.js:9:37:9:38 | ev | +| example.js:9:37:9:38 | ev | | example.js:10:9:10:37 | message | | example.js:10:19:10:37 | JSON.parse(ev.data) | | example.js:10:30:10:31 | ev | | example.js:10:30:10:36 | ev.data | | example.js:13:5:13:24 | window[message.name] | +| example.js:13:5:13:24 | window[message.name] | | example.js:13:12:13:18 | message | | example.js:13:12:13:23 | message.name | | tst.js:3:37:3:38 | ev | +| tst.js:3:37:3:38 | ev | | tst.js:4:9:4:37 | message | | tst.js:4:19:4:37 | JSON.parse(ev.data) | | tst.js:4:30:4:31 | ev | | tst.js:4:30:4:36 | ev.data | | tst.js:5:5:5:24 | window[message.name] | +| tst.js:5:5:5:24 | window[message.name] | | tst.js:5:12:5:18 | message | | tst.js:5:12:5:23 | message.name | | tst.js:6:9:6:28 | window[message.name] | +| tst.js:6:9:6:28 | window[message.name] | | tst.js:6:16:6:22 | message | | tst.js:6:16:6:27 | message.name | | tst.js:11:5:11:19 | f[message.name] | +| tst.js:11:5:11:19 | f[message.name] | | tst.js:11:7:11:13 | message | | tst.js:11:7:11:18 | message.name | | tst.js:15:5:15:14 | window[ev] | +| tst.js:15:5:15:14 | window[ev] | | tst.js:15:12:15:13 | ev | | tst.js:21:5:21:29 | window[ ... e.name] | +| tst.js:21:5:21:29 | window[ ... e.name] | | tst.js:21:12:21:28 | '' + message.name | | tst.js:21:17:21:23 | message | | tst.js:21:17:21:28 | message.name | edges | example.js:9:37:9:38 | ev | example.js:10:30:10:31 | ev | +| example.js:9:37:9:38 | ev | example.js:10:30:10:31 | ev | | example.js:10:9:10:37 | message | example.js:13:12:13:18 | message | | example.js:10:19:10:37 | JSON.parse(ev.data) | example.js:10:9:10:37 | message | | example.js:10:30:10:31 | ev | example.js:10:30:10:36 | ev.data | | example.js:10:30:10:36 | ev.data | example.js:10:19:10:37 | JSON.parse(ev.data) | | example.js:13:12:13:18 | message | example.js:13:12:13:23 | message.name | | example.js:13:12:13:23 | message.name | example.js:13:5:13:24 | window[message.name] | +| example.js:13:12:13:23 | message.name | example.js:13:5:13:24 | window[message.name] | | tst.js:3:37:3:38 | ev | tst.js:4:30:4:31 | ev | +| tst.js:3:37:3:38 | ev | tst.js:4:30:4:31 | ev | +| tst.js:3:37:3:38 | ev | tst.js:15:12:15:13 | ev | | tst.js:3:37:3:38 | ev | tst.js:15:12:15:13 | ev | | tst.js:4:9:4:37 | message | tst.js:5:12:5:18 | message | | tst.js:4:9:4:37 | message | tst.js:6:16:6:22 | message | @@ -46,11 +58,16 @@ edges | tst.js:4:30:4:36 | ev.data | tst.js:4:19:4:37 | JSON.parse(ev.data) | | tst.js:5:12:5:18 | message | tst.js:5:12:5:23 | message.name | | tst.js:5:12:5:23 | message.name | tst.js:5:5:5:24 | window[message.name] | +| tst.js:5:12:5:23 | message.name | tst.js:5:5:5:24 | window[message.name] | | tst.js:6:16:6:22 | message | tst.js:6:16:6:27 | message.name | | tst.js:6:16:6:27 | message.name | tst.js:6:9:6:28 | window[message.name] | +| tst.js:6:16:6:27 | message.name | tst.js:6:9:6:28 | window[message.name] | | tst.js:11:7:11:13 | message | tst.js:11:7:11:18 | message.name | | tst.js:11:7:11:18 | message.name | tst.js:11:5:11:19 | f[message.name] | +| tst.js:11:7:11:18 | message.name | tst.js:11:5:11:19 | f[message.name] | | tst.js:15:12:15:13 | ev | tst.js:15:5:15:14 | window[ev] | +| tst.js:15:12:15:13 | ev | tst.js:15:5:15:14 | window[ev] | +| tst.js:21:12:21:28 | '' + message.name | tst.js:21:5:21:29 | window[ ... e.name] | | tst.js:21:12:21:28 | '' + message.name | tst.js:21:5:21:29 | window[ ... e.name] | | tst.js:21:17:21:23 | message | tst.js:21:17:21:28 | message.name | | tst.js:21:17:21:28 | message.name | tst.js:21:12:21:28 | '' + message.name | diff --git a/javascript/ql/test/query-tests/Security/CWE-134/TaintedFormatString.expected b/javascript/ql/test/query-tests/Security/CWE-134/TaintedFormatString.expected index 161ad1ecbbb..0ea3425b00e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-134/TaintedFormatString.expected +++ b/javascript/ql/test/query-tests/Security/CWE-134/TaintedFormatString.expected @@ -1,25 +1,85 @@ nodes | tst.js:5:15:5:30 | req.query.format | +| tst.js:5:15:5:30 | req.query.format | +| tst.js:5:15:5:30 | req.query.format | +| tst.js:6:26:6:41 | req.query.format | +| tst.js:6:26:6:41 | req.query.format | | tst.js:6:26:6:41 | req.query.format | | tst.js:7:15:7:30 | req.query.format | +| tst.js:7:15:7:30 | req.query.format | +| tst.js:7:15:7:30 | req.query.format | +| tst.js:8:17:8:32 | req.query.format | +| tst.js:8:17:8:32 | req.query.format | | tst.js:8:17:8:32 | req.query.format | | tst.js:9:16:9:31 | req.query.format | +| tst.js:9:16:9:31 | req.query.format | +| tst.js:9:16:9:31 | req.query.format | +| tst.js:10:12:10:27 | req.query.format | +| tst.js:10:12:10:27 | req.query.format | | tst.js:10:12:10:27 | req.query.format | | tst.js:11:32:11:47 | req.query.format | +| tst.js:11:32:11:47 | req.query.format | +| tst.js:11:32:11:47 | req.query.format | +| tst.js:12:21:12:36 | req.query.format | +| tst.js:12:21:12:36 | req.query.format | | tst.js:12:21:12:36 | req.query.format | | tst.js:13:35:13:50 | req.query.format | +| tst.js:13:35:13:50 | req.query.format | +| tst.js:13:35:13:50 | req.query.format | +| tst.js:14:29:14:44 | req.query.format | +| tst.js:14:29:14:44 | req.query.format | | tst.js:14:29:14:44 | req.query.format | | tst.js:15:30:15:45 | req.query.format | +| tst.js:15:30:15:45 | req.query.format | +| tst.js:15:30:15:45 | req.query.format | +| tst.js:16:26:16:41 | req.query.format | +| tst.js:16:26:16:41 | req.query.format | | tst.js:16:26:16:41 | req.query.format | | tst.js:17:30:17:45 | req.query.format | +| tst.js:17:30:17:45 | req.query.format | +| tst.js:17:30:17:45 | req.query.format | +| tst.js:18:38:18:53 | req.query.format | +| tst.js:18:38:18:53 | req.query.format | | tst.js:18:38:18:53 | req.query.format | | tst.js:20:17:20:32 | req.query.format | +| tst.js:20:17:20:32 | req.query.format | +| tst.js:20:17:20:32 | req.query.format | +| tst.js:21:16:21:31 | req.query.format | +| tst.js:21:16:21:31 | req.query.format | | tst.js:21:16:21:31 | req.query.format | | tst.js:22:17:22:32 | req.query.format | +| tst.js:22:17:22:32 | req.query.format | +| tst.js:22:17:22:32 | req.query.format | +| tst.js:24:25:24:40 | req.query.format | +| tst.js:24:25:24:40 | req.query.format | | tst.js:24:25:24:40 | req.query.format | | tst.js:25:33:25:48 | req.query.format | +| tst.js:25:33:25:48 | req.query.format | +| tst.js:25:33:25:48 | req.query.format | +| tst.js:26:34:26:49 | req.query.format | +| tst.js:26:34:26:49 | req.query.format | | tst.js:26:34:26:49 | req.query.format | edges +| tst.js:5:15:5:30 | req.query.format | tst.js:5:15:5:30 | req.query.format | +| tst.js:6:26:6:41 | req.query.format | tst.js:6:26:6:41 | req.query.format | +| tst.js:7:15:7:30 | req.query.format | tst.js:7:15:7:30 | req.query.format | +| tst.js:8:17:8:32 | req.query.format | tst.js:8:17:8:32 | req.query.format | +| tst.js:9:16:9:31 | req.query.format | tst.js:9:16:9:31 | req.query.format | +| tst.js:10:12:10:27 | req.query.format | tst.js:10:12:10:27 | req.query.format | +| tst.js:11:32:11:47 | req.query.format | tst.js:11:32:11:47 | req.query.format | +| tst.js:12:21:12:36 | req.query.format | tst.js:12:21:12:36 | req.query.format | +| tst.js:13:35:13:50 | req.query.format | tst.js:13:35:13:50 | req.query.format | +| tst.js:14:29:14:44 | req.query.format | tst.js:14:29:14:44 | req.query.format | +| tst.js:15:30:15:45 | req.query.format | tst.js:15:30:15:45 | req.query.format | +| tst.js:16:26:16:41 | req.query.format | tst.js:16:26:16:41 | req.query.format | +| tst.js:17:30:17:45 | req.query.format | tst.js:17:30:17:45 | req.query.format | +| tst.js:18:38:18:53 | req.query.format | tst.js:18:38:18:53 | req.query.format | +| tst.js:20:17:20:32 | req.query.format | tst.js:20:17:20:32 | req.query.format | +| tst.js:21:16:21:31 | req.query.format | tst.js:21:16:21:31 | req.query.format | +| tst.js:22:17:22:32 | req.query.format | tst.js:22:17:22:32 | req.query.format | +| tst.js:24:25:24:40 | req.query.format | tst.js:24:25:24:40 | req.query.format | +| tst.js:25:33:25:48 | req.query.format | tst.js:25:33:25:48 | req.query.format | +| tst.js:26:34:26:49 | req.query.format | tst.js:26:34:26:49 | req.query.format | #select | tst.js:5:15:5:30 | req.query.format | tst.js:5:15:5:30 | req.query.format | tst.js:5:15:5:30 | req.query.format | $@ flows here and is used in a format string. | tst.js:5:15:5:30 | req.query.format | User-provided value | | tst.js:6:26:6:41 | req.query.format | tst.js:6:26:6:41 | req.query.format | tst.js:6:26:6:41 | req.query.format | $@ flows here and is used in a format string. | tst.js:6:26:6:41 | req.query.format | User-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-200/FileAccessToHttp.expected b/javascript/ql/test/query-tests/Security/CWE-200/FileAccessToHttp.expected index 940a463636d..36d71d9c229 100644 --- a/javascript/ql/test/query-tests/Security/CWE-200/FileAccessToHttp.expected +++ b/javascript/ql/test/query-tests/Security/CWE-200/FileAccessToHttp.expected @@ -1,43 +1,58 @@ nodes | FileAccessToHttp.js:4:5:4:47 | content | | FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | +| FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | +| FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | | FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | | FileAccessToHttp.js:9:12:9:31 | { Referer: content } | | FileAccessToHttp.js:9:23:9:29 | content | | bufferRead.js:12:13:12:43 | buffer | | bufferRead.js:12:22:12:43 | new Buf ... s.size) | +| bufferRead.js:12:22:12:43 | new Buf ... s.size) | | bufferRead.js:15:15:15:62 | postData | | bufferRead.js:15:26:15:31 | buffer | | bufferRead.js:15:26:15:62 | buffer. ... esRead) | | bufferRead.js:33:21:33:28 | postData | +| bufferRead.js:33:21:33:28 | postData | | googlecompiler.js:7:19:7:28 | codestring | | googlecompiler.js:9:7:15:4 | post_data | | googlecompiler.js:9:19:15:4 | queryst ... dy\\n }) | | googlecompiler.js:9:41:15:3 | {\\n ... ody\\n } | | googlecompiler.js:14:21:14:30 | codestring | | googlecompiler.js:38:18:38:26 | post_data | +| googlecompiler.js:38:18:38:26 | post_data | +| googlecompiler.js:44:54:44:57 | data | | googlecompiler.js:44:54:44:57 | data | | googlecompiler.js:56:14:56:17 | data | | readFileSync.js:5:5:5:39 | data | | readFileSync.js:5:12:5:39 | fs.read ... t.txt") | +| readFileSync.js:5:12:5:39 | fs.read ... t.txt") | | readFileSync.js:7:7:7:25 | s | | readFileSync.js:7:11:7:14 | data | | readFileSync.js:7:11:7:25 | data.toString() | | readFileSync.js:26:18:26:18 | s | +| readFileSync.js:26:18:26:18 | s | | readStreamRead.js:13:13:13:35 | chunk | | readStreamRead.js:13:21:13:35 | readable.read() | +| readStreamRead.js:13:21:13:35 | readable.read() | +| readStreamRead.js:30:19:30:23 | chunk | | readStreamRead.js:30:19:30:23 | chunk | | request.js:6:19:6:26 | jsonData | | request.js:8:11:8:20 | {jsonData} | +| request.js:8:11:8:20 | {jsonData} | | request.js:8:12:8:19 | jsonData | | request.js:13:18:13:24 | xmlData | | request.js:16:11:23:3 | {\\n u ... ody\\n } | +| request.js:16:11:23:3 | {\\n u ... ody\\n } | | request.js:22:11:22:17 | xmlData | | request.js:28:52:28:55 | data | +| request.js:28:52:28:55 | data | | request.js:35:14:35:17 | data | | request.js:43:51:43:54 | data | +| request.js:43:51:43:54 | data | | request.js:50:13:50:16 | data | | sentAsHeaders.js:10:79:10:84 | buffer | +| sentAsHeaders.js:10:79:10:84 | buffer | | sentAsHeaders.js:11:13:11:59 | content | | sentAsHeaders.js:11:23:11:28 | buffer | | sentAsHeaders.js:11:23:11:59 | buffer. ... esRead) | @@ -46,54 +61,63 @@ nodes | sentAsHeaders.js:12:19:12:74 | content ... =", "") | | sentAsHeaders.js:12:19:12:81 | content ... .trim() | | sentAsHeaders.js:14:20:19:9 | {\\n ... } | +| sentAsHeaders.js:14:20:19:9 | {\\n ... } | | sentAsHeaders.js:18:20:18:55 | { Refer ... ntent } | | sentAsHeaders.js:18:31:18:53 | "http:/ ... content | | sentAsHeaders.js:18:47:18:53 | content | | sentAsHeaders.js:20:20:25:9 | {\\n ... } | +| sentAsHeaders.js:20:20:25:9 | {\\n ... } | | sentAsHeaders.js:24:20:24:55 | { Refer ... ntent } | | sentAsHeaders.js:24:31:24:53 | "http:/ ... content | | sentAsHeaders.js:24:47:24:53 | content | edges | FileAccessToHttp.js:4:5:4:47 | content | FileAccessToHttp.js:9:23:9:29 | content | | FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | FileAccessToHttp.js:4:5:4:47 | content | +| FileAccessToHttp.js:4:15:4:47 | fs.read ... "utf8") | FileAccessToHttp.js:4:5:4:47 | content | +| FileAccessToHttp.js:9:12:9:31 | { Referer: content } | FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | | FileAccessToHttp.js:9:12:9:31 | { Referer: content } | FileAccessToHttp.js:5:11:10:1 | {\\n hos ... ent }\\n} | | FileAccessToHttp.js:9:23:9:29 | content | FileAccessToHttp.js:9:12:9:31 | { Referer: content } | -| bufferRead.js:12:13:12:43 | buffer | bufferRead.js:13:53:13:52 | buffer | | bufferRead.js:12:13:12:43 | buffer | bufferRead.js:15:26:15:31 | buffer | | bufferRead.js:12:22:12:43 | new Buf ... s.size) | bufferRead.js:12:13:12:43 | buffer | -| bufferRead.js:13:53:13:52 | buffer | bufferRead.js:15:26:15:31 | buffer | +| bufferRead.js:12:22:12:43 | new Buf ... s.size) | bufferRead.js:12:13:12:43 | buffer | +| bufferRead.js:15:15:15:62 | postData | bufferRead.js:33:21:33:28 | postData | | bufferRead.js:15:15:15:62 | postData | bufferRead.js:33:21:33:28 | postData | | bufferRead.js:15:26:15:31 | buffer | bufferRead.js:15:26:15:62 | buffer. ... esRead) | | bufferRead.js:15:26:15:62 | buffer. ... esRead) | bufferRead.js:15:15:15:62 | postData | | googlecompiler.js:7:19:7:28 | codestring | googlecompiler.js:14:21:14:30 | codestring | | googlecompiler.js:9:7:15:4 | post_data | googlecompiler.js:38:18:38:26 | post_data | +| googlecompiler.js:9:7:15:4 | post_data | googlecompiler.js:38:18:38:26 | post_data | | googlecompiler.js:9:19:15:4 | queryst ... dy\\n }) | googlecompiler.js:9:7:15:4 | post_data | | googlecompiler.js:9:41:15:3 | {\\n ... ody\\n } | googlecompiler.js:9:19:15:4 | queryst ... dy\\n }) | | googlecompiler.js:14:21:14:30 | codestring | googlecompiler.js:9:41:15:3 | {\\n ... ody\\n } | -| googlecompiler.js:44:54:44:57 | data | googlecompiler.js:55:6:55:9 | data | | googlecompiler.js:44:54:44:57 | data | googlecompiler.js:56:14:56:17 | data | -| googlecompiler.js:55:6:55:9 | data | googlecompiler.js:56:14:56:17 | data | +| googlecompiler.js:44:54:44:57 | data | googlecompiler.js:56:14:56:17 | data | | googlecompiler.js:56:14:56:17 | data | googlecompiler.js:7:19:7:28 | codestring | | readFileSync.js:5:5:5:39 | data | readFileSync.js:7:11:7:14 | data | | readFileSync.js:5:12:5:39 | fs.read ... t.txt") | readFileSync.js:5:5:5:39 | data | +| readFileSync.js:5:12:5:39 | fs.read ... t.txt") | readFileSync.js:5:5:5:39 | data | +| readFileSync.js:7:7:7:25 | s | readFileSync.js:26:18:26:18 | s | | readFileSync.js:7:7:7:25 | s | readFileSync.js:26:18:26:18 | s | | readFileSync.js:7:11:7:14 | data | readFileSync.js:7:11:7:25 | data.toString() | | readFileSync.js:7:11:7:25 | data.toString() | readFileSync.js:7:7:7:25 | s | | readStreamRead.js:13:13:13:35 | chunk | readStreamRead.js:30:19:30:23 | chunk | +| readStreamRead.js:13:13:13:35 | chunk | readStreamRead.js:30:19:30:23 | chunk | +| readStreamRead.js:13:21:13:35 | readable.read() | readStreamRead.js:13:13:13:35 | chunk | | readStreamRead.js:13:21:13:35 | readable.read() | readStreamRead.js:13:13:13:35 | chunk | | request.js:6:19:6:26 | jsonData | request.js:8:12:8:19 | jsonData | | request.js:8:12:8:19 | jsonData | request.js:8:11:8:20 | {jsonData} | +| request.js:8:12:8:19 | jsonData | request.js:8:11:8:20 | {jsonData} | | request.js:13:18:13:24 | xmlData | request.js:22:11:22:17 | xmlData | | request.js:22:11:22:17 | xmlData | request.js:16:11:23:3 | {\\n u ... ody\\n } | -| request.js:28:52:28:55 | data | request.js:34:6:34:9 | data | +| request.js:22:11:22:17 | xmlData | request.js:16:11:23:3 | {\\n u ... ody\\n } | +| request.js:28:52:28:55 | data | request.js:35:14:35:17 | data | | request.js:28:52:28:55 | data | request.js:35:14:35:17 | data | -| request.js:34:6:34:9 | data | request.js:35:14:35:17 | data | | request.js:35:14:35:17 | data | request.js:6:19:6:26 | jsonData | -| request.js:43:51:43:54 | data | request.js:49:6:49:9 | data | | request.js:43:51:43:54 | data | request.js:50:13:50:16 | data | -| request.js:49:6:49:9 | data | request.js:50:13:50:16 | data | +| request.js:43:51:43:54 | data | request.js:50:13:50:16 | data | | request.js:50:13:50:16 | data | request.js:13:18:13:24 | xmlData | | sentAsHeaders.js:10:79:10:84 | buffer | sentAsHeaders.js:11:23:11:28 | buffer | +| sentAsHeaders.js:10:79:10:84 | buffer | sentAsHeaders.js:11:23:11:28 | buffer | | sentAsHeaders.js:11:13:11:59 | content | sentAsHeaders.js:12:19:12:25 | content | | sentAsHeaders.js:11:23:11:28 | buffer | sentAsHeaders.js:11:23:11:59 | buffer. ... esRead) | | sentAsHeaders.js:11:23:11:59 | buffer. ... esRead) | sentAsHeaders.js:11:13:11:59 | content | @@ -103,9 +127,11 @@ edges | sentAsHeaders.js:12:19:12:74 | content ... =", "") | sentAsHeaders.js:12:19:12:81 | content ... .trim() | | sentAsHeaders.js:12:19:12:81 | content ... .trim() | sentAsHeaders.js:12:9:12:81 | content | | sentAsHeaders.js:18:20:18:55 | { Refer ... ntent } | sentAsHeaders.js:14:20:19:9 | {\\n ... } | +| sentAsHeaders.js:18:20:18:55 | { Refer ... ntent } | sentAsHeaders.js:14:20:19:9 | {\\n ... } | | sentAsHeaders.js:18:31:18:53 | "http:/ ... content | sentAsHeaders.js:18:20:18:55 | { Refer ... ntent } | | sentAsHeaders.js:18:47:18:53 | content | sentAsHeaders.js:18:31:18:53 | "http:/ ... content | | sentAsHeaders.js:24:20:24:55 | { Refer ... ntent } | sentAsHeaders.js:20:20:25:9 | {\\n ... } | +| sentAsHeaders.js:24:20:24:55 | { Refer ... ntent } | sentAsHeaders.js:20:20:25:9 | {\\n ... } | | sentAsHeaders.js:24:31:24:53 | "http:/ ... content | sentAsHeaders.js:24:20:24:55 | { Refer ... ntent } | | sentAsHeaders.js:24:47:24:53 | content | sentAsHeaders.js:24:31:24:53 | "http:/ ... content | #select diff --git a/javascript/ql/test/query-tests/Security/CWE-201/PostMessageStar.expected b/javascript/ql/test/query-tests/Security/CWE-201/PostMessageStar.expected index d5f76456e25..bb1736fd461 100644 --- a/javascript/ql/test/query-tests/Security/CWE-201/PostMessageStar.expected +++ b/javascript/ql/test/query-tests/Security/CWE-201/PostMessageStar.expected @@ -1,17 +1,34 @@ nodes | PostMessageStar2.js:1:27:1:34 | password | +| PostMessageStar2.js:1:27:1:34 | password | +| PostMessageStar2.js:1:27:1:34 | password | | PostMessageStar2.js:4:7:4:15 | data | | PostMessageStar2.js:4:14:4:15 | {} | | PostMessageStar2.js:5:14:5:21 | password | +| PostMessageStar2.js:5:14:5:21 | password | +| PostMessageStar2.js:8:29:8:32 | data | | PostMessageStar2.js:8:29:8:32 | data | | PostMessageStar2.js:9:29:9:36 | data.foo | +| PostMessageStar2.js:9:29:9:36 | data.foo | +| PostMessageStar2.js:13:27:13:33 | authKey | +| PostMessageStar2.js:13:27:13:33 | authKey | | PostMessageStar2.js:13:27:13:33 | authKey | | PostMessageStar.js:1:27:1:34 | userName | +| PostMessageStar.js:1:27:1:34 | userName | +| PostMessageStar.js:1:27:1:34 | userName | edges +| PostMessageStar2.js:1:27:1:34 | password | PostMessageStar2.js:1:27:1:34 | password | +| PostMessageStar2.js:4:7:4:15 | data | PostMessageStar2.js:8:29:8:32 | data | | PostMessageStar2.js:4:7:4:15 | data | PostMessageStar2.js:8:29:8:32 | data | | PostMessageStar2.js:4:14:4:15 | {} | PostMessageStar2.js:4:7:4:15 | data | | PostMessageStar2.js:5:14:5:21 | password | PostMessageStar2.js:4:14:4:15 | {} | +| PostMessageStar2.js:5:14:5:21 | password | PostMessageStar2.js:4:14:4:15 | {} | | PostMessageStar2.js:5:14:5:21 | password | PostMessageStar2.js:9:29:9:36 | data.foo | +| PostMessageStar2.js:5:14:5:21 | password | PostMessageStar2.js:9:29:9:36 | data.foo | +| PostMessageStar2.js:5:14:5:21 | password | PostMessageStar2.js:9:29:9:36 | data.foo | +| PostMessageStar2.js:5:14:5:21 | password | PostMessageStar2.js:9:29:9:36 | data.foo | +| PostMessageStar2.js:13:27:13:33 | authKey | PostMessageStar2.js:13:27:13:33 | authKey | +| PostMessageStar.js:1:27:1:34 | userName | PostMessageStar.js:1:27:1:34 | userName | #select | PostMessageStar2.js:1:27:1:34 | password | PostMessageStar2.js:1:27:1:34 | password | PostMessageStar2.js:1:27:1:34 | password | Sensitive data returned from $@ is sent to another window without origin restriction. | PostMessageStar2.js:1:27:1:34 | password | here | | PostMessageStar2.js:8:29:8:32 | data | PostMessageStar2.js:5:14:5:21 | password | PostMessageStar2.js:8:29:8:32 | data | Sensitive data returned from $@ is sent to another window without origin restriction. | PostMessageStar2.js:5:14:5:21 | password | here | diff --git a/javascript/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected b/javascript/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected index e85b168c31e..dfee2aaa859 100644 --- a/javascript/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected +++ b/javascript/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected @@ -1,21 +1,33 @@ nodes | node.js:8:10:8:12 | err | +| node.js:8:10:8:12 | err | | node.js:11:13:11:15 | err | | node.js:11:13:11:21 | err.stack | +| node.js:11:13:11:21 | err.stack | | tst.js:6:12:6:12 | e | +| tst.js:6:12:6:12 | e | +| tst.js:7:13:7:13 | e | | tst.js:7:13:7:13 | e | | tst.js:8:15:8:15 | e | | tst.js:16:20:16:20 | e | | tst.js:17:11:17:11 | e | | tst.js:17:11:17:17 | e.stack | +| tst.js:17:11:17:17 | e.stack | edges | node.js:8:10:8:12 | err | node.js:11:13:11:15 | err | +| node.js:8:10:8:12 | err | node.js:11:13:11:15 | err | +| node.js:11:13:11:15 | err | node.js:11:13:11:21 | err.stack | | node.js:11:13:11:15 | err | node.js:11:13:11:21 | err.stack | | tst.js:6:12:6:12 | e | tst.js:7:13:7:13 | e | +| tst.js:6:12:6:12 | e | tst.js:7:13:7:13 | e | +| tst.js:6:12:6:12 | e | tst.js:7:13:7:13 | e | +| tst.js:6:12:6:12 | e | tst.js:7:13:7:13 | e | +| tst.js:6:12:6:12 | e | tst.js:8:15:8:15 | e | | tst.js:6:12:6:12 | e | tst.js:8:15:8:15 | e | | tst.js:8:15:8:15 | e | tst.js:16:20:16:20 | e | | tst.js:16:20:16:20 | e | tst.js:17:11:17:11 | e | | tst.js:17:11:17:11 | e | tst.js:17:11:17:17 | e.stack | +| tst.js:17:11:17:11 | e | tst.js:17:11:17:17 | e.stack | #select | node.js:11:13:11:21 | err.stack | node.js:8:10:8:12 | err | node.js:11:13:11:21 | err.stack | Stack trace information from $@ may be exposed to an external user here. | node.js:8:10:8:12 | err | here | | tst.js:7:13:7:13 | e | tst.js:6:12:6:12 | e | tst.js:7:13:7:13 | e | Stack trace information from $@ may be exposed to an external user here. | tst.js:6:12:6:12 | e | here | diff --git a/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected b/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected index e562c22f904..ef07eb2ea18 100644 --- a/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected +++ b/javascript/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected @@ -1,101 +1,227 @@ nodes | passwords.js:2:17:2:24 | password | +| passwords.js:2:17:2:24 | password | +| passwords.js:2:17:2:24 | password | +| passwords.js:3:17:3:26 | o.password | +| passwords.js:3:17:3:26 | o.password | | passwords.js:3:17:3:26 | o.password | | passwords.js:4:17:4:29 | getPassword() | +| passwords.js:4:17:4:29 | getPassword() | +| passwords.js:4:17:4:29 | getPassword() | +| passwords.js:5:17:5:31 | o.getPassword() | +| passwords.js:5:17:5:31 | o.getPassword() | | passwords.js:5:17:5:31 | o.getPassword() | | passwords.js:7:20:7:20 | x | | passwords.js:8:21:8:21 | x | +| passwords.js:8:21:8:21 | x | +| passwords.js:10:11:10:18 | password | | passwords.js:10:11:10:18 | password | | passwords.js:12:18:12:25 | password | +| passwords.js:12:18:12:25 | password | +| passwords.js:12:18:12:25 | password | +| passwords.js:14:17:14:38 | name + ... assword | | passwords.js:14:17:14:38 | name + ... assword | | passwords.js:14:31:14:38 | password | +| passwords.js:14:31:14:38 | password | | passwords.js:16:17:16:38 | `${name ... sword}` | +| passwords.js:16:17:16:38 | `${name ... sword}` | +| passwords.js:16:29:16:36 | password | | passwords.js:16:29:16:36 | password | | passwords.js:18:9:20:5 | obj1 | | passwords.js:18:16:20:5 | {\\n ... x\\n } | +| passwords.js:18:16:20:5 | {\\n ... x\\n } | +| passwords.js:21:17:21:20 | obj1 | | passwords.js:21:17:21:20 | obj1 | | passwords.js:23:9:25:5 | obj2 | | passwords.js:23:16:25:5 | {\\n ... d\\n } | | passwords.js:24:12:24:19 | password | +| passwords.js:24:12:24:19 | password | +| passwords.js:26:17:26:20 | obj2 | | passwords.js:26:17:26:20 | obj2 | | passwords.js:28:9:28:17 | obj3 | | passwords.js:28:16:28:17 | {} | | passwords.js:29:17:29:20 | obj3 | +| passwords.js:29:17:29:20 | obj3 | +| passwords.js:30:14:30:21 | password | | passwords.js:30:14:30:21 | password | | passwords.js:77:37:77:53 | req.body.password | +| passwords.js:77:37:77:53 | req.body.password | +| passwords.js:78:17:78:38 | temp.en ... assword | | passwords.js:78:17:78:38 | temp.en ... assword | | passwords.js:80:9:80:25 | secret | | passwords.js:80:18:80:25 | password | +| passwords.js:80:18:80:25 | password | +| passwords.js:81:17:81:31 | `pw: ${secret}` | | passwords.js:81:17:81:31 | `pw: ${secret}` | | passwords.js:81:24:81:29 | secret | | passwords.js:93:21:93:46 | "Passwo ... assword | +| passwords.js:93:21:93:46 | "Passwo ... assword | +| passwords.js:93:39:93:46 | password | | passwords.js:93:39:93:46 | password | | passwords.js:98:21:98:46 | "Passwo ... assword | +| passwords.js:98:21:98:46 | "Passwo ... assword | +| passwords.js:98:39:98:46 | password | | passwords.js:98:39:98:46 | password | | passwords.js:105:21:105:46 | "Passwo ... assword | +| passwords.js:105:21:105:46 | "Passwo ... assword | +| passwords.js:105:39:105:46 | password | | passwords.js:105:39:105:46 | password | | passwords.js:110:21:110:46 | "Passwo ... assword | +| passwords.js:110:21:110:46 | "Passwo ... assword | +| passwords.js:110:39:110:46 | password | | passwords.js:110:39:110:46 | password | | passwords.js:114:25:114:50 | "Passwo ... assword | +| passwords.js:114:25:114:50 | "Passwo ... assword | +| passwords.js:114:43:114:50 | password | | passwords.js:114:43:114:50 | password | | passwords.js:119:21:119:46 | "Passwo ... assword | +| passwords.js:119:21:119:46 | "Passwo ... assword | +| passwords.js:119:39:119:46 | password | | passwords.js:119:39:119:46 | password | | passwords.js:122:17:122:49 | name + ... tring() | +| passwords.js:122:17:122:49 | name + ... tring() | +| passwords.js:122:31:122:38 | password | | passwords.js:122:31:122:38 | password | | passwords.js:122:31:122:49 | password.toString() | | passwords.js:123:17:123:48 | name + ... lueOf() | +| passwords.js:123:17:123:48 | name + ... lueOf() | +| passwords.js:123:31:123:38 | password | | passwords.js:123:31:123:38 | password | | passwords.js:123:31:123:48 | password.valueOf() | | passwords.js:127:9:132:5 | config | | passwords.js:127:18:132:5 | {\\n ... )\\n } | +| passwords.js:127:18:132:5 | {\\n ... )\\n } | +| passwords.js:130:12:130:19 | password | | passwords.js:130:12:130:19 | password | | passwords.js:131:12:131:24 | getPassword() | +| passwords.js:131:12:131:24 | getPassword() | +| passwords.js:135:17:135:22 | config | | passwords.js:135:17:135:22 | config | | passwords.js:136:17:136:24 | config.x | +| passwords.js:136:17:136:24 | config.x | +| passwords.js:137:17:137:24 | config.y | | passwords.js:137:17:137:24 | config.y | | passwords_in_browser1.js:2:13:2:20 | password | +| passwords_in_browser1.js:2:13:2:20 | password | +| passwords_in_browser1.js:2:13:2:20 | password | +| passwords_in_browser2.js:2:13:2:20 | password | +| passwords_in_browser2.js:2:13:2:20 | password | | passwords_in_browser2.js:2:13:2:20 | password | | passwords_in_server_1.js:6:13:6:20 | password | +| passwords_in_server_1.js:6:13:6:20 | password | +| passwords_in_server_1.js:6:13:6:20 | password | +| passwords_in_server_2.js:3:13:3:20 | password | +| passwords_in_server_2.js:3:13:3:20 | password | | passwords_in_server_2.js:3:13:3:20 | password | | passwords_in_server_3.js:2:13:2:20 | password | +| passwords_in_server_3.js:2:13:2:20 | password | +| passwords_in_server_3.js:2:13:2:20 | password | | passwords_in_server_4.js:2:13:2:20 | password | +| passwords_in_server_4.js:2:13:2:20 | password | +| passwords_in_server_4.js:2:13:2:20 | password | +| passwords_in_server_5.js:4:7:4:24 | req.query.password | | passwords_in_server_5.js:4:7:4:24 | req.query.password | | passwords_in_server_5.js:7:12:7:12 | x | | passwords_in_server_5.js:8:17:8:17 | x | +| passwords_in_server_5.js:8:17:8:17 | x | edges +| passwords.js:2:17:2:24 | password | passwords.js:2:17:2:24 | password | +| passwords.js:3:17:3:26 | o.password | passwords.js:3:17:3:26 | o.password | +| passwords.js:4:17:4:29 | getPassword() | passwords.js:4:17:4:29 | getPassword() | +| passwords.js:5:17:5:31 | o.getPassword() | passwords.js:5:17:5:31 | o.getPassword() | +| passwords.js:7:20:7:20 | x | passwords.js:8:21:8:21 | x | | passwords.js:7:20:7:20 | x | passwords.js:8:21:8:21 | x | | passwords.js:10:11:10:18 | password | passwords.js:7:20:7:20 | x | +| passwords.js:10:11:10:18 | password | passwords.js:7:20:7:20 | x | +| passwords.js:12:18:12:25 | password | passwords.js:12:18:12:25 | password | +| passwords.js:14:31:14:38 | password | passwords.js:14:17:14:38 | name + ... assword | +| passwords.js:14:31:14:38 | password | passwords.js:14:17:14:38 | name + ... assword | +| passwords.js:14:31:14:38 | password | passwords.js:14:17:14:38 | name + ... assword | | passwords.js:14:31:14:38 | password | passwords.js:14:17:14:38 | name + ... assword | | passwords.js:16:29:16:36 | password | passwords.js:16:17:16:38 | `${name ... sword}` | +| passwords.js:16:29:16:36 | password | passwords.js:16:17:16:38 | `${name ... sword}` | +| passwords.js:16:29:16:36 | password | passwords.js:16:17:16:38 | `${name ... sword}` | +| passwords.js:16:29:16:36 | password | passwords.js:16:17:16:38 | `${name ... sword}` | +| passwords.js:18:9:20:5 | obj1 | passwords.js:21:17:21:20 | obj1 | | passwords.js:18:9:20:5 | obj1 | passwords.js:21:17:21:20 | obj1 | | passwords.js:18:16:20:5 | {\\n ... x\\n } | passwords.js:18:9:20:5 | obj1 | +| passwords.js:18:16:20:5 | {\\n ... x\\n } | passwords.js:18:9:20:5 | obj1 | +| passwords.js:23:9:25:5 | obj2 | passwords.js:26:17:26:20 | obj2 | | passwords.js:23:9:25:5 | obj2 | passwords.js:26:17:26:20 | obj2 | | passwords.js:23:16:25:5 | {\\n ... d\\n } | passwords.js:23:9:25:5 | obj2 | | passwords.js:24:12:24:19 | password | passwords.js:23:16:25:5 | {\\n ... d\\n } | +| passwords.js:24:12:24:19 | password | passwords.js:23:16:25:5 | {\\n ... d\\n } | +| passwords.js:28:9:28:17 | obj3 | passwords.js:29:17:29:20 | obj3 | | passwords.js:28:9:28:17 | obj3 | passwords.js:29:17:29:20 | obj3 | | passwords.js:28:16:28:17 | {} | passwords.js:28:9:28:17 | obj3 | | passwords.js:30:14:30:21 | password | passwords.js:28:16:28:17 | {} | +| passwords.js:30:14:30:21 | password | passwords.js:28:16:28:17 | {} | +| passwords.js:77:37:77:53 | req.body.password | passwords.js:78:17:78:38 | temp.en ... assword | +| passwords.js:77:37:77:53 | req.body.password | passwords.js:78:17:78:38 | temp.en ... assword | +| passwords.js:77:37:77:53 | req.body.password | passwords.js:78:17:78:38 | temp.en ... assword | | passwords.js:77:37:77:53 | req.body.password | passwords.js:78:17:78:38 | temp.en ... assword | | passwords.js:80:9:80:25 | secret | passwords.js:81:24:81:29 | secret | | passwords.js:80:18:80:25 | password | passwords.js:80:9:80:25 | secret | +| passwords.js:80:18:80:25 | password | passwords.js:80:9:80:25 | secret | +| passwords.js:81:24:81:29 | secret | passwords.js:81:17:81:31 | `pw: ${secret}` | | passwords.js:81:24:81:29 | secret | passwords.js:81:17:81:31 | `pw: ${secret}` | | passwords.js:93:39:93:46 | password | passwords.js:93:21:93:46 | "Passwo ... assword | +| passwords.js:93:39:93:46 | password | passwords.js:93:21:93:46 | "Passwo ... assword | +| passwords.js:93:39:93:46 | password | passwords.js:93:21:93:46 | "Passwo ... assword | +| passwords.js:93:39:93:46 | password | passwords.js:93:21:93:46 | "Passwo ... assword | +| passwords.js:98:39:98:46 | password | passwords.js:98:21:98:46 | "Passwo ... assword | +| passwords.js:98:39:98:46 | password | passwords.js:98:21:98:46 | "Passwo ... assword | +| passwords.js:98:39:98:46 | password | passwords.js:98:21:98:46 | "Passwo ... assword | | passwords.js:98:39:98:46 | password | passwords.js:98:21:98:46 | "Passwo ... assword | | passwords.js:105:39:105:46 | password | passwords.js:105:21:105:46 | "Passwo ... assword | +| passwords.js:105:39:105:46 | password | passwords.js:105:21:105:46 | "Passwo ... assword | +| passwords.js:105:39:105:46 | password | passwords.js:105:21:105:46 | "Passwo ... assword | +| passwords.js:105:39:105:46 | password | passwords.js:105:21:105:46 | "Passwo ... assword | +| passwords.js:110:39:110:46 | password | passwords.js:110:21:110:46 | "Passwo ... assword | +| passwords.js:110:39:110:46 | password | passwords.js:110:21:110:46 | "Passwo ... assword | +| passwords.js:110:39:110:46 | password | passwords.js:110:21:110:46 | "Passwo ... assword | | passwords.js:110:39:110:46 | password | passwords.js:110:21:110:46 | "Passwo ... assword | | passwords.js:114:43:114:50 | password | passwords.js:114:25:114:50 | "Passwo ... assword | +| passwords.js:114:43:114:50 | password | passwords.js:114:25:114:50 | "Passwo ... assword | +| passwords.js:114:43:114:50 | password | passwords.js:114:25:114:50 | "Passwo ... assword | +| passwords.js:114:43:114:50 | password | passwords.js:114:25:114:50 | "Passwo ... assword | +| passwords.js:119:39:119:46 | password | passwords.js:119:21:119:46 | "Passwo ... assword | +| passwords.js:119:39:119:46 | password | passwords.js:119:21:119:46 | "Passwo ... assword | +| passwords.js:119:39:119:46 | password | passwords.js:119:21:119:46 | "Passwo ... assword | | passwords.js:119:39:119:46 | password | passwords.js:119:21:119:46 | "Passwo ... assword | | passwords.js:122:31:122:38 | password | passwords.js:122:31:122:49 | password.toString() | +| passwords.js:122:31:122:38 | password | passwords.js:122:31:122:49 | password.toString() | +| passwords.js:122:31:122:49 | password.toString() | passwords.js:122:17:122:49 | name + ... tring() | | passwords.js:122:31:122:49 | password.toString() | passwords.js:122:17:122:49 | name + ... tring() | | passwords.js:123:31:123:38 | password | passwords.js:123:31:123:48 | password.valueOf() | +| passwords.js:123:31:123:38 | password | passwords.js:123:31:123:48 | password.valueOf() | +| passwords.js:123:31:123:48 | password.valueOf() | passwords.js:123:17:123:48 | name + ... lueOf() | | passwords.js:123:31:123:48 | password.valueOf() | passwords.js:123:17:123:48 | name + ... lueOf() | | passwords.js:127:9:132:5 | config | passwords.js:135:17:135:22 | config | +| passwords.js:127:9:132:5 | config | passwords.js:135:17:135:22 | config | +| passwords.js:127:18:132:5 | {\\n ... )\\n } | passwords.js:127:9:132:5 | config | | passwords.js:127:18:132:5 | {\\n ... )\\n } | passwords.js:127:9:132:5 | config | | passwords.js:130:12:130:19 | password | passwords.js:127:18:132:5 | {\\n ... )\\n } | +| passwords.js:130:12:130:19 | password | passwords.js:127:18:132:5 | {\\n ... )\\n } | +| passwords.js:130:12:130:19 | password | passwords.js:136:17:136:24 | config.x | +| passwords.js:130:12:130:19 | password | passwords.js:136:17:136:24 | config.x | +| passwords.js:130:12:130:19 | password | passwords.js:136:17:136:24 | config.x | | passwords.js:130:12:130:19 | password | passwords.js:136:17:136:24 | config.x | | passwords.js:131:12:131:24 | getPassword() | passwords.js:127:18:132:5 | {\\n ... )\\n } | +| passwords.js:131:12:131:24 | getPassword() | passwords.js:127:18:132:5 | {\\n ... )\\n } | | passwords.js:131:12:131:24 | getPassword() | passwords.js:137:17:137:24 | config.y | +| passwords.js:131:12:131:24 | getPassword() | passwords.js:137:17:137:24 | config.y | +| passwords.js:131:12:131:24 | getPassword() | passwords.js:137:17:137:24 | config.y | +| passwords.js:131:12:131:24 | getPassword() | passwords.js:137:17:137:24 | config.y | +| passwords_in_browser1.js:2:13:2:20 | password | passwords_in_browser1.js:2:13:2:20 | password | +| passwords_in_browser2.js:2:13:2:20 | password | passwords_in_browser2.js:2:13:2:20 | password | +| passwords_in_server_1.js:6:13:6:20 | password | passwords_in_server_1.js:6:13:6:20 | password | +| passwords_in_server_2.js:3:13:3:20 | password | passwords_in_server_2.js:3:13:3:20 | password | +| passwords_in_server_3.js:2:13:2:20 | password | passwords_in_server_3.js:2:13:2:20 | password | +| passwords_in_server_4.js:2:13:2:20 | password | passwords_in_server_4.js:2:13:2:20 | password | | passwords_in_server_5.js:4:7:4:24 | req.query.password | passwords_in_server_5.js:7:12:7:12 | x | +| passwords_in_server_5.js:4:7:4:24 | req.query.password | passwords_in_server_5.js:7:12:7:12 | x | +| passwords_in_server_5.js:7:12:7:12 | x | passwords_in_server_5.js:8:17:8:17 | x | | passwords_in_server_5.js:7:12:7:12 | x | passwords_in_server_5.js:8:17:8:17 | x | #select | passwords.js:2:17:2:24 | password | passwords.js:2:17:2:24 | password | passwords.js:2:17:2:24 | password | Sensitive data returned by $@ is logged here. | passwords.js:2:17:2:24 | password | an access to password | diff --git a/javascript/ql/test/query-tests/Security/CWE-312/CleartextStorage.expected b/javascript/ql/test/query-tests/Security/CWE-312/CleartextStorage.expected index ee327c75a5f..096bcfe6528 100644 --- a/javascript/ql/test/query-tests/Security/CWE-312/CleartextStorage.expected +++ b/javascript/ql/test/query-tests/Security/CWE-312/CleartextStorage.expected @@ -1,25 +1,57 @@ nodes | CleartextStorage2.js:5:7:5:58 | pw | | CleartextStorage2.js:5:12:5:58 | url.par ... assword | +| CleartextStorage2.js:5:12:5:58 | url.par ... assword | +| CleartextStorage2.js:7:19:7:34 | 'password=' + pw | | CleartextStorage2.js:7:19:7:34 | 'password=' + pw | | CleartextStorage2.js:7:33:7:34 | pw | | CleartextStorage.js:5:7:5:40 | pw | | CleartextStorage.js:5:12:5:40 | req.par ... sword") | +| CleartextStorage.js:5:12:5:40 | req.par ... sword") | +| CleartextStorage.js:7:26:7:27 | pw | | CleartextStorage.js:7:26:7:27 | pw | | tst-angularjs.js:3:32:3:45 | data1.password | +| tst-angularjs.js:3:32:3:45 | data1.password | +| tst-angularjs.js:3:32:3:45 | data1.password | +| tst-angularjs.js:4:33:4:46 | data2.password | +| tst-angularjs.js:4:33:4:46 | data2.password | | tst-angularjs.js:4:33:4:46 | data2.password | | tst-angularjs.js:5:27:5:40 | data3.password | +| tst-angularjs.js:5:27:5:40 | data3.password | +| tst-angularjs.js:5:27:5:40 | data3.password | +| tst-angularjs.js:6:33:6:46 | data4.password | +| tst-angularjs.js:6:33:6:46 | data4.password | | tst-angularjs.js:6:33:6:46 | data4.password | | tst-webstorage.js:1:18:1:30 | data.password | +| tst-webstorage.js:1:18:1:30 | data.password | +| tst-webstorage.js:1:18:1:30 | data.password | +| tst-webstorage.js:2:27:2:39 | data.password | +| tst-webstorage.js:2:27:2:39 | data.password | | tst-webstorage.js:2:27:2:39 | data.password | | tst-webstorage.js:3:20:3:32 | data.password | +| tst-webstorage.js:3:20:3:32 | data.password | +| tst-webstorage.js:3:20:3:32 | data.password | +| tst-webstorage.js:4:29:4:41 | data.password | +| tst-webstorage.js:4:29:4:41 | data.password | | tst-webstorage.js:4:29:4:41 | data.password | edges | CleartextStorage2.js:5:7:5:58 | pw | CleartextStorage2.js:7:33:7:34 | pw | | CleartextStorage2.js:5:12:5:58 | url.par ... assword | CleartextStorage2.js:5:7:5:58 | pw | +| CleartextStorage2.js:5:12:5:58 | url.par ... assword | CleartextStorage2.js:5:7:5:58 | pw | +| CleartextStorage2.js:7:33:7:34 | pw | CleartextStorage2.js:7:19:7:34 | 'password=' + pw | | CleartextStorage2.js:7:33:7:34 | pw | CleartextStorage2.js:7:19:7:34 | 'password=' + pw | | CleartextStorage.js:5:7:5:40 | pw | CleartextStorage.js:7:26:7:27 | pw | +| CleartextStorage.js:5:7:5:40 | pw | CleartextStorage.js:7:26:7:27 | pw | | CleartextStorage.js:5:12:5:40 | req.par ... sword") | CleartextStorage.js:5:7:5:40 | pw | +| CleartextStorage.js:5:12:5:40 | req.par ... sword") | CleartextStorage.js:5:7:5:40 | pw | +| tst-angularjs.js:3:32:3:45 | data1.password | tst-angularjs.js:3:32:3:45 | data1.password | +| tst-angularjs.js:4:33:4:46 | data2.password | tst-angularjs.js:4:33:4:46 | data2.password | +| tst-angularjs.js:5:27:5:40 | data3.password | tst-angularjs.js:5:27:5:40 | data3.password | +| tst-angularjs.js:6:33:6:46 | data4.password | tst-angularjs.js:6:33:6:46 | data4.password | +| tst-webstorage.js:1:18:1:30 | data.password | tst-webstorage.js:1:18:1:30 | data.password | +| tst-webstorage.js:2:27:2:39 | data.password | tst-webstorage.js:2:27:2:39 | data.password | +| tst-webstorage.js:3:20:3:32 | data.password | tst-webstorage.js:3:20:3:32 | data.password | +| tst-webstorage.js:4:29:4:41 | data.password | tst-webstorage.js:4:29:4:41 | data.password | #select | CleartextStorage2.js:7:19:7:34 | 'password=' + pw | CleartextStorage2.js:5:12:5:58 | url.par ... assword | CleartextStorage2.js:7:19:7:34 | 'password=' + pw | Sensitive data returned by $@ is stored here. | CleartextStorage2.js:5:12:5:58 | url.par ... assword | an access to current_password | | CleartextStorage.js:7:26:7:27 | pw | CleartextStorage.js:5:12:5:40 | req.par ... sword") | CleartextStorage.js:7:26:7:27 | pw | Sensitive data returned by $@ is stored here. | CleartextStorage.js:5:12:5:40 | req.par ... sword") | a call to param | diff --git a/javascript/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected b/javascript/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected index a8b7a6f3598..491d6a3aa00 100644 --- a/javascript/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected +++ b/javascript/ql/test/query-tests/Security/CWE-327/BrokenCryptoAlgorithm.expected @@ -1,12 +1,24 @@ nodes | tst.js:3:5:3:24 | secretText | | tst.js:3:18:3:24 | trusted | +| tst.js:3:18:3:24 | trusted | +| tst.js:11:17:11:26 | secretText | +| tst.js:11:17:11:26 | secretText | | tst.js:11:17:11:26 | secretText | | tst.js:17:17:17:25 | o.trusted | +| tst.js:17:17:17:25 | o.trusted | +| tst.js:17:17:17:25 | o.trusted | +| tst.js:19:17:19:24 | password | +| tst.js:19:17:19:24 | password | | tst.js:19:17:19:24 | password | edges | tst.js:3:5:3:24 | secretText | tst.js:11:17:11:26 | secretText | +| tst.js:3:5:3:24 | secretText | tst.js:11:17:11:26 | secretText | | tst.js:3:18:3:24 | trusted | tst.js:3:5:3:24 | secretText | +| tst.js:3:18:3:24 | trusted | tst.js:3:5:3:24 | secretText | +| tst.js:11:17:11:26 | secretText | tst.js:11:17:11:26 | secretText | +| tst.js:17:17:17:25 | o.trusted | tst.js:17:17:17:25 | o.trusted | +| tst.js:19:17:19:24 | password | tst.js:19:17:19:24 | password | #select | tst.js:11:17:11:26 | secretText | tst.js:3:18:3:24 | trusted | tst.js:11:17:11:26 | secretText | Sensitive data from $@ is used in a broken or weak cryptographic algorithm. | tst.js:3:18:3:24 | trusted | an access to trusted | | tst.js:11:17:11:26 | secretText | tst.js:11:17:11:26 | secretText | tst.js:11:17:11:26 | secretText | Sensitive data from $@ is used in a broken or weak cryptographic algorithm. | tst.js:11:17:11:26 | secretText | an access to secretText | diff --git a/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected b/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected index 3b4f56f3326..256f0f044be 100644 --- a/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected +++ b/javascript/ql/test/query-tests/Security/CWE-338/InsecureRandomness.expected @@ -1,59 +1,120 @@ nodes | tst.js:2:20:2:32 | Math.random() | +| tst.js:2:20:2:32 | Math.random() | +| tst.js:2:20:2:32 | Math.random() | +| tst.js:6:20:6:43 | "prefix ... andom() | | tst.js:6:20:6:43 | "prefix ... andom() | | tst.js:6:31:6:43 | Math.random() | +| tst.js:6:31:6:43 | Math.random() | +| tst.js:10:20:10:32 | Math.random() | +| tst.js:10:20:10:32 | Math.random() | | tst.js:10:20:10:32 | Math.random() | | tst.js:19:9:19:36 | suffix | | tst.js:19:18:19:30 | Math.random() | +| tst.js:19:18:19:30 | Math.random() | | tst.js:19:18:19:36 | Math.random() % 255 | | tst.js:20:20:20:36 | "prefix" + suffix | +| tst.js:20:20:20:36 | "prefix" + suffix | | tst.js:20:31:20:36 | suffix | | tst.js:28:9:28:26 | pw | | tst.js:28:14:28:26 | Math.random() | +| tst.js:28:14:28:26 | Math.random() | +| tst.js:29:20:29:21 | pw | | tst.js:29:20:29:21 | pw | | tst.js:41:20:41:33 | !Math.random() | +| tst.js:41:20:41:33 | !Math.random() | +| tst.js:41:21:41:33 | Math.random() | | tst.js:41:21:41:33 | Math.random() | | tst.js:45:18:45:30 | Math.random() | +| tst.js:45:18:45:30 | Math.random() | +| tst.js:45:18:45:30 | Math.random() | +| tst.js:50:16:50:28 | Math.random() | +| tst.js:50:16:50:28 | Math.random() | | tst.js:50:16:50:28 | Math.random() | | tst.js:55:17:55:29 | Math.random() | +| tst.js:55:17:55:29 | Math.random() | +| tst.js:55:17:55:29 | Math.random() | +| tst.js:61:17:61:34 | '' + Math.random() | | tst.js:61:17:61:34 | '' + Math.random() | | tst.js:61:22:61:34 | Math.random() | +| tst.js:61:22:61:34 | Math.random() | | tst.js:66:18:66:42 | Math.fl ... ndom()) | +| tst.js:66:18:66:42 | Math.fl ... ndom()) | +| tst.js:66:29:66:41 | Math.random() | | tst.js:66:29:66:41 | Math.random() | | tst.js:71:9:71:48 | rand | | tst.js:71:16:71:48 | Math.fl ... 999999) | | tst.js:71:27:71:39 | Math.random() | +| tst.js:71:27:71:39 | Math.random() | | tst.js:71:27:71:47 | Math.ra ... 9999999 | | tst.js:72:9:72:48 | concat | | tst.js:72:18:72:48 | ts.toSt ... tring() | | tst.js:72:34:72:37 | rand | | tst.js:72:34:72:48 | rand.toString() | | tst.js:73:23:73:28 | concat | +| tst.js:73:23:73:28 | concat | +| tst.js:77:16:77:21 | secret | | tst.js:77:16:77:21 | secret | | tst.js:80:7:80:19 | Math.random() | +| tst.js:80:7:80:19 | Math.random() | +| tst.js:84:19:84:31 | Math.random() | +| tst.js:84:19:84:31 | Math.random() | | tst.js:84:19:84:31 | Math.random() | | tst.js:90:32:90:44 | Math.random() | +| tst.js:90:32:90:44 | Math.random() | +| tst.js:90:32:90:44 | Math.random() | +| tst.js:95:33:95:45 | Math.random() | +| tst.js:95:33:95:45 | Math.random() | | tst.js:95:33:95:45 | Math.random() | edges +| tst.js:2:20:2:32 | Math.random() | tst.js:2:20:2:32 | Math.random() | | tst.js:6:31:6:43 | Math.random() | tst.js:6:20:6:43 | "prefix ... andom() | +| tst.js:6:31:6:43 | Math.random() | tst.js:6:20:6:43 | "prefix ... andom() | +| tst.js:6:31:6:43 | Math.random() | tst.js:6:20:6:43 | "prefix ... andom() | +| tst.js:6:31:6:43 | Math.random() | tst.js:6:20:6:43 | "prefix ... andom() | +| tst.js:10:20:10:32 | Math.random() | tst.js:10:20:10:32 | Math.random() | | tst.js:19:9:19:36 | suffix | tst.js:20:31:20:36 | suffix | | tst.js:19:18:19:30 | Math.random() | tst.js:19:18:19:36 | Math.random() % 255 | +| tst.js:19:18:19:30 | Math.random() | tst.js:19:18:19:36 | Math.random() % 255 | | tst.js:19:18:19:36 | Math.random() % 255 | tst.js:19:9:19:36 | suffix | | tst.js:20:31:20:36 | suffix | tst.js:20:20:20:36 | "prefix" + suffix | +| tst.js:20:31:20:36 | suffix | tst.js:20:20:20:36 | "prefix" + suffix | +| tst.js:28:9:28:26 | pw | tst.js:29:20:29:21 | pw | | tst.js:28:9:28:26 | pw | tst.js:29:20:29:21 | pw | | tst.js:28:14:28:26 | Math.random() | tst.js:28:9:28:26 | pw | +| tst.js:28:14:28:26 | Math.random() | tst.js:28:9:28:26 | pw | | tst.js:41:21:41:33 | Math.random() | tst.js:41:20:41:33 | !Math.random() | +| tst.js:41:21:41:33 | Math.random() | tst.js:41:20:41:33 | !Math.random() | +| tst.js:41:21:41:33 | Math.random() | tst.js:41:20:41:33 | !Math.random() | +| tst.js:41:21:41:33 | Math.random() | tst.js:41:20:41:33 | !Math.random() | +| tst.js:45:18:45:30 | Math.random() | tst.js:45:18:45:30 | Math.random() | +| tst.js:50:16:50:28 | Math.random() | tst.js:50:16:50:28 | Math.random() | +| tst.js:55:17:55:29 | Math.random() | tst.js:55:17:55:29 | Math.random() | | tst.js:61:22:61:34 | Math.random() | tst.js:61:17:61:34 | '' + Math.random() | +| tst.js:61:22:61:34 | Math.random() | tst.js:61:17:61:34 | '' + Math.random() | +| tst.js:61:22:61:34 | Math.random() | tst.js:61:17:61:34 | '' + Math.random() | +| tst.js:61:22:61:34 | Math.random() | tst.js:61:17:61:34 | '' + Math.random() | +| tst.js:66:29:66:41 | Math.random() | tst.js:66:18:66:42 | Math.fl ... ndom()) | +| tst.js:66:29:66:41 | Math.random() | tst.js:66:18:66:42 | Math.fl ... ndom()) | +| tst.js:66:29:66:41 | Math.random() | tst.js:66:18:66:42 | Math.fl ... ndom()) | | tst.js:66:29:66:41 | Math.random() | tst.js:66:18:66:42 | Math.fl ... ndom()) | | tst.js:71:9:71:48 | rand | tst.js:72:34:72:37 | rand | | tst.js:71:16:71:48 | Math.fl ... 999999) | tst.js:71:9:71:48 | rand | | tst.js:71:27:71:39 | Math.random() | tst.js:71:27:71:47 | Math.ra ... 9999999 | +| tst.js:71:27:71:39 | Math.random() | tst.js:71:27:71:47 | Math.ra ... 9999999 | | tst.js:71:27:71:47 | Math.ra ... 9999999 | tst.js:71:16:71:48 | Math.fl ... 999999) | | tst.js:72:9:72:48 | concat | tst.js:73:23:73:28 | concat | +| tst.js:72:9:72:48 | concat | tst.js:73:23:73:28 | concat | | tst.js:72:18:72:48 | ts.toSt ... tring() | tst.js:72:9:72:48 | concat | | tst.js:72:34:72:37 | rand | tst.js:72:34:72:48 | rand.toString() | | tst.js:72:34:72:48 | rand.toString() | tst.js:72:18:72:48 | ts.toSt ... tring() | | tst.js:80:7:80:19 | Math.random() | tst.js:77:16:77:21 | secret | +| tst.js:80:7:80:19 | Math.random() | tst.js:77:16:77:21 | secret | +| tst.js:80:7:80:19 | Math.random() | tst.js:77:16:77:21 | secret | +| tst.js:80:7:80:19 | Math.random() | tst.js:77:16:77:21 | secret | +| tst.js:84:19:84:31 | Math.random() | tst.js:84:19:84:31 | Math.random() | +| tst.js:90:32:90:44 | Math.random() | tst.js:90:32:90:44 | Math.random() | +| tst.js:95:33:95:45 | Math.random() | tst.js:95:33:95:45 | Math.random() | #select | tst.js:2:20:2:32 | Math.random() | tst.js:2:20:2:32 | Math.random() | tst.js:2:20:2:32 | Math.random() | Cryptographically insecure $@ in a security context. | tst.js:2:20:2:32 | Math.random() | random value | | tst.js:6:20:6:43 | "prefix ... andom() | tst.js:6:31:6:43 | Math.random() | tst.js:6:20:6:43 | "prefix ... andom() | Cryptographically insecure $@ in a security context. | tst.js:6:31:6:43 | Math.random() | random value | diff --git a/javascript/ql/test/query-tests/Security/CWE-346/CorsMisconfigurationForCredentials.expected b/javascript/ql/test/query-tests/Security/CWE-346/CorsMisconfigurationForCredentials.expected index e1c2b876501..22058065dfc 100644 --- a/javascript/ql/test/query-tests/Security/CWE-346/CorsMisconfigurationForCredentials.expected +++ b/javascript/ql/test/query-tests/Security/CWE-346/CorsMisconfigurationForCredentials.expected @@ -4,15 +4,25 @@ nodes | tst.js:12:18:12:47 | url.par ... ).query | | tst.js:12:18:12:54 | url.par ... .origin | | tst.js:12:28:12:34 | req.url | +| tst.js:12:28:12:34 | req.url | +| tst.js:13:50:13:55 | origin | | tst.js:13:50:13:55 | origin | | tst.js:18:50:18:53 | null | +| tst.js:18:50:18:53 | null | +| tst.js:18:50:18:53 | null | +| tst.js:23:50:23:55 | "null" | +| tst.js:23:50:23:55 | "null" | | tst.js:23:50:23:55 | "null" | edges | tst.js:12:9:12:54 | origin | tst.js:13:50:13:55 | origin | +| tst.js:12:9:12:54 | origin | tst.js:13:50:13:55 | origin | | tst.js:12:18:12:41 | url.par ... , true) | tst.js:12:18:12:47 | url.par ... ).query | | tst.js:12:18:12:47 | url.par ... ).query | tst.js:12:18:12:54 | url.par ... .origin | | tst.js:12:18:12:54 | url.par ... .origin | tst.js:12:9:12:54 | origin | | tst.js:12:28:12:34 | req.url | tst.js:12:18:12:41 | url.par ... , true) | +| tst.js:12:28:12:34 | req.url | tst.js:12:18:12:41 | url.par ... , true) | +| tst.js:18:50:18:53 | null | tst.js:18:50:18:53 | null | +| tst.js:23:50:23:55 | "null" | tst.js:23:50:23:55 | "null" | #select | tst.js:13:50:13:55 | origin | tst.js:12:28:12:34 | req.url | tst.js:13:50:13:55 | origin | $@ leak vulnerability due to $@. | tst.js:14:5:14:59 | res.set ... , true) | Credential | tst.js:12:28:12:34 | req.url | a misconfigured CORS header value | | tst.js:18:50:18:53 | null | tst.js:18:50:18:53 | null | tst.js:18:50:18:53 | null | $@ leak vulnerability due to $@. | tst.js:19:5:19:59 | res.set ... , true) | Credential | tst.js:18:50:18:53 | null | a misconfigured CORS header value | diff --git a/javascript/ql/test/query-tests/Security/CWE-400/PrototypePollution.expected b/javascript/ql/test/query-tests/Security/CWE-400/PrototypePollution.expected index 3151701d190..8200ed7876d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/PrototypePollution.expected +++ b/javascript/ql/test/query-tests/Security/CWE-400/PrototypePollution.expected @@ -1,20 +1,36 @@ nodes | angularmerge.js:1:30:1:34 | event | +| angularmerge.js:1:30:1:34 | event | +| angularmerge.js:2:21:2:42 | JSON.pa ... t.data) | | angularmerge.js:2:21:2:42 | JSON.pa ... t.data) | | angularmerge.js:2:32:2:36 | event | | angularmerge.js:2:32:2:41 | event.data | | src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | +| src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | +| src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | +| src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } | | src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } | | src-vulnerable-lodash/tst.js:11:16:11:30 | req.query.value | +| src-vulnerable-lodash/tst.js:11:16:11:30 | req.query.value | | src-vulnerable-lodash/tst.js:15:14:15:28 | req.query.value | +| src-vulnerable-lodash/tst.js:15:14:15:28 | req.query.value | +| src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } | | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } | | src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | edges | angularmerge.js:1:30:1:34 | event | angularmerge.js:2:32:2:36 | event | +| angularmerge.js:1:30:1:34 | event | angularmerge.js:2:32:2:36 | event | | angularmerge.js:2:32:2:36 | event | angularmerge.js:2:32:2:41 | event.data | | angularmerge.js:2:32:2:41 | event.data | angularmerge.js:2:21:2:42 | JSON.pa ... t.data) | +| angularmerge.js:2:32:2:41 | event.data | angularmerge.js:2:21:2:42 | JSON.pa ... t.data) | +| src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | src-vulnerable-lodash/tst.js:7:17:7:29 | req.query.foo | +| src-vulnerable-lodash/tst.js:11:16:11:30 | req.query.value | src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } | +| src-vulnerable-lodash/tst.js:11:16:11:30 | req.query.value | src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } | +| src-vulnerable-lodash/tst.js:11:16:11:30 | req.query.value | src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } | | src-vulnerable-lodash/tst.js:11:16:11:30 | req.query.value | src-vulnerable-lodash/tst.js:10:17:12:5 | {\\n ... K\\n } | | src-vulnerable-lodash/tst.js:15:14:15:28 | req.query.value | src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | +| src-vulnerable-lodash/tst.js:15:14:15:28 | req.query.value | src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | +| src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } | | src-vulnerable-lodash/tst.js:18:16:18:25 | opts.thing | src-vulnerable-lodash/tst.js:17:17:19:5 | {\\n ... K\\n } | #select | angularmerge.js:2:21:2:42 | JSON.pa ... t.data) | angularmerge.js:1:30:1:34 | event | angularmerge.js:2:21:2:42 | JSON.pa ... t.data) | Prototype pollution caused by merging a user-controlled value from $@ using a vulnerable version of $@. | angularmerge.js:1:30:1:34 | event | here | angularmerge.js:2:3:2:43 | angular ... .data)) | angular | diff --git a/javascript/ql/test/query-tests/Security/CWE-400/RemotePropertyInjection.expected b/javascript/ql/test/query-tests/Security/CWE-400/RemotePropertyInjection.expected index 1c61836da65..4eecfb2b0ee 100644 --- a/javascript/ql/test/query-tests/Security/CWE-400/RemotePropertyInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-400/RemotePropertyInjection.expected @@ -2,21 +2,35 @@ nodes | tst.js:8:6:8:52 | prop | | tst.js:8:13:8:52 | myCoolL ... rolled) | | tst.js:8:28:8:51 | req.que ... trolled | +| tst.js:8:28:8:51 | req.que ... trolled | +| tst.js:9:8:9:11 | prop | | tst.js:9:8:9:11 | prop | | tst.js:13:15:13:18 | prop | +| tst.js:13:15:13:18 | prop | | tst.js:14:31:14:34 | prop | +| tst.js:14:31:14:34 | prop | +| tst.js:16:10:16:13 | prop | | tst.js:16:10:16:13 | prop | | tstNonExpr.js:5:7:5:23 | userVal | | tstNonExpr.js:5:17:5:23 | req.url | +| tstNonExpr.js:5:17:5:23 | req.url | +| tstNonExpr.js:8:17:8:23 | userVal | | tstNonExpr.js:8:17:8:23 | userVal | edges | tst.js:8:6:8:52 | prop | tst.js:9:8:9:11 | prop | +| tst.js:8:6:8:52 | prop | tst.js:9:8:9:11 | prop | +| tst.js:8:6:8:52 | prop | tst.js:13:15:13:18 | prop | | tst.js:8:6:8:52 | prop | tst.js:13:15:13:18 | prop | | tst.js:8:6:8:52 | prop | tst.js:14:31:14:34 | prop | +| tst.js:8:6:8:52 | prop | tst.js:14:31:14:34 | prop | +| tst.js:8:6:8:52 | prop | tst.js:16:10:16:13 | prop | | tst.js:8:6:8:52 | prop | tst.js:16:10:16:13 | prop | | tst.js:8:13:8:52 | myCoolL ... rolled) | tst.js:8:6:8:52 | prop | | tst.js:8:28:8:51 | req.que ... trolled | tst.js:8:13:8:52 | myCoolL ... rolled) | +| tst.js:8:28:8:51 | req.que ... trolled | tst.js:8:13:8:52 | myCoolL ... rolled) | | tstNonExpr.js:5:7:5:23 | userVal | tstNonExpr.js:8:17:8:23 | userVal | +| tstNonExpr.js:5:7:5:23 | userVal | tstNonExpr.js:8:17:8:23 | userVal | +| tstNonExpr.js:5:17:5:23 | req.url | tstNonExpr.js:5:7:5:23 | userVal | | tstNonExpr.js:5:17:5:23 | req.url | tstNonExpr.js:5:7:5:23 | userVal | #select | tst.js:9:8:9:11 | prop | tst.js:8:28:8:51 | req.que ... trolled | tst.js:9:8:9:11 | prop | A $@ is used as a property name to write to. | tst.js:8:28:8:51 | req.que ... trolled | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected b/javascript/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected index d898f17eb60..9e405b7a8d4 100644 --- a/javascript/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected +++ b/javascript/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected @@ -1,9 +1,21 @@ nodes | tst.js:7:22:7:36 | req.params.data | +| tst.js:7:22:7:36 | req.params.data | +| tst.js:7:22:7:36 | req.params.data | +| tst.js:8:25:8:39 | req.params.data | +| tst.js:8:25:8:39 | req.params.data | | tst.js:8:25:8:39 | req.params.data | | tst.js:12:26:12:40 | req.params.data | +| tst.js:12:26:12:40 | req.params.data | +| tst.js:12:26:12:40 | req.params.data | +| tst.js:13:29:13:43 | req.params.data | +| tst.js:13:29:13:43 | req.params.data | | tst.js:13:29:13:43 | req.params.data | edges +| tst.js:7:22:7:36 | req.params.data | tst.js:7:22:7:36 | req.params.data | +| tst.js:8:25:8:39 | req.params.data | tst.js:8:25:8:39 | req.params.data | +| tst.js:12:26:12:40 | req.params.data | tst.js:12:26:12:40 | req.params.data | +| tst.js:13:29:13:43 | req.params.data | tst.js:13:29:13:43 | req.params.data | #select | tst.js:7:22:7:36 | req.params.data | tst.js:7:22:7:36 | req.params.data | tst.js:7:22:7:36 | req.params.data | Unsafe deserialization of $@. | tst.js:7:22:7:36 | req.params.data | user input | | tst.js:8:25:8:39 | req.params.data | tst.js:8:25:8:39 | req.params.data | tst.js:8:25:8:39 | req.params.data | Unsafe deserialization of $@. | tst.js:8:25:8:39 | req.params.data | user input | diff --git a/javascript/ql/test/query-tests/Security/CWE-506/HardcodedDataInterpretedAsCode.expected b/javascript/ql/test/query-tests/Security/CWE-506/HardcodedDataInterpretedAsCode.expected index 2c244ed4bde..9fa00a26d25 100644 --- a/javascript/ql/test/query-tests/Security/CWE-506/HardcodedDataInterpretedAsCode.expected +++ b/javascript/ql/test/query-tests/Security/CWE-506/HardcodedDataInterpretedAsCode.expected @@ -1,26 +1,44 @@ nodes | event-stream-orig.js:2:1113:2:1139 | e("2e2f ... 17461") | +| event-stream-orig.js:2:1113:2:1139 | e("2e2f ... 17461") | +| event-stream-orig.js:2:1115:2:1138 | "2e2f74 ... 617461" | | event-stream-orig.js:2:1115:2:1138 | "2e2f74 ... 617461" | | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | +| event-stream.js:9:11:9:37 | e("2e2f ... 17461") | +| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | | event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | | tst.js:1:5:1:88 | totallyHarmlessString | | tst.js:1:29:1:88 | '636f6e ... 6e2729' | +| tst.js:1:29:1:88 | '636f6e ... 6e2729' | | tst.js:2:6:2:46 | Buffer. ... 'hex') | | tst.js:2:6:2:57 | Buffer. ... tring() | +| tst.js:2:6:2:57 | Buffer. ... tring() | | tst.js:2:18:2:38 | totally ... sString | | tst.js:5:5:5:23 | test | | tst.js:5:12:5:23 | "0123456789" | +| tst.js:5:12:5:23 | "0123456789" | | tst.js:7:8:7:11 | test | | tst.js:7:8:7:15 | test+"n" | +| tst.js:7:8:7:15 | test+"n" | edges | event-stream-orig.js:2:1115:2:1138 | "2e2f74 ... 617461" | event-stream-orig.js:2:1113:2:1139 | e("2e2f ... 17461") | +| event-stream-orig.js:2:1115:2:1138 | "2e2f74 ... 617461" | event-stream-orig.js:2:1113:2:1139 | e("2e2f ... 17461") | +| event-stream-orig.js:2:1115:2:1138 | "2e2f74 ... 617461" | event-stream-orig.js:2:1113:2:1139 | e("2e2f ... 17461") | +| event-stream-orig.js:2:1115:2:1138 | "2e2f74 ... 617461" | event-stream-orig.js:2:1113:2:1139 | e("2e2f ... 17461") | +| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | +| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | +| event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | | event-stream.js:9:13:9:36 | "2e2f74 ... 617461" | event-stream.js:9:11:9:37 | e("2e2f ... 17461") | | tst.js:1:5:1:88 | totallyHarmlessString | tst.js:2:18:2:38 | totally ... sString | | tst.js:1:29:1:88 | '636f6e ... 6e2729' | tst.js:1:5:1:88 | totallyHarmlessString | +| tst.js:1:29:1:88 | '636f6e ... 6e2729' | tst.js:1:5:1:88 | totallyHarmlessString | +| tst.js:2:6:2:46 | Buffer. ... 'hex') | tst.js:2:6:2:57 | Buffer. ... tring() | | tst.js:2:6:2:46 | Buffer. ... 'hex') | tst.js:2:6:2:57 | Buffer. ... tring() | | tst.js:2:18:2:38 | totally ... sString | tst.js:2:6:2:46 | Buffer. ... 'hex') | | tst.js:5:5:5:23 | test | tst.js:7:8:7:11 | test | | tst.js:5:12:5:23 | "0123456789" | tst.js:5:5:5:23 | test | +| tst.js:5:12:5:23 | "0123456789" | tst.js:5:5:5:23 | test | +| tst.js:7:8:7:11 | test | tst.js:7:8:7:15 | test+"n" | | tst.js:7:8:7:11 | test | tst.js:7:8:7:15 | test+"n" | #select | event-stream-orig.js:2:1113:2:1139 | e("2e2f ... 17461") | event-stream-orig.js:2:1115:2:1138 | "2e2f74 ... 617461" | event-stream-orig.js:2:1113:2:1139 | e("2e2f ... 17461") | Hard-coded data from $@ is interpreted as an import path. | event-stream-orig.js:2:1115:2:1138 | "2e2f74 ... 617461" | here | diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected index 29e1740021e..85eda636b0e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected +++ b/javascript/ql/test/query-tests/Security/CWE-601/ClientSideUrlRedirect/ClientSideUrlRedirect.expected @@ -3,43 +3,68 @@ nodes | tst2.js:2:7:2:33 | href | | tst2.js:2:14:2:28 | window.location | | tst2.js:2:14:2:28 | window.location | +| tst2.js:2:14:2:28 | window.location | | tst2.js:2:14:2:33 | window.location.href | | tst2.js:2:14:2:33 | window.location.href | | tst2.js:4:21:4:24 | href | | tst2.js:4:21:4:24 | href | | tst2.js:4:21:4:55 | href.su ... '?')+1) | +| tst2.js:4:21:4:55 | href.su ... '?')+1) | | tst6.js:2:7:2:45 | redirect | | tst6.js:2:18:2:45 | $locati ... irect') | +| tst6.js:2:18:2:45 | $locati ... irect') | +| tst6.js:4:21:4:28 | redirect | | tst6.js:4:21:4:28 | redirect | | tst6.js:6:17:6:24 | redirect | +| tst6.js:6:17:6:24 | redirect | +| tst6.js:8:21:8:48 | $locati ... irect') | | tst6.js:8:21:8:48 | $locati ... irect') | | tst6.js:8:21:8:56 | $locati ... + "foo" | +| tst6.js:8:21:8:56 | $locati ... + "foo" | +| tst7.js:2:12:2:28 | document.location | | tst7.js:2:12:2:28 | document.location | | tst7.js:2:12:2:35 | documen ... .search | +| tst7.js:2:12:2:35 | documen ... .search | +| tst7.js:5:27:5:43 | document.location | | tst7.js:5:27:5:43 | document.location | | tst7.js:5:27:5:50 | documen ... .search | +| tst7.js:5:27:5:50 | documen ... .search | +| tst9.js:2:21:2:37 | document.location | | tst9.js:2:21:2:37 | document.location | | tst9.js:2:21:2:37 | document.location | | tst9.js:2:21:2:42 | documen ... on.hash | | tst9.js:2:21:2:55 | documen ... ring(1) | +| tst9.js:2:21:2:55 | documen ... ring(1) | | tst10.js:5:17:5:46 | '/' + d ... .search | +| tst10.js:5:17:5:46 | '/' + d ... .search | +| tst10.js:5:23:5:39 | document.location | | tst10.js:5:23:5:39 | document.location | | tst10.js:5:23:5:46 | documen ... .search | | tst10.js:8:17:8:47 | '//' + ... .search | +| tst10.js:8:17:8:47 | '//' + ... .search | +| tst10.js:8:24:8:40 | document.location | | tst10.js:8:24:8:40 | document.location | | tst10.js:8:24:8:47 | documen ... .search | | tst10.js:11:17:11:50 | '//foo' ... .search | +| tst10.js:11:17:11:50 | '//foo' ... .search | +| tst10.js:11:27:11:43 | document.location | | tst10.js:11:27:11:43 | document.location | | tst10.js:11:27:11:50 | documen ... .search | | tst10.js:14:17:14:56 | 'https: ... .search | +| tst10.js:14:17:14:56 | 'https: ... .search | +| tst10.js:14:33:14:49 | document.location | | tst10.js:14:33:14:49 | document.location | | tst10.js:14:33:14:56 | documen ... .search | | tst.js:2:19:2:69 | /.*redi ... n.href) | | tst.js:2:19:2:72 | /.*redi ... ref)[1] | +| tst.js:2:19:2:72 | /.*redi ... ref)[1] | +| tst.js:2:47:2:63 | document.location | | tst.js:2:47:2:63 | document.location | | tst.js:2:47:2:68 | documen ... on.href | | tst.js:6:20:6:56 | indirec ... n.href) | | tst.js:6:20:6:59 | indirec ... ref)[1] | +| tst.js:6:20:6:59 | indirec ... ref)[1] | +| tst.js:6:34:6:50 | document.location | | tst.js:6:34:6:50 | document.location | | tst.js:6:34:6:55 | documen ... on.href | edges @@ -47,33 +72,62 @@ edges | tst2.js:2:7:2:33 | href | tst2.js:4:21:4:24 | href | | tst2.js:2:14:2:28 | window.location | tst2.js:2:14:2:33 | window.location.href | | tst2.js:2:14:2:28 | window.location | tst2.js:2:14:2:33 | window.location.href | +| tst2.js:2:14:2:28 | window.location | tst2.js:2:14:2:33 | window.location.href | | tst2.js:2:14:2:33 | window.location.href | tst2.js:2:7:2:33 | href | | tst2.js:2:14:2:33 | window.location.href | tst2.js:2:7:2:33 | href | | tst2.js:4:21:4:24 | href | tst2.js:4:21:4:55 | href.su ... '?')+1) | | tst2.js:4:21:4:24 | href | tst2.js:4:21:4:55 | href.su ... '?')+1) | +| tst2.js:4:21:4:24 | href | tst2.js:4:21:4:55 | href.su ... '?')+1) | +| tst2.js:4:21:4:24 | href | tst2.js:4:21:4:55 | href.su ... '?')+1) | | tst2.js:4:21:4:55 | href.su ... '?')+1) | tst2.js:2:14:2:28 | window.location | | tst6.js:2:7:2:45 | redirect | tst6.js:4:21:4:28 | redirect | +| tst6.js:2:7:2:45 | redirect | tst6.js:4:21:4:28 | redirect | +| tst6.js:2:7:2:45 | redirect | tst6.js:6:17:6:24 | redirect | | tst6.js:2:7:2:45 | redirect | tst6.js:6:17:6:24 | redirect | | tst6.js:2:18:2:45 | $locati ... irect') | tst6.js:2:7:2:45 | redirect | +| tst6.js:2:18:2:45 | $locati ... irect') | tst6.js:2:7:2:45 | redirect | +| tst6.js:8:21:8:48 | $locati ... irect') | tst6.js:8:21:8:56 | $locati ... + "foo" | +| tst6.js:8:21:8:48 | $locati ... irect') | tst6.js:8:21:8:56 | $locati ... + "foo" | +| tst6.js:8:21:8:48 | $locati ... irect') | tst6.js:8:21:8:56 | $locati ... + "foo" | | tst6.js:8:21:8:48 | $locati ... irect') | tst6.js:8:21:8:56 | $locati ... + "foo" | | tst7.js:2:12:2:28 | document.location | tst7.js:2:12:2:35 | documen ... .search | +| tst7.js:2:12:2:28 | document.location | tst7.js:2:12:2:35 | documen ... .search | +| tst7.js:2:12:2:28 | document.location | tst7.js:2:12:2:35 | documen ... .search | +| tst7.js:2:12:2:28 | document.location | tst7.js:2:12:2:35 | documen ... .search | +| tst7.js:5:27:5:43 | document.location | tst7.js:5:27:5:50 | documen ... .search | +| tst7.js:5:27:5:43 | document.location | tst7.js:5:27:5:50 | documen ... .search | +| tst7.js:5:27:5:43 | document.location | tst7.js:5:27:5:50 | documen ... .search | | tst7.js:5:27:5:43 | document.location | tst7.js:5:27:5:50 | documen ... .search | | tst9.js:2:21:2:37 | document.location | tst9.js:2:21:2:42 | documen ... on.hash | | tst9.js:2:21:2:37 | document.location | tst9.js:2:21:2:42 | documen ... on.hash | +| tst9.js:2:21:2:37 | document.location | tst9.js:2:21:2:42 | documen ... on.hash | +| tst9.js:2:21:2:42 | documen ... on.hash | tst9.js:2:21:2:55 | documen ... ring(1) | | tst9.js:2:21:2:42 | documen ... on.hash | tst9.js:2:21:2:55 | documen ... ring(1) | | tst9.js:2:21:2:55 | documen ... ring(1) | tst9.js:2:21:2:37 | document.location | | tst10.js:5:23:5:39 | document.location | tst10.js:5:23:5:46 | documen ... .search | +| tst10.js:5:23:5:39 | document.location | tst10.js:5:23:5:46 | documen ... .search | +| tst10.js:5:23:5:46 | documen ... .search | tst10.js:5:17:5:46 | '/' + d ... .search | | tst10.js:5:23:5:46 | documen ... .search | tst10.js:5:17:5:46 | '/' + d ... .search | | tst10.js:8:24:8:40 | document.location | tst10.js:8:24:8:47 | documen ... .search | +| tst10.js:8:24:8:40 | document.location | tst10.js:8:24:8:47 | documen ... .search | +| tst10.js:8:24:8:47 | documen ... .search | tst10.js:8:17:8:47 | '//' + ... .search | | tst10.js:8:24:8:47 | documen ... .search | tst10.js:8:17:8:47 | '//' + ... .search | | tst10.js:11:27:11:43 | document.location | tst10.js:11:27:11:50 | documen ... .search | +| tst10.js:11:27:11:43 | document.location | tst10.js:11:27:11:50 | documen ... .search | +| tst10.js:11:27:11:50 | documen ... .search | tst10.js:11:17:11:50 | '//foo' ... .search | | tst10.js:11:27:11:50 | documen ... .search | tst10.js:11:17:11:50 | '//foo' ... .search | | tst10.js:14:33:14:49 | document.location | tst10.js:14:33:14:56 | documen ... .search | +| tst10.js:14:33:14:49 | document.location | tst10.js:14:33:14:56 | documen ... .search | +| tst10.js:14:33:14:56 | documen ... .search | tst10.js:14:17:14:56 | 'https: ... .search | | tst10.js:14:33:14:56 | documen ... .search | tst10.js:14:17:14:56 | 'https: ... .search | | tst.js:2:19:2:69 | /.*redi ... n.href) | tst.js:2:19:2:72 | /.*redi ... ref)[1] | +| tst.js:2:19:2:69 | /.*redi ... n.href) | tst.js:2:19:2:72 | /.*redi ... ref)[1] | +| tst.js:2:47:2:63 | document.location | tst.js:2:47:2:68 | documen ... on.href | | tst.js:2:47:2:63 | document.location | tst.js:2:47:2:68 | documen ... on.href | | tst.js:2:47:2:68 | documen ... on.href | tst.js:2:19:2:69 | /.*redi ... n.href) | | tst.js:6:20:6:56 | indirec ... n.href) | tst.js:6:20:6:59 | indirec ... ref)[1] | +| tst.js:6:20:6:56 | indirec ... n.href) | tst.js:6:20:6:59 | indirec ... ref)[1] | +| tst.js:6:34:6:50 | document.location | tst.js:6:34:6:55 | documen ... on.href | | tst.js:6:34:6:50 | document.location | tst.js:6:34:6:55 | documen ... on.href | | tst.js:6:34:6:55 | documen ... on.href | tst.js:6:20:6:56 | indirec ... n.href) | #select diff --git a/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected b/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected index 158aa410f19..5e92ab22c9f 100644 --- a/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected +++ b/javascript/ql/test/query-tests/Security/CWE-601/ServerSideUrlRedirect/ServerSideUrlRedirect.expected @@ -1,44 +1,74 @@ nodes | express.js:7:16:7:34 | req.param("target") | +| express.js:7:16:7:34 | req.param("target") | +| express.js:7:16:7:34 | req.param("target") | +| express.js:12:26:12:44 | req.param("target") | +| express.js:12:26:12:44 | req.param("target") | | express.js:12:26:12:44 | req.param("target") | | express.js:27:7:27:34 | target | | express.js:27:16:27:34 | req.param("target") | +| express.js:27:16:27:34 | req.param("target") | +| express.js:33:18:33:23 | target | | express.js:33:18:33:23 | target | | express.js:35:16:35:21 | target | +| express.js:35:16:35:21 | target | +| express.js:40:16:40:108 | (req.pa ... ntacts" | | express.js:40:16:40:108 | (req.pa ... ntacts" | | express.js:40:69:40:87 | req.param('action') | +| express.js:40:69:40:87 | req.param('action') | | express.js:74:16:74:43 | `${req. ... )}/foo` | +| express.js:74:16:74:43 | `${req. ... )}/foo` | +| express.js:74:19:74:37 | req.param("target") | | express.js:74:19:74:37 | req.param("target") | | express.js:83:7:83:34 | target | | express.js:83:16:83:34 | req.param("target") | +| express.js:83:16:83:34 | req.param("target") | | express.js:90:18:90:23 | target | +| express.js:90:18:90:23 | target | +| express.js:97:16:97:21 | target | | express.js:97:16:97:21 | target | | express.js:118:16:118:63 | [req.qu ... ection] | | express.js:118:16:118:72 | [req.qu ... oin('') | +| express.js:118:16:118:72 | [req.qu ... oin('') | +| express.js:118:17:118:30 | req.query.page | | express.js:118:17:118:30 | req.query.page | | express.js:134:16:134:36 | '/' + r ... ms.user | +| express.js:134:16:134:36 | '/' + r ... ms.user | +| express.js:134:22:134:36 | req.params.user | | express.js:134:22:134:36 | req.params.user | | express.js:135:16:135:37 | '//' + ... ms.user | +| express.js:135:16:135:37 | '//' + ... ms.user | +| express.js:135:23:135:37 | req.params.user | | express.js:135:23:135:37 | req.params.user | | express.js:136:16:136:36 | 'u' + r ... ms.user | +| express.js:136:16:136:36 | 'u' + r ... ms.user | +| express.js:136:22:136:36 | req.params.user | | express.js:136:22:136:36 | req.params.user | | koa.js:6:6:6:27 | url | | koa.js:6:12:6:27 | ctx.query.target | +| koa.js:6:12:6:27 | ctx.query.target | +| koa.js:7:15:7:17 | url | | koa.js:7:15:7:17 | url | | koa.js:8:15:8:26 | `${url}${x}` | +| koa.js:8:15:8:26 | `${url}${x}` | | koa.js:8:18:8:20 | url | | koa.js:14:16:14:18 | url | +| koa.js:14:16:14:18 | url | | node.js:6:7:6:52 | target | | node.js:6:16:6:39 | url.par ... , true) | | node.js:6:16:6:45 | url.par ... ).query | | node.js:6:16:6:52 | url.par ... .target | | node.js:6:26:6:32 | req.url | +| node.js:6:26:6:32 | req.url | +| node.js:7:34:7:39 | target | | node.js:7:34:7:39 | target | | node.js:11:7:11:52 | target | | node.js:11:16:11:39 | url.par ... , true) | | node.js:11:16:11:45 | url.par ... ).query | | node.js:11:16:11:52 | url.par ... .target | | node.js:11:26:11:32 | req.url | +| node.js:11:26:11:32 | req.url | +| node.js:15:34:15:45 | '/' + target | | node.js:15:34:15:45 | '/' + target | | node.js:15:40:15:45 | target | | node.js:29:7:29:52 | target | @@ -46,65 +76,93 @@ nodes | node.js:29:16:29:45 | url.par ... ).query | | node.js:29:16:29:52 | url.par ... .target | | node.js:29:26:29:32 | req.url | +| node.js:29:26:29:32 | req.url | | node.js:32:34:32:39 | target | | node.js:32:34:32:55 | target ... =" + me | +| node.js:32:34:32:55 | target ... =" + me | | react-native.js:7:7:7:33 | tainted | | react-native.js:7:17:7:33 | req.param("code") | +| react-native.js:7:17:7:33 | req.param("code") | +| react-native.js:8:17:8:23 | tainted | | react-native.js:8:17:8:23 | tainted | | react-native.js:9:26:9:32 | tainted | +| react-native.js:9:26:9:32 | tainted | edges +| express.js:7:16:7:34 | req.param("target") | express.js:7:16:7:34 | req.param("target") | +| express.js:12:26:12:44 | req.param("target") | express.js:12:26:12:44 | req.param("target") | +| express.js:27:7:27:34 | target | express.js:33:18:33:23 | target | | express.js:27:7:27:34 | target | express.js:33:18:33:23 | target | | express.js:27:7:27:34 | target | express.js:35:16:35:21 | target | +| express.js:27:7:27:34 | target | express.js:35:16:35:21 | target | +| express.js:27:16:27:34 | req.param("target") | express.js:27:7:27:34 | target | | express.js:27:16:27:34 | req.param("target") | express.js:27:7:27:34 | target | | express.js:40:69:40:87 | req.param('action') | express.js:40:16:40:108 | (req.pa ... ntacts" | +| express.js:40:69:40:87 | req.param('action') | express.js:40:16:40:108 | (req.pa ... ntacts" | +| express.js:40:69:40:87 | req.param('action') | express.js:40:16:40:108 | (req.pa ... ntacts" | +| express.js:40:69:40:87 | req.param('action') | express.js:40:16:40:108 | (req.pa ... ntacts" | +| express.js:74:19:74:37 | req.param("target") | express.js:74:16:74:43 | `${req. ... )}/foo` | +| express.js:74:19:74:37 | req.param("target") | express.js:74:16:74:43 | `${req. ... )}/foo` | +| express.js:74:19:74:37 | req.param("target") | express.js:74:16:74:43 | `${req. ... )}/foo` | | express.js:74:19:74:37 | req.param("target") | express.js:74:16:74:43 | `${req. ... )}/foo` | | express.js:83:7:83:34 | target | express.js:90:18:90:23 | target | +| express.js:83:7:83:34 | target | express.js:90:18:90:23 | target | +| express.js:83:7:83:34 | target | express.js:97:16:97:21 | target | | express.js:83:7:83:34 | target | express.js:97:16:97:21 | target | | express.js:83:16:83:34 | req.param("target") | express.js:83:7:83:34 | target | +| express.js:83:16:83:34 | req.param("target") | express.js:83:7:83:34 | target | +| express.js:118:16:118:63 | [req.qu ... ection] | express.js:118:16:118:72 | [req.qu ... oin('') | | express.js:118:16:118:63 | [req.qu ... ection] | express.js:118:16:118:72 | [req.qu ... oin('') | | express.js:118:17:118:30 | req.query.page | express.js:118:16:118:63 | [req.qu ... ection] | +| express.js:118:17:118:30 | req.query.page | express.js:118:16:118:63 | [req.qu ... ection] | +| express.js:134:22:134:36 | req.params.user | express.js:134:16:134:36 | '/' + r ... ms.user | +| express.js:134:22:134:36 | req.params.user | express.js:134:16:134:36 | '/' + r ... ms.user | +| express.js:134:22:134:36 | req.params.user | express.js:134:16:134:36 | '/' + r ... ms.user | | express.js:134:22:134:36 | req.params.user | express.js:134:16:134:36 | '/' + r ... ms.user | | express.js:135:23:135:37 | req.params.user | express.js:135:16:135:37 | '//' + ... ms.user | +| express.js:135:23:135:37 | req.params.user | express.js:135:16:135:37 | '//' + ... ms.user | +| express.js:135:23:135:37 | req.params.user | express.js:135:16:135:37 | '//' + ... ms.user | +| express.js:135:23:135:37 | req.params.user | express.js:135:16:135:37 | '//' + ... ms.user | +| express.js:136:22:136:36 | req.params.user | express.js:136:16:136:36 | 'u' + r ... ms.user | +| express.js:136:22:136:36 | req.params.user | express.js:136:16:136:36 | 'u' + r ... ms.user | +| express.js:136:22:136:36 | req.params.user | express.js:136:16:136:36 | 'u' + r ... ms.user | | express.js:136:22:136:36 | req.params.user | express.js:136:16:136:36 | 'u' + r ... ms.user | | koa.js:6:6:6:27 | url | koa.js:7:15:7:17 | url | +| koa.js:6:6:6:27 | url | koa.js:7:15:7:17 | url | | koa.js:6:6:6:27 | url | koa.js:8:18:8:20 | url | -| koa.js:6:6:6:27 | url | koa.js:10:40:10:42 | url | -| koa.js:6:6:6:27 | url | koa.js:10:40:10:42 | url | -| koa.js:6:6:6:27 | url | koa.js:10:51:10:51 | url | -| koa.js:6:6:6:27 | url | koa.js:11:6:11:8 | url | +| koa.js:6:6:6:27 | url | koa.js:14:16:14:18 | url | | koa.js:6:6:6:27 | url | koa.js:14:16:14:18 | url | | koa.js:6:12:6:27 | ctx.query.target | koa.js:6:6:6:27 | url | +| koa.js:6:12:6:27 | ctx.query.target | koa.js:6:6:6:27 | url | | koa.js:8:18:8:20 | url | koa.js:8:15:8:26 | `${url}${x}` | -| koa.js:10:40:10:42 | url | koa.js:10:51:10:51 | url | -| koa.js:10:40:10:42 | url | koa.js:10:51:10:51 | url | -| koa.js:10:40:10:42 | url | koa.js:11:6:11:8 | url | -| koa.js:10:40:10:42 | url | koa.js:11:6:11:8 | url | -| koa.js:10:40:10:42 | url | koa.js:14:16:14:18 | url | -| koa.js:10:40:10:42 | url | koa.js:14:16:14:18 | url | -| koa.js:10:51:10:51 | url | koa.js:11:6:11:8 | url | -| koa.js:10:51:10:51 | url | koa.js:14:16:14:18 | url | -| koa.js:11:6:11:8 | url | koa.js:14:16:14:18 | url | +| koa.js:8:18:8:20 | url | koa.js:8:15:8:26 | `${url}${x}` | +| node.js:6:7:6:52 | target | node.js:7:34:7:39 | target | | node.js:6:7:6:52 | target | node.js:7:34:7:39 | target | | node.js:6:16:6:39 | url.par ... , true) | node.js:6:16:6:45 | url.par ... ).query | | node.js:6:16:6:45 | url.par ... ).query | node.js:6:16:6:52 | url.par ... .target | | node.js:6:16:6:52 | url.par ... .target | node.js:6:7:6:52 | target | | node.js:6:26:6:32 | req.url | node.js:6:16:6:39 | url.par ... , true) | +| node.js:6:26:6:32 | req.url | node.js:6:16:6:39 | url.par ... , true) | | node.js:11:7:11:52 | target | node.js:15:40:15:45 | target | | node.js:11:16:11:39 | url.par ... , true) | node.js:11:16:11:45 | url.par ... ).query | | node.js:11:16:11:45 | url.par ... ).query | node.js:11:16:11:52 | url.par ... .target | | node.js:11:16:11:52 | url.par ... .target | node.js:11:7:11:52 | target | | node.js:11:26:11:32 | req.url | node.js:11:16:11:39 | url.par ... , true) | +| node.js:11:26:11:32 | req.url | node.js:11:16:11:39 | url.par ... , true) | +| node.js:15:40:15:45 | target | node.js:15:34:15:45 | '/' + target | | node.js:15:40:15:45 | target | node.js:15:34:15:45 | '/' + target | | node.js:29:7:29:52 | target | node.js:32:34:32:39 | target | | node.js:29:16:29:39 | url.par ... , true) | node.js:29:16:29:45 | url.par ... ).query | | node.js:29:16:29:45 | url.par ... ).query | node.js:29:16:29:52 | url.par ... .target | | node.js:29:16:29:52 | url.par ... .target | node.js:29:7:29:52 | target | | node.js:29:26:29:32 | req.url | node.js:29:16:29:39 | url.par ... , true) | -| node.js:32:34:32:39 | target | node.js:32:34:32:50 | target + "?from=" | +| node.js:29:26:29:32 | req.url | node.js:29:16:29:39 | url.par ... , true) | | node.js:32:34:32:39 | target | node.js:32:34:32:55 | target ... =" + me | -| node.js:32:34:32:50 | target + "?from=" | node.js:32:34:32:55 | target ... =" + me | +| node.js:32:34:32:39 | target | node.js:32:34:32:55 | target ... =" + me | +| react-native.js:7:7:7:33 | tainted | react-native.js:8:17:8:23 | tainted | | react-native.js:7:7:7:33 | tainted | react-native.js:8:17:8:23 | tainted | | react-native.js:7:7:7:33 | tainted | react-native.js:9:26:9:32 | tainted | +| react-native.js:7:7:7:33 | tainted | react-native.js:9:26:9:32 | tainted | +| react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | | react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:33 | tainted | #select | express.js:7:16:7:34 | req.param("target") | express.js:7:16:7:34 | req.param("target") | express.js:7:16:7:34 | req.param("target") | Untrusted URL redirection due to $@. | express.js:7:16:7:34 | req.param("target") | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected b/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected index 982bd6ee841..03dc33e7113 100644 --- a/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected +++ b/javascript/ql/test/query-tests/Security/CWE-611/Xxe.expected @@ -1,17 +1,32 @@ nodes | domparser.js:2:7:2:36 | src | | domparser.js:2:13:2:29 | document.location | +| domparser.js:2:13:2:29 | document.location | | domparser.js:2:13:2:36 | documen ... .search | | domparser.js:11:55:11:57 | src | +| domparser.js:11:55:11:57 | src | +| domparser.js:14:57:14:59 | src | | domparser.js:14:57:14:59 | src | | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | +| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | +| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | +| libxml.sax.js:7:22:7:42 | req.par ... e-xml") | +| libxml.sax.js:7:22:7:42 | req.par ... e-xml") | +| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | +| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | edges | domparser.js:2:7:2:36 | src | domparser.js:11:55:11:57 | src | +| domparser.js:2:7:2:36 | src | domparser.js:11:55:11:57 | src | +| domparser.js:2:7:2:36 | src | domparser.js:14:57:14:59 | src | | domparser.js:2:7:2:36 | src | domparser.js:14:57:14:59 | src | | domparser.js:2:13:2:29 | document.location | domparser.js:2:13:2:36 | documen ... .search | +| domparser.js:2:13:2:29 | document.location | domparser.js:2:13:2:36 | documen ... .search | | domparser.js:2:13:2:36 | documen ... .search | domparser.js:2:7:2:36 | src | +| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | +| libxml.sax.js:7:22:7:42 | req.par ... e-xml") | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | +| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | #select | domparser.js:11:55:11:57 | src | domparser.js:2:13:2:29 | document.location | domparser.js:11:55:11:57 | src | A $@ is parsed as XML without guarding against external entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value | | domparser.js:14:57:14:59 | src | domparser.js:2:13:2:29 | document.location | domparser.js:14:57:14:59 | src | A $@ is parsed as XML without guarding against external entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.expected b/javascript/ql/test/query-tests/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.expected index 0fe75f2e75e..dc2b32cdd9e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.expected +++ b/javascript/ql/test/query-tests/Security/CWE-640/HostHeaderPoisoningInEmailGeneration.expected @@ -1,10 +1,20 @@ nodes | tst.js:17:11:17:113 | `Hi, lo ... token}` | +| tst.js:17:11:17:113 | `Hi, lo ... token}` | +| tst.js:17:84:17:91 | req.host | | tst.js:17:84:17:91 | req.host | | tst.js:18:11:18:127 | `Hi, lo ... reset.` | +| tst.js:18:11:18:127 | `Hi, lo ... reset.` | +| tst.js:18:78:18:85 | req.host | | tst.js:18:78:18:85 | req.host | edges | tst.js:17:84:17:91 | req.host | tst.js:17:11:17:113 | `Hi, lo ... token}` | +| tst.js:17:84:17:91 | req.host | tst.js:17:11:17:113 | `Hi, lo ... token}` | +| tst.js:17:84:17:91 | req.host | tst.js:17:11:17:113 | `Hi, lo ... token}` | +| tst.js:17:84:17:91 | req.host | tst.js:17:11:17:113 | `Hi, lo ... token}` | +| tst.js:18:78:18:85 | req.host | tst.js:18:11:18:127 | `Hi, lo ... reset.` | +| tst.js:18:78:18:85 | req.host | tst.js:18:11:18:127 | `Hi, lo ... reset.` | +| tst.js:18:78:18:85 | req.host | tst.js:18:11:18:127 | `Hi, lo ... reset.` | | tst.js:18:78:18:85 | req.host | tst.js:18:11:18:127 | `Hi, lo ... reset.` | #select | tst.js:17:11:17:113 | `Hi, lo ... token}` | tst.js:17:84:17:91 | req.host | tst.js:17:11:17:113 | `Hi, lo ... token}` | Links in this email can be hijacked by poisoning the HTTP host header $@. | tst.js:17:84:17:91 | req.host | here | diff --git a/javascript/ql/test/query-tests/Security/CWE-643/XpathInjection.expected b/javascript/ql/test/query-tests/Security/CWE-643/XpathInjection.expected index dc107f8d15d..8cb5413d0b3 100644 --- a/javascript/ql/test/query-tests/Security/CWE-643/XpathInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-643/XpathInjection.expected @@ -1,33 +1,51 @@ nodes | XpathInjectionBad.js:6:7:6:38 | userName | | XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | +| XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | +| XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | | XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | | XpathInjectionBad.js:9:66:9:73 | userName | | tst2.js:1:13:1:29 | document.location | +| tst2.js:1:13:1:29 | document.location | | tst2.js:1:13:1:34 | documen ... on.hash | | tst2.js:1:13:1:47 | documen ... ring(1) | | tst2.js:2:27:2:31 | query | +| tst2.js:2:27:2:31 | query | +| tst2.js:3:19:3:23 | query | | tst2.js:3:19:3:23 | query | | tst.js:6:7:6:37 | tainted | | tst.js:6:17:6:37 | req.par ... rName") | +| tst.js:6:17:6:37 | req.par ... rName") | +| tst.js:7:15:7:21 | tainted | | tst.js:7:15:7:21 | tainted | | tst.js:8:16:8:22 | tainted | +| tst.js:8:16:8:22 | tainted | | tst.js:9:17:9:23 | tainted | +| tst.js:9:17:9:23 | tainted | +| tst.js:11:8:11:14 | tainted | | tst.js:11:8:11:14 | tainted | edges | XpathInjectionBad.js:6:7:6:38 | userName | XpathInjectionBad.js:9:66:9:73 | userName | | XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | XpathInjectionBad.js:6:7:6:38 | userName | -| XpathInjectionBad.js:9:34:9:73 | "//user ... serName | XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | -| XpathInjectionBad.js:9:66:9:73 | userName | XpathInjectionBad.js:9:34:9:73 | "//user ... serName | +| XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | XpathInjectionBad.js:6:7:6:38 | userName | | XpathInjectionBad.js:9:66:9:73 | userName | XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | +| XpathInjectionBad.js:9:66:9:73 | userName | XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | +| tst2.js:1:13:1:29 | document.location | tst2.js:1:13:1:34 | documen ... on.hash | | tst2.js:1:13:1:29 | document.location | tst2.js:1:13:1:34 | documen ... on.hash | | tst2.js:1:13:1:34 | documen ... on.hash | tst2.js:1:13:1:47 | documen ... ring(1) | | tst2.js:1:13:1:47 | documen ... ring(1) | tst2.js:2:27:2:31 | query | +| tst2.js:1:13:1:47 | documen ... ring(1) | tst2.js:2:27:2:31 | query | +| tst2.js:1:13:1:47 | documen ... ring(1) | tst2.js:3:19:3:23 | query | | tst2.js:1:13:1:47 | documen ... ring(1) | tst2.js:3:19:3:23 | query | | tst.js:6:7:6:37 | tainted | tst.js:7:15:7:21 | tainted | +| tst.js:6:7:6:37 | tainted | tst.js:7:15:7:21 | tainted | +| tst.js:6:7:6:37 | tainted | tst.js:8:16:8:22 | tainted | | tst.js:6:7:6:37 | tainted | tst.js:8:16:8:22 | tainted | | tst.js:6:7:6:37 | tainted | tst.js:9:17:9:23 | tainted | +| tst.js:6:7:6:37 | tainted | tst.js:9:17:9:23 | tainted | | tst.js:6:7:6:37 | tainted | tst.js:11:8:11:14 | tainted | +| tst.js:6:7:6:37 | tainted | tst.js:11:8:11:14 | tainted | +| tst.js:6:17:6:37 | req.par ... rName") | tst.js:6:7:6:37 | tainted | | tst.js:6:17:6:37 | req.par ... rName") | tst.js:6:7:6:37 | tainted | #select | XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | XpathInjectionBad.js:9:34:9:96 | "//user ... text()" | $@ flows here and is used in an XPath expression. | XpathInjectionBad.js:6:18:6:38 | req.par ... rName") | User-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected index 2343c1c34bf..dedd3625d6e 100644 --- a/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-730/RegExpInjection.expected @@ -1,34 +1,51 @@ nodes | RegExpInjection.js:5:7:5:28 | key | | RegExpInjection.js:5:13:5:28 | req.param("key") | +| RegExpInjection.js:5:13:5:28 | req.param("key") | | RegExpInjection.js:5:31:5:56 | input | | RegExpInjection.js:5:39:5:56 | req.param("input") | +| RegExpInjection.js:5:39:5:56 | req.param("input") | +| RegExpInjection.js:8:23:8:45 | "\\\\b" + ... (.*)\\n" | | RegExpInjection.js:8:23:8:45 | "\\\\b" + ... (.*)\\n" | | RegExpInjection.js:8:31:8:33 | key | | RegExpInjection.js:19:14:19:22 | wrap(key) | +| RegExpInjection.js:19:14:19:22 | wrap(key) | | RegExpInjection.js:19:19:19:21 | key | | RegExpInjection.js:21:14:21:22 | wrap(key) | +| RegExpInjection.js:21:14:21:22 | wrap(key) | | RegExpInjection.js:21:19:21:21 | key | | RegExpInjection.js:24:12:24:27 | req.param("key") | +| RegExpInjection.js:24:12:24:27 | req.param("key") | +| RegExpInjection.js:27:14:27:21 | getKey() | | RegExpInjection.js:27:14:27:21 | getKey() | | RegExpInjection.js:29:21:29:21 | s | | RegExpInjection.js:29:21:29:21 | s | | RegExpInjection.js:31:23:31:23 | s | | RegExpInjection.js:31:23:31:23 | s | +| RegExpInjection.js:31:23:31:23 | s | | RegExpInjection.js:33:12:33:14 | key | | RegExpInjection.js:34:12:34:19 | getKey() | | RegExpInjection.js:40:19:40:23 | input | +| RegExpInjection.js:40:19:40:23 | input | +| RegExpInjection.js:41:22:41:26 | input | | RegExpInjection.js:41:22:41:26 | input | | RegExpInjection.js:42:21:42:25 | input | +| RegExpInjection.js:42:21:42:25 | input | +| RegExpInjection.js:45:20:45:24 | input | | RegExpInjection.js:45:20:45:24 | input | | RegExpInjection.js:46:23:46:27 | input | +| RegExpInjection.js:46:23:46:27 | input | +| RegExpInjection.js:47:22:47:26 | input | | RegExpInjection.js:47:22:47:26 | input | | RegExpInjection.js:50:46:50:50 | input | +| RegExpInjection.js:50:46:50:50 | input | +| tst.js:1:46:1:46 | e | | tst.js:1:46:1:46 | e | | tst.js:2:9:2:21 | data | | tst.js:2:16:2:16 | e | | tst.js:2:16:2:21 | e.data | | tst.js:3:16:3:35 | "^"+ data.name + "$" | +| tst.js:3:16:3:35 | "^"+ data.name + "$" | | tst.js:3:21:3:24 | data | | tst.js:3:21:3:29 | data.name | edges @@ -37,32 +54,48 @@ edges | RegExpInjection.js:5:7:5:28 | key | RegExpInjection.js:21:19:21:21 | key | | RegExpInjection.js:5:7:5:28 | key | RegExpInjection.js:33:12:33:14 | key | | RegExpInjection.js:5:13:5:28 | req.param("key") | RegExpInjection.js:5:7:5:28 | key | +| RegExpInjection.js:5:13:5:28 | req.param("key") | RegExpInjection.js:5:7:5:28 | key | +| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:40:19:40:23 | input | | RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:40:19:40:23 | input | | RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:41:22:41:26 | input | +| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:41:22:41:26 | input | +| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:42:21:42:25 | input | | RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:42:21:42:25 | input | | RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:45:20:45:24 | input | +| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:45:20:45:24 | input | +| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:46:23:46:27 | input | | RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:46:23:46:27 | input | | RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:47:22:47:26 | input | +| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:47:22:47:26 | input | +| RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:50:46:50:50 | input | | RegExpInjection.js:5:31:5:56 | input | RegExpInjection.js:50:46:50:50 | input | | RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:5:31:5:56 | input | -| RegExpInjection.js:8:23:8:33 | "\\\\b" + key | RegExpInjection.js:8:23:8:45 | "\\\\b" + ... (.*)\\n" | -| RegExpInjection.js:8:31:8:33 | key | RegExpInjection.js:8:23:8:33 | "\\\\b" + key | +| RegExpInjection.js:5:39:5:56 | req.param("input") | RegExpInjection.js:5:31:5:56 | input | +| RegExpInjection.js:8:31:8:33 | key | RegExpInjection.js:8:23:8:45 | "\\\\b" + ... (.*)\\n" | | RegExpInjection.js:8:31:8:33 | key | RegExpInjection.js:8:23:8:45 | "\\\\b" + ... (.*)\\n" | | RegExpInjection.js:19:19:19:21 | key | RegExpInjection.js:19:14:19:22 | wrap(key) | +| RegExpInjection.js:19:19:19:21 | key | RegExpInjection.js:19:14:19:22 | wrap(key) | +| RegExpInjection.js:21:19:21:21 | key | RegExpInjection.js:21:14:21:22 | wrap(key) | | RegExpInjection.js:21:19:21:21 | key | RegExpInjection.js:21:14:21:22 | wrap(key) | | RegExpInjection.js:24:12:24:27 | req.param("key") | RegExpInjection.js:27:14:27:21 | getKey() | +| RegExpInjection.js:24:12:24:27 | req.param("key") | RegExpInjection.js:27:14:27:21 | getKey() | +| RegExpInjection.js:24:12:24:27 | req.param("key") | RegExpInjection.js:27:14:27:21 | getKey() | +| RegExpInjection.js:24:12:24:27 | req.param("key") | RegExpInjection.js:27:14:27:21 | getKey() | | RegExpInjection.js:24:12:24:27 | req.param("key") | RegExpInjection.js:34:12:34:19 | getKey() | +| RegExpInjection.js:24:12:24:27 | req.param("key") | RegExpInjection.js:34:12:34:19 | getKey() | +| RegExpInjection.js:29:21:29:21 | s | RegExpInjection.js:31:23:31:23 | s | +| RegExpInjection.js:29:21:29:21 | s | RegExpInjection.js:31:23:31:23 | s | | RegExpInjection.js:29:21:29:21 | s | RegExpInjection.js:31:23:31:23 | s | | RegExpInjection.js:29:21:29:21 | s | RegExpInjection.js:31:23:31:23 | s | | RegExpInjection.js:33:12:33:14 | key | RegExpInjection.js:29:21:29:21 | s | | RegExpInjection.js:34:12:34:19 | getKey() | RegExpInjection.js:29:21:29:21 | s | | tst.js:1:46:1:46 | e | tst.js:2:16:2:16 | e | +| tst.js:1:46:1:46 | e | tst.js:2:16:2:16 | e | | tst.js:2:9:2:21 | data | tst.js:3:21:3:24 | data | | tst.js:2:16:2:16 | e | tst.js:2:16:2:21 | e.data | | tst.js:2:16:2:21 | e.data | tst.js:2:9:2:21 | data | -| tst.js:3:16:3:29 | "^"+ data.name | tst.js:3:16:3:35 | "^"+ data.name + "$" | | tst.js:3:21:3:24 | data | tst.js:3:21:3:29 | data.name | -| tst.js:3:21:3:29 | data.name | tst.js:3:16:3:29 | "^"+ data.name | +| tst.js:3:21:3:29 | data.name | tst.js:3:16:3:35 | "^"+ data.name + "$" | | tst.js:3:21:3:29 | data.name | tst.js:3:16:3:35 | "^"+ data.name + "$" | #select | RegExpInjection.js:8:23:8:45 | "\\\\b" + ... (.*)\\n" | RegExpInjection.js:5:13:5:28 | req.param("key") | RegExpInjection.js:8:23:8:45 | "\\\\b" + ... (.*)\\n" | This regular expression is constructed from a $@. | RegExpInjection.js:5:13:5:28 | req.param("key") | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-754/UnvalidatedDynamicMethodCall.expected b/javascript/ql/test/query-tests/Security/CWE-754/UnvalidatedDynamicMethodCall.expected index 8de8a639cd3..1a512526e98 100644 --- a/javascript/ql/test/query-tests/Security/CWE-754/UnvalidatedDynamicMethodCall.expected +++ b/javascript/ql/test/query-tests/Security/CWE-754/UnvalidatedDynamicMethodCall.expected @@ -1,11 +1,13 @@ nodes | UnsafeDynamicMethodAccess.js:5:37:5:38 | ev | +| UnsafeDynamicMethodAccess.js:5:37:5:38 | ev | | UnsafeDynamicMethodAccess.js:6:9:6:37 | message | | UnsafeDynamicMethodAccess.js:6:19:6:37 | JSON.parse(ev.data) | | UnsafeDynamicMethodAccess.js:6:30:6:31 | ev | | UnsafeDynamicMethodAccess.js:6:30:6:36 | ev.data | | UnsafeDynamicMethodAccess.js:15:5:15:21 | obj[message.name] | | UnsafeDynamicMethodAccess.js:15:5:15:21 | obj[message.name] | +| UnsafeDynamicMethodAccess.js:15:5:15:21 | obj[message.name] | | UnsafeDynamicMethodAccess.js:15:9:15:15 | message | | UnsafeDynamicMethodAccess.js:15:9:15:20 | message.name | | UnvalidatedDynamicMethodCall.js:14:7:14:41 | action | @@ -13,8 +15,11 @@ nodes | UnvalidatedDynamicMethodCall.js:14:16:14:41 | actions ... action] | | UnvalidatedDynamicMethodCall.js:14:16:14:41 | actions ... action] | | UnvalidatedDynamicMethodCall.js:14:24:14:40 | req.params.action | +| UnvalidatedDynamicMethodCall.js:14:24:14:40 | req.params.action | | UnvalidatedDynamicMethodCall.js:15:11:15:16 | action | | UnvalidatedDynamicMethodCall.js:15:11:15:16 | action | +| UnvalidatedDynamicMethodCall.js:15:11:15:16 | action | +| tst.js:6:39:6:40 | ev | | tst.js:6:39:6:40 | ev | | tst.js:7:9:7:39 | name | | tst.js:7:16:7:34 | JSON.parse(ev.data) | @@ -23,10 +28,12 @@ nodes | tst.js:7:27:7:33 | ev.data | | tst.js:9:5:9:16 | obj[ev.data] | | tst.js:9:5:9:16 | obj[ev.data] | +| tst.js:9:5:9:16 | obj[ev.data] | | tst.js:9:9:9:10 | ev | | tst.js:9:9:9:15 | ev.data | | tst.js:11:5:11:13 | obj[name] | | tst.js:11:5:11:13 | obj[name] | +| tst.js:11:5:11:13 | obj[name] | | tst.js:11:9:11:12 | name | | tst.js:17:9:17:22 | fn | | tst.js:17:9:17:22 | fn | @@ -35,25 +42,34 @@ nodes | tst.js:17:18:17:21 | name | | tst.js:18:5:18:6 | fn | | tst.js:18:5:18:6 | fn | +| tst.js:18:5:18:6 | fn | | tst.js:20:7:20:8 | fn | +| tst.js:20:7:20:8 | fn | +| tst.js:21:7:21:15 | obj[name] | | tst.js:21:7:21:15 | obj[name] | | tst.js:21:7:21:15 | obj[name] | | tst.js:21:11:21:14 | name | | tst.js:22:11:22:12 | fn | +| tst.js:22:11:22:12 | fn | +| tst.js:26:7:26:15 | obj[name] | | tst.js:26:7:26:15 | obj[name] | | tst.js:26:7:26:15 | obj[name] | | tst.js:26:11:26:14 | name | | tst.js:28:7:28:15 | obj[name] | +| tst.js:28:7:28:15 | obj[name] | | tst.js:28:11:28:14 | name | | tst.js:34:9:34:24 | key | | tst.js:34:15:34:24 | "$" + name | | tst.js:34:21:34:24 | name | | tst.js:35:5:35:12 | obj[key] | | tst.js:35:5:35:12 | obj[key] | +| tst.js:35:5:35:12 | obj[key] | | tst.js:35:9:35:11 | key | | tst.js:37:7:37:14 | obj[key] | +| tst.js:37:7:37:14 | obj[key] | | tst.js:37:11:37:13 | key | | tst.js:47:39:47:40 | ev | +| tst.js:47:39:47:40 | ev | | tst.js:48:9:48:39 | name | | tst.js:48:16:48:34 | JSON.parse(ev.data) | | tst.js:48:16:48:39 | JSON.pa ... a).name | @@ -63,8 +79,10 @@ nodes | tst.js:49:14:49:23 | obj2[name] | | tst.js:49:19:49:22 | name | | tst.js:50:5:50:6 | fn | +| tst.js:50:5:50:6 | fn | edges | UnsafeDynamicMethodAccess.js:5:37:5:38 | ev | UnsafeDynamicMethodAccess.js:6:30:6:31 | ev | +| UnsafeDynamicMethodAccess.js:5:37:5:38 | ev | UnsafeDynamicMethodAccess.js:6:30:6:31 | ev | | UnsafeDynamicMethodAccess.js:6:9:6:37 | message | UnsafeDynamicMethodAccess.js:15:9:15:15 | message | | UnsafeDynamicMethodAccess.js:6:19:6:37 | JSON.parse(ev.data) | UnsafeDynamicMethodAccess.js:6:9:6:37 | message | | UnsafeDynamicMethodAccess.js:6:30:6:31 | ev | UnsafeDynamicMethodAccess.js:6:30:6:36 | ev.data | @@ -72,13 +90,20 @@ edges | UnsafeDynamicMethodAccess.js:15:9:15:15 | message | UnsafeDynamicMethodAccess.js:15:9:15:20 | message.name | | UnsafeDynamicMethodAccess.js:15:9:15:20 | message.name | UnsafeDynamicMethodAccess.js:15:5:15:21 | obj[message.name] | | UnsafeDynamicMethodAccess.js:15:9:15:20 | message.name | UnsafeDynamicMethodAccess.js:15:5:15:21 | obj[message.name] | +| UnsafeDynamicMethodAccess.js:15:9:15:20 | message.name | UnsafeDynamicMethodAccess.js:15:5:15:21 | obj[message.name] | +| UnvalidatedDynamicMethodCall.js:14:7:14:41 | action | UnvalidatedDynamicMethodCall.js:15:11:15:16 | action | +| UnvalidatedDynamicMethodCall.js:14:7:14:41 | action | UnvalidatedDynamicMethodCall.js:15:11:15:16 | action | | UnvalidatedDynamicMethodCall.js:14:7:14:41 | action | UnvalidatedDynamicMethodCall.js:15:11:15:16 | action | | UnvalidatedDynamicMethodCall.js:14:7:14:41 | action | UnvalidatedDynamicMethodCall.js:15:11:15:16 | action | | UnvalidatedDynamicMethodCall.js:14:16:14:41 | actions ... action] | UnvalidatedDynamicMethodCall.js:14:7:14:41 | action | | UnvalidatedDynamicMethodCall.js:14:16:14:41 | actions ... action] | UnvalidatedDynamicMethodCall.js:14:7:14:41 | action | | UnvalidatedDynamicMethodCall.js:14:24:14:40 | req.params.action | UnvalidatedDynamicMethodCall.js:14:16:14:41 | actions ... action] | | UnvalidatedDynamicMethodCall.js:14:24:14:40 | req.params.action | UnvalidatedDynamicMethodCall.js:14:16:14:41 | actions ... action] | +| UnvalidatedDynamicMethodCall.js:14:24:14:40 | req.params.action | UnvalidatedDynamicMethodCall.js:14:16:14:41 | actions ... action] | +| UnvalidatedDynamicMethodCall.js:14:24:14:40 | req.params.action | UnvalidatedDynamicMethodCall.js:14:16:14:41 | actions ... action] | | tst.js:6:39:6:40 | ev | tst.js:7:27:7:28 | ev | +| tst.js:6:39:6:40 | ev | tst.js:7:27:7:28 | ev | +| tst.js:6:39:6:40 | ev | tst.js:9:9:9:10 | ev | | tst.js:6:39:6:40 | ev | tst.js:9:9:9:10 | ev | | tst.js:7:9:7:39 | name | tst.js:11:9:11:12 | name | | tst.js:7:9:7:39 | name | tst.js:17:18:17:21 | name | @@ -93,23 +118,29 @@ edges | tst.js:9:9:9:10 | ev | tst.js:9:9:9:15 | ev.data | | tst.js:9:9:9:15 | ev.data | tst.js:9:5:9:16 | obj[ev.data] | | tst.js:9:9:9:15 | ev.data | tst.js:9:5:9:16 | obj[ev.data] | +| tst.js:9:9:9:15 | ev.data | tst.js:9:5:9:16 | obj[ev.data] | +| tst.js:11:9:11:12 | name | tst.js:11:5:11:13 | obj[name] | | tst.js:11:9:11:12 | name | tst.js:11:5:11:13 | obj[name] | | tst.js:11:9:11:12 | name | tst.js:11:5:11:13 | obj[name] | | tst.js:17:9:17:22 | fn | tst.js:18:5:18:6 | fn | | tst.js:17:9:17:22 | fn | tst.js:18:5:18:6 | fn | -| tst.js:17:9:17:22 | fn | tst.js:19:9:19:31 | fn | +| tst.js:17:9:17:22 | fn | tst.js:18:5:18:6 | fn | +| tst.js:17:9:17:22 | fn | tst.js:18:5:18:6 | fn | | tst.js:17:9:17:22 | fn | tst.js:20:7:20:8 | fn | +| tst.js:17:9:17:22 | fn | tst.js:20:7:20:8 | fn | +| tst.js:17:9:17:22 | fn | tst.js:22:11:22:12 | fn | | tst.js:17:9:17:22 | fn | tst.js:22:11:22:12 | fn | | tst.js:17:14:17:22 | obj[name] | tst.js:17:9:17:22 | fn | | tst.js:17:14:17:22 | obj[name] | tst.js:17:9:17:22 | fn | | tst.js:17:18:17:21 | name | tst.js:17:14:17:22 | obj[name] | | tst.js:17:18:17:21 | name | tst.js:17:14:17:22 | obj[name] | -| tst.js:19:9:19:31 | fn | tst.js:20:7:20:8 | fn | -| tst.js:19:9:19:31 | fn | tst.js:22:11:22:12 | fn | +| tst.js:21:11:21:14 | name | tst.js:21:7:21:15 | obj[name] | | tst.js:21:11:21:14 | name | tst.js:21:7:21:15 | obj[name] | | tst.js:21:11:21:14 | name | tst.js:21:7:21:15 | obj[name] | | tst.js:26:11:26:14 | name | tst.js:26:7:26:15 | obj[name] | | tst.js:26:11:26:14 | name | tst.js:26:7:26:15 | obj[name] | +| tst.js:26:11:26:14 | name | tst.js:26:7:26:15 | obj[name] | +| tst.js:28:11:28:14 | name | tst.js:28:7:28:15 | obj[name] | | tst.js:28:11:28:14 | name | tst.js:28:7:28:15 | obj[name] | | tst.js:34:9:34:24 | key | tst.js:35:9:35:11 | key | | tst.js:34:9:34:24 | key | tst.js:37:11:37:13 | key | @@ -117,7 +148,10 @@ edges | tst.js:34:21:34:24 | name | tst.js:34:15:34:24 | "$" + name | | tst.js:35:9:35:11 | key | tst.js:35:5:35:12 | obj[key] | | tst.js:35:9:35:11 | key | tst.js:35:5:35:12 | obj[key] | +| tst.js:35:9:35:11 | key | tst.js:35:5:35:12 | obj[key] | | tst.js:37:11:37:13 | key | tst.js:37:7:37:14 | obj[key] | +| tst.js:37:11:37:13 | key | tst.js:37:7:37:14 | obj[key] | +| tst.js:47:39:47:40 | ev | tst.js:48:27:48:28 | ev | | tst.js:47:39:47:40 | ev | tst.js:48:27:48:28 | ev | | tst.js:48:9:48:39 | name | tst.js:49:19:49:22 | name | | tst.js:48:16:48:34 | JSON.parse(ev.data) | tst.js:48:16:48:39 | JSON.pa ... a).name | @@ -125,27 +159,20 @@ edges | tst.js:48:27:48:28 | ev | tst.js:48:27:48:33 | ev.data | | tst.js:48:27:48:33 | ev.data | tst.js:48:16:48:34 | JSON.parse(ev.data) | | tst.js:49:9:49:23 | fn | tst.js:50:5:50:6 | fn | +| tst.js:49:9:49:23 | fn | tst.js:50:5:50:6 | fn | | tst.js:49:14:49:23 | obj2[name] | tst.js:49:9:49:23 | fn | | tst.js:49:19:49:22 | name | tst.js:49:14:49:23 | obj2[name] | #select | UnsafeDynamicMethodAccess.js:15:5:15:21 | obj[message.name] | UnsafeDynamicMethodAccess.js:5:37:5:38 | ev | UnsafeDynamicMethodAccess.js:15:5:15:21 | obj[message.name] | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | UnsafeDynamicMethodAccess.js:5:37:5:38 | ev | user-controlled | -| UnsafeDynamicMethodAccess.js:15:5:15:21 | obj[message.name] | UnsafeDynamicMethodAccess.js:5:37:5:38 | ev | UnsafeDynamicMethodAccess.js:15:5:15:21 | obj[message.name] | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | UnsafeDynamicMethodAccess.js:5:37:5:38 | ev | user-controlled | -| UnvalidatedDynamicMethodCall.js:15:11:15:16 | action | UnvalidatedDynamicMethodCall.js:14:24:14:40 | req.params.action | UnvalidatedDynamicMethodCall.js:15:11:15:16 | action | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | UnvalidatedDynamicMethodCall.js:14:24:14:40 | req.params.action | user-controlled | | UnvalidatedDynamicMethodCall.js:15:11:15:16 | action | UnvalidatedDynamicMethodCall.js:14:24:14:40 | req.params.action | UnvalidatedDynamicMethodCall.js:15:11:15:16 | action | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | UnvalidatedDynamicMethodCall.js:14:24:14:40 | req.params.action | user-controlled | | tst.js:9:5:9:16 | obj[ev.data] | tst.js:6:39:6:40 | ev | tst.js:9:5:9:16 | obj[ev.data] | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | tst.js:6:39:6:40 | ev | user-controlled | -| tst.js:9:5:9:16 | obj[ev.data] | tst.js:6:39:6:40 | ev | tst.js:9:5:9:16 | obj[ev.data] | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | tst.js:6:39:6:40 | ev | user-controlled | | tst.js:11:5:11:13 | obj[name] | tst.js:6:39:6:40 | ev | tst.js:11:5:11:13 | obj[name] | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | tst.js:6:39:6:40 | ev | user-controlled | -| tst.js:11:5:11:13 | obj[name] | tst.js:6:39:6:40 | ev | tst.js:11:5:11:13 | obj[name] | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | tst.js:6:39:6:40 | ev | user-controlled | -| tst.js:18:5:18:6 | fn | tst.js:6:39:6:40 | ev | tst.js:18:5:18:6 | fn | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | tst.js:6:39:6:40 | ev | user-controlled | | tst.js:18:5:18:6 | fn | tst.js:6:39:6:40 | ev | tst.js:18:5:18:6 | fn | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | tst.js:6:39:6:40 | ev | user-controlled | | tst.js:20:7:20:8 | fn | tst.js:6:39:6:40 | ev | tst.js:20:7:20:8 | fn | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | tst.js:6:39:6:40 | ev | user-controlled | | tst.js:21:7:21:15 | obj[name] | tst.js:6:39:6:40 | ev | tst.js:21:7:21:15 | obj[name] | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | tst.js:6:39:6:40 | ev | user-controlled | -| tst.js:21:7:21:15 | obj[name] | tst.js:6:39:6:40 | ev | tst.js:21:7:21:15 | obj[name] | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | tst.js:6:39:6:40 | ev | user-controlled | | tst.js:22:11:22:12 | fn | tst.js:6:39:6:40 | ev | tst.js:22:11:22:12 | fn | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | tst.js:6:39:6:40 | ev | user-controlled | | tst.js:26:7:26:15 | obj[name] | tst.js:6:39:6:40 | ev | tst.js:26:7:26:15 | obj[name] | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | tst.js:6:39:6:40 | ev | user-controlled | -| tst.js:26:7:26:15 | obj[name] | tst.js:6:39:6:40 | ev | tst.js:26:7:26:15 | obj[name] | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | tst.js:6:39:6:40 | ev | user-controlled | | tst.js:28:7:28:15 | obj[name] | tst.js:6:39:6:40 | ev | tst.js:28:7:28:15 | obj[name] | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | tst.js:6:39:6:40 | ev | user-controlled | | tst.js:35:5:35:12 | obj[key] | tst.js:6:39:6:40 | ev | tst.js:35:5:35:12 | obj[key] | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | tst.js:6:39:6:40 | ev | user-controlled | -| tst.js:35:5:35:12 | obj[key] | tst.js:6:39:6:40 | ev | tst.js:35:5:35:12 | obj[key] | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | tst.js:6:39:6:40 | ev | user-controlled | | tst.js:37:7:37:14 | obj[key] | tst.js:6:39:6:40 | ev | tst.js:37:7:37:14 | obj[key] | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | tst.js:6:39:6:40 | ev | user-controlled | | tst.js:50:5:50:6 | fn | tst.js:47:39:47:40 | ev | tst.js:50:5:50:6 | fn | Invocation of method with $@ name may dispatch to unexpected target and cause an exception. | tst.js:47:39:47:40 | ev | user-controlled | diff --git a/javascript/ql/test/query-tests/Security/CWE-776/XmlBomb.expected b/javascript/ql/test/query-tests/Security/CWE-776/XmlBomb.expected index 483d2d585c7..77b9f6f86ca 100644 --- a/javascript/ql/test/query-tests/Security/CWE-776/XmlBomb.expected +++ b/javascript/ql/test/query-tests/Security/CWE-776/XmlBomb.expected @@ -1,35 +1,66 @@ nodes | closure.js:2:7:2:36 | src | | closure.js:2:13:2:29 | document.location | +| closure.js:2:13:2:29 | document.location | | closure.js:2:13:2:36 | documen ... .search | | closure.js:4:24:4:26 | src | +| closure.js:4:24:4:26 | src | | domparser.js:2:7:2:36 | src | | domparser.js:2:13:2:29 | document.location | +| domparser.js:2:13:2:29 | document.location | | domparser.js:2:13:2:36 | documen ... .search | | domparser.js:6:37:6:39 | src | +| domparser.js:6:37:6:39 | src | +| domparser.js:11:55:11:57 | src | | domparser.js:11:55:11:57 | src | | domparser.js:14:57:14:59 | src | +| domparser.js:14:57:14:59 | src | +| expat.js:7:16:7:36 | req.par ... e-xml") | +| expat.js:7:16:7:36 | req.par ... e-xml") | | expat.js:7:16:7:36 | req.par ... e-xml") | | jquery.js:2:7:2:36 | src | | jquery.js:2:13:2:29 | document.location | +| jquery.js:2:13:2:29 | document.location | | jquery.js:2:13:2:36 | documen ... .search | | jquery.js:5:14:5:16 | src | +| jquery.js:5:14:5:16 | src | +| libxml.js:6:21:6:41 | req.par ... e-xml") | +| libxml.js:6:21:6:41 | req.par ... e-xml") | | libxml.js:6:21:6:41 | req.par ... e-xml") | | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | +| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | +| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | +| libxml.sax.js:7:22:7:42 | req.par ... e-xml") | +| libxml.sax.js:7:22:7:42 | req.par ... e-xml") | +| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | +| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | edges | closure.js:2:7:2:36 | src | closure.js:4:24:4:26 | src | +| closure.js:2:7:2:36 | src | closure.js:4:24:4:26 | src | +| closure.js:2:13:2:29 | document.location | closure.js:2:13:2:36 | documen ... .search | | closure.js:2:13:2:29 | document.location | closure.js:2:13:2:36 | documen ... .search | | closure.js:2:13:2:36 | documen ... .search | closure.js:2:7:2:36 | src | | domparser.js:2:7:2:36 | src | domparser.js:6:37:6:39 | src | +| domparser.js:2:7:2:36 | src | domparser.js:6:37:6:39 | src | +| domparser.js:2:7:2:36 | src | domparser.js:11:55:11:57 | src | | domparser.js:2:7:2:36 | src | domparser.js:11:55:11:57 | src | | domparser.js:2:7:2:36 | src | domparser.js:14:57:14:59 | src | +| domparser.js:2:7:2:36 | src | domparser.js:14:57:14:59 | src | +| domparser.js:2:13:2:29 | document.location | domparser.js:2:13:2:36 | documen ... .search | | domparser.js:2:13:2:29 | document.location | domparser.js:2:13:2:36 | documen ... .search | | domparser.js:2:13:2:36 | documen ... .search | domparser.js:2:7:2:36 | src | +| expat.js:7:16:7:36 | req.par ... e-xml") | expat.js:7:16:7:36 | req.par ... e-xml") | +| jquery.js:2:7:2:36 | src | jquery.js:5:14:5:16 | src | | jquery.js:2:7:2:36 | src | jquery.js:5:14:5:16 | src | | jquery.js:2:13:2:29 | document.location | jquery.js:2:13:2:36 | documen ... .search | +| jquery.js:2:13:2:29 | document.location | jquery.js:2:13:2:36 | documen ... .search | | jquery.js:2:13:2:36 | documen ... .search | jquery.js:2:7:2:36 | src | +| libxml.js:6:21:6:41 | req.par ... e-xml") | libxml.js:6:21:6:41 | req.par ... e-xml") | +| libxml.noent.js:6:21:6:41 | req.par ... e-xml") | libxml.noent.js:6:21:6:41 | req.par ... e-xml") | +| libxml.sax.js:7:22:7:42 | req.par ... e-xml") | libxml.sax.js:7:22:7:42 | req.par ... e-xml") | +| libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | libxml.saxpush.js:7:15:7:35 | req.par ... e-xml") | #select | closure.js:4:24:4:26 | src | closure.js:2:13:2:29 | document.location | closure.js:4:24:4:26 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | closure.js:2:13:2:29 | document.location | user-provided value | | domparser.js:6:37:6:39 | src | domparser.js:2:13:2:29 | document.location | domparser.js:6:37:6:39 | src | A $@ is parsed as XML without guarding against uncontrolled entity expansion. | domparser.js:2:13:2:29 | document.location | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected index 2542f187d84..e2c1a2ded5c 100644 --- a/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected +++ b/javascript/ql/test/query-tests/Security/CWE-798/HardcodedCredentials.expected @@ -1,61 +1,225 @@ nodes | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | +| HardcodedCredentials.js:5:15:5:22 | 'dbuser' | +| HardcodedCredentials.js:5:15:5:22 | 'dbuser' | +| HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' | +| HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' | | HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' | | HardcodedCredentials.js:15:36:15:50 | "user:abcdefgh" | +| HardcodedCredentials.js:15:36:15:50 | "user:abcdefgh" | +| HardcodedCredentials.js:15:36:15:50 | "user:abcdefgh" | +| HardcodedCredentials.js:16:37:16:51 | "user:abcdefgh" | +| HardcodedCredentials.js:16:37:16:51 | "user:abcdefgh" | | HardcodedCredentials.js:16:37:16:51 | "user:abcdefgh" | | HardcodedCredentials.js:18:16:18:30 | "user:abcdefgh" | +| HardcodedCredentials.js:18:16:18:30 | "user:abcdefgh" | +| HardcodedCredentials.js:20:36:20:51 | getCredentials() | | HardcodedCredentials.js:20:36:20:51 | getCredentials() | | HardcodedCredentials.js:27:25:27:31 | 'admin' | +| HardcodedCredentials.js:27:25:27:31 | 'admin' | +| HardcodedCredentials.js:27:25:27:31 | 'admin' | +| HardcodedCredentials.js:27:34:27:43 | 'abcdefgh' | +| HardcodedCredentials.js:27:34:27:43 | 'abcdefgh' | | HardcodedCredentials.js:27:34:27:43 | 'abcdefgh' | | HardcodedCredentials.js:29:11:29:30 | 'unknown-admin-name' | +| HardcodedCredentials.js:29:11:29:30 | 'unknown-admin-name' | +| HardcodedCredentials.js:29:11:29:30 | 'unknown-admin-name' | +| HardcodedCredentials.js:29:35:29:44 | 'abcdefgh' | +| HardcodedCredentials.js:29:35:29:44 | 'abcdefgh' | | HardcodedCredentials.js:29:35:29:44 | 'abcdefgh' | | HardcodedCredentials.js:35:15:35:24 | 'username' | +| HardcodedCredentials.js:35:15:35:24 | 'username' | +| HardcodedCredentials.js:35:15:35:24 | 'username' | +| HardcodedCredentials.js:35:27:35:36 | 'abcdefgh' | +| HardcodedCredentials.js:35:27:35:36 | 'abcdefgh' | | HardcodedCredentials.js:35:27:35:36 | 'abcdefgh' | | HardcodedCredentials.js:41:38:41:47 | 'username' | +| HardcodedCredentials.js:41:38:41:47 | 'username' | +| HardcodedCredentials.js:41:38:41:47 | 'username' | +| HardcodedCredentials.js:41:67:41:76 | 'abcdefgh' | +| HardcodedCredentials.js:41:67:41:76 | 'abcdefgh' | | HardcodedCredentials.js:41:67:41:76 | 'abcdefgh' | | HardcodedCredentials.js:42:35:42:44 | 'username' | +| HardcodedCredentials.js:42:35:42:44 | 'username' | +| HardcodedCredentials.js:42:35:42:44 | 'username' | +| HardcodedCredentials.js:42:64:42:73 | 'abcdefgh' | +| HardcodedCredentials.js:42:64:42:73 | 'abcdefgh' | | HardcodedCredentials.js:42:64:42:73 | 'abcdefgh' | | HardcodedCredentials.js:44:34:44:43 | 'username' | +| HardcodedCredentials.js:44:34:44:43 | 'username' | +| HardcodedCredentials.js:44:34:44:43 | 'username' | +| HardcodedCredentials.js:44:63:44:72 | 'abcdefgh' | +| HardcodedCredentials.js:44:63:44:72 | 'abcdefgh' | | HardcodedCredentials.js:44:63:44:72 | 'abcdefgh' | | HardcodedCredentials.js:46:25:46:34 | 'abcdefgh' | +| HardcodedCredentials.js:46:25:46:34 | 'abcdefgh' | +| HardcodedCredentials.js:46:25:46:34 | 'abcdefgh' | +| HardcodedCredentials.js:53:27:53:36 | 'username' | +| HardcodedCredentials.js:53:27:53:36 | 'username' | | HardcodedCredentials.js:53:27:53:36 | 'username' | | HardcodedCredentials.js:53:39:53:48 | 'abcdefgh' | +| HardcodedCredentials.js:53:39:53:48 | 'abcdefgh' | +| HardcodedCredentials.js:53:39:53:48 | 'abcdefgh' | +| HardcodedCredentials.js:56:21:56:30 | 'username' | +| HardcodedCredentials.js:56:21:56:30 | 'username' | | HardcodedCredentials.js:56:21:56:30 | 'username' | | HardcodedCredentials.js:57:21:57:30 | 'abcdefgh' | +| HardcodedCredentials.js:57:21:57:30 | 'abcdefgh' | +| HardcodedCredentials.js:57:21:57:30 | 'abcdefgh' | +| HardcodedCredentials.js:61:42:61:54 | 'bearerToken' | +| HardcodedCredentials.js:61:42:61:54 | 'bearerToken' | | HardcodedCredentials.js:61:42:61:54 | 'bearerToken' | | HardcodedCredentials.js:65:23:65:35 | 'bearerToken' | +| HardcodedCredentials.js:65:23:65:35 | 'bearerToken' | +| HardcodedCredentials.js:65:23:65:35 | 'bearerToken' | +| HardcodedCredentials.js:69:28:69:37 | 'username' | +| HardcodedCredentials.js:69:28:69:37 | 'username' | | HardcodedCredentials.js:69:28:69:37 | 'username' | | HardcodedCredentials.js:69:40:69:49 | 'abcdefgh' | +| HardcodedCredentials.js:69:40:69:49 | 'abcdefgh' | +| HardcodedCredentials.js:69:40:69:49 | 'abcdefgh' | +| HardcodedCredentials.js:70:28:70:37 | 'username' | +| HardcodedCredentials.js:70:28:70:37 | 'username' | | HardcodedCredentials.js:70:28:70:37 | 'username' | | HardcodedCredentials.js:70:40:70:49 | 'abcdefgh' | +| HardcodedCredentials.js:70:40:70:49 | 'abcdefgh' | +| HardcodedCredentials.js:70:40:70:49 | 'abcdefgh' | +| HardcodedCredentials.js:72:23:72:32 | 'username' | +| HardcodedCredentials.js:72:23:72:32 | 'username' | | HardcodedCredentials.js:72:23:72:32 | 'username' | | HardcodedCredentials.js:72:35:72:44 | 'abcdefgh' | +| HardcodedCredentials.js:72:35:72:44 | 'abcdefgh' | +| HardcodedCredentials.js:72:35:72:44 | 'abcdefgh' | +| HardcodedCredentials.js:75:21:75:30 | 'username' | +| HardcodedCredentials.js:75:21:75:30 | 'username' | | HardcodedCredentials.js:75:21:75:30 | 'username' | | HardcodedCredentials.js:76:21:76:30 | 'abcdefgh' | +| HardcodedCredentials.js:76:21:76:30 | 'abcdefgh' | +| HardcodedCredentials.js:76:21:76:30 | 'abcdefgh' | +| HardcodedCredentials.js:84:38:84:47 | 'username' | +| HardcodedCredentials.js:84:38:84:47 | 'username' | | HardcodedCredentials.js:84:38:84:47 | 'username' | | HardcodedCredentials.js:84:50:84:59 | 'abcdefgh' | +| HardcodedCredentials.js:84:50:84:59 | 'abcdefgh' | +| HardcodedCredentials.js:84:50:84:59 | 'abcdefgh' | +| HardcodedCredentials.js:86:44:86:53 | 'username' | +| HardcodedCredentials.js:86:44:86:53 | 'username' | | HardcodedCredentials.js:86:44:86:53 | 'username' | | HardcodedCredentials.js:86:56:86:65 | 'abcdefgh' | +| HardcodedCredentials.js:86:56:86:65 | 'abcdefgh' | +| HardcodedCredentials.js:86:56:86:65 | 'abcdefgh' | +| HardcodedCredentials.js:91:25:91:31 | 'TOKEN' | +| HardcodedCredentials.js:91:25:91:31 | 'TOKEN' | | HardcodedCredentials.js:91:25:91:31 | 'TOKEN' | | HardcodedCredentials.js:98:18:98:21 | 'x1' | +| HardcodedCredentials.js:98:18:98:21 | 'x1' | +| HardcodedCredentials.js:98:18:98:21 | 'x1' | +| HardcodedCredentials.js:99:16:99:19 | 'x2' | +| HardcodedCredentials.js:99:16:99:19 | 'x2' | | HardcodedCredentials.js:99:16:99:19 | 'x2' | | HardcodedCredentials.js:100:25:100:28 | 'x3' | +| HardcodedCredentials.js:100:25:100:28 | 'x3' | +| HardcodedCredentials.js:100:25:100:28 | 'x3' | +| HardcodedCredentials.js:101:19:101:22 | 'x4' | +| HardcodedCredentials.js:101:19:101:22 | 'x4' | | HardcodedCredentials.js:101:19:101:22 | 'x4' | | HardcodedCredentials.js:102:14:102:23 | 'abcdefgh' | +| HardcodedCredentials.js:102:14:102:23 | 'abcdefgh' | +| HardcodedCredentials.js:102:14:102:23 | 'abcdefgh' | +| HardcodedCredentials.js:103:17:103:26 | 'abcdefgh' | +| HardcodedCredentials.js:103:17:103:26 | 'abcdefgh' | | HardcodedCredentials.js:103:17:103:26 | 'abcdefgh' | | HardcodedCredentials.js:104:27:104:36 | 'abcdefgh' | +| HardcodedCredentials.js:104:27:104:36 | 'abcdefgh' | +| HardcodedCredentials.js:104:27:104:36 | 'abcdefgh' | +| HardcodedCredentials.js:105:19:105:28 | 'abcdefgh' | +| HardcodedCredentials.js:105:19:105:28 | 'abcdefgh' | | HardcodedCredentials.js:105:19:105:28 | 'abcdefgh' | | HardcodedCredentials.js:106:16:106:25 | 'abcdefgh' | +| HardcodedCredentials.js:106:16:106:25 | 'abcdefgh' | +| HardcodedCredentials.js:106:16:106:25 | 'abcdefgh' | +| HardcodedCredentials.js:112:19:112:22 | 'x5' | +| HardcodedCredentials.js:112:19:112:22 | 'x5' | | HardcodedCredentials.js:112:19:112:22 | 'x5' | | HardcodedCredentials.js:113:19:113:28 | 'abcdefgh' | +| HardcodedCredentials.js:113:19:113:28 | 'abcdefgh' | +| HardcodedCredentials.js:113:19:113:28 | 'abcdefgh' | +| HardcodedCredentials.js:130:44:130:53 | 'abcdefgh' | +| HardcodedCredentials.js:130:44:130:53 | 'abcdefgh' | | HardcodedCredentials.js:130:44:130:53 | 'abcdefgh' | | HardcodedCredentials.js:131:52:131:61 | 'abcdefgh' | +| HardcodedCredentials.js:131:52:131:61 | 'abcdefgh' | +| HardcodedCredentials.js:131:52:131:61 | 'abcdefgh' | +| HardcodedCredentials.js:135:41:135:50 | "abcdefgh" | +| HardcodedCredentials.js:135:41:135:50 | "abcdefgh" | | HardcodedCredentials.js:135:41:135:50 | "abcdefgh" | | HardcodedCredentials.js:160:38:160:48 | "change_me" | +| HardcodedCredentials.js:160:38:160:48 | "change_me" | +| HardcodedCredentials.js:160:38:160:48 | "change_me" | +| HardcodedCredentials.js:161:41:161:51 | 'change_me' | +| HardcodedCredentials.js:161:41:161:51 | 'change_me' | | HardcodedCredentials.js:161:41:161:51 | 'change_me' | | HardcodedCredentials.js:164:35:164:45 | 'change_me' | +| HardcodedCredentials.js:164:35:164:45 | 'change_me' | +| HardcodedCredentials.js:164:35:164:45 | 'change_me' | edges +| HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | +| HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' | HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' | +| HardcodedCredentials.js:15:36:15:50 | "user:abcdefgh" | HardcodedCredentials.js:15:36:15:50 | "user:abcdefgh" | +| HardcodedCredentials.js:16:37:16:51 | "user:abcdefgh" | HardcodedCredentials.js:16:37:16:51 | "user:abcdefgh" | | HardcodedCredentials.js:18:16:18:30 | "user:abcdefgh" | HardcodedCredentials.js:20:36:20:51 | getCredentials() | +| HardcodedCredentials.js:18:16:18:30 | "user:abcdefgh" | HardcodedCredentials.js:20:36:20:51 | getCredentials() | +| HardcodedCredentials.js:18:16:18:30 | "user:abcdefgh" | HardcodedCredentials.js:20:36:20:51 | getCredentials() | +| HardcodedCredentials.js:18:16:18:30 | "user:abcdefgh" | HardcodedCredentials.js:20:36:20:51 | getCredentials() | +| HardcodedCredentials.js:27:25:27:31 | 'admin' | HardcodedCredentials.js:27:25:27:31 | 'admin' | +| HardcodedCredentials.js:27:34:27:43 | 'abcdefgh' | HardcodedCredentials.js:27:34:27:43 | 'abcdefgh' | +| HardcodedCredentials.js:29:11:29:30 | 'unknown-admin-name' | HardcodedCredentials.js:29:11:29:30 | 'unknown-admin-name' | +| HardcodedCredentials.js:29:35:29:44 | 'abcdefgh' | HardcodedCredentials.js:29:35:29:44 | 'abcdefgh' | +| HardcodedCredentials.js:35:15:35:24 | 'username' | HardcodedCredentials.js:35:15:35:24 | 'username' | +| HardcodedCredentials.js:35:27:35:36 | 'abcdefgh' | HardcodedCredentials.js:35:27:35:36 | 'abcdefgh' | +| HardcodedCredentials.js:41:38:41:47 | 'username' | HardcodedCredentials.js:41:38:41:47 | 'username' | +| HardcodedCredentials.js:41:67:41:76 | 'abcdefgh' | HardcodedCredentials.js:41:67:41:76 | 'abcdefgh' | +| HardcodedCredentials.js:42:35:42:44 | 'username' | HardcodedCredentials.js:42:35:42:44 | 'username' | +| HardcodedCredentials.js:42:64:42:73 | 'abcdefgh' | HardcodedCredentials.js:42:64:42:73 | 'abcdefgh' | +| HardcodedCredentials.js:44:34:44:43 | 'username' | HardcodedCredentials.js:44:34:44:43 | 'username' | +| HardcodedCredentials.js:44:63:44:72 | 'abcdefgh' | HardcodedCredentials.js:44:63:44:72 | 'abcdefgh' | +| HardcodedCredentials.js:46:25:46:34 | 'abcdefgh' | HardcodedCredentials.js:46:25:46:34 | 'abcdefgh' | +| HardcodedCredentials.js:53:27:53:36 | 'username' | HardcodedCredentials.js:53:27:53:36 | 'username' | +| HardcodedCredentials.js:53:39:53:48 | 'abcdefgh' | HardcodedCredentials.js:53:39:53:48 | 'abcdefgh' | +| HardcodedCredentials.js:56:21:56:30 | 'username' | HardcodedCredentials.js:56:21:56:30 | 'username' | +| HardcodedCredentials.js:57:21:57:30 | 'abcdefgh' | HardcodedCredentials.js:57:21:57:30 | 'abcdefgh' | +| HardcodedCredentials.js:61:42:61:54 | 'bearerToken' | HardcodedCredentials.js:61:42:61:54 | 'bearerToken' | +| HardcodedCredentials.js:65:23:65:35 | 'bearerToken' | HardcodedCredentials.js:65:23:65:35 | 'bearerToken' | +| HardcodedCredentials.js:69:28:69:37 | 'username' | HardcodedCredentials.js:69:28:69:37 | 'username' | +| HardcodedCredentials.js:69:40:69:49 | 'abcdefgh' | HardcodedCredentials.js:69:40:69:49 | 'abcdefgh' | +| HardcodedCredentials.js:70:28:70:37 | 'username' | HardcodedCredentials.js:70:28:70:37 | 'username' | +| HardcodedCredentials.js:70:40:70:49 | 'abcdefgh' | HardcodedCredentials.js:70:40:70:49 | 'abcdefgh' | +| HardcodedCredentials.js:72:23:72:32 | 'username' | HardcodedCredentials.js:72:23:72:32 | 'username' | +| HardcodedCredentials.js:72:35:72:44 | 'abcdefgh' | HardcodedCredentials.js:72:35:72:44 | 'abcdefgh' | +| HardcodedCredentials.js:75:21:75:30 | 'username' | HardcodedCredentials.js:75:21:75:30 | 'username' | +| HardcodedCredentials.js:76:21:76:30 | 'abcdefgh' | HardcodedCredentials.js:76:21:76:30 | 'abcdefgh' | +| HardcodedCredentials.js:84:38:84:47 | 'username' | HardcodedCredentials.js:84:38:84:47 | 'username' | +| HardcodedCredentials.js:84:50:84:59 | 'abcdefgh' | HardcodedCredentials.js:84:50:84:59 | 'abcdefgh' | +| HardcodedCredentials.js:86:44:86:53 | 'username' | HardcodedCredentials.js:86:44:86:53 | 'username' | +| HardcodedCredentials.js:86:56:86:65 | 'abcdefgh' | HardcodedCredentials.js:86:56:86:65 | 'abcdefgh' | +| HardcodedCredentials.js:91:25:91:31 | 'TOKEN' | HardcodedCredentials.js:91:25:91:31 | 'TOKEN' | +| HardcodedCredentials.js:98:18:98:21 | 'x1' | HardcodedCredentials.js:98:18:98:21 | 'x1' | +| HardcodedCredentials.js:99:16:99:19 | 'x2' | HardcodedCredentials.js:99:16:99:19 | 'x2' | +| HardcodedCredentials.js:100:25:100:28 | 'x3' | HardcodedCredentials.js:100:25:100:28 | 'x3' | +| HardcodedCredentials.js:101:19:101:22 | 'x4' | HardcodedCredentials.js:101:19:101:22 | 'x4' | +| HardcodedCredentials.js:102:14:102:23 | 'abcdefgh' | HardcodedCredentials.js:102:14:102:23 | 'abcdefgh' | +| HardcodedCredentials.js:103:17:103:26 | 'abcdefgh' | HardcodedCredentials.js:103:17:103:26 | 'abcdefgh' | +| HardcodedCredentials.js:104:27:104:36 | 'abcdefgh' | HardcodedCredentials.js:104:27:104:36 | 'abcdefgh' | +| HardcodedCredentials.js:105:19:105:28 | 'abcdefgh' | HardcodedCredentials.js:105:19:105:28 | 'abcdefgh' | +| HardcodedCredentials.js:106:16:106:25 | 'abcdefgh' | HardcodedCredentials.js:106:16:106:25 | 'abcdefgh' | +| HardcodedCredentials.js:112:19:112:22 | 'x5' | HardcodedCredentials.js:112:19:112:22 | 'x5' | +| HardcodedCredentials.js:113:19:113:28 | 'abcdefgh' | HardcodedCredentials.js:113:19:113:28 | 'abcdefgh' | +| HardcodedCredentials.js:130:44:130:53 | 'abcdefgh' | HardcodedCredentials.js:130:44:130:53 | 'abcdefgh' | +| HardcodedCredentials.js:131:52:131:61 | 'abcdefgh' | HardcodedCredentials.js:131:52:131:61 | 'abcdefgh' | +| HardcodedCredentials.js:135:41:135:50 | "abcdefgh" | HardcodedCredentials.js:135:41:135:50 | "abcdefgh" | +| HardcodedCredentials.js:160:38:160:48 | "change_me" | HardcodedCredentials.js:160:38:160:48 | "change_me" | +| HardcodedCredentials.js:161:41:161:51 | 'change_me' | HardcodedCredentials.js:161:41:161:51 | 'change_me' | +| HardcodedCredentials.js:164:35:164:45 | 'change_me' | HardcodedCredentials.js:164:35:164:45 | 'change_me' | #select | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | The hard-coded value "dbuser" is used as $@. | HardcodedCredentials.js:5:15:5:22 | 'dbuser' | user name | | HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' | HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' | HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' | The hard-coded value "abcdefgh" is used as $@. | HardcodedCredentials.js:8:19:8:28 | 'abcdefgh' | password | diff --git a/javascript/ql/test/query-tests/Security/CWE-807/ConditionalBypass.expected b/javascript/ql/test/query-tests/Security/CWE-807/ConditionalBypass.expected index 8c2d94e0a9d..ff45448452c 100644 --- a/javascript/ql/test/query-tests/Security/CWE-807/ConditionalBypass.expected +++ b/javascript/ql/test/query-tests/Security/CWE-807/ConditionalBypass.expected @@ -1,43 +1,106 @@ nodes | tst.js:9:8:9:26 | req.params.shutDown | +| tst.js:9:8:9:26 | req.params.shutDown | +| tst.js:9:8:9:26 | req.params.shutDown | | tst.js:14:9:14:19 | req.cookies | +| tst.js:14:9:14:19 | req.cookies | +| tst.js:14:9:14:30 | req.coo ... inThing | | tst.js:14:9:14:30 | req.coo ... inThing | | tst.js:30:9:30:37 | v3 | | tst.js:30:14:30:37 | id(req. ... okieId) | | tst.js:30:17:30:27 | req.cookies | +| tst.js:30:17:30:27 | req.cookies | | tst.js:30:17:30:36 | req.cookies.cookieId | | tst.js:31:9:31:10 | v3 | +| tst.js:31:9:31:10 | v3 | +| tst.js:37:13:37:23 | req.cookies | | tst.js:37:13:37:23 | req.cookies | | tst.js:37:13:37:32 | req.cookies.cookieId | +| tst.js:37:13:37:32 | req.cookies.cookieId | +| tst.js:43:9:43:19 | req.cookies | | tst.js:43:9:43:19 | req.cookies | | tst.js:43:9:43:28 | req.cookies.cookieId | +| tst.js:43:9:43:28 | req.cookies.cookieId | +| tst.js:50:8:50:23 | req.params.login | +| tst.js:50:8:50:23 | req.params.login | | tst.js:50:8:50:23 | req.params.login | | tst.js:65:8:65:23 | req.params.login | +| tst.js:65:8:65:23 | req.params.login | +| tst.js:65:8:65:23 | req.params.login | +| tst.js:70:9:70:19 | req.cookies | | tst.js:70:9:70:19 | req.cookies | | tst.js:70:9:70:28 | req.cookies.cookieId | +| tst.js:70:9:70:28 | req.cookies.cookieId | +| tst.js:70:34:70:53 | req.params.requestId | +| tst.js:70:34:70:53 | req.params.requestId | | tst.js:70:34:70:53 | req.params.requestId | | tst.js:75:14:75:24 | req.cookies | +| tst.js:75:14:75:24 | req.cookies | +| tst.js:75:14:75:33 | req.cookies.cookieId | | tst.js:75:14:75:33 | req.cookies.cookieId | | tst.js:75:39:75:58 | req.params.requestId | +| tst.js:75:39:75:58 | req.params.requestId | +| tst.js:75:39:75:58 | req.params.requestId | +| tst.js:90:9:90:19 | req.cookies | | tst.js:90:9:90:19 | req.cookies | | tst.js:90:9:90:28 | req.cookies.cookieId | +| tst.js:90:9:90:28 | req.cookies.cookieId | +| tst.js:90:9:90:41 | req.coo ... secret" | | tst.js:90:9:90:41 | req.coo ... secret" | | tst.js:104:10:104:17 | req.body | +| tst.js:104:10:104:17 | req.body | +| tst.js:104:10:104:17 | req.body | +| tst.js:111:13:111:32 | req.query.vulnerable | +| tst.js:111:13:111:32 | req.query.vulnerable | | tst.js:111:13:111:32 | req.query.vulnerable | | tst.js:118:13:118:32 | req.query.vulnerable | +| tst.js:118:13:118:32 | req.query.vulnerable | +| tst.js:118:13:118:32 | req.query.vulnerable | +| tst.js:126:13:126:32 | req.query.vulnerable | +| tst.js:126:13:126:32 | req.query.vulnerable | | tst.js:126:13:126:32 | req.query.vulnerable | edges +| tst.js:9:8:9:26 | req.params.shutDown | tst.js:9:8:9:26 | req.params.shutDown | | tst.js:14:9:14:19 | req.cookies | tst.js:14:9:14:30 | req.coo ... inThing | +| tst.js:14:9:14:19 | req.cookies | tst.js:14:9:14:30 | req.coo ... inThing | +| tst.js:14:9:14:19 | req.cookies | tst.js:14:9:14:30 | req.coo ... inThing | +| tst.js:14:9:14:19 | req.cookies | tst.js:14:9:14:30 | req.coo ... inThing | +| tst.js:30:9:30:37 | v3 | tst.js:31:9:31:10 | v3 | | tst.js:30:9:30:37 | v3 | tst.js:31:9:31:10 | v3 | | tst.js:30:14:30:37 | id(req. ... okieId) | tst.js:30:9:30:37 | v3 | | tst.js:30:17:30:27 | req.cookies | tst.js:30:17:30:36 | req.cookies.cookieId | +| tst.js:30:17:30:27 | req.cookies | tst.js:30:17:30:36 | req.cookies.cookieId | | tst.js:30:17:30:36 | req.cookies.cookieId | tst.js:30:14:30:37 | id(req. ... okieId) | | tst.js:37:13:37:23 | req.cookies | tst.js:37:13:37:32 | req.cookies.cookieId | +| tst.js:37:13:37:23 | req.cookies | tst.js:37:13:37:32 | req.cookies.cookieId | +| tst.js:37:13:37:23 | req.cookies | tst.js:37:13:37:32 | req.cookies.cookieId | +| tst.js:37:13:37:23 | req.cookies | tst.js:37:13:37:32 | req.cookies.cookieId | | tst.js:43:9:43:19 | req.cookies | tst.js:43:9:43:28 | req.cookies.cookieId | +| tst.js:43:9:43:19 | req.cookies | tst.js:43:9:43:28 | req.cookies.cookieId | +| tst.js:43:9:43:19 | req.cookies | tst.js:43:9:43:28 | req.cookies.cookieId | +| tst.js:43:9:43:19 | req.cookies | tst.js:43:9:43:28 | req.cookies.cookieId | +| tst.js:50:8:50:23 | req.params.login | tst.js:50:8:50:23 | req.params.login | +| tst.js:65:8:65:23 | req.params.login | tst.js:65:8:65:23 | req.params.login | | tst.js:70:9:70:19 | req.cookies | tst.js:70:9:70:28 | req.cookies.cookieId | +| tst.js:70:9:70:19 | req.cookies | tst.js:70:9:70:28 | req.cookies.cookieId | +| tst.js:70:9:70:19 | req.cookies | tst.js:70:9:70:28 | req.cookies.cookieId | +| tst.js:70:9:70:19 | req.cookies | tst.js:70:9:70:28 | req.cookies.cookieId | +| tst.js:70:34:70:53 | req.params.requestId | tst.js:70:34:70:53 | req.params.requestId | | tst.js:75:14:75:24 | req.cookies | tst.js:75:14:75:33 | req.cookies.cookieId | +| tst.js:75:14:75:24 | req.cookies | tst.js:75:14:75:33 | req.cookies.cookieId | +| tst.js:75:14:75:24 | req.cookies | tst.js:75:14:75:33 | req.cookies.cookieId | +| tst.js:75:14:75:24 | req.cookies | tst.js:75:14:75:33 | req.cookies.cookieId | +| tst.js:75:39:75:58 | req.params.requestId | tst.js:75:39:75:58 | req.params.requestId | +| tst.js:90:9:90:19 | req.cookies | tst.js:90:9:90:28 | req.cookies.cookieId | +| tst.js:90:9:90:19 | req.cookies | tst.js:90:9:90:28 | req.cookies.cookieId | +| tst.js:90:9:90:19 | req.cookies | tst.js:90:9:90:28 | req.cookies.cookieId | | tst.js:90:9:90:19 | req.cookies | tst.js:90:9:90:28 | req.cookies.cookieId | | tst.js:90:9:90:28 | req.cookies.cookieId | tst.js:90:9:90:41 | req.coo ... secret" | +| tst.js:90:9:90:28 | req.cookies.cookieId | tst.js:90:9:90:41 | req.coo ... secret" | +| tst.js:104:10:104:17 | req.body | tst.js:104:10:104:17 | req.body | +| tst.js:111:13:111:32 | req.query.vulnerable | tst.js:111:13:111:32 | req.query.vulnerable | +| tst.js:118:13:118:32 | req.query.vulnerable | tst.js:118:13:118:32 | req.query.vulnerable | +| tst.js:126:13:126:32 | req.query.vulnerable | tst.js:126:13:126:32 | req.query.vulnerable | #select | tst.js:9:8:9:26 | req.params.shutDown | tst.js:9:8:9:26 | req.params.shutDown | tst.js:9:8:9:26 | req.params.shutDown | This condition guards a sensitive $@, but $@ controls it. | tst.js:11:9:11:22 | process.exit() | action | tst.js:9:8:9:26 | req.params.shutDown | a user-provided value | | tst.js:14:9:14:30 | req.coo ... inThing | tst.js:14:9:14:19 | req.cookies | tst.js:14:9:14:30 | req.coo ... inThing | This condition guards a sensitive $@, but $@ controls it. | tst.js:16:9:16:17 | o.login() | action | tst.js:14:9:14:19 | req.cookies | a user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-834/LoopBoundInjection.expected b/javascript/ql/test/query-tests/Security/CWE-834/LoopBoundInjection.expected index dec60a2bbb8..7f1b07adbe4 100644 --- a/javascript/ql/test/query-tests/Security/CWE-834/LoopBoundInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-834/LoopBoundInjection.expected @@ -1,49 +1,85 @@ nodes | LoopBoundInjectionBad.js:8:13:8:20 | req.body | +| LoopBoundInjectionBad.js:8:13:8:20 | req.body | +| LoopBoundInjectionBad.js:10:15:10:22 | req.body | | LoopBoundInjectionBad.js:10:15:10:22 | req.body | | LoopBoundInjectionBad.js:12:25:12:32 | req.body | +| LoopBoundInjectionBad.js:12:25:12:32 | req.body | +| LoopBoundInjectionBad.js:14:19:14:26 | req.body | | LoopBoundInjectionBad.js:14:19:14:26 | req.body | | LoopBoundInjectionBad.js:17:18:17:20 | val | | LoopBoundInjectionBad.js:20:25:20:27 | val | +| LoopBoundInjectionBad.js:20:25:20:27 | val | | LoopBoundInjectionBad.js:25:20:25:22 | val | | LoopBoundInjectionBad.js:29:16:29:18 | val | +| LoopBoundInjectionBad.js:29:16:29:18 | val | | LoopBoundInjectionBad.js:35:30:35:32 | val | | LoopBoundInjectionBad.js:38:15:38:17 | val | +| LoopBoundInjectionBad.js:38:15:38:17 | val | | LoopBoundInjectionBad.js:46:24:46:26 | val | | LoopBoundInjectionBad.js:51:25:51:27 | val | +| LoopBoundInjectionBad.js:51:25:51:27 | val | +| LoopBoundInjectionExitBad.js:8:9:8:16 | req.body | | LoopBoundInjectionExitBad.js:8:9:8:16 | req.body | | LoopBoundInjectionExitBad.js:10:9:10:16 | req.body | +| LoopBoundInjectionExitBad.js:10:9:10:16 | req.body | | LoopBoundInjectionExitBad.js:12:10:12:17 | req.body | +| LoopBoundInjectionExitBad.js:12:10:12:17 | req.body | +| LoopBoundInjectionExitBad.js:14:14:14:21 | req.body | | LoopBoundInjectionExitBad.js:14:14:14:21 | req.body | | LoopBoundInjectionExitBad.js:17:17:17:19 | val | | LoopBoundInjectionExitBad.js:20:22:20:24 | val | +| LoopBoundInjectionExitBad.js:20:22:20:24 | val | | LoopBoundInjectionExitBad.js:31:17:31:19 | val | | LoopBoundInjectionExitBad.js:34:22:34:24 | val | +| LoopBoundInjectionExitBad.js:34:22:34:24 | val | | LoopBoundInjectionExitBad.js:46:18:46:20 | val | | LoopBoundInjectionExitBad.js:49:22:49:24 | val | +| LoopBoundInjectionExitBad.js:49:22:49:24 | val | | LoopBoundInjectionExitBad.js:59:22:59:24 | val | | LoopBoundInjectionExitBad.js:60:8:60:10 | val | +| LoopBoundInjectionExitBad.js:60:8:60:10 | val | +| LoopBoundInjectionLodash.js:9:13:9:20 | req.body | | LoopBoundInjectionLodash.js:9:13:9:20 | req.body | | LoopBoundInjectionLodash.js:12:18:12:20 | val | | LoopBoundInjectionLodash.js:13:13:13:15 | val | +| LoopBoundInjectionLodash.js:13:13:13:15 | val | edges | LoopBoundInjectionBad.js:8:13:8:20 | req.body | LoopBoundInjectionBad.js:17:18:17:20 | val | +| LoopBoundInjectionBad.js:8:13:8:20 | req.body | LoopBoundInjectionBad.js:17:18:17:20 | val | +| LoopBoundInjectionBad.js:10:15:10:22 | req.body | LoopBoundInjectionBad.js:25:20:25:22 | val | | LoopBoundInjectionBad.js:10:15:10:22 | req.body | LoopBoundInjectionBad.js:25:20:25:22 | val | | LoopBoundInjectionBad.js:12:25:12:32 | req.body | LoopBoundInjectionBad.js:35:30:35:32 | val | +| LoopBoundInjectionBad.js:12:25:12:32 | req.body | LoopBoundInjectionBad.js:35:30:35:32 | val | +| LoopBoundInjectionBad.js:14:19:14:26 | req.body | LoopBoundInjectionBad.js:46:24:46:26 | val | | LoopBoundInjectionBad.js:14:19:14:26 | req.body | LoopBoundInjectionBad.js:46:24:46:26 | val | | LoopBoundInjectionBad.js:17:18:17:20 | val | LoopBoundInjectionBad.js:20:25:20:27 | val | +| LoopBoundInjectionBad.js:17:18:17:20 | val | LoopBoundInjectionBad.js:20:25:20:27 | val | +| LoopBoundInjectionBad.js:25:20:25:22 | val | LoopBoundInjectionBad.js:29:16:29:18 | val | | LoopBoundInjectionBad.js:25:20:25:22 | val | LoopBoundInjectionBad.js:29:16:29:18 | val | | LoopBoundInjectionBad.js:35:30:35:32 | val | LoopBoundInjectionBad.js:38:15:38:17 | val | +| LoopBoundInjectionBad.js:35:30:35:32 | val | LoopBoundInjectionBad.js:38:15:38:17 | val | +| LoopBoundInjectionBad.js:46:24:46:26 | val | LoopBoundInjectionBad.js:51:25:51:27 | val | | LoopBoundInjectionBad.js:46:24:46:26 | val | LoopBoundInjectionBad.js:51:25:51:27 | val | | LoopBoundInjectionExitBad.js:8:9:8:16 | req.body | LoopBoundInjectionExitBad.js:17:17:17:19 | val | +| LoopBoundInjectionExitBad.js:8:9:8:16 | req.body | LoopBoundInjectionExitBad.js:17:17:17:19 | val | +| LoopBoundInjectionExitBad.js:10:9:10:16 | req.body | LoopBoundInjectionExitBad.js:31:17:31:19 | val | | LoopBoundInjectionExitBad.js:10:9:10:16 | req.body | LoopBoundInjectionExitBad.js:31:17:31:19 | val | | LoopBoundInjectionExitBad.js:12:10:12:17 | req.body | LoopBoundInjectionExitBad.js:46:18:46:20 | val | +| LoopBoundInjectionExitBad.js:12:10:12:17 | req.body | LoopBoundInjectionExitBad.js:46:18:46:20 | val | +| LoopBoundInjectionExitBad.js:14:14:14:21 | req.body | LoopBoundInjectionExitBad.js:59:22:59:24 | val | | LoopBoundInjectionExitBad.js:14:14:14:21 | req.body | LoopBoundInjectionExitBad.js:59:22:59:24 | val | | LoopBoundInjectionExitBad.js:17:17:17:19 | val | LoopBoundInjectionExitBad.js:20:22:20:24 | val | +| LoopBoundInjectionExitBad.js:17:17:17:19 | val | LoopBoundInjectionExitBad.js:20:22:20:24 | val | +| LoopBoundInjectionExitBad.js:31:17:31:19 | val | LoopBoundInjectionExitBad.js:34:22:34:24 | val | | LoopBoundInjectionExitBad.js:31:17:31:19 | val | LoopBoundInjectionExitBad.js:34:22:34:24 | val | | LoopBoundInjectionExitBad.js:46:18:46:20 | val | LoopBoundInjectionExitBad.js:49:22:49:24 | val | +| LoopBoundInjectionExitBad.js:46:18:46:20 | val | LoopBoundInjectionExitBad.js:49:22:49:24 | val | +| LoopBoundInjectionExitBad.js:59:22:59:24 | val | LoopBoundInjectionExitBad.js:60:8:60:10 | val | | LoopBoundInjectionExitBad.js:59:22:59:24 | val | LoopBoundInjectionExitBad.js:60:8:60:10 | val | | LoopBoundInjectionLodash.js:9:13:9:20 | req.body | LoopBoundInjectionLodash.js:12:18:12:20 | val | +| LoopBoundInjectionLodash.js:9:13:9:20 | req.body | LoopBoundInjectionLodash.js:12:18:12:20 | val | +| LoopBoundInjectionLodash.js:12:18:12:20 | val | LoopBoundInjectionLodash.js:13:13:13:15 | val | | LoopBoundInjectionLodash.js:12:18:12:20 | val | LoopBoundInjectionLodash.js:13:13:13:15 | val | #select | LoopBoundInjectionBad.js:20:25:20:27 | val | LoopBoundInjectionBad.js:8:13:8:20 | req.body | LoopBoundInjectionBad.js:20:25:20:27 | val | Iterating over user-controlled object with a potentially unbounded .length property from $@. | LoopBoundInjectionBad.js:8:13:8:20 | req.body | here | diff --git a/javascript/ql/test/query-tests/Security/CWE-843/TypeConfusionThroughParameterTampering.expected b/javascript/ql/test/query-tests/Security/CWE-843/TypeConfusionThroughParameterTampering.expected index 5cd1cf4abaa..9baa3bcaecd 100644 --- a/javascript/ql/test/query-tests/Security/CWE-843/TypeConfusionThroughParameterTampering.expected +++ b/javascript/ql/test/query-tests/Security/CWE-843/TypeConfusionThroughParameterTampering.expected @@ -1,45 +1,54 @@ nodes | tst.js:5:9:5:27 | foo | | tst.js:5:15:5:27 | req.query.foo | +| tst.js:5:15:5:27 | req.query.foo | +| tst.js:6:5:6:7 | foo | | tst.js:6:5:6:7 | foo | | tst.js:8:5:8:7 | foo | +| tst.js:8:5:8:7 | foo | +| tst.js:11:9:11:11 | foo | | tst.js:11:9:11:11 | foo | | tst.js:14:16:14:18 | bar | | tst.js:15:9:15:11 | bar | +| tst.js:15:9:15:11 | bar | | tst.js:17:7:17:9 | foo | | tst.js:27:5:27:7 | foo | +| tst.js:27:5:27:7 | foo | +| tst.js:28:5:28:7 | foo | | tst.js:28:5:28:7 | foo | | tst.js:36:9:36:11 | foo | +| tst.js:36:9:36:11 | foo | +| tst.js:41:5:41:7 | foo | | tst.js:41:5:41:7 | foo | | tst.js:45:9:45:35 | foo | | tst.js:45:15:45:35 | ctx.req ... ery.foo | +| tst.js:45:15:45:35 | ctx.req ... ery.foo | +| tst.js:46:5:46:7 | foo | | tst.js:46:5:46:7 | foo | edges | tst.js:5:9:5:27 | foo | tst.js:6:5:6:7 | foo | +| tst.js:5:9:5:27 | foo | tst.js:6:5:6:7 | foo | | tst.js:5:9:5:27 | foo | tst.js:8:5:8:7 | foo | -| tst.js:5:9:5:27 | foo | tst.js:10:5:10:4 | foo | +| tst.js:5:9:5:27 | foo | tst.js:8:5:8:7 | foo | +| tst.js:5:9:5:27 | foo | tst.js:11:9:11:11 | foo | | tst.js:5:9:5:27 | foo | tst.js:11:9:11:11 | foo | | tst.js:5:9:5:27 | foo | tst.js:17:7:17:9 | foo | | tst.js:5:9:5:27 | foo | tst.js:27:5:27:7 | foo | +| tst.js:5:9:5:27 | foo | tst.js:27:5:27:7 | foo | | tst.js:5:9:5:27 | foo | tst.js:28:5:28:7 | foo | -| tst.js:5:9:5:27 | foo | tst.js:30:9:30:31 | foo | -| tst.js:5:9:5:27 | foo | tst.js:30:9:30:31 | foo | -| tst.js:5:9:5:27 | foo | tst.js:35:5:35:5 | foo | +| tst.js:5:9:5:27 | foo | tst.js:28:5:28:7 | foo | +| tst.js:5:9:5:27 | foo | tst.js:36:9:36:11 | foo | | tst.js:5:9:5:27 | foo | tst.js:36:9:36:11 | foo | | tst.js:5:9:5:27 | foo | tst.js:41:5:41:7 | foo | +| tst.js:5:9:5:27 | foo | tst.js:41:5:41:7 | foo | | tst.js:5:15:5:27 | req.query.foo | tst.js:5:9:5:27 | foo | -| tst.js:10:5:10:4 | foo | tst.js:11:9:11:11 | foo | +| tst.js:5:15:5:27 | req.query.foo | tst.js:5:9:5:27 | foo | +| tst.js:14:16:14:18 | bar | tst.js:15:9:15:11 | bar | | tst.js:14:16:14:18 | bar | tst.js:15:9:15:11 | bar | | tst.js:17:7:17:9 | foo | tst.js:14:16:14:18 | bar | -| tst.js:30:9:30:31 | foo | tst.js:35:5:35:5 | foo | -| tst.js:30:9:30:31 | foo | tst.js:35:5:35:5 | foo | -| tst.js:30:9:30:31 | foo | tst.js:36:9:36:11 | foo | -| tst.js:30:9:30:31 | foo | tst.js:36:9:36:11 | foo | -| tst.js:30:9:30:31 | foo | tst.js:41:5:41:7 | foo | -| tst.js:30:9:30:31 | foo | tst.js:41:5:41:7 | foo | -| tst.js:35:5:35:5 | foo | tst.js:36:9:36:11 | foo | -| tst.js:35:5:35:5 | foo | tst.js:41:5:41:7 | foo | | tst.js:45:9:45:35 | foo | tst.js:46:5:46:7 | foo | +| tst.js:45:9:45:35 | foo | tst.js:46:5:46:7 | foo | +| tst.js:45:15:45:35 | ctx.req ... ery.foo | tst.js:45:9:45:35 | foo | | tst.js:45:15:45:35 | ctx.req ... ery.foo | tst.js:45:9:45:35 | foo | #select | tst.js:6:5:6:7 | foo | tst.js:5:15:5:27 | req.query.foo | tst.js:6:5:6:7 | foo | Potential type confusion for $@. | tst.js:5:15:5:27 | req.query.foo | HTTP request parameter | diff --git a/javascript/ql/test/query-tests/Security/CWE-912/HttpToFileAccess.expected b/javascript/ql/test/query-tests/Security/CWE-912/HttpToFileAccess.expected index 0f56b81d0e3..53a6ddea6a5 100644 --- a/javascript/ql/test/query-tests/Security/CWE-912/HttpToFileAccess.expected +++ b/javascript/ql/test/query-tests/Security/CWE-912/HttpToFileAccess.expected @@ -1,17 +1,33 @@ nodes | HttpToFileAccess.js:5:18:5:18 | d | +| HttpToFileAccess.js:5:18:5:18 | d | +| HttpToFileAccess.js:6:37:6:37 | d | | HttpToFileAccess.js:6:37:6:37 | d | | tst.js:15:26:15:26 | c | +| tst.js:15:26:15:26 | c | +| tst.js:16:33:16:33 | c | | tst.js:16:33:16:33 | c | | tst.js:19:25:19:25 | c | +| tst.js:19:25:19:25 | c | +| tst.js:24:22:24:22 | c | | tst.js:24:22:24:22 | c | edges | HttpToFileAccess.js:5:18:5:18 | d | HttpToFileAccess.js:6:37:6:37 | d | +| HttpToFileAccess.js:5:18:5:18 | d | HttpToFileAccess.js:6:37:6:37 | d | +| HttpToFileAccess.js:5:18:5:18 | d | HttpToFileAccess.js:6:37:6:37 | d | +| HttpToFileAccess.js:5:18:5:18 | d | HttpToFileAccess.js:6:37:6:37 | d | +| tst.js:15:26:15:26 | c | tst.js:16:33:16:33 | c | +| tst.js:15:26:15:26 | c | tst.js:16:33:16:33 | c | +| tst.js:15:26:15:26 | c | tst.js:16:33:16:33 | c | | tst.js:15:26:15:26 | c | tst.js:16:33:16:33 | c | | tst.js:15:26:15:26 | c | tst.js:19:25:19:25 | c | -| tst.js:15:26:15:26 | c | tst.js:23:27:23:26 | c | +| tst.js:15:26:15:26 | c | tst.js:19:25:19:25 | c | +| tst.js:15:26:15:26 | c | tst.js:19:25:19:25 | c | +| tst.js:15:26:15:26 | c | tst.js:19:25:19:25 | c | +| tst.js:15:26:15:26 | c | tst.js:24:22:24:22 | c | +| tst.js:15:26:15:26 | c | tst.js:24:22:24:22 | c | +| tst.js:15:26:15:26 | c | tst.js:24:22:24:22 | c | | tst.js:15:26:15:26 | c | tst.js:24:22:24:22 | c | -| tst.js:23:27:23:26 | c | tst.js:24:22:24:22 | c | #select | HttpToFileAccess.js:6:37:6:37 | d | HttpToFileAccess.js:5:18:5:18 | d | HttpToFileAccess.js:6:37:6:37 | d | $@ flows to file system | HttpToFileAccess.js:5:18:5:18 | d | Untrusted data | | tst.js:16:33:16:33 | c | tst.js:15:26:15:26 | c | tst.js:16:33:16:33 | c | $@ flows to file system | tst.js:15:26:15:26 | c | Untrusted data | diff --git a/javascript/ql/test/query-tests/Security/CWE-916/InsufficientPasswordHash.expected b/javascript/ql/test/query-tests/Security/CWE-916/InsufficientPasswordHash.expected index cdd69e35a19..40cd78138e4 100644 --- a/javascript/ql/test/query-tests/Security/CWE-916/InsufficientPasswordHash.expected +++ b/javascript/ql/test/query-tests/Security/CWE-916/InsufficientPasswordHash.expected @@ -1,8 +1,17 @@ nodes | tst.js:5:48:5:55 | password | +| tst.js:5:48:5:55 | password | +| tst.js:5:48:5:55 | password | +| tst.js:7:46:7:53 | password | +| tst.js:7:46:7:53 | password | | tst.js:7:46:7:53 | password | | tst.js:9:43:9:50 | password | +| tst.js:9:43:9:50 | password | +| tst.js:9:43:9:50 | password | edges +| tst.js:5:48:5:55 | password | tst.js:5:48:5:55 | password | +| tst.js:7:46:7:53 | password | tst.js:7:46:7:53 | password | +| tst.js:9:43:9:50 | password | tst.js:9:43:9:50 | password | #select | tst.js:5:48:5:55 | password | tst.js:5:48:5:55 | password | tst.js:5:48:5:55 | password | Password from $@ is hashed insecurely. | tst.js:5:48:5:55 | password | an access to password | | tst.js:7:46:7:53 | password | tst.js:7:46:7:53 | password | tst.js:7:46:7:53 | password | Password from $@ is hashed insecurely. | tst.js:7:46:7:53 | password | an access to password | diff --git a/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected b/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected index a8520620fd3..5aeef6447cc 100644 --- a/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected +++ b/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected @@ -4,34 +4,51 @@ nodes | tst.js:14:19:14:48 | url.par ... ).query | | tst.js:14:19:14:52 | url.par ... ery.url | | tst.js:14:29:14:35 | req.url | +| tst.js:14:29:14:35 | req.url | +| tst.js:18:13:18:19 | tainted | | tst.js:18:13:18:19 | tainted | | tst.js:20:17:20:23 | tainted | +| tst.js:20:17:20:23 | tainted | | tst.js:23:19:23:25 | tainted | +| tst.js:23:19:23:25 | tainted | +| tst.js:26:13:26:31 | "http://" + tainted | | tst.js:26:13:26:31 | "http://" + tainted | | tst.js:26:25:26:31 | tainted | | tst.js:28:13:28:42 | "http:/ ... tainted | +| tst.js:28:13:28:42 | "http:/ ... tainted | | tst.js:28:36:28:42 | tainted | | tst.js:30:13:30:43 | "http:/ ... tainted | +| tst.js:30:13:30:43 | "http:/ ... tainted | | tst.js:30:37:30:43 | tainted | | tst.js:34:34:34:40 | tainted | +| tst.js:34:34:34:40 | tainted | +| tst.js:36:16:36:31 | new Uri(tainted) | | tst.js:36:16:36:31 | new Uri(tainted) | | tst.js:36:24:36:30 | tainted | | tst.js:37:22:37:37 | new Uri(tainted) | +| tst.js:37:22:37:37 | new Uri(tainted) | | tst.js:37:30:37:36 | tainted | | tst.js:41:13:41:51 | `http:/ ... inted}` | +| tst.js:41:13:41:51 | `http:/ ... inted}` | | tst.js:41:43:41:49 | tainted | | tst.js:43:13:43:54 | `http:/ ... inted}` | +| tst.js:43:13:43:54 | `http:/ ... inted}` | | tst.js:43:46:43:52 | tainted | | tst.js:45:13:45:56 | 'http:/ ... tainted | +| tst.js:45:13:45:56 | 'http:/ ... tainted | | tst.js:45:50:45:56 | tainted | edges | tst.js:14:9:14:52 | tainted | tst.js:18:13:18:19 | tainted | +| tst.js:14:9:14:52 | tainted | tst.js:18:13:18:19 | tainted | | tst.js:14:9:14:52 | tainted | tst.js:20:17:20:23 | tainted | +| tst.js:14:9:14:52 | tainted | tst.js:20:17:20:23 | tainted | +| tst.js:14:9:14:52 | tainted | tst.js:23:19:23:25 | tainted | | tst.js:14:9:14:52 | tainted | tst.js:23:19:23:25 | tainted | | tst.js:14:9:14:52 | tainted | tst.js:26:25:26:31 | tainted | | tst.js:14:9:14:52 | tainted | tst.js:28:36:28:42 | tainted | | tst.js:14:9:14:52 | tainted | tst.js:30:37:30:43 | tainted | | tst.js:14:9:14:52 | tainted | tst.js:34:34:34:40 | tainted | +| tst.js:14:9:14:52 | tainted | tst.js:34:34:34:40 | tainted | | tst.js:14:9:14:52 | tainted | tst.js:36:24:36:30 | tainted | | tst.js:14:9:14:52 | tainted | tst.js:37:30:37:36 | tainted | | tst.js:14:9:14:52 | tainted | tst.js:41:43:41:49 | tainted | @@ -41,13 +58,22 @@ edges | tst.js:14:19:14:48 | url.par ... ).query | tst.js:14:19:14:52 | url.par ... ery.url | | tst.js:14:19:14:52 | url.par ... ery.url | tst.js:14:9:14:52 | tainted | | tst.js:14:29:14:35 | req.url | tst.js:14:19:14:42 | url.par ... , true) | +| tst.js:14:29:14:35 | req.url | tst.js:14:19:14:42 | url.par ... , true) | +| tst.js:26:25:26:31 | tainted | tst.js:26:13:26:31 | "http://" + tainted | | tst.js:26:25:26:31 | tainted | tst.js:26:13:26:31 | "http://" + tainted | | tst.js:28:36:28:42 | tainted | tst.js:28:13:28:42 | "http:/ ... tainted | +| tst.js:28:36:28:42 | tainted | tst.js:28:13:28:42 | "http:/ ... tainted | +| tst.js:30:37:30:43 | tainted | tst.js:30:13:30:43 | "http:/ ... tainted | | tst.js:30:37:30:43 | tainted | tst.js:30:13:30:43 | "http:/ ... tainted | | tst.js:36:24:36:30 | tainted | tst.js:36:16:36:31 | new Uri(tainted) | +| tst.js:36:24:36:30 | tainted | tst.js:36:16:36:31 | new Uri(tainted) | +| tst.js:37:30:37:36 | tainted | tst.js:37:22:37:37 | new Uri(tainted) | | tst.js:37:30:37:36 | tainted | tst.js:37:22:37:37 | new Uri(tainted) | | tst.js:41:43:41:49 | tainted | tst.js:41:13:41:51 | `http:/ ... inted}` | +| tst.js:41:43:41:49 | tainted | tst.js:41:13:41:51 | `http:/ ... inted}` | | tst.js:43:46:43:52 | tainted | tst.js:43:13:43:54 | `http:/ ... inted}` | +| tst.js:43:46:43:52 | tainted | tst.js:43:13:43:54 | `http:/ ... inted}` | +| tst.js:45:50:45:56 | tainted | tst.js:45:13:45:56 | 'http:/ ... tainted | | tst.js:45:50:45:56 | tainted | tst.js:45:13:45:56 | 'http:/ ... tainted | #select | tst.js:18:5:18:20 | request(tainted) | tst.js:14:29:14:35 | req.url | tst.js:18:13:18:19 | tainted | The $@ of this request depends on $@. | tst.js:18:13:18:19 | tainted | URL | tst.js:14:29:14:35 | req.url | a user-provided value | diff --git a/javascript/ql/test/query-tests/Statements/IgnoreArrayResult/IgnoreArrayResult.expected b/javascript/ql/test/query-tests/Statements/IgnoreArrayResult/IgnoreArrayResult.expected new file mode 100644 index 00000000000..9f5c5a0b082 --- /dev/null +++ b/javascript/ql/test/query-tests/Statements/IgnoreArrayResult/IgnoreArrayResult.expected @@ -0,0 +1,2 @@ +| tst.js:3:1:3:19 | arr.concat([1,2,3]) | Result from call to concat ignored. | +| tst.js:5:1:5:15 | arr.concat(arr) | Result from call to concat ignored. | diff --git a/javascript/ql/test/query-tests/Statements/IgnoreArrayResult/IgnoreArrayResult.qlref b/javascript/ql/test/query-tests/Statements/IgnoreArrayResult/IgnoreArrayResult.qlref new file mode 100644 index 00000000000..2cbc7e722a5 --- /dev/null +++ b/javascript/ql/test/query-tests/Statements/IgnoreArrayResult/IgnoreArrayResult.qlref @@ -0,0 +1 @@ +Statements/IgnoreArrayResult.ql \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Statements/IgnoreArrayResult/tst.js b/javascript/ql/test/query-tests/Statements/IgnoreArrayResult/tst.js new file mode 100644 index 00000000000..47efe8c1cb6 --- /dev/null +++ b/javascript/ql/test/query-tests/Statements/IgnoreArrayResult/tst.js @@ -0,0 +1,11 @@ +var arr = [1,2,3]; + +arr.concat([1,2,3]); // NOT OK! + +arr.concat(arr); // NOT OK! + +console.log(arr.concat([1,2,3])); + +({concat: Array.prototype.concat}.concat(arr)); + +[].concat([1,2,3]); \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Statements/ReturnOutsideFunction/node.js b/javascript/ql/test/query-tests/Statements/ReturnOutsideFunction/node.js index 3397ebd38a4..572dbe25035 100644 --- a/javascript/ql/test/query-tests/Statements/ReturnOutsideFunction/node.js +++ b/javascript/ql/test/query-tests/Statements/ReturnOutsideFunction/node.js @@ -1,5 +1,4 @@ // not a syntax error, but still NOT OK return 42; -// semmle-extractor-options: --platform -// semmle-extractor-options: node +require("path") // ensure this is treated as Node.js code diff --git a/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/UseOfReturnlessFunction.expected b/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/UseOfReturnlessFunction.expected index 500d900ff9e..fd808fd8387 100644 --- a/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/UseOfReturnlessFunction.expected +++ b/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/UseOfReturnlessFunction.expected @@ -1,5 +1,8 @@ -| tst.js:20:17:20:33 | onlySideEffects() | the function $@ does not return anything, yet the return value is used. | tst.js:11:5:13:5 | functio ... )\\n } | onlySideEffects | -| tst.js:24:13:24:29 | onlySideEffects() | the function $@ does not return anything, yet the return value is used. | tst.js:11:5:13:5 | functio ... )\\n } | onlySideEffects | -| tst.js:30:20:30:36 | onlySideEffects() | the function $@ does not return anything, yet the return value is used. | tst.js:11:5:13:5 | functio ... )\\n } | onlySideEffects | -| tst.js:53:10:53:34 | bothOnl ... fects() | the function $@ does not return anything, yet the return value is used. | tst.js:11:5:13:5 | functio ... )\\n } | bothOnlyHaveSideEffects | -| tst.js:53:10:53:34 | bothOnl ... fects() | the function $@ does not return anything, yet the return value is used. | tst.js:48:2:50:5 | functio ... )\\n } | bothOnlyHaveSideEffects | +| tst.html:19:31:19:43 | addHandlers() | the $@ does not return anything, yet the return value is used. | tst.html:5:7:12:7 | functio ... } | function addHandlers | +| tst.js:20:17:20:33 | onlySideEffects() | the $@ does not return anything, yet the return value is used. | tst.js:11:5:13:5 | functio ... )\\n } | function onlySideEffects | +| tst.js:24:13:24:29 | onlySideEffects() | the $@ does not return anything, yet the return value is used. | tst.js:11:5:13:5 | functio ... )\\n } | function onlySideEffects | +| tst.js:30:20:30:36 | onlySideEffects() | the $@ does not return anything, yet the return value is used. | tst.js:11:5:13:5 | functio ... )\\n } | function onlySideEffects | +| tst.js:53:10:53:34 | bothOnl ... fects() | the $@ does not return anything, yet the return value is used. | tst.js:11:5:13:5 | functio ... )\\n } | function onlySideEffects | +| tst.js:53:10:53:34 | bothOnl ... fects() | the $@ does not return anything, yet the return value is used. | tst.js:48:2:50:5 | functio ... )\\n } | function onlySideEffects2 | +| tst.js:76:12:76:46 | [1,2,3] ... n, 3)}) | the $@ does not return anything, yet the return value from the call to filter is used. | tst.js:76:27:76:45 | n => {equals(n, 3)} | callback function | +| tst.js:80:12:80:50 | filter( ... 3) } ) | the $@ does not return anything, yet the return value from the call to filter is used. | tst.js:80:28:80:48 | x => { ... x, 3) } | callback function | diff --git a/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/tst.html b/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/tst.html new file mode 100644 index 00000000000..062d23c4a7c --- /dev/null +++ b/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/tst.html @@ -0,0 +1,21 @@ + + + + + + + + Foo +
    Click me
    +
    Click me
    + + \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/tst.js b/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/tst.js index 8bb49f7e761..90a52153dea 100644 --- a/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/tst.js +++ b/javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/tst.js @@ -68,4 +68,24 @@ var h = returnsValue() || alwaysThrows(); // OK! console.log(h); + + function equals(x, y) { + return x === y; + } + + var foo = [1,2,3].filter(n => {equals(n, 3)}) // NOT OK! + console.log(foo); + + import { filter } from 'lodash' + var bar = filter([1,2,4], x => { equals(x, 3) } ) // NOT OK! + console.log(bar); + + var baz = [1,2,3].filter(n => {n === 3}) // OK + console.log(baz); + + class Deferred { + + } + + new Deferred().resolve(onlySideEffects()); // OK })(); \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Statements/UselessConditional/UselessConditional.js b/javascript/ql/test/query-tests/Statements/UselessConditional/UselessConditional.js index 8731ac0cfac..a3e429ed0b5 100644 --- a/javascript/ql/test/query-tests/Statements/UselessConditional/UselessConditional.js +++ b/javascript/ql/test/query-tests/Statements/UselessConditional/UselessConditional.js @@ -176,5 +176,3 @@ async function awaitFlow(){ if (v) { // OK } }); - -// semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/Statements/UselessConditional/options b/javascript/ql/test/query-tests/Statements/UselessConditional/options new file mode 100644 index 00000000000..ae107b46f9e --- /dev/null +++ b/javascript/ql/test/query-tests/Statements/UselessConditional/options @@ -0,0 +1 @@ +semmle-extractor-options: --experimental diff --git a/javascript/ql/test/query-tests/filters/ClassifyFiles/ClassifyFiles.expected b/javascript/ql/test/query-tests/filters/ClassifyFiles/ClassifyFiles.expected index 045fccd225e..da235c205ee 100644 --- a/javascript/ql/test/query-tests/filters/ClassifyFiles/ClassifyFiles.expected +++ b/javascript/ql/test/query-tests/filters/ClassifyFiles/ClassifyFiles.expected @@ -6,6 +6,7 @@ | ai.1.2.3-build0123.js:0:0:0:0 | ai.1.2.3-build0123.js | library | | bundle-directive.js:0:0:0:0 | bundle-directive.js | generated | | data.js:0:0:0:0 | data.js | generated | +| doxygen-generated.html:0:0:0:0 | doxygen-generated.html | generated | | etherpad.html:0:0:0:0 | etherpad.html | generated | | exported-data.js:0:0:0:0 | exported-data.js | generated | | htmltidy.html:0:0:0:0 | htmltidy.html | generated | @@ -38,8 +39,11 @@ | textmate.html:0:0:0:0 | textmate.html | generated | | tmpl2.html:0:0:0:0 | tmpl2.html | template | | tmpl.html:0:0:0:0 | tmpl.html | template | +| tst-min.js:0:0:0:0 | tst-min.js | generated | | tst.browserify.js:0:0:0:0 | tst.browserify.js | generated | | tst.dart.js:0:0:0:0 | tst.dart.js | generated | +| tst.min.js:0:0:0:0 | tst.min.js | generated | +| tst_min.js:0:0:0:0 | tst_min.js | generated | | twitter-text.js:0:0:0:0 | twitter-text.js | library | | twitter_text.js:0:0:0:0 | twitter_text.js | library | | unannotated-externs-1.js:0:0:0:0 | unannotated-externs-1.js | externs | diff --git a/javascript/ql/test/query-tests/filters/ClassifyFiles/doxygen-generated.html b/javascript/ql/test/query-tests/filters/ClassifyFiles/doxygen-generated.html new file mode 100644 index 00000000000..b659cc3fcb0 --- /dev/null +++ b/javascript/ql/test/query-tests/filters/ClassifyFiles/doxygen-generated.html @@ -0,0 +1,8 @@ + + + + + + 1 + + diff --git a/javascript/ql/test/query-tests/filters/ClassifyFiles/nonbmp.js b/javascript/ql/test/query-tests/filters/ClassifyFiles/nonbmp.js index ba9b39b4f72..5d56c9b782e 100644 --- a/javascript/ql/test/query-tests/filters/ClassifyFiles/nonbmp.js +++ b/javascript/ql/test/query-tests/filters/ClassifyFiles/nonbmp.js @@ -1,3 +1 @@ ๐Ÿ˜ผ๐Ÿ˜ผ - -// semmle-extractor-options: --tolerate-parse-errors diff --git a/javascript/ql/test/query-tests/filters/ClassifyFiles/options b/javascript/ql/test/query-tests/filters/ClassifyFiles/options new file mode 100644 index 00000000000..13f987b19ca --- /dev/null +++ b/javascript/ql/test/query-tests/filters/ClassifyFiles/options @@ -0,0 +1 @@ +semmle-extractor-options: --tolerate-parse-errors diff --git a/javascript/ql/test/query-tests/filters/ClassifyFiles/some-template.html b/javascript/ql/test/query-tests/filters/ClassifyFiles/some-template.html index 734e6cf7da8..671a0c7b51b 100644 --- a/javascript/ql/test/query-tests/filters/ClassifyFiles/some-template.html +++ b/javascript/ql/test/query-tests/filters/ClassifyFiles/some-template.html @@ -1,4 +1,3 @@ -semmle-extractor-options: --tolerate-parse-errors diff --git a/javascript/ql/test/query-tests/filters/ClassifyFiles/templ.js b/javascript/ql/test/query-tests/filters/ClassifyFiles/templ.js index 1a42f3cf925..cda21380525 100644 --- a/javascript/ql/test/query-tests/filters/ClassifyFiles/templ.js +++ b/javascript/ql/test/query-tests/filters/ClassifyFiles/templ.js @@ -3,4 +3,3 @@ common.autofocus('#id_password'); {% else %} common.autofocus('#id_username'); {% endif %} -// semmle-extractor-options: --tolerate-parse-errors diff --git a/javascript/ql/test/query-tests/filters/ClassifyFiles/tmpl.html b/javascript/ql/test/query-tests/filters/ClassifyFiles/tmpl.html index c21d85208f5..e3bdc744425 100644 --- a/javascript/ql/test/query-tests/filters/ClassifyFiles/tmpl.html +++ b/javascript/ql/test/query-tests/filters/ClassifyFiles/tmpl.html @@ -5,4 +5,3 @@ common.autofocus('#id_password'); common.autofocus('#id_username'); {% endif %} -semmle-extractor-options: --tolerate-parse-errors diff --git a/javascript/ql/test/query-tests/filters/ClassifyFiles/tmpl2.html b/javascript/ql/test/query-tests/filters/ClassifyFiles/tmpl2.html index 8e96a8b41f4..700fe9c08d2 100644 --- a/javascript/ql/test/query-tests/filters/ClassifyFiles/tmpl2.html +++ b/javascript/ql/test/query-tests/filters/ClassifyFiles/tmpl2.html @@ -5,4 +5,3 @@ {{/config}} } -semmle-extractor-options: --tolerate-parse-errors diff --git a/javascript/ql/test/query-tests/filters/ClassifyFiles/tst-min.js b/javascript/ql/test/query-tests/filters/ClassifyFiles/tst-min.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/javascript/ql/test/query-tests/filters/ClassifyFiles/tst.min.js b/javascript/ql/test/query-tests/filters/ClassifyFiles/tst.min.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/javascript/ql/test/query-tests/filters/ClassifyFiles/tst_min.js b/javascript/ql/test/query-tests/filters/ClassifyFiles/tst_min.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/javascript/ql/test/tutorials/Introducing the JavaScript libraries/m.js b/javascript/ql/test/tutorials/Introducing the JavaScript libraries/m.js index c53a0a15327..a54fda636cc 100644 --- a/javascript/ql/test/tutorials/Introducing the JavaScript libraries/m.js +++ b/javascript/ql/test/tutorials/Introducing the JavaScript libraries/m.js @@ -1,2 +1,2 @@ -// semmle-extractor-options: --platform -// semmle-extractor-options: node +require("process") +; diff --git a/javascript/ql/test/tutorials/Introducing the JavaScript libraries/options b/javascript/ql/test/tutorials/Introducing the JavaScript libraries/options new file mode 100644 index 00000000000..a1b2b21840f --- /dev/null +++ b/javascript/ql/test/tutorials/Introducing the JavaScript libraries/options @@ -0,0 +1 @@ +semmle-extractor-options: --tolerate-parse-errors \ No newline at end of file diff --git a/javascript/upgrades/874ebfcd4d2fd346c10ebec145466d9071d78606/old.dbscheme b/javascript/upgrades/874ebfcd4d2fd346c10ebec145466d9071d78606/old.dbscheme new file mode 100644 index 00000000000..874ebfcd4d2 --- /dev/null +++ b/javascript/upgrades/874ebfcd4d2fd346c10ebec145466d9071d78606/old.dbscheme @@ -0,0 +1,1173 @@ +/*** Standard fragments ***/ + +/** Files and folders **/ + +@location = @location_default; + +locations_default(unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref + ); + +@sourceline = @locatable; + +numlines(int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref + ); + + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files(unique int id: @file, + varchar(900) name: string ref, + varchar(900) simple: string ref, + varchar(900) ext: string ref, + int fromSource: int ref); + +folders(unique int id: @folder, + varchar(900) name: string ref, + varchar(900) simple: string ref); + + +@container = @folder | @file ; + + +containerparent(int parent: @container ref, + unique int child: @container ref); + +/** Duplicate code **/ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity; + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/** External data **/ + +externalData( + int id : @externalDataElement, + varchar(900) path : string ref, + int column: int ref, + varchar(900) value : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + +/** Version control data **/ + +svnentries( + int id : @svnentry, + varchar(500) revision : string ref, + varchar(500) author : string ref, + date revisionDate : date ref, + int changeSize : int ref +); + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + varchar(500) action : string ref +); + +svnentrymsg( + int id : @svnentry ref, + varchar(500) message : string ref +); + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +); + + +/*** JavaScript-specific part ***/ + +filetype( + int file: @file ref, + string filetype: string ref +) + +// top-level code fragments +toplevels (unique int id: @toplevel, + int kind: int ref); + +isExterns (int toplevel: @toplevel ref); + +case @toplevel.kind of + 0 = @script +| 1 = @inline_script +| 2 = @event_handler +| 3 = @javascript_url; + +isModule (int tl: @toplevel ref); +isNodejs (int tl: @toplevel ref); +isES2015Module (int tl: @toplevel ref); +isClosureModule (int tl: @toplevel ref); + +// statements +#keyset[parent, idx] +stmts (unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +stmtContainers (unique int stmt: @stmt ref, + int container: @stmt_container ref); + +jumpTargets (unique int jump: @stmt ref, + int target: @stmt ref); + +@stmtparent = @stmt | @toplevel | @functionexpr | @arrowfunctionexpr; +@stmt_container = @toplevel | @function | @namespacedeclaration | @externalmoduledeclaration | @globalaugmentationdeclaration; + +case @stmt.kind of + 0 = @emptystmt +| 1 = @blockstmt +| 2 = @exprstmt +| 3 = @ifstmt +| 4 = @labeledstmt +| 5 = @breakstmt +| 6 = @continuestmt +| 7 = @withstmt +| 8 = @switchstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @trystmt +| 12 = @whilestmt +| 13 = @dowhilestmt +| 14 = @forstmt +| 15 = @forinstmt +| 16 = @debuggerstmt +| 17 = @functiondeclstmt +| 18 = @vardeclstmt +| 19 = @case +| 20 = @catchclause +| 21 = @forofstmt +| 22 = @constdeclstmt +| 23 = @letstmt +| 24 = @legacy_letstmt +| 25 = @foreachstmt +| 26 = @classdeclstmt +| 27 = @importdeclaration +| 28 = @exportalldeclaration +| 29 = @exportdefaultdeclaration +| 30 = @exportnameddeclaration +| 31 = @namespacedeclaration +| 32 = @importequalsdeclaration +| 33 = @exportassigndeclaration +| 34 = @interfacedeclaration +| 35 = @typealiasdeclaration +| 36 = @enumdeclaration +| 37 = @externalmoduledeclaration +| 38 = @exportasnamespacedeclaration +| 39 = @globalaugmentationdeclaration +; + +@declstmt = @vardeclstmt | @constdeclstmt | @letstmt | @legacy_letstmt; + +@exportdeclaration = @exportalldeclaration | @exportdefaultdeclaration | @exportnameddeclaration; + +@namespacedefinition = @namespacedeclaration | @enumdeclaration; +@typedefinition = @classdefinition | @interfacedeclaration | @enumdeclaration | @typealiasdeclaration | @enum_member; + +isInstantiated(unique int decl: @namespacedeclaration ref); + +@declarablestmt = @declstmt | @namespacedeclaration | @classdeclstmt | @functiondeclstmt | @enumdeclaration | @externalmoduledeclaration | @globalaugmentationdeclaration; +hasDeclareKeyword(unique int stmt: @declarablestmt ref); + +isForAwaitOf(unique int forof: @forofstmt ref); + +// expressions +#keyset[parent, idx] +exprs (unique int id: @expr, + int kind: int ref, + int parent: @exprparent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @exprortype ref); + +enclosingStmt (unique int expr: @exprortype ref, + int stmt: @stmt ref); + +exprContainers (unique int expr: @exprortype ref, + int container: @stmt_container ref); + +arraySize (unique int ae: @arraylike ref, + int sz: int ref); + +isDelegating (int yield: @yieldexpr ref); + +@exprorstmt = @expr | @stmt; +@exprortype = @expr | @typeexpr; +@exprparent = @exprorstmt | @property | @functiontypeexpr; +@arraylike = @arrayexpr | @arraypattern; +@type_annotation = @typeexpr | @jsdoc_type_expr; + +case @expr.kind of + 0 = @label +| 1 = @nullliteral +| 2 = @booleanliteral +| 3 = @numberliteral +| 4 = @stringliteral +| 5 = @regexpliteral +| 6 = @thisexpr +| 7 = @arrayexpr +| 8 = @objexpr +| 9 = @functionexpr +| 10 = @seqexpr +| 11 = @conditionalexpr +| 12 = @newexpr +| 13 = @callexpr +| 14 = @dotexpr +| 15 = @indexexpr +| 16 = @negexpr +| 17 = @plusexpr +| 18 = @lognotexpr +| 19 = @bitnotexpr +| 20 = @typeofexpr +| 21 = @voidexpr +| 22 = @deleteexpr +| 23 = @eqexpr +| 24 = @neqexpr +| 25 = @eqqexpr +| 26 = @neqqexpr +| 27 = @ltexpr +| 28 = @leexpr +| 29 = @gtexpr +| 30 = @geexpr +| 31 = @lshiftexpr +| 32 = @rshiftexpr +| 33 = @urshiftexpr +| 34 = @addexpr +| 35 = @subexpr +| 36 = @mulexpr +| 37 = @divexpr +| 38 = @modexpr +| 39 = @bitorexpr +| 40 = @xorexpr +| 41 = @bitandexpr +| 42 = @inexpr +| 43 = @instanceofexpr +| 44 = @logandexpr +| 45 = @logorexpr +| 47 = @assignexpr +| 48 = @assignaddexpr +| 49 = @assignsubexpr +| 50 = @assignmulexpr +| 51 = @assigndivexpr +| 52 = @assignmodexpr +| 53 = @assignlshiftexpr +| 54 = @assignrshiftexpr +| 55 = @assignurshiftexpr +| 56 = @assignorexpr +| 57 = @assignxorexpr +| 58 = @assignandexpr +| 59 = @preincexpr +| 60 = @postincexpr +| 61 = @predecexpr +| 62 = @postdecexpr +| 63 = @parexpr +| 64 = @vardeclarator +| 65 = @arrowfunctionexpr +| 66 = @spreadelement +| 67 = @arraypattern +| 68 = @objectpattern +| 69 = @yieldexpr +| 70 = @taggedtemplateexpr +| 71 = @templateliteral +| 72 = @templateelement +| 73 = @arraycomprehensionexpr +| 74 = @generatorexpr +| 75 = @forincomprehensionblock +| 76 = @forofcomprehensionblock +| 77 = @legacy_letexpr +| 78 = @vardecl +| 79 = @proper_varaccess +| 80 = @classexpr +| 81 = @superexpr +| 82 = @newtargetexpr +| 83 = @namedimportspecifier +| 84 = @importdefaultspecifier +| 85 = @importnamespacespecifier +| 86 = @namedexportspecifier +| 87 = @expexpr +| 88 = @assignexpexpr +| 89 = @jsxelement +| 90 = @jsxqualifiedname +| 91 = @jsxemptyexpr +| 92 = @awaitexpr +| 93 = @functionsentexpr +| 94 = @decorator +| 95 = @exportdefaultspecifier +| 96 = @exportnamespacespecifier +| 97 = @bindexpr +| 98 = @externalmodulereference +| 99 = @dynamicimport +| 100 = @expressionwithtypearguments +| 101 = @prefixtypeassertion +| 102 = @astypeassertion +| 103 = @export_varaccess +| 104 = @decorator_list +| 105 = @non_null_assertion +| 106 = @bigintliteral +| 107 = @nullishcoalescingexpr +| 108 = @e4x_xml_anyname +| 109 = @e4x_xml_static_attribute_selector +| 110 = @e4x_xml_dynamic_attribute_selector +| 111 = @e4x_xml_filter_expression +| 112 = @e4x_xml_static_qualident +| 113 = @e4x_xml_dynamic_qualident +| 114 = @e4x_xml_dotdotexpr +| 115 = @importmetaexpr +; + +@varaccess = @proper_varaccess | @export_varaccess; +@varref = @vardecl | @varaccess; + +@identifier = @label | @varref | @typeidentifier; + +@literal = @nullliteral | @booleanliteral | @numberliteral | @stringliteral | @regexpliteral | @bigintliteral; + +@propaccess = @dotexpr | @indexexpr; + +@invokeexpr = @newexpr | @callexpr; + +@unaryexpr = @negexpr | @plusexpr | @lognotexpr | @bitnotexpr | @typeofexpr | @voidexpr | @deleteexpr | @spreadelement; + +@equalitytest = @eqexpr | @neqexpr | @eqqexpr | @neqqexpr; + +@comparison = @equalitytest | @ltexpr | @leexpr | @gtexpr | @geexpr; + +@binaryexpr = @comparison | @lshiftexpr | @rshiftexpr | @urshiftexpr | @addexpr | @subexpr | @mulexpr | @divexpr | @modexpr | @expexpr | @bitorexpr | @xorexpr | @bitandexpr | @inexpr | @instanceofexpr | @logandexpr | @logorexpr | @nullishcoalescingexpr; + +@assignment = @assignexpr | @assignaddexpr | @assignsubexpr | @assignmulexpr | @assigndivexpr | @assignmodexpr | @assignexpexpr | @assignlshiftexpr | @assignrshiftexpr | @assignurshiftexpr | @assignorexpr | @assignxorexpr | @assignandexpr; + +@updateexpr = @preincexpr | @postincexpr | @predecexpr | @postdecexpr; + +@pattern = @varref | @arraypattern | @objectpattern; + +@comprehensionexpr = @arraycomprehensionexpr | @generatorexpr; + +@comprehensionblock = @forincomprehensionblock | @forofcomprehensionblock; + +@importspecifier = @namedimportspecifier | @importdefaultspecifier | @importnamespacespecifier; + +@exportspecifier = @namedexportspecifier | @exportdefaultspecifier | @exportnamespacespecifier; + +@typeassertion = @astypeassertion | @prefixtypeassertion; + +@classdefinition = @classdeclstmt | @classexpr; +@interfacedefinition = @interfacedeclaration | @interfacetypeexpr; +@classorinterface = @classdefinition | @interfacedefinition; + +@lexical_decl = @vardecl | @typedecl; +@lexical_access = @varaccess | @localtypeaccess | @localvartypeaccess | @localnamespaceaccess; +@lexical_ref = @lexical_decl | @lexical_access; + +@e4x_xml_attribute_selector = @e4x_xml_static_attribute_selector | @e4x_xml_dynamic_attribute_selector; +@e4x_xml_qualident = @e4x_xml_static_qualident | @e4x_xml_dynamic_qualident; + +// scopes +scopes (unique int id: @scope, + int kind: int ref); + +case @scope.kind of + 0 = @globalscope +| 1 = @functionscope +| 2 = @catchscope +| 3 = @modulescope +| 4 = @blockscope +| 5 = @forscope +| 6 = @forinscope // for-of scopes work the same as for-in scopes +| 7 = @comprehensionblockscope +| 8 = @classexprscope +| 9 = @namespacescope +| 10 = @classdeclscope +| 11 = @interfacescope +| 12 = @typealiasscope +| 13 = @mappedtypescope +| 14 = @enumscope +| 15 = @externalmodulescope +| 16 = @conditionaltypescope; + +scopenodes (unique int node: @ast_node ref, + int scope: @scope ref); + +scopenesting (unique int inner: @scope ref, + int outer: @scope ref); + +// functions +@function = @functiondeclstmt | @functionexpr | @arrowfunctionexpr; + +@parameterized = @function | @catchclause; +@type_parameterized = @function | @classorinterface | @typealiasdeclaration | @mappedtypeexpr | @infertypeexpr; + +isGenerator (int fun: @function ref); +hasRestParameter (int fun: @function ref); +isAsync (int fun: @function ref); + +// variables and lexically scoped type names +#keyset[scope, name] +variables (unique int id: @variable, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_type_names (unique int id: @local_type_name, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_namespace_names (unique int id: @local_namespace_name, + varchar(900) name: string ref, + int scope: @scope ref); + +isArgumentsObject (int id: @variable ref); + +@lexical_name = @variable | @local_type_name | @local_namespace_name; + +@bind_id = @varaccess | @localvartypeaccess; +bind (unique int id: @bind_id ref, + int decl: @variable ref); + +decl (unique int id: @vardecl ref, + int decl: @variable ref); + +@typebind_id = @localtypeaccess | @export_varaccess; +typebind (unique int id: @typebind_id ref, + int decl: @local_type_name ref); + +@typedecl_id = @typedecl | @vardecl; +typedecl (unique int id: @typedecl_id ref, + int decl: @local_type_name ref); + +namespacedecl (unique int id: @vardecl ref, + int decl: @local_namespace_name ref); + +@namespacebind_id = @localnamespaceaccess | @export_varaccess; +namespacebind (unique int id: @namespacebind_id ref, + int decl: @local_namespace_name ref); + + +// properties in object literals, property patterns in object patterns, and method declarations in classes +#keyset[parent, index] +properties (unique int id: @property, + int parent: @property_parent ref, + int index: int ref, + int kind: int ref, + varchar(900) tostring: string ref); + +case @property.kind of + 0 = @value_property +| 1 = @property_getter +| 2 = @property_setter +| 3 = @jsx_attribute +| 4 = @function_call_signature +| 5 = @constructor_call_signature +| 6 = @index_signature +| 7 = @enum_member +| 8 = @proper_field +| 9 = @parameter_field +; + +@property_parent = @objexpr | @objectpattern | @classdefinition | @jsxelement | @interfacedefinition | @enumdeclaration; +@property_accessor = @property_getter | @property_setter; +@call_signature = @function_call_signature | @constructor_call_signature; +@field = @proper_field | @parameter_field; +@field_or_vardeclarator = @field | @vardeclarator; + +isComputed (int id: @property ref); +isMethod (int id: @property ref); +isStatic (int id: @property ref); +isAbstractMember (int id: @property ref); +isConstEnum (int id: @enumdeclaration ref); +isAbstractClass (int id: @classdeclstmt ref); + +hasPublicKeyword (int id: @property ref); +hasPrivateKeyword (int id: @property ref); +hasProtectedKeyword (int id: @property ref); +hasReadonlyKeyword (int id: @property ref); +isOptionalMember (int id: @property ref); +hasDefiniteAssignmentAssertion (int id: @field_or_vardeclarator ref); + +#keyset[constructor, param_index] +parameter_fields( + unique int field: @parameter_field ref, + int constructor: @functionexpr ref, + int param_index: int ref +); + +// types +#keyset[parent, idx] +typeexprs ( + unique int id: @typeexpr, + int kind: int ref, + int parent: @typeexpr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref +); + +case @typeexpr.kind of + 0 = @localtypeaccess +| 1 = @typedecl +| 2 = @keywordtypeexpr +| 3 = @stringliteraltypeexpr +| 4 = @numberliteraltypeexpr +| 5 = @booleanliteraltypeexpr +| 6 = @arraytypeexpr +| 7 = @uniontypeexpr +| 8 = @indexedaccesstypeexpr +| 9 = @intersectiontypeexpr +| 10 = @parenthesizedtypeexpr +| 11 = @tupletypeexpr +| 12 = @keyoftypeexpr +| 13 = @qualifiedtypeaccess +| 14 = @generictypeexpr +| 15 = @typelabel +| 16 = @typeoftypeexpr +| 17 = @localvartypeaccess +| 18 = @qualifiedvartypeaccess +| 19 = @thisvartypeaccess +| 20 = @istypeexpr +| 21 = @interfacetypeexpr +| 22 = @typeparameter +| 23 = @plainfunctiontypeexpr +| 24 = @constructortypeexpr +| 25 = @localnamespaceaccess +| 26 = @qualifiednamespaceaccess +| 27 = @mappedtypeexpr +| 28 = @conditionaltypeexpr +| 29 = @infertypeexpr +| 30 = @importtypeaccess +| 31 = @importnamespaceaccess +| 32 = @importvartypeaccess +| 33 = @optionaltypeexpr +| 34 = @resttypeexpr +| 35 = @bigintliteraltypeexpr +| 36 = @readonlytypeexpr +; + +@typeref = @typeaccess | @typedecl; +@typeidentifier = @typedecl | @localtypeaccess | @typelabel | @localvartypeaccess | @localnamespaceaccess; +@typeexpr_parent = @expr | @stmt | @property | @typeexpr; +@literaltypeexpr = @stringliteraltypeexpr | @numberliteraltypeexpr | @booleanliteraltypeexpr | @bigintliteraltypeexpr; +@typeaccess = @localtypeaccess | @qualifiedtypeaccess | @importtypeaccess; +@vartypeaccess = @localvartypeaccess | @qualifiedvartypeaccess | @thisvartypeaccess | @importvartypeaccess; +@namespaceaccess = @localnamespaceaccess | @qualifiednamespaceaccess | @importnamespaceaccess; +@importtypeexpr = @importtypeaccess | @importnamespaceaccess | @importvartypeaccess; + +@functiontypeexpr = @plainfunctiontypeexpr | @constructortypeexpr; + +// types +types ( + unique int id: @type, + int kind: int ref, + varchar(900) tostring: string ref +); + +#keyset[parent, idx] +type_child ( + int child: @type ref, + int parent: @type ref, + int idx: int ref +); + +case @type.kind of + 0 = @anytype +| 1 = @stringtype +| 2 = @numbertype +| 3 = @uniontype +| 4 = @truetype +| 5 = @falsetype +| 6 = @typereference +| 7 = @objecttype +| 8 = @canonicaltypevariabletype +| 9 = @typeoftype +| 10 = @voidtype +| 11 = @undefinedtype +| 12 = @nulltype +| 13 = @nevertype +| 14 = @plainsymboltype +| 15 = @uniquesymboltype +| 16 = @objectkeywordtype +| 17 = @intersectiontype +| 18 = @tupletype +| 19 = @lexicaltypevariabletype +| 20 = @thistype +| 21 = @numberliteraltype +| 22 = @stringliteraltype +| 23 = @unknowntype +| 24 = @biginttype +| 25 = @bigintliteraltype +; + +@booleanliteraltype = @truetype | @falsetype; +@symboltype = @plainsymboltype | @uniquesymboltype; +@unionorintersectiontype = @uniontype | @intersectiontype; +@typevariabletype = @canonicaltypevariabletype | @lexicaltypevariabletype; + +@typed_ast_node = @expr | @typeexpr | @function; +ast_node_type( + unique int node: @typed_ast_node ref, + int typ: @type ref); + +declared_function_signature( + unique int node: @function ref, + int sig: @signature_type ref +); + +invoke_expr_signature( + unique int node: @invokeexpr ref, + int sig: @signature_type ref +); + +invoke_expr_overload_index( + unique int node: @invokeexpr ref, + int index: int ref +); + +symbols ( + unique int id: @symbol, + int kind: int ref, + varchar(900) name: string ref +); + +symbol_parent ( + unique int symbol: @symbol ref, + int parent: @symbol ref +); + +symbol_module ( + int symbol: @symbol ref, + varchar(900) moduleName: string ref +); + +symbol_global ( + int symbol: @symbol ref, + varchar(900) globalName: string ref +); + +case @symbol.kind of + 0 = @root_symbol +| 1 = @member_symbol +| 2 = @other_symbol +; + +@type_with_symbol = @typereference | @typevariabletype | @typeoftype | @uniquesymboltype; +@ast_node_with_symbol = @typedefinition | @namespacedefinition | @toplevel | @typeaccess | @namespaceaccess | @vardecl | @function | @invokeexpr; + +ast_node_symbol( + unique int node: @ast_node_with_symbol ref, + int symbol: @symbol ref); + +type_symbol( + unique int typ: @type_with_symbol ref, + int symbol: @symbol ref); + +#keyset[typ, name] +type_property( + int typ: @type ref, + varchar(900) name: string ref, + int propertyType: @type ref); + +@literaltype = @stringliteraltype | @numberliteraltype | @booleanliteraltype | @bigintliteraltype; +@type_with_literal_value = @stringliteraltype | @numberliteraltype | @bigintliteraltype; +type_literal_value( + unique int typ: @type_with_literal_value ref, + varchar(900) value: string ref); + +signature_types ( + unique int id: @signature_type, + int kind: int ref, + varchar(900) tostring: string ref, + int type_parameters: int ref, + int required_params: int ref +); + +case @signature_type.kind of + 0 = @function_signature_type +| 1 = @constructor_signature_type +; + +#keyset[typ, kind, index] +type_contains_signature ( + int typ: @type ref, + int kind: int ref, // constructor/call/index + int index: int ref, // ordering of overloaded signatures + int sig: @signature_type ref +); + +#keyset[parent, index] +signature_contains_type ( + int child: @type ref, + int parent: @signature_type ref, + int index: int ref +); + +#keyset[sig, index] +signature_parameter_name ( + int sig: @signature_type ref, + int index: int ref, + varchar(900) name: string ref +); + +number_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +string_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +base_type_names( + int typeName: @symbol ref, + int baseTypeName: @symbol ref +); + +self_types( + int typeName: @symbol ref, + int selfType: @typereference ref +); + +tuple_type_min_length( + unique int typ: @type ref, + int minLength: int ref +); + +tuple_type_rest( + unique int typ: @type ref +); + +// comments +comments (unique int id: @comment, + int kind: int ref, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(900) tostring: string ref); + +case @comment.kind of + 0 = @slashslashcomment +| 1 = @slashstarcomment +| 2 = @doccomment +| 3 = @htmlcommentstart +| 4 = @htmlcommentend; + +@htmlcomment = @htmlcommentstart | @htmlcommentend; +@linecomment = @slashslashcomment | @htmlcomment; +@blockcomment = @slashstarcomment | @doccomment; + +// source lines +lines (unique int id: @line, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(2) terminator: string ref); +indentation (int file: @file ref, + int lineno: int ref, + varchar(1) indentChar: string ref, + int indentDepth: int ref); + +// JavaScript parse errors +jsParseErrors (unique int id: @js_parse_error, + int toplevel: @toplevel ref, + varchar(900) message: string ref, + varchar(900) line: string ref); + +// regular expressions +#keyset[parent, idx] +regexpterm (unique int id: @regexpterm, + int kind: int ref, + int parent: @regexpparent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +@regexpparent = @regexpterm | @regexpliteral; + +case @regexpterm.kind of + 0 = @regexp_alt +| 1 = @regexp_seq +| 2 = @regexp_caret +| 3 = @regexp_dollar +| 4 = @regexp_wordboundary +| 5 = @regexp_nonwordboundary +| 6 = @regexp_positive_lookahead +| 7 = @regexp_negative_lookahead +| 8 = @regexp_star +| 9 = @regexp_plus +| 10 = @regexp_opt +| 11 = @regexp_range +| 12 = @regexp_dot +| 13 = @regexp_group +| 14 = @regexp_normal_char +| 15 = @regexp_hex_escape +| 16 = @regexp_unicode_escape +| 17 = @regexp_dec_escape +| 18 = @regexp_oct_escape +| 19 = @regexp_ctrl_escape +| 20 = @regexp_char_class_escape +| 21 = @regexp_id_escape +| 22 = @regexp_backref +| 23 = @regexp_char_class +| 24 = @regexp_char_range +| 25 = @regexp_positive_lookbehind +| 26 = @regexp_negative_lookbehind +| 27 = @regexp_unicode_property_escape; + +regexpParseErrors (unique int id: @regexp_parse_error, + int regexp: @regexpterm ref, + varchar(900) message: string ref); + +@regexp_quantifier = @regexp_star | @regexp_plus | @regexp_opt | @regexp_range; +@regexp_escape = @regexp_char_escape | @regexp_char_class_escape | @regexp_unicode_property_escape; +@regexp_char_escape = @regexp_hex_escape | @regexp_unicode_escape | @regexp_dec_escape | @regexp_oct_escape | @regexp_ctrl_escape | @regexp_id_escape; +@regexp_constant = @regexp_normal_char | @regexp_char_escape; +@regexp_lookahead = @regexp_positive_lookahead | @regexp_negative_lookahead; +@regexp_lookbehind = @regexp_positive_lookbehind | @regexp_negative_lookbehind; +@regexp_subpattern = @regexp_lookahead | @regexp_lookbehind; + +isGreedy (int id: @regexp_quantifier ref); +rangeQuantifierLowerBound (unique int id: @regexp_range ref, int lo: int ref); +rangeQuantifierUpperBound (unique int id: @regexp_range ref, int hi: int ref); +isCapture (unique int id: @regexp_group ref, int number: int ref); +isNamedCapture (unique int id: @regexp_group ref, string name: string ref); +isInverted (int id: @regexp_char_class ref); +regexpConstValue (unique int id: @regexp_constant ref, varchar(1) value: string ref); +charClassEscape (unique int id: @regexp_char_class_escape ref, varchar(1) value: string ref); +backref (unique int id: @regexp_backref ref, int value: int ref); +namedBackref (unique int id: @regexp_backref ref, string name: string ref); +unicodePropertyEscapeName (unique int id: @regexp_unicode_property_escape ref, string name: string ref); +unicodePropertyEscapeValue (unique int id: @regexp_unicode_property_escape ref, string value: string ref); + +// tokens +#keyset[toplevel, idx] +tokeninfo (unique int id: @token, + int kind: int ref, + int toplevel: @toplevel ref, + int idx: int ref, + varchar(900) value: string ref); + +case @token.kind of + 0 = @token_eof +| 1 = @token_null_literal +| 2 = @token_boolean_literal +| 3 = @token_numeric_literal +| 4 = @token_string_literal +| 5 = @token_regular_expression +| 6 = @token_identifier +| 7 = @token_keyword +| 8 = @token_punctuator; + +// associate comments with the token immediately following them (which may be EOF) +next_token (int comment: @comment ref, int token: @token ref); + +// JSON +#keyset[parent, idx] +json (unique int id: @json_value, + int kind: int ref, + int parent: @json_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +json_literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @json_value ref); + +json_properties (int obj: @json_object ref, + varchar(900) property: string ref, + int value: @json_value ref); + +json_errors (unique int id: @json_parse_error, + varchar(900) message: string ref); + +json_locations(unique int locatable: @json_locatable ref, + int location: @location_default ref); + +case @json_value.kind of + 0 = @json_null +| 1 = @json_boolean +| 2 = @json_number +| 3 = @json_string +| 4 = @json_array +| 5 = @json_object; + +@json_parent = @json_object | @json_array | @file; + +@json_locatable = @json_value | @json_parse_error; + +// locations +@ast_node = @toplevel | @stmt | @expr | @property | @typeexpr; + +@locatable = @file + | @ast_node + | @comment + | @line + | @js_parse_error | @regexp_parse_error + | @regexpterm + | @json_locatable + | @token + | @cfg_node + | @jsdoc | @jsdoc_type_expr | @jsdoc_tag + | @yaml_locatable + | @xmllocatable + | @configLocatable; + +hasLocation (unique int locatable: @locatable ref, + int location: @location ref); + +// CFG +entry_cfg_node (unique int id: @entry_node, int container: @stmt_container ref); +exit_cfg_node (unique int id: @exit_node, int container: @stmt_container ref); +guard_node (unique int id: @guard_node, int kind: int ref, int test: @expr ref); +case @guard_node.kind of + 0 = @falsy_guard +| 1 = @truthy_guard; +@condition_guard = @falsy_guard | @truthy_guard; + +@synthetic_cfg_node = @entry_node | @exit_node | @guard_node; +@cfg_node = @synthetic_cfg_node | @exprparent; + +successor (int pred: @cfg_node ref, int succ: @cfg_node ref); + +// JSDoc comments +jsdoc (unique int id: @jsdoc, varchar(900) description: string ref, int comment: @comment ref); +#keyset[parent, idx] +jsdoc_tags (unique int id: @jsdoc_tag, varchar(900) title: string ref, + int parent: @jsdoc ref, int idx: int ref, varchar(900) tostring: string ref); +jsdoc_tag_descriptions (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); +jsdoc_tag_names (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); + +#keyset[parent, idx] +jsdoc_type_exprs (unique int id: @jsdoc_type_expr, + int kind: int ref, + int parent: @jsdoc_type_expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); +case @jsdoc_type_expr.kind of + 0 = @jsdoc_any_type_expr +| 1 = @jsdoc_null_type_expr +| 2 = @jsdoc_undefined_type_expr +| 3 = @jsdoc_unknown_type_expr +| 4 = @jsdoc_void_type_expr +| 5 = @jsdoc_named_type_expr +| 6 = @jsdoc_applied_type_expr +| 7 = @jsdoc_nullable_type_expr +| 8 = @jsdoc_non_nullable_type_expr +| 9 = @jsdoc_record_type_expr +| 10 = @jsdoc_array_type_expr +| 11 = @jsdoc_union_type_expr +| 12 = @jsdoc_function_type_expr +| 13 = @jsdoc_optional_type_expr +| 14 = @jsdoc_rest_type_expr +; + +#keyset[id, idx] +jsdoc_record_field_name (int id: @jsdoc_record_type_expr ref, int idx: int ref, varchar(900) name: string ref); +jsdoc_prefix_qualifier (int id: @jsdoc_type_expr ref); +jsdoc_has_new_parameter (int fn: @jsdoc_function_type_expr ref); + +@jsdoc_type_expr_parent = @jsdoc_type_expr | @jsdoc_tag; + +jsdoc_errors (unique int id: @jsdoc_error, int tag: @jsdoc_tag ref, varchar(900) message: string ref, varchar(900) tostring: string ref); + +// YAML +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + varchar(900) tag: string ref, + varchar(900) tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + varchar(900) anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + varchar(900) target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + varchar(900) value: string ref); + +yaml_errors (unique int id: @yaml_error, + varchar(900) message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/* XML Files */ + +xmlEncoding( + unique int id: @file ref, + varchar(900) encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + varchar(900) root: string ref, + varchar(900) publicId: string ref, + varchar(900) systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + varchar(900) name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + varchar(900) name: string ref, + varchar(3600) value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + varchar(900) prefixName: string ref, + varchar(900) URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +@dataflownode = @expr | @functiondeclstmt | @classdeclstmt | @namespacedeclaration | @enumdeclaration | @property; + +@optionalchainable = @callexpr | @propaccess; + +isOptionalChaining(int id: @optionalchainable ref); + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +/** + * The time taken for the extraction of a file. + * This table contains non-deterministic content. + * + * The sum of the `time` column for each (`file`, `timerKind`) pair + * is the total time taken for extraction of `file`. The `extractionPhase` + * column provides a granular view of the extraction time of the file. + */ +extraction_time( + int file : @file ref, + // see `com.semmle.js.extractor.ExtractionMetrics.ExtractionPhase`. + int extractionPhase: int ref, + // 0 for the elapsed CPU time in nanoseconds, 1 for the elapsed wallclock time in nanoseconds + int timerKind: int ref, + float time: float ref +) + +/** + * Non-timing related data for the extraction of a single file. + * This table contains non-deterministic content. + */ +extraction_data( + int file : @file ref, + // the absolute path to the cache file + varchar(900) cacheFile: string ref, + boolean fromCache: boolean ref, + int length: int ref +) diff --git a/javascript/upgrades/874ebfcd4d2fd346c10ebec145466d9071d78606/semmlecode.javascript.dbscheme b/javascript/upgrades/874ebfcd4d2fd346c10ebec145466d9071d78606/semmlecode.javascript.dbscheme new file mode 100644 index 00000000000..5a5adbf98dc --- /dev/null +++ b/javascript/upgrades/874ebfcd4d2fd346c10ebec145466d9071d78606/semmlecode.javascript.dbscheme @@ -0,0 +1,1175 @@ +/*** Standard fragments ***/ + +/** Files and folders **/ + +@location = @location_default; + +locations_default(unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref + ); + +@sourceline = @locatable; + +numlines(int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref + ); + + +/* + fromSource(0) = unknown, + fromSource(1) = from source, + fromSource(2) = from library +*/ +files(unique int id: @file, + varchar(900) name: string ref, + varchar(900) simple: string ref, + varchar(900) ext: string ref, + int fromSource: int ref); + +folders(unique int id: @folder, + varchar(900) name: string ref, + varchar(900) simple: string ref); + + +@container = @folder | @file ; + + +containerparent(int parent: @container ref, + unique int child: @container ref); + +/** Duplicate code **/ + +duplicateCode( + unique int id : @duplication, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +similarCode( + unique int id : @similarity, + varchar(900) relativePath : string ref, + int equivClass : int ref); + +@duplication_or_similarity = @duplication | @similarity; + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref); + +/** External data **/ + +externalData( + int id : @externalDataElement, + varchar(900) path : string ref, + int column: int ref, + varchar(900) value : string ref +); + +snapshotDate(unique date snapshotDate : date ref); + +sourceLocationPrefix(varchar(900) prefix : string ref); + +/** Version control data **/ + +svnentries( + int id : @svnentry, + varchar(500) revision : string ref, + varchar(500) author : string ref, + date revisionDate : date ref, + int changeSize : int ref +); + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + varchar(500) action : string ref +); + +svnentrymsg( + int id : @svnentry ref, + varchar(500) message : string ref +); + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +); + + +/*** JavaScript-specific part ***/ + +filetype( + int file: @file ref, + string filetype: string ref +) + +// top-level code fragments +toplevels (unique int id: @toplevel, + int kind: int ref); + +isExterns (int toplevel: @toplevel ref); + +case @toplevel.kind of + 0 = @script +| 1 = @inline_script +| 2 = @event_handler +| 3 = @javascript_url; + +isModule (int tl: @toplevel ref); +isNodejs (int tl: @toplevel ref); +isES2015Module (int tl: @toplevel ref); +isClosureModule (int tl: @toplevel ref); + +// statements +#keyset[parent, idx] +stmts (unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +stmtContainers (unique int stmt: @stmt ref, + int container: @stmt_container ref); + +jumpTargets (unique int jump: @stmt ref, + int target: @stmt ref); + +@stmtparent = @stmt | @toplevel | @functionexpr | @arrowfunctionexpr; +@stmt_container = @toplevel | @function | @namespacedeclaration | @externalmoduledeclaration | @globalaugmentationdeclaration; + +case @stmt.kind of + 0 = @emptystmt +| 1 = @blockstmt +| 2 = @exprstmt +| 3 = @ifstmt +| 4 = @labeledstmt +| 5 = @breakstmt +| 6 = @continuestmt +| 7 = @withstmt +| 8 = @switchstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @trystmt +| 12 = @whilestmt +| 13 = @dowhilestmt +| 14 = @forstmt +| 15 = @forinstmt +| 16 = @debuggerstmt +| 17 = @functiondeclstmt +| 18 = @vardeclstmt +| 19 = @case +| 20 = @catchclause +| 21 = @forofstmt +| 22 = @constdeclstmt +| 23 = @letstmt +| 24 = @legacy_letstmt +| 25 = @foreachstmt +| 26 = @classdeclstmt +| 27 = @importdeclaration +| 28 = @exportalldeclaration +| 29 = @exportdefaultdeclaration +| 30 = @exportnameddeclaration +| 31 = @namespacedeclaration +| 32 = @importequalsdeclaration +| 33 = @exportassigndeclaration +| 34 = @interfacedeclaration +| 35 = @typealiasdeclaration +| 36 = @enumdeclaration +| 37 = @externalmoduledeclaration +| 38 = @exportasnamespacedeclaration +| 39 = @globalaugmentationdeclaration +; + +@declstmt = @vardeclstmt | @constdeclstmt | @letstmt | @legacy_letstmt; + +@exportdeclaration = @exportalldeclaration | @exportdefaultdeclaration | @exportnameddeclaration; + +@namespacedefinition = @namespacedeclaration | @enumdeclaration; +@typedefinition = @classdefinition | @interfacedeclaration | @enumdeclaration | @typealiasdeclaration | @enum_member; + +isInstantiated(unique int decl: @namespacedeclaration ref); + +@declarablenode = @declstmt | @namespacedeclaration | @classdeclstmt | @functiondeclstmt | @enumdeclaration | @externalmoduledeclaration | @globalaugmentationdeclaration | @field; +hasDeclareKeyword(unique int stmt: @declarablenode ref); + +isForAwaitOf(unique int forof: @forofstmt ref); + +// expressions +#keyset[parent, idx] +exprs (unique int id: @expr, + int kind: int ref, + int parent: @exprparent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @exprortype ref); + +enclosingStmt (unique int expr: @exprortype ref, + int stmt: @stmt ref); + +exprContainers (unique int expr: @exprortype ref, + int container: @stmt_container ref); + +arraySize (unique int ae: @arraylike ref, + int sz: int ref); + +isDelegating (int yield: @yieldexpr ref); + +@exprorstmt = @expr | @stmt; +@exprortype = @expr | @typeexpr; +@exprparent = @exprorstmt | @property | @functiontypeexpr; +@arraylike = @arrayexpr | @arraypattern; +@type_annotation = @typeexpr | @jsdoc_type_expr; + +case @expr.kind of + 0 = @label +| 1 = @nullliteral +| 2 = @booleanliteral +| 3 = @numberliteral +| 4 = @stringliteral +| 5 = @regexpliteral +| 6 = @thisexpr +| 7 = @arrayexpr +| 8 = @objexpr +| 9 = @functionexpr +| 10 = @seqexpr +| 11 = @conditionalexpr +| 12 = @newexpr +| 13 = @callexpr +| 14 = @dotexpr +| 15 = @indexexpr +| 16 = @negexpr +| 17 = @plusexpr +| 18 = @lognotexpr +| 19 = @bitnotexpr +| 20 = @typeofexpr +| 21 = @voidexpr +| 22 = @deleteexpr +| 23 = @eqexpr +| 24 = @neqexpr +| 25 = @eqqexpr +| 26 = @neqqexpr +| 27 = @ltexpr +| 28 = @leexpr +| 29 = @gtexpr +| 30 = @geexpr +| 31 = @lshiftexpr +| 32 = @rshiftexpr +| 33 = @urshiftexpr +| 34 = @addexpr +| 35 = @subexpr +| 36 = @mulexpr +| 37 = @divexpr +| 38 = @modexpr +| 39 = @bitorexpr +| 40 = @xorexpr +| 41 = @bitandexpr +| 42 = @inexpr +| 43 = @instanceofexpr +| 44 = @logandexpr +| 45 = @logorexpr +| 47 = @assignexpr +| 48 = @assignaddexpr +| 49 = @assignsubexpr +| 50 = @assignmulexpr +| 51 = @assigndivexpr +| 52 = @assignmodexpr +| 53 = @assignlshiftexpr +| 54 = @assignrshiftexpr +| 55 = @assignurshiftexpr +| 56 = @assignorexpr +| 57 = @assignxorexpr +| 58 = @assignandexpr +| 59 = @preincexpr +| 60 = @postincexpr +| 61 = @predecexpr +| 62 = @postdecexpr +| 63 = @parexpr +| 64 = @vardeclarator +| 65 = @arrowfunctionexpr +| 66 = @spreadelement +| 67 = @arraypattern +| 68 = @objectpattern +| 69 = @yieldexpr +| 70 = @taggedtemplateexpr +| 71 = @templateliteral +| 72 = @templateelement +| 73 = @arraycomprehensionexpr +| 74 = @generatorexpr +| 75 = @forincomprehensionblock +| 76 = @forofcomprehensionblock +| 77 = @legacy_letexpr +| 78 = @vardecl +| 79 = @proper_varaccess +| 80 = @classexpr +| 81 = @superexpr +| 82 = @newtargetexpr +| 83 = @namedimportspecifier +| 84 = @importdefaultspecifier +| 85 = @importnamespacespecifier +| 86 = @namedexportspecifier +| 87 = @expexpr +| 88 = @assignexpexpr +| 89 = @jsxelement +| 90 = @jsxqualifiedname +| 91 = @jsxemptyexpr +| 92 = @awaitexpr +| 93 = @functionsentexpr +| 94 = @decorator +| 95 = @exportdefaultspecifier +| 96 = @exportnamespacespecifier +| 97 = @bindexpr +| 98 = @externalmodulereference +| 99 = @dynamicimport +| 100 = @expressionwithtypearguments +| 101 = @prefixtypeassertion +| 102 = @astypeassertion +| 103 = @export_varaccess +| 104 = @decorator_list +| 105 = @non_null_assertion +| 106 = @bigintliteral +| 107 = @nullishcoalescingexpr +| 108 = @e4x_xml_anyname +| 109 = @e4x_xml_static_attribute_selector +| 110 = @e4x_xml_dynamic_attribute_selector +| 111 = @e4x_xml_filter_expression +| 112 = @e4x_xml_static_qualident +| 113 = @e4x_xml_dynamic_qualident +| 114 = @e4x_xml_dotdotexpr +| 115 = @importmetaexpr +; + +@varaccess = @proper_varaccess | @export_varaccess; +@varref = @vardecl | @varaccess; + +@identifier = @label | @varref | @typeidentifier; + +@literal = @nullliteral | @booleanliteral | @numberliteral | @stringliteral | @regexpliteral | @bigintliteral; + +@propaccess = @dotexpr | @indexexpr; + +@invokeexpr = @newexpr | @callexpr; + +@unaryexpr = @negexpr | @plusexpr | @lognotexpr | @bitnotexpr | @typeofexpr | @voidexpr | @deleteexpr | @spreadelement; + +@equalitytest = @eqexpr | @neqexpr | @eqqexpr | @neqqexpr; + +@comparison = @equalitytest | @ltexpr | @leexpr | @gtexpr | @geexpr; + +@binaryexpr = @comparison | @lshiftexpr | @rshiftexpr | @urshiftexpr | @addexpr | @subexpr | @mulexpr | @divexpr | @modexpr | @expexpr | @bitorexpr | @xorexpr | @bitandexpr | @inexpr | @instanceofexpr | @logandexpr | @logorexpr | @nullishcoalescingexpr; + +@assignment = @assignexpr | @assignaddexpr | @assignsubexpr | @assignmulexpr | @assigndivexpr | @assignmodexpr | @assignexpexpr | @assignlshiftexpr | @assignrshiftexpr | @assignurshiftexpr | @assignorexpr | @assignxorexpr | @assignandexpr; + +@updateexpr = @preincexpr | @postincexpr | @predecexpr | @postdecexpr; + +@pattern = @varref | @arraypattern | @objectpattern; + +@comprehensionexpr = @arraycomprehensionexpr | @generatorexpr; + +@comprehensionblock = @forincomprehensionblock | @forofcomprehensionblock; + +@importspecifier = @namedimportspecifier | @importdefaultspecifier | @importnamespacespecifier; + +@exportspecifier = @namedexportspecifier | @exportdefaultspecifier | @exportnamespacespecifier; + +@typeassertion = @astypeassertion | @prefixtypeassertion; + +@classdefinition = @classdeclstmt | @classexpr; +@interfacedefinition = @interfacedeclaration | @interfacetypeexpr; +@classorinterface = @classdefinition | @interfacedefinition; + +@lexical_decl = @vardecl | @typedecl; +@lexical_access = @varaccess | @localtypeaccess | @localvartypeaccess | @localnamespaceaccess; +@lexical_ref = @lexical_decl | @lexical_access; + +@e4x_xml_attribute_selector = @e4x_xml_static_attribute_selector | @e4x_xml_dynamic_attribute_selector; +@e4x_xml_qualident = @e4x_xml_static_qualident | @e4x_xml_dynamic_qualident; + +// scopes +scopes (unique int id: @scope, + int kind: int ref); + +case @scope.kind of + 0 = @globalscope +| 1 = @functionscope +| 2 = @catchscope +| 3 = @modulescope +| 4 = @blockscope +| 5 = @forscope +| 6 = @forinscope // for-of scopes work the same as for-in scopes +| 7 = @comprehensionblockscope +| 8 = @classexprscope +| 9 = @namespacescope +| 10 = @classdeclscope +| 11 = @interfacescope +| 12 = @typealiasscope +| 13 = @mappedtypescope +| 14 = @enumscope +| 15 = @externalmodulescope +| 16 = @conditionaltypescope; + +scopenodes (unique int node: @ast_node ref, + int scope: @scope ref); + +scopenesting (unique int inner: @scope ref, + int outer: @scope ref); + +// functions +@function = @functiondeclstmt | @functionexpr | @arrowfunctionexpr; + +@parameterized = @function | @catchclause; +@type_parameterized = @function | @classorinterface | @typealiasdeclaration | @mappedtypeexpr | @infertypeexpr; + +isGenerator (int fun: @function ref); +hasRestParameter (int fun: @function ref); +isAsync (int fun: @function ref); + +// variables and lexically scoped type names +#keyset[scope, name] +variables (unique int id: @variable, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_type_names (unique int id: @local_type_name, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_namespace_names (unique int id: @local_namespace_name, + varchar(900) name: string ref, + int scope: @scope ref); + +isArgumentsObject (int id: @variable ref); + +@lexical_name = @variable | @local_type_name | @local_namespace_name; + +@bind_id = @varaccess | @localvartypeaccess; +bind (unique int id: @bind_id ref, + int decl: @variable ref); + +decl (unique int id: @vardecl ref, + int decl: @variable ref); + +@typebind_id = @localtypeaccess | @export_varaccess; +typebind (unique int id: @typebind_id ref, + int decl: @local_type_name ref); + +@typedecl_id = @typedecl | @vardecl; +typedecl (unique int id: @typedecl_id ref, + int decl: @local_type_name ref); + +namespacedecl (unique int id: @vardecl ref, + int decl: @local_namespace_name ref); + +@namespacebind_id = @localnamespaceaccess | @export_varaccess; +namespacebind (unique int id: @namespacebind_id ref, + int decl: @local_namespace_name ref); + + +// properties in object literals, property patterns in object patterns, and method declarations in classes +#keyset[parent, index] +properties (unique int id: @property, + int parent: @property_parent ref, + int index: int ref, + int kind: int ref, + varchar(900) tostring: string ref); + +case @property.kind of + 0 = @value_property +| 1 = @property_getter +| 2 = @property_setter +| 3 = @jsx_attribute +| 4 = @function_call_signature +| 5 = @constructor_call_signature +| 6 = @index_signature +| 7 = @enum_member +| 8 = @proper_field +| 9 = @parameter_field +; + +@property_parent = @objexpr | @objectpattern | @classdefinition | @jsxelement | @interfacedefinition | @enumdeclaration; +@property_accessor = @property_getter | @property_setter; +@call_signature = @function_call_signature | @constructor_call_signature; +@field = @proper_field | @parameter_field; +@field_or_vardeclarator = @field | @vardeclarator; + +isComputed (int id: @property ref); +isMethod (int id: @property ref); +isStatic (int id: @property ref); +isAbstractMember (int id: @property ref); +isConstEnum (int id: @enumdeclaration ref); +isAbstractClass (int id: @classdeclstmt ref); + +hasPublicKeyword (int id: @property ref); +hasPrivateKeyword (int id: @property ref); +hasProtectedKeyword (int id: @property ref); +hasReadonlyKeyword (int id: @property ref); +isOptionalMember (int id: @property ref); +hasDefiniteAssignmentAssertion (int id: @field_or_vardeclarator ref); + +#keyset[constructor, param_index] +parameter_fields( + unique int field: @parameter_field ref, + int constructor: @functionexpr ref, + int param_index: int ref +); + +// types +#keyset[parent, idx] +typeexprs ( + unique int id: @typeexpr, + int kind: int ref, + int parent: @typeexpr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref +); + +case @typeexpr.kind of + 0 = @localtypeaccess +| 1 = @typedecl +| 2 = @keywordtypeexpr +| 3 = @stringliteraltypeexpr +| 4 = @numberliteraltypeexpr +| 5 = @booleanliteraltypeexpr +| 6 = @arraytypeexpr +| 7 = @uniontypeexpr +| 8 = @indexedaccesstypeexpr +| 9 = @intersectiontypeexpr +| 10 = @parenthesizedtypeexpr +| 11 = @tupletypeexpr +| 12 = @keyoftypeexpr +| 13 = @qualifiedtypeaccess +| 14 = @generictypeexpr +| 15 = @typelabel +| 16 = @typeoftypeexpr +| 17 = @localvartypeaccess +| 18 = @qualifiedvartypeaccess +| 19 = @thisvartypeaccess +| 20 = @predicatetypeexpr +| 21 = @interfacetypeexpr +| 22 = @typeparameter +| 23 = @plainfunctiontypeexpr +| 24 = @constructortypeexpr +| 25 = @localnamespaceaccess +| 26 = @qualifiednamespaceaccess +| 27 = @mappedtypeexpr +| 28 = @conditionaltypeexpr +| 29 = @infertypeexpr +| 30 = @importtypeaccess +| 31 = @importnamespaceaccess +| 32 = @importvartypeaccess +| 33 = @optionaltypeexpr +| 34 = @resttypeexpr +| 35 = @bigintliteraltypeexpr +| 36 = @readonlytypeexpr +; + +@typeref = @typeaccess | @typedecl; +@typeidentifier = @typedecl | @localtypeaccess | @typelabel | @localvartypeaccess | @localnamespaceaccess; +@typeexpr_parent = @expr | @stmt | @property | @typeexpr; +@literaltypeexpr = @stringliteraltypeexpr | @numberliteraltypeexpr | @booleanliteraltypeexpr | @bigintliteraltypeexpr; +@typeaccess = @localtypeaccess | @qualifiedtypeaccess | @importtypeaccess; +@vartypeaccess = @localvartypeaccess | @qualifiedvartypeaccess | @thisvartypeaccess | @importvartypeaccess; +@namespaceaccess = @localnamespaceaccess | @qualifiednamespaceaccess | @importnamespaceaccess; +@importtypeexpr = @importtypeaccess | @importnamespaceaccess | @importvartypeaccess; + +@functiontypeexpr = @plainfunctiontypeexpr | @constructortypeexpr; + +// types +types ( + unique int id: @type, + int kind: int ref, + varchar(900) tostring: string ref +); + +#keyset[parent, idx] +type_child ( + int child: @type ref, + int parent: @type ref, + int idx: int ref +); + +case @type.kind of + 0 = @anytype +| 1 = @stringtype +| 2 = @numbertype +| 3 = @uniontype +| 4 = @truetype +| 5 = @falsetype +| 6 = @typereference +| 7 = @objecttype +| 8 = @canonicaltypevariabletype +| 9 = @typeoftype +| 10 = @voidtype +| 11 = @undefinedtype +| 12 = @nulltype +| 13 = @nevertype +| 14 = @plainsymboltype +| 15 = @uniquesymboltype +| 16 = @objectkeywordtype +| 17 = @intersectiontype +| 18 = @tupletype +| 19 = @lexicaltypevariabletype +| 20 = @thistype +| 21 = @numberliteraltype +| 22 = @stringliteraltype +| 23 = @unknowntype +| 24 = @biginttype +| 25 = @bigintliteraltype +; + +@booleanliteraltype = @truetype | @falsetype; +@symboltype = @plainsymboltype | @uniquesymboltype; +@unionorintersectiontype = @uniontype | @intersectiontype; +@typevariabletype = @canonicaltypevariabletype | @lexicaltypevariabletype; + +hasAssertsKeyword(int node: @predicatetypeexpr ref); + +@typed_ast_node = @expr | @typeexpr | @function; +ast_node_type( + unique int node: @typed_ast_node ref, + int typ: @type ref); + +declared_function_signature( + unique int node: @function ref, + int sig: @signature_type ref +); + +invoke_expr_signature( + unique int node: @invokeexpr ref, + int sig: @signature_type ref +); + +invoke_expr_overload_index( + unique int node: @invokeexpr ref, + int index: int ref +); + +symbols ( + unique int id: @symbol, + int kind: int ref, + varchar(900) name: string ref +); + +symbol_parent ( + unique int symbol: @symbol ref, + int parent: @symbol ref +); + +symbol_module ( + int symbol: @symbol ref, + varchar(900) moduleName: string ref +); + +symbol_global ( + int symbol: @symbol ref, + varchar(900) globalName: string ref +); + +case @symbol.kind of + 0 = @root_symbol +| 1 = @member_symbol +| 2 = @other_symbol +; + +@type_with_symbol = @typereference | @typevariabletype | @typeoftype | @uniquesymboltype; +@ast_node_with_symbol = @typedefinition | @namespacedefinition | @toplevel | @typeaccess | @namespaceaccess | @vardecl | @function | @invokeexpr; + +ast_node_symbol( + unique int node: @ast_node_with_symbol ref, + int symbol: @symbol ref); + +type_symbol( + unique int typ: @type_with_symbol ref, + int symbol: @symbol ref); + +#keyset[typ, name] +type_property( + int typ: @type ref, + varchar(900) name: string ref, + int propertyType: @type ref); + +@literaltype = @stringliteraltype | @numberliteraltype | @booleanliteraltype | @bigintliteraltype; +@type_with_literal_value = @stringliteraltype | @numberliteraltype | @bigintliteraltype; +type_literal_value( + unique int typ: @type_with_literal_value ref, + varchar(900) value: string ref); + +signature_types ( + unique int id: @signature_type, + int kind: int ref, + varchar(900) tostring: string ref, + int type_parameters: int ref, + int required_params: int ref +); + +case @signature_type.kind of + 0 = @function_signature_type +| 1 = @constructor_signature_type +; + +#keyset[typ, kind, index] +type_contains_signature ( + int typ: @type ref, + int kind: int ref, // constructor/call/index + int index: int ref, // ordering of overloaded signatures + int sig: @signature_type ref +); + +#keyset[parent, index] +signature_contains_type ( + int child: @type ref, + int parent: @signature_type ref, + int index: int ref +); + +#keyset[sig, index] +signature_parameter_name ( + int sig: @signature_type ref, + int index: int ref, + varchar(900) name: string ref +); + +number_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +string_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +base_type_names( + int typeName: @symbol ref, + int baseTypeName: @symbol ref +); + +self_types( + int typeName: @symbol ref, + int selfType: @typereference ref +); + +tuple_type_min_length( + unique int typ: @type ref, + int minLength: int ref +); + +tuple_type_rest( + unique int typ: @type ref +); + +// comments +comments (unique int id: @comment, + int kind: int ref, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(900) tostring: string ref); + +case @comment.kind of + 0 = @slashslashcomment +| 1 = @slashstarcomment +| 2 = @doccomment +| 3 = @htmlcommentstart +| 4 = @htmlcommentend; + +@htmlcomment = @htmlcommentstart | @htmlcommentend; +@linecomment = @slashslashcomment | @htmlcomment; +@blockcomment = @slashstarcomment | @doccomment; + +// source lines +lines (unique int id: @line, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(2) terminator: string ref); +indentation (int file: @file ref, + int lineno: int ref, + varchar(1) indentChar: string ref, + int indentDepth: int ref); + +// JavaScript parse errors +jsParseErrors (unique int id: @js_parse_error, + int toplevel: @toplevel ref, + varchar(900) message: string ref, + varchar(900) line: string ref); + +// regular expressions +#keyset[parent, idx] +regexpterm (unique int id: @regexpterm, + int kind: int ref, + int parent: @regexpparent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +@regexpparent = @regexpterm | @regexpliteral; + +case @regexpterm.kind of + 0 = @regexp_alt +| 1 = @regexp_seq +| 2 = @regexp_caret +| 3 = @regexp_dollar +| 4 = @regexp_wordboundary +| 5 = @regexp_nonwordboundary +| 6 = @regexp_positive_lookahead +| 7 = @regexp_negative_lookahead +| 8 = @regexp_star +| 9 = @regexp_plus +| 10 = @regexp_opt +| 11 = @regexp_range +| 12 = @regexp_dot +| 13 = @regexp_group +| 14 = @regexp_normal_char +| 15 = @regexp_hex_escape +| 16 = @regexp_unicode_escape +| 17 = @regexp_dec_escape +| 18 = @regexp_oct_escape +| 19 = @regexp_ctrl_escape +| 20 = @regexp_char_class_escape +| 21 = @regexp_id_escape +| 22 = @regexp_backref +| 23 = @regexp_char_class +| 24 = @regexp_char_range +| 25 = @regexp_positive_lookbehind +| 26 = @regexp_negative_lookbehind +| 27 = @regexp_unicode_property_escape; + +regexpParseErrors (unique int id: @regexp_parse_error, + int regexp: @regexpterm ref, + varchar(900) message: string ref); + +@regexp_quantifier = @regexp_star | @regexp_plus | @regexp_opt | @regexp_range; +@regexp_escape = @regexp_char_escape | @regexp_char_class_escape | @regexp_unicode_property_escape; +@regexp_char_escape = @regexp_hex_escape | @regexp_unicode_escape | @regexp_dec_escape | @regexp_oct_escape | @regexp_ctrl_escape | @regexp_id_escape; +@regexp_constant = @regexp_normal_char | @regexp_char_escape; +@regexp_lookahead = @regexp_positive_lookahead | @regexp_negative_lookahead; +@regexp_lookbehind = @regexp_positive_lookbehind | @regexp_negative_lookbehind; +@regexp_subpattern = @regexp_lookahead | @regexp_lookbehind; + +isGreedy (int id: @regexp_quantifier ref); +rangeQuantifierLowerBound (unique int id: @regexp_range ref, int lo: int ref); +rangeQuantifierUpperBound (unique int id: @regexp_range ref, int hi: int ref); +isCapture (unique int id: @regexp_group ref, int number: int ref); +isNamedCapture (unique int id: @regexp_group ref, string name: string ref); +isInverted (int id: @regexp_char_class ref); +regexpConstValue (unique int id: @regexp_constant ref, varchar(1) value: string ref); +charClassEscape (unique int id: @regexp_char_class_escape ref, varchar(1) value: string ref); +backref (unique int id: @regexp_backref ref, int value: int ref); +namedBackref (unique int id: @regexp_backref ref, string name: string ref); +unicodePropertyEscapeName (unique int id: @regexp_unicode_property_escape ref, string name: string ref); +unicodePropertyEscapeValue (unique int id: @regexp_unicode_property_escape ref, string value: string ref); + +// tokens +#keyset[toplevel, idx] +tokeninfo (unique int id: @token, + int kind: int ref, + int toplevel: @toplevel ref, + int idx: int ref, + varchar(900) value: string ref); + +case @token.kind of + 0 = @token_eof +| 1 = @token_null_literal +| 2 = @token_boolean_literal +| 3 = @token_numeric_literal +| 4 = @token_string_literal +| 5 = @token_regular_expression +| 6 = @token_identifier +| 7 = @token_keyword +| 8 = @token_punctuator; + +// associate comments with the token immediately following them (which may be EOF) +next_token (int comment: @comment ref, int token: @token ref); + +// JSON +#keyset[parent, idx] +json (unique int id: @json_value, + int kind: int ref, + int parent: @json_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +json_literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @json_value ref); + +json_properties (int obj: @json_object ref, + varchar(900) property: string ref, + int value: @json_value ref); + +json_errors (unique int id: @json_parse_error, + varchar(900) message: string ref); + +json_locations(unique int locatable: @json_locatable ref, + int location: @location_default ref); + +case @json_value.kind of + 0 = @json_null +| 1 = @json_boolean +| 2 = @json_number +| 3 = @json_string +| 4 = @json_array +| 5 = @json_object; + +@json_parent = @json_object | @json_array | @file; + +@json_locatable = @json_value | @json_parse_error; + +// locations +@ast_node = @toplevel | @stmt | @expr | @property | @typeexpr; + +@locatable = @file + | @ast_node + | @comment + | @line + | @js_parse_error | @regexp_parse_error + | @regexpterm + | @json_locatable + | @token + | @cfg_node + | @jsdoc | @jsdoc_type_expr | @jsdoc_tag + | @yaml_locatable + | @xmllocatable + | @configLocatable; + +hasLocation (unique int locatable: @locatable ref, + int location: @location ref); + +// CFG +entry_cfg_node (unique int id: @entry_node, int container: @stmt_container ref); +exit_cfg_node (unique int id: @exit_node, int container: @stmt_container ref); +guard_node (unique int id: @guard_node, int kind: int ref, int test: @expr ref); +case @guard_node.kind of + 0 = @falsy_guard +| 1 = @truthy_guard; +@condition_guard = @falsy_guard | @truthy_guard; + +@synthetic_cfg_node = @entry_node | @exit_node | @guard_node; +@cfg_node = @synthetic_cfg_node | @exprparent; + +successor (int pred: @cfg_node ref, int succ: @cfg_node ref); + +// JSDoc comments +jsdoc (unique int id: @jsdoc, varchar(900) description: string ref, int comment: @comment ref); +#keyset[parent, idx] +jsdoc_tags (unique int id: @jsdoc_tag, varchar(900) title: string ref, + int parent: @jsdoc ref, int idx: int ref, varchar(900) tostring: string ref); +jsdoc_tag_descriptions (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); +jsdoc_tag_names (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); + +#keyset[parent, idx] +jsdoc_type_exprs (unique int id: @jsdoc_type_expr, + int kind: int ref, + int parent: @jsdoc_type_expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); +case @jsdoc_type_expr.kind of + 0 = @jsdoc_any_type_expr +| 1 = @jsdoc_null_type_expr +| 2 = @jsdoc_undefined_type_expr +| 3 = @jsdoc_unknown_type_expr +| 4 = @jsdoc_void_type_expr +| 5 = @jsdoc_named_type_expr +| 6 = @jsdoc_applied_type_expr +| 7 = @jsdoc_nullable_type_expr +| 8 = @jsdoc_non_nullable_type_expr +| 9 = @jsdoc_record_type_expr +| 10 = @jsdoc_array_type_expr +| 11 = @jsdoc_union_type_expr +| 12 = @jsdoc_function_type_expr +| 13 = @jsdoc_optional_type_expr +| 14 = @jsdoc_rest_type_expr +; + +#keyset[id, idx] +jsdoc_record_field_name (int id: @jsdoc_record_type_expr ref, int idx: int ref, varchar(900) name: string ref); +jsdoc_prefix_qualifier (int id: @jsdoc_type_expr ref); +jsdoc_has_new_parameter (int fn: @jsdoc_function_type_expr ref); + +@jsdoc_type_expr_parent = @jsdoc_type_expr | @jsdoc_tag; + +jsdoc_errors (unique int id: @jsdoc_error, int tag: @jsdoc_tag ref, varchar(900) message: string ref, varchar(900) tostring: string ref); + +// YAML +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + varchar(900) tag: string ref, + varchar(900) tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + varchar(900) anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + varchar(900) target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + varchar(900) value: string ref); + +yaml_errors (unique int id: @yaml_error, + varchar(900) message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/* XML Files */ + +xmlEncoding( + unique int id: @file ref, + varchar(900) encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + varchar(900) root: string ref, + varchar(900) publicId: string ref, + varchar(900) systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + varchar(900) name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + varchar(900) name: string ref, + varchar(3600) value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + varchar(900) prefixName: string ref, + varchar(900) URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + varchar(3600) text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +@dataflownode = @expr | @functiondeclstmt | @classdeclstmt | @namespacedeclaration | @enumdeclaration | @property; + +@optionalchainable = @callexpr | @propaccess; + +isOptionalChaining(int id: @optionalchainable ref); + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +/** + * The time taken for the extraction of a file. + * This table contains non-deterministic content. + * + * The sum of the `time` column for each (`file`, `timerKind`) pair + * is the total time taken for extraction of `file`. The `extractionPhase` + * column provides a granular view of the extraction time of the file. + */ +extraction_time( + int file : @file ref, + // see `com.semmle.js.extractor.ExtractionMetrics.ExtractionPhase`. + int extractionPhase: int ref, + // 0 for the elapsed CPU time in nanoseconds, 1 for the elapsed wallclock time in nanoseconds + int timerKind: int ref, + float time: float ref +) + +/** + * Non-timing related data for the extraction of a single file. + * This table contains non-deterministic content. + */ +extraction_data( + int file : @file ref, + // the absolute path to the cache file + varchar(900) cacheFile: string ref, + boolean fromCache: boolean ref, + int length: int ref +) diff --git a/javascript/upgrades/874ebfcd4d2fd346c10ebec145466d9071d78606/upgrade.properties b/javascript/upgrades/874ebfcd4d2fd346c10ebec145466d9071d78606/upgrade.properties new file mode 100644 index 00000000000..bf1a8cb0c61 --- /dev/null +++ b/javascript/upgrades/874ebfcd4d2fd346c10ebec145466d9071d78606/upgrade.properties @@ -0,0 +1,2 @@ +description: add support for TypeScript 3.7 features +compatibility: backwards diff --git a/javascript/upgrades/qlpack.yml b/javascript/upgrades/qlpack.yml new file mode 100644 index 00000000000..e28efab120f --- /dev/null +++ b/javascript/upgrades/qlpack.yml @@ -0,0 +1,2 @@ +name: codeql-javascript-upgrades +upgrades: . diff --git a/python/ql/src/Classes/MethodCallOrder.qll b/python/ql/src/Classes/MethodCallOrder.qll index fe6ef07266a..5073cefc134 100644 --- a/python/ql/src/Classes/MethodCallOrder.qll +++ b/python/ql/src/Classes/MethodCallOrder.qll @@ -3,11 +3,16 @@ import python // Helper predicates for multiple call to __init__/__del__ queries. pragma [noinline] -private predicate multiple_invocation_paths(FunctionInvocation top, FunctionInvocation i1, FunctionInvocation i2, FunctionObject multi) { +private predicate multiple_invocation_paths_helper(FunctionInvocation top, FunctionInvocation i1, FunctionInvocation i2, FunctionObject multi) { i1 != i2 and i1 = top.getACallee+() and i2 = top.getACallee+() and - i1.getFunction() = multi and + i1.getFunction() = multi +} + +pragma [noinline] +private predicate multiple_invocation_paths(FunctionInvocation top, FunctionInvocation i1, FunctionInvocation i2, FunctionObject multi) { + multiple_invocation_paths_helper(top, i1, i2, multi) and i2.getFunction() = multi } diff --git a/python/ql/src/Imports/UnusedImport.ql b/python/ql/src/Imports/UnusedImport.ql index 6d927550c0c..d5867aaaf46 100644 --- a/python/ql/src/Imports/UnusedImport.ql +++ b/python/ql/src/Imports/UnusedImport.ql @@ -13,17 +13,17 @@ import python import Variables.Definition -predicate global_name_used(Module m, Variable name) { - exists (Name u, GlobalVariable v | +predicate global_name_used(Module m, string name) { + exists(Name u, GlobalVariable v | u.uses(v) and - v.getId() = name.getId() and + v.getId() = name and u.getEnclosingModule() = m ) or - /* A use of an undefined class local variable, will use the global variable */ + // A use of an undefined class local variable, will use the global variable exists(Name u, LocalVariable v | u.uses(v) and - v.getId() = name.getId() and + v.getId() = name and u.getEnclosingModule() = m and not v.getScope().getEnclosingScope*() instanceof Function ) @@ -31,79 +31,93 @@ predicate global_name_used(Module m, Variable name) { /** Holds if a module has `__all__` but we don't understand it */ predicate all_not_understood(Module m) { - exists(GlobalVariable a | - a.getId() = "__all__" and a.getScope() = m | - /* __all__ is not defined as a simple list */ + exists(GlobalVariable a | a.getId() = "__all__" and a.getScope() = m | + // `__all__` is not defined as a simple list not m.declaredInAll(_) or - /* __all__ is modified */ + // `__all__` is modified exists(Call c | c.getFunc().(Attribute).getObject() = a.getALoad()) ) } predicate imported_module_used_in_doctest(Import imp) { - exists(string modname | - imp.getAName().getAsname().(Name).getId() = modname - and - /* Look for doctests containing the patterns: - * >>> โ€ฆnameโ€ฆ - * ... โ€ฆnameโ€ฆ - */ - exists(StrConst doc | - doc.getEnclosingModule() = imp.getScope() and - doc.isDocString() and - doc.getText().regexpMatch("[\\s\\S]*(>>>|\\.\\.\\.).*" + modname + "[\\s\\S]*") - ) + exists(string modname, string docstring | + imp.getAName().getAsname().(Name).getId() = modname and + // Look for doctests containing the patterns: + // >>> โ€ฆnameโ€ฆ + // ... โ€ฆnameโ€ฆ + docstring = doctest_in_scope(imp.getScope()) and + docstring.regexpMatch("[\\s\\S]*(>>>|\\.\\.\\.).*" + modname + "[\\s\\S]*") + ) +} + +pragma[noinline] +private string doctest_in_scope(Scope scope) { + exists(StrConst doc | + doc.getEnclosingModule() = scope and + doc.isDocString() and + result = doc.getText() and + result.regexpMatch("[\\s\\S]*(>>>|\\.\\.\\.)[\\s\\S]*") + ) +} + +pragma[noinline] +private string typehint_annotation_in_file(File file) { + exists(StrConst annotation | + annotation = any(Arguments a).getAnAnnotation() + or + annotation = any(AnnAssign a).getAnnotation() + | + annotation.pointsTo(Value::forString(result)) and + file = annotation.getLocation().getFile() + ) +} + +pragma[noinline] +private string typehint_comment_in_file(File file) { + exists(Comment typehint | + file = typehint.getLocation().getFile() and + result = typehint.getText() and + result.matches("# type:%") ) } predicate imported_module_used_in_typehint(Import imp) { - exists(string modname | - imp.getAName().getAsname().(Name).getId() = modname - and - /* Look for typehints containing the patterns: - * # type: โ€ฆnameโ€ฆ - */ - exists(Comment typehint | - typehint.getLocation().getFile() = imp.getScope().(Module).getFile() and - typehint.getText().regexpMatch("# type:.*" + modname + ".*") - ) + exists(string modname, File file | + imp.getAName().getAsname().(Name).getId() = modname and + file = imp.getScope().(Module).getFile() + | + // Look for type hints containing the patterns: + // # type: โ€ฆnameโ€ฆ + typehint_comment_in_file(file).regexpMatch("# type:.*" + modname + ".*") + or + // Type hint is inside a string annotation, as needed for forward references + typehint_annotation_in_file(file).regexpMatch(".*\\b" + modname + "\\b.*") ) } - predicate unused_import(Import imp, Variable name) { - ((Name)imp.getAName().getAsname()).getVariable() = name - and - not imp.getAnImportedModuleName() = "__future__" - and - not imp.getEnclosingModule().declaredInAll(name.getId()) - and - imp.getScope() = imp.getEnclosingModule() - and - not global_name_used(imp.getScope(), name) - and - /* Imports in __init__.py are used to force module loading */ - not imp.getEnclosingModule().isPackageInit() - and - /* Name may be imported for use in epytext documentation */ - not exists(Comment cmt | - cmt.getText().matches("%L{" + name.getId() + "}%") | + imp.getAName().getAsname().(Name).getVariable() = name and + not imp.getAnImportedModuleName() = "__future__" and + not imp.getEnclosingModule().declaredInAll(name.getId()) and + imp.getScope() = imp.getEnclosingModule() and + not global_name_used(imp.getScope(), name.getId()) and + // Imports in `__init__.py` are used to force module loading + not imp.getEnclosingModule().isPackageInit() and + // Name may be imported for use in epytext documentation + not exists(Comment cmt | cmt.getText().matches("%L{" + name.getId() + "}%") | cmt.getLocation().getFile() = imp.getLocation().getFile() - ) - and - not name_acceptable_for_unused_variable(name) - and - /* Assume that opaque `__all__` includes imported module */ - not all_not_understood(imp.getEnclosingModule()) - and - not imported_module_used_in_doctest(imp) - and - not imported_module_used_in_typehint(imp) + ) and + not name_acceptable_for_unused_variable(name) and + // Assume that opaque `__all__` includes imported module + not all_not_understood(imp.getEnclosingModule()) and + not imported_module_used_in_doctest(imp) and + not imported_module_used_in_typehint(imp) and + // Only consider import statements that actually point-to something (possibly an unknown module). + // If this is not the case, it's likely that the import statement never gets executed. + imp.getAName().getValue().pointsTo(_) } - from Stmt s, Variable name where unused_import(s, name) select s, "Import of '" + name.getId() + "' is not used." - diff --git a/python/ql/src/Security/CWE-020/IncompleteHostnameRegExp.qhelp b/python/ql/src/Security/CWE-020/IncompleteHostnameRegExp.qhelp index b542ae252eb..8eb0f43eb01 100644 --- a/python/ql/src/Security/CWE-020/IncompleteHostnameRegExp.qhelp +++ b/python/ql/src/Security/CWE-020/IncompleteHostnameRegExp.qhelp @@ -64,6 +64,6 @@
  • OWASP: SSRF
  • -
  • OWASP: XSS Unvalidated Redirects and Forwards Cheat Sheet.
  • +
  • OWASP: XSS Unvalidated Redirects and Forwards Cheat Sheet.
  • diff --git a/python/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.qhelp b/python/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.qhelp index 6c783a4f729..828c71153b5 100644 --- a/python/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.qhelp +++ b/python/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.qhelp @@ -80,6 +80,6 @@
  • OWASP: SSRF
  • -
  • OWASP: XSS Unvalidated Redirects and Forwards Cheat Sheet.
  • +
  • OWASP: XSS Unvalidated Redirects and Forwards Cheat Sheet.
  • diff --git a/python/ql/src/Security/CWE-079/Jinja2WithoutEscaping.qhelp b/python/ql/src/Security/CWE-079/Jinja2WithoutEscaping.qhelp index 4497437aac1..5b4d21bb37e 100644 --- a/python/ql/src/Security/CWE-079/Jinja2WithoutEscaping.qhelp +++ b/python/ql/src/Security/CWE-079/Jinja2WithoutEscaping.qhelp @@ -38,7 +38,7 @@ Jinja2: API. Wikipedia: Cross-site scripting.
  • -OWASP: XSS (Cross Site Scripting) Prevention Cheat Sheet. +OWASP: XSS (Cross Site Scripting) Prevention Cheat Sheet.
  • diff --git a/python/ql/src/Security/CWE-079/ReflectedXss.qhelp b/python/ql/src/Security/CWE-079/ReflectedXss.qhelp index 8cdeb4d3e79..04a83fba6b4 100644 --- a/python/ql/src/Security/CWE-079/ReflectedXss.qhelp +++ b/python/ql/src/Security/CWE-079/ReflectedXss.qhelp @@ -31,7 +31,7 @@ The second view is safe as first_name is escaped, so it is not vuln
  • OWASP: -XSS +XSS (Cross Site Scripting) Prevention Cheat Sheet.
  • diff --git a/python/ql/src/Security/CWE-089/SqlInjection.qhelp b/python/ql/src/Security/CWE-089/SqlInjection.qhelp index e976401a6b5..63941706e84 100644 --- a/python/ql/src/Security/CWE-089/SqlInjection.qhelp +++ b/python/ql/src/Security/CWE-089/SqlInjection.qhelp @@ -21,20 +21,29 @@ or prepared statements.

    -In the following snippet, from an example django app, -a name is stored in the database using two different queries. +In the following snippet, a user is fetched from the database using three +different queries.

    In the first case, the query string is built by -directly using string formatting from a user-supplied request attribute. +directly using string formatting from a user-supplied request parameter. The parameter may include quote characters, so this code is vulnerable to a SQL injection attack.

    In the second case, the user-supplied request attribute is passed -to the database using query parameters. +to the database using query parameters. The database connector library will +take care of escaping and inserting quotes as needed. +

    + +

    +In the third case, the placeholder in the SQL string has been manually quoted. Since most +databaseconnector libraries will insert their own quotes, doing so yourself will make the code +vulnerable to SQL injection attacks. In this example, if username was +; DROP ALL TABLES -- , the final SQL query would be +SELECT * FROM users WHERE username = ''; DROP ALL TABLES -- ''

    @@ -42,6 +51,6 @@ to the database using query parameters.
  • Wikipedia: SQL injection.
  • -
  • OWASP: SQL Injection Prevention Cheat Sheet.
  • +
  • OWASP: SQL Injection Prevention Cheat Sheet.
  • diff --git a/python/ql/src/Security/CWE-089/examples/sql_injection.py b/python/ql/src/Security/CWE-089/examples/sql_injection.py index 541c580f712..fe6dbc50c01 100644 --- a/python/ql/src/Security/CWE-089/examples/sql_injection.py +++ b/python/ql/src/Security/CWE-089/examples/sql_injection.py @@ -1,21 +1,19 @@ - -from django.conf.urls import patterns, url +from django.conf.urls import url from django.db import connection -def save_name(request): +def show_user(request, username): + with connection.cursor() as cursor: + # BAD -- Using string formatting + cursor.execute("SELECT * FROM users WHERE username = '%s'" % username) + user = cursor.fetchone() - if request.method == 'POST': - name = request.POST.get('name') - curs = connection.cursor() - #BAD -- Using string formatting - curs.execute( - "insert into names_file ('name') values ('%s')" % name) - #GOOD -- Using parameters - curs.execute( - "insert into names_file ('name') values ('%s')", name) + # GOOD -- Using parameters + cursor.execute("SELECT * FROM users WHERE username = %s", username) + user = cursor.fetchone() + # BAD -- Manually quoting placeholder (%s) + cursor.execute("SELECT * FROM users WHERE username = '%s'", username) + user = cursor.fetchone() -urlpatterns = patterns(url(r'^save_name/$', - upload, name='save_name')) - +urlpatterns = [url(r'^users/(?P[^/]+)$', show_user)] diff --git a/python/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.qhelp b/python/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.qhelp index 6cc787e52e4..1b4031b1cc5 100644 --- a/python/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.qhelp +++ b/python/ql/src/Security/CWE-327/BrokenCryptoAlgorithm.qhelp @@ -49,7 +49,7 @@
  • NIST, FIPS 140 Annex a: Approved Security Functions.
  • NIST, SP 800-131A: Transitions: Recommendation for Transitioning the Use of Cryptographic Algorithms and Key Lengths.
  • OWASP: Rule + href="https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html#rule---use-strong-approved-authenticated-encryption">Rule - Use strong approved cryptographic algorithms.
  • diff --git a/python/ql/src/Security/CWE-502/UnsafeDeserialization.qhelp b/python/ql/src/Security/CWE-502/UnsafeDeserialization.qhelp index f298e62695f..8c2660b9865 100644 --- a/python/ql/src/Security/CWE-502/UnsafeDeserialization.qhelp +++ b/python/ql/src/Security/CWE-502/UnsafeDeserialization.qhelp @@ -49,7 +49,7 @@ OWASP vulnerability description:
  • OWASP guidance on deserializing objects: -Deserialization Cheat Sheet. +Deserialization Cheat Sheet.
  • Talks by Chris Frohoff & Gabriel Lawrence: diff --git a/python/ql/src/Security/CWE-601/UrlRedirect.qhelp b/python/ql/src/Security/CWE-601/UrlRedirect.qhelp index c2e053f030b..756a43cc106 100644 --- a/python/ql/src/Security/CWE-601/UrlRedirect.qhelp +++ b/python/ql/src/Security/CWE-601/UrlRedirect.qhelp @@ -35,7 +35,7 @@ before doing the redirection: -
  • OWASP: +
  • OWASP: XSS Unvalidated Redirects and Forwards Cheat Sheet.
  • diff --git a/python/ql/src/Statements/UnreachableCode.ql b/python/ql/src/Statements/UnreachableCode.ql index 2bdfc84ebb3..88f8b9427a2 100644 --- a/python/ql/src/Statements/UnreachableCode.ql +++ b/python/ql/src/Statements/UnreachableCode.ql @@ -16,9 +16,7 @@ import python predicate typing_import(ImportingStmt is) { exists(Module m | is.getScope() = m and - exists(TypeHintComment tc | - tc.getLocation().getFile() = m.getFile() - ) + exists(TypeHintComment tc | tc.getLocation().getFile() = m.getFile()) ) } @@ -39,6 +37,15 @@ predicate suppression_in_scope(Stmt s) { ) } +/** Holds if `s` is a statement that raises an exception at the end of an if-elif-else chain. */ +predicate marks_an_impossible_else_branch(Stmt s) { + exists(If i | i.getOrelse().getItem(0) = s | + s.(Assert).getTest() instanceof False + or + s instanceof Raise + ) +} + predicate reportable_unreachable(Stmt s) { s.isUnreachable() and not typing_import(s) and @@ -46,11 +53,10 @@ predicate reportable_unreachable(Stmt s) { not exists(Stmt other | other.isUnreachable() | other.contains(s) or - exists(StmtList l, int i, int j | - l.getItem(i) = other and l.getItem(j) = s and i < j - ) + exists(StmtList l, int i, int j | l.getItem(i) = other and l.getItem(j) = s and i < j) ) and - not unique_yield(s) + not unique_yield(s) and + not marks_an_impossible_else_branch(s) } from Stmt s diff --git a/python/ql/src/Variables/UndefinedExport.ql b/python/ql/src/Variables/UndefinedExport.ql index 6bf128def79..edd2e375c0f 100644 --- a/python/ql/src/Variables/UndefinedExport.ql +++ b/python/ql/src/Variables/UndefinedExport.ql @@ -14,39 +14,54 @@ import python /** Whether name is declared in the __all__ list of this module */ -predicate declaredInAll(Module m, StrConst name) -{ - exists(Assign a, GlobalVariable all | - a.defines(all) and a.getScope() = m and - all.getId() = "__all__" and ((List)a.getValue()).getAnElt() = name +predicate declaredInAll(Module m, StrConst name) { + exists(Assign a, GlobalVariable all | + a.defines(all) and + a.getScope() = m and + all.getId() = "__all__" and + a.getValue().(List).getAnElt() = name ) } -predicate mutates_globals(PythonModuleObject m) { +predicate mutates_globals(ModuleValue m) { exists(CallNode globals | - globals = Object::builtin("globals").(FunctionObject).getACall() and - globals.getScope() = m.getModule() | + globals = Value::named("globals").(FunctionValue).getACall() and + globals.getScope() = m.getScope() + | exists(AttrNode attr | attr.getObject() = globals) or exists(SubscriptNode sub | sub.getValue() = globals and sub.isStore()) ) or - exists(Object enum_convert | - enum_convert.hasLongName("enum.Enum._convert") and - exists(CallNode call | - call.getScope() = m.getModule() - | - enum_convert.(FunctionObject).getACall() = call or - call.getFunction().refersTo(enum_convert) + exists(Value enum_convert, ClassValue enum_class | + enum_class.getASuperType() = Value::named("enum.Enum") and + enum_convert = enum_class.attr("_convert") and + exists(CallNode call | call.getScope() = m.getScope() | + enum_convert.getACall() = call or + call.getFunction().pointsTo(enum_convert) ) ) } -from PythonModuleObject m, StrConst name, string exported_name -where declaredInAll(m.getModule(), name) and -exported_name = name.strValue() and -not m.hasAttribute(exported_name) and -not (m.getShortName() = "__init__" and exists(m.getPackage().getModule().getSubModule(exported_name))) and -not exists(ImportStarNode imp | imp.getEnclosingModule() = m.getModule() | not imp.getModule().refersTo(_)) and -not mutates_globals(m) -select name, "The name '" + exported_name + "' is exported by __all__ but is not defined." \ No newline at end of file +predicate is_exported_submodule_name(ModuleValue m, string exported_name) { + m.getScope().getShortName() = "__init__" and + exists(m.getScope().getPackage().getSubModule(exported_name)) +} + +predicate contains_unknown_import_star(ModuleValue m) { + exists(ImportStarNode imp | imp.getEnclosingModule() = m.getScope() | + imp.getModule().pointsTo().isAbsent() + or + not exists(imp.getModule().pointsTo()) + ) +} + +from ModuleValue m, StrConst name, string exported_name +where + declaredInAll(m.getScope(), name) and + exported_name = name.strValue() and + not m.hasAttribute(exported_name) and + not is_exported_submodule_name(m, exported_name) and + not contains_unknown_import_star(m) and + not mutates_globals(m) +select name, "The name '" + exported_name + "' is exported by __all__ but is not defined." diff --git a/python/ql/src/semmle/python/Module.qll b/python/ql/src/semmle/python/Module.qll index a3bf174897f..68361d1b12c 100644 --- a/python/ql/src/semmle/python/Module.qll +++ b/python/ql/src/semmle/python/Module.qll @@ -52,6 +52,13 @@ class Module extends Module_, Scope, AstNode { result = moduleNameFromFile(this.getPath()) } + /** Gets the short name of the module. For example the short name of module x.y.z is 'z' */ + string getShortName() { + result = this.getName().suffix(this.getPackage().getName().length()+1) + or + result = this.getName() and not exists(this.getPackage()) + } + /** Gets this module */ override Module getEnclosingModule() { result = this diff --git a/python/ql/src/semmle/python/dataflow/Configuration.qll b/python/ql/src/semmle/python/dataflow/Configuration.qll index b1eb4ced1ed..3672f022b4c 100644 --- a/python/ql/src/semmle/python/dataflow/Configuration.qll +++ b/python/ql/src/semmle/python/dataflow/Configuration.qll @@ -23,7 +23,7 @@ module TaintTracking { /* Old implementation API */ - predicate isSource(Source source) { none() } + predicate isSource(Source src) { none() } predicate isSink(Sink sink) { none() } @@ -34,14 +34,14 @@ module TaintTracking { /* New implementation API */ /** - * Holds if `source` is a source of taint of `kind` that is relevant + * Holds if `src` is a source of taint of `kind` that is relevant * for this configuration. */ - predicate isSource(DataFlow::Node node, TaintKind kind) { - exists(TaintSource source | - this.isSource(source) and - node.asCfgNode() = source and - source.isSourceOf(kind) + predicate isSource(DataFlow::Node src, TaintKind kind) { + exists(TaintSource taintSrc | + this.isSource(taintSrc) and + src.asCfgNode() = taintSrc and + taintSrc.isSourceOf(kind) ) } @@ -49,11 +49,11 @@ module TaintTracking { * Holds if `sink` is a sink of taint of `kind` that is relevant * for this configuration. */ - predicate isSink(DataFlow::Node node, TaintKind kind) { - exists(TaintSink sink | - this.isSink(sink) and - node.asCfgNode() = sink and - sink.sinks(kind) + predicate isSink(DataFlow::Node sink, TaintKind kind) { + exists(TaintSink taintSink | + this.isSink(taintSink) and + sink.asCfgNode() = taintSink and + taintSink.sinks(kind) ) } @@ -116,27 +116,27 @@ module TaintTracking { /* Common query API */ - predicate hasFlowPath(PathSource source, PathSink sink) { - this.(TaintTrackingImplementation).hasFlowPath(source, sink) + predicate hasFlowPath(PathSource src, PathSink sink) { + this.(TaintTrackingImplementation).hasFlowPath(src, sink) } /* Old query API */ /* deprecated */ - predicate hasFlow(Source source, Sink sink) { - exists(PathSource psource, PathSink psink | - this.hasFlowPath(psource, psink) and - source = psource.getNode().asCfgNode() and + predicate hasFlow(Source src, Sink sink) { + exists(PathSource psrc, PathSink psink | + this.hasFlowPath(psrc, psink) and + src = psrc.getNode().asCfgNode() and sink = psink.getNode().asCfgNode() ) } /* New query API */ - predicate hasSimpleFlow(DataFlow::Node source, DataFlow::Node sink) { - exists(PathSource psource, PathSink psink | - this.hasFlowPath(psource, psink) and - source = psource.getNode() and + predicate hasSimpleFlow(DataFlow::Node src, DataFlow::Node sink) { + exists(PathSource psrc, PathSink psink | + this.hasFlowPath(psrc, psink) and + src = psrc.getNode() and sink = psink.getNode() ) } diff --git a/python/ql/src/semmle/python/dataflow/Legacy.qll b/python/ql/src/semmle/python/dataflow/Legacy.qll index d401fc1a418..94dd55e20fa 100644 --- a/python/ql/src/semmle/python/dataflow/Legacy.qll +++ b/python/ql/src/semmle/python/dataflow/Legacy.qll @@ -33,26 +33,18 @@ private class LegacyConfiguration extends TaintTracking::Configuration { } override predicate isSource(TaintSource src) { - isValid() and src = src } override predicate isSink(TaintSink sink) { - isValid() and sink = sink } override predicate isSanitizer(Sanitizer sanitizer) { - isValid() and sanitizer = sanitizer } - private predicate isValid() { - not exists(TaintTracking::Configuration config | config != this) - } - override predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node dest) { - isValid() and exists(DataFlowExtension::DataFlowNode legacyExtension | src.asCfgNode() = legacyExtension | @@ -67,7 +59,6 @@ private class LegacyConfiguration extends TaintTracking::Configuration { } override predicate isAdditionalFlowStep(DataFlow::Node src, DataFlow::Node dest, TaintKind srckind, TaintKind destkind) { - isValid() and exists(DataFlowExtension::DataFlowNode legacyExtension | src.asCfgNode() = legacyExtension | @@ -76,7 +67,6 @@ private class LegacyConfiguration extends TaintTracking::Configuration { } override predicate isBarrierEdge(DataFlow::Node src, DataFlow::Node dest) { - isValid() and ( exists(DataFlowExtension::DataFlowVariable legacyExtension | src.asVariable() = legacyExtension and @@ -91,4 +81,3 @@ private class LegacyConfiguration extends TaintTracking::Configuration { } } - diff --git a/python/ql/src/semmle/python/objects/ObjectAPI.qll b/python/ql/src/semmle/python/objects/ObjectAPI.qll index c5004295cc3..7247b7d450c 100644 --- a/python/ql/src/semmle/python/objects/ObjectAPI.qll +++ b/python/ql/src/semmle/python/objects/ObjectAPI.qll @@ -99,6 +99,12 @@ class Value extends TObject { this.(ObjectInternal).hasAttribute(name) } + /** Whether this value is absent from the database, but has been inferred to likely exist */ + predicate isAbsent() { + this instanceof AbsentModuleObjectInternal + or + this instanceof AbsentModuleAttributeObjectInternal + } } /** Class representing modules in the Python program diff --git a/python/ql/src/semmle/python/security/SensitiveData.qll b/python/ql/src/semmle/python/security/SensitiveData.qll index 9b253da6937..5dddd9b0d30 100644 --- a/python/ql/src/semmle/python/security/SensitiveData.qll +++ b/python/ql/src/semmle/python/security/SensitiveData.qll @@ -112,12 +112,6 @@ module SensitiveData { private SensitiveData fromFunction(Value func) { result = HeuristicNames::getSensitiveDataForName(func.getName()) - or - // This is particularly to pick up methods with an argument like "password", which - // may indicate a lookup. - exists(string name | name = func.(PythonFunctionValue).getScope().getAnArg().asName().getId() | - result = HeuristicNames::getSensitiveDataForName(name) - ) } abstract class Source extends TaintSource { diff --git a/python/ql/src/semmle/python/web/django/General.qll b/python/ql/src/semmle/python/web/django/General.qll new file mode 100644 index 00000000000..423d853cdad --- /dev/null +++ b/python/ql/src/semmle/python/web/django/General.qll @@ -0,0 +1,40 @@ +import python +import semmle.python.regex +import semmle.python.web.Http + +predicate django_route(CallNode call, ControlFlowNode regex, FunctionValue view) { + exists(FunctionValue url | + Value::named("django.conf.urls.url") = url and + url.getArgumentForCall(call, 0) = regex and + url.getArgumentForCall(call, 1).pointsTo(view) + ) +} + +class DjangoRouteRegex extends RegexString { + DjangoRouteRegex() { django_route(_, this.getAFlowNode(), _) } +} + +class DjangoRoute extends CallNode { + DjangoRoute() { django_route(this, _, _) } + + FunctionValue getViewFunction() { django_route(this, _, result) } + + string getNamedArgument() { + exists(DjangoRouteRegex regex | + django_route(this, regex.getAFlowNode(), _) and + regex.getGroupName(_, _) = result + ) + } + + /** + * Get the number of positional arguments that will be passed to the view. + * Will only return a result if there are no named arguments. + */ + int getNumPositionalArguments() { + exists(DjangoRouteRegex regex | + django_route(this, regex.getAFlowNode(), _) and + not exists(string s | s = regex.getGroupName(_, _)) and + result = count(regex.getGroupNumber(_, _)) + ) + } +} diff --git a/python/ql/src/semmle/python/web/django/Model.qll b/python/ql/src/semmle/python/web/django/Model.qll index 34cf5856802..b8f47b64bdf 100644 --- a/python/ql/src/semmle/python/web/django/Model.qll +++ b/python/ql/src/semmle/python/web/django/Model.qll @@ -54,33 +54,6 @@ class DjangoModelObjects extends TaintSource { override string toString() { result = "django.db.models.Model.objects" } } -/** A write to a field of a django model, which is a vulnerable to external data. */ -class DjangoModelFieldWrite extends SqlInjectionSink { - DjangoModelFieldWrite() { - exists(AttrNode attr, DjangoModel model | - this = attr and attr.isStore() and attr.getObject(_).pointsTo(model) - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } - - override string toString() { result = "django model field write" } -} - -/** A direct reference to a django model object, which is vulnerable to external data. */ -class DjangoModelDirectObjectReference extends TaintSink { - DjangoModelDirectObjectReference() { - exists(CallNode objects_get_call, ControlFlowNode objects | this = objects_get_call.getAnArg() | - objects_get_call.getFunction().(AttrNode).getObject("get") = objects and - any(DjangoDbTableObjects objs).taints(objects) - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof ExternalStringKind } - - override string toString() { result = "django model object reference" } -} - /** * A call to the `raw` method on a django model. This allows a raw SQL query * to be sent to the database, which is a security risk. diff --git a/python/ql/src/semmle/python/web/django/Request.qll b/python/ql/src/semmle/python/web/django/Request.qll index d2ad2ff30d3..24a29ea4542 100644 --- a/python/ql/src/semmle/python/web/django/Request.qll +++ b/python/ql/src/semmle/python/web/django/Request.qll @@ -1,7 +1,7 @@ import python -import semmle.python.regex import semmle.python.security.TaintTracking import semmle.python.web.Http +import semmle.python.web.django.General /** A django.request.HttpRequest object */ class DjangoRequest extends TaintKind { @@ -52,7 +52,7 @@ abstract class DjangoRequestSource extends HttpRequestTaintSource { private class DjangoFunctionBasedViewRequestArgument extends DjangoRequestSource { DjangoFunctionBasedViewRequestArgument() { exists(FunctionValue view | - url_dispatch(_, _, view) and + django_route(_, _, view) and this = view.getScope().getArg(0).asName().getAFlowNode() ) } @@ -67,7 +67,7 @@ private class DjangoView extends ClassValue { } private FunctionValue djangoViewHttpMethod() { - exists(DjangoView view | view.attr(httpVerbLower()) = result) + exists(DjangoView view | view.lookup(httpVerbLower()) = result) } class DjangoClassBasedViewRequestArgument extends DjangoRequestSource { @@ -76,41 +76,18 @@ class DjangoClassBasedViewRequestArgument extends DjangoRequestSource { } } -/* *********** Routing ********* */ -/* Function based views */ -predicate url_dispatch(CallNode call, ControlFlowNode regex, FunctionValue view) { - exists(FunctionValue url | - Value::named("django.conf.urls.url") = url and - url.getArgumentForCall(call, 0) = regex and - url.getArgumentForCall(call, 1).pointsTo(view) - ) -} - -class UrlRegex extends RegexString { - UrlRegex() { url_dispatch(_, this.getAFlowNode(), _) } -} - -class UrlRouting extends CallNode { - UrlRouting() { url_dispatch(this, _, _) } - - FunctionValue getViewFunction() { url_dispatch(this, _, result) } - - string getNamedArgument() { - exists(UrlRegex regex | - url_dispatch(this, regex.getAFlowNode(), _) and - regex.getGroupName(_, _) = result - ) - } -} - /** An argument specified in a url routing table */ -class HttpRequestParameter extends HttpRequestTaintSource { - HttpRequestParameter() { - exists(UrlRouting url | - this.(ControlFlowNode).getNode() = url - .getViewFunction() - .getScope() - .getArgByName(url.getNamedArgument()) +class DjangoRequestParameter extends HttpRequestTaintSource { + DjangoRequestParameter() { + exists(DjangoRoute route, Function f | + f = route.getViewFunction().getScope() | + this.(ControlFlowNode).getNode() = f.getArgByName(route.getNamedArgument()) + or + exists(int i | i >= 0 | + i < route.getNumPositionalArguments() and + // +1 because first argument is always the request + this.(ControlFlowNode).getNode() = f.getArg(i+1) + ) ) } diff --git a/python/ql/test/2/library-tests/classes/attr/list_attr.expected b/python/ql/test/2/library-tests/classes/attr/list_attr.expected index b281b8f9e9a..4668766c5e5 100644 --- a/python/ql/test/2/library-tests/classes/attr/list_attr.expected +++ b/python/ql/test/2/library-tests/classes/attr/list_attr.expected @@ -1,9 +1,12 @@ | builtin-class list | __add__ | Builtin-method __add__ | +| builtin-class list | __class__ | Property __class__ | | builtin-class list | __contains__ | Builtin-method __contains__ | +| builtin-class list | __delattr__ | Builtin-method __delattr__ | | builtin-class list | __delitem__ | Builtin-method __delitem__ | | builtin-class list | __delslice__ | Builtin-method __delslice__ | | builtin-class list | __doc__ | str b'list() -> new empty list\nlist(iterable) -> new list initialized from iterable's items' | | builtin-class list | __eq__ | Builtin-method __eq__ | +| builtin-class list | __format__ | Builtin-method __format__ | | builtin-class list | __ge__ | Builtin-method __ge__ | | builtin-class list | __getattribute__ | Builtin-method __getattribute__ | | builtin-class list | __getitem__ | Builtin-method __getitem__ | @@ -20,12 +23,17 @@ | builtin-class list | __mul__ | Builtin-method __mul__ | | builtin-class list | __ne__ | Builtin-method __ne__ | | builtin-class list | __new__ | builtin_function_or_method __new__ | +| builtin-class list | __reduce__ | Builtin-method __reduce__ | +| builtin-class list | __reduce_ex__ | Builtin-method __reduce_ex__ | | builtin-class list | __repr__ | Builtin-method __repr__ | | builtin-class list | __reversed__ | Builtin-method __reversed__ | | builtin-class list | __rmul__ | Builtin-method __rmul__ | +| builtin-class list | __setattr__ | Builtin-method __setattr__ | | builtin-class list | __setitem__ | Builtin-method __setitem__ | | builtin-class list | __setslice__ | Builtin-method __setslice__ | | builtin-class list | __sizeof__ | Builtin-method __sizeof__ | +| builtin-class list | __str__ | Builtin-method __str__ | +| builtin-class list | __subclasshook__ | classmethod_descriptor __subclasshook__ | | builtin-class list | append | Builtin-method append | | builtin-class list | count | Builtin-method count | | builtin-class list | extend | Builtin-method extend | diff --git a/python/ql/test/2/library-tests/classes/mro/C3.expected b/python/ql/test/2/library-tests/classes/mro/C3.expected index bd86482f34d..d55fae894de 100644 --- a/python/ql/test/2/library-tests/classes/mro/C3.expected +++ b/python/ql/test/2/library-tests/classes/mro/C3.expected @@ -3,7 +3,6 @@ | class C | [C, BaseException, object] | | class D | [D, X, object] | | class Meta | [Meta, type, object] | -| class N | [N, object, O] | | class NewStyle | [NewStyle, object] | | class NewStyleDerived | [NewStyleDerived, NewStyle, object] | | class O | [O] | diff --git a/python/ql/test/2/library-tests/classes/mro/mro.expected b/python/ql/test/2/library-tests/classes/mro/mro.expected index 41db9554fe1..aab6cc1a001 100644 --- a/python/ql/test/2/library-tests/classes/mro/mro.expected +++ b/python/ql/test/2/library-tests/classes/mro/mro.expected @@ -8,8 +8,6 @@ | class D | class X | builtin-class object | | class Meta | builtin-class type | builtin-class object | | class Meta | class Meta | builtin-class type | -| class N | builtin-class object | class O | -| class N | class N | builtin-class object | | class NewStyle | class NewStyle | builtin-class object | | class NewStyleDerived | class NewStyle | builtin-class object | | class NewStyleDerived | class NewStyleDerived | class NewStyle | diff --git a/python/ql/test/2/library-tests/six/test.expected b/python/ql/test/2/library-tests/six/test.expected index 8462f2b2464..50ad5bc7e57 100644 --- a/python/ql/test/2/library-tests/six/test.expected +++ b/python/ql/test/2/library-tests/six/test.expected @@ -1,5 +1,6 @@ | Module six | BytesIO | class StringIO | | Module six | Iterator | class Iterator | +| Module six | MAXSIZE | int() | | Module six | PY2 | bool True | | Module six | PY3 | bool False | | Module six | StringIO | class StringIO | @@ -45,14 +46,6 @@ | Module six | iterlists | Function iterlists | | Module six | itervalues | Function itervalues | | Module six | moves | Module six.moves | -| Module six | moves.__init__ | Module six.moves.__init__ | -| Module six | moves.urllib | Module six.moves.urllib | -| Module six | moves.urllib.__init__ | Module six.moves.urllib.__init__ | -| Module six | moves.urllib_error | Module six.moves.urllib_error | -| Module six | moves.urllib_parse | Module six.moves.urllib_parse | -| Module six | moves.urllib_request | Module six.moves.urllib_request | -| Module six | moves.urllib_response | Module six.moves.urllib_response | -| Module six | moves.urllib_robotparser | Module six.moves.urllib_robotparser | | Module six | next | Builtin-function next | | Module six | operator | Module operator | | Module six | print_ | Function print_ | @@ -67,6 +60,7 @@ | Module six | with_metaclass | Function with_metaclass | | Module six.__init__ | BytesIO | class StringIO | | Module six.__init__ | Iterator | class Iterator | +| Module six.__init__ | MAXSIZE | int() | | Module six.__init__ | PY2 | bool True | | Module six.__init__ | PY3 | bool False | | Module six.__init__ | StringIO | class StringIO | @@ -174,7 +168,6 @@ | Module six.moves | tkinter_tksimpledialog | Module tkSimpleDialog | | Module six.moves | tkinter_ttk | Module ttk | | Module six.moves | urllib | Module six.moves.urllib | -| Module six.moves | urllib.__init__ | Module six.moves.urllib.__init__ | | Module six.moves | urllib_error | Module six.moves.urllib_error | | Module six.moves | urllib_parse | Module six.moves.urllib_parse | | Module six.moves | urllib_request | Module six.moves.urllib_request | diff --git a/python/ql/test/2/library-tests/types/classes/mro_test.expected b/python/ql/test/2/library-tests/types/classes/mro_test.expected index b1aa3af843e..6c1d3b50bf2 100644 --- a/python/ql/test/2/library-tests/types/classes/mro_test.expected +++ b/python/ql/test/2/library-tests/types/classes/mro_test.expected @@ -1,3 +1,5 @@ +| class A | [A, ??, object] | +| class J | [J, ??, object] | | class MyDict | [MyDict, dict, object] | | class MyList | [MyList, list, object] | | class O1 | [O1] | diff --git a/python/ql/test/2/query-tests/Classes/equals-hash/EqualsOrHash.expected b/python/ql/test/2/query-tests/Classes/equals-hash/EqualsOrHash.expected index aaed9443525..916a9bb4454 100644 --- a/python/ql/test/2/query-tests/Classes/equals-hash/EqualsOrHash.expected +++ b/python/ql/test/2/query-tests/Classes/equals-hash/EqualsOrHash.expected @@ -1,2 +1,2 @@ -| equals_hash.py:8:5:8:28 | Function __eq__ | Class $@ implements __eq__ but does not define __hash__. | equals_hash.py:3:1:3:17 | class Eq | Eq | -| equals_hash.py:24:5:24:23 | Function __hash__ | Class $@ implements __hash__ but does not define __eq__ or __cmp__. | equals_hash.py:19:1:19:19 | class Hash | Hash | +| equals_hash.py:8:5:8:28 | Function Eq.__eq__ | Class $@ implements __eq__ but does not define __hash__. | equals_hash.py:3:1:3:17 | class Eq | Eq | +| equals_hash.py:24:5:24:23 | Function Hash.__hash__ | Class $@ implements __hash__ but does not define __eq__ or __cmp__. | equals_hash.py:19:1:19:19 | class Hash | Hash | diff --git a/python/ql/test/2/query-tests/Classes/equals-hash/EqualsOrNotEquals.expected b/python/ql/test/2/query-tests/Classes/equals-hash/EqualsOrNotEquals.expected index a7ac0084132..04e395c668b 100644 --- a/python/ql/test/2/query-tests/Classes/equals-hash/EqualsOrNotEquals.expected +++ b/python/ql/test/2/query-tests/Classes/equals-hash/EqualsOrNotEquals.expected @@ -1,2 +1,2 @@ -| equals_hash.py:8:5:8:28 | Function __eq__ | Class $@ implements __eq__ but does not implement __ne__. | equals_hash.py:3:1:3:17 | class Eq | Eq | -| equals_hash.py:16:5:16:28 | Function __ne__ | Class $@ implements __ne__ but does not implement __eq__. | equals_hash.py:11:1:11:17 | class Ne | Ne | +| equals_hash.py:8:5:8:28 | Function Eq.__eq__ | Class $@ implements __eq__ but does not implement __ne__. | equals_hash.py:3:1:3:17 | class Eq | Eq | +| equals_hash.py:16:5:16:28 | Function Ne.__ne__ | Class $@ implements __ne__ but does not implement __eq__. | equals_hash.py:11:1:11:17 | class Ne | Ne | diff --git a/python/ql/test/3/library-tests/web/django/Sinks.expected b/python/ql/test/3/library-tests/web/django/Sinks.expected deleted file mode 100644 index b4142a2d82a..00000000000 --- a/python/ql/test/3/library-tests/web/django/Sinks.expected +++ /dev/null @@ -1,6 +0,0 @@ -| models.py:9 | key | externally controlled string | -| rawsql.py:4 | BinaryExpr | externally controlled string | -| rawsql.py:13 | BinaryExpr | externally controlled string | -| rawsql.py:18 | BinaryExpr | externally controlled string | -| rawsql.py:22 | BinaryExpr | externally controlled string | -| views.py:8 | Attribute() | externally controlled string | diff --git a/python/ql/test/3/library-tests/web/django/Sinks.ql b/python/ql/test/3/library-tests/web/django/Sinks.ql deleted file mode 100644 index db9b6a89b93..00000000000 --- a/python/ql/test/3/library-tests/web/django/Sinks.ql +++ /dev/null @@ -1,13 +0,0 @@ - -import python - - -import semmle.python.web.django.Request -import semmle.python.web.django.Model -import semmle.python.web.django.Db -import semmle.python.web.django.Response -import semmle.python.security.strings.Untrusted - -from TaintSink sink, TaintKind kind -where sink.sinks(kind) -select sink.getLocation().toString(), sink.(ControlFlowNode).getNode().toString(), kind.toString() diff --git a/python/ql/test/3/library-tests/web/django/Sources.expected b/python/ql/test/3/library-tests/web/django/Sources.expected deleted file mode 100644 index 965142343dc..00000000000 --- a/python/ql/test/3/library-tests/web/django/Sources.expected +++ /dev/null @@ -1,8 +0,0 @@ -| models.py:9 | Attribute | django.db.models.Model.objects | -| rawsql.py:13 | Attribute | django.db.models.Model.objects | -| rawsql.py:16 | Attribute | django.db.models.Model.objects | -| rawsql.py:21 | Attribute | django.db.models.Model.objects | -| views.py:6 | request | django.request.HttpRequest | -| views.py:8 | HttpResponse() | django.response.HttpResponse | -| views.py:11 | path | externally controlled string | -| views.py:11 | request | django.request.HttpRequest | diff --git a/python/ql/test/3/library-tests/web/django/Sources.ql b/python/ql/test/3/library-tests/web/django/Sources.ql deleted file mode 100644 index 60d42cb2ac1..00000000000 --- a/python/ql/test/3/library-tests/web/django/Sources.ql +++ /dev/null @@ -1,12 +0,0 @@ - -import python - - -import semmle.python.web.django.Request -import semmle.python.web.django.Model -import semmle.python.web.django.Response -import semmle.python.security.strings.Untrusted - -from TaintSource src, TaintKind kind -where src.isSourceOf(kind) -select src.getLocation().toString(), src.(ControlFlowNode).getNode().toString(), kind.toString() diff --git a/python/ql/test/3/library-tests/web/django/Taint.expected b/python/ql/test/3/library-tests/web/django/Taint.expected deleted file mode 100644 index 3f40979c8a2..00000000000 --- a/python/ql/test/3/library-tests/web/django/Taint.expected +++ /dev/null @@ -1,24 +0,0 @@ -| models.py:9 | Attribute | django.db.models.Model.objects | -| rawsql.py:13 | Attribute | django.db.models.Model.objects | -| rawsql.py:13 | Attribute() | django.db.models.Model.objects | -| rawsql.py:16 | Attribute | django.db.models.Model.objects | -| rawsql.py:16 | Attribute() | django.db.models.Model.objects | -| rawsql.py:17 | Attribute() | django.db.models.Model.objects | -| rawsql.py:17 | m | django.db.models.Model.objects | -| rawsql.py:18 | Attribute() | django.db.models.Model.objects | -| rawsql.py:18 | m | django.db.models.Model.objects | -| rawsql.py:21 | Attribute | django.db.models.Model.objects | -| rawsql.py:21 | Attribute() | django.db.models.Model.objects | -| rawsql.py:22 | Attribute() | django.db.models.Model.objects | -| rawsql.py:22 | m | django.db.models.Model.objects | -| views.py:6 | request | django.request.HttpRequest | -| views.py:8 | Attribute | django.http.request.QueryDict | -| views.py:8 | Attribute() | externally controlled string | -| views.py:8 | HttpResponse() | django.response.HttpResponse | -| views.py:8 | request | django.request.HttpRequest | -| views.py:11 | path | externally controlled string | -| views.py:11 | request | django.request.HttpRequest | -| views.py:12 | Dict | {externally controlled string} | -| views.py:12 | path | externally controlled string | -| views.py:13 | env | {externally controlled string} | -| views.py:13 | request | django.request.HttpRequest | diff --git a/python/ql/test/3/library-tests/web/django/Taint.ql b/python/ql/test/3/library-tests/web/django/Taint.ql deleted file mode 100644 index b12a6560125..00000000000 --- a/python/ql/test/3/library-tests/web/django/Taint.ql +++ /dev/null @@ -1,14 +0,0 @@ - -import python - - -import semmle.python.web.django.Request -import semmle.python.web.django.Model -import semmle.python.web.django.Response -import semmle.python.security.strings.Untrusted - - -from TaintedNode node - -select node.getLocation().toString(), node.getAstNode().toString(), node.getTaintKind().toString() - diff --git a/python/ql/test/3/library-tests/web/django/django/__init__.py b/python/ql/test/3/library-tests/web/django/django/__init__.py deleted file mode 100644 index fc8d5b8c09b..00000000000 --- a/python/ql/test/3/library-tests/web/django/django/__init__.py +++ /dev/null @@ -1 +0,0 @@ -#Fake django package \ No newline at end of file diff --git a/python/ql/test/3/library-tests/web/django/django/conf/__init__.py b/python/ql/test/3/library-tests/web/django/django/conf/__init__.py deleted file mode 100644 index fc8d5b8c09b..00000000000 --- a/python/ql/test/3/library-tests/web/django/django/conf/__init__.py +++ /dev/null @@ -1 +0,0 @@ -#Fake django package \ No newline at end of file diff --git a/python/ql/test/3/library-tests/web/django/django/conf/urls.py b/python/ql/test/3/library-tests/web/django/django/conf/urls.py deleted file mode 100644 index 580cc063d99..00000000000 --- a/python/ql/test/3/library-tests/web/django/django/conf/urls.py +++ /dev/null @@ -1,3 +0,0 @@ - -def url(regex, view): - pass \ No newline at end of file diff --git a/python/ql/test/3/library-tests/web/django/django/db/__init__.py b/python/ql/test/3/library-tests/web/django/django/db/__init__.py deleted file mode 100644 index fc8d5b8c09b..00000000000 --- a/python/ql/test/3/library-tests/web/django/django/db/__init__.py +++ /dev/null @@ -1 +0,0 @@ -#Fake django package \ No newline at end of file diff --git a/python/ql/test/3/library-tests/web/django/django/db/models/__init__.py b/python/ql/test/3/library-tests/web/django/django/db/models/__init__.py deleted file mode 100644 index eb9c72adc45..00000000000 --- a/python/ql/test/3/library-tests/web/django/django/db/models/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -class Model: - pass diff --git a/python/ql/test/3/library-tests/web/django/django/db/models/expressions.py b/python/ql/test/3/library-tests/web/django/django/db/models/expressions.py deleted file mode 100644 index d7e0d1c27b6..00000000000 --- a/python/ql/test/3/library-tests/web/django/django/db/models/expressions.py +++ /dev/null @@ -1,2 +0,0 @@ -class RawSQL: - pass diff --git a/python/ql/test/3/library-tests/web/django/django/http/__init__.py b/python/ql/test/3/library-tests/web/django/django/http/__init__.py deleted file mode 100644 index e1a02f873cb..00000000000 --- a/python/ql/test/3/library-tests/web/django/django/http/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ - -from .response import HttpResponse diff --git a/python/ql/test/3/library-tests/web/django/django/http/response.py b/python/ql/test/3/library-tests/web/django/django/http/response.py deleted file mode 100644 index f3dd53d15b0..00000000000 --- a/python/ql/test/3/library-tests/web/django/django/http/response.py +++ /dev/null @@ -1,5 +0,0 @@ - -class HttpResponse: - - def __init__(self, *args): - pass diff --git a/python/ql/test/3/library-tests/web/django/models.py b/python/ql/test/3/library-tests/web/django/models.py deleted file mode 100644 index 571c594d055..00000000000 --- a/python/ql/test/3/library-tests/web/django/models.py +++ /dev/null @@ -1,10 +0,0 @@ - -from django.db import models - -class MyModel(models.Model): - title = models.CharField(max_length=500) - summary = models.TextField(blank=True) - -def update_my_model(key, title): - item = MyModel.objects.get(pk=key) - item.title = title diff --git a/python/ql/test/3/library-tests/web/django/rawsql.py b/python/ql/test/3/library-tests/web/django/rawsql.py deleted file mode 100644 index c6c82909c2d..00000000000 --- a/python/ql/test/3/library-tests/web/django/rawsql.py +++ /dev/null @@ -1,23 +0,0 @@ -from django.db.models.expressions import RawSQL - -def raw1(arg): - return RawSQL("select foo from bar where baz = %s" % arg, "") - - -from django.db import models - -class MyModel(models.Model): - pass - -def raw2(arg): - MyModel.objects.raw("select foo from bar where baz = %s" % arg) - -def raw3(arg): - m = MyModel.objects.filter('foo') - m = m.filter('bar') - m.raw("select foo from bar where baz = %s" % arg) - -def raw4(arg): - m = MyModel.objects.filter('foo') - m.extra("select foo from bar where baz = %s" % arg) - diff --git a/python/ql/test/3/library-tests/web/django/urls.py b/python/ql/test/3/library-tests/web/django/urls.py deleted file mode 100644 index d5a941ae519..00000000000 --- a/python/ql/test/3/library-tests/web/django/urls.py +++ /dev/null @@ -1,9 +0,0 @@ -from django.conf.urls import url -import views - -urlpatterns = [ - - url(r'^route1$', views.view_func1), - url(r'^(?P.*)$', views.view_func2), - url(r'^route2$', views.ClassView.as_view()) -] diff --git a/python/ql/test/3/library-tests/web/django/views.py b/python/ql/test/3/library-tests/web/django/views.py deleted file mode 100644 index f7de60a23f6..00000000000 --- a/python/ql/test/3/library-tests/web/django/views.py +++ /dev/null @@ -1,19 +0,0 @@ - -from django.http import HttpResponse -from django.shortcuts import redirect, render -from django.views.generic import View - -def view_func1(request): - # Whether this is safe depends on template.html -- annoyingly - return HttpResponse(request.GET.get("untrusted")) - - -def view_func2(request, path='default'): - env = {'path': path} - return render(request, 'vulnerable-path.html', env) - - -class ClassView(View): - - def get(self, request): - pass diff --git a/python/ql/test/3/library-tests/web/options b/python/ql/test/3/library-tests/web/options deleted file mode 100644 index f2d60a4bc3c..00000000000 --- a/python/ql/test/3/library-tests/web/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: --max-import-depth=3 --lang=3 diff --git a/python/ql/test/library-tests/taint/config/RockPaperScissors.expected b/python/ql/test/library-tests/taint/config/RockPaperScissors.expected index 9e8ed503047..0639e4bf227 100644 --- a/python/ql/test/library-tests/taint/config/RockPaperScissors.expected +++ b/python/ql/test/library-tests/taint/config/RockPaperScissors.expected @@ -28,6 +28,12 @@ edges | rockpaperscissors.py:25:9:25:9 | rock | rockpaperscissors.py:25:9:25:16 | scissors | | rockpaperscissors.py:25:9:25:16 | scissors | rockpaperscissors.py:25:9:25:23 | paper | | rockpaperscissors.py:25:9:25:23 | paper | rockpaperscissors.py:26:14:26:14 | paper | +| sanitizer.py:9:9:9:20 | SQL injection | sanitizer.py:13:19:13:19 | SQL injection | +| sanitizer.py:16:9:16:20 | Command injection | sanitizer.py:20:20:20:20 | Command injection | +| sanitizer.py:24:9:24:20 | SQL injection | sanitizer.py:26:19:26:19 | SQL injection | +| sanitizer.py:24:9:24:20 | SQL injection | sanitizer.py:28:19:28:19 | SQL injection | +| sanitizer.py:31:9:31:20 | Command injection | sanitizer.py:33:20:33:20 | Command injection | +| sanitizer.py:31:9:31:20 | Command injection | sanitizer.py:35:20:35:20 | Command injection | | test.py:6:9:6:14 | simple.test | test.py:7:10:7:10 | simple.test | | test.py:10:12:10:17 | simple.test | test.py:16:9:16:16 | simple.test | | test.py:10:12:10:17 | simple.test | test.py:24:9:24:16 | simple.test | diff --git a/python/ql/test/library-tests/taint/config/Simple.expected b/python/ql/test/library-tests/taint/config/Simple.expected index 6c2b87aa31e..108f0f12015 100644 --- a/python/ql/test/library-tests/taint/config/Simple.expected +++ b/python/ql/test/library-tests/taint/config/Simple.expected @@ -28,6 +28,12 @@ edges | rockpaperscissors.py:25:9:25:9 | rock | rockpaperscissors.py:25:9:25:16 | scissors | | rockpaperscissors.py:25:9:25:16 | scissors | rockpaperscissors.py:25:9:25:23 | paper | | rockpaperscissors.py:25:9:25:23 | paper | rockpaperscissors.py:26:14:26:14 | paper | +| sanitizer.py:9:9:9:20 | SQL injection | sanitizer.py:13:19:13:19 | SQL injection | +| sanitizer.py:16:9:16:20 | Command injection | sanitizer.py:20:20:20:20 | Command injection | +| sanitizer.py:24:9:24:20 | SQL injection | sanitizer.py:26:19:26:19 | SQL injection | +| sanitizer.py:24:9:24:20 | SQL injection | sanitizer.py:28:19:28:19 | SQL injection | +| sanitizer.py:31:9:31:20 | Command injection | sanitizer.py:33:20:33:20 | Command injection | +| sanitizer.py:31:9:31:20 | Command injection | sanitizer.py:35:20:35:20 | Command injection | | test.py:6:9:6:14 | simple.test | test.py:7:10:7:10 | simple.test | | test.py:10:12:10:17 | simple.test | test.py:16:9:16:16 | simple.test | | test.py:10:12:10:17 | simple.test | test.py:24:9:24:16 | simple.test | diff --git a/python/ql/test/library-tests/web/django/Sinks.expected b/python/ql/test/library-tests/web/django/Sinks.expected index 82d1b71e53a..e3d233c9990 100644 --- a/python/ql/test/library-tests/web/django/Sinks.expected +++ b/python/ql/test/library-tests/web/django/Sinks.expected @@ -1,6 +1,16 @@ -| test.py:18 | Str | externally controlled string | -| test.py:21 | BinaryExpr | externally controlled string | -| test.py:24 | BinaryExpr | externally controlled string | -| test.py:25 | BinaryExpr | externally controlled string | -| test.py:26 | BinaryExpr | externally controlled string | -| test.py:34 | BinaryExpr | externally controlled string | +| sql.py:13 | Str | externally controlled string | +| sql.py:14 | Str | externally controlled string | +| sql.py:17 | BinaryExpr | externally controlled string | +| sql.py:20 | BinaryExpr | externally controlled string | +| sql.py:21 | BinaryExpr | externally controlled string | +| sql.py:22 | BinaryExpr | externally controlled string | +| sql.py:36 | Str | externally controlled string | +| sql.py:42 | BinaryExpr | externally controlled string | +| sql.py:47 | BinaryExpr | externally controlled string | +| views.py:7 | Attribute() | externally controlled string | +| views.py:11 | Attribute() | externally controlled string | +| views.py:15 | Attribute() | externally controlled string | +| views.py:23 | Attribute() | externally controlled string | +| views.py:29 | Attribute() | externally controlled string | +| views.py:34 | Attribute() | externally controlled string | +| views.py:38 | Attribute() | externally controlled string | diff --git a/python/ql/test/library-tests/web/django/Sources.expected b/python/ql/test/library-tests/web/django/Sources.expected index 8f421a2d169..35e0d3d8ced 100644 --- a/python/ql/test/library-tests/web/django/Sources.expected +++ b/python/ql/test/library-tests/web/django/Sources.expected @@ -1,2 +1,19 @@ +| test.py:5 | path | externally controlled string | +| test.py:5 | request | django.request.HttpRequest | +| test.py:11 | path | externally controlled string | | test.py:11 | request | django.request.HttpRequest | -| test.py:31 | request | django.request.HttpRequest | +| views.py:6 | bar | externally controlled string | +| views.py:6 | foo | externally controlled string | +| views.py:6 | request | django.request.HttpRequest | +| views.py:10 | request | django.request.HttpRequest | +| views.py:14 | request | django.request.HttpRequest | +| views.py:22 | request | django.request.HttpRequest | +| views.py:28 | request | django.request.HttpRequest | +| views.py:32 | page_number | externally controlled string | +| views.py:32 | request | django.request.HttpRequest | +| views.py:37 | arg0 | externally controlled string | +| views.py:37 | arg1 | externally controlled string | +| views.py:37 | request | django.request.HttpRequest | +| views.py:57 | request | django.request.HttpRequest | +| views.py:57 | username | externally controlled string | +| views.py:66 | request | django.request.HttpRequest | diff --git a/python/ql/test/library-tests/web/django/sql.py b/python/ql/test/library-tests/web/django/sql.py new file mode 100644 index 00000000000..7809c24edc1 --- /dev/null +++ b/python/ql/test/library-tests/web/django/sql.py @@ -0,0 +1,53 @@ +from django.db import connection, models +from django.db.models.expressions import RawSQL + + +class User(models.Model): + username = models.CharField(max_length=100) + description = models.TextField(blank=True) + + +def show_user(username): + with connection.cursor() as cursor: + # GOOD -- Using parameters + cursor.execute("SELECT * FROM users WHERE username = %s", username) + User.objects.raw("SELECT * FROM users WHERE username = %s", (username,)) + + # BAD -- Using string formatting + cursor.execute("SELECT * FROM users WHERE username = '%s'" % username) + + # BAD -- other ways of executing raw SQL code with string interpolation + User.objects.annotate(RawSQL("insert into names_file ('name') values ('%s')" % username)) + User.objects.raw("insert into names_file ('name') values ('%s')" % username) + User.objects.extra("insert into names_file ('name') values ('%s')" % username) + + # BAD (but currently no custom query to find this) + # + # It is exposed to SQL injection (https://docs.djangoproject.com/en/2.2/ref/models/querysets/#extra) + # For example, using name = "; DROP ALL TABLES -- " + # will result in SQL: SELECT * FROM name WHERE name = ''; DROP ALL TABLES -- '' + # + # This shouldn't be very widespread, since using a normal string will result in invalid SQL + # Using name = "example", will result in SQL: SELECT * FROM name WHERE name = ''example'' + # which in MySQL will give a syntax error + # + # When testing this out locally, none of the queries worked against SQLite3, but I could use + # the SQL injection against MySQL. + User.objects.raw("SELECT * FROM users WHERE username = '%s'", (username,)) + + +def raw3(arg): + m = User.objects.filter('foo') + m = m.filter('bar') + m.raw("select foo from bar where baz = %s" % arg) + + +def raw4(arg): + m = User.objects.filter('foo') + m.extra("select foo from bar where baz = %s" % arg) + + +def update_user(key, description1): + # Neither of these are exposed to sql-injections + user = User.objects.get(pk=key) + item.description = description diff --git a/python/ql/test/library-tests/web/django/test.py b/python/ql/test/library-tests/web/django/test.py index e6c39c30a32..5664647c3a7 100644 --- a/python/ql/test/library-tests/web/django/test.py +++ b/python/ql/test/library-tests/web/django/test.py @@ -1,40 +1,18 @@ +from django.conf.urls import url +from django.shortcuts import redirect, render -from django.conf.urls import patterns, url -from django.db import connection, models -from django.db.models.expressions import RawSQL -from django.http.response import HttpResponse -import base64 -class Name(models.Model): - pass +def with_template(request, path='default'): + env = {'path': path} + # We would need to understand django templates to know if this is safe or not + return render(request, 'possibly-vulnerable-template.html', env) -def save_name(request): - if request.method == 'POST': - name = request.POST.get('name') - curs = connection.cursor() - #GOOD -- Using parameters - curs.execute( - "insert into names_file ('name') values ('%s')", name) - #BAD -- Using string formatting - curs.execute( - "insert into names_file ('name') values ('%s')" % name) +def vuln_redirect(request, path): + return redirect(path) - #BAD -- other ways of executing raw SQL code with string interpolation - Name.objects.annotate(RawSQL("insert into names_file ('name') values ('%s')" % name)) - Name.objects.raw("insert into names_file ('name') values ('%s')" % name) - Name.objects.extra("insert into names_file ('name') values ('%s')" % name) -urlpatterns1 = patterns(url(r'^save_name/$', - save_name, name='save_name')) - -def maybe_xss(request): - first_name = request.POST.get('first_name', '') - resp = HttpResponse() - resp.write("first name is " + first_name) - return resp - -urlpatterns2 = [ - # Route to code_execution - url(r'^maybe_xss$', maybe_xss, name='maybe_xss') +urlpatterns = [ + url(r'^(?P.*)$', with_template), + url(r'^redirect/(?P.*)$', vuln_redirect), ] diff --git a/python/ql/test/library-tests/web/django/views.py b/python/ql/test/library-tests/web/django/views.py new file mode 100644 index 00000000000..57d1ea5460c --- /dev/null +++ b/python/ql/test/library-tests/web/django/views.py @@ -0,0 +1,72 @@ +from django.conf.urls import patterns, url +from django.http.response import HttpResponse +from django.views.generic import View + + +def url_match_xss(request, foo, bar, no_taint=None): + return HttpResponse('url_match_xss: {} {}'.format(foo, bar)) + + +def get_params_xss(request): + return HttpResponse(request.GET.get("untrusted")) + + +def post_params_xss(request): + return HttpResponse(request.POST.get("untrusted")) + + +class Foo(object): + # Note: since Foo is used as the super type in a class view, it will be able to handle requests. + + # TODO: Currently we don't flag `untrusted` as a DjangoRequestParameter + def post(self, request, untrusted): + return HttpResponse('Foo post: {}'.format(untrusted)) + + +class ClassView(View, Foo): + # TODO: Currently we don't flag `untrusted` as a DjangoRequestParameter + def get(self, request, untrusted): + return HttpResponse('ClassView get: {}'.format(untrusted)) + + +def show_articles(request, page_number=1): + page_number = int(page_number) + return HttpResponse('articles page: {}'.format(page_number)) + + +def xxs_positional_arg(request, arg0, arg1, no_taint=None): + return HttpResponse('xxs_positional_arg: {} {}'.format(arg0, arg1)) + + +urlpatterns = [ + url(r'^url_match/(?P[^/]+)/(?P[^/]+)$', url_match_xss), + url(r'^get_params$', get_params_xss), + url(r'^post_params$', post_params_xss), + url(r'^class_view/(?P.+)$', ClassView.as_view()), + + # one pattern to support `articles/page-` and ensuring that articles/ goes to page-1 + url(r'articles/^(?:page-(?P\d+)/)?$', show_articles), + # passing as positional argument is not the recommended way of doing things, but it is certainly + # possible + url(r'^([^/]+)/(?:foo|bar)/([^/]+)$', xxs_positional_arg, name='xxs_positional_arg'), +] + + +# Using patterns() for routing + +def show_user(request, username): + pass + + +urlpatterns = patterns(url(r'^users/(?P[^/]+)$', show_user)) + + +# Show we understand the keyword arguments to django.conf.urls.url + +def we_understand_url_kwargs(request): + pass + + +urlpatterns = [ + url(view=we_understand_url_kwargs, regex=r'^specifying-as-kwargs-is-not-a-problem$') +] diff --git a/python/ql/test/qlpack.yml b/python/ql/test/qlpack.yml new file mode 100644 index 00000000000..eed82a82aec --- /dev/null +++ b/python/ql/test/qlpack.yml @@ -0,0 +1,3 @@ +name: codeql-python-tests +version: 0.0.0 +libraryPathDependencies: codeql-python diff --git a/python/ql/test/query-tests/Imports/unused/imports_test.py b/python/ql/test/query-tests/Imports/unused/imports_test.py index a1b457f0422..cf2024ac183 100644 --- a/python/ql/test/query-tests/Imports/unused/imports_test.py +++ b/python/ql/test/query-tests/Imports/unused/imports_test.py @@ -76,3 +76,17 @@ import typing foo = None # type: typing.Optional[int] + +# OK since the import statement is never executed +if False: + import never_imported + +# OK since the imported module is used in a forward-referenced type annotation. +import only_used_in_parameter_annotation + +def func(x: 'Optional[only_used_in_parameter_annotation]'): + pass + +import only_used_in_annotated_assignment + +var : 'Optional[only_used_in_annotated_assignment]' = 5 diff --git a/python/ql/test/query-tests/Security/CWE-022/PathInjection.expected b/python/ql/test/query-tests/Security/CWE-022/PathInjection.expected index 646b22edea4..3cf398a025e 100644 --- a/python/ql/test/query-tests/Security/CWE-022/PathInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-022/PathInjection.expected @@ -1,16 +1,29 @@ edges | path_injection.py:9:12:9:23 | dict of externally controlled string | path_injection.py:9:12:9:39 | externally controlled string | +| path_injection.py:9:12:9:23 | dict of externally controlled string | path_injection.py:9:12:9:39 | externally controlled string | +| path_injection.py:9:12:9:39 | externally controlled string | path_injection.py:10:40:10:43 | externally controlled string | | path_injection.py:9:12:9:39 | externally controlled string | path_injection.py:10:40:10:43 | externally controlled string | | path_injection.py:10:40:10:43 | externally controlled string | path_injection.py:10:14:10:44 | externally controlled string | +| path_injection.py:10:40:10:43 | externally controlled string | path_injection.py:10:14:10:44 | externally controlled string | +| path_injection.py:15:12:15:23 | dict of externally controlled string | path_injection.py:15:12:15:39 | externally controlled string | | path_injection.py:15:12:15:23 | dict of externally controlled string | path_injection.py:15:12:15:39 | externally controlled string | | path_injection.py:15:12:15:39 | externally controlled string | path_injection.py:16:56:16:59 | externally controlled string | +| path_injection.py:15:12:15:39 | externally controlled string | path_injection.py:16:56:16:59 | externally controlled string | +| path_injection.py:16:13:16:61 | normalized path | path_injection.py:17:14:17:18 | normalized path | | path_injection.py:16:13:16:61 | normalized path | path_injection.py:17:14:17:18 | normalized path | | path_injection.py:16:30:16:60 | externally controlled string | path_injection.py:16:13:16:61 | normalized path | +| path_injection.py:16:30:16:60 | externally controlled string | path_injection.py:16:13:16:61 | normalized path | +| path_injection.py:16:56:16:59 | externally controlled string | path_injection.py:16:30:16:60 | externally controlled string | | path_injection.py:16:56:16:59 | externally controlled string | path_injection.py:16:30:16:60 | externally controlled string | | path_injection.py:24:12:24:23 | dict of externally controlled string | path_injection.py:24:12:24:39 | externally controlled string | +| path_injection.py:24:12:24:23 | dict of externally controlled string | path_injection.py:24:12:24:39 | externally controlled string | +| path_injection.py:24:12:24:39 | externally controlled string | path_injection.py:25:56:25:59 | externally controlled string | | path_injection.py:24:12:24:39 | externally controlled string | path_injection.py:25:56:25:59 | externally controlled string | | path_injection.py:25:13:25:61 | normalized path | path_injection.py:28:14:28:18 | normalized path | +| path_injection.py:25:13:25:61 | normalized path | path_injection.py:28:14:28:18 | normalized path | | path_injection.py:25:30:25:60 | externally controlled string | path_injection.py:25:13:25:61 | normalized path | +| path_injection.py:25:30:25:60 | externally controlled string | path_injection.py:25:13:25:61 | normalized path | +| path_injection.py:25:56:25:59 | externally controlled string | path_injection.py:25:30:25:60 | externally controlled string | | path_injection.py:25:56:25:59 | externally controlled string | path_injection.py:25:30:25:60 | externally controlled string | #select | path_injection.py:10:14:10:44 | Attribute() | path_injection.py:9:12:9:23 | dict of externally controlled string | path_injection.py:10:14:10:44 | externally controlled string | This path depends on $@. | path_injection.py:9:12:9:23 | Attribute | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-022/TarSlip.expected b/python/ql/test/query-tests/Security/CWE-022/TarSlip.expected index d1ddd948a43..73e28287dcf 100644 --- a/python/ql/test/query-tests/Security/CWE-022/TarSlip.expected +++ b/python/ql/test/query-tests/Security/CWE-022/TarSlip.expected @@ -1,11 +1,19 @@ edges | tarslip.py:12:7:12:39 | tarfile.open | tarslip.py:13:1:13:3 | tarfile.open | +| tarslip.py:12:7:12:39 | tarfile.open | tarslip.py:13:1:13:3 | tarfile.open | +| tarslip.py:16:7:16:39 | tarfile.open | tarslip.py:17:14:17:16 | tarfile.open | | tarslip.py:16:7:16:39 | tarfile.open | tarslip.py:17:14:17:16 | tarfile.open | | tarslip.py:17:1:17:17 | tarfile.entry | tarslip.py:18:17:18:21 | tarfile.entry | +| tarslip.py:17:1:17:17 | tarfile.entry | tarslip.py:18:17:18:21 | tarfile.entry | +| tarslip.py:17:14:17:16 | tarfile.open | tarslip.py:17:1:17:17 | tarfile.entry | | tarslip.py:17:14:17:16 | tarfile.open | tarslip.py:17:1:17:17 | tarfile.entry | | tarslip.py:33:7:33:39 | tarfile.open | tarslip.py:34:14:34:16 | tarfile.open | +| tarslip.py:33:7:33:39 | tarfile.open | tarslip.py:34:14:34:16 | tarfile.open | +| tarslip.py:34:1:34:17 | tarfile.entry | tarslip.py:37:17:37:21 | tarfile.entry | | tarslip.py:34:1:34:17 | tarfile.entry | tarslip.py:37:17:37:21 | tarfile.entry | | tarslip.py:34:14:34:16 | tarfile.open | tarslip.py:34:1:34:17 | tarfile.entry | +| tarslip.py:34:14:34:16 | tarfile.open | tarslip.py:34:1:34:17 | tarfile.entry | +| tarslip.py:40:7:40:39 | tarfile.open | tarslip.py:41:24:41:26 | tarfile.open | | tarslip.py:40:7:40:39 | tarfile.open | tarslip.py:41:24:41:26 | tarfile.open | #select | tarslip.py:13:1:13:3 | tar | tarslip.py:12:7:12:39 | tarfile.open | tarslip.py:13:1:13:3 | tarfile.open | Extraction of tarfile from $@ | tarslip.py:12:7:12:39 | Attribute() | a potentially untrusted source | diff --git a/python/ql/test/query-tests/Security/CWE-078/CommandInjection.expected b/python/ql/test/query-tests/Security/CWE-078/CommandInjection.expected index d3b67cc239d..3d1cf22a2d1 100644 --- a/python/ql/test/query-tests/Security/CWE-078/CommandInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-078/CommandInjection.expected @@ -1,15 +1,27 @@ edges | command_injection.py:10:13:10:24 | dict of externally controlled string | command_injection.py:10:13:10:41 | externally controlled string | +| command_injection.py:10:13:10:24 | dict of externally controlled string | command_injection.py:10:13:10:41 | externally controlled string | +| command_injection.py:10:13:10:41 | externally controlled string | command_injection.py:12:23:12:27 | externally controlled string | | command_injection.py:10:13:10:41 | externally controlled string | command_injection.py:12:23:12:27 | externally controlled string | | command_injection.py:12:23:12:27 | externally controlled string | command_injection.py:12:15:12:27 | externally controlled string | +| command_injection.py:12:23:12:27 | externally controlled string | command_injection.py:12:15:12:27 | externally controlled string | +| command_injection.py:17:13:17:24 | dict of externally controlled string | command_injection.py:17:13:17:41 | externally controlled string | | command_injection.py:17:13:17:24 | dict of externally controlled string | command_injection.py:17:13:17:41 | externally controlled string | | command_injection.py:17:13:17:41 | externally controlled string | command_injection.py:19:29:19:33 | externally controlled string | +| command_injection.py:17:13:17:41 | externally controlled string | command_injection.py:19:29:19:33 | externally controlled string | +| command_injection.py:19:29:19:33 | externally controlled string | command_injection.py:19:22:19:34 | sequence of externally controlled string | | command_injection.py:19:29:19:33 | externally controlled string | command_injection.py:19:22:19:34 | sequence of externally controlled string | | command_injection.py:24:11:24:22 | dict of externally controlled string | command_injection.py:24:11:24:37 | externally controlled string | +| command_injection.py:24:11:24:22 | dict of externally controlled string | command_injection.py:24:11:24:37 | externally controlled string | +| command_injection.py:24:11:24:37 | externally controlled string | command_injection.py:25:23:25:25 | externally controlled string | | command_injection.py:24:11:24:37 | externally controlled string | command_injection.py:25:23:25:25 | externally controlled string | | command_injection.py:25:23:25:25 | externally controlled string | command_injection.py:25:22:25:36 | first item in sequence of externally controlled string | +| command_injection.py:25:23:25:25 | externally controlled string | command_injection.py:25:22:25:36 | first item in sequence of externally controlled string | +| command_injection.py:30:13:30:24 | dict of externally controlled string | command_injection.py:30:13:30:41 | externally controlled string | | command_injection.py:30:13:30:24 | dict of externally controlled string | command_injection.py:30:13:30:41 | externally controlled string | | command_injection.py:30:13:30:41 | externally controlled string | command_injection.py:32:22:32:26 | externally controlled string | +| command_injection.py:30:13:30:41 | externally controlled string | command_injection.py:32:22:32:26 | externally controlled string | +| command_injection.py:32:22:32:26 | externally controlled string | command_injection.py:32:14:32:26 | externally controlled string | | command_injection.py:32:22:32:26 | externally controlled string | command_injection.py:32:14:32:26 | externally controlled string | #select | command_injection.py:12:15:12:27 | BinaryExpr | command_injection.py:10:13:10:24 | dict of externally controlled string | command_injection.py:12:15:12:27 | externally controlled string | This command depends on $@. | command_injection.py:10:13:10:24 | Attribute | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected b/python/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected index d23198b92a7..46236de24ed 100644 --- a/python/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected +++ b/python/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected @@ -1,8 +1,13 @@ edges | ../lib/flask/__init__.py:14:19:14:20 | externally controlled string | ../lib/flask/__init__.py:16:25:16:26 | externally controlled string | +| ../lib/flask/__init__.py:14:19:14:20 | externally controlled string | ../lib/flask/__init__.py:16:25:16:26 | externally controlled string | +| reflected_xss.py:7:18:7:29 | dict of externally controlled string | reflected_xss.py:7:18:7:45 | externally controlled string | | reflected_xss.py:7:18:7:29 | dict of externally controlled string | reflected_xss.py:7:18:7:45 | externally controlled string | | reflected_xss.py:7:18:7:45 | externally controlled string | reflected_xss.py:8:44:8:53 | externally controlled string | +| reflected_xss.py:7:18:7:45 | externally controlled string | reflected_xss.py:8:44:8:53 | externally controlled string | | reflected_xss.py:8:26:8:53 | externally controlled string | ../lib/flask/__init__.py:14:19:14:20 | externally controlled string | +| reflected_xss.py:8:26:8:53 | externally controlled string | ../lib/flask/__init__.py:14:19:14:20 | externally controlled string | +| reflected_xss.py:8:44:8:53 | externally controlled string | reflected_xss.py:8:26:8:53 | externally controlled string | | reflected_xss.py:8:44:8:53 | externally controlled string | reflected_xss.py:8:26:8:53 | externally controlled string | #select | ../lib/flask/__init__.py:16:25:16:26 | rv | reflected_xss.py:7:18:7:29 | dict of externally controlled string | ../lib/flask/__init__.py:16:25:16:26 | externally controlled string | Cross-site scripting vulnerability due to $@. | reflected_xss.py:7:18:7:29 | Attribute | user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-089/SqlInjection.expected b/python/ql/test/query-tests/Security/CWE-089/SqlInjection.expected index 9c00ffdb2db..c137359a683 100644 --- a/python/ql/test/query-tests/Security/CWE-089/SqlInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-089/SqlInjection.expected @@ -1,17 +1,22 @@ edges -| sql_injection.py:9:15:9:21 | django.request.HttpRequest | sql_injection.py:12:16:12:22 | django.request.HttpRequest | -| sql_injection.py:12:16:12:22 | django.request.HttpRequest | sql_injection.py:12:16:12:27 | django.http.request.QueryDict | -| sql_injection.py:12:16:12:27 | django.http.request.QueryDict | sql_injection.py:12:16:12:39 | externally controlled string | -| sql_injection.py:12:16:12:39 | externally controlled string | sql_injection.py:19:63:19:66 | externally controlled string | -| sql_injection.py:12:16:12:39 | externally controlled string | sql_injection.py:22:88:22:91 | externally controlled string | -| sql_injection.py:12:16:12:39 | externally controlled string | sql_injection.py:23:76:23:79 | externally controlled string | -| sql_injection.py:12:16:12:39 | externally controlled string | sql_injection.py:24:78:24:81 | externally controlled string | -| sql_injection.py:19:63:19:66 | externally controlled string | sql_injection.py:19:13:19:66 | externally controlled string | -| sql_injection.py:22:88:22:91 | externally controlled string | sql_injection.py:22:38:22:91 | externally controlled string | -| sql_injection.py:23:76:23:79 | externally controlled string | sql_injection.py:23:26:23:79 | externally controlled string | -| sql_injection.py:24:78:24:81 | externally controlled string | sql_injection.py:24:28:24:81 | externally controlled string | +| sql_injection.py:12:24:12:31 | externally controlled string | sql_injection.py:19:70:19:77 | externally controlled string | +| sql_injection.py:12:24:12:31 | externally controlled string | sql_injection.py:19:70:19:77 | externally controlled string | +| sql_injection.py:12:24:12:31 | externally controlled string | sql_injection.py:22:88:22:95 | externally controlled string | +| sql_injection.py:12:24:12:31 | externally controlled string | sql_injection.py:22:88:22:95 | externally controlled string | +| sql_injection.py:12:24:12:31 | externally controlled string | sql_injection.py:23:76:23:83 | externally controlled string | +| sql_injection.py:12:24:12:31 | externally controlled string | sql_injection.py:23:76:23:83 | externally controlled string | +| sql_injection.py:12:24:12:31 | externally controlled string | sql_injection.py:24:78:24:85 | externally controlled string | +| sql_injection.py:12:24:12:31 | externally controlled string | sql_injection.py:24:78:24:85 | externally controlled string | +| sql_injection.py:19:70:19:77 | externally controlled string | sql_injection.py:19:24:19:77 | externally controlled string | +| sql_injection.py:19:70:19:77 | externally controlled string | sql_injection.py:19:24:19:77 | externally controlled string | +| sql_injection.py:22:88:22:95 | externally controlled string | sql_injection.py:22:38:22:95 | externally controlled string | +| sql_injection.py:22:88:22:95 | externally controlled string | sql_injection.py:22:38:22:95 | externally controlled string | +| sql_injection.py:23:76:23:83 | externally controlled string | sql_injection.py:23:26:23:83 | externally controlled string | +| sql_injection.py:23:76:23:83 | externally controlled string | sql_injection.py:23:26:23:83 | externally controlled string | +| sql_injection.py:24:78:24:85 | externally controlled string | sql_injection.py:24:28:24:85 | externally controlled string | +| sql_injection.py:24:78:24:85 | externally controlled string | sql_injection.py:24:28:24:85 | externally controlled string | #select -| sql_injection.py:19:13:19:66 | BinaryExpr | sql_injection.py:9:15:9:21 | django.request.HttpRequest | sql_injection.py:19:13:19:66 | externally controlled string | This SQL query depends on $@. | sql_injection.py:9:15:9:21 | request | a user-provided value | -| sql_injection.py:22:38:22:91 | BinaryExpr | sql_injection.py:9:15:9:21 | django.request.HttpRequest | sql_injection.py:22:38:22:91 | externally controlled string | This SQL query depends on $@. | sql_injection.py:9:15:9:21 | request | a user-provided value | -| sql_injection.py:23:26:23:79 | BinaryExpr | sql_injection.py:9:15:9:21 | django.request.HttpRequest | sql_injection.py:23:26:23:79 | externally controlled string | This SQL query depends on $@. | sql_injection.py:9:15:9:21 | request | a user-provided value | -| sql_injection.py:24:28:24:81 | BinaryExpr | sql_injection.py:9:15:9:21 | django.request.HttpRequest | sql_injection.py:24:28:24:81 | externally controlled string | This SQL query depends on $@. | sql_injection.py:9:15:9:21 | request | a user-provided value | +| sql_injection.py:19:24:19:77 | BinaryExpr | sql_injection.py:12:24:12:31 | externally controlled string | sql_injection.py:19:24:19:77 | externally controlled string | This SQL query depends on $@. | sql_injection.py:12:24:12:31 | username | a user-provided value | +| sql_injection.py:22:38:22:95 | BinaryExpr | sql_injection.py:12:24:12:31 | externally controlled string | sql_injection.py:22:38:22:95 | externally controlled string | This SQL query depends on $@. | sql_injection.py:12:24:12:31 | username | a user-provided value | +| sql_injection.py:23:26:23:83 | BinaryExpr | sql_injection.py:12:24:12:31 | externally controlled string | sql_injection.py:23:26:23:83 | externally controlled string | This SQL query depends on $@. | sql_injection.py:12:24:12:31 | username | a user-provided value | +| sql_injection.py:24:28:24:85 | BinaryExpr | sql_injection.py:12:24:12:31 | externally controlled string | sql_injection.py:24:28:24:85 | externally controlled string | This SQL query depends on $@. | sql_injection.py:12:24:12:31 | username | a user-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-089/sql_injection.py b/python/ql/test/query-tests/Security/CWE-089/sql_injection.py index b312241b809..9ccca7503bd 100644 --- a/python/ql/test/query-tests/Security/CWE-089/sql_injection.py +++ b/python/ql/test/query-tests/Security/CWE-089/sql_injection.py @@ -1,28 +1,40 @@ +"""This is copied from ql/python/ql/test/library-tests/web/django/test.py +and a only a slight extension of ql/python/ql/src/Security/CWE-089/examples/sql_injection.py +""" -from django.conf.urls import patterns, url +from django.conf.urls import url from django.db import connection, models from django.db.models.expressions import RawSQL -class Name(models.Model): +class User(models.Model): pass -def save_name(request): +def show_user(request, username): + with connection.cursor() as cursor: + # GOOD -- Using parameters + cursor.execute("SELECT * FROM users WHERE username = %s", username) + User.objects.raw("SELECT * FROM users WHERE username = %s", (username,)) - if request.method == 'POST': - name = request.POST.get('name') - curs = connection.cursor() - #GOOD -- Using parameters - curs.execute( - "insert into names_file ('name') values ('%s')", name) - #BAD -- Using string formatting - curs.execute( - "insert into names_file ('name') values ('%s')" % name) + # BAD -- Using string formatting + cursor.execute("SELECT * FROM users WHERE username = '%s'" % username) - #BAD -- other ways of executing raw SQL code with string interpolation - Name.objects.annotate(RawSQL("insert into names_file ('name') values ('%s')" % name)) - Name.objects.raw("insert into names_file ('name') values ('%s')" % name) - Name.objects.extra("insert into names_file ('name') values ('%s')" % name) + # BAD -- other ways of executing raw SQL code with string interpolation + User.objects.annotate(RawSQL("insert into names_file ('name') values ('%s')" % username)) + User.objects.raw("insert into names_file ('name') values ('%s')" % username) + User.objects.extra("insert into names_file ('name') values ('%s')" % username) -urlpatterns = patterns(url(r'^save_name/$', - save_name, name='save_name')) + # BAD (but currently no custom query to find this) + # + # It is exposed to SQL injection (https://docs.djangoproject.com/en/2.2/ref/models/querysets/#extra) + # For example, using name = "; DROP ALL TABLES -- " + # will result in SQL: SELECT * FROM name WHERE name = ''; DROP ALL TABLES -- '' + # + # This shouldn't be very widespread, since using a normal string will result in invalid SQL + # Using name = "example", will result in SQL: SELECT * FROM name WHERE name = ''example'' + # which in MySQL will give a syntax error + # + # When testing this out locally, none of the queries worked against SQLite3, but I could use + # the SQL injection against MySQL. + User.objects.raw("SELECT * FROM users WHERE username = '%s'", (username,)) +urlpatterns = [url(r'^users/(?P[^/]+)$', show_user)] diff --git a/python/ql/test/query-tests/Security/CWE-094/CodeInjection.expected b/python/ql/test/query-tests/Security/CWE-094/CodeInjection.expected index e01d6b651e3..17430312cf6 100644 --- a/python/ql/test/query-tests/Security/CWE-094/CodeInjection.expected +++ b/python/ql/test/query-tests/Security/CWE-094/CodeInjection.expected @@ -1,8 +1,13 @@ edges | code_injection.py:4:20:4:26 | django.request.HttpRequest | code_injection.py:6:22:6:28 | django.request.HttpRequest | +| code_injection.py:4:20:4:26 | django.request.HttpRequest | code_injection.py:6:22:6:28 | django.request.HttpRequest | +| code_injection.py:6:22:6:28 | django.request.HttpRequest | code_injection.py:6:22:6:33 | django.http.request.QueryDict | | code_injection.py:6:22:6:28 | django.request.HttpRequest | code_injection.py:6:22:6:33 | django.http.request.QueryDict | | code_injection.py:6:22:6:33 | django.http.request.QueryDict | code_injection.py:6:22:6:55 | externally controlled string | +| code_injection.py:6:22:6:33 | django.http.request.QueryDict | code_injection.py:6:22:6:55 | externally controlled string | | code_injection.py:6:22:6:55 | externally controlled string | code_injection.py:7:34:7:43 | externally controlled string | +| code_injection.py:6:22:6:55 | externally controlled string | code_injection.py:7:34:7:43 | externally controlled string | +| code_injection.py:7:34:7:43 | externally controlled string | code_injection.py:7:14:7:44 | externally controlled string | | code_injection.py:7:34:7:43 | externally controlled string | code_injection.py:7:14:7:44 | externally controlled string | #select | code_injection.py:7:14:7:44 | Attribute() | code_injection.py:4:20:4:26 | django.request.HttpRequest | code_injection.py:7:14:7:44 | externally controlled string | $@ flows to here and is interpreted as code. | code_injection.py:4:20:4:26 | request | User-provided value | diff --git a/python/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected b/python/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected index c714bd52fa5..8bf682bf052 100644 --- a/python/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected +++ b/python/ql/test/query-tests/Security/CWE-209/StackTraceExposure.expected @@ -1,5 +1,7 @@ edges | test.py:33:15:33:36 | exception info | test.py:34:29:34:31 | exception info | +| test.py:33:15:33:36 | exception info | test.py:34:29:34:31 | exception info | +| test.py:34:29:34:31 | exception info | test.py:34:16:34:32 | exception info | | test.py:34:29:34:31 | exception info | test.py:34:16:34:32 | exception info | #select | test.py:16:16:16:37 | Attribute() | test.py:16:16:16:37 | exception info | test.py:16:16:16:37 | exception info | $@ may be exposed to an external user | test.py:16:16:16:37 | Attribute() | Error information | diff --git a/python/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected b/python/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected index cb6106aa395..7681eb91319 100644 --- a/python/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected +++ b/python/ql/test/query-tests/Security/CWE-312/CleartextLogging.expected @@ -1,5 +1,8 @@ edges +| password_in_cookie.py:7:16:7:43 | a password | password_in_cookie.py:9:33:9:40 | a password | | test.py:7:16:7:29 | a password | test.py:8:35:8:42 | a password | +| test.py:7:16:7:29 | a password | test.py:8:35:8:42 | a password | +| test.py:20:12:20:21 | a certificate or key | test.py:22:20:22:23 | a certificate or key | #select | test.py:8:35:8:42 | password | test.py:7:16:7:29 | a password | test.py:8:35:8:42 | a password | Sensitive data returned by $@ is logged here. | test.py:7:16:7:29 | get_password() | a call returning a password | | test.py:14:30:14:39 | get_cert() | test.py:14:30:14:39 | a certificate or key | test.py:14:30:14:39 | a certificate or key | Sensitive data returned by $@ is logged here. | test.py:14:30:14:39 | get_cert() | a call returning a certificate or key | diff --git a/python/ql/test/query-tests/Security/CWE-312/CleartextStorage.expected b/python/ql/test/query-tests/Security/CWE-312/CleartextStorage.expected index 23459c0980e..75bedd7187e 100644 --- a/python/ql/test/query-tests/Security/CWE-312/CleartextStorage.expected +++ b/python/ql/test/query-tests/Security/CWE-312/CleartextStorage.expected @@ -1,5 +1,8 @@ edges | password_in_cookie.py:7:16:7:43 | a password | password_in_cookie.py:9:33:9:40 | a password | +| password_in_cookie.py:7:16:7:43 | a password | password_in_cookie.py:9:33:9:40 | a password | +| test.py:7:16:7:29 | a password | test.py:8:35:8:42 | a password | +| test.py:20:12:20:21 | a certificate or key | test.py:22:20:22:23 | a certificate or key | | test.py:20:12:20:21 | a certificate or key | test.py:22:20:22:23 | a certificate or key | #select | password_in_cookie.py:9:33:9:40 | password | password_in_cookie.py:7:16:7:43 | a password | password_in_cookie.py:9:33:9:40 | a password | Sensitive data from $@ is stored here. | password_in_cookie.py:7:16:7:43 | Attribute() | a request parameter containing a password | diff --git a/python/ql/test/query-tests/Security/CWE-327/TestNode.expected b/python/ql/test/query-tests/Security/CWE-327/TestNode.expected index f49293eddec..c79f7a9d195 100644 --- a/python/ql/test/query-tests/Security/CWE-327/TestNode.expected +++ b/python/ql/test/query-tests/Security/CWE-327/TestNode.expected @@ -5,3 +5,8 @@ | Taint cryptography.encryptor.RC4 | test_cryptography.py:7:17:7:34 | test_cryptography.py:7 | test_cryptography.py:7:17:7:34 | Attribute() | | | Taint cryptography.encryptor.RC4 | test_cryptography.py:8:12:8:20 | test_cryptography.py:8 | test_cryptography.py:8:12:8:20 | encryptor | | | Taint cryptography.encryptor.RC4 | test_cryptography.py:8:42:8:50 | test_cryptography.py:8 | test_cryptography.py:8:42:8:50 | encryptor | | +| Taint sensitive.data.password | test_cryptography.py:5:17:5:30 | test_cryptography.py:5 | test_cryptography.py:5:17:5:30 | get_password() | | +| Taint sensitive.data.password | test_cryptography.py:8:29:8:37 | test_cryptography.py:8 | test_cryptography.py:8:29:8:37 | dangerous | | +| Taint sensitive.data.password | test_cryptography.py:8:42:8:50 | test_cryptography.py:8 | test_cryptography.py:8:42:8:50 | encryptor | | +| Taint sensitive.data.password | test_pycrypto.py:5:17:5:30 | test_pycrypto.py:5 | test_pycrypto.py:5:17:5:30 | get_password() | | +| Taint sensitive.data.password | test_pycrypto.py:7:27:7:35 | test_pycrypto.py:7 | test_pycrypto.py:7:27:7:35 | dangerous | | diff --git a/python/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected b/python/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected index af91773ca1d..29618f5dd68 100644 --- a/python/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected +++ b/python/ql/test/query-tests/Security/CWE-502/UnsafeDeserialization.expected @@ -1,8 +1,13 @@ edges | test.py:11:15:11:26 | dict of externally controlled string | test.py:11:15:11:41 | externally controlled string | +| test.py:11:15:11:26 | dict of externally controlled string | test.py:11:15:11:41 | externally controlled string | +| test.py:11:15:11:41 | externally controlled string | test.py:12:18:12:24 | externally controlled string | | test.py:11:15:11:41 | externally controlled string | test.py:12:18:12:24 | externally controlled string | | test.py:11:15:11:41 | externally controlled string | test.py:13:15:13:21 | externally controlled string | +| test.py:11:15:11:41 | externally controlled string | test.py:13:15:13:21 | externally controlled string | | test.py:11:15:11:41 | externally controlled string | test.py:14:19:14:25 | externally controlled string | +| test.py:11:15:11:41 | externally controlled string | test.py:14:19:14:25 | externally controlled string | +| test.py:11:15:11:41 | externally controlled string | test.py:16:16:16:22 | externally controlled string | | test.py:11:15:11:41 | externally controlled string | test.py:16:16:16:22 | externally controlled string | #select | test.py:12:18:12:24 | payload | test.py:11:15:11:26 | dict of externally controlled string | test.py:12:18:12:24 | externally controlled string | Deserializing of $@. | test.py:11:15:11:26 | Attribute | untrusted input | diff --git a/python/ql/test/query-tests/Security/CWE-601/UrlRedirect.expected b/python/ql/test/query-tests/Security/CWE-601/UrlRedirect.expected index 94f878414da..b9deb72bd40 100644 --- a/python/ql/test/query-tests/Security/CWE-601/UrlRedirect.expected +++ b/python/ql/test/query-tests/Security/CWE-601/UrlRedirect.expected @@ -1,5 +1,7 @@ edges | test.py:7:22:7:33 | dict of externally controlled string | test.py:7:22:7:51 | externally controlled string | +| test.py:7:22:7:33 | dict of externally controlled string | test.py:7:22:7:51 | externally controlled string | +| test.py:7:22:7:51 | externally controlled string | test.py:8:21:8:26 | externally controlled string | | test.py:7:22:7:51 | externally controlled string | test.py:8:21:8:26 | externally controlled string | #select | test.py:8:21:8:26 | target | test.py:7:22:7:33 | dict of externally controlled string | test.py:8:21:8:26 | externally controlled string | Untrusted URL redirection due to $@. | test.py:7:22:7:33 | Attribute | a user-provided value | diff --git a/python/ql/test/query-tests/Security/lib/django/conf/urls.py b/python/ql/test/query-tests/Security/lib/django/conf/urls.py index cf65525e893..6c1a83baf0b 100644 --- a/python/ql/test/query-tests/Security/lib/django/conf/urls.py +++ b/python/ql/test/query-tests/Security/lib/django/conf/urls.py @@ -1,7 +1,6 @@ - -def url(pattern, *args): +# https://docs.djangoproject.com/en/1.11/_modules/django/conf/urls/#url +def url(regex, view, kwargs=None, name=None): pass def patterns(*urls): pass - diff --git a/python/ql/test/query-tests/Security/lib/django/views/__init__.py b/python/ql/test/query-tests/Security/lib/django/views/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/python/ql/test/query-tests/Security/lib/django/views/generic.py b/python/ql/test/query-tests/Security/lib/django/views/generic.py new file mode 100644 index 00000000000..d924b03d062 --- /dev/null +++ b/python/ql/test/query-tests/Security/lib/django/views/generic.py @@ -0,0 +1,2 @@ +class View: + pass diff --git a/python/ql/test/query-tests/Statements/unreachable/test.py b/python/ql/test/query-tests/Statements/unreachable/test.py index b1b69942de9..493dcc24dd1 100755 --- a/python/ql/test/query-tests/Statements/unreachable/test.py +++ b/python/ql/test/query-tests/Statements/unreachable/test.py @@ -120,3 +120,20 @@ def foo(x): print(x, "== 0") +# Unreachable catch-all case + +def unreachable_catch_all_assert_false(x): + if x < 0: + return "negative" + elif x >= 0: + return "positive" + else: + assert False, x + +def unreachable_catch_all_raise(x): + if x < 0: + pass + elif x >= 0: + pass + else: + raise ValueError(x) diff --git a/python/upgrades/qlpack.yml b/python/upgrades/qlpack.yml new file mode 100644 index 00000000000..9939911eb99 --- /dev/null +++ b/python/upgrades/qlpack.yml @@ -0,0 +1,2 @@ +name: codeql-python-upgrades +upgrades: .