Merge branch 'master' into python-improve-file-taint

This commit is contained in:
Rasmus Wriedt Larsen
2020-04-30 11:24:29 +02:00
274 changed files with 8969 additions and 1057 deletions

1
.gitignore vendored
View File

@@ -21,4 +21,3 @@
/codeql/
csharp/extractor/Semmle.Extraction.CSharp.Driver/Properties/launchSettings.json
.vscode

1
.vscode/.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
*.json linguist-language=JSON-with-Comments

10
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,10 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations.
// Extension identifier format: ${publisher}.${name}. Example: vscode.csharp
// List of extensions which should be recommended for users of this workspace.
"recommendations": [
"github.vscode-codeql"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": []
}

27
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,27 @@
{
// To run a task, select the `Terminal | Run Task...` menu option, and then select the task from
// the list in the dropdown, or invoke the `Tasks: Run Task` command from the command palette/
// To bind a keyboard shortcut to invoke a task, see https://code.visualstudio.com/docs/editor/tasks#_binding-keyboard-shortcuts-to-tasks.
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Sync Identical Files",
"type": "process",
// Non-Windows OS will usually have Python 3 already installed at /usr/bin/python3.
"command": "python3",
"args": [
"config/sync-files.py",
"--latest"
],
"group": "build",
"windows": {
// On Windows, use whatever Python interpreter is configured for this workspace. The default is
// just `python`, so if Python is already on the path, this will find it.
"command": "${config:python.pythonPath}",
},
"problemMatcher": []
}
]
}

View File

