mirror of
https://github.com/github/codeql.git
synced 2025-12-21 19:26:31 +01:00
Merge branch 'master' into python-improve-file-taint
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -21,4 +21,3 @@
|
|||||||
/codeql/
|
/codeql/
|
||||||
|
|
||||||
csharp/extractor/Semmle.Extraction.CSharp.Driver/Properties/launchSettings.json
|
csharp/extractor/Semmle.Extraction.CSharp.Driver/Properties/launchSettings.json
|
||||||
.vscode
|
|
||||||
|
|||||||
1
.vscode/.gitattributes
vendored
Normal file
1
.vscode/.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*.json linguist-language=JSON-with-Comments
|
||||||
10
.vscode/extensions.json
vendored
Normal file
10
.vscode/extensions.json
vendored
Normal 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
27
.vscode/tasks.json
vendored
Normal 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": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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:
|
## Our Standards
|
||||||
* Be friendly and patient: Remember you might not be communicating in someone else’s 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, people’s 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.
|
|
||||||
|
|
||||||
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
|
## Enforcement Responsibilities
|
||||||
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.
|
|
||||||
|
|
||||||
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.
|
||||||
|
|||||||
@@ -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`
|
* Python: `python/ql/src`
|
||||||
|
|
||||||
Each language-specific directory contains further subdirectories that group queries based on their `@tags` or purpose.
|
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.
|
- 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.
|
- 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**
|
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**
|
4. **Compilation**
|
||||||
|
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -9,8 +9,20 @@ You can use the [interactive query console](https://lgtm.com/help/lgtm/using-que
|
|||||||
|
|
||||||
## Contributing
|
## 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
|
## License
|
||||||
|
|
||||||
The code in this repository is licensed under the [MIT License](LICENSE) by [GitHub](https://github.com).
|
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.
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ The following changes in version 1.24 affect C/C++ analysis in all applications.
|
|||||||
|
|
||||||
## General improvements
|
## General improvements
|
||||||
|
|
||||||
|
You can now suppress alerts using either single-line block comments (`/* ... */`) or line comments (`// ...`).
|
||||||
|
|
||||||
## New queries
|
## New queries
|
||||||
|
|
||||||
| **Query** | **Tags** | **Purpose** |
|
| **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
|
## 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** |
|
| **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. |
|
| 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 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. |
|
| 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. |
|
| 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 | Functions containing `asm` statements are no longer highlighted by this query. |
|
| 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. |
|
||||||
| 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 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. |
|
||||||
| 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. |
|
| 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. |
|
||||||
| 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. |
|
|
||||||
| 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. |
|
| 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. |
|
| 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`. |
|
| 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
|
## 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 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
|
- 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.
|
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.
|
* The security pack taint tracking library
|
||||||
* 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.
|
(`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`
|
* The new class `StackVariable` should be used in place of `LocalScopeVariable`
|
||||||
in most cases. The difference is that `StackVariable` does not include
|
in most cases. The difference is that `StackVariable` does not include
|
||||||
variables declared with `static` or `thread_local`.
|
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.
|
about the _name or scope_ of variables should remain unchanged.
|
||||||
* The `LocalScopeVariableReachability` library is deprecated in favor of
|
* The `LocalScopeVariableReachability` library is deprecated in favor of
|
||||||
`StackVariableReachability`. The functionality is the same.
|
`StackVariableReachability`. The functionality is the same.
|
||||||
* The models library models `strlen` in more detail, and includes common variations such as `wcslen`.
|
* Taint tracking and data flow now features better modeling of commonly-used
|
||||||
* The models library models `gets` and similar functions.
|
library functions:
|
||||||
* The models library now partially models `std::string`.
|
* `gets` and similar functions,
|
||||||
* The taint tracking library (`semmle.code.cpp.dataflow.TaintTracking`) has had
|
* the most common operations on `std::string`,
|
||||||
the following improvements:
|
* `strdup` and similar functions, and
|
||||||
* The library now models data flow through `strdup` and similar functions.
|
* formatting functions such as `sprintf`.
|
||||||
* 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.
|
|
||||||
|
|||||||
@@ -2,30 +2,31 @@
|
|||||||
|
|
||||||
The following changes in version 1.24 affect C# analysis in all applications.
|
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
|
## New queries
|
||||||
|
|
||||||
| **Query** | **Tags** | **Purpose** |
|
| **Query** | **Tags** | **Purpose** |
|
||||||
|-----------------------------|-----------|--------------------------------------------------------------------|
|
|-----------------------------|-----------|--------------------------------------------------------------------|
|
||||||
| Assembly path injection (`cs/assembly-path-injection`) | security, external/cwe/cwe-114 | Finds user-controlled data used to load an assembly. |
|
| 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. |
|
| 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. |
|
| 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. |
|
| 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. |
|
| 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. |
|
| 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
|
## Changes to existing queries
|
||||||
|
|
||||||
| **Query** | **Expected impact** | **Change** |
|
| **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`. |
|
| 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. |
|
| 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. |
|
||||||
|
| 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. |
|
||||||
## Removal of old queries
|
| 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
|
## 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:
|
* 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 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
|
- Track flow through clone-like methods, that is, methods that read the contents of a field from a
|
||||||
parameter and stores the value in the field of a returned object.
|
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.
|
* 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.
|
* [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()`.
|
* 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`.
|
* `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.
|
* 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.
|
||||||
|
|
||||||
## Changes to autobuilder
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ The following changes in version 1.24 affect Java analysis in all applications.
|
|||||||
|
|
||||||
## General improvements
|
## 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.
|
* A `Customizations.qll` file has been added to allow customizations of the standard library that apply to all queries.
|
||||||
|
|
||||||
## New queries
|
## New queries
|
||||||
@@ -21,9 +21,9 @@ The following changes in version 1.24 affect Java analysis in all applications.
|
|||||||
|
|
||||||
| **Query** | **Expected impact** | **Change** |
|
| **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. |
|
| 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 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`. |
|
| 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 positives | Useless checks on final fields with a non-null initializer are now reported. |
|
| 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
|
## 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
|
general file classification mechanism and thus suppression of alerts, and
|
||||||
also any security queries using taint tracking, as test classes act as
|
also any security queries using taint tracking, as test classes act as
|
||||||
default barriers stopping taint flow.
|
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
|
`ParExpr` class is empty. Instead, a parenthesized expression can be
|
||||||
identified with the `Expr.isParenthesized()` member predicate.
|
identified with the `Expr.isParenthesized()` member predicate.
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
* TypeScript 3.8 is now supported.
|
* 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:
|
* 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,
|
- 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 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:
|
* 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)
|
- [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-in](https://www.npmjs.com/package/for-in)
|
||||||
- [for-own](https://www.npmjs.com/package/for-own)
|
- [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)
|
- [http2](https://nodejs.org/api/http2.html)
|
||||||
- [jQuery](https://jquery.com/)
|
- [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)
|
- [lazy-cache](https://www.npmjs.com/package/lazy-cache)
|
||||||
- [mongodb](https://www.npmjs.com/package/mongodb)
|
- [mongodb](https://www.npmjs.com/package/mongodb)
|
||||||
- [ncp](https://www.npmjs.com/package/ncp)
|
- [ncp](https://www.npmjs.com/package/ncp)
|
||||||
|
- [Node.js](https://nodejs.org/)
|
||||||
- [node-dir](https://www.npmjs.com/package/node-dir)
|
- [node-dir](https://www.npmjs.com/package/node-dir)
|
||||||
- [path-exists](https://www.npmjs.com/package/path-exists)
|
- [path-exists](https://www.npmjs.com/package/path-exists)
|
||||||
- [pg](https://www.npmjs.com/package/pg)
|
- [pg](https://www.npmjs.com/package/pg)
|
||||||
@@ -48,23 +46,26 @@
|
|||||||
- [request](https://www.npmjs.com/package/request)
|
- [request](https://www.npmjs.com/package/request)
|
||||||
- [rimraf](https://www.npmjs.com/package/rimraf)
|
- [rimraf](https://www.npmjs.com/package/rimraf)
|
||||||
- [send](https://www.npmjs.com/package/send)
|
- [send](https://www.npmjs.com/package/send)
|
||||||
|
- [Socket.IO](https://socket.io/)
|
||||||
- [SockJS](https://www.npmjs.com/package/sockjs)
|
- [SockJS](https://www.npmjs.com/package/sockjs)
|
||||||
- [SockJS-client](https://www.npmjs.com/package/sockjs-client)
|
- [SockJS-client](https://www.npmjs.com/package/sockjs-client)
|
||||||
- [typeahead.js](https://www.npmjs.com/package/typeahead.js)
|
- [typeahead.js](https://www.npmjs.com/package/typeahead.js)
|
||||||
- [vinyl-fs](https://www.npmjs.com/package/vinyl-fs)
|
- [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)
|
- [write-file-atomic](https://www.npmjs.com/package/write-file-atomic)
|
||||||
- [ws](https://github.com/websockets/ws)
|
- [ws](https://github.com/websockets/ws)
|
||||||
|
|
||||||
|
|
||||||
## New queries
|
## New queries
|
||||||
|
|
||||||
| **Query** | **Tags** | **Purpose** |
|
| **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. |
|
| 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. |
|
| 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. |
|
| 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. |
|
| 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. |
|
| 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** |
|
| **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. |
|
| 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. |
|
| Duplicate parameter names (`js/duplicate-parameter-name`) | Fewer results | This query now ignores 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. |
|
|
||||||
| 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. |
|
| 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. |
|
| Identical operands (`js/redundant-operation`) | Fewer results | This query now excludes cases where the operands change a value using ++/-- expressions. |
|
||||||
| 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. |
|
| 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. |
|
||||||
| 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. |
|
|
||||||
| Incomplete URL scheme check (`js/incomplete-url-scheme-check`) | More results | This query now recognizes additional variations of URL scheme checks. |
|
| 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
|
## Changes to libraries
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,16 @@
|
|||||||
|
|
||||||
## General improvements
|
## General improvements
|
||||||
|
|
||||||
|
* Support for the following frameworks and libraries has been improved:
|
||||||
|
- [jGrowl](https://github.com/stanlemon/jGrowl)
|
||||||
|
- [jQuery](https://jquery.com/)
|
||||||
|
|
||||||
## New queries
|
## New queries
|
||||||
|
|
||||||
| **Query** | **Tags** | **Purpose** |
|
| **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. |
|
| 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
|
## Changes to existing queries
|
||||||
|
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ def choose_latest_file(files):
|
|||||||
|
|
||||||
local_error_count = 0
|
local_error_count = 0
|
||||||
def emit_local_error(path, line, error):
|
def emit_local_error(path, line, error):
|
||||||
print('ERROR: ' + path + ':' + line + " - " + error)
|
print('ERROR: ' + path + ':' + str(line) + " - " + error)
|
||||||
global local_error_count
|
global local_error_count
|
||||||
local_error_count += 1
|
local_error_count += 1
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
import cpp
|
import cpp
|
||||||
|
|
||||||
|
pragma[inline]
|
||||||
private predicate arithTypesMatch(Type arg, Type parm) {
|
private predicate arithTypesMatch(Type arg, Type parm) {
|
||||||
arg = parm
|
arg = parm
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -28,5 +28,5 @@ where
|
|||||||
// is probably a mistake.
|
// is probably a mistake.
|
||||||
addWithSizeof(e, sizeofExpr, _) and not isCharSzPtrExpr(e)
|
addWithSizeof(e, sizeofExpr, _) and not isCharSzPtrExpr(e)
|
||||||
select sizeofExpr,
|
select sizeofExpr,
|
||||||
"Suspicious sizeof offset in a pointer arithmetic expression. " + "The type of the pointer is " +
|
"Suspicious sizeof offset in a pointer arithmetic expression. The type of the pointer is $@.",
|
||||||
e.getFullyConverted().getType().toString() + "."
|
e.getFullyConverted().getType() as t, t.toString()
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ private import semmle.code.cpp.internal.QualifiedName as Q
|
|||||||
* `DeclarationEntry`, because they always have a unique source location.
|
* `DeclarationEntry`, because they always have a unique source location.
|
||||||
* `EnumConstant` and `FriendDecl` are both examples of this.
|
* `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.
|
* Gets the innermost namespace which contains this declaration.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -376,6 +376,8 @@ private predicate isIntegralType(@builtintype type, int kind) {
|
|||||||
kind = 43
|
kind = 43
|
||||||
or
|
or
|
||||||
kind = 44
|
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
|
original = 43 and canonical = 43 and unsigned = -1 and signed = -1 // char16_t
|
||||||
or
|
or
|
||||||
original = 44 and canonical = 44 and unsigned = -1 and signed = -1 // char32_t
|
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" }
|
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.
|
* The C/C++ `char16_t` type. This is available starting with C11 and C++11.
|
||||||
* ```
|
* ```
|
||||||
|
|||||||
@@ -126,10 +126,7 @@ class Variable extends Declaration, @variable {
|
|||||||
or
|
or
|
||||||
exists(AssignExpr ae | ae.getLValue().(Access).getTarget() = this and result = ae.getRValue())
|
exists(AssignExpr ae | ae.getLValue().(Access).getTarget() = this and result = ae.getRValue())
|
||||||
or
|
or
|
||||||
exists(AggregateLiteral l |
|
exists(ClassAggregateLiteral l | result = l.getFieldExpr(this))
|
||||||
this.getDeclaringType() = l.getType() and
|
|
||||||
result = l.getChild(this.(Field).getInitializationOrder())
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ abstract class Assertion extends Locatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A libc assert, as defined in assert.h. A macro with the head
|
* A libc assert, as defined in assert.h. A macro with a head
|
||||||
* "assert(expr)" that expands to a conditional expression which
|
* that matches the prefix "assert(", and expands to a conditional
|
||||||
* may terminate the program.
|
* expression which may terminate the program.
|
||||||
*/
|
*/
|
||||||
class LibcAssert extends MacroInvocation, Assertion {
|
class LibcAssert extends MacroInvocation, Assertion {
|
||||||
LibcAssert() { this.getMacro().getHead() = "assert(expr)" }
|
LibcAssert() { this.getMacro().getHead().matches("assert(%") }
|
||||||
|
|
||||||
override Expr getAsserted() {
|
override Expr getAsserted() {
|
||||||
exists(ConditionalExpr ce | this.getAGeneratedElement() = ce | result = ce.getCondition())
|
exists(ConditionalExpr ce | this.getAGeneratedElement() = ce | result = ce.getCondition())
|
||||||
|
|||||||
@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
|||||||
* a callable is recorded by `cc`.
|
* a callable is recorded by `cc`.
|
||||||
*/
|
*/
|
||||||
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
||||||
exists(
|
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
|
||||||
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
|
midnode = mid.getNode() and
|
||||||
LocalCallContext localCC
|
conf = mid.getConfiguration() and
|
||||||
|
|
cc = mid.getCallContext() and
|
||||||
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, enclosing)
|
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
|
||||||
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
ap = ap0
|
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()
|
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]
|
pragma[nomagic]
|
||||||
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
||||||
readDirect(node1, f, node2) and
|
readDirect(node1, f, node2) and
|
||||||
|
|||||||
@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
|||||||
* a callable is recorded by `cc`.
|
* a callable is recorded by `cc`.
|
||||||
*/
|
*/
|
||||||
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
||||||
exists(
|
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
|
||||||
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
|
midnode = mid.getNode() and
|
||||||
LocalCallContext localCC
|
conf = mid.getConfiguration() and
|
||||||
|
|
cc = mid.getCallContext() and
|
||||||
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, enclosing)
|
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
|
||||||
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
ap = ap0
|
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()
|
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]
|
pragma[nomagic]
|
||||||
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
||||||
readDirect(node1, f, node2) and
|
readDirect(node1, f, node2) and
|
||||||
|
|||||||
@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
|||||||
* a callable is recorded by `cc`.
|
* a callable is recorded by `cc`.
|
||||||
*/
|
*/
|
||||||
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
||||||
exists(
|
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
|
||||||
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
|
midnode = mid.getNode() and
|
||||||
LocalCallContext localCC
|
conf = mid.getConfiguration() and
|
||||||
|
|
cc = mid.getCallContext() and
|
||||||
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, enclosing)
|
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
|
||||||
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
ap = ap0
|
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()
|
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]
|
pragma[nomagic]
|
||||||
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
||||||
readDirect(node1, f, node2) and
|
readDirect(node1, f, node2) and
|
||||||
|
|||||||
@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
|||||||
* a callable is recorded by `cc`.
|
* a callable is recorded by `cc`.
|
||||||
*/
|
*/
|
||||||
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
||||||
exists(
|
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
|
||||||
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
|
midnode = mid.getNode() and
|
||||||
LocalCallContext localCC
|
conf = mid.getConfiguration() and
|
||||||
|
|
cc = mid.getCallContext() and
|
||||||
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, enclosing)
|
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
|
||||||
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
ap = ap0
|
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()
|
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]
|
pragma[nomagic]
|
||||||
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
||||||
readDirect(node1, f, node2) and
|
readDirect(node1, f, node2) and
|
||||||
|
|||||||
@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
|||||||
* a callable is recorded by `cc`.
|
* a callable is recorded by `cc`.
|
||||||
*/
|
*/
|
||||||
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
||||||
exists(
|
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
|
||||||
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
|
midnode = mid.getNode() and
|
||||||
LocalCallContext localCC
|
conf = mid.getConfiguration() and
|
||||||
|
|
cc = mid.getCallContext() and
|
||||||
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, enclosing)
|
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
|
||||||
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
ap = ap0
|
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()
|
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]
|
pragma[nomagic]
|
||||||
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
||||||
readDirect(node1, f, node2) and
|
readDirect(node1, f, node2) and
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class Node extends TNode {
|
|||||||
/**
|
/**
|
||||||
* INTERNAL: Do not use. Alternative name for `getFunction`.
|
* 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. */
|
/** Gets the type of this node. */
|
||||||
Type getType() { none() } // overridden in subclasses
|
Type getType() { none() } // overridden in subclasses
|
||||||
@@ -299,7 +299,7 @@ private class PartialDefinitionNode extends PostUpdateNode, TPartialDefinitionNo
|
|||||||
|
|
||||||
override Node getPreUpdateNode() { result.asExpr() = pd.getDefinedExpr() }
|
override Node getPreUpdateNode() { result.asExpr() = pd.getDefinedExpr() }
|
||||||
|
|
||||||
override Location getLocation() { result = pd.getLocation() }
|
override Location getLocation() { result = pd.getActualLocation() }
|
||||||
|
|
||||||
PartialDefinition getPartialDefinition() { result = pd }
|
PartialDefinition getPartialDefinition() { result = pd }
|
||||||
|
|
||||||
|
|||||||
@@ -113,44 +113,39 @@ class FlowVar extends TFlowVar {
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
private module PartialDefinitions {
|
private module PartialDefinitions {
|
||||||
private newtype TPartialDefinition =
|
private predicate isInstanceFieldWrite(FieldAccess fa, ControlFlowNode node) {
|
||||||
TExplicitFieldStoreQualifier(Expr qualifier, ControlFlowNode node) {
|
assignmentLikeOperation(node, _, fa, _)
|
||||||
exists(FieldAccess fa | qualifier = fa.getQualifier() |
|
}
|
||||||
|
|
||||||
|
class PartialDefinition extends Expr {
|
||||||
|
ControlFlowNode node;
|
||||||
|
|
||||||
|
PartialDefinition() {
|
||||||
|
exists(FieldAccess fa | this = fa.getQualifier() |
|
||||||
|
// `fa = ...`, `fa += ...`, etc.
|
||||||
isInstanceFieldWrite(fa, node)
|
isInstanceFieldWrite(fa, node)
|
||||||
or
|
or
|
||||||
|
// `fa.a = ...`, `f(&fa)`, etc.
|
||||||
exists(PartialDefinition pd |
|
exists(PartialDefinition pd |
|
||||||
node = pd.getSubBasicBlockStart() and
|
node = pd.getSubBasicBlockStart() and
|
||||||
fa = pd.getDefinedExpr()
|
fa = pd.getDefinedExpr()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
} or
|
or
|
||||||
TExplicitCallQualifier(Expr qualifier) {
|
// `e.f(...)`
|
||||||
exists(Call call |
|
exists(Call call |
|
||||||
qualifier = call.getQualifier() and
|
this = call.getQualifier() and
|
||||||
not call.getTarget().hasSpecifier("const")
|
not call.getTarget().hasSpecifier("const")
|
||||||
)
|
) and
|
||||||
} or
|
node = this
|
||||||
TReferenceArgument(Expr arg, VariableAccess va) { referenceArgument(va, arg) }
|
or
|
||||||
|
// `f(e)`, `f(&e)`, etc.
|
||||||
private predicate isInstanceFieldWrite(FieldAccess fa, ControlFlowNode node) {
|
referenceArgument(node, this)
|
||||||
assignmentLikeOperation(node, _, fa, _)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class PartialDefinition extends TPartialDefinition {
|
predicate partiallyDefines(Variable v) { this = v.getAnAccess() }
|
||||||
Expr definedExpr;
|
|
||||||
ControlFlowNode node;
|
|
||||||
|
|
||||||
PartialDefinition() {
|
predicate partiallyDefinesThis(ThisExpr e) { this = e }
|
||||||
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 }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the subBasicBlock where this `PartialDefinition` is defined.
|
* Gets the subBasicBlock where this `PartialDefinition` is defined.
|
||||||
@@ -165,33 +160,29 @@ private module PartialDefinitions {
|
|||||||
* ```
|
* ```
|
||||||
* The expression `x` is being partially defined.
|
* 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
|
or
|
||||||
definedExpr.getLocation() instanceof UnknownLocation and
|
this.getLocation() instanceof UnknownLocation and
|
||||||
result = definedExpr.getParent().getLocation()
|
result = this.getParent().getLocation()
|
||||||
or
|
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.
|
* A partial definition that's a definition by reference.
|
||||||
*/
|
*/
|
||||||
class DefinitionByReference extends PartialDefinition, TReferenceArgument {
|
class DefinitionByReference extends PartialDefinition {
|
||||||
VariableAccess va;
|
VariableAccess va;
|
||||||
|
|
||||||
DefinitionByReference() {
|
DefinitionByReference() { referenceArgument(va, this) }
|
||||||
// `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)
|
|
||||||
}
|
|
||||||
|
|
||||||
VariableAccess getVariableAccess() { result = va }
|
VariableAccess getVariableAccess() { result = va }
|
||||||
|
|
||||||
|
|||||||
@@ -145,8 +145,6 @@ class HexLiteral extends Literal {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A C/C++ aggregate literal.
|
* A C/C++ aggregate literal.
|
||||||
*
|
|
||||||
* For example:
|
|
||||||
*/
|
*/
|
||||||
class AggregateLiteral extends Expr, @aggregateliteral {
|
class AggregateLiteral extends Expr, @aggregateliteral {
|
||||||
override string getCanonicalQLClass() { result = "AggregateLiteral" }
|
override string getCanonicalQLClass() { result = "AggregateLiteral" }
|
||||||
|
|||||||
@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
|||||||
* a callable is recorded by `cc`.
|
* a callable is recorded by `cc`.
|
||||||
*/
|
*/
|
||||||
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
||||||
exists(
|
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
|
||||||
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
|
midnode = mid.getNode() and
|
||||||
LocalCallContext localCC
|
conf = mid.getConfiguration() and
|
||||||
|
|
cc = mid.getCallContext() and
|
||||||
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, enclosing)
|
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
|
||||||
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
ap = ap0
|
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()
|
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]
|
pragma[nomagic]
|
||||||
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
||||||
readDirect(node1, f, node2) and
|
readDirect(node1, f, node2) and
|
||||||
|
|||||||
@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
|||||||
* a callable is recorded by `cc`.
|
* a callable is recorded by `cc`.
|
||||||
*/
|
*/
|
||||||
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
||||||
exists(
|
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
|
||||||
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
|
midnode = mid.getNode() and
|
||||||
LocalCallContext localCC
|
conf = mid.getConfiguration() and
|
||||||
|
|
cc = mid.getCallContext() and
|
||||||
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, enclosing)
|
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
|
||||||
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
ap = ap0
|
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()
|
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]
|
pragma[nomagic]
|
||||||
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
||||||
readDirect(node1, f, node2) and
|
readDirect(node1, f, node2) and
|
||||||
|
|||||||
@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
|||||||
* a callable is recorded by `cc`.
|
* a callable is recorded by `cc`.
|
||||||
*/
|
*/
|
||||||
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
||||||
exists(
|
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
|
||||||
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
|
midnode = mid.getNode() and
|
||||||
LocalCallContext localCC
|
conf = mid.getConfiguration() and
|
||||||
|
|
cc = mid.getCallContext() and
|
||||||
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, enclosing)
|
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
|
||||||
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
ap = ap0
|
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()
|
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]
|
pragma[nomagic]
|
||||||
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
||||||
readDirect(node1, f, node2) and
|
readDirect(node1, f, node2) and
|
||||||
|
|||||||
@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
|||||||
* a callable is recorded by `cc`.
|
* a callable is recorded by `cc`.
|
||||||
*/
|
*/
|
||||||
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
||||||
exists(
|
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
|
||||||
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
|
midnode = mid.getNode() and
|
||||||
LocalCallContext localCC
|
conf = mid.getConfiguration() and
|
||||||
|
|
cc = mid.getCallContext() and
|
||||||
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, enclosing)
|
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
|
||||||
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
ap = ap0
|
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()
|
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]
|
pragma[nomagic]
|
||||||
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
||||||
readDirect(node1, f, node2) and
|
readDirect(node1, f, node2) and
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
private import semmle.code.cpp.ir.IR
|
private import semmle.code.cpp.ir.IR
|
||||||
private import semmle.code.cpp.ir.dataflow.DataFlow
|
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
|
* Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local
|
||||||
@@ -45,6 +48,25 @@ private predicate localInstructionTaintStep(Instruction nodeFrom, Instruction no
|
|||||||
)
|
)
|
||||||
or
|
or
|
||||||
nodeTo.(LoadInstruction).getSourceAddress() = nodeFrom
|
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.
|
* but not in local taint.
|
||||||
*/
|
*/
|
||||||
predicate defaultTaintBarrier(DataFlow::Node node) { none() }
|
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)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
@@ -89,6 +89,18 @@ class MallocAllocationFunction extends AllocationFunction {
|
|||||||
or
|
or
|
||||||
// kmem_zalloc(size, flags)
|
// kmem_zalloc(size, flags)
|
||||||
name = "kmem_zalloc" and sizeArg = 0
|
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
|
or
|
||||||
// CoTaskMemRealloc(ptr, size)
|
// CoTaskMemRealloc(ptr, size)
|
||||||
name = "CoTaskMemRealloc" and sizeArg = 1 and reallocArg = 0
|
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`.
|
* 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)
|
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() {
|
override int getSizeMult() {
|
||||||
// malloc with multiplier argument that is a constant
|
// malloc with multiplier argument that is a constant
|
||||||
@@ -280,13 +335,19 @@ class CallAllocationExpr extends AllocationExpr, FunctionCall {
|
|||||||
or
|
or
|
||||||
// malloc with no multiplier argument
|
// malloc with no multiplier argument
|
||||||
not exists(target.getSizeMult()) and
|
not exists(target.getSizeMult()) and
|
||||||
result = 1
|
deconstructSizeExpr(getArgument(target.getSizeArg()), _, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
override int getSizeBytes() { result = getSizeExpr().getValue().toInt() * getSizeMult() }
|
override int getSizeBytes() { result = getSizeExpr().getValue().toInt() * getSizeMult() }
|
||||||
|
|
||||||
override Expr getReallocPtr() { result = getArgument(target.getReallocPtrArg()) }
|
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() }
|
override predicate requiresDealloc() { target.requiresDealloc() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,6 +359,8 @@ class NewAllocationExpr extends AllocationExpr, NewExpr {
|
|||||||
|
|
||||||
override int getSizeBytes() { result = getAllocatedType().getSize() }
|
override int getSizeBytes() { result = getAllocatedType().getSize() }
|
||||||
|
|
||||||
|
override Type getAllocatedElementType() { result = getAllocatedType() }
|
||||||
|
|
||||||
override predicate requiresDealloc() { not exists(getPlacementPointer()) }
|
override predicate requiresDealloc() { not exists(getPlacementPointer()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,6 +381,8 @@ class NewArrayAllocationExpr extends AllocationExpr, NewArrayExpr {
|
|||||||
result = getAllocatedElementType().getSize()
|
result = getAllocatedElementType().getSize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override Type getAllocatedElementType() { result = NewArrayExpr.super.getAllocatedElementType() }
|
||||||
|
|
||||||
override int getSizeBytes() { result = getAllocatedType().getSize() }
|
override int getSizeBytes() { result = getAllocatedType().getSize() }
|
||||||
|
|
||||||
override predicate requiresDealloc() { not exists(getPlacementPointer()) }
|
override predicate requiresDealloc() { not exists(getPlacementPointer()) }
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ class StandardDeallocationFunction extends DeallocationFunction {
|
|||||||
name = "free" and freedArg = 0
|
name = "free" and freedArg = 0
|
||||||
or
|
or
|
||||||
name = "realloc" and freedArg = 0
|
name = "realloc" and freedArg = 0
|
||||||
|
or
|
||||||
|
name = "CRYPTO_free" and freedArg = 0
|
||||||
|
or
|
||||||
|
name = "CRYPTO_secure_free" and freedArg = 0
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
hasGlobalOrStdName(name) and
|
hasGlobalOrStdName(name) and
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import semmle.code.cpp.models.interfaces.Taint
|
|||||||
* The `std::basic_string` constructor(s).
|
* The `std::basic_string` constructor(s).
|
||||||
*/
|
*/
|
||||||
class StdStringConstructor extends TaintFunction {
|
class StdStringConstructor extends TaintFunction {
|
||||||
|
pragma[noinline]
|
||||||
StdStringConstructor() { this.hasQualifiedName("std", "basic_string", "basic_string") }
|
StdStringConstructor() { this.hasQualifiedName("std", "basic_string", "basic_string") }
|
||||||
|
|
||||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||||
|
|||||||
@@ -72,6 +72,11 @@ abstract class AllocationExpr extends Expr {
|
|||||||
*/
|
*/
|
||||||
Expr getReallocPtr() { none() }
|
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
|
* Whether or not this allocation requires a corresponding deallocation of
|
||||||
* some sort (most do, but `alloca` for example does not). If it is unclear,
|
* some sort (most do, but `alloca` for example does not). If it is unclear,
|
||||||
|
|||||||
@@ -74,6 +74,8 @@ abstract class Architecture extends string {
|
|||||||
or
|
or
|
||||||
t instanceof WideCharType and result = wideCharSize()
|
t instanceof WideCharType and result = wideCharSize()
|
||||||
or
|
or
|
||||||
|
t instanceof Char8Type and result = 8
|
||||||
|
or
|
||||||
t instanceof Char16Type and result = 16
|
t instanceof Char16Type and result = 16
|
||||||
or
|
or
|
||||||
t instanceof Char32Type and result = 32
|
t instanceof Char32Type and result = 32
|
||||||
@@ -155,6 +157,8 @@ abstract class Architecture extends string {
|
|||||||
or
|
or
|
||||||
t instanceof WideCharType and result = wideCharSize()
|
t instanceof WideCharType and result = wideCharSize()
|
||||||
or
|
or
|
||||||
|
t instanceof Char8Type and result = 8
|
||||||
|
or
|
||||||
t instanceof Char16Type and result = 16
|
t instanceof Char16Type and result = 16
|
||||||
or
|
or
|
||||||
t instanceof Char32Type and result = 32
|
t instanceof Char32Type and result = 32
|
||||||
|
|||||||
@@ -616,6 +616,7 @@ enumconstants(
|
|||||||
| 48 = _Float64x
|
| 48 = _Float64x
|
||||||
| 49 = _Float128
|
| 49 = _Float128
|
||||||
| 50 = _Float128x
|
| 50 = _Float128x
|
||||||
|
| 51 = char8_t
|
||||||
;
|
;
|
||||||
*/
|
*/
|
||||||
builtintypes(
|
builtintypes(
|
||||||
|
|||||||
@@ -149,3 +149,16 @@ void directOperatorCall() {
|
|||||||
ptr = operator new(sizeof(int));
|
ptr = operator new(sizeof(int));
|
||||||
operator delete(ptr);
|
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));
|
||||||
|
}
|
||||||
|
|||||||
@@ -55,35 +55,43 @@ allocationFunctions
|
|||||||
| allocators.cpp:122:7:122:20 | operator new[] | getPlacementArgument = 1, getSizeArg = 0 |
|
| 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:123:7:123:18 | operator new | getSizeArg = 0, requiresDealloc |
|
||||||
| allocators.cpp:124:7:124:20 | 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 |
|
||||||
| 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
|
allocationExprs
|
||||||
| allocators.cpp:49:3:49:9 | new | getSizeBytes = 4, requiresDealloc |
|
| allocators.cpp:49:3:49:9 | new | getAllocatedElementType = int, getSizeBytes = 4, requiresDealloc |
|
||||||
| allocators.cpp:50:3:50:15 | new | getSizeBytes = 4, requiresDealloc |
|
| allocators.cpp:50:3:50:15 | new | getAllocatedElementType = int, getSizeBytes = 4, requiresDealloc |
|
||||||
| allocators.cpp:51:3:51:11 | new | getSizeBytes = 4, requiresDealloc |
|
| allocators.cpp:51:3:51:11 | new | getAllocatedElementType = int, getSizeBytes = 4, requiresDealloc |
|
||||||
| allocators.cpp:52:3:52:14 | new | getSizeBytes = 8, requiresDealloc |
|
| allocators.cpp:52:3:52:14 | new | getAllocatedElementType = String, getSizeBytes = 8, requiresDealloc |
|
||||||
| allocators.cpp:53:3:53:27 | new | getSizeBytes = 8, requiresDealloc |
|
| allocators.cpp:53:3:53:27 | new | getAllocatedElementType = String, getSizeBytes = 8, requiresDealloc |
|
||||||
| allocators.cpp:54:3:54:17 | new | getSizeBytes = 256, requiresDealloc |
|
| allocators.cpp:54:3:54:17 | new | getAllocatedElementType = Overaligned, getSizeBytes = 256, requiresDealloc |
|
||||||
| allocators.cpp:55:3:55:25 | new | getSizeBytes = 256, requiresDealloc |
|
| allocators.cpp:55:3:55:25 | new | getAllocatedElementType = Overaligned, getSizeBytes = 256, requiresDealloc |
|
||||||
| allocators.cpp:68:3:68:12 | new[] | getSizeExpr = n, getSizeMult = 4, requiresDealloc |
|
| allocators.cpp:68:3:68:12 | new[] | getAllocatedElementType = int, getSizeExpr = n, getSizeMult = 4, requiresDealloc |
|
||||||
| allocators.cpp:69:3:69:18 | new[] | 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[] | getSizeExpr = n, getSizeMult = 8, requiresDealloc |
|
| allocators.cpp:70:3:70:15 | new[] | getAllocatedElementType = String, getSizeExpr = n, getSizeMult = 8, requiresDealloc |
|
||||||
| allocators.cpp:71:3:71:20 | new[] | getSizeExpr = n, getSizeMult = 256, requiresDealloc |
|
| allocators.cpp:71:3:71:20 | new[] | getAllocatedElementType = Overaligned, getSizeExpr = n, getSizeMult = 256, requiresDealloc |
|
||||||
| allocators.cpp:72:3:72:16 | new[] | getSizeBytes = 80, requiresDealloc |
|
| allocators.cpp:72:3:72:16 | new[] | getAllocatedElementType = String, getSizeBytes = 80, requiresDealloc |
|
||||||
| allocators.cpp:107:3:107:18 | new | getSizeBytes = 1, requiresDealloc |
|
| allocators.cpp:107:3:107:18 | new | getAllocatedElementType = FailedInit, getSizeBytes = 1, requiresDealloc |
|
||||||
| allocators.cpp:108:3:108:19 | new[] | getSizeExpr = n, getSizeMult = 1, requiresDealloc |
|
| allocators.cpp:108:3:108:19 | new[] | getAllocatedElementType = FailedInit, getSizeExpr = n, getSizeMult = 1, requiresDealloc |
|
||||||
| allocators.cpp:109:3:109:35 | new | getSizeBytes = 128, requiresDealloc |
|
| allocators.cpp:109:3:109:35 | new | getAllocatedElementType = FailedInitOveraligned, getSizeBytes = 128, requiresDealloc |
|
||||||
| allocators.cpp:110:3:110:37 | new[] | getSizeBytes = 1280, requiresDealloc |
|
| allocators.cpp:110:3:110:37 | new[] | getAllocatedElementType = FailedInitOveraligned, getSizeBytes = 1280, requiresDealloc |
|
||||||
| allocators.cpp:129:3:129:21 | new | getSizeBytes = 4 |
|
| allocators.cpp:129:3:129:21 | new | getAllocatedElementType = int, getSizeBytes = 4 |
|
||||||
| allocators.cpp:132:3:132:17 | new[] | getSizeBytes = 4 |
|
| allocators.cpp:132:3:132:17 | new[] | getAllocatedElementType = int, getSizeBytes = 4 |
|
||||||
| allocators.cpp:135:3:135:26 | new | getSizeBytes = 4, requiresDealloc |
|
| allocators.cpp:135:3:135:26 | new | getAllocatedElementType = int, getSizeBytes = 4, requiresDealloc |
|
||||||
| allocators.cpp:136:3:136:26 | new[] | getSizeBytes = 8, requiresDealloc |
|
| allocators.cpp:136:3:136:26 | new[] | getAllocatedElementType = int, getSizeBytes = 8, requiresDealloc |
|
||||||
| allocators.cpp:142:13:142:27 | new[] | getSizeExpr = x, getSizeMult = 10, requiresDealloc |
|
| allocators.cpp:142:13:142:27 | new[] | getAllocatedElementType = char[10], getSizeExpr = x, getSizeMult = 10, requiresDealloc |
|
||||||
| allocators.cpp:143:13:143:28 | new[] | getSizeBytes = 400, requiresDealloc |
|
| allocators.cpp:143:13:143:28 | new[] | getAllocatedElementType = char[20], getSizeBytes = 400, requiresDealloc |
|
||||||
| allocators.cpp:144:13:144:31 | new[] | getSizeExpr = x, getSizeMult = 900, 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: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
|
deallocationFunctions
|
||||||
| allocators.cpp:11:6:11:20 | operator delete | getFreedArg = 0 |
|
| allocators.cpp:11:6:11:20 | operator delete | getFreedArg = 0 |
|
||||||
| allocators.cpp:12:6:12:22 | operator delete[] | getFreedArg = 0 |
|
| allocators.cpp:12:6:12:22 | operator delete[] | getFreedArg = 0 |
|
||||||
|
|||||||
@@ -138,6 +138,8 @@ string describeAllocationExpr(AllocationExpr e) {
|
|||||||
or
|
or
|
||||||
result = "getReallocPtr = " + e.getReallocPtr().toString()
|
result = "getReallocPtr = " + e.getReallocPtr().toString()
|
||||||
or
|
or
|
||||||
|
result = "getAllocatedElementType = " + e.getAllocatedElementType().toString()
|
||||||
|
or
|
||||||
e.requiresDealloc() and
|
e.requiresDealloc() and
|
||||||
result = "requiresDealloc"
|
result = "requiresDealloc"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,7 @@
|
|||||||
| file://:0:0:0:0 | auto |
|
| file://:0:0:0:0 | auto |
|
||||||
| file://:0:0:0:0 | bool |
|
| file://:0:0:0:0 | bool |
|
||||||
| file://:0:0:0:0 | char |
|
| 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 | char16_t |
|
||||||
| file://:0:0:0:0 | char32_t |
|
| file://:0:0:0:0 | char32_t |
|
||||||
| file://:0:0:0:0 | const |
|
| file://:0:0:0:0 | const |
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
| file://:0:0:0:0 | auto |
|
| file://:0:0:0:0 | auto |
|
||||||
| file://:0:0:0:0 | bool |
|
| file://:0:0:0:0 | bool |
|
||||||
| file://:0:0:0:0 | char |
|
| 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 | char16_t |
|
||||||
| file://:0:0:0:0 | char32_t |
|
| file://:0:0:0:0 | char32_t |
|
||||||
| file://:0:0:0:0 | const |
|
| file://:0:0:0:0 | const |
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import semmle.code.cpp.dataflow.internal.FlowVar
|
import semmle.code.cpp.dataflow.internal.FlowVar
|
||||||
|
|
||||||
from PartialDefinition def
|
from PartialDefinition def
|
||||||
select def, def.getDefinedExpr(), def.getSubBasicBlockStart()
|
select def.getActualLocation().toString(), "partial def of " + def.toString(), def.getDefinedExpr(),
|
||||||
|
def.getSubBasicBlockStart()
|
||||||
|
|||||||
@@ -22,6 +22,9 @@
|
|||||||
| taint.cpp:93:11:93:11 | taint.cpp:71:22:71:27 | AST only |
|
| 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: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: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: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: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 |
|
| taint.cpp:173:8:173:13 | taint.cpp:164:19:164:24 | AST only |
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
| taint.cpp:16:8:16:14 | source1 | taint.cpp:12:22:12:27 | call to source |
|
| 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: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: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: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: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 |
|
| taint.cpp:134:7:134:9 | * ... | taint.cpp:120:11:120:16 | call to source |
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
| file://:0:0:0:0 | auto |
|
| file://:0:0:0:0 | auto |
|
||||||
| file://:0:0:0:0 | bool |
|
| file://:0:0:0:0 | bool |
|
||||||
| file://:0:0:0:0 | char |
|
| 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 | char16_t |
|
||||||
| file://:0:0:0:0 | char32_t |
|
| file://:0:0:0:0 | char32_t |
|
||||||
| file://:0:0:0:0 | composite<int> & |
|
| file://:0:0:0:0 | composite<int> & |
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
| file://:0:0:0:0 | auto |
|
| file://:0:0:0:0 | auto |
|
||||||
| file://:0:0:0:0 | bool |
|
| file://:0:0:0:0 | bool |
|
||||||
| file://:0:0:0:0 | char |
|
| 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 | char16_t |
|
||||||
| file://:0:0:0:0 | char32_t |
|
| file://:0:0:0:0 | char32_t |
|
||||||
| file://:0:0:0:0 | const __va_list_tag |
|
| file://:0:0:0:0 | const __va_list_tag |
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
| file://:0:0:0:0 | auto | <none> |
|
| file://:0:0:0:0 | auto | <none> |
|
||||||
| file://:0:0:0:0 | bool | 1 |
|
| file://:0:0:0:0 | bool | 1 |
|
||||||
| file://:0:0:0:0 | char | 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 | char16_t | 2 |
|
||||||
| file://:0:0:0:0 | char32_t | 4 |
|
| file://:0:0:0:0 | char32_t | 4 |
|
||||||
| file://:0:0:0:0 | char * | 8 |
|
| file://:0:0:0:0 | char * | 8 |
|
||||||
|
|||||||
@@ -20,3 +20,4 @@
|
|||||||
| 37 | signed __int128 | signed | -------- | explicitlySigned | ------------------ | ---------------- | 16 | 16 | unsigned __int128 | |
|
| 37 | signed __int128 | signed | -------- | explicitlySigned | ------------------ | ---------------- | 16 | 16 | unsigned __int128 | |
|
||||||
| 43 | char16_t | ------ | -------- | ---------------- | ------------------ | ---------------- | 2 | 2 | <no unsigned equivalent> | |
|
| 43 | char16_t | ------ | -------- | ---------------- | ------------------ | ---------------- | 2 | 2 | <no unsigned equivalent> | |
|
||||||
| 44 | char32_t | ------ | -------- | ---------------- | ------------------ | ---------------- | 4 | 4 | <no unsigned equivalent> | |
|
| 44 | char32_t | ------ | -------- | ---------------- | ------------------ | ---------------- | 4 | 4 | <no unsigned equivalent> | |
|
||||||
|
| 51 | char8_t | ------ | -------- | ---------------- | ------------------ | ---------------- | 1 | 1 | <no unsigned equivalent> | |
|
||||||
|
|||||||
@@ -20,3 +20,4 @@
|
|||||||
| 37 | signed __int128 | signed | -------- | explicitlySigned | ------------------ | ---------------- | 16 | 16 | unsigned __int128 | |
|
| 37 | signed __int128 | signed | -------- | explicitlySigned | ------------------ | ---------------- | 16 | 16 | unsigned __int128 | |
|
||||||
| 43 | char16_t | ------ | -------- | ---------------- | ------------------ | ---------------- | 2 | 2 | <no unsigned equivalent> | |
|
| 43 | char16_t | ------ | -------- | ---------------- | ------------------ | ---------------- | 2 | 2 | <no unsigned equivalent> | |
|
||||||
| 44 | char32_t | ------ | -------- | ---------------- | ------------------ | ---------------- | 4 | 4 | <no unsigned equivalent> | |
|
| 44 | char32_t | ------ | -------- | ---------------- | ------------------ | ---------------- | 4 | 4 | <no unsigned equivalent> | |
|
||||||
|
| 51 | char8_t | ------ | -------- | ---------------- | ------------------ | ---------------- | 1 | 1 | <no unsigned equivalent> | |
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
| file://:0:0:0:0 | auto | Other |
|
| file://:0:0:0:0 | auto | Other |
|
||||||
| file://:0:0:0:0 | bool | Other |
|
| file://:0:0:0:0 | bool | Other |
|
||||||
| file://:0:0:0:0 | char | 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 | char16_t | Other |
|
||||||
| file://:0:0:0:0 | char32_t | Other |
|
| file://:0:0:0:0 | char32_t | Other |
|
||||||
| file://:0:0:0:0 | const | Other |
|
| file://:0:0:0:0 | const | Other |
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
| file://:0:0:0:0 | auto | auto |
|
| file://:0:0:0:0 | auto | auto |
|
||||||
| file://:0:0:0:0 | bool | bool |
|
| file://:0:0:0:0 | bool | bool |
|
||||||
| file://:0:0:0:0 | char | char |
|
| 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 | char16_t | char16_t |
|
||||||
| file://:0:0:0:0 | char32_t | char32_t |
|
| file://:0:0:0:0 | char32_t | char32_t |
|
||||||
| file://:0:0:0:0 | const __va_list_tag | __va_list_tag |
|
| file://:0:0:0:0 | const __va_list_tag | __va_list_tag |
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
| auto | AutoType | | | | |
|
| auto | AutoType | | | | |
|
||||||
| bool | BoolType | | | | |
|
| bool | BoolType | | | | |
|
||||||
| char | MicrosoftInt8Type, PlainCharType | | | | |
|
| char | MicrosoftInt8Type, PlainCharType | | | | |
|
||||||
|
| char8_t | Char8Type | | | | |
|
||||||
| char16_t | Char16Type | | | | |
|
| char16_t | Char16Type | | | | |
|
||||||
| char32_t | Char32Type | | | | |
|
| char32_t | Char32Type | | | | |
|
||||||
| char * | CharPointerType | | char | | |
|
| char * | CharPointerType | | char | | |
|
||||||
|
|||||||
@@ -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: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: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: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: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: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: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. |
|
| tests3.cpp:53:17:53:44 | new[] | This allocation does not include space to null-terminate the string. |
|
||||||
|
|||||||
@@ -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: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) |
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ void tests1(int case_num)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
buffer = (char *)malloc(strlen(str) * sizeof(char)); // BAD [NOT DETECTED]
|
buffer = (char *)malloc(strlen(str) * sizeof(char)); // BAD
|
||||||
strcpy(buffer, str);
|
strcpy(buffer, str);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ void tests1(int case_num)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 105:
|
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);
|
wcscpy(wbuffer, wstr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ void tests2(int case_num)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
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);
|
strcpy(buffer, str1);
|
||||||
strcat(buffer, str2);
|
strcat(buffer, str2);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -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: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: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: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: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: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: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. |
|
| test.cpp:63:28:63:33 | call to malloc | This allocation does not include space to null-terminate the string. |
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ void good2(char *str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void bad3(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));
|
char *buffer = malloc(strlen(str) * sizeof(char));
|
||||||
strcpy(buffer, str);
|
strcpy(buffer, str);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ void bad1(wchar_t *wstr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void bad2(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));
|
wchar_t *wbuffer = (wchar_t *)malloc(wcslen(wstr) * sizeof(wchar_t));
|
||||||
wcscpy(wbuffer, wstr);
|
wcscpy(wbuffer, wstr);
|
||||||
free(wbuffer);
|
free(wbuffer);
|
||||||
|
|||||||
@@ -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: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 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 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 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 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 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 myInt *const. |
|
| 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 |
|
||||||
|
|||||||
2038
cpp/upgrades/d6ca4ebb7680e241b647e78b96999eaf9d84e5b7/old.dbscheme
Normal file
2038
cpp/upgrades/d6ca4ebb7680e241b647e78b96999eaf9d84e5b7/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
|||||||
|
description: Add support for char8_t C++ builtin type
|
||||||
|
compatibility: backwards
|
||||||
@@ -462,7 +462,7 @@ Microsoft.NETCore.App 2.2.5 [/usr/local/share/dotnet/shared/Microsoft.NETCore.Ap
|
|||||||
public void TestCppAutobuilderSuccess()
|
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 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.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 installationPath"] = 1;
|
||||||
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationVersion"] = 0;
|
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()
|
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 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 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:\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.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0;
|
||||||
Actions.FileExists["csharp.log"] = true;
|
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()
|
public void TestWindowCSharpMsBuildMultipleSolutions()
|
||||||
{
|
{
|
||||||
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore test1.csproj"] = 0;
|
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore test1.csproj"] = 0;
|
||||||
Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && C:\\odasa\\tools\\odasa index --auto msbuild test1.csproj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
Actions.RunProcess["cmd.exe /C 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 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:\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.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0;
|
||||||
Actions.FileExists["csharp.log"] = true;
|
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()
|
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 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["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\Installer\vswhere.exe"] = false;
|
||||||
Actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = 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]
|
[Fact]
|
||||||
public void TestSkipNugetMsBuild()
|
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^\" && 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^\" && 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:\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.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0;
|
||||||
Actions.FileExists["csharp.log"] = true;
|
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()
|
public void TestDirsProjWindows()
|
||||||
{
|
{
|
||||||
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore dirs.proj"] = 1;
|
Actions.RunProcess[@"cmd.exe /C C:\odasa\tools\csharp\nuget\nuget.exe restore dirs.proj"] = 1;
|
||||||
Actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && C:\\odasa\\tools\\odasa index --auto msbuild dirs.proj /p:UseSharedCompilation=false /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /p:MvcBuildViews=true /P:Fu=Bar"] = 0;
|
Actions.RunProcess["cmd.exe /C 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:\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.RunProcess[@"cmd.exe /C C:\odasa\tools\odasa index --xml --extensions config csproj props xml"] = 0;
|
||||||
Actions.FileExists["csharp.log"] = true;
|
Actions.FileExists["csharp.log"] = true;
|
||||||
|
|||||||
@@ -118,6 +118,24 @@ namespace Semmle.Autobuild
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public IBuildActions Actions { get; }
|
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>
|
/// <summary>
|
||||||
/// Find all the relevant files and picks the best
|
/// Find all the relevant files and picks the best
|
||||||
/// solution file and tools.
|
/// solution file and tools.
|
||||||
@@ -151,24 +169,6 @@ namespace Semmle.Autobuild
|
|||||||
return ret;
|
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
|
// First look for `.proj` files
|
||||||
ret = FindFiles(".proj", f => new Project(this, f))?.ToList();
|
ret = FindFiles(".proj", f => new Project(this, f))?.ToList();
|
||||||
if (ret != null)
|
if (ret != null)
|
||||||
|
|||||||
@@ -1710,9 +1710,9 @@ module ControlFlow {
|
|||||||
exists(getAThrownException(ts, cfe, c)) and
|
exists(getAThrownException(ts, cfe, c)) and
|
||||||
result = first(ts.getCatchClause(0))
|
result = first(ts.getCatchClause(0))
|
||||||
or
|
or
|
||||||
exists(SpecificCatchClause scc, int i | scc = ts.getCatchClause(i) |
|
exists(CatchClause cc, int i | cc = ts.getCatchClause(i) |
|
||||||
cfe = scc and
|
cfe = cc and
|
||||||
scc = last(ts.getCatchClause(i), c) and
|
cc = last(ts.getCatchClause(i), c) and
|
||||||
(
|
(
|
||||||
// Flow from one `catch` clause to the next
|
// Flow from one `catch` clause to the next
|
||||||
result = first(ts.getCatchClause(i + 1)) and
|
result = first(ts.getCatchClause(i + 1)) and
|
||||||
@@ -1725,7 +1725,7 @@ module ControlFlow {
|
|||||||
)
|
)
|
||||||
or
|
or
|
||||||
cfe = last(ts.getCatchClause(i), c) and
|
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
|
// Flow from last element of `catch` clause filter to next `catch` clause
|
||||||
result = first(ts.getCatchClause(i + 1)) and
|
result = first(ts.getCatchClause(i + 1)) and
|
||||||
@@ -1739,7 +1739,7 @@ module ControlFlow {
|
|||||||
)
|
)
|
||||||
or
|
or
|
||||||
// Flow from last element of a `catch` block to first element of `finally` block
|
// 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())
|
result = first(ts.getFinally())
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
|||||||
* a callable is recorded by `cc`.
|
* a callable is recorded by `cc`.
|
||||||
*/
|
*/
|
||||||
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
||||||
exists(
|
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
|
||||||
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
|
midnode = mid.getNode() and
|
||||||
LocalCallContext localCC
|
conf = mid.getConfiguration() and
|
||||||
|
|
cc = mid.getCallContext() and
|
||||||
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, enclosing)
|
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
|
||||||
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
ap = ap0
|
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()
|
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]
|
pragma[nomagic]
|
||||||
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
||||||
readDirect(node1, f, node2) and
|
readDirect(node1, f, node2) and
|
||||||
|
|||||||
@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
|||||||
* a callable is recorded by `cc`.
|
* a callable is recorded by `cc`.
|
||||||
*/
|
*/
|
||||||
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
||||||
exists(
|
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
|
||||||
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
|
midnode = mid.getNode() and
|
||||||
LocalCallContext localCC
|
conf = mid.getConfiguration() and
|
||||||
|
|
cc = mid.getCallContext() and
|
||||||
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, enclosing)
|
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
|
||||||
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
ap = ap0
|
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()
|
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]
|
pragma[nomagic]
|
||||||
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
||||||
readDirect(node1, f, node2) and
|
readDirect(node1, f, node2) and
|
||||||
|
|||||||
@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
|||||||
* a callable is recorded by `cc`.
|
* a callable is recorded by `cc`.
|
||||||
*/
|
*/
|
||||||
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
||||||
exists(
|
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
|
||||||
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
|
midnode = mid.getNode() and
|
||||||
LocalCallContext localCC
|
conf = mid.getConfiguration() and
|
||||||
|
|
cc = mid.getCallContext() and
|
||||||
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, enclosing)
|
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
|
||||||
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
ap = ap0
|
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()
|
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]
|
pragma[nomagic]
|
||||||
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
||||||
readDirect(node1, f, node2) and
|
readDirect(node1, f, node2) and
|
||||||
|
|||||||
@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
|||||||
* a callable is recorded by `cc`.
|
* a callable is recorded by `cc`.
|
||||||
*/
|
*/
|
||||||
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
||||||
exists(
|
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
|
||||||
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
|
midnode = mid.getNode() and
|
||||||
LocalCallContext localCC
|
conf = mid.getConfiguration() and
|
||||||
|
|
cc = mid.getCallContext() and
|
||||||
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, enclosing)
|
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
|
||||||
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
ap = ap0
|
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()
|
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]
|
pragma[nomagic]
|
||||||
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
||||||
readDirect(node1, f, node2) and
|
readDirect(node1, f, node2) and
|
||||||
|
|||||||
@@ -2293,12 +2293,13 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink {
|
|||||||
* a callable is recorded by `cc`.
|
* a callable is recorded by `cc`.
|
||||||
*/
|
*/
|
||||||
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, SummaryCtx sc, AccessPath ap) {
|
||||||
exists(
|
exists(AccessPath ap0, Node midnode, Configuration conf, LocalCallContext localCC |
|
||||||
AccessPath ap0, Node midnode, Configuration conf, DataFlowCallable enclosing,
|
midnode = mid.getNode() and
|
||||||
LocalCallContext localCC
|
conf = mid.getConfiguration() and
|
||||||
|
|
cc = mid.getCallContext() and
|
||||||
pathIntoLocalStep(mid, midnode, cc, enclosing, sc, ap0, conf) and
|
sc = mid.getSummaryCtx() and
|
||||||
localCC = getLocalCallContext(cc, enclosing)
|
localCC = getLocalCallContext(cc, midnode.getEnclosingCallable()) and
|
||||||
|
ap0 = mid.getAp()
|
||||||
|
|
|
|
||||||
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
localFlowBigStep(midnode, node, true, _, conf, localCC) and
|
||||||
ap = ap0
|
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()
|
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]
|
pragma[nomagic]
|
||||||
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
private predicate readCand(Node node1, Content f, Node node2, Configuration config) {
|
||||||
readDirect(node1, f, node2) and
|
readDirect(node1, f, node2) and
|
||||||
|
|||||||
@@ -370,6 +370,10 @@
|
|||||||
| Finally.cs:211:13:211:29 | ...; | Finally.cs:213:9:213:24 | ... = ... | 8 |
|
| 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(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: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 | 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: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 |
|
| Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | 1 |
|
||||||
|
|||||||
@@ -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: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: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: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: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: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 |
|
| 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:24 | ... = ... | Finally.cs:213:22:213:24 | "1" |
|
||||||
| Finally.cs:213:9:213:25 | ...; | Finally.cs:211:13:211:28 | ... = ... |
|
| 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: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: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: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 |
|
| 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.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(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: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 | 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 | enter M1 | Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... |
|
| 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.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(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: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 | 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 | enter M1 |
|
||||||
| Foreach.cs:6:10:6:11 | exit M1 | Foreach.cs:6:10:6:11 | exit M1 |
|
| Foreach.cs:6:10:6:11 | exit M1 | Foreach.cs:6:10:6:11 | exit M1 |
|
||||||
|
|||||||
@@ -1742,6 +1742,26 @@ nodeEnclosing
|
|||||||
| Finally.cs:213:9:213:24 | ... = ... | Finally.cs:195:10:195:12 | M10 |
|
| 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: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: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 | 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: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 |
|
| 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.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(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: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 | 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: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 |
|
| Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | Foreach.cs:6:10:6:11 | M1 |
|
||||||
|
|||||||
@@ -1169,6 +1169,24 @@
|
|||||||
| Finally.cs:213:9:213:24 | ... = ... | Finally.cs:213:9:213:12 | this access |
|
| 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: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: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: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: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 |
|
| Foreach.cs:8:22:8:24 | String arg | Foreach.cs:8:22:8:24 | String arg |
|
||||||
|
|||||||
@@ -1652,6 +1652,31 @@
|
|||||||
| Finally.cs:213:9:213:24 | ... = ... | Finally.cs:213:9:213:24 | ... = ... | normal |
|
| 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: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: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: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: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 |
|
| Foreach.cs:8:22:8:24 | String arg | Foreach.cs:8:22:8:24 | String arg | normal |
|
||||||
|
|||||||
@@ -212,4 +212,21 @@ public class Finally
|
|||||||
}
|
}
|
||||||
this.Field = "1";
|
this.Field = "1";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void M11()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Console.WriteLine("Try");
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Console.WriteLine("Catch");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Console.WriteLine("Finally");
|
||||||
|
}
|
||||||
|
Console.WriteLine("Done");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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: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: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: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: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: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 |
|
| Foreach.cs:8:9:9:13 | foreach (... ... in ...) ... | Foreach.cs:6:10:6:11 | exit M1 | semmle.label | empty |
|
||||||
|
|||||||
@@ -710,6 +710,7 @@ entryPoint
|
|||||||
| Finally.cs:147:10:147:11 | M8 | Finally.cs:148:5:170:5 | {...} |
|
| 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: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: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: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:12:10:12:11 | M2 | Foreach.cs:13:5:16:5 | {...} |
|
||||||
| Foreach.cs:18:10:18:11 | M3 | Foreach.cs:19:5:22:5 | {...} |
|
| Foreach.cs:18:10:18:11 | M3 | Foreach.cs:19:5:22:5 | {...} |
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ generates html slide shows in the ``<slides-output>`` directory when run from
|
|||||||
the ``ql-training`` source directory.
|
the ``ql-training`` source directory.
|
||||||
|
|
||||||
For more information about creating slides for QL training and variant analysis
|
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
|
Viewing the current version of the CodeQL documentation
|
||||||
*******************************************************
|
*******************************************************
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class QLLexer(RegexLexer):
|
|||||||
'max', 'min', 'module', 'newtype', 'not', 'none', 'or', 'order',
|
'max', 'min', 'module', 'newtype', 'not', 'none', 'or', 'order',
|
||||||
'predicate', 'rank', 'result', 'select', 'strictconcat',
|
'predicate', 'rank', 'result', 'select', 'strictconcat',
|
||||||
'strictcount', 'strictsum', 'sum', 'super', 'then', 'this',
|
'strictcount', 'strictsum', 'sum', 'super', 'then', 'this',
|
||||||
'true', 'where'), prefix=r'\b', suffix=r'\b'),
|
'true', 'unique', 'where'), prefix=r'\b', suffix=r'\b'),
|
||||||
Keyword),
|
Keyword),
|
||||||
# Identifiers
|
# Identifiers
|
||||||
(r'@?\w', Name),
|
(r'@?\w', Name),
|
||||||
|
|||||||
@@ -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.
|
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
|
Using global data flow
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
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
|
Using global data flow
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
|
||||||
@@ -15,5 +15,6 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat
|
|||||||
Further reading
|
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 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/>`__.
|
- For more information about the library for Go see the `CodeQL library for Go <https://help.semmle.com/qldoc/go/>`__.
|
||||||
@@ -3,7 +3,7 @@ Learning CodeQL
|
|||||||
|
|
||||||
CodeQL is the code analysis platform used by security researchers to automate variant analysis.
|
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.
|
You can use CodeQL queries to explore code and quickly find variants of security vulnerabilities and bugs.
|
||||||
These queries are easy to write and share–visit 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 share–visit 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>`__.
|
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.
|
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
|
javascript/ql-for-javascript
|
||||||
python/ql-for-python
|
python/ql-for-python
|
||||||
ql-training
|
ql-training
|
||||||
technical-info
|
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:hidden:
|
:hidden:
|
||||||
|
|||||||
@@ -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.
|
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
|
Using global data flow
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
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.
|
more time and memory than local analysis.
|
||||||
|
|
||||||
|
.. pull-quote:: Note
|
||||||
|
|
||||||
|
.. include:: ../../reusables/path-problem.rst
|
||||||
|
|
||||||
Using global data flow
|
Using global data flow
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,6 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat
|
|||||||
Further reading
|
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 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/>`__.
|
- For more information about the library for JavaScript see the `CodeQL library for Python <https://help.semmle.com/qldoc/python/>`__.
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
Technical information
|
|
||||||
=====================
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:hidden:
|
|
||||||
|
|
||||||
database
|
|
||||||
|
|
||||||
- :doc:`What's in a CodeQL database? <database>`
|
|
||||||
@@ -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 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.
|
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.
|
QL is a general-purpose, object-oriented language that can be used to query any kind of data.
|
||||||
|
|
||||||
CodeQL databases
|
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.
|
||||||
|
|||||||
@@ -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.
|
- **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.
|
- **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::
|
.. 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>`__.
|
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
|
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:
|
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 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 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.
|
- 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.
|
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:
|
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>`.
|
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
|
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
|
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>`__.
|
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
|
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:
|
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>`
|
- :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
|
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?
|
What next?
|
||||||
==========
|
==========
|
||||||
|
|||||||
@@ -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.
|
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.
|
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::
|
.. pull-quote::
|
||||||
@@ -12,8 +12,8 @@ For more information about how to write useful query help in a style that is con
|
|||||||
Note
|
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 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>`__.
|
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/Semmle/ql/tree/master/javascript/ql/src/Security>`__ and `C/C++ critical queries <https://github.com/Semmle/ql/tree/master/cpp/ql/src/Critical>`__.
|
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.
|
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
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
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
|
.. code-block:: xml
|
||||||
|
|
||||||
@@ -177,12 +177,12 @@ Section-level ``include`` elements can be located beneath the top-level ``qhelp`
|
|||||||
<include src="XSS.qhelp" />
|
<include src="XSS.qhelp" />
|
||||||
</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
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
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
|
.. code-block:: xml
|
||||||
|
|
||||||
@@ -193,7 +193,7 @@ Block-level ``include`` elements can be included beneath section-level elements.
|
|||||||
...
|
...
|
||||||
</qhelp>
|
</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
|
.. code-block:: xml
|
||||||
|
|
||||||
@@ -209,5 +209,5 @@ The included file, `ThreadUnsafeICryptoTransformOverview.qhelp <https://github.
|
|||||||
Further information
|
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>`__.
|
- 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>`__.
|
||||||
|
|||||||
@@ -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.
|
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.
|
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>`__.
|
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::
|
.. pull-quote::
|
||||||
@@ -98,7 +98,7 @@ Here is the metadata for one of the standard Java queries:
|
|||||||
|
|
||||||
.. |image0| image:: ../../images/query-metadata.png
|
.. |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>`__.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -385,7 +385,7 @@ Algebraic datatypes
|
|||||||
*******************
|
*******************
|
||||||
|
|
||||||
.. note:: The syntax for algebraic datatypes is considered experimental and is subject to
|
.. 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.
|
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``.
|
An algebraic datatype is another form of user-defined type, declared with the keyword ``newtype``.
|
||||||
|
|||||||
@@ -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:
|
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/github/codeql/blob/master/cpp/ql/src/semmlecode.cpp.dbscheme
|
||||||
- https://github.com/Semmle/ql/blob/master/csharp/ql/src/semmlecode.csharp.dbscheme
|
- https://github.com/github/codeql/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/java/ql/src/config/semmlecode.dbscheme
|
||||||
@@ -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.
|
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 developer’s 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 developer’s 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>`__.
|
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.
|
- All common logic connectives are available, including quantifiers like ``exist``, which can also introduce new variables.
|
||||||
- The language is declarative–the user focuses on stating what they would like to find, and leaves the details of how to evaluate the query to the engine.
|
- The language is declarative–the 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 top–for 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 top–for 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.
|
- 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>`__.
|
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
Reference in New Issue
Block a user