@@ -1,39 +1,126 @@
# Code of Conduct
## Our Pledge
This code of conduct outlines expectations for participation in the Semmle open source community, including any open source repositories on GitHub.com, as well as steps for reporting unacceptable behavior. We are committed to providing a welcoming and inspiring community for all.
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
People violating this code of conduct may be banned from the community.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
Our community strives to:
* Be friendly and patient: Remember you might not be communicating in someone elses primary spoken or programming language, and others may not have your level of understanding.
* Be welcoming: Our community welcomes and supports people of all backgrounds and identities. This includes, but is not limited to members of any race, ethnicity, culture, national origin, color, immigration status, social and economic class, educational level, sex, sexual orientation, gender identity and expression, age, size, family status, political belief, religion, and mental and physical ability.
* Be respectful: We are a world-wide community of professionals, and we conduct ourselves professionally. Disagreement is no excuse for poor behavior and poor manners. Disrespectful and unacceptable behavior includes, but is not limited to:
* Violent threats or language.
* Discriminatory or derogatory jokes and language.
* Posting sexually explicit or violent material.
* Posting, or threatening to post, peoples personally identifying information (“doxing”).
* Insults, especially those using discriminatory terms or slurs.
* Behavior that could be perceived as sexual attention.
* Advocating for or encouraging any of the above behaviors.
* Understand disagreements: Disagreements, both social and technical, are useful learning opportunities. Seek to understand others viewpoints and resolve differences constructively.
## Our Standards
This code is not exhaustive or complete. It serves to capture our common understanding of a productive, collaborative environment. We expect the code to be followed in spirit as much as in the letter.
Examples of behavior that contributes to a positive environment for our
community include:
# Scope
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
This code of conduct applies to all repositories and communities for Semmle open source projects, regardless of whether or not the repository explicitly calls out its use of this code. The code also applies in public spaces when an individual is representing the Semmle open source community. Examples include using an official project email address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
# Reporting Code of Conduct Issues
We encourage members of the community to resolve issues on their own whenever possible. This builds a broader and deeper understanding and ultimately a healthier interaction. In the event that an issue cannot be resolved locally, please feel free to report your concerns by contacting code-of-conduct@semmle.com.
In your report please include:
* Your contact information.
* Names (real, usernames or pseudonyms) of any individuals involved. If there are additional witnesses, please include them as well.
* Your account of what occurred, and if you believe the incident is ongoing. If there is a publicly available record (e.g. a mailing list archive or a public chat log), please include a link or attachment.
* Any additional information that may be helpful.
## Enforcement Responsibilities
All reports will be reviewed by a multi-person team and will result in a response that is deemed necessary and appropriate to the circumstances. Where additional perspectives are needed, the team may seek insight from others with relevant expertise or experience. The confidentiality of the person reporting the incident will be kept at all times. Involved parties are never part of the review team.
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Anyone asked to stop unacceptable behavior is expected to comply immediately. If an individual engages in unacceptable behavior, the review team may take any action they deem appropriate, including a permanent ban from the community.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
*This text is licensed under the [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/) license. It is based on a template established by the [TODO Group](http://todogroup.org/) and variants thereof used by numerous other large communities (e.g., [Microsoft](https://microsoft.github.io/codeofconduct/), [Facebook](https://code.fb.com/codeofconduct/), [Yahoo](https://yahoo.github.io/codeofconduct), [Twitter](https://github.com/twitter/code-of-conduct), [GitHub](https://blog.github.com/2015-07-20-adopting-the-open-code-of-conduct/)) and the Scope section from the [Contributor Covenant version 1.4](http://contributor-covenant.org/version/1/4/).*
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
opensource@github.com.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

View File

@@ -20,7 +20,7 @@ If you have an idea for a query that you would like to share with other CodeQL u
* Python: `python/ql/src`
Each language-specific directory contains further subdirectories that group queries based on their `@tags` or purpose.
- Experimental queries and libraries are stored in the `experimental` subdirectory within each language-specific directory in the [CodeQL repository](https://github.com/Semmle/ql). For example, experimental Java queries and libraries are stored in `java/ql/src/experimental` and any corresponding tests in `java/ql/test/experimental`.
- Experimental queries and libraries are stored in the `experimental` subdirectory within each language-specific directory in the [CodeQL repository](https://github.com/github/codeql). For example, experimental Java queries and libraries are stored in `java/ql/src/experimental` and any corresponding tests in `java/ql/test/experimental`.
- The structure of an `experimental` subdirectory mirrors the structure of its parent directory.
- Select or create an appropriate directory in `experimental` based on the existing directory structure of `experimental` or its parent directory.
@@ -36,7 +36,7 @@ If you have an idea for a query that you would like to share with other CodeQL u
3. **Formatting**
- The queries and libraries must be [autoformatted](https://help.semmle.com/codeql/codeql-for-vscode/reference/editor.html#autoformatting).
- The queries and libraries must be autoformatted, for example using the "Format Document" command in [CodeQL for Visual Studio Code](https://help.semmle.com/codeql/codeql-for-vscode/procedures/about-codeql-for-vscode.html).
4. **Compilation**

View File

@@ -9,8 +9,20 @@ You can use the [interactive query console](https://lgtm.com/help/lgtm/using-que
## 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 code 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/github/codeql/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 code in this repository is licensed under the [MIT License](LICENSE) by [GitHub](https://github.com).
## Visual Studio Code integration
If you use Visual Studio Code to work in this repository, there are a few integration features to make development easier.
### CodeQL for Visual Studio Code
You can install the [CodeQL for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-codeql) extension to get syntax highlighting, IntelliSense, and code navigation for the QL language, as well as unit test support for testing CodeQL libraries and queries.
### Tasks
The `.vscode/tasks.json` file defines custom tasks specific to working in this repository. To invoke one of these tasks, select the `Terminal | Run Task...` menu option, and then select the desired task from the dropdown. You can also invoke the `Tasks: Run Task` command from the command palette.

View File

@@ -4,6 +4,8 @@ The following changes in version 1.24 affect C/C++ analysis in all applications.
## General improvements
You can now suppress alerts using either single-line block comments (`/* ... */`) or line comments (`// ...`).
## New queries
| **Query** | **Tags** | **Purpose** |
@@ -12,32 +14,60 @@ The following changes in version 1.24 affect C/C++ analysis in all applications.
## Changes to existing queries
A new taint-tracking library is used by all the security queries that track tainted values
(`cpp/path-injection`, `cpp/cgi-xss`, `cpp/sql-injection`, `cpp/uncontrolled-process-operation`,
`cpp/unbounded-write`, `cpp/tainted-format-string`, `cpp/tainted-format-string-through-global`,
`cpp/uncontrolled-arithmetic`, `cpp/uncontrolled-allocation-size`, `cpp/user-controlled-bypass`,
`cpp/cleartext-storage-buffer`, `cpp/tainted-permissions-check`).
These queries now have more precise results and also offer _path explanations_ so you can explore the results easily.
There is a performance cost to this, and the LGTM query suite will overall run slower than before.
| **Query** | **Expected impact** | **Change** |
|----------------------------|------------------------|------------------------------------------------------------------|
| Boost\_asio TLS Settings Misconfiguration (`cpp/boost/tls-settings-misconfiguration`) | Query id change | The identifier was updated to use dashes in place of underscores (previous identifier `cpp/boost/tls_settings_misconfiguration`). |
| Buffer not sufficient for string (`cpp/overflow-calculated`) | More true positive results | This query now identifies a wider variety of buffer allocations using the `semmle.code.cpp.models.interfaces.Allocation` library. |
| No space for zero terminator (`cpp/no-space-for-terminator`) | More true positive results | This query now identifies a wider variety of buffer allocations using the `semmle.code.cpp.models.interfaces.Allocation` library. |
| Hard-coded Japanese era start date (`cpp/japanese-era/exact-era-date`) | | This query is no longer run on LGTM. |
| Memory is never freed (`cpp/memory-never-freed`) | More true positive results | This query now identifies a wider variety of buffer allocations using the `semmle.code.cpp.models.interfaces.Allocation` library. |
| Memory may not be freed (`cpp/memory-may-not-be-freed`) | More true positive results | This query now identifies a wider variety of buffer allocations using the `semmle.code.cpp.models.interfaces.Allocation` library. |
| Mismatching new/free or malloc/delete (`cpp/new-free-mismatch`) | Fewer false positive results | Fixed false positive results in template code. |
| Missing return statement (`cpp/missing-return`) | Fewer false positive results | Functions containing `asm` statements are no longer highlighted by this query. |
| Missing return statement (`cpp/missing-return`) | More accurate locations | Locations reported by this query are now more accurate in some cases. |
| No space for zero terminator (`cpp/no-space-for-terminator`) | More correct results | String arguments to formatting functions are now (usually) expected to be null terminated strings. |
| Hard-coded Japanese era start date (`cpp/japanese-era/exact-era-date`) | | This query is no longer run on LGTM. |
| No space for zero terminator (`cpp/no-space-for-terminator`) | Fewer false positive results | This query has been modified to be more conservative when identifying which pointers point to null-terminated strings. This approach produces fewer, more accurate results. |
| Overflow in uncontrolled allocation size (`cpp/uncontrolled-allocation-size`) | Fewer false positive results | Cases where the tainted allocation size is range checked are now more reliably excluded. |
| Overflow in uncontrolled allocation size (`cpp/uncontrolled-allocation-size`) | Fewer false positive results | The query now produces fewer, more accurate results. |
| Mismatching new/free or malloc/delete (`cpp/new-free-mismatch`) | Fewer false positive results | Improved handling of template code gives greater precision. |
| Missing return statement (`cpp/missing-return`) | Fewer false positive results and more accurate locations | Functions containing `asm` statements are no longer highlighted by this query. The locations reported by this query are now more accurate in some cases. |
| No space for zero terminator (`cpp/no-space-for-terminator`) | More results with greater precision | The query gives more precise results for a wider variety of buffer allocations. String arguments to formatting functions are now (usually) expected to be null terminated strings. Use of the `semmle.code.cpp.models.interfaces.Allocation` library identifies problems with a wider variety of buffer allocations. This query is also more conservative when identifying which pointers point to null-terminated strings. |
| Overflow in uncontrolled allocation size (`cpp/uncontrolled-allocation-size`) | Fewer false positive results | The query now produces fewer, more accurate results. Cases where the tainted allocation size is range checked are more reliably excluded. |
| Overloaded assignment does not return 'this' (`cpp/assignment-does-not-return-this`) | Fewer false positive results | This query no longer reports incorrect results in template classes. |
| Pointer overflow check (`cpp/pointer-overflow-check`),<br> Possibly wrong buffer size in string copy (`cpp/bad-strncpy-size`),<br> Signed overflow check (`cpp/signed-overflow-check`) | More correct results | A new library is used for determining which expressions have identical value, giving more precise results. There is a performance cost to this, and the LGTM suite will overall run slower than before. |
| Unsafe array for days of the year (`cpp/leap-year/unsafe-array-for-days-of-the-year`) | | This query is no longer run on LGTM. |
| Unsigned comparison to zero (`cpp/unsigned-comparison-zero`) | More correct results | This query now also looks for comparisons of the form `0 <= x`. |
## Changes to libraries
* The data-flow library has been improved, which affects and improves some security queries. The improvements are:
* The built-in C++20 "spaceship operator" (`<=>`) is now supported via the QL
class `SpaceshipExpr`. Overloaded forms are modeled as calls to functions
named `operator<=>`.
* The data-flow library (`semmle.code.cpp.dataflow.DataFlow` and
`semmle.code.cpp.dataflow.TaintTracking`) has been improved, which affects
and improves some security queries. The improvements are:
- Track flow through functions that combine taint tracking with flow through fields.
- Track flow through clone-like functions, that is, functions that read contents of a field from a
parameter and stores the value in the field of a returned object.
* Created the `semmle.code.cpp.models.interfaces.Allocation` library to model allocation such as `new` expressions and calls to `malloc`. This in intended to replace the functionality in `semmle.code.cpp.commons.Alloc` with a more consistent and useful interface.
* Created the `semmle.code.cpp.models.interfaces.Deallocation` library to model deallocation such as `delete` expressions and calls to `free`. This in intended to replace the functionality in `semmle.code.cpp.commons.Alloc` with a more consistent and useful interface.
* The security pack taint tracking library
(`semmle.code.cpp.security.TaintTracking`) uses a new intermediate
representation. This provides a more precise analysis of flow through
parameters and pointers. For new queries, however, we continue to recommend
using `semmle.code.cpp.dataflow.TaintTracking`.
* The global value numbering library
(`semmle.code.cpp.valuenumbering.GlobalValueNumbering`) uses a new
intermediate representation to provide a more precise analysis of
heap-allocated memory and pointers to stack variables.
* New libraries have been created to provide a more consistent and useful interface
for modeling allocation and deallocation. These replace the old
`semmle.code.cpp.commons.Alloc` library.
* The new `semmle.code.cpp.models.interfaces.Allocation` library models
allocations, such as `new` expressions and calls to `malloc`.
* The new `semmle.code.cpp.models.interfaces.Deallocation` library
models deallocations, such as `delete` expressions and calls to `free`.
* The predicate `freeCall` in `semmle.code.cpp.commons.Alloc` has been
deprecated. The `Allocation` and `Deallocation` models in
`semmle.code.cpp.models.interfaces` should be used instead.
* The new class `StackVariable` should be used in place of `LocalScopeVariable`
in most cases. The difference is that `StackVariable` does not include
variables declared with `static` or `thread_local`.
@@ -46,13 +76,9 @@ The following changes in version 1.24 affect C/C++ analysis in all applications.
about the _name or scope_ of variables should remain unchanged.
* The `LocalScopeVariableReachability` library is deprecated in favor of
`StackVariableReachability`. The functionality is the same.
* The models library models `strlen` in more detail, and includes common variations such as `wcslen`.
* The models library models `gets` and similar functions.
* The models library now partially models `std::string`.
* The taint tracking library (`semmle.code.cpp.dataflow.TaintTracking`) has had
the following improvements:
* The library now models data flow through `strdup` and similar functions.
* The library now models data flow through formatting functions such as `sprintf`.
* The security pack taint tracking library (`semmle.code.cpp.security.TaintTracking`) uses a new intermediate representation. This provides a more precise analysis of pointers to stack variables and flow through parameters, improving the results of many security queries.
* The global value numbering library (`semmle.code.cpp.valuenumbering.GlobalValueNumbering`) uses a new intermediate representation to provide a more precise analysis of heap allocated memory and pointers to stack variables.
* `freeCall` in `semmle.code.cpp.commons.Alloc` has been deprecated. The`Allocation` and `Deallocation` models in `semmle.code.cpp.models.interfaces` should be used instead.
* Taint tracking and data flow now features better modeling of commonly-used
library functions:
* `gets` and similar functions,
* the most common operations on `std::string`,
* `strdup` and similar functions, and
* formatting functions such as `sprintf`.

View File

@@ -2,30 +2,31 @@
The following changes in version 1.24 affect C# analysis in all applications.
## General improvements
You can now suppress alerts using either single-line block comments (`/* ... */`) or line comments (`// ...`).
## New queries
| **Query** | **Tags** | **Purpose** |
|-----------------------------|-----------|--------------------------------------------------------------------|
| Assembly path injection (`cs/assembly-path-injection`) | security, external/cwe/cwe-114 | Finds user-controlled data used to load an assembly. |
| Insecure configuration for ASP.NET requestValidationMode (`cs/insecure-request-validation-mode`) | security, external/cwe/cwe-016 | Finds where this attribute has been set to a value less than 4.5, which turns off some validation features and makes the application less secure. |
| Insecure SQL connection (`cs/insecure-sql-connection`) | security, external/cwe/cwe-327 | Finds unencrypted SQL connection strings. |
| Page request validation is disabled (`cs/web/request-validation-disabled`) | security, frameworks/asp.net, external/cwe/cwe-016 | Finds where ASP.NET page request validation has been disabled, which could make the application less secure. |
| Serialization check bypass (`cs/serialization-check-bypass`) | security, external/cwe/cwe-20 | Finds where data is not validated in a deserialization method. |
| XML injection (`cs/xml-injection`) | security, external/cwe/cwe-091 | Finds user-controlled data that is used to write directly to an XML document. |
| Assembly path injection (`cs/assembly-path-injection`) | security, external/cwe/cwe-114 | Finds user-controlled data used to load an assembly. Results are shown on LGTM by default. |
| Insecure configuration for ASP.NET requestValidationMode (`cs/insecure-request-validation-mode`) | security, external/cwe/cwe-016 | Finds where this attribute has been set to a value less than 4.5, which turns off some validation features and makes the application less secure. By default, the query is not run on LGTM. |
| Insecure SQL connection (`cs/insecure-sql-connection`) | security, external/cwe/cwe-327 | Finds unencrypted SQL connection strings. Results are not shown on LGTM by default. |
| Page request validation is disabled (`cs/web/request-validation-disabled`) | security, frameworks/asp.net, external/cwe/cwe-016 | Finds where ASP.NET page request validation has been disabled, which could make the application less secure. By default, the query is not run on LGTM. |
| Serialization check bypass (`cs/serialization-check-bypass`) | security, external/cwe/cwe-20 | Finds where data is not validated in a deserialization method. Results are not shown on LGTM by default. |
| XML injection (`cs/xml-injection`) | security, external/cwe/cwe-091 | Finds user-controlled data that is used to write directly to an XML document. Results are shown on LGTM by default. |
## Changes to existing queries
| **Query** | **Expected impact** | **Change** |
|------------------------------|------------------------|-----------------------------------|
| Useless assignment to local variable (`cs/useless-assignment-to-local`) | Fewer false positive results | Results have been removed when the variable is named `_` in a `foreach` statement. |
| Potentially dangerous use of non-short-circuit logic (`cs/non-short-circuit`) | Fewer false positive results | Results have been removed when the expression contains an `out` parameter. |
| Dereferenced variable may be null (`cs/dereferenced-value-may-be-null`) | More results | Results are reported from parameters with a default value of `null`. |
| Useless assignment to local variable (`cs/useless-assignment-to-local`) | Fewer false positive results | Results have been removed when the value assigned is an (implicitly or explicitly) cast default-like value. For example, `var s = (string)null` and `string s = default`. |
| XPath injection (`cs/xml/xpath-injection`) | More results | The query now recognizes calls to methods on `System.Xml.XPath.XPathNavigator` objects. |
| Information exposure through transmitted data (`cs/sensitive-data-transmission`) | More results | The query now recognizes writes to cookies and writes to ASP.NET (`Inner`)`Text` properties as additional sinks. |
| Information exposure through an exception (`cs/information-exposure-through-exception`) | More results | The query now recognizes writes to cookies, writes to ASP.NET (`Inner`)`Text` properties, and email contents as additional sinks. |
## Removal of old queries
| Information exposure through transmitted data (`cs/sensitive-data-transmission`) | More results | The query now recognizes writes to cookies and writes to ASP.NET (`Inner`)`Text` properties as additional sinks. |
| Potentially dangerous use of non-short-circuit logic (`cs/non-short-circuit`) | Fewer false positive results | Results have been removed when the expression contains an `out` parameter. |
| Useless assignment to local variable (`cs/useless-assignment-to-local`) | Fewer false positive results | Results have been removed when the value assigned is an (implicitly or explicitly) cast default-like value. For example, `var s = (string)null` and `string s = default`. Results have also been removed when the variable is named `_` in a `foreach` statement. |
| XPath injection (`cs/xml/xpath-injection`) | More results | The query now recognizes calls to methods on `System.Xml.XPath.XPathNavigator` objects. |
## Changes to code extraction
@@ -38,12 +39,10 @@ The following changes in version 1.24 affect C# analysis in all applications.
* The data-flow library has been improved, which affects and improves most security queries. The improvements are:
- Track flow through methods that combine taint tracking with flow through fields.
- Track flow through clone-like methods, that is, methods that read contents of a field from a
parameter and stores the value in the field of a returned object.
- Track flow through clone-like methods, that is, methods that read the contents of a field from a
parameter and store the value in the field of a returned object.
* The taint tracking library now tracks flow through (implicit or explicit) conversion operator calls.
* [Code contracts](https://docs.microsoft.com/en-us/dotnet/framework/debug-trace-profile/code-contracts) are now recognized, and are treated like any other assertion methods.
* Expression nullability flow state is given by the predicates `Expr.hasNotNullFlowState()` and `Expr.hasMaybeNullFlowState()`.
* `stackalloc` array creations are now represented by the QL class `Stackalloc`. Previously they were represented by the class `ArrayCreation`.
* A new class `RemoteFlowSink` has been added to model sinks where data might be exposed to external users. Examples include web page output, e-mails, and cookies.
## Changes to autobuilder
* A new class `RemoteFlowSink` has been added to model sinks where data might be exposed to external users. Examples include web page output, emails, and cookies.

View File

@@ -4,7 +4,7 @@ The following changes in version 1.24 affect Java analysis in all applications.
## General improvements
* Alert suppression can now be done with single-line block comments (`/* ... */`) as well as line comments (`// ...`).
* You can now suppress alerts using either single-line block comments (`/* ... */`) or line comments (`// ...`).
* A `Customizations.qll` file has been added to allow customizations of the standard library that apply to all queries.
## New queries
@@ -21,9 +21,9 @@ The following changes in version 1.24 affect Java analysis in all applications.
| **Query** | **Expected impact** | **Change** |
|------------------------------|------------------------|-----------------------------------|
| Dereferenced variable may be null (`java/dereferenced-value-may-be-null`) | Fewer false positives | Final fields with a non-null initializer are no longer reported. |
| Expression always evaluates to the same value (`java/evaluation-to-constant`) | Fewer false positives | Expressions of the form `0 * x` are usually intended and no longer reported. Also left shift of ints by 32 bits and longs by 64 bits are no longer reported as they are not constant, these results are instead reported by the new query `java/lshift-larger-than-type-width`. |
| Useless null check (`java/useless-null-check`) | More true positives | Useless checks on final fields with a non-null initializer are now reported. |
| Dereferenced variable may be null (`java/dereferenced-value-may-be-null`) | Fewer false positive results | Final fields with a non-null initializer are no longer reported. |
| Expression always evaluates to the same value (`java/evaluation-to-constant`) | Fewer false positive results | Expressions of the form `0 * x` are usually intended and no longer reported. Also left shift of ints by 32 bits and longs by 64 bits are no longer reported as they are not constant, these results are instead reported by the new query `java/lshift-larger-than-type-width`. |
| Useless null check (`java/useless-null-check`) | More true positive results | Useless checks on final fields with a non-null initializer are now reported. |
## Changes to libraries
@@ -38,6 +38,6 @@ The following changes in version 1.24 affect Java analysis in all applications.
general file classification mechanism and thus suppression of alerts, and
also any security queries using taint tracking, as test classes act as
default barriers stopping taint flow.
* Parentheses are now no longer modelled directly in the AST, that is, the
* Parentheses are now no longer modeled directly in the AST, that is, the
`ParExpr` class is empty. Instead, a parenthesized expression can be
identified with the `Expr.isParenthesized()` member predicate.

View File

@@ -4,7 +4,7 @@
* TypeScript 3.8 is now supported.
* Alert suppression can now be done with single-line block comments (`/* ... */`) as well as line comments (`// ...`).
* You can now suppress alerts using either single-line block comments (`/* ... */`) or line comments (`// ...`).
* Resolution of imports has improved, leading to more results from the security queries:
- Imports with the `.js` extension can now be resolved to a TypeScript file,
@@ -24,22 +24,20 @@
* Support for flow summaries has been more clearly marked as being experimental and moved to the new `experimental` folder.
* Support for the following frameworks and libraries has been improved:
- [Electron](https://electronjs.org/)
- [fstream](https://www.npmjs.com/package/fstream)
- [Handlebars](https://www.npmjs.com/package/handlebars)
- [jsonfile](https://www.npmjs.com/package/jsonfile)
- [Koa](https://www.npmjs.com/package/koa)
- [Node.js](https://nodejs.org/)
- [Socket.IO](https://socket.io/)
- [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)
- [chrome-remote-interface](https://www.npmjs.com/package/chrome-remote-interface)
- [Electron](https://electronjs.org/)
- [for-in](https://www.npmjs.com/package/for-in)
- [for-own](https://www.npmjs.com/package/for-own)
- [fstream](https://www.npmjs.com/package/fstream)
- [Handlebars](https://www.npmjs.com/package/handlebars)
- [http2](https://nodejs.org/api/http2.html)
- [jQuery](https://jquery.com/)
- [jsonfile](https://www.npmjs.com/package/jsonfile)
- [Koa](https://www.npmjs.com/package/koa)
- [lazy-cache](https://www.npmjs.com/package/lazy-cache)
- [mongodb](https://www.npmjs.com/package/mongodb)
- [ncp](https://www.npmjs.com/package/ncp)
- [Node.js](https://nodejs.org/)
- [node-dir](https://www.npmjs.com/package/node-dir)
- [path-exists](https://www.npmjs.com/package/path-exists)
- [pg](https://www.npmjs.com/package/pg)
@@ -48,23 +46,26 @@
- [request](https://www.npmjs.com/package/request)
- [rimraf](https://www.npmjs.com/package/rimraf)
- [send](https://www.npmjs.com/package/send)
- [Socket.IO](https://socket.io/)
- [SockJS](https://www.npmjs.com/package/sockjs)
- [SockJS-client](https://www.npmjs.com/package/sockjs-client)
- [typeahead.js](https://www.npmjs.com/package/typeahead.js)
- [vinyl-fs](https://www.npmjs.com/package/vinyl-fs)
- [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)
- [write-file-atomic](https://www.npmjs.com/package/write-file-atomic)
- [ws](https://github.com/websockets/ws)
## New queries
| **Query** | **Tags** | **Purpose** |
|---------------------------------------------------------------------------------|-------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Cross-site scripting through exception (`js/xss-through-exception`) | security, external/cwe/cwe-079, external/cwe/cwe-116 | Highlights potential XSS vulnerabilities where an exception is written to the DOM. Results are not shown on LGTM by default. |
| Regular expression always matches (`js/regex/always-matches`) | correctness, regular-expressions | Highlights regular expression checks that trivially succeed by matching an empty substring. Results are shown on LGTM by default. |
| Missing await (`js/missing-await`) | correctness | Highlights expressions that operate directly on a promise object in a nonsensical way, instead of awaiting its result. Results are shown on LGTM by default. |
| Polynomial regular expression used on uncontrolled data (`js/polynomial-redos`) | security, external/cwe/cwe-730, external/cwe/cwe-400 | Highlights expensive regular expressions that may be used on malicious input. Results are shown on LGTM by default. |
| Prototype pollution in utility function (`js/prototype-pollution-utility`) | security, external/cwe/cwe-400, external/cwe/cwe-471 | Highlights recursive assignment operations that are susceptible to prototype pollution. Results are shown on LGTM by default. |
| Unsafe jQuery plugin (`js/unsafe-jquery-plugin`) | Highlights potential XSS vulnerabilities in unsafely designed jQuery plugins. Results are shown on LGTM by default. |
| Regular expression always matches (`js/regex/always-matches`) | correctness, regular-expressions | Highlights regular expression checks that trivially succeed by matching an empty substring. Results are shown on LGTM by default. |
| Unsafe jQuery plugin (`js/unsafe-jquery-plugin`) | | Highlights potential XSS vulnerabilities in unsafely designed jQuery plugins. Results are shown on LGTM by default. |
| Unnecessary use of `cat` process (`js/unnecessary-use-of-cat`) | correctness, security, maintainability | Highlights command executions of `cat` where the fs API should be used instead. Results are shown on LGTM by default. |
@@ -73,20 +74,20 @@
| **Query** | **Expected impact** | **Change** |
|--------------------------------|------------------------------|---------------------------------------------------------------------------|
| Clear-text logging of sensitive information (`js/clear-text-logging`) | More results | More results involving `process.env` and indirect calls to logging methods are recognized. |
| Duplicate parameter names (`js/duplicate-parameter-name`) | Fewer results | This query now recognizes additional parameters that reasonably can have duplicated names. |
| Incomplete string escaping or encoding (`js/incomplete-sanitization`) | Fewer false positive results | This query now recognizes additional cases where a single replacement is likely to be intentional. |
| Unbound event handler receiver (`js/unbound-event-handler-receiver`) | Fewer false positive results | This query now recognizes additional ways event handler receivers can be bound. |
| Duplicate parameter names (`js/duplicate-parameter-name`) | Fewer results | This query now ignores additional parameters that reasonably can have duplicated names. |
| Expression has no effect (`js/useless-expression`) | Fewer false positive results | The query now recognizes block-level flow type annotations and ignores the first statement of a try block. |
| Use of call stack introspection in strict mode (`js/strict-mode-call-stack-introspection`) | Fewer false positive results | The query no longer flags expression statements. |
| Missing CSRF middleware (`js/missing-token-validation`) | Fewer false positive results | The query reports fewer duplicates and only flags handlers that explicitly access cookie data. |
| Uncontrolled data used in path expression (`js/path-injection`) | More results | This query now recognizes additional ways dangerous paths can be constructed and used. |
| Uncontrolled command line (`js/command-line-injection`) | More results | This query now recognizes additional ways of constructing arguments to `cmd.exe` and `/bin/sh`. |
| Syntax error (`js/syntax-error`) | Lower severity | This results of this query are now displayed with lower severity. |
| Use of password hash with insufficient computational effort (`js/insufficient-password-hash`) | Fewer false positive results | This query now recognizes additional cases that do not require secure hashing. |
| Useless regular-expression character escape (`js/useless-regexp-character-escape`) | Fewer false positive results | This query now distinguishes escapes in strings and regular expression literals. |
| Identical operands (`js/redundant-operation`) | Fewer results | This query now recognizes cases where the operands change a value using ++/-- expressions. |
| Superfluous trailing arguments (`js/superfluous-trailing-arguments`) | Fewer results | This query now recognizes cases where a function uses the `Function.arguments` value to process a variable number of parameters. |
| Identical operands (`js/redundant-operation`) | Fewer results | This query now excludes cases where the operands change a value using ++/-- expressions. |
| Incomplete string escaping or encoding (`js/incomplete-sanitization`) | Fewer false positive results | This query now recognizes and excludes additional cases where a single replacement is likely to be intentional. |
| Incomplete URL scheme check (`js/incomplete-url-scheme-check`) | More results | This query now recognizes additional variations of URL scheme checks. |
| Missing CSRF middleware (`js/missing-token-validation`) | Fewer false positive results | The query reports fewer duplicates and only flags handlers that explicitly access cookie data. |
| Superfluous trailing arguments (`js/superfluous-trailing-arguments`) | Fewer results | This query now excludes cases where a function uses the `Function.arguments` value to process a variable number of parameters. |
| Syntax error (`js/syntax-error`) | Lower severity | This results of this query are now displayed with lower severity. |
| Unbound event handler receiver (`js/unbound-event-handler-receiver`) | Fewer false positive results | This query now recognizes additional ways event handler receivers can be bound. |
| Uncontrolled command line (`js/command-line-injection`) | More results | This query now recognizes additional ways of constructing arguments to `cmd.exe` and `/bin/sh`. |
| Uncontrolled data used in path expression (`js/path-injection`) | More results | This query now recognizes additional ways dangerous paths can be constructed and used. |
| Use of call stack introspection in strict mode (`js/strict-mode-call-stack-introspection`) | Fewer false positive results | The query no longer flags expression statements. |
| Use of password hash with insufficient computational effort (`js/insufficient-password-hash`) | Fewer false positive results | This query now recognizes and excludes additional cases that do not require secure hashing. |
| Useless regular-expression character escape (`js/useless-regexp-character-escape`) | Fewer false positive results | This query now distinguishes between escapes in strings and regular expression literals. |
## Changes to libraries

View File

@@ -2,12 +2,16 @@
## General improvements
* Support for the following frameworks and libraries has been improved:
- [jGrowl](https://github.com/stanlemon/jGrowl)
- [jQuery](https://jquery.com/)
## New queries
| **Query** | **Tags** | **Purpose** |
|---------------------------------------------------------------------------------|-------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Cross-site scripting through DOM (`js/xss-through-dom`) | security, external/cwe/cwe-079, external/cwe/cwe-116 | Highlights potential XSS vulnerabilities where existing text from the DOM is used as HTML. Results are not shown on LGTM by default. |
| Incomplete HTML attribute sanitization (`js/incomplete-html-attribute-sanitization`) | security, external/cwe/cwe-20, external/cwe/cwe-079, external/cwe/cwe-116 | Highlights potential XSS vulnerabilities due to incomplete sanitization of HTML meta-characters. Results are shown on LGTM by default. |
## Changes to existing queries

View File

@@ -107,7 +107,7 @@ def choose_latest_file(files):
local_error_count = 0
def emit_local_error(path, line, error):
print('ERROR: ' + path + ':' + line + " - " + error)
print('ERROR: ' + path + ':' + str(line) + " - " + error)
global local_error_count
local_error_count += 1

View File

@@ -6,6 +6,7 @@
import cpp
pragma[inline]
private predicate arithTypesMatch(Type arg, Type parm) {
arg = parm
or

View File

@@ -28,5 +28,5 @@ where
// is probably a mistake.
addWithSizeof(e, sizeofExpr, _) and not isCharSzPtrExpr(e)
select sizeofExpr,
"Suspicious sizeof offset in a pointer arithmetic expression. " + "The type of the pointer is " +
e.getFullyConverted().getType().toString() + "."
"Suspicious sizeof offset in a pointer arithmetic expression. The type of the pointer is $@.",
e.getFullyConverted().getType() as t, t.toString()

View File

@@ -25,7 +25,7 @@ private import semmle.code.cpp.internal.QualifiedName as Q
* `DeclarationEntry`, because they always have a unique source location.
* `EnumConstant` and `FriendDecl` are both examples of this.
*/
abstract class Declaration extends Locatable, @declaration {
class Declaration extends Locatable, @declaration {
/**
* Gets the innermost namespace which contains this declaration.
*

View File

@@ -376,6 +376,8 @@ private predicate isIntegralType(@builtintype type, int kind) {
kind = 43
or
kind = 44
or
kind = 51
)
}
@@ -463,6 +465,8 @@ private predicate integralTypeMapping(int original, int canonical, int unsigned,
original = 43 and canonical = 43 and unsigned = -1 and signed = -1 // char16_t
or
original = 44 and canonical = 44 and unsigned = -1 and signed = -1 // char32_t
or
original = 51 and canonical = 51 and unsigned = -1 and signed = -1 // char8_t
}
/**
@@ -993,6 +997,18 @@ class WideCharType extends IntegralType {
override string getCanonicalQLClass() { result = "WideCharType" }
}
/**
* The C/C++ `char8_t` type. This is available starting with C++20.
* ```
* char8_t c8;
* ```
*/
class Char8Type extends IntegralType {
Char8Type() { builtintypes(underlyingElement(this), _, 51, _, _, _) }
override string getCanonicalQLClass() { result = "Char8Type" }
}
/**
* The C/C++ `char16_t` type. This is available starting with C11 and C++11.
* ```

View File

@@ -126,10 +126,7 @@ class Variable extends Declaration, @variable {
or
exists(AssignExpr ae | ae.getLValue().(Access).getTarget() = this and result = ae.getRValue())
or
exists(AggregateLiteral l |
this.getDeclaringType() = l.getType() and
result = l.getChild(this.(Field).getInitializationOrder())
)
exists(ClassAggregateLiteral l | result = l.getFieldExpr(this))
}
/**

View File

@@ -12,12 +12,12 @@ abstract class Assertion extends Locatable {
}
/**
* A libc assert, as defined in assert.h. A macro with the head
* "assert(expr)" that expands to a conditional expression which
* may terminate the program.
* A libc assert, as defined in assert.h. A macro with a head
* that matches the prefix "assert(", and expands to a conditional
* expression which may terminate the program.
*/
class LibcAssert extends MacroInvocation, Assertion {
LibcAssert() { this.getMacro().getHead() = "assert(expr)" }
LibcAssert() { this.getMacro().getHead().matches("assert(%") }
override Expr getAsserted() {
exists(ConditionalExpr ce | this.getAGeneratedElement() = ce | result = ce.getCondition())

View File

@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
* a callable is recorded by `cc`.
*/
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
exists(
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
LocalCallContext localCC
|
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
localCC = getLocalCallContext(cc, enclosing)
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
midnode = mid.getNode() and
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
ap = ap0
@@ -2331,20 +2332,6 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
pathThroughCallable(mid, node, cc, ap) and sc = mid.getSummaryCtx()
}
pragma[nomagic]
private predicate pathIntoLocalStep(
PathNodeMid mid, Node midnode, CallContext cc, DataFlowCallable enclosing, SummaryCtx sc,
AccessPath ap0, Configuration conf
) {
midnode = mid.getNode() and
cc = mid.getCallContext() and
conf = mid.getConfiguration() and
localFlowBigStep(midnode, _, _, _, conf, _) and
enclosing = midnode.getEnclosingCallable() and
sc = mid.getSummaryCtx() and
ap0 = mid.getAp()
}
pragma[nomagic]
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
readDirect(node1, f, node2) and

View File

@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
* a callable is recorded by `cc`.
*/
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
exists(
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
LocalCallContext localCC
|
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
localCC = getLocalCallContext(cc, enclosing)
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
midnode = mid.getNode() and
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
ap = ap0
@@ -2331,20 +2332,6 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
pathThroughCallable(mid, node, cc, ap) and sc = mid.getSummaryCtx()
}
pragma[nomagic]
private predicate pathIntoLocalStep(
PathNodeMid mid, Node midnode, CallContext cc, DataFlowCallable enclosing, SummaryCtx sc,
AccessPath ap0, Configuration conf
) {
midnode = mid.getNode() and
cc = mid.getCallContext() and
conf = mid.getConfiguration() and
localFlowBigStep(midnode, _, _, _, conf, _) and
enclosing = midnode.getEnclosingCallable() and
sc = mid.getSummaryCtx() and
ap0 = mid.getAp()
}
pragma[nomagic]
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
readDirect(node1, f, node2) and

View File

@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
* a callable is recorded by `cc`.
*/
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
exists(
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
LocalCallContext localCC
|
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
localCC = getLocalCallContext(cc, enclosing)
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
midnode = mid.getNode() and
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
ap = ap0
@@ -2331,20 +2332,6 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
pathThroughCallable(mid, node, cc, ap) and sc = mid.getSummaryCtx()
}
pragma[nomagic]
private predicate pathIntoLocalStep(
PathNodeMid mid, Node midnode, CallContext cc, DataFlowCallable enclosing, SummaryCtx sc,
AccessPath ap0, Configuration conf
) {
midnode = mid.getNode() and
cc = mid.getCallContext() and
conf = mid.getConfiguration() and
localFlowBigStep(midnode, _, _, _, conf, _) and
enclosing = midnode.getEnclosingCallable() and
sc = mid.getSummaryCtx() and
ap0 = mid.getAp()
}
pragma[nomagic]
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
readDirect(node1, f, node2) and

View File

@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
* a callable is recorded by `cc`.
*/
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
exists(
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
LocalCallContext localCC
|
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
localCC = getLocalCallContext(cc, enclosing)
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
midnode = mid.getNode() and
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
ap = ap0
@@ -2331,20 +2332,6 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
pathThroughCallable(mid, node, cc, ap) and sc = mid.getSummaryCtx()
}
pragma[nomagic]
private predicate pathIntoLocalStep(
PathNodeMid mid, Node midnode, CallContext cc, DataFlowCallable enclosing, SummaryCtx sc,
AccessPath ap0, Configuration conf
) {
midnode = mid.getNode() and
cc = mid.getCallContext() and
conf = mid.getConfiguration() and
localFlowBigStep(midnode, _, _, _, conf, _) and
enclosing = midnode.getEnclosingCallable() and
sc = mid.getSummaryCtx() and
ap0 = mid.getAp()
}
pragma[nomagic]
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
readDirect(node1, f, node2) and

View File

@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
* a callable is recorded by `cc`.
*/
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
exists(
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
LocalCallContext localCC
|
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
localCC = getLocalCallContext(cc, enclosing)
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
midnode = mid.getNode() and
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
ap = ap0
@@ -2331,20 +2332,6 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
pathThroughCallable(mid, node, cc, ap) and sc = mid.getSummaryCtx()
}
pragma[nomagic]
private predicate pathIntoLocalStep(
PathNodeMid mid, Node midnode, CallContext cc, DataFlowCallable enclosing, SummaryCtx sc,
AccessPath ap0, Configuration conf
) {
midnode = mid.getNode() and
cc = mid.getCallContext() and
conf = mid.getConfiguration() and
localFlowBigStep(midnode, _, _, _, conf, _) and
enclosing = midnode.getEnclosingCallable() and
sc = mid.getSummaryCtx() and
ap0 = mid.getAp()
}
pragma[nomagic]
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
readDirect(node1, f, node2) and

View File

@@ -43,7 +43,7 @@ class Node extends TNode {
/**
* INTERNAL: Do not use. Alternative name for `getFunction`.
*/
Function getEnclosingCallable() { result = this.getFunction() }
final Function getEnclosingCallable() { result = unique(Function f | f = this.getFunction() | f) }
/** Gets the type of this node. */
Type getType() { none() } // overridden in subclasses
@@ -299,7 +299,7 @@ private class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNo
override Node getPreUpdateNode() { result.asExpr() = pd.getDefinedExpr() }
override Location getLocation() { result = pd.getLocation() }
override Location getLocation() { result = pd.getActualLocation() }
PartialDefinition getPartialDefinition() { result = pd }

View File

@@ -113,44 +113,39 @@ class FlowVar extends TFlowVar {
* ```
*/
private module PartialDefinitions {
private newtype TPartialDefinition =
TExplicitFieldStoreQualifier(Expr qualifier, ControlFlowNode node) {
exists(FieldAccess fa | qualifier = fa.getQualifier() |
private predicate isInstanceFieldWrite(FieldAccess fa, ControlFlowNode node) {
assignmentLikeOperation(node, _, fa, _)
}
class PartialDefinition extends Expr {
ControlFlowNode node;
PartialDefinition() {
exists(FieldAccess fa | this = fa.getQualifier() |
// `fa = ...`, `fa += ...`, etc.
isInstanceFieldWrite(fa, node)
or
// `fa.a = ...`, `f(&fa)`, etc.
exists(PartialDefinition pd |
node = pd.getSubBasicBlockStart() and
fa = pd.getDefinedExpr()
)
)
} or
TExplicitCallQualifier(Expr qualifier) {
or
// `e.f(...)`
exists(Call call |
qualifier = call.getQualifier() and
this = call.getQualifier() and
not call.getTarget().hasSpecifier("const")
)
} or
TReferenceArgument(Expr arg, VariableAccess va) { referenceArgument(va, arg) }
private predicate isInstanceFieldWrite(FieldAccess fa, ControlFlowNode node) {
assignmentLikeOperation(node, _, fa, _)
) and
node = this
or
// `f(e)`, `f(&e)`, etc.
referenceArgument(node, this)
}
class PartialDefinition extends TPartialDefinition {
Expr definedExpr;
ControlFlowNode node;
predicate partiallyDefines(Variable v) { this = v.getAnAccess() }
PartialDefinition() {
this = TExplicitFieldStoreQualifier(definedExpr, node)
or
this = TExplicitCallQualifier(definedExpr) and node = definedExpr
or
this = TReferenceArgument(definedExpr, node)
}
predicate partiallyDefines(Variable v) { definedExpr = v.getAnAccess() }
predicate partiallyDefinesThis(ThisExpr e) { definedExpr = e }
predicate partiallyDefinesThis(ThisExpr e) { this = e }
/**
* Gets the subBasicBlock where this `PartialDefinition` is defined.
@@ -165,33 +160,29 @@ private module PartialDefinitions {
* ```
* The expression `x` is being partially defined.
*/
Expr getDefinedExpr() { result = definedExpr }
Expr getDefinedExpr() { result = this }
Location getLocation() {
not exists(definedExpr.getLocation()) and result = definedExpr.getParent().getLocation()
/**
* Gets the location of this element, adjusted to avoid unknown locations
* on compiler-generated `ThisExpr`s.
*/
Location getActualLocation() {
not exists(this.getLocation()) and result = this.getParent().getLocation()
or
definedExpr.getLocation() instanceof UnknownLocation and
result = definedExpr.getParent().getLocation()
this.getLocation() instanceof UnknownLocation and
result = this.getParent().getLocation()
or
result = definedExpr.getLocation() and not result instanceof UnknownLocation
result = this.getLocation() and not result instanceof UnknownLocation
}
string toString() { result = "partial def of " + definedExpr }
}
/**
* A partial definition that's a definition by reference.
*/
class DefinitionByReference extends PartialDefinition, TReferenceArgument {
class DefinitionByReference extends PartialDefinition {
VariableAccess va;
DefinitionByReference() {
// `this` is not restricted in this charpred. That's because the full
// extent of this class includes the charpred of the superclass, which
// relates `this` to `definedExpr`, and `va` is functionally determined
// by `definedExpr`.
referenceArgument(va, definedExpr)
}
DefinitionByReference() { referenceArgument(va, this) }
VariableAccess getVariableAccess() { result = va }

View File

@@ -145,8 +145,6 @@ class HexLiteral extends Literal {
/**
* A C/C++ aggregate literal.
*
* For example:
*/
class AggregateLiteral extends Expr, @aggregateliteral {
override string getCanonicalQLClass() { result = "AggregateLiteral" }

View File

@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
* a callable is recorded by `cc`.
*/
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
exists(
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
LocalCallContext localCC
|
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
localCC = getLocalCallContext(cc, enclosing)
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
midnode = mid.getNode() and
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
ap = ap0
@@ -2331,20 +2332,6 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
pathThroughCallable(mid, node, cc, ap) and sc = mid.getSummaryCtx()
}
pragma[nomagic]
private predicate pathIntoLocalStep(
PathNodeMid mid, Node midnode, CallContext cc, DataFlowCallable enclosing, SummaryCtx sc,
AccessPath ap0, Configuration conf
) {
midnode = mid.getNode() and
cc = mid.getCallContext() and
conf = mid.getConfiguration() and
localFlowBigStep(midnode, _, _, _, conf, _) and
enclosing = midnode.getEnclosingCallable() and
sc = mid.getSummaryCtx() and
ap0 = mid.getAp()
}
pragma[nomagic]
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
readDirect(node1, f, node2) and

View File

@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
* a callable is recorded by `cc`.
*/
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
exists(
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
LocalCallContext localCC
|
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
localCC = getLocalCallContext(cc, enclosing)
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
midnode = mid.getNode() and
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
ap = ap0
@@ -2331,20 +2332,6 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
pathThroughCallable(mid, node, cc, ap) and sc = mid.getSummaryCtx()
}
pragma[nomagic]
private predicate pathIntoLocalStep(
PathNodeMid mid, Node midnode, CallContext cc, DataFlowCallable enclosing, SummaryCtx sc,
AccessPath ap0, Configuration conf
) {
midnode = mid.getNode() and
cc = mid.getCallContext() and
conf = mid.getConfiguration() and
localFlowBigStep(midnode, _, _, _, conf, _) and
enclosing = midnode.getEnclosingCallable() and
sc = mid.getSummaryCtx() and
ap0 = mid.getAp()
}
pragma[nomagic]
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
readDirect(node1, f, node2) and

View File

@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
* a callable is recorded by `cc`.
*/
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
exists(
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
LocalCallContext localCC
|
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
localCC = getLocalCallContext(cc, enclosing)
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
midnode = mid.getNode() and
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
ap = ap0
@@ -2331,20 +2332,6 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
pathThroughCallable(mid, node, cc, ap) and sc = mid.getSummaryCtx()
}
pragma[nomagic]
private predicate pathIntoLocalStep(
PathNodeMid mid, Node midnode, CallContext cc, DataFlowCallable enclosing, SummaryCtx sc,
AccessPath ap0, Configuration conf
) {
midnode = mid.getNode() and
cc = mid.getCallContext() and
conf = mid.getConfiguration() and
localFlowBigStep(midnode, _, _, _, conf, _) and
enclosing = midnode.getEnclosingCallable() and
sc = mid.getSummaryCtx() and
ap0 = mid.getAp()
}
pragma[nomagic]
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
readDirect(node1, f, node2) and

View File

@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
* a callable is recorded by `cc`.
*/
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
exists(
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
LocalCallContext localCC
|
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
localCC = getLocalCallContext(cc, enclosing)
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
midnode = mid.getNode() and
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
ap = ap0
@@ -2331,20 +2332,6 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
pathThroughCallable(mid, node, cc, ap) and sc = mid.getSummaryCtx()
}
pragma[nomagic]
private predicate pathIntoLocalStep(
PathNodeMid mid, Node midnode, CallContext cc, DataFlowCallable enclosing, SummaryCtx sc,
AccessPath ap0, Configuration conf
) {
midnode = mid.getNode() and
cc = mid.getCallContext() and
conf = mid.getConfiguration() and
localFlowBigStep(midnode, _, _, _, conf, _) and
enclosing = midnode.getEnclosingCallable() and
sc = mid.getSummaryCtx() and
ap0 = mid.getAp()
}
pragma[nomagic]
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
readDirect(node1, f, node2) and

View File

@@ -0,0 +1,47 @@
/**
* Provides predicates for mapping the `FunctionInput` and `FunctionOutput`
* classes used in function models to the corresponding instructions.
*/
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.DataFlow
/**
* Gets the instruction that goes into `input` for `call`.
*/
Instruction callInput(CallInstruction call, FunctionInput input) {
// A positional argument
exists(int index |
result = call.getPositionalArgument(index) and
input.isParameter(index)
)
or
// A value pointed to by a positional argument
exists(ReadSideEffectInstruction read |
result = read and
read.getPrimaryInstruction() = call and
input.isParameterDeref(read.getIndex())
)
or
// The qualifier pointer
result = call.getThisArgument() and
input.isQualifierAddress()
//TODO: qualifier deref
}
/**
* Gets the instruction that holds the `output` for `call`.
*/
Instruction callOutput(CallInstruction call, FunctionOutput output) {
// The return value
result = call and
output.isReturnValue()
or
// The side effect of a call on the value pointed to by a positional argument
exists(WriteSideEffectInstruction effect |
result = effect and
effect.getPrimaryInstruction() = call and
output.isParameterDeref(effect.getIndex())
)
// TODO: qualifiers, return value dereference
}

View File

@@ -1,5 +1,8 @@
private import semmle.code.cpp.ir.IR
private import semmle.code.cpp.ir.dataflow.DataFlow
private import ModelUtil
private import semmle.code.cpp.models.interfaces.DataFlow
private import semmle.code.cpp.models.interfaces.SideEffect
/**
* Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local
@@ -45,6 +48,25 @@ private predicate localInstructionTaintStep(Instruction nodeFrom, Instruction no
)
or
nodeTo.(LoadInstruction).getSourceAddress() = nodeFrom
or
modeledInstructionTaintStep(nodeFrom, nodeTo)
or
// Flow through partial reads of arrays and unions
nodeTo.(LoadInstruction).getSourceValueOperand().getAnyDef() = nodeFrom and
not nodeFrom.isResultConflated() and
(
nodeFrom.getResultType() instanceof ArrayType or
nodeFrom.getResultType() instanceof Union
)
or
// Flow from an element to an array or union that contains it.
nodeTo.(ChiInstruction).getPartial() = nodeFrom and
not nodeTo.isResultConflated() and
exists(Type t | nodeTo.getResultLanguageType().hasType(t, false) |
t instanceof Union
or
t instanceof ArrayType
)
}
/**
@@ -82,3 +104,34 @@ predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
* but not in local taint.
*/
predicate defaultTaintBarrier(DataFlow::Node node) { none() }
/**
* Holds if taint can flow from `instrIn` to `instrOut` through a call to a
* modeled function.
*/
predicate modeledInstructionTaintStep(Instruction instrIn, Instruction instrOut) {
exists(CallInstruction call, TaintFunction func, FunctionInput modelIn, FunctionOutput modelOut |
instrIn = callInput(call, modelIn) and
instrOut = callOutput(call, modelOut) and
call.getStaticCallTarget() = func and
func.hasTaintFlow(modelIn, modelOut)
)
or
// Taint flow from one argument to another and data flow from an argument to a
// return value. This happens in functions like `strcat` and `memcpy`. We
// could model this flow in two separate steps, but that would add reverse
// flow from the write side-effect to the call instruction, which may not be
// desirable.
exists(
CallInstruction call, Function func, FunctionInput modelIn, OutParameterDeref modelMidOut,
int indexMid, InParameter modelMidIn, OutReturnValue modelOut
|
instrIn = callInput(call, modelIn) and
instrOut = callOutput(call, modelOut) and
call.getStaticCallTarget() = func and
func.(TaintFunction).hasTaintFlow(modelIn, modelMidOut) and
func.(DataFlowFunction).hasDataFlow(modelMidIn, modelOut) and
modelMidOut.isParameterDeref(indexMid) and
modelMidIn.isParameter(indexMid)
)
}

View File

@@ -89,6 +89,18 @@ class MallocAllocationFunction extends AllocationFunction {
or
// kmem_zalloc(size, flags)
name = "kmem_zalloc" and sizeArg = 0
or
// CRYPTO_malloc(size_t num, const char *file, int line)
name = "CRYPTO_malloc" and sizeArg = 0
or
// CRYPTO_zalloc(size_t num, const char *file, int line)
name = "CRYPTO_zalloc" and sizeArg = 0
or
// CRYPTO_secure_malloc(size_t num, const char *file, int line)
name = "CRYPTO_secure_malloc" and sizeArg = 0
or
// CRYPTO_secure_zalloc(size_t num, const char *file, int line)
name = "CRYPTO_secure_zalloc" and sizeArg = 0
)
)
}
@@ -169,6 +181,9 @@ class ReallocAllocationFunction extends AllocationFunction {
or
// CoTaskMemRealloc(ptr, size)
name = "CoTaskMemRealloc" and sizeArg = 1 and reallocArg = 0
or
// CRYPTO_realloc(void *addr, size_t num, const char *file, int line);
name = "CRYPTO_realloc" and sizeArg = 1 and reallocArg = 0
)
)
}
@@ -255,6 +270,36 @@ class OperatorNewAllocationFunction extends AllocationFunction {
}
}
/**
* The predicate analyzes a `sizeExpr`, which is an argument to an allocation
* function like malloc, and tries to split it into an expression `lengthExpr`
* that describes the length of the allocated array, and the size of the allocated
* element type `sizeof`.
* If this is not possible, the allocation is considered to be of size 1 and of
* length `sizeExpr`.
*/
private predicate deconstructSizeExpr(Expr sizeExpr, Expr lengthExpr, int sizeof) {
if
sizeExpr instanceof MulExpr and
exists(SizeofOperator sizeofOp, Expr lengthOp |
sizeofOp = sizeExpr.(MulExpr).getAnOperand() and
lengthOp = sizeExpr.(MulExpr).getAnOperand() and
not lengthOp instanceof SizeofOperator and
exists(sizeofOp.getValue().toInt())
)
then
exists(SizeofOperator sizeofOp |
sizeofOp = sizeExpr.(MulExpr).getAnOperand() and
lengthExpr = sizeExpr.(MulExpr).getAnOperand() and
not lengthExpr instanceof SizeofOperator and
sizeof = sizeofOp.getValue().toInt()
)
else (
lengthExpr = sizeExpr and
sizeof = 1
)
}
/**
* An allocation expression that is a function call, such as call to `malloc`.
*/
@@ -272,7 +317,17 @@ class CallAllocationExpr extends AllocationExpr, FunctionCall {
not exists(NewOrNewArrayExpr new | new.getAllocatorCall() = this)
}
override Expr getSizeExpr() { result = getArgument(target.getSizeArg()) }
override Expr getSizeExpr() {
exists(Expr sizeExpr | sizeExpr = getArgument(target.getSizeArg()) |
if exists(target.getSizeMult())
then result = sizeExpr
else
exists(Expr lengthExpr |
deconstructSizeExpr(sizeExpr, lengthExpr, _) and
result = lengthExpr
)
)
}
override int getSizeMult() {
// malloc with multiplier argument that is a constant
@@ -280,13 +335,19 @@ class CallAllocationExpr extends AllocationExpr, FunctionCall {
or
// malloc with no multiplier argument
not exists(target.getSizeMult()) and
result = 1
deconstructSizeExpr(getArgument(target.getSizeArg()), _, result)
}
override int getSizeBytes() { result = getSizeExpr().getValue().toInt() * getSizeMult() }
override Expr getReallocPtr() { result = getArgument(target.getReallocPtrArg()) }
override Type getAllocatedElementType() {
result =
this.getFullyConverted().getType().stripTopLevelSpecifiers().(PointerType).getBaseType() and
not result instanceof VoidType
}
override predicate requiresDealloc() { target.requiresDealloc() }
}
@@ -298,6 +359,8 @@ class NewAllocationExpr extends AllocationExpr, NewExpr {
override int getSizeBytes() { result = getAllocatedType().getSize() }
override Type getAllocatedElementType() { result = getAllocatedType() }
override predicate requiresDealloc() { not exists(getPlacementPointer()) }
}
@@ -318,6 +381,8 @@ class NewArrayAllocationExpr extends AllocationExpr, NewArrayExpr {
result = getAllocatedElementType().getSize()
}
override Type getAllocatedElementType() { result = NewArrayExpr.super.getAllocatedElementType() }
override int getSizeBytes() { result = getAllocatedType().getSize() }
override predicate requiresDealloc() { not exists(getPlacementPointer()) }

View File

@@ -19,6 +19,10 @@ class StandardDeallocationFunction extends DeallocationFunction {
name = "free" and freedArg = 0
or
name = "realloc" and freedArg = 0
or
name = "CRYPTO_free" and freedArg = 0
or
name = "CRYPTO_secure_free" and freedArg = 0
)
or
hasGlobalOrStdName(name) and

View File

@@ -4,6 +4,7 @@ import semmle.code.cpp.models.interfaces.Taint
* The `std::basic_string` constructor(s).
*/
class StdStringConstructor extends TaintFunction {
pragma[noinline]
StdStringConstructor() { this.hasQualifiedName("std", "basic_string", "basic_string") }
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {

View File

@@ -72,6 +72,11 @@ abstract class AllocationExpr extends Expr {
*/
Expr getReallocPtr() { none() }
/**
* Gets the type of the elements that are allocated, if it can be determined.
*/
Type getAllocatedElementType() { none() }
/**
* Whether or not this allocation requires a corresponding deallocation of
* some sort (most do, but `alloca` for example does not). If it is unclear,

View File

@@ -74,6 +74,8 @@ abstract class Architecture extends string {
or
t instanceof WideCharType and result = wideCharSize()
or
t instanceof Char8Type and result = 8
or
t instanceof Char16Type and result = 16
or
t instanceof Char32Type and result = 32
@@ -155,6 +157,8 @@ abstract class Architecture extends string {
or
t instanceof WideCharType and result = wideCharSize()
or
t instanceof Char8Type and result = 8
or
t instanceof Char16Type and result = 16
or
t instanceof Char32Type and result = 32

View File

@@ -616,6 +616,7 @@ enumconstants(
| 48 = _Float64x
| 49 = _Float128
| 50 = _Float128x
| 51 = char8_t
;
*/
builtintypes(

View File

@@ -149,3 +149,16 @@ void directOperatorCall() {
ptr = operator new(sizeof(int));
operator delete(ptr);
}
void *malloc(size_t);
typedef int* ptr_int;
void testMalloc(size_t count) {
const volatile int *i = (const volatile int *) malloc(5);
ptr_int i2 = (ptr_int) malloc(5 * sizeof(int));
volatile long *l = (long *) malloc(count);
l = (long *) malloc(count * sizeof(int));
const char* c = (const char *) malloc(count * sizeof(int) + 1);
void * v = (void *) malloc(((int) count) * sizeof(void *));
malloc(sizeof(void *) * sizeof(int));
}

View File

@@ -55,35 +55,43 @@ allocationFunctions
| allocators.cpp:122:7:122:20 | operator new[] | getPlacementArgument = 1, getSizeArg = 0 |
| allocators.cpp:123:7:123:18 | operator new | getSizeArg = 0, requiresDealloc |
| allocators.cpp:124:7:124:20 | operator new[] | getSizeArg = 0, requiresDealloc |
| allocators.cpp:153:7:153:12 | malloc | getSizeArg = 0, requiresDealloc |
| file://:0:0:0:0 | operator new | getSizeArg = 0, requiresDealloc |
| file://:0:0:0:0 | operator new | getSizeArg = 0, requiresDealloc |
| file://:0:0:0:0 | operator new[] | getSizeArg = 0, requiresDealloc |
| file://:0:0:0:0 | operator new[] | getSizeArg = 0, requiresDealloc |
allocationExprs
| allocators.cpp:49:3:49:9 | new | getSizeBytes = 4, requiresDealloc |
| allocators.cpp:50:3:50:15 | new | getSizeBytes = 4, requiresDealloc |
| allocators.cpp:51:3:51:11 | new | getSizeBytes = 4, requiresDealloc |
| allocators.cpp:52:3:52:14 | new | getSizeBytes = 8, requiresDealloc |
| allocators.cpp:53:3:53:27 | new | getSizeBytes = 8, requiresDealloc |
| allocators.cpp:54:3:54:17 | new | getSizeBytes = 256, requiresDealloc |
| allocators.cpp:55:3:55:25 | new | getSizeBytes = 256, requiresDealloc |
| allocators.cpp:68:3:68:12 | new[] | getSizeExpr = n, getSizeMult = 4, requiresDealloc |
| allocators.cpp:69:3:69:18 | new[] | getSizeExpr = n, getSizeMult = 4, requiresDealloc |
| allocators.cpp:70:3:70:15 | new[] | getSizeExpr = n, getSizeMult = 8, requiresDealloc |
| allocators.cpp:71:3:71:20 | new[] | getSizeExpr = n, getSizeMult = 256, requiresDealloc |
| allocators.cpp:72:3:72:16 | new[] | getSizeBytes = 80, requiresDealloc |
| allocators.cpp:107:3:107:18 | new | getSizeBytes = 1, requiresDealloc |
| allocators.cpp:108:3:108:19 | new[] | getSizeExpr = n, getSizeMult = 1, requiresDealloc |
| allocators.cpp:109:3:109:35 | new | getSizeBytes = 128, requiresDealloc |
| allocators.cpp:110:3:110:37 | new[] | getSizeBytes = 1280, requiresDealloc |
| allocators.cpp:129:3:129:21 | new | getSizeBytes = 4 |
| allocators.cpp:132:3:132:17 | new[] | getSizeBytes = 4 |
| allocators.cpp:135:3:135:26 | new | getSizeBytes = 4, requiresDealloc |
| allocators.cpp:136:3:136:26 | new[] | getSizeBytes = 8, requiresDealloc |
| allocators.cpp:142:13:142:27 | new[] | getSizeExpr = x, getSizeMult = 10, requiresDealloc |
| allocators.cpp:143:13:143:28 | new[] | getSizeBytes = 400, requiresDealloc |
| allocators.cpp:144:13:144:31 | new[] | getSizeExpr = x, getSizeMult = 900, requiresDealloc |
| allocators.cpp:49:3:49:9 | new | getAllocatedElementType = int, getSizeBytes = 4, requiresDealloc |
| allocators.cpp:50:3:50:15 | new | getAllocatedElementType = int, getSizeBytes = 4, requiresDealloc |
| allocators.cpp:51:3:51:11 | new | getAllocatedElementType = int, getSizeBytes = 4, requiresDealloc |
| allocators.cpp:52:3:52:14 | new | getAllocatedElementType = String, getSizeBytes = 8, requiresDealloc |
| allocators.cpp:53:3:53:27 | new | getAllocatedElementType = String, getSizeBytes = 8, requiresDealloc |
| allocators.cpp:54:3:54:17 | new | getAllocatedElementType = Overaligned, getSizeBytes = 256, requiresDealloc |
| allocators.cpp:55:3:55:25 | new | getAllocatedElementType = Overaligned, getSizeBytes = 256, requiresDealloc |
| allocators.cpp:68:3:68:12 | new[] | getAllocatedElementType = int, getSizeExpr = n, getSizeMult = 4, requiresDealloc |
| allocators.cpp:69:3:69:18 | new[] | getAllocatedElementType = int, getSizeExpr = n, getSizeMult = 4, requiresDealloc |
| allocators.cpp:70:3:70:15 | new[] | getAllocatedElementType = String, getSizeExpr = n, getSizeMult = 8, requiresDealloc |
| allocators.cpp:71:3:71:20 | new[] | getAllocatedElementType = Overaligned, getSizeExpr = n, getSizeMult = 256, requiresDealloc |
| allocators.cpp:72:3:72:16 | new[] | getAllocatedElementType = String, getSizeBytes = 80, requiresDealloc |
| allocators.cpp:107:3:107:18 | new | getAllocatedElementType = FailedInit, getSizeBytes = 1, requiresDealloc |
| allocators.cpp:108:3:108:19 | new[] | getAllocatedElementType = FailedInit, getSizeExpr = n, getSizeMult = 1, requiresDealloc |
| allocators.cpp:109:3:109:35 | new | getAllocatedElementType = FailedInitOveraligned, getSizeBytes = 128, requiresDealloc |
| allocators.cpp:110:3:110:37 | new[] | getAllocatedElementType = FailedInitOveraligned, getSizeBytes = 1280, requiresDealloc |
| allocators.cpp:129:3:129:21 | new | getAllocatedElementType = int, getSizeBytes = 4 |
| allocators.cpp:132:3:132:17 | new[] | getAllocatedElementType = int, getSizeBytes = 4 |
| allocators.cpp:135:3:135:26 | new | getAllocatedElementType = int, getSizeBytes = 4, requiresDealloc |
| allocators.cpp:136:3:136:26 | new[] | getAllocatedElementType = int, getSizeBytes = 8, requiresDealloc |
| allocators.cpp:142:13:142:27 | new[] | getAllocatedElementType = char[10], getSizeExpr = x, getSizeMult = 10, requiresDealloc |
| allocators.cpp:143:13:143:28 | new[] | getAllocatedElementType = char[20], getSizeBytes = 400, requiresDealloc |
| allocators.cpp:144:13:144:31 | new[] | getAllocatedElementType = char[30][30], getSizeExpr = x, getSizeMult = 900, requiresDealloc |
| allocators.cpp:149:8:149:19 | call to operator new | getSizeBytes = 4, getSizeExpr = sizeof(int), getSizeMult = 1, requiresDealloc |
| allocators.cpp:157:50:157:55 | call to malloc | getAllocatedElementType = const volatile int, getSizeBytes = 5, getSizeExpr = 5, getSizeMult = 1, requiresDealloc |
| allocators.cpp:158:26:158:31 | call to malloc | getAllocatedElementType = int, getSizeBytes = 20, getSizeExpr = 5, getSizeMult = 4, requiresDealloc |
| allocators.cpp:159:31:159:36 | call to malloc | getAllocatedElementType = volatile long, getSizeExpr = count, getSizeMult = 1, requiresDealloc |
| allocators.cpp:160:16:160:21 | call to malloc | getAllocatedElementType = volatile long, getSizeExpr = count, getSizeMult = 4, requiresDealloc |
| allocators.cpp:161:34:161:39 | call to malloc | getAllocatedElementType = const char, getSizeExpr = ... + ..., getSizeMult = 1, requiresDealloc |
| allocators.cpp:162:23:162:28 | call to malloc | getSizeExpr = count, getSizeMult = 8, requiresDealloc |
| allocators.cpp:163:3:163:8 | call to malloc | getSizeBytes = 32, getSizeExpr = ... * ..., getSizeMult = 1, requiresDealloc |
deallocationFunctions
| allocators.cpp:11:6:11:20 | operator delete | getFreedArg = 0 |
| allocators.cpp:12:6:12:22 | operator delete[] | getFreedArg = 0 |

View File

@@ -138,6 +138,8 @@ string describeAllocationExpr(AllocationExpr e) {
or
result = "getReallocPtr = " + e.getReallocPtr().toString()
or
result = "getAllocatedElementType = " + e.getAllocatedElementType().toString()
or
e.requiresDealloc() and
result = "requiresDealloc"
}

View File

@@ -61,6 +61,7 @@
| file://:0:0:0:0 | auto |
| file://:0:0:0:0 | bool |
| file://:0:0:0:0 | char |
| file://:0:0:0:0 | char8_t |
| file://:0:0:0:0 | char16_t |
| file://:0:0:0:0 | char32_t |
| file://:0:0:0:0 | const |

View File

@@ -38,6 +38,7 @@
| file://:0:0:0:0 | auto |
| file://:0:0:0:0 | bool |
| file://:0:0:0:0 | char |
| file://:0:0:0:0 | char8_t |
| file://:0:0:0:0 | char16_t |
| file://:0:0:0:0 | char32_t |
| file://:0:0:0:0 | const |

View File

@@ -1,4 +1,5 @@
import semmle.code.cpp.dataflow.internal.FlowVar
from PartialDefinition def
select def, def.getDefinedExpr(), def.getSubBasicBlockStart()
select def.getActualLocation().toString(), "partial def of " + def.toString(), def.getDefinedExpr(),
def.getSubBasicBlockStart()

View File

@@ -22,6 +22,9 @@
| taint.cpp:93:11:93:11 | taint.cpp:71:22:71:27 | AST only |
| taint.cpp:94:11:94:11 | taint.cpp:72:7:72:12 | AST only |
| taint.cpp:109:7:109:13 | taint.cpp:105:12:105:17 | IR only |
| taint.cpp:110:7:110:13 | taint.cpp:105:12:105:17 | IR only |
| taint.cpp:111:7:111:13 | taint.cpp:106:12:106:17 | IR only |
| taint.cpp:112:7:112:13 | taint.cpp:106:12:106:17 | IR only |
| taint.cpp:130:7:130:9 | taint.cpp:127:8:127:13 | IR only |
| taint.cpp:137:7:137:9 | taint.cpp:120:11:120:16 | AST only |
| taint.cpp:173:8:173:13 | taint.cpp:164:19:164:24 | AST only |

View File

@@ -4,6 +4,9 @@
| taint.cpp:16:8:16:14 | source1 | taint.cpp:12:22:12:27 | call to source |
| taint.cpp:17:8:17:16 | ++ ... | taint.cpp:12:22:12:27 | call to source |
| taint.cpp:109:7:109:13 | access to array | taint.cpp:105:12:105:17 | call to source |
| taint.cpp:110:7:110:13 | access to array | taint.cpp:105:12:105:17 | call to source |
| taint.cpp:111:7:111:13 | access to array | taint.cpp:106:12:106:17 | call to source |
| taint.cpp:112:7:112:13 | access to array | taint.cpp:106:12:106:17 | call to source |
| taint.cpp:129:7:129:9 | * ... | taint.cpp:120:11:120:16 | call to source |
| taint.cpp:130:7:130:9 | * ... | taint.cpp:127:8:127:13 | call to source |
| taint.cpp:134:7:134:9 | * ... | taint.cpp:120:11:120:16 | call to source |

View File

@@ -51,6 +51,7 @@
| file://:0:0:0:0 | auto |
| file://:0:0:0:0 | bool |
| file://:0:0:0:0 | char |
| file://:0:0:0:0 | char8_t |
| file://:0:0:0:0 | char16_t |
| file://:0:0:0:0 | char32_t |
| file://:0:0:0:0 | composite<int> & |

View File

@@ -23,6 +23,7 @@
| file://:0:0:0:0 | auto |
| file://:0:0:0:0 | bool |
| file://:0:0:0:0 | char |
| file://:0:0:0:0 | char8_t |
| file://:0:0:0:0 | char16_t |
| file://:0:0:0:0 | char32_t |
| file://:0:0:0:0 | const __va_list_tag |

View File

@@ -44,6 +44,7 @@
| file://:0:0:0:0 | auto | <none> |
| file://:0:0:0:0 | bool | 1 |
| file://:0:0:0:0 | char | 1 |
| file://:0:0:0:0 | char8_t | 1 |
| file://:0:0:0:0 | char16_t | 2 |
| file://:0:0:0:0 | char32_t | 4 |
| file://:0:0:0:0 | char * | 8 |

View File

@@ -20,3 +20,4 @@
| 37 | signed __int128 | signed | -------- | explicitlySigned | ------------------ | ---------------- | 16 | 16 | unsigned __int128 | |
| 43 | char16_t | ------ | -------- | ---------------- | ------------------ | ---------------- | 2 | 2 | <no unsigned equivalent> | |
| 44 | char32_t | ------ | -------- | ---------------- | ------------------ | ---------------- | 4 | 4 | <no unsigned equivalent> | |
| 51 | char8_t | ------ | -------- | ---------------- | ------------------ | ---------------- | 1 | 1 | <no unsigned equivalent> | |

View File

@@ -20,3 +20,4 @@
| 37 | signed __int128 | signed | -------- | explicitlySigned | ------------------ | ---------------- | 16 | 16 | unsigned __int128 | |
| 43 | char16_t | ------ | -------- | ---------------- | ------------------ | ---------------- | 2 | 2 | <no unsigned equivalent> | |
| 44 | char32_t | ------ | -------- | ---------------- | ------------------ | ---------------- | 4 | 4 | <no unsigned equivalent> | |
| 51 | char8_t | ------ | -------- | ---------------- | ------------------ | ---------------- | 1 | 1 | <no unsigned equivalent> | |

View File

@@ -33,6 +33,7 @@
| file://:0:0:0:0 | auto | Other |
| file://:0:0:0:0 | bool | Other |
| file://:0:0:0:0 | char | Other |
| file://:0:0:0:0 | char8_t | Other |
| file://:0:0:0:0 | char16_t | Other |
| file://:0:0:0:0 | char32_t | Other |
| file://:0:0:0:0 | const | Other |

View File

@@ -24,6 +24,7 @@
| file://:0:0:0:0 | auto | auto |
| file://:0:0:0:0 | bool | bool |
| file://:0:0:0:0 | char | char |
| file://:0:0:0:0 | char8_t | char8_t |
| file://:0:0:0:0 | char16_t | char16_t |
| file://:0:0:0:0 | char32_t | char32_t |
| file://:0:0:0:0 | const __va_list_tag | __va_list_tag |

View File

@@ -27,6 +27,7 @@
| auto | AutoType | | | | |
| bool | BoolType | | | | |
| char | MicrosoftInt8Type, PlainCharType | | | | |
| char8_t | Char8Type | | | | |
| char16_t | Char16Type | | | | |
| char32_t | Char32Type | | | | |
| char * | CharPointerType | | char | | |

View File

@@ -1,7 +1,9 @@
| tests1.cpp:26:21:26:26 | call to malloc | This allocation does not include space to null-terminate the string. |
| tests1.cpp:36:21:36:26 | call to malloc | This allocation does not include space to null-terminate the string. |
| tests1.cpp:56:21:56:27 | call to realloc | This allocation does not include space to null-terminate the string. |
| tests1.cpp:67:21:67:26 | call to malloc | This allocation does not include space to null-terminate the string. |
| tests1.cpp:89:25:89:30 | call to malloc | This allocation does not include space to null-terminate the string. |
| tests1.cpp:109:25:109:30 | call to malloc | This allocation does not include space to null-terminate the string. |
| tests3.cpp:25:21:25:31 | call to malloc | This allocation does not include space to null-terminate the string. |
| tests3.cpp:30:21:30:31 | call to malloc | This allocation does not include space to null-terminate the string. |
| tests3.cpp:53:17:53:44 | new[] | This allocation does not include space to null-terminate the string. |

View File

@@ -1 +1,2 @@
| tests2.cpp:34:4:34:9 | call to strcat | This buffer only contains enough room for 'str1' (copied on line 33) |
| tests2.cpp:52:4:52:9 | call to strcat | This buffer only contains enough room for 'str1' (copied on line 51) |

View File

@@ -33,7 +33,7 @@ void tests1(int case_num)
break;
case 3:
buffer = (char *)malloc(strlen(str) * sizeof(char)); // BAD [NOT DETECTED]
buffer = (char *)malloc(strlen(str) * sizeof(char)); // BAD
strcpy(buffer, str);
break;
@@ -106,7 +106,7 @@ void tests1(int case_num)
break;
case 105:
wbuffer = (wchar_t *)malloc(wcslen(wstr) * sizeof(wchar_t)); // BAD [NOT DETECTED]
wbuffer = (wchar_t *)malloc(wcslen(wstr) * sizeof(wchar_t)); // BAD
wcscpy(wbuffer, wstr);
break;

View File

@@ -47,7 +47,7 @@ void tests2(int case_num)
break;
case 4:
buffer = (char *)malloc((strlen(str1) + 1) * sizeof(char)); // BAD [NOT DETECTED]
buffer = (char *)malloc((strlen(str1) + 1) * sizeof(char)); // BAD
strcpy(buffer, str1);
strcat(buffer, str2);
break;

View File

@@ -3,7 +3,9 @@
| test.c:16:20:16:25 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.c:32:20:32:25 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.c:49:20:49:25 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.c:64:20:64:25 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.cpp:24:35:24:40 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.cpp:31:35:31:40 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.cpp:45:28:45:33 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.cpp:55:28:55:33 | call to malloc | This allocation does not include space to null-terminate the string. |
| test.cpp:63:28:63:33 | call to malloc | This allocation does not include space to null-terminate the string. |

View File

@@ -60,7 +60,7 @@ void good2(char *str) {
}
void bad3(char *str) {
// BAD -- Not allocating space for '\0' terminator [NOT DETECTED]
// BAD -- Not allocating space for '\0' terminator
char *buffer = malloc(strlen(str) * sizeof(char));
strcpy(buffer, str);
free(buffer);

View File

@@ -27,7 +27,7 @@ void bad1(wchar_t *wstr) {
}
void bad2(wchar_t *wstr) {
// BAD -- Not allocating space for '\0' terminator [NOT DETECTED]
// BAD -- Not allocating space for '\0' terminator
wchar_t *wbuffer = (wchar_t *)malloc(wcslen(wstr) * sizeof(wchar_t));
wcscpy(wbuffer, wstr);
free(wbuffer);

View File

@@ -1,7 +1,7 @@
| test.cpp:6:30:6:40 | sizeof(int) | Suspicious sizeof offset in a pointer arithmetic expression. The type of the pointer is int *. |
| test.cpp:14:30:14:40 | sizeof(int) | Suspicious sizeof offset in a pointer arithmetic expression. The type of the pointer is int *. |
| test.cpp:22:25:22:35 | sizeof(int) | Suspicious sizeof offset in a pointer arithmetic expression. The type of the pointer is int *. |
| test.cpp:30:25:30:35 | sizeof(int) | Suspicious sizeof offset in a pointer arithmetic expression. The type of the pointer is int *. |
| test.cpp:38:30:38:40 | sizeof(int) | Suspicious sizeof offset in a pointer arithmetic expression. The type of the pointer is int *. |
| test.cpp:61:27:61:37 | sizeof(int) | Suspicious sizeof offset in a pointer arithmetic expression. The type of the pointer is int *. |
| test.cpp:89:43:89:55 | sizeof(MyABC) | Suspicious sizeof offset in a pointer arithmetic expression. The type of the pointer is myInt *const. |
| test.cpp:6:30:6:40 | sizeof(int) | Suspicious sizeof offset in a pointer arithmetic expression. The type of the pointer is $@. | file://:0:0:0:0 | int * | int * |
| test.cpp:14:30:14:40 | sizeof(int) | Suspicious sizeof offset in a pointer arithmetic expression. The type of the pointer is $@. | file://:0:0:0:0 | int * | int * |
| test.cpp:22:25:22:35 | sizeof(int) | Suspicious sizeof offset in a pointer arithmetic expression. The type of the pointer is $@. | file://:0:0:0:0 | int * | int * |
| test.cpp:30:25:30:35 | sizeof(int) | Suspicious sizeof offset in a pointer arithmetic expression. The type of the pointer is $@. | file://:0:0:0:0 | int * | int * |
| test.cpp:38:30:38:40 | sizeof(int) | Suspicious sizeof offset in a pointer arithmetic expression. The type of the pointer is $@. | file://:0:0:0:0 | int * | int * |
| test.cpp:61:27:61:37 | sizeof(int) | Suspicious sizeof offset in a pointer arithmetic expression. The type of the pointer is $@. | file://:0:0:0:0 | int * | int * |
| test.cpp:89:43:89:55 | sizeof(MyABC) | Suspicious sizeof offset in a pointer arithmetic expression. The type of the pointer is $@. | file://:0:0:0:0 | myInt *const | myInt *const |

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Add support for char8_t C++ builtin type
compatibility: backwards

View File

@@ -462,7 +462,7 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
public void TestCppAutobuilderSuccess()
{
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.RunProcess[@"cmd.exe /C CALL ^""C:\Program Files ^(x86^)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat^"" && set Platform=&& type NUL && 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;
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationVersion"] = 0;
@@ -733,9 +733,9 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
public void TestWindowCSharpMsBuild()
{
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 CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && 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:\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 CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && 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;
Actions.FileExists["csharp.log"] = true;
@@ -764,9 +764,9 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
public void TestWindowCSharpMsBuildMultipleSolutions()
{
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 CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && 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:\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 CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && 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;
Actions.FileExists["csharp.log"] = true;
@@ -811,7 +811,7 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
public void TestWindowCSharpMsBuildFailed()
{
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.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && 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;
Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false;
@@ -837,8 +837,8 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
[Fact]
public void TestSkipNugetMsBuild()
{
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 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 CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && 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 CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && 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;
Actions.FileExists["csharp.log"] = true;
@@ -1031,7 +1031,7 @@ Microsoft.NETCore.App 2.1.4 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
public void TestDirsProjWindows()
{
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 CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && 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;
Actions.FileExists["csharp.log"] = true;

View File

@@ -118,6 +118,24 @@ namespace Semmle.Autobuild
/// </summary>
public IBuildActions Actions { get; }
IEnumerable<IProjectOrSolution>? FindFiles(string extension, Func<string, ProjectOrSolution> create)
{
var matchingFiles = GetExtensions(extension).
Select(p => (ProjectOrSolution: create(p.Item1), DistanceFromRoot: p.Item2)).
Where(p => p.ProjectOrSolution.HasLanguage(this.Options.Language)).
ToArray();
if (matchingFiles.Length == 0)
return null;
if (Options.AllSolutions)
return matchingFiles.Select(p => p.ProjectOrSolution);
return matchingFiles.
Where(f => f.DistanceFromRoot == matchingFiles[0].DistanceFromRoot).
Select(f => f.ProjectOrSolution);
}
/// <summary>
/// Find all the relevant files and picks the best
/// solution file and tools.
@@ -151,24 +169,6 @@ namespace Semmle.Autobuild
return ret;
}
IEnumerable<IProjectOrSolution>? FindFiles(string extension, Func<string, ProjectOrSolution> create)
{
var matchingFiles = GetExtensions(extension).
Select(p => (ProjectOrSolution: create(p.Item1), DistanceFromRoot: p.Item2)).
Where(p => p.ProjectOrSolution.HasLanguage(this.Options.Language)).
ToArray();
if (matchingFiles.Length == 0)
return null;
if (options.AllSolutions)
return matchingFiles.Select(p => p.ProjectOrSolution);
return matchingFiles.
Where(f => f.DistanceFromRoot == matchingFiles[0].DistanceFromRoot).
Select(f => f.ProjectOrSolution);
}
// First look for `.proj` files
ret = FindFiles(".proj", f => new Project(this, f))?.ToList();
if (ret != null)

View File

@@ -1710,9 +1710,9 @@ module ControlFlow {
exists(getAThrownException(ts, cfe, c)) and
result = first(ts.getCatchClause(0))
or
exists(SpecificCatchClause scc, int i | scc = ts.getCatchClause(i) |
cfe = scc and
scc = last(ts.getCatchClause(i), c) and
exists(CatchClause cc, int i | cc = ts.getCatchClause(i) |
cfe = cc and
cc = last(ts.getCatchClause(i), c) and
(
// Flow from one `catch` clause to the next
result = first(ts.getCatchClause(i + 1)) and
@@ -1725,7 +1725,7 @@ module ControlFlow {
)
or
cfe = last(ts.getCatchClause(i), c) and
cfe = last(scc.getFilterClause(), _) and
cfe = last(cc.getFilterClause(), _) and
(
// Flow from last element of `catch` clause filter to next `catch` clause
result = first(ts.getCatchClause(i + 1)) and
@@ -1739,7 +1739,7 @@ module ControlFlow {
)
or
// Flow from last element of a `catch` block to first element of `finally` block
cfe = lastCatchClauseBlock(scc, c) and
cfe = lastCatchClauseBlock(cc, c) and
result = first(ts.getFinally())
)
or

View File

@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
* a callable is recorded by `cc`.
*/
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
exists(
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
LocalCallContext localCC
|
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
localCC = getLocalCallContext(cc, enclosing)
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
midnode = mid.getNode() and
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
ap = ap0
@@ -2331,20 +2332,6 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
pathThroughCallable(mid, node, cc, ap) and sc = mid.getSummaryCtx()
}
pragma[nomagic]
private predicate pathIntoLocalStep(
PathNodeMid mid, Node midnode, CallContext cc, DataFlowCallable enclosing, SummaryCtx sc,
AccessPath ap0, Configuration conf
) {
midnode = mid.getNode() and
cc = mid.getCallContext() and
conf = mid.getConfiguration() and
localFlowBigStep(midnode, _, _, _, conf, _) and
enclosing = midnode.getEnclosingCallable() and
sc = mid.getSummaryCtx() and
ap0 = mid.getAp()
}
pragma[nomagic]
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
readDirect(node1, f, node2) and

View File

@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
* a callable is recorded by `cc`.
*/
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
exists(
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
LocalCallContext localCC
|
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
localCC = getLocalCallContext(cc, enclosing)
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
midnode = mid.getNode() and
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
ap = ap0
@@ -2331,20 +2332,6 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
pathThroughCallable(mid, node, cc, ap) and sc = mid.getSummaryCtx()
}
pragma[nomagic]
private predicate pathIntoLocalStep(
PathNodeMid mid, Node midnode, CallContext cc, DataFlowCallable enclosing, SummaryCtx sc,
AccessPath ap0, Configuration conf
) {
midnode = mid.getNode() and
cc = mid.getCallContext() and
conf = mid.getConfiguration() and
localFlowBigStep(midnode, _, _, _, conf, _) and
enclosing = midnode.getEnclosingCallable() and
sc = mid.getSummaryCtx() and
ap0 = mid.getAp()
}
pragma[nomagic]
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
readDirect(node1, f, node2) and

View File

@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
* a callable is recorded by `cc`.
*/
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
exists(
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
LocalCallContext localCC
|
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
localCC = getLocalCallContext(cc, enclosing)
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
midnode = mid.getNode() and
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
ap = ap0
@@ -2331,20 +2332,6 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
pathThroughCallable(mid, node, cc, ap) and sc = mid.getSummaryCtx()
}
pragma[nomagic]
private predicate pathIntoLocalStep(
PathNodeMid mid, Node midnode, CallContext cc, DataFlowCallable enclosing, SummaryCtx sc,
AccessPath ap0, Configuration conf
) {
midnode = mid.getNode() and
cc = mid.getCallContext() and
conf = mid.getConfiguration() and
localFlowBigStep(midnode, _, _, _, conf, _) and
enclosing = midnode.getEnclosingCallable() and
sc = mid.getSummaryCtx() and
ap0 = mid.getAp()
}
pragma[nomagic]
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
readDirect(node1, f, node2) and

View File

@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
* a callable is recorded by `cc`.
*/
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
exists(
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
LocalCallContext localCC
|
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
localCC = getLocalCallContext(cc, enclosing)
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
midnode = mid.getNode() and
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
ap = ap0
@@ -2331,20 +2332,6 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
pathThroughCallable(mid, node, cc, ap) and sc = mid.getSummaryCtx()
}
pragma[nomagic]
private predicate pathIntoLocalStep(
PathNodeMid mid, Node midnode, CallContext cc, DataFlowCallable enclosing, SummaryCtx sc,
AccessPath ap0, Configuration conf
) {
midnode = mid.getNode() and
cc = mid.getCallContext() and
conf = mid.getConfiguration() and
localFlowBigStep(midnode, _, _, _, conf, _) and
enclosing = midnode.getEnclosingCallable() and
sc = mid.getSummaryCtx() and
ap0 = mid.getAp()
}
pragma[nomagic]
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
readDirect(node1, f, node2) and

View File

@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
* a callable is recorded by `cc`.
*/
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
exists(
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
LocalCallContext localCC
|
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
localCC = getLocalCallContext(cc, enclosing)
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
midnode = mid.getNode() and
conf = mid.getConfiguration() and
cc = mid.getCallContext() and
sc = mid.getSummaryCtx() and
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
ap0 = mid.getAp()
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
ap = ap0
@@ -2331,20 +2332,6 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCt
pathThroughCallable(mid, node, cc, ap) and sc = mid.getSummaryCtx()
}
pragma[nomagic]
private predicate pathIntoLocalStep(
PathNodeMid mid, Node midnode, CallContext cc, DataFlowCallable enclosing, SummaryCtx sc,
AccessPath ap0, Configuration conf
) {
midnode = mid.getNode() and
cc = mid.getCallContext() and
conf = mid.getConfiguration() and
localFlowBigStep(midnode, _, _, _, conf, _) and
enclosing = midnode.getEnclosingCallable() and
sc = mid.getSummaryCtx() and
ap0 = mid.getAp()
}
pragma[nomagic]
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
readDirect(node1, f, node2) and

View File

@@ -370,6 +370,10 @@
| Finally.cs:211:13:211:29 | ...; | Finally.cs:213:9:213:24 | ... = ... | 8 |
| Finally.cs:211:13:211:29 | [finally: exception(Exception)] ...; | Finally.cs:211:13:211:28 | [finally: exception(Exception)] ... = ... | 4 |
| Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; | Finally.cs:211:13:211:28 | [finally: exception(ExceptionA)] ... = ... | 4 |
| Finally.cs:216:10:216:12 | enter M11 | Finally.cs:220:31:220:35 | "Try" | 6 |
| Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:220:13:220:36 | call to method WriteLine | 1 |
| Finally.cs:222:9:225:9 | catch {...} | Finally.cs:224:13:224:38 | call to method WriteLine | 5 |
| Finally.cs:227:9:229:9 | {...} | Finally.cs:216:10:216:12 | exit M11 | 8 |
| Foreach.cs:6:10:6:11 | enter M1 | Foreach.cs:8:29:8:32 | access to parameter args | 3 |
| Foreach.cs:6:10:6:11 | exit M1 | Foreach.cs:6:10:6:11 | exit M1 | 1 |
| Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | 1 |

View File

@@ -1621,6 +1621,24 @@ dominance
| Finally.cs:213:9:213:12 | this access | Finally.cs:213:22:213:24 | "1" |
| Finally.cs:213:9:213:25 | ...; | Finally.cs:213:9:213:12 | this access |
| Finally.cs:213:22:213:24 | "1" | Finally.cs:213:9:213:24 | ... = ... |
| Finally.cs:216:10:216:12 | enter M11 | Finally.cs:217:5:231:5 | {...} |
| Finally.cs:217:5:231:5 | {...} | Finally.cs:218:9:229:9 | try {...} ... |
| Finally.cs:218:9:229:9 | try {...} ... | Finally.cs:219:9:221:9 | {...} |
| Finally.cs:219:9:221:9 | {...} | Finally.cs:220:13:220:37 | ...; |
| Finally.cs:220:13:220:37 | ...; | Finally.cs:220:31:220:35 | "Try" |
| Finally.cs:220:31:220:35 | "Try" | Finally.cs:220:13:220:36 | call to method WriteLine |
| Finally.cs:220:31:220:35 | "Try" | Finally.cs:222:9:225:9 | catch {...} |
| Finally.cs:222:9:225:9 | catch {...} | Finally.cs:223:9:225:9 | {...} |
| Finally.cs:223:9:225:9 | {...} | Finally.cs:224:13:224:39 | ...; |
| Finally.cs:224:13:224:39 | ...; | Finally.cs:224:31:224:37 | "Catch" |
| Finally.cs:224:31:224:37 | "Catch" | Finally.cs:224:13:224:38 | call to method WriteLine |
| Finally.cs:227:9:229:9 | {...} | Finally.cs:228:13:228:41 | ...; |
| Finally.cs:228:13:228:40 | call to method WriteLine | Finally.cs:230:9:230:34 | ...; |
| Finally.cs:228:13:228:41 | ...; | Finally.cs:228:31:228:39 | "Finally" |
| Finally.cs:228:31:228:39 | "Finally" | Finally.cs:228:13:228:40 | call to method WriteLine |
| Finally.cs:230:9:230:33 | call to method WriteLine | Finally.cs:216:10:216:12 | exit M11 |
| Finally.cs:230:9:230:34 | ...; | Finally.cs:230:27:230:32 | "Done" |
| Finally.cs:230:27:230:32 | "Done" | Finally.cs:230:9:230:33 | call to method WriteLine |
| Foreach.cs:6:10:6:11 | enter M1 | Foreach.cs:7:5:10:5 | {...} |
| Foreach.cs:7:5:10:5 | {...} | Foreach.cs:8:29:8:32 | access to parameter args |
| Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | Foreach.cs:6:10:6:11 | exit M1 |
@@ -4515,6 +4533,24 @@ postDominance
| Finally.cs:213:9:213:24 | ... = ... | Finally.cs:213:22:213:24 | "1" |
| Finally.cs:213:9:213:25 | ...; | Finally.cs:211:13:211:28 | ... = ... |
| Finally.cs:213:22:213:24 | "1" | Finally.cs:213:9:213:12 | this access |
| Finally.cs:216:10:216:12 | exit M11 | Finally.cs:230:9:230:33 | call to method WriteLine |
| Finally.cs:217:5:231:5 | {...} | Finally.cs:216:10:216:12 | enter M11 |
| Finally.cs:218:9:229:9 | try {...} ... | Finally.cs:217:5:231:5 | {...} |
| Finally.cs:219:9:221:9 | {...} | Finally.cs:218:9:229:9 | try {...} ... |
| Finally.cs:220:13:220:37 | ...; | Finally.cs:219:9:221:9 | {...} |
| Finally.cs:220:31:220:35 | "Try" | Finally.cs:220:13:220:37 | ...; |
| Finally.cs:223:9:225:9 | {...} | Finally.cs:222:9:225:9 | catch {...} |
| Finally.cs:224:13:224:38 | call to method WriteLine | Finally.cs:224:31:224:37 | "Catch" |
| Finally.cs:224:13:224:39 | ...; | Finally.cs:223:9:225:9 | {...} |
| Finally.cs:224:31:224:37 | "Catch" | Finally.cs:224:13:224:39 | ...; |
| Finally.cs:227:9:229:9 | {...} | Finally.cs:220:13:220:36 | call to method WriteLine |
| Finally.cs:227:9:229:9 | {...} | Finally.cs:224:13:224:38 | call to method WriteLine |
| Finally.cs:228:13:228:40 | call to method WriteLine | Finally.cs:228:31:228:39 | "Finally" |
| Finally.cs:228:13:228:41 | ...; | Finally.cs:227:9:229:9 | {...} |
| Finally.cs:228:31:228:39 | "Finally" | Finally.cs:228:13:228:41 | ...; |
| Finally.cs:230:9:230:33 | call to method WriteLine | Finally.cs:230:27:230:32 | "Done" |
| Finally.cs:230:9:230:34 | ...; | Finally.cs:228:13:228:40 | call to method WriteLine |
| Finally.cs:230:27:230:32 | "Done" | Finally.cs:230:9:230:34 | ...; |
| Foreach.cs:6:10:6:11 | exit M1 | Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... |
| Foreach.cs:7:5:10:5 | {...} | Foreach.cs:6:10:6:11 | enter M1 |
| Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | Foreach.cs:8:29:8:32 | access to parameter args |
@@ -6943,6 +6979,13 @@ blockDominance
| Finally.cs:211:13:211:29 | ...; | Finally.cs:211:13:211:29 | ...; |
| Finally.cs:211:13:211:29 | [finally: exception(Exception)] ...; | Finally.cs:211:13:211:29 | [finally: exception(Exception)] ...; |
| Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; | Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; |
| Finally.cs:216:10:216:12 | enter M11 | Finally.cs:216:10:216:12 | enter M11 |
| Finally.cs:216:10:216:12 | enter M11 | Finally.cs:220:13:220:36 | call to method WriteLine |
| Finally.cs:216:10:216:12 | enter M11 | Finally.cs:222:9:225:9 | catch {...} |
| Finally.cs:216:10:216:12 | enter M11 | Finally.cs:227:9:229:9 | {...} |
| Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:220:13:220:36 | call to method WriteLine |
| Finally.cs:222:9:225:9 | catch {...} | Finally.cs:222:9:225:9 | catch {...} |
| Finally.cs:227:9:229:9 | {...} | Finally.cs:227:9:229:9 | {...} |
| Foreach.cs:6:10:6:11 | enter M1 | Foreach.cs:6:10:6:11 | enter M1 |
| Foreach.cs:6:10:6:11 | enter M1 | Foreach.cs:6:10:6:11 | exit M1 |
| Foreach.cs:6:10:6:11 | enter M1 | Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... |
@@ -8747,6 +8790,13 @@ postBlockDominance
| Finally.cs:211:13:211:29 | ...; | Finally.cs:211:13:211:29 | ...; |
| Finally.cs:211:13:211:29 | [finally: exception(Exception)] ...; | Finally.cs:211:13:211:29 | [finally: exception(Exception)] ...; |
| Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; | Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; |
| Finally.cs:216:10:216:12 | enter M11 | Finally.cs:216:10:216:12 | enter M11 |
| Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:220:13:220:36 | call to method WriteLine |
| Finally.cs:222:9:225:9 | catch {...} | Finally.cs:222:9:225:9 | catch {...} |
| Finally.cs:227:9:229:9 | {...} | Finally.cs:216:10:216:12 | enter M11 |
| Finally.cs:227:9:229:9 | {...} | Finally.cs:220:13:220:36 | call to method WriteLine |
| Finally.cs:227:9:229:9 | {...} | Finally.cs:222:9:225:9 | catch {...} |
| Finally.cs:227:9:229:9 | {...} | Finally.cs:227:9:229:9 | {...} |
| Foreach.cs:6:10:6:11 | enter M1 | Foreach.cs:6:10:6:11 | enter M1 |
| Foreach.cs:6:10:6:11 | exit M1 | Foreach.cs:6:10:6:11 | enter M1 |
| Foreach.cs:6:10:6:11 | exit M1 | Foreach.cs:6:10:6:11 | exit M1 |

View File

@@ -1742,6 +1742,26 @@ nodeEnclosing
| Finally.cs:213:9:213:24 | ... = ... | Finally.cs:195:10:195:12 | M10 |
| Finally.cs:213:9:213:25 | ...; | Finally.cs:195:10:195:12 | M10 |
| Finally.cs:213:22:213:24 | "1" | Finally.cs:195:10:195:12 | M10 |
| Finally.cs:216:10:216:12 | enter M11 | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:216:10:216:12 | exit M11 | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:217:5:231:5 | {...} | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:218:9:229:9 | try {...} ... | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:219:9:221:9 | {...} | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:220:13:220:37 | ...; | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:220:31:220:35 | "Try" | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:222:9:225:9 | catch {...} | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:223:9:225:9 | {...} | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:224:13:224:38 | call to method WriteLine | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:224:13:224:39 | ...; | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:224:31:224:37 | "Catch" | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:227:9:229:9 | {...} | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:228:13:228:40 | call to method WriteLine | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:228:13:228:41 | ...; | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:228:31:228:39 | "Finally" | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:230:9:230:33 | call to method WriteLine | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:230:9:230:34 | ...; | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:230:27:230:32 | "Done" | Finally.cs:216:10:216:12 | M11 |
| Foreach.cs:6:10:6:11 | enter M1 | Foreach.cs:6:10:6:11 | M1 |
| Foreach.cs:6:10:6:11 | exit M1 | Foreach.cs:6:10:6:11 | M1 |
| Foreach.cs:7:5:10:5 | {...} | Foreach.cs:6:10:6:11 | M1 |
@@ -3548,6 +3568,10 @@ blockEnclosing
| Finally.cs:211:13:211:29 | ...; | Finally.cs:195:10:195:12 | M10 |
| Finally.cs:211:13:211:29 | [finally: exception(Exception)] ...; | Finally.cs:195:10:195:12 | M10 |
| Finally.cs:211:13:211:29 | [finally: exception(ExceptionA)] ...; | Finally.cs:195:10:195:12 | M10 |
| Finally.cs:216:10:216:12 | enter M11 | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:222:9:225:9 | catch {...} | Finally.cs:216:10:216:12 | M11 |
| Finally.cs:227:9:229:9 | {...} | Finally.cs:216:10:216:12 | M11 |
| Foreach.cs:6:10:6:11 | enter M1 | Foreach.cs:6:10:6:11 | M1 |
| Foreach.cs:6:10:6:11 | exit M1 | Foreach.cs:6:10:6:11 | M1 |
| Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | Foreach.cs:6:10:6:11 | M1 |

View File

@@ -1169,6 +1169,24 @@
| Finally.cs:213:9:213:24 | ... = ... | Finally.cs:213:9:213:12 | this access |
| Finally.cs:213:9:213:25 | ...; | Finally.cs:213:9:213:25 | ...; |
| Finally.cs:213:22:213:24 | "1" | Finally.cs:213:22:213:24 | "1" |
| Finally.cs:217:5:231:5 | {...} | Finally.cs:217:5:231:5 | {...} |
| Finally.cs:218:9:229:9 | try {...} ... | Finally.cs:218:9:229:9 | try {...} ... |
| Finally.cs:219:9:221:9 | {...} | Finally.cs:219:9:221:9 | {...} |
| Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:220:31:220:35 | "Try" |
| Finally.cs:220:13:220:37 | ...; | Finally.cs:220:13:220:37 | ...; |
| Finally.cs:220:31:220:35 | "Try" | Finally.cs:220:31:220:35 | "Try" |
| Finally.cs:222:9:225:9 | catch {...} | Finally.cs:222:9:225:9 | catch {...} |
| Finally.cs:223:9:225:9 | {...} | Finally.cs:223:9:225:9 | {...} |
| Finally.cs:224:13:224:38 | call to method WriteLine | Finally.cs:224:31:224:37 | "Catch" |
| Finally.cs:224:13:224:39 | ...; | Finally.cs:224:13:224:39 | ...; |
| Finally.cs:224:31:224:37 | "Catch" | Finally.cs:224:31:224:37 | "Catch" |
| Finally.cs:227:9:229:9 | {...} | Finally.cs:227:9:229:9 | {...} |
| Finally.cs:228:13:228:40 | call to method WriteLine | Finally.cs:228:31:228:39 | "Finally" |
| Finally.cs:228:13:228:41 | ...; | Finally.cs:228:13:228:41 | ...; |
| Finally.cs:228:31:228:39 | "Finally" | Finally.cs:228:31:228:39 | "Finally" |
| Finally.cs:230:9:230:33 | call to method WriteLine | Finally.cs:230:27:230:32 | "Done" |
| Finally.cs:230:9:230:34 | ...; | Finally.cs:230:9:230:34 | ...; |
| Finally.cs:230:27:230:32 | "Done" | Finally.cs:230:27:230:32 | "Done" |
| Foreach.cs:7:5:10:5 | {...} | Foreach.cs:7:5:10:5 | {...} |
| Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | Foreach.cs:8:29:8:32 | access to parameter args |
| Foreach.cs:8:22:8:24 | String arg | Foreach.cs:8:22:8:24 | String arg |

View File

@@ -1652,6 +1652,31 @@
| Finally.cs:213:9:213:24 | ... = ... | Finally.cs:213:9:213:24 | ... = ... | normal |
| Finally.cs:213:9:213:25 | ...; | Finally.cs:213:9:213:24 | ... = ... | normal |
| Finally.cs:213:22:213:24 | "1" | Finally.cs:213:22:213:24 | "1" | normal |
| Finally.cs:217:5:231:5 | {...} | Finally.cs:230:9:230:33 | call to method WriteLine | normal |
| Finally.cs:218:9:229:9 | try {...} ... | Finally.cs:228:13:228:40 | call to method WriteLine | normal |
| Finally.cs:219:9:221:9 | {...} | Finally.cs:220:13:220:36 | call to method WriteLine | normal |
| Finally.cs:219:9:221:9 | {...} | Finally.cs:220:13:220:36 | call to method WriteLine | throw(Exception) |
| Finally.cs:219:9:221:9 | {...} | Finally.cs:220:31:220:35 | "Try" | throw(OutOfMemoryException) |
| Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:220:13:220:36 | call to method WriteLine | normal |
| Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:220:13:220:36 | call to method WriteLine | throw(Exception) |
| Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:220:31:220:35 | "Try" | throw(OutOfMemoryException) |
| Finally.cs:220:13:220:37 | ...; | Finally.cs:220:13:220:36 | call to method WriteLine | normal |
| Finally.cs:220:13:220:37 | ...; | Finally.cs:220:13:220:36 | call to method WriteLine | throw(Exception) |
| Finally.cs:220:13:220:37 | ...; | Finally.cs:220:31:220:35 | "Try" | throw(OutOfMemoryException) |
| Finally.cs:220:31:220:35 | "Try" | Finally.cs:220:31:220:35 | "Try" | normal |
| Finally.cs:220:31:220:35 | "Try" | Finally.cs:220:31:220:35 | "Try" | throw(OutOfMemoryException) |
| Finally.cs:222:9:225:9 | catch {...} | Finally.cs:224:13:224:38 | call to method WriteLine | normal |
| Finally.cs:223:9:225:9 | {...} | Finally.cs:224:13:224:38 | call to method WriteLine | normal |
| Finally.cs:224:13:224:38 | call to method WriteLine | Finally.cs:224:13:224:38 | call to method WriteLine | normal |
| Finally.cs:224:13:224:39 | ...; | Finally.cs:224:13:224:38 | call to method WriteLine | normal |
| Finally.cs:224:31:224:37 | "Catch" | Finally.cs:224:31:224:37 | "Catch" | normal |
| Finally.cs:227:9:229:9 | {...} | Finally.cs:228:13:228:40 | call to method WriteLine | normal |
| Finally.cs:228:13:228:40 | call to method WriteLine | Finally.cs:228:13:228:40 | call to method WriteLine | normal |
| Finally.cs:228:13:228:41 | ...; | Finally.cs:228:13:228:40 | call to method WriteLine | normal |
| Finally.cs:228:31:228:39 | "Finally" | Finally.cs:228:31:228:39 | "Finally" | normal |
| Finally.cs:230:9:230:33 | call to method WriteLine | Finally.cs:230:9:230:33 | call to method WriteLine | normal |
| Finally.cs:230:9:230:34 | ...; | Finally.cs:230:9:230:33 | call to method WriteLine | normal |
| Finally.cs:230:27:230:32 | "Done" | Finally.cs:230:27:230:32 | "Done" | normal |
| Foreach.cs:7:5:10:5 | {...} | Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | empty |
| Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | empty |
| Foreach.cs:8:22:8:24 | String arg | Foreach.cs:8:22:8:24 | String arg | normal |

View File

@@ -212,4 +212,21 @@ public class Finally
}
this.Field = "1";
}
void M11()
{
try
{
Console.WriteLine("Try");
}
catch
{
Console.WriteLine("Catch");
}
finally
{
Console.WriteLine("Finally");
}
Console.WriteLine("Done");
}
}

View File

@@ -1818,6 +1818,27 @@
| Finally.cs:213:9:213:24 | ... = ... | Finally.cs:195:10:195:12 | exit M10 | semmle.label | successor |
| Finally.cs:213:9:213:25 | ...; | Finally.cs:213:9:213:12 | this access | semmle.label | successor |
| Finally.cs:213:22:213:24 | "1" | Finally.cs:213:9:213:24 | ... = ... | semmle.label | successor |
| Finally.cs:216:10:216:12 | enter M11 | Finally.cs:217:5:231:5 | {...} | semmle.label | successor |
| Finally.cs:217:5:231:5 | {...} | Finally.cs:218:9:229:9 | try {...} ... | semmle.label | successor |
| Finally.cs:218:9:229:9 | try {...} ... | Finally.cs:219:9:221:9 | {...} | semmle.label | successor |
| Finally.cs:219:9:221:9 | {...} | Finally.cs:220:13:220:37 | ...; | semmle.label | successor |
| Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:222:9:225:9 | catch {...} | semmle.label | exception(Exception) |
| Finally.cs:220:13:220:36 | call to method WriteLine | Finally.cs:227:9:229:9 | {...} | semmle.label | successor |
| Finally.cs:220:13:220:37 | ...; | Finally.cs:220:31:220:35 | "Try" | semmle.label | successor |
| Finally.cs:220:31:220:35 | "Try" | Finally.cs:220:13:220:36 | call to method WriteLine | semmle.label | successor |
| Finally.cs:220:31:220:35 | "Try" | Finally.cs:222:9:225:9 | catch {...} | semmle.label | exception(OutOfMemoryException) |
| Finally.cs:222:9:225:9 | catch {...} | Finally.cs:223:9:225:9 | {...} | semmle.label | successor |
| Finally.cs:223:9:225:9 | {...} | Finally.cs:224:13:224:39 | ...; | semmle.label | successor |
| Finally.cs:224:13:224:38 | call to method WriteLine | Finally.cs:227:9:229:9 | {...} | semmle.label | successor |
| Finally.cs:224:13:224:39 | ...; | Finally.cs:224:31:224:37 | "Catch" | semmle.label | successor |
| Finally.cs:224:31:224:37 | "Catch" | Finally.cs:224:13:224:38 | call to method WriteLine | semmle.label | successor |
| Finally.cs:227:9:229:9 | {...} | Finally.cs:228:13:228:41 | ...; | semmle.label | successor |
| Finally.cs:228:13:228:40 | call to method WriteLine | Finally.cs:230:9:230:34 | ...; | semmle.label | successor |
| Finally.cs:228:13:228:41 | ...; | Finally.cs:228:31:228:39 | "Finally" | semmle.label | successor |
| Finally.cs:228:31:228:39 | "Finally" | Finally.cs:228:13:228:40 | call to method WriteLine | semmle.label | successor |
| Finally.cs:230:9:230:33 | call to method WriteLine | Finally.cs:216:10:216:12 | exit M11 | semmle.label | successor |
| Finally.cs:230:9:230:34 | ...; | Finally.cs:230:27:230:32 | "Done" | semmle.label | successor |
| Finally.cs:230:27:230:32 | "Done" | Finally.cs:230:9:230:33 | call to method WriteLine | semmle.label | successor |
| Foreach.cs:6:10:6:11 | enter M1 | Foreach.cs:7:5:10:5 | {...} | semmle.label | successor |
| Foreach.cs:7:5:10:5 | {...} | Foreach.cs:8:29:8:32 | access to parameter args | semmle.label | successor |
| Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | Foreach.cs:6:10:6:11 | exit M1 | semmle.label | empty |

View File

@@ -710,6 +710,7 @@ entryPoint
| Finally.cs:147:10:147:11 | M8 | Finally.cs:148:5:170:5 | {...} |
| Finally.cs:176:10:176:11 | M9 | Finally.cs:177:5:193:5 | {...} |
| Finally.cs:195:10:195:12 | M10 | Finally.cs:196:5:214:5 | {...} |
| Finally.cs:216:10:216:12 | M11 | Finally.cs:217:5:231:5 | {...} |
| Foreach.cs:6:10:6:11 | M1 | Foreach.cs:7:5:10:5 | {...} |
| Foreach.cs:12:10:12:11 | M2 | Foreach.cs:13:5:16:5 | {...} |
| Foreach.cs:18:10:18:11 | M3 | Foreach.cs:19:5:22:5 | {...} |

View File

@@ -104,7 +104,7 @@ generates html slide shows in the ``<slides-output>`` directory when run from
the ``ql-training`` source directory.
For more information about creating slides for QL training and variant analysis
examples, see the `template slide deck <https://github.com/Semmle/ql/blob/master/docs/language/ql-training/template.rst>`__.
examples, see the `template slide deck <https://github.com/github/codeql/blob/master/docs/language/ql-training/template.rst>`__.
Viewing the current version of the CodeQL documentation
*******************************************************

View File

@@ -44,7 +44,7 @@ class QLLexer(RegexLexer):
'max', 'min', 'module', 'newtype', 'not', 'none', 'or', 'order',
'predicate', 'rank', 'result', 'select', 'strictconcat',
'strictcount', 'strictsum', 'sum', 'super', 'then', 'this',
'true', 'where'), prefix=r'\b', suffix=r'\b'),
'true', 'unique', 'where'), prefix=r'\b', suffix=r'\b'),
Keyword),
# Identifiers
(r'@?\w', Name),

View File

@@ -139,6 +139,10 @@ Global data flow
Global data flow tracks data flow throughout the entire program, and is therefore more powerful than local data flow. However, global data flow is less precise than local data flow, and the analysis typically requires significantly more time and memory to perform.
.. pull-quote:: Note
.. include:: ../../reusables/path-problem.rst
Using global data flow
~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -137,6 +137,10 @@ Global data flow
Global data flow tracks data flow throughout the entire program, and is therefore more powerful than local data flow. However, global data flow is less precise than local data flow, and the analysis typically requires significantly more time and memory to perform.
.. pull-quote:: Note
.. include:: ../../reusables/path-problem.rst
Using global data flow
~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -1,33 +0,0 @@
What's in a CodeQL database?
============================
A CodeQL database contains a variety of data related to a particular code base at a particular point in time. For details of how the database is generated see `Database generation <https://lgtm.com/help/lgtm/generate-database>`__ on LGTM.com.
The database contains a full, hierarchical representation of the program defined by the code base. The database schema varies according to the language analyzed. The schema provides an interface between the initial lexical analysis during the extraction process, and the actual complex analysis using CodeQL. When the source code languages being analyzed change (such as Java 7 evolving into Java 8), this interface between the analysis phases can also change.
For each language, a CodeQL library defines classes to provide a layer of abstraction over the database tables. This provides an object-oriented view of the data which makes it easier to write queries. This is easiest to explain using an example.
Example
-------
For a Java program, two key tables are:
- The ``expressions`` table containing a row for every single expression in the source code that was analyzed during the build process.
- The ``statements`` table containing a row for every single statement in the source code that was analyzed during the build process.
The CodeQL library defines classes to provide a layer of abstraction over each of these tables (and the related auxiliary tables): ``Expr`` and ``Stmt``.
Most classes in the library are similar: they are abstractions over one or more database tables. Looking at one of the libraries illustrates this:
.. code-block:: ql
class Expr extends StmtParent, @expr {
...
/** the location of this expression */
Location getLocation() { exprs(this,_,_,result) }
...
}
The ``Expr`` class, shown here, extends from the database type ``@expr``. Member predicates of the ``Expr`` class are implemented in terms of the database-provided ``exprs`` table.

View File

@@ -15,5 +15,6 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat
Further reading
---------------
- For examples of how to query common Go elements, see the `Go cookbook <https://help.semmle.com/wiki/display/CBGO>`__.
- For the queries used in LGTM, display a `Go query <https://lgtm.com/search?q=language%3Ago&t=rules>`__ and click **Open in query console** to see the code used to find alerts.
- For more information about the library for Go see the `CodeQL library for Go <https://help.semmle.com/qldoc/go/>`__.

View File

@@ -3,7 +3,7 @@ Learning CodeQL
CodeQL is the code analysis platform used by security researchers to automate variant analysis.
You can use CodeQL queries to explore code and quickly find variants of security vulnerabilities and bugs.
These queries are easy to write and sharevisit the topics below and `our open source repository on GitHub <https://github.com/Semmle/ql>`__ to learn more.
These queries are easy to write and sharevisit the topics below and `our open source repository on GitHub <https://github.com/github/codeql>`__ to learn more.
You can also try out CodeQL in the `query console on LGTM.com <https://lgtm.com/query>`__.
Here, you can query open source projects directly, without having to download CodeQL databases and libraries.
@@ -27,7 +27,6 @@ CodeQL is based on a powerful query language called QL. The following topics hel
javascript/ql-for-javascript
python/ql-for-python
ql-training
technical-info
.. toctree::
:hidden:

View File

@@ -147,6 +147,10 @@ Global data flow
Global data flow tracks data flow throughout the entire program, and is therefore more powerful than local data flow. However, global data flow is less precise than local data flow, and the analysis typically requires significantly more time and memory to perform.
.. pull-quote:: Note
.. include:: ../../reusables/path-problem.rst
Using global data flow
~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -188,6 +188,10 @@ Global data flow tracks data flow throughout the entire program, and is therefor
than local data flow. That is, the analysis may report spurious flows that cannot in fact happen. Moreover, global data flow analysis typically requires significantly
more time and memory than local analysis.
.. pull-quote:: Note
.. include:: ../../reusables/path-problem.rst
Using global data flow
~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -30,6 +30,6 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat
Further reading
---------------
- For examples of how to query common Python elements, see the `JavaScript cookbook <https://help.semmle.com/wiki/display/CBPython>`__.
- For examples of how to query common Python elements, see the `Python cookbook <https://help.semmle.com/wiki/display/CBPython>`__.
- For the queries used in LGTM, display a `Python query <https://lgtm.com/search?q=language%3APython&t=rules>`__ and click **Open in query console** to see the code used to find alerts.
- For more information about the library for JavaScript see the `CodeQL library for Python <https://help.semmle.com/qldoc/python/>`__.

View File

@@ -1,9 +0,0 @@
Technical information
=====================
.. toctree::
:hidden:
database
- :doc:`What's in a CodeQL database? <database>`

View File

@@ -18,10 +18,10 @@ Previously we used the term QL to refer to the whole code analysis platform, whi
The name QL now only refers to the query language that powers CodeQL analysis.
The CodeQL queries and libraries used to analyze source code are written in QL.
These queries and libraries are open source, and can be found in the `CodeQL repository <https://github.com/semmle/ql>`__.
These queries and libraries are open source, and can be found in the `CodeQL repository <https://github.com/github/codeql>`__.
QL is a general-purpose, object-oriented language that can be used to query any kind of data.
CodeQL databases
----------------
QL snapshots have been renamed CodeQL databases. :doc:`CodeQL databases <database>` contain relational data created and analyzed using CodeQL. They are the equivalent of QL snapshots, but have been optimized for use with the CodeQL tools.
QL snapshots have been renamed CodeQL databases. `CodeQL databases <https://help.semmle.com/codeql/about-codeql.html#about-codeql-databases>`__ contain relational data created and analyzed using CodeQL. They are the equivalent of QL snapshots, but have been optimized for use with the CodeQL tools.

View File

@@ -12,7 +12,7 @@ CodeQL includes queries to find the most relevant and interesting problems for e
- **Path queries**: queries that describe the flow of information between a source and a sink in your code.
- **Metric queries**: queries that compute statistics for your code.
You can add custom queries to `custom query packs <https://lgtm.com/help/lgtm/about-queries#what-are-query-packs>`__ to analyze your projects in `LGTM <https://lgtm.com>`__, use them to analyze a database with the `CodeQL CLI <https://help.semmle.com/codeql/codeql-cli.html>`__, or you can contribute to the standard CodeQL queries in our `open source repository on GitHub <https://github.com/semmle/ql>`__.
You can add custom queries to `custom query packs <https://lgtm.com/help/lgtm/about-queries#what-are-query-packs>`__ to analyze your projects in `LGTM <https://lgtm.com>`__, use them to analyze a database with the `CodeQL CLI <https://help.semmle.com/codeql/codeql-cli.html>`__, or you can contribute to the standard CodeQL queries in our `open source repository on GitHub <https://github.com/github/codeql>`__.
.. pull-quote::
@@ -24,7 +24,7 @@ You can add custom queries to `custom query packs <https://lgtm.com/help/lgtm/ab
This topic is a basic introduction to query files. You can find more information on writing queries for specific programming languages `here <https://help.semmle.com/QL/learn-ql/>`__, and detailed technical information about QL in the `QL language reference <https://help.semmle.com/QL/ql-handbook/index.html>`__.
For more information on how to format your code when contributing queries to the GitHub repository, see the `CodeQL style guide <https://github.com/Semmle/ql/blob/master/docs/ql-style-guide.md>`__.
For more information on how to format your code when contributing queries to the GitHub repository, see the `CodeQL style guide <https://github.com/github/codeql/blob/master/docs/ql-style-guide.md>`__.
Basic query structure
*********************
@@ -52,7 +52,7 @@ Query metadata
Query metadata is used to identify your custom queries when they are added to the GitHub repository or used in your analysis. Metadata provides information about the query's purpose, and also specifies how to interpret and display the query results. For a full list of metadata properties, see the :doc:`query metadata reference <query-metadata>`. The exact metadata requirement depends on how you are going to run your query:
- If you are contributing a query to the GitHub repository, please read the `query metadata style guide <https://github.com/Semmle/ql/blob/master/docs/query-metadata-style-guide.md#metadata-area>`__.
- If you are contributing a query to the GitHub repository, please read the `query metadata style guide <https://github.com/github/codeql/blob/master/docs/query-metadata-style-guide.md#metadata-area>`__.
- If you are adding a custom query to a query pack for analysis using LGTM , see `Writing custom queries to include in LGTM analysis <https://lgtm.com/help/lgtm/writing-custom-queries>`__.
- If you are analyzing a database using the `CodeQL CLI <https://help.semmle.com/codeql/codeql-cli.html>`__, your query metadata must contain ``@kind``.
- If you are running a query in the query console on LGTM or with the CodeQL extension for VS Code, metadata is not mandatory. However, if you want your results to be displayed as either an 'alert' or a 'path', you must specify the correct ``@kind`` property, as explained below. For more information, see `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__ on LGTM.com and `Using the extension <https://help.semmle.com/codeql/codeql-for-vscode/procedures/using-extension.html>`__ in the CodeQL for VS Code help.
@@ -73,7 +73,7 @@ Import statements
=================
Each query generally contains one or more ``import`` statements, which define the `libraries <https://help.semmle.com/QL/ql-handbook/modules.html#library-modules>`__ or `modules <https://help.semmle.com/QL/ql-handbook/modules.html>`__ to import into the query. Libraries and modules provide a way of grouping together related `types <https://help.semmle.com/QL/ql-handbook/types.html>`__, `predicates <https://help.semmle.com/QL/ql-handbook/predicates.html>`__, and other modules. The contents of each library or module that you import can then be accessed by the query.
Our `open source repository on GitHub <https://github.com/semmle/ql>`__ contains the standard CodeQL libraries for each supported language.
Our `open source repository on GitHub <https://github.com/github/codeql>`__ contains the standard CodeQL libraries for each supported language.
When writing your own alert queries, you would typically import the standard library for the language of the project that you are querying, using ``import`` followed by a language:
@@ -86,7 +86,7 @@ When writing your own alert queries, you would typically import the standard lib
There are also libraries containing commonly used predicates, types, and other modules associated with different analyses, including data flow, control flow, and taint-tracking. In order to calculate path graphs, path queries require you to import a data flow library into the query file. For more information, see :doc:`Creating path queries <path-queries>`.
You can explore the contents of all the standard libraries in the `CodeQL library reference documentation <https://help.semmle.com/QL/ql-libraries.html>`__ or in the `GitHub repository <https://github.com/semmle/ql>`__.
You can explore the contents of all the standard libraries in the `CodeQL library reference documentation <https://help.semmle.com/QL/ql-libraries.html>`__ or in the `GitHub repository <https://github.com/github/codeql>`__.
Optional CodeQL classes and predicates
--------------------------------------
@@ -131,25 +131,25 @@ Select clauses for metric queries (``@kind metric``) consist of two 'columns', w
Viewing the standard CodeQL queries
***********************************
One of the easiest ways to get started writing your own queries is to modify an existing query. To view the standard CodeQL queries, or to try out other examples, visit the `CodeQL <https://github.com/semmle/ql>`__ and `CodeQL for Go <https://github.com/github/codeql-go>`__ repositories on GitHub.
One of the easiest ways to get started writing your own queries is to modify an existing query. To view the standard CodeQL queries, or to try out other examples, visit the `CodeQL <https://github.com/github/codeql>`__ and `CodeQL for Go <https://github.com/github/codeql-go>`__ repositories on GitHub.
You can also find examples of queries developed to find security vulnerabilities and bugs in open source software projects on the `GitHub Security Lab website <https://securitylab.github.com/research>`__ and in the associated `repository <https://github.com/github/security-lab>`__.
Contributing queries
********************
Contributions to the standard queries and libraries are very welcome. For more information, see our `contributing guidelines <https://github.com/Semmle/ql/blob/master/CONTRIBUTING.md>`__.
Contributions to the standard queries and libraries are very welcome. For more information, see our `contributing guidelines <https://github.com/github/codeql/blob/master/CONTRIBUTING.md>`__.
If you are contributing a query to the open source GitHub repository, writing a custom query for LGTM, or using a custom query in an analysis with the CodeQL CLI, then you need to include extra metadata in your query to ensure that the query results are interpreted and displayed correctly. See the following topics for more information on query metadata:
- :doc:`Metadata for CodeQL queries <query-metadata>`
- `Query metadata style guide on GitHub <https://github.com/Semmle/ql/blob/master/docs/query-metadata-style-guide.md>`__
- `Query metadata style guide on GitHub <https://github.com/github/codeql/blob/master/docs/query-metadata-style-guide.md>`__
Query contributions to the open source GitHub repository may also have an accompanying query help file to provide information about their purpose for other users. For more information on writing query help, see the `Query help style guide on GitHub <https://github.com/Semmle/ql/blob/master/docs/query-help-style-guide.md>`__ and the :doc:`Query help files <query-help>`.
Query contributions to the open source GitHub repository may also have an accompanying query help file to provide information about their purpose for other users. For more information on writing query help, see the `Query help style guide on GitHub <https://github.com/github/codeql/blob/master/docs/query-help-style-guide.md>`__ and the :doc:`Query help files <query-help>`.
Query help files
****************
When you write a custom query, we also recommend that you write a query help file to explain the purpose of the query to other users. For more information, see the `Query help style guide <https://github.com/Semmle/ql/blob/master/docs/query-help-style-guide.md>`__ on GitHub, and the :doc:`Query help files <query-help>`.
When you write a custom query, we also recommend that you write a query help file to explain the purpose of the query to other users. For more information, see the `Query help style guide <https://github.com/github/codeql/blob/master/docs/query-help-style-guide.md>`__ on GitHub, and the :doc:`Query help files <query-help>`.
What next?
==========

View File

@@ -4,7 +4,7 @@ Query help files
Query help files tell users the purpose of a query, and recommend how to solve the potential problem the query finds.
This topic provides detailed information on the structure of query help files.
For more information about how to write useful query help in a style that is consistent with the standard CodeQL queries, see the `Query help style guide <https://github.com/Semmle/ql/blob/master/docs/query-help-style-guide.md>`__ on GitHub.
For more information about how to write useful query help in a style that is consistent with the standard CodeQL queries, see the `Query help style guide <https://github.com/github/codeql/blob/master/docs/query-help-style-guide.md>`__ on GitHub.
.. pull-quote::
@@ -12,8 +12,8 @@ For more information about how to write useful query help in a style that is con
Note
You can access the query help for CodeQL queries by visiting the `Built-in query pages <https://help.semmle.com/wiki/display/QL/Built-in+queries>`__.
You can also access the raw query help files in the `GitHub repository <https://github.com/semmle/ql>`__.
For example, see the `JavaScript security queries <https://github.com/Semmle/ql/tree/master/javascript/ql/src/Security>`__ and `C/C++ critical queries <https://github.com/Semmle/ql/tree/master/cpp/ql/src/Critical>`__.
You can also access the raw query help files in the `GitHub repository <https://github.com/github/codeql>`__.
For example, see the `JavaScript security queries <https://github.com/github/codeql/tree/master/javascript/ql/src/Security>`__ and `C/C++ critical queries <https://github.com/github/codeql/tree/master/cpp/ql/src/Critical>`__.
For queries run by default on LGTM, there are several different ways to access the query help. For further information, see `Where do I see the query help for a query on LGTM? <https://lgtm.com/help/lgtm/query-help#where-query-help-in-lgtm>`__ in the LGTM user help.
@@ -169,7 +169,7 @@ The ``include`` element can be used as a section or block element. The content
Section-level include elements
------------------------------
Section-level ``include`` elements can be located beneath the top-level ``qhelp`` element. For example, in `StoredXSS.qhelp <https://github.com/Semmle/ql/blob/master/csharp/ql/src/Security%20Features/CWE-079/StoredXSS.qhelp>`__, a full query help file is reused:
Section-level ``include`` elements can be located beneath the top-level ``qhelp`` element. For example, in `StoredXSS.qhelp <https://github.com/github/codeql/blob/master/csharp/ql/src/Security%20Features/CWE-079/StoredXSS.qhelp>`__, a full query help file is reused:
.. code-block:: xml
@@ -177,12 +177,12 @@ Section-level ``include`` elements can be located beneath the top-level ``qhelp`
<include src="XSS.qhelp" />
</qhelp>
In this example, the `XSS.qhelp <https://github.com/Semmle/ql/blob/master/csharp/ql/src/Security%20Features/CWE-079/XSS.qhelp>`__ file must conform to the standard for a full query help file as described above. That is, the ``qhelp`` element may only contain non-``fragment``, section-level elements.
In this example, the `XSS.qhelp <https://github.com/github/codeql/blob/master/csharp/ql/src/Security%20Features/CWE-079/XSS.qhelp>`__ file must conform to the standard for a full query help file as described above. That is, the ``qhelp`` element may only contain non-``fragment``, section-level elements.
Block-level include elements
----------------------------
Block-level ``include`` elements can be included beneath section-level elements. For example, an ``include`` element is used beneath the ``overview`` section in `ThreadUnsafeICryptoTransform.qhelp <https://github.com/Semmle/ql/blob/master/csharp/ql/src/Likely%20Bugs/ThreadUnsafeICryptoTransform.qhelp>`__:
Block-level ``include`` elements can be included beneath section-level elements. For example, an ``include`` element is used beneath the ``overview`` section in `ThreadUnsafeICryptoTransform.qhelp <https://github.com/github/codeql/blob/master/csharp/ql/src/Likely%20Bugs/ThreadUnsafeICryptoTransform.qhelp>`__:
.. code-block:: xml
@@ -193,7 +193,7 @@ Block-level ``include`` elements can be included beneath section-level elements.
...
</qhelp>
The included file, `ThreadUnsafeICryptoTransformOverview.qhelp <https://github.com/Semmle/ql/blob/master/csharp/ql/src/Likely%20Bugs/ThreadUnsafeICryptoTransformOverview.qhelp>`_, may only contain one or more ``fragment`` sections. For example:
The included file, `ThreadUnsafeICryptoTransformOverview.qhelp <https://github.com/github/codeql/blob/master/csharp/ql/src/Likely%20Bugs/ThreadUnsafeICryptoTransformOverview.qhelp>`_, may only contain one or more ``fragment`` sections. For example:
.. code-block:: xml
@@ -209,5 +209,5 @@ The included file, `ThreadUnsafeICryptoTransformOverview.qhelp <https://github.
Further information
===================
- To learn more about contributing to the standard CodeQL queries and libraries, see our `Contributing guidelines <https://github.com/Semmle/ql/blob/master/CONTRIBUTING.md>`__ on GitHub.
- To learn more about contributing to the standard CodeQL queries and libraries, see our `Contributing guidelines <https://github.com/github/codeql/blob/master/CONTRIBUTING.md>`__ on GitHub.
- To learn more about writing custom queries, and how to format your code for clarity and consistency, see `Writing CodeQL queries <https://help.semmle.com/QL/learn-ql/writing-queries/writing-queries.html>`__.

View File

@@ -8,7 +8,7 @@ About query metadata
Any query that is run as part of an analysis includes a number of properties, known as query metadata. Metadata is included at the top of each query file as the content of a `QLDoc <https://help.semmle.com/QL/ql-spec/qldoc.html>`__ comment.
For alerts and path queries, this metadata tells LGTM and the CodeQL `extension for VS Code <https://help.semmle.com/codeql/codeql-for-vscode.html>`__ how to handle the query and display its results correctly.
It also gives other users information about what the query results mean. For further information on query metadata, see the `query metadata style guide <https://github.com/Semmle/ql/blob/master/docs/query-metadata-style-guide.md#metadata-area>`__ in our `open source repository <https://github.com/semmle/ql>`__ on GitHub.
It also gives other users information about what the query results mean. For further information on query metadata, see the `query metadata style guide <https://github.com/github/codeql/blob/master/docs/query-metadata-style-guide.md#metadata-area>`__ in our `open source repository <https://github.com/github/codeql>`__ on GitHub.
You can also add metric queries to LGTM, but the results are not shown. To see the results of metric queries, you can run them in the query console or in `Visual Studio Code <https://help.semmle.com/codeql/codeql-for-vscode.html>`__.
.. pull-quote::
@@ -98,7 +98,7 @@ Here is the metadata for one of the standard Java queries:
.. |image0| image:: ../../images/query-metadata.png
For more examples of query metadata, see the standard CodeQL queries in our `GitHub repository <https://github.com/semmle/ql>`__.
For more examples of query metadata, see the standard CodeQL queries in our `GitHub repository <https://github.com/github/codeql>`__.

View File

@@ -385,7 +385,7 @@ Algebraic datatypes
*******************
.. note:: The syntax for algebraic datatypes is considered experimental and is subject to
change. However, they appear in the `standard QL libraries <https://github.com/Semmle/ql>`_
change. However, they appear in the `standard QL libraries <https://github.com/github/codeql>`_
so the following sections should help you understand those examples.
An algebraic datatype is another form of user-defined type, declared with the keyword ``newtype``.

View File

@@ -65,6 +65,6 @@ Entity types are rarely used directly, the usual pattern is to define a class th
For example, the database schemas for C/++, C#, and Java CodeQL databases are here:
- https://github.com/Semmle/ql/blob/master/cpp/ql/src/semmlecode.cpp.dbscheme
- https://github.com/Semmle/ql/blob/master/csharp/ql/src/semmlecode.csharp.dbscheme
- https://github.com/Semmle/ql/blob/master/java/ql/src/config/semmlecode.dbscheme
- https://github.com/github/codeql/blob/master/cpp/ql/src/semmlecode.cpp.dbscheme
- https://github.com/github/codeql/blob/master/csharp/ql/src/semmlecode.csharp.dbscheme
- https://github.com/github/codeql/blob/master/java/ql/src/config/semmlecode.dbscheme

View File

@@ -103,9 +103,9 @@ Analysis overview
CodeQL analysis works by extracting a queryable database from your project. For compiled languages, the tools observe an ordinary build of the source code. Each time a compiler is invoked to process a source file, a copy of that file is made, and all relevant information about the source code (syntactic data about the abstract syntax tree, semantic data like name binding and type information, data on the operation of the C preprocessor, etc.) is collected. For interpreted languages, the extractor gathers similar information by running directly on the source code. Multi-language code bases are analyzed one language at a time.
Once the extraction finishes, all this information is collected into a single `CodeQL database <https://help.semmle.com/QL/learn-ql/database.html>`__, which is then ready to query, possibly on a different machine. A copy of the source files, made at the time the database was created, is also included in the CodeQL database so analysis results can be displayed at the correct location in the code. The database schema is (source) language specific.
Once the extraction finishes, all this information is collected into a single `CodeQL database <https://help.semmle.com/codeql/about-codeql.html#about-codeql-databases>`__, which is then ready to query, possibly on a different machine. A copy of the source files, made at the time the database was created, is also included in the CodeQL database so analysis results can be displayed at the correct location in the code. The database schema is (source) language specific.
Queries are written in QL and usually depend on one or more of the `standard CodeQL libraries <https://github.com/semmle/ql>`__ (and of course you can write your own custom libraries). They are compiled into an efficiently executable format by the QL compiler and then run on a CodeQL database by the QL evaluator, either on a remote worker machine or locally on a developers machine.
Queries are written in QL and usually depend on one or more of the `standard CodeQL libraries <https://github.com/github/codeql>`__ (and of course you can write your own custom libraries). They are compiled into an efficiently executable format by the QL compiler and then run on a CodeQL database by the QL evaluator, either on a remote worker machine or locally on a developers machine.
Query results can be interpreted and presented in a variety of ways, including displaying them in an `IDE extension <https://lgtm.com/help/lgtm/running-queries-ide>`__ such as CodeQL for Visual Studio Code, or in a web dashboard as on `LGTM <https://lgtm.com/help/lgtm/about-lgtm>`__.
@@ -129,7 +129,7 @@ QL is:
- All common logic connectives are available, including quantifiers like ``exist``, which can also introduce new variables.
- The language is declarativethe user focuses on stating what they would like to find, and leaves the details of how to evaluate the query to the engine.
- The object-oriented layer allows us to develop rich standard libraries for program analysis. These model the common AST node types, control flow and name lookup, and define further layers on topfor example control flow or data flow analysis. The `standard CodeQL libraries and queries <https://github.com/semmle/ql>`__ ship as source and can be inspected by the user, and new abstractions are readily defined.
- The object-oriented layer allows us to develop rich standard libraries for program analysis. These model the common AST node types, control flow and name lookup, and define further layers on topfor example control flow or data flow analysis. The `standard CodeQL libraries and queries <https://github.com/github/codeql>`__ ship as source and can be inspected by the user, and new abstractions are readily defined.
- The database generated by the CodeQL tools is treated as read-only; queries cannot insert new data into it, though they can inspect its contents in various ways.
You can start writing running queries on open source projects in the `query console <https://lgtm.com/query>`__ on LGTM.com. You can also download CodeQL databases from LGTM.com to query locally, by `running queries in your IDE <https://lgtm.com/help/lgtm/running-queries-ide>`__.

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