mirror of
https://github.com/github/codeql.git
synced 2025-12-21 03:06:31 +01:00
Merge branch 'master' into rdmarsh/cpp/ir-flow-through-outparams
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -19,5 +19,6 @@
|
|||||||
|
|
||||||
# It's useful (though not required) to be able to unpack codeql in the ql checkout itself
|
# It's useful (though not required) to be able to unpack codeql in the ql checkout itself
|
||||||
/codeql/
|
/codeql/
|
||||||
.vscode/settings.json
|
|
||||||
csharp/extractor/Semmle.Extraction.CSharp.Driver/Properties/launchSettings.json
|
csharp/extractor/Semmle.Extraction.CSharp.Driver/Properties/launchSettings.json
|
||||||
|
.vscode
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Contributing to CodeQL
|
# Contributing to CodeQL
|
||||||
|
|
||||||
We welcome contributions to our CodeQL libraries and queries. Got an idea for a new check, or how to improve an existing query? Then please go ahead and open a pull request!
|
We welcome contributions to our CodeQL libraries and queries. Got an idea for a new check, or how to improve an existing query? Then please go ahead and open a pull request! Contributions to this project are [released](https://help.github.com/articles/github-terms-of-service/#6-contributions-under-repository-license) to the public under the [project's open source license](LICENSE).
|
||||||
|
|
||||||
There is lots of useful documentation to help you write queries, ranging from information about query file structure to tutorials for specific target languages. For more information on the documentation available, see [Writing CodeQL queries](https://help.semmle.com/QL/learn-ql/writing-queries/writing-queries.html) on [help.semmle.com](https://help.semmle.com).
|
There is lots of useful documentation to help you write queries, ranging from information about query file structure to tutorials for specific target languages. For more information on the documentation available, see [Writing CodeQL queries](https://help.semmle.com/QL/learn-ql/writing-queries/writing-queries.html) on [help.semmle.com](https://help.semmle.com).
|
||||||
|
|
||||||
@@ -47,10 +47,6 @@ If you have an idea for a query that you would like to share with other CodeQL u
|
|||||||
|
|
||||||
- The query must have at least one true positive result on some revision of a real project.
|
- The query must have at least one true positive result on some revision of a real project.
|
||||||
|
|
||||||
6. **Contributor License Agreement**
|
|
||||||
|
|
||||||
- The contributor can satisfy the [CLA](#contributor-license-agreement).
|
|
||||||
|
|
||||||
Experimental queries and libraries may not be actively maintained as the [supported](docs/supported-queries.md) libraries evolve. They may also be changed in backwards-incompatible ways or may be removed entirely in the future without deprecation warnings.
|
Experimental queries and libraries may not be actively maintained as the [supported](docs/supported-queries.md) libraries evolve. They may also be changed in backwards-incompatible ways or may be removed entirely in the future without deprecation warnings.
|
||||||
|
|
||||||
After the experimental query is merged, we welcome pull requests to improve it. Before a query can be moved out of the `experimental` subdirectory, it must satisfy [the requirements for being a supported query](docs/supported-queries.md).
|
After the experimental query is merged, we welcome pull requests to improve it. Before a query can be moved out of the `experimental` subdirectory, it must satisfy [the requirements for being a supported query](docs/supported-queries.md).
|
||||||
@@ -65,33 +61,6 @@ normal course of software development. We also store records of your
|
|||||||
CLA agreements. Under GDPR legislation, we do this
|
CLA agreements. Under GDPR legislation, we do this
|
||||||
on the basis of our legitimate interest in creating the CodeQL product.
|
on the basis of our legitimate interest in creating the CodeQL product.
|
||||||
|
|
||||||
Please do get in touch (privacy@semmle.com) if you have any questions about
|
Please do get in touch (privacy@github.com) if you have any questions about
|
||||||
this or our data protection policies.
|
this or our data protection policies.
|
||||||
|
|
||||||
## Contributor License Agreement
|
|
||||||
|
|
||||||
This Contributor License Agreement (“Agreement”) is entered into between Semmle Limited (“Semmle,” “we” or “us” etc.), and You (as defined and further identified below).
|
|
||||||
|
|
||||||
Accordingly, You hereby agree to the following terms for Your present and future Contributions submitted to Semmle:
|
|
||||||
|
|
||||||
1. **Definitions**.
|
|
||||||
|
|
||||||
* "You" (or "Your") shall mean the Contribution copyright owner (whether an individual or organization) or legal entity authorized by the copyright owner that is making this Agreement with Semmle. For legal entities, the entity making a Contribution and all other entities that control, are controlled by, or are under common control with that entity are considered to be a single Contributor. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
* "Contribution(s)" shall mean the code, documentation or other original works of authorship, including any modifications or additions to an existing work, submitted by You to Semmle for inclusion in, or documentation of, any of the products or projects owned or managed by Semmle (the "Work(s)"). For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to Semmle or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, Semmle for the purpose of discussing and/or improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by You as "Not a Contribution."
|
|
||||||
|
|
||||||
2. **Grant of Copyright License**. You hereby grant to Semmle and to recipients of software distributed by Semmle a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Your Contributions and such derivative works.
|
|
||||||
|
|
||||||
3. **Grant of Patent License**. You hereby grant to Semmle and to recipients of software distributed by Semmle a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by You that are necessarily infringed by Your Contribution(s) alone or by combination of Your Contribution(s) with the Work to which such Contribution(s) was submitted. If any entity institutes patent litigation against You or any other entity (including a cross-claim or counterclaim in a lawsuit) alleging that Your Contribution, or the Work to which You have contributed, constitutes direct or contributory patent infringement, then any patent licenses granted to that entity under this Agreement for that Contribution or Work shall terminate as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. **Ownership**. Except as set out above, You keep all right, title, and interest in Your Contribution. The rights that You grant to us under this Agreement are effective on the date You first submitted a Contribution to us, even if Your submission took place before the date You entered this Agreement.
|
|
||||||
|
|
||||||
5. **Representations**. You represent and warrant that: (i) the Contributions are an original work and that You can legally grant the rights set out in this Agreement; (ii) the Contributions and Semmle’s exercise of any license rights granted hereunder, does not and will not, infringe the rights of any third party; (iii) You are not aware of any pending or threatened claims, suits, actions, or charges pertaining to the Contributions, including without limitation any claims or allegations that any or all of the Contributions infringes, violates, or misappropriate the intellectual property rights of any third party (You further agree that You will notify Semmle immediately if You become aware of any such actual or potential claims, suits, actions, allegations or charges).
|
|
||||||
|
|
||||||
6. **Employer**. If Your employer(s) has rights to intellectual property that You create that includes Your Contributions, You represent and warrant that Your employer has waived such rights for Your Contributions to Semmle, or that You have received permission to make Contributions on behalf of that employer and that You are authorized to execute this Agreement on behalf of Your employer.
|
|
||||||
|
|
||||||
7. **Inclusion of Code**. We determine the code that is in our Works. You understand that the decision to include the Contribution in any project or source repository is entirely that of Semmle, and this agreement does not guarantee that the Contributions will be included in any product.
|
|
||||||
|
|
||||||
8. **Disclaimer**. You are not expected to provide support for Your Contributions, except to the extent You desire to provide support. You may provide support for free, for a fee, or not at all. Except as set forth herein, and unless required by applicable law or agreed to in writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND.
|
|
||||||
|
|
||||||
9. **General**. The failure of either party to enforce its rights under this Agreement for any period shall not be construed as a waiver of such rights. No changes or modifications or waivers to this Agreement will be effective unless in writing and signed by both parties. In the event that any provision of this Agreement shall be determined to be illegal or unenforceable, that provision will be limited or eliminated to the minimum extent necessary so that this Agreement shall otherwise remain in full force and effect and enforceable. This Agreement shall be governed by and construed in accordance with the laws of the State of California in the United States without regard to the conflicts of laws provisions thereof. In any action or proceeding to enforce rights under this Agreement, the prevailing party will be entitled to recover costs and attorneys’ fees.
|
|
||||||
|
|||||||
13
COPYRIGHT
13
COPYRIGHT
@@ -1,13 +0,0 @@
|
|||||||
Copyright (c) Semmle Inc and other contributors. All rights reserved.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
||||||
this file except in compliance with the License. You may obtain a copy of the
|
|
||||||
License at http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
|
||||||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
|
||||||
MERCHANTABLITY OR NON-INFRINGEMENT.
|
|
||||||
|
|
||||||
See the Apache Version 2.0 License for specific language governing permissions
|
|
||||||
and limitations under the License.
|
|
||||||
189
LICENSE
189
LICENSE
@@ -1,176 +1,21 @@
|
|||||||
Apache License
|
MIT License
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
Copyright (c) 2006-2020 GitHub, Inc.
|
||||||
|
|
||||||
1. Definitions.
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
The above copyright notice and this permission notice shall be included in all
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
the copyright owner that is granting the License.
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
other entities that control, are controlled by, or are under common
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
control with that entity. For the purposes of this definition,
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
SOFTWARE.
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ The following changes in version 1.24 affect C/C++ analysis in all applications.
|
|||||||
| 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. |
|
| No space for zero terminator (`cpp/no-space-for-terminator`) | More correct results | String arguments to formatting functions are now (usually) expected to be null terminated strings. |
|
||||||
| Hard-coded Japanese era start date (`cpp/japanese-era/exact-era-date`) | | This query is no longer run on LGTM. |
|
| 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. |
|
| 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. |
|
||||||
| 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. |
|
||||||
| 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`. |
|
||||||
@@ -46,9 +47,11 @@ The following changes in version 1.24 affect C/C++ analysis in all applications.
|
|||||||
`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`.
|
* The models library models `strlen` in more detail, and includes common variations such as `wcslen`.
|
||||||
* The models library models `gets` and similar functions.
|
* The models library models `gets` and similar functions.
|
||||||
|
* The models library now partially models `std::string`.
|
||||||
* The taint tracking library (`semmle.code.cpp.dataflow.TaintTracking`) has had
|
* The taint tracking library (`semmle.code.cpp.dataflow.TaintTracking`) has had
|
||||||
the following improvements:
|
the following improvements:
|
||||||
* The library now models data flow through `strdup` and similar functions.
|
* The library now models data flow through `strdup` and similar functions.
|
||||||
* The library now models data flow through 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 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.
|
* 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.
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ The following changes in version 1.24 affect C# analysis in all applications.
|
|||||||
| 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`. |
|
| 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. |
|
| XPath injection (`cs/xml/xpath-injection`) | More results | The query now recognizes calls to methods on `System.Xml.XPath.XPathNavigator` objects. |
|
||||||
|
| Information exposure through transmitted data (`cs/sensitive-data-transmission`) | More results | The query now recognizes writes to cookies and writes to ASP.NET (`Inner`)`Text` properties as additional sinks. |
|
||||||
|
| Information exposure through an exception (`cs/information-exposure-through-exception`) | More results | The query now recognizes writes to cookies, writes to ASP.NET (`Inner`)`Text` properties, and email contents as additional sinks. |
|
||||||
|
|
||||||
## Removal of old queries
|
## Removal of old queries
|
||||||
|
|
||||||
@@ -42,5 +44,6 @@ The following changes in version 1.24 affect C# analysis in all applications.
|
|||||||
* [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.
|
||||||
|
|
||||||
## Changes to autobuilder
|
## Changes to autobuilder
|
||||||
|
|||||||
@@ -86,6 +86,7 @@
|
|||||||
| 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. |
|
| 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. |
|
| 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. |
|
| 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 more variations of URL scheme checks. |
|
||||||
|
|
||||||
## Changes to libraries
|
## Changes to libraries
|
||||||
|
|
||||||
|
|||||||
@@ -242,6 +242,13 @@
|
|||||||
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/gvn/ValueNumbering.qll",
|
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/gvn/ValueNumbering.qll",
|
||||||
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/gvn/ValueNumbering.qll"
|
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/gvn/ValueNumbering.qll"
|
||||||
],
|
],
|
||||||
|
"C++ IR PrintValueNumbering": [
|
||||||
|
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/gvn/PrintValueNumbering.qll",
|
||||||
|
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/gvn/PrintValueNumbering.qll",
|
||||||
|
"cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/gvn/PrintValueNumbering.qll",
|
||||||
|
"csharp/ql/src/semmle/code/csharp/ir/implementation/raw/gvn/PrintValueNumbering.qll",
|
||||||
|
"csharp/ql/src/semmle/code/csharp/ir/implementation/unaliased_ssa/gvn/PrintValueNumbering.qll"
|
||||||
|
],
|
||||||
"C++ IR ConstantAnalysis": [
|
"C++ IR ConstantAnalysis": [
|
||||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/constant/ConstantAnalysis.qll",
|
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/constant/ConstantAnalysis.qll",
|
||||||
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/constant/ConstantAnalysis.qll",
|
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/constant/ConstantAnalysis.qll",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ private predicate freed(Expr e) {
|
|||||||
e = any(DeallocationExpr de).getFreedExpr()
|
e = any(DeallocationExpr de).getFreedExpr()
|
||||||
or
|
or
|
||||||
exists(ExprCall c |
|
exists(ExprCall c |
|
||||||
// cautiously assume that any ExprCall could be a freeCall.
|
// cautiously assume that any `ExprCall` could be a deallocation expression.
|
||||||
c.getAnArgument() = e
|
c.getAnArgument() = e
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,17 +5,34 @@
|
|||||||
import cpp
|
import cpp
|
||||||
import semmle.code.cpp.controlflow.SSA
|
import semmle.code.cpp.controlflow.SSA
|
||||||
import semmle.code.cpp.dataflow.DataFlow
|
import semmle.code.cpp.dataflow.DataFlow
|
||||||
|
import semmle.code.cpp.models.implementations.Allocation
|
||||||
|
import semmle.code.cpp.models.implementations.Deallocation
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `alloc` is a use of `malloc` or `new`. `kind` is
|
* Holds if `alloc` is a use of `malloc` or `new`. `kind` is
|
||||||
* a string describing the type of the allocation.
|
* a string describing the type of the allocation.
|
||||||
*/
|
*/
|
||||||
predicate allocExpr(Expr alloc, string kind) {
|
predicate allocExpr(Expr alloc, string kind) {
|
||||||
isAllocationExpr(alloc) and
|
|
||||||
not alloc.isFromUninstantiatedTemplate(_) and
|
|
||||||
(
|
(
|
||||||
alloc instanceof FunctionCall and
|
exists(Function target |
|
||||||
kind = "malloc"
|
alloc.(AllocationExpr).(FunctionCall).getTarget() = target and
|
||||||
|
(
|
||||||
|
target.getName() = "operator new" and
|
||||||
|
kind = "new" and
|
||||||
|
// exclude placement new and custom overloads as they
|
||||||
|
// may not conform to assumptions
|
||||||
|
not target.getNumberOfParameters() > 1
|
||||||
|
or
|
||||||
|
target.getName() = "operator new[]" and
|
||||||
|
kind = "new[]" and
|
||||||
|
// exclude placement new and custom overloads as they
|
||||||
|
// may not conform to assumptions
|
||||||
|
not target.getNumberOfParameters() > 1
|
||||||
|
or
|
||||||
|
not target instanceof OperatorNewAllocationFunction and
|
||||||
|
kind = "malloc"
|
||||||
|
)
|
||||||
|
)
|
||||||
or
|
or
|
||||||
alloc instanceof NewExpr and
|
alloc instanceof NewExpr and
|
||||||
kind = "new" and
|
kind = "new" and
|
||||||
@@ -28,7 +45,8 @@ predicate allocExpr(Expr alloc, string kind) {
|
|||||||
// exclude placement new and custom overloads as they
|
// exclude placement new and custom overloads as they
|
||||||
// may not conform to assumptions
|
// may not conform to assumptions
|
||||||
not alloc.(NewArrayExpr).getAllocatorCall().getTarget().getNumberOfParameters() > 1
|
not alloc.(NewArrayExpr).getAllocatorCall().getTarget().getNumberOfParameters() > 1
|
||||||
)
|
) and
|
||||||
|
not alloc.isFromUninstantiatedTemplate(_)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -110,8 +128,20 @@ predicate allocReaches(Expr e, Expr alloc, string kind) {
|
|||||||
* describing the type of that free or delete.
|
* describing the type of that free or delete.
|
||||||
*/
|
*/
|
||||||
predicate freeExpr(Expr free, Expr freed, string kind) {
|
predicate freeExpr(Expr free, Expr freed, string kind) {
|
||||||
freeCall(free, freed) and
|
exists(Function target |
|
||||||
kind = "free"
|
freed = free.(DeallocationExpr).getFreedExpr() and
|
||||||
|
free.(FunctionCall).getTarget() = target and
|
||||||
|
(
|
||||||
|
target.getName() = "operator delete" and
|
||||||
|
kind = "delete"
|
||||||
|
or
|
||||||
|
target.getName() = "operator delete[]" and
|
||||||
|
kind = "delete[]"
|
||||||
|
or
|
||||||
|
not target instanceof OperatorDeleteDeallocationFunction and
|
||||||
|
kind = "free"
|
||||||
|
)
|
||||||
|
)
|
||||||
or
|
or
|
||||||
free.(DeleteExpr).getExpr() = freed and
|
free.(DeleteExpr).getExpr() = freed and
|
||||||
kind = "delete"
|
kind = "delete"
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ struct S {
|
|||||||
|
|
||||||
// Whereas here it does make a semantic difference.
|
// Whereas here it does make a semantic difference.
|
||||||
auto getValCorrect() const -> int {
|
auto getValCorrect() const -> int {
|
||||||
return val
|
return val;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* @name Uncontrolled data used in path expression
|
* @name Uncontrolled data used in path expression
|
||||||
* @description Accessing paths influenced by users can allow an
|
* @description Accessing paths influenced by users can allow an
|
||||||
* attacker to access unexpected resources.
|
* attacker to access unexpected resources.
|
||||||
* @kind problem
|
* @kind path-problem
|
||||||
* @problem.severity warning
|
* @problem.severity warning
|
||||||
* @precision medium
|
* @precision medium
|
||||||
* @id cpp/path-injection
|
* @id cpp/path-injection
|
||||||
@@ -17,6 +17,7 @@ import cpp
|
|||||||
import semmle.code.cpp.security.FunctionWithWrappers
|
import semmle.code.cpp.security.FunctionWithWrappers
|
||||||
import semmle.code.cpp.security.Security
|
import semmle.code.cpp.security.Security
|
||||||
import semmle.code.cpp.security.TaintTracking
|
import semmle.code.cpp.security.TaintTracking
|
||||||
|
import TaintedWithPath
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A function for opening a file.
|
* A function for opening a file.
|
||||||
@@ -51,12 +52,19 @@ class FileFunction extends FunctionWithWrappers {
|
|||||||
override predicate interestingArg(int arg) { arg = 0 }
|
override predicate interestingArg(int arg) { arg = 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TaintedPathConfiguration extends TaintTrackingConfiguration {
|
||||||
|
override predicate isSink(Element tainted) {
|
||||||
|
exists(FileFunction fileFunction | fileFunction.outermostWrapperFunctionCall(tainted, _))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
from
|
from
|
||||||
FileFunction fileFunction, Expr taintedArg, Expr taintSource, string taintCause, string callChain
|
FileFunction fileFunction, Expr taintedArg, Expr taintSource, PathNode sourceNode,
|
||||||
|
PathNode sinkNode, string taintCause, string callChain
|
||||||
where
|
where
|
||||||
fileFunction.outermostWrapperFunctionCall(taintedArg, callChain) and
|
fileFunction.outermostWrapperFunctionCall(taintedArg, callChain) and
|
||||||
tainted(taintSource, taintedArg) and
|
taintedWithPath(taintSource, taintedArg, sourceNode, sinkNode) and
|
||||||
isUserInput(taintSource, taintCause)
|
isUserInput(taintSource, taintCause)
|
||||||
select taintedArg,
|
select taintedArg, sourceNode, sinkNode,
|
||||||
"This argument to a file access function is derived from $@ and then passed to " + callChain,
|
"This argument to a file access function is derived from $@ and then passed to " + callChain,
|
||||||
taintSource, "user input (" + taintCause + ")"
|
taintSource, "user input (" + taintCause + ")"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* @name CGI script vulnerable to cross-site scripting
|
* @name CGI script vulnerable to cross-site scripting
|
||||||
* @description Writing user input directly to a web page
|
* @description Writing user input directly to a web page
|
||||||
* allows for a cross-site scripting vulnerability.
|
* allows for a cross-site scripting vulnerability.
|
||||||
* @kind problem
|
* @kind path-problem
|
||||||
* @problem.severity error
|
* @problem.severity error
|
||||||
* @precision high
|
* @precision high
|
||||||
* @id cpp/cgi-xss
|
* @id cpp/cgi-xss
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
import cpp
|
import cpp
|
||||||
import semmle.code.cpp.commons.Environment
|
import semmle.code.cpp.commons.Environment
|
||||||
import semmle.code.cpp.security.TaintTracking
|
import semmle.code.cpp.security.TaintTracking
|
||||||
|
import TaintedWithPath
|
||||||
|
|
||||||
/** A call that prints its arguments to `stdout`. */
|
/** A call that prints its arguments to `stdout`. */
|
||||||
class PrintStdoutCall extends FunctionCall {
|
class PrintStdoutCall extends FunctionCall {
|
||||||
@@ -27,8 +28,13 @@ class QueryString extends EnvironmentRead {
|
|||||||
QueryString() { getEnvironmentVariable() = "QUERY_STRING" }
|
QueryString() { getEnvironmentVariable() = "QUERY_STRING" }
|
||||||
}
|
}
|
||||||
|
|
||||||
from QueryString query, PrintStdoutCall call, Element printedArg
|
class Configuration extends TaintTrackingConfiguration {
|
||||||
where
|
override predicate isSink(Element tainted) {
|
||||||
call.getAnArgument() = printedArg and
|
exists(PrintStdoutCall call | call.getAnArgument() = tainted)
|
||||||
tainted(query, printedArg)
|
}
|
||||||
select printedArg, "Cross-site scripting vulnerability due to $@.", query, "this query data"
|
}
|
||||||
|
|
||||||
|
from QueryString query, Element printedArg, PathNode sourceNode, PathNode sinkNode
|
||||||
|
where taintedWithPath(query, printedArg, sourceNode, sinkNode)
|
||||||
|
select printedArg, sourceNode, sinkNode, "Cross-site scripting vulnerability due to $@.", query,
|
||||||
|
"this query data"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* @description Including user-supplied data in a SQL query without
|
* @description Including user-supplied data in a SQL query without
|
||||||
* neutralizing special elements can make code vulnerable
|
* neutralizing special elements can make code vulnerable
|
||||||
* to SQL Injection.
|
* to SQL Injection.
|
||||||
* @kind problem
|
* @kind path-problem
|
||||||
* @problem.severity error
|
* @problem.severity error
|
||||||
* @precision high
|
* @precision high
|
||||||
* @id cpp/sql-injection
|
* @id cpp/sql-injection
|
||||||
@@ -15,6 +15,7 @@ import cpp
|
|||||||
import semmle.code.cpp.security.Security
|
import semmle.code.cpp.security.Security
|
||||||
import semmle.code.cpp.security.FunctionWithWrappers
|
import semmle.code.cpp.security.FunctionWithWrappers
|
||||||
import semmle.code.cpp.security.TaintTracking
|
import semmle.code.cpp.security.TaintTracking
|
||||||
|
import TaintedWithPath
|
||||||
|
|
||||||
class SQLLikeFunction extends FunctionWithWrappers {
|
class SQLLikeFunction extends FunctionWithWrappers {
|
||||||
SQLLikeFunction() { sqlArgument(this.getName(), _) }
|
SQLLikeFunction() { sqlArgument(this.getName(), _) }
|
||||||
@@ -22,11 +23,19 @@ class SQLLikeFunction extends FunctionWithWrappers {
|
|||||||
override predicate interestingArg(int arg) { sqlArgument(this.getName(), arg) }
|
override predicate interestingArg(int arg) { sqlArgument(this.getName(), arg) }
|
||||||
}
|
}
|
||||||
|
|
||||||
from SQLLikeFunction runSql, Expr taintedArg, Expr taintSource, string taintCause, string callChain
|
class Configuration extends TaintTrackingConfiguration {
|
||||||
|
override predicate isSink(Element tainted) {
|
||||||
|
exists(SQLLikeFunction runSql | runSql.outermostWrapperFunctionCall(tainted, _))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
from
|
||||||
|
SQLLikeFunction runSql, Expr taintedArg, Expr taintSource, PathNode sourceNode, PathNode sinkNode,
|
||||||
|
string taintCause, string callChain
|
||||||
where
|
where
|
||||||
runSql.outermostWrapperFunctionCall(taintedArg, callChain) and
|
runSql.outermostWrapperFunctionCall(taintedArg, callChain) and
|
||||||
tainted(taintSource, taintedArg) and
|
taintedWithPath(taintSource, taintedArg, sourceNode, sinkNode) and
|
||||||
isUserInput(taintSource, taintCause)
|
isUserInput(taintSource, taintCause)
|
||||||
select taintedArg,
|
select taintedArg, sourceNode, sinkNode,
|
||||||
"This argument to a SQL query function is derived from $@ and then passed to " + callChain,
|
"This argument to a SQL query function is derived from $@ and then passed to " + callChain,
|
||||||
taintSource, "user input (" + taintCause + ")"
|
taintSource, "user input (" + taintCause + ")"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* @description Using externally controlled strings in a process
|
* @description Using externally controlled strings in a process
|
||||||
* operation can allow an attacker to execute malicious
|
* operation can allow an attacker to execute malicious
|
||||||
* commands.
|
* commands.
|
||||||
* @kind problem
|
* @kind path-problem
|
||||||
* @problem.severity warning
|
* @problem.severity warning
|
||||||
* @precision medium
|
* @precision medium
|
||||||
* @id cpp/uncontrolled-process-operation
|
* @id cpp/uncontrolled-process-operation
|
||||||
@@ -14,13 +14,24 @@
|
|||||||
import cpp
|
import cpp
|
||||||
import semmle.code.cpp.security.Security
|
import semmle.code.cpp.security.Security
|
||||||
import semmle.code.cpp.security.TaintTracking
|
import semmle.code.cpp.security.TaintTracking
|
||||||
|
import TaintedWithPath
|
||||||
|
|
||||||
from string processOperation, int processOperationArg, FunctionCall call, Expr arg, Element source
|
predicate isProcessOperationExplanation(Expr arg, string processOperation) {
|
||||||
|
exists(int processOperationArg, FunctionCall call |
|
||||||
|
isProcessOperationArgument(processOperation, processOperationArg) and
|
||||||
|
call.getTarget().getName() = processOperation and
|
||||||
|
call.getArgument(processOperationArg) = arg
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
class Configuration extends TaintTrackingConfiguration {
|
||||||
|
override predicate isSink(Element arg) { isProcessOperationExplanation(arg, _) }
|
||||||
|
}
|
||||||
|
|
||||||
|
from string processOperation, Expr arg, Expr source, PathNode sourceNode, PathNode sinkNode
|
||||||
where
|
where
|
||||||
isProcessOperationArgument(processOperation, processOperationArg) and
|
isProcessOperationExplanation(arg, processOperation) and
|
||||||
call.getTarget().getName() = processOperation and
|
taintedWithPath(source, arg, sourceNode, sinkNode)
|
||||||
call.getArgument(processOperationArg) = arg and
|
select arg, sourceNode, sinkNode,
|
||||||
tainted(source, arg)
|
|
||||||
select arg,
|
|
||||||
"The value of this argument may come from $@ and is being passed to " + processOperation, source,
|
"The value of this argument may come from $@ and is being passed to " + processOperation, source,
|
||||||
source.toString()
|
source.toString()
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* @name Unbounded write
|
* @name Unbounded write
|
||||||
* @description Buffer write operations that do not control the length
|
* @description Buffer write operations that do not control the length
|
||||||
* of data written may overflow.
|
* of data written may overflow.
|
||||||
* @kind problem
|
* @kind path-problem
|
||||||
* @problem.severity error
|
* @problem.severity error
|
||||||
* @precision medium
|
* @precision medium
|
||||||
* @id cpp/unbounded-write
|
* @id cpp/unbounded-write
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
import semmle.code.cpp.security.BufferWrite
|
import semmle.code.cpp.security.BufferWrite
|
||||||
import semmle.code.cpp.security.Security
|
import semmle.code.cpp.security.Security
|
||||||
import semmle.code.cpp.security.TaintTracking
|
import semmle.code.cpp.security.TaintTracking
|
||||||
|
import TaintedWithPath
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* --- Summary of CWE-120 alerts ---
|
* --- Summary of CWE-120 alerts ---
|
||||||
@@ -54,32 +55,48 @@ predicate isUnboundedWrite(BufferWrite bw) {
|
|||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `e` is a source buffer going into an unbounded write `bw` or a
|
||||||
|
* qualifier of (a qualifier of ...) such a source.
|
||||||
|
*/
|
||||||
|
predicate unboundedWriteSource(Expr e, BufferWrite bw) {
|
||||||
|
isUnboundedWrite(bw) and e = bw.getASource()
|
||||||
|
or
|
||||||
|
exists(FieldAccess fa | unboundedWriteSource(fa, bw) and e = fa.getQualifier())
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* --- user input reach ---
|
* --- user input reach ---
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
class Configuration extends TaintTrackingConfiguration {
|
||||||
* Identifies expressions that are potentially tainted with user
|
override predicate isSink(Element tainted) { unboundedWriteSource(tainted, _) }
|
||||||
* input. Most of the work for this is actually done by the
|
|
||||||
* TaintTracking library.
|
override predicate taintThroughGlobals() { any() }
|
||||||
*/
|
|
||||||
predicate tainted2(Expr expr, Expr inputSource, string inputCause) {
|
|
||||||
taintedIncludingGlobalVars(inputSource, expr, _) and
|
|
||||||
inputCause = inputSource.toString()
|
|
||||||
or
|
|
||||||
exists(Expr e | tainted2(e, inputSource, inputCause) |
|
|
||||||
// field accesses of a tainted struct are tainted
|
|
||||||
e = expr.(FieldAccess).getQualifier()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* --- put it together ---
|
* --- put it together ---
|
||||||
*/
|
*/
|
||||||
|
|
||||||
from BufferWrite bw, Expr inputSource, string inputCause
|
/*
|
||||||
|
* An unbounded write is, for example `strcpy(..., tainted)`. We're looking
|
||||||
|
* for a tainted source buffer of an unbounded write, where this source buffer
|
||||||
|
* is a sink in the taint-tracking analysis.
|
||||||
|
*
|
||||||
|
* In the case of `gets` and `scanf`, where the source buffer is implicit, the
|
||||||
|
* `BufferWrite` library reports the source buffer to be the same as the
|
||||||
|
* destination buffer. Since those destination-buffer arguments are also
|
||||||
|
* modeled in the taint-tracking library as being _sources_ of taint, they are
|
||||||
|
* in practice reported as being tainted because the `security.TaintTracking`
|
||||||
|
* library does not distinguish between taint going into an argument and out of
|
||||||
|
* an argument. Thus, we get the desired alerts.
|
||||||
|
*/
|
||||||
|
|
||||||
|
from BufferWrite bw, Expr inputSource, Expr tainted, PathNode sourceNode, PathNode sinkNode
|
||||||
where
|
where
|
||||||
isUnboundedWrite(bw) and
|
taintedWithPath(inputSource, tainted, sourceNode, sinkNode) and
|
||||||
tainted2(bw.getASource(), inputSource, inputCause)
|
unboundedWriteSource(tainted, bw)
|
||||||
select bw, "This '" + bw.getBWDesc() + "' with input from $@ may overflow the destination.",
|
select bw, sourceNode, sinkNode,
|
||||||
inputSource, inputCause
|
"This '" + bw.getBWDesc() + "' with input from $@ may overflow the destination.", inputSource,
|
||||||
|
inputSource.toString()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* @description Using externally-controlled format strings in
|
* @description Using externally-controlled format strings in
|
||||||
* printf-style functions can lead to buffer overflows
|
* printf-style functions can lead to buffer overflows
|
||||||
* or data representation problems.
|
* or data representation problems.
|
||||||
* @kind problem
|
* @kind path-problem
|
||||||
* @problem.severity warning
|
* @problem.severity warning
|
||||||
* @precision medium
|
* @precision medium
|
||||||
* @id cpp/tainted-format-string
|
* @id cpp/tainted-format-string
|
||||||
@@ -16,12 +16,21 @@ import cpp
|
|||||||
import semmle.code.cpp.security.Security
|
import semmle.code.cpp.security.Security
|
||||||
import semmle.code.cpp.security.FunctionWithWrappers
|
import semmle.code.cpp.security.FunctionWithWrappers
|
||||||
import semmle.code.cpp.security.TaintTracking
|
import semmle.code.cpp.security.TaintTracking
|
||||||
|
import TaintedWithPath
|
||||||
|
|
||||||
from PrintfLikeFunction printf, Expr arg, string printfFunction, Expr userValue, string cause
|
class Configuration extends TaintTrackingConfiguration {
|
||||||
|
override predicate isSink(Element tainted) {
|
||||||
|
exists(PrintfLikeFunction printf | printf.outermostWrapperFunctionCall(tainted, _))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
from
|
||||||
|
PrintfLikeFunction printf, Expr arg, PathNode sourceNode, PathNode sinkNode,
|
||||||
|
string printfFunction, Expr userValue, string cause
|
||||||
where
|
where
|
||||||
printf.outermostWrapperFunctionCall(arg, printfFunction) and
|
printf.outermostWrapperFunctionCall(arg, printfFunction) and
|
||||||
tainted(userValue, arg) and
|
taintedWithPath(userValue, arg, sourceNode, sinkNode) and
|
||||||
isUserInput(userValue, cause)
|
isUserInput(userValue, cause)
|
||||||
select arg,
|
select arg, sourceNode, sinkNode,
|
||||||
"The value of this argument may come from $@ and is being used as a formatting argument to " +
|
"The value of this argument may come from $@ and is being used as a formatting argument to " +
|
||||||
printfFunction, userValue, cause
|
printfFunction, userValue, cause
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* @description Using externally-controlled format strings in
|
* @description Using externally-controlled format strings in
|
||||||
* printf-style functions can lead to buffer overflows
|
* printf-style functions can lead to buffer overflows
|
||||||
* or data representation problems.
|
* or data representation problems.
|
||||||
* @kind problem
|
* @kind path-problem
|
||||||
* @problem.severity warning
|
* @problem.severity warning
|
||||||
* @precision medium
|
* @precision medium
|
||||||
* @id cpp/tainted-format-string-through-global
|
* @id cpp/tainted-format-string-through-global
|
||||||
@@ -16,15 +16,24 @@ import cpp
|
|||||||
import semmle.code.cpp.security.FunctionWithWrappers
|
import semmle.code.cpp.security.FunctionWithWrappers
|
||||||
import semmle.code.cpp.security.Security
|
import semmle.code.cpp.security.Security
|
||||||
import semmle.code.cpp.security.TaintTracking
|
import semmle.code.cpp.security.TaintTracking
|
||||||
|
import TaintedWithPath
|
||||||
|
|
||||||
|
class Configuration extends TaintTrackingConfiguration {
|
||||||
|
override predicate isSink(Element tainted) {
|
||||||
|
exists(PrintfLikeFunction printf | printf.outermostWrapperFunctionCall(tainted, _))
|
||||||
|
}
|
||||||
|
|
||||||
|
override predicate taintThroughGlobals() { any() }
|
||||||
|
}
|
||||||
|
|
||||||
from
|
from
|
||||||
PrintfLikeFunction printf, Expr arg, string printfFunction, Expr userValue, string cause,
|
PrintfLikeFunction printf, Expr arg, PathNode sourceNode, PathNode sinkNode,
|
||||||
string globalVar
|
string printfFunction, Expr userValue, string cause
|
||||||
where
|
where
|
||||||
printf.outermostWrapperFunctionCall(arg, printfFunction) and
|
printf.outermostWrapperFunctionCall(arg, printfFunction) and
|
||||||
not tainted(_, arg) and
|
not taintedWithoutGlobals(arg) and
|
||||||
taintedIncludingGlobalVars(userValue, arg, globalVar) and
|
taintedWithPath(userValue, arg, sourceNode, sinkNode) and
|
||||||
isUserInput(userValue, cause)
|
isUserInput(userValue, cause)
|
||||||
select arg,
|
select arg, sourceNode, sinkNode,
|
||||||
"This value may flow through $@, originating from $@, and is a formatting argument to " +
|
"The value of this argument may come from $@ and is being used as a formatting argument to " +
|
||||||
printfFunction + ".", globalVarFromId(globalVar), globalVar, userValue, cause
|
printfFunction, userValue, cause
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* @name Uncontrolled data in arithmetic expression
|
* @name Uncontrolled data in arithmetic expression
|
||||||
* @description Arithmetic operations on uncontrolled data that is not
|
* @description Arithmetic operations on uncontrolled data that is not
|
||||||
* validated can cause overflows.
|
* validated can cause overflows.
|
||||||
* @kind problem
|
* @kind path-problem
|
||||||
* @problem.severity warning
|
* @problem.severity warning
|
||||||
* @precision medium
|
* @precision medium
|
||||||
* @id cpp/uncontrolled-arithmetic
|
* @id cpp/uncontrolled-arithmetic
|
||||||
@@ -15,6 +15,7 @@ import cpp
|
|||||||
import semmle.code.cpp.security.Overflow
|
import semmle.code.cpp.security.Overflow
|
||||||
import semmle.code.cpp.security.Security
|
import semmle.code.cpp.security.Security
|
||||||
import semmle.code.cpp.security.TaintTracking
|
import semmle.code.cpp.security.TaintTracking
|
||||||
|
import TaintedWithPath
|
||||||
|
|
||||||
predicate isRandCall(FunctionCall fc) { fc.getTarget().getName() = "rand" }
|
predicate isRandCall(FunctionCall fc) { fc.getTarget().getName() = "rand" }
|
||||||
|
|
||||||
@@ -40,9 +41,22 @@ class SecurityOptionsArith extends SecurityOptions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate taintedVarAccess(Expr origin, VariableAccess va) {
|
predicate isDiv(VariableAccess va) { exists(AssignDivExpr div | div.getLValue() = va) }
|
||||||
isUserInput(origin, _) and
|
|
||||||
tainted(origin, va)
|
predicate missingGuard(VariableAccess va, string effect) {
|
||||||
|
exists(Operation op | op.getAnOperand() = va |
|
||||||
|
missingGuardAgainstUnderflow(op, va) and effect = "underflow"
|
||||||
|
or
|
||||||
|
missingGuardAgainstOverflow(op, va) and effect = "overflow"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
class Configuration extends TaintTrackingConfiguration {
|
||||||
|
override predicate isSink(Element e) {
|
||||||
|
isDiv(e)
|
||||||
|
or
|
||||||
|
missingGuard(e, _)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,19 +64,17 @@ predicate taintedVarAccess(Expr origin, VariableAccess va) {
|
|||||||
* range.
|
* range.
|
||||||
*/
|
*/
|
||||||
predicate guardedByAssignDiv(Expr origin) {
|
predicate guardedByAssignDiv(Expr origin) {
|
||||||
isUserInput(origin, _) and
|
exists(VariableAccess va |
|
||||||
exists(AssignDivExpr div, VariableAccess va | tainted(origin, va) and div.getLValue() = va)
|
taintedWithPath(origin, va, _, _) and
|
||||||
|
isDiv(va)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
from Expr origin, Operation op, VariableAccess va, string effect
|
from Expr origin, VariableAccess va, string effect, PathNode sourceNode, PathNode sinkNode
|
||||||
where
|
where
|
||||||
taintedVarAccess(origin, va) and
|
taintedWithPath(origin, va, sourceNode, sinkNode) and
|
||||||
op.getAnOperand() = va and
|
missingGuard(va, effect) and
|
||||||
(
|
|
||||||
missingGuardAgainstUnderflow(op, va) and effect = "underflow"
|
|
||||||
or
|
|
||||||
missingGuardAgainstOverflow(op, va) and effect = "overflow"
|
|
||||||
) and
|
|
||||||
not guardedByAssignDiv(origin)
|
not guardedByAssignDiv(origin)
|
||||||
select va, "$@ flows to here and is used in arithmetic, potentially causing an " + effect + ".",
|
select va, sourceNode, sinkNode,
|
||||||
origin, "Uncontrolled value"
|
"$@ flows to here and is used in arithmetic, potentially causing an " + effect + ".", origin,
|
||||||
|
"Uncontrolled value"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* @name Overflow in uncontrolled allocation size
|
* @name Overflow in uncontrolled allocation size
|
||||||
* @description Allocating memory with a size controlled by an external
|
* @description Allocating memory with a size controlled by an external
|
||||||
* user can result in integer overflow.
|
* user can result in integer overflow.
|
||||||
* @kind problem
|
* @kind path-problem
|
||||||
* @problem.severity error
|
* @problem.severity error
|
||||||
* @precision high
|
* @precision high
|
||||||
* @id cpp/uncontrolled-allocation-size
|
* @id cpp/uncontrolled-allocation-size
|
||||||
@@ -13,21 +13,33 @@
|
|||||||
|
|
||||||
import cpp
|
import cpp
|
||||||
import semmle.code.cpp.security.TaintTracking
|
import semmle.code.cpp.security.TaintTracking
|
||||||
|
import TaintedWithPath
|
||||||
|
|
||||||
predicate taintedAllocSize(Expr e, Expr source, string taintCause) {
|
predicate taintedChild(Expr e, Expr tainted) {
|
||||||
(
|
(
|
||||||
isAllocationExpr(e) or
|
isAllocationExpr(e)
|
||||||
|
or
|
||||||
any(MulExpr me | me.getAChild() instanceof SizeofOperator) = e
|
any(MulExpr me | me.getAChild() instanceof SizeofOperator) = e
|
||||||
) and
|
) and
|
||||||
|
tainted = e.getAChild() and
|
||||||
|
tainted.getUnspecifiedType() instanceof IntegralType
|
||||||
|
}
|
||||||
|
|
||||||
|
class TaintedAllocationSizeConfiguration extends TaintTrackingConfiguration {
|
||||||
|
override predicate isSink(Element tainted) { taintedChild(_, tainted) }
|
||||||
|
}
|
||||||
|
|
||||||
|
predicate taintedAllocSize(
|
||||||
|
Expr e, Expr source, PathNode sourceNode, PathNode sinkNode, string taintCause
|
||||||
|
) {
|
||||||
|
isUserInput(source, taintCause) and
|
||||||
exists(Expr tainted |
|
exists(Expr tainted |
|
||||||
tainted = e.getAChild() and
|
taintedChild(e, tainted) and
|
||||||
tainted.getUnspecifiedType() instanceof IntegralType and
|
taintedWithPath(source, tainted, sourceNode, sinkNode)
|
||||||
isUserInput(source, taintCause) and
|
|
||||||
tainted(source, tainted)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
from Expr e, Expr source, string taintCause
|
from Expr e, Expr source, PathNode sourceNode, PathNode sinkNode, string taintCause
|
||||||
where taintedAllocSize(e, source, taintCause)
|
where taintedAllocSize(e, source, sourceNode, sinkNode, taintCause)
|
||||||
select e, "This allocation size is derived from $@ and might overflow", source,
|
select e, sourceNode, sinkNode, "This allocation size is derived from $@ and might overflow",
|
||||||
"user input (" + taintCause + ")"
|
source, "user input (" + taintCause + ")"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* @description Authentication by checking that the peer's address
|
* @description Authentication by checking that the peer's address
|
||||||
* matches a known IP or web address is unsafe as it is
|
* matches a known IP or web address is unsafe as it is
|
||||||
* vulnerable to spoofing attacks.
|
* vulnerable to spoofing attacks.
|
||||||
* @kind problem
|
* @kind path-problem
|
||||||
* @problem.severity warning
|
* @problem.severity warning
|
||||||
* @precision medium
|
* @precision medium
|
||||||
* @id cpp/user-controlled-bypass
|
* @id cpp/user-controlled-bypass
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import semmle.code.cpp.security.TaintTracking
|
import semmle.code.cpp.security.TaintTracking
|
||||||
|
import TaintedWithPath
|
||||||
|
|
||||||
predicate hardCodedAddressOrIP(StringLiteral txt) {
|
predicate hardCodedAddressOrIP(StringLiteral txt) {
|
||||||
exists(string s | s = txt.getValueText() |
|
exists(string s | s = txt.getValueText() |
|
||||||
@@ -102,16 +103,21 @@ predicate useOfHardCodedAddressOrIP(Expr use) {
|
|||||||
* untrusted input then it might be vulnerable to a spoofing
|
* untrusted input then it might be vulnerable to a spoofing
|
||||||
* attack.
|
* attack.
|
||||||
*/
|
*/
|
||||||
predicate hardCodedAddressInCondition(Expr source, Expr condition) {
|
predicate hardCodedAddressInCondition(Expr subexpression, Expr condition) {
|
||||||
// One of the sub-expressions of the condition is tainted.
|
subexpression = condition.getAChild+() and
|
||||||
exists(Expr taintedExpr | taintedExpr.getParent+() = condition | tainted(source, taintedExpr)) and
|
|
||||||
// One of the sub-expressions of the condition is a hard-coded
|
// One of the sub-expressions of the condition is a hard-coded
|
||||||
// IP or web-address.
|
// IP or web-address.
|
||||||
exists(Expr use | use.getParent+() = condition | useOfHardCodedAddressOrIP(use)) and
|
exists(Expr use | use = condition.getAChild+() | useOfHardCodedAddressOrIP(use)) and
|
||||||
condition = any(IfStmt ifStmt).getCondition()
|
condition = any(IfStmt ifStmt).getCondition()
|
||||||
}
|
}
|
||||||
|
|
||||||
from Expr source, Expr condition
|
class Configuration extends TaintTrackingConfiguration {
|
||||||
where hardCodedAddressInCondition(source, condition)
|
override predicate isSink(Element sink) { hardCodedAddressInCondition(sink, _) }
|
||||||
select condition, "Untrusted input $@ might be vulnerable to a spoofing attack.", source,
|
}
|
||||||
source.toString()
|
|
||||||
|
from Expr subexpression, Expr source, Expr condition, PathNode sourceNode, PathNode sinkNode
|
||||||
|
where
|
||||||
|
hardCodedAddressInCondition(subexpression, condition) and
|
||||||
|
taintedWithPath(source, subexpression, sourceNode, sinkNode)
|
||||||
|
select condition, sourceNode, sinkNode,
|
||||||
|
"Untrusted input $@ might be vulnerable to a spoofing attack.", source, source.toString()
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* @name Cleartext storage of sensitive information in buffer
|
* @name Cleartext storage of sensitive information in buffer
|
||||||
* @description Storing sensitive information in cleartext can expose it
|
* @description Storing sensitive information in cleartext can expose it
|
||||||
* to an attacker.
|
* to an attacker.
|
||||||
* @kind problem
|
* @kind path-problem
|
||||||
* @problem.severity warning
|
* @problem.severity warning
|
||||||
* @precision medium
|
* @precision medium
|
||||||
* @id cpp/cleartext-storage-buffer
|
* @id cpp/cleartext-storage-buffer
|
||||||
@@ -14,12 +14,20 @@ import cpp
|
|||||||
import semmle.code.cpp.security.BufferWrite
|
import semmle.code.cpp.security.BufferWrite
|
||||||
import semmle.code.cpp.security.TaintTracking
|
import semmle.code.cpp.security.TaintTracking
|
||||||
import semmle.code.cpp.security.SensitiveExprs
|
import semmle.code.cpp.security.SensitiveExprs
|
||||||
|
import TaintedWithPath
|
||||||
|
|
||||||
from BufferWrite w, Expr taintedArg, Expr taintSource, string taintCause, SensitiveExpr dest
|
class Configuration extends TaintTrackingConfiguration {
|
||||||
|
override predicate isSink(Element tainted) { exists(BufferWrite w | w.getASource() = tainted) }
|
||||||
|
}
|
||||||
|
|
||||||
|
from
|
||||||
|
BufferWrite w, Expr taintedArg, Expr taintSource, PathNode sourceNode, PathNode sinkNode,
|
||||||
|
string taintCause, SensitiveExpr dest
|
||||||
where
|
where
|
||||||
tainted(taintSource, taintedArg) and
|
taintedWithPath(taintSource, taintedArg, sourceNode, sinkNode) and
|
||||||
isUserInput(taintSource, taintCause) and
|
isUserInput(taintSource, taintCause) and
|
||||||
w.getASource() = taintedArg and
|
w.getASource() = taintedArg and
|
||||||
dest = w.getDest()
|
dest = w.getDest()
|
||||||
select w, "This write into buffer '" + dest.toString() + "' may contain unencrypted data from $@",
|
select w, sourceNode, sinkNode,
|
||||||
|
"This write into buffer '" + dest.toString() + "' may contain unencrypted data from $@",
|
||||||
taintSource, "user input (" + taintCause + ")"
|
taintSource, "user input (" + taintCause + ")"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* @name Cleartext storage of sensitive information in an SQLite database
|
* @name Cleartext storage of sensitive information in an SQLite database
|
||||||
* @description Storing sensitive information in a non-encrypted
|
* @description Storing sensitive information in a non-encrypted
|
||||||
* database can expose it to an attacker.
|
* database can expose it to an attacker.
|
||||||
* @kind problem
|
* @kind path-problem
|
||||||
* @problem.severity warning
|
* @problem.severity warning
|
||||||
* @precision medium
|
* @precision medium
|
||||||
* @id cpp/cleartext-storage-database
|
* @id cpp/cleartext-storage-database
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
import cpp
|
import cpp
|
||||||
import semmle.code.cpp.security.SensitiveExprs
|
import semmle.code.cpp.security.SensitiveExprs
|
||||||
import semmle.code.cpp.security.TaintTracking
|
import semmle.code.cpp.security.TaintTracking
|
||||||
|
import TaintedWithPath
|
||||||
|
|
||||||
class UserInputIsSensitiveExpr extends SecurityOptions {
|
class UserInputIsSensitiveExpr extends SecurityOptions {
|
||||||
override predicate isUserInput(Expr expr, string cause) {
|
override predicate isUserInput(Expr expr, string cause) {
|
||||||
@@ -32,10 +33,21 @@ predicate sqlite_encryption_used() {
|
|||||||
any(FunctionCall fc).getTarget().getName().matches("sqlite%\\_key\\_%")
|
any(FunctionCall fc).getTarget().getName().matches("sqlite%\\_key\\_%")
|
||||||
}
|
}
|
||||||
|
|
||||||
from SensitiveExpr taintSource, Expr taintedArg, SqliteFunctionCall sqliteCall
|
class Configuration extends TaintTrackingConfiguration {
|
||||||
|
override predicate isSink(Element taintedArg) {
|
||||||
|
exists(SqliteFunctionCall sqliteCall |
|
||||||
|
taintedArg = sqliteCall.getASource() and
|
||||||
|
not sqlite_encryption_used()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
from
|
||||||
|
SensitiveExpr taintSource, Expr taintedArg, SqliteFunctionCall sqliteCall, PathNode sourceNode,
|
||||||
|
PathNode sinkNode
|
||||||
where
|
where
|
||||||
tainted(taintSource, taintedArg) and
|
taintedWithPath(taintSource, taintedArg, sourceNode, sinkNode) and
|
||||||
taintedArg = sqliteCall.getASource() and
|
taintedArg = sqliteCall.getASource()
|
||||||
not sqlite_encryption_used()
|
select sqliteCall, sourceNode, sinkNode,
|
||||||
select sqliteCall, "This SQLite call may store $@ in a non-encrypted SQLite database", taintSource,
|
"This SQLite call may store $@ in a non-encrypted SQLite database", taintSource,
|
||||||
"sensitive information"
|
"sensitive information"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* @description Using untrusted inputs in a statement that makes a
|
* @description Using untrusted inputs in a statement that makes a
|
||||||
* security decision makes code vulnerable to
|
* security decision makes code vulnerable to
|
||||||
* attack.
|
* attack.
|
||||||
* @kind problem
|
* @kind path-problem
|
||||||
* @problem.severity warning
|
* @problem.severity warning
|
||||||
* @precision medium
|
* @precision medium
|
||||||
* @id cpp/tainted-permissions-check
|
* @id cpp/tainted-permissions-check
|
||||||
@@ -12,14 +12,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import semmle.code.cpp.security.TaintTracking
|
import semmle.code.cpp.security.TaintTracking
|
||||||
|
import TaintedWithPath
|
||||||
|
|
||||||
/**
|
predicate sensitiveCondition(Expr condition, Expr raise) {
|
||||||
* Holds if there is an 'if' statement whose condition `condition`
|
|
||||||
* is influenced by tainted data `source`, and the body contains
|
|
||||||
* `raise` which escalates privilege.
|
|
||||||
*/
|
|
||||||
predicate cwe807violation(Expr source, Expr condition, Expr raise) {
|
|
||||||
tainted(source, condition) and
|
|
||||||
raisesPrivilege(raise) and
|
raisesPrivilege(raise) and
|
||||||
exists(IfStmt ifstmt |
|
exists(IfStmt ifstmt |
|
||||||
ifstmt.getCondition() = condition and
|
ifstmt.getCondition() = condition and
|
||||||
@@ -27,7 +22,19 @@ predicate cwe807violation(Expr source, Expr condition, Expr raise) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
from Expr source, Expr condition, Expr raise
|
class Configuration extends TaintTrackingConfiguration {
|
||||||
where cwe807violation(source, condition, raise)
|
override predicate isSink(Element tainted) { sensitiveCondition(tainted, _) }
|
||||||
select condition, "Reliance on untrusted input $@ to raise privilege at $@", source,
|
}
|
||||||
source.toString(), raise, raise.toString()
|
|
||||||
|
/*
|
||||||
|
* Produce an alert if there is an 'if' statement whose condition `condition`
|
||||||
|
* is influenced by tainted data `source`, and the body contains
|
||||||
|
* `raise` which escalates privilege.
|
||||||
|
*/
|
||||||
|
|
||||||
|
from Expr source, Expr condition, Expr raise, PathNode sourceNode, PathNode sinkNode
|
||||||
|
where
|
||||||
|
taintedWithPath(source, condition, sourceNode, sinkNode) and
|
||||||
|
sensitiveCondition(condition, raise)
|
||||||
|
select condition, sourceNode, sinkNode, "Reliance on untrusted input $@ to raise privilege at $@",
|
||||||
|
source, source.toString(), raise, raise.toString()
|
||||||
|
|||||||
4
cpp/ql/src/codeql-suites/cpp-code-scanning.qls
Normal file
4
cpp/ql/src/codeql-suites/cpp-code-scanning.qls
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
- description: Standard Code Scanning queries for C and C++
|
||||||
|
- qlpack: codeql-cpp
|
||||||
|
- apply: code-scanning-selectors.yml
|
||||||
|
from: codeql-suite-helpers
|
||||||
@@ -23,6 +23,8 @@ predicate freeFunction(Function f, int argNum) { argNum = f.(DeallocationFunctio
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A call to a library routine that frees memory.
|
* A call to a library routine that frees memory.
|
||||||
|
*
|
||||||
|
* DEPRECATED: Use `DeallocationExpr` instead (this also includes `delete` expressions).
|
||||||
*/
|
*/
|
||||||
predicate freeCall(FunctionCall fc, Expr arg) { arg = fc.(DeallocationExpr).getFreedExpr() }
|
predicate freeCall(FunctionCall fc, Expr arg) { arg = fc.(DeallocationExpr).getFreedExpr() }
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import cpp
|
|||||||
import semmle.code.cpp.security.Security
|
import semmle.code.cpp.security.Security
|
||||||
private import semmle.code.cpp.ir.dataflow.DataFlow
|
private import semmle.code.cpp.ir.dataflow.DataFlow
|
||||||
private import semmle.code.cpp.ir.dataflow.DataFlow2
|
private import semmle.code.cpp.ir.dataflow.DataFlow2
|
||||||
|
private import semmle.code.cpp.ir.dataflow.DataFlow3
|
||||||
private import semmle.code.cpp.ir.IR
|
private import semmle.code.cpp.ir.IR
|
||||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowDispatch as Dispatch
|
private import semmle.code.cpp.ir.dataflow.internal.DataFlowDispatch as Dispatch
|
||||||
private import semmle.code.cpp.models.interfaces.Taint
|
private import semmle.code.cpp.models.interfaces.Taint
|
||||||
@@ -143,7 +144,17 @@ private predicate writesVariable(StoreInstruction store, Variable var) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A variable that has any kind of upper-bound check anywhere in the program
|
* A variable that has any kind of upper-bound check anywhere in the program. This is
|
||||||
|
* biased towards being inclusive because there are a lot of valid ways of doing an
|
||||||
|
* upper bounds checks if we don't consider where it occurs, for example:
|
||||||
|
* ```
|
||||||
|
* if (x < 10) { sink(x); }
|
||||||
|
*
|
||||||
|
* if (10 > y) { sink(y); }
|
||||||
|
*
|
||||||
|
* if (z > 10) { z = 10; }
|
||||||
|
* sink(z);
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
// TODO: This coarse overapproximation, ported from the old taint tracking
|
// TODO: This coarse overapproximation, ported from the old taint tracking
|
||||||
// library, could be replaced with an actual semantic check that a particular
|
// library, could be replaced with an actual semantic check that a particular
|
||||||
@@ -152,10 +163,10 @@ private predicate writesVariable(StoreInstruction store, Variable var) {
|
|||||||
// previously suppressed by this predicate by coincidence.
|
// previously suppressed by this predicate by coincidence.
|
||||||
private predicate hasUpperBoundsCheck(Variable var) {
|
private predicate hasUpperBoundsCheck(Variable var) {
|
||||||
exists(RelationalOperation oper, VariableAccess access |
|
exists(RelationalOperation oper, VariableAccess access |
|
||||||
oper.getLeftOperand() = access and
|
oper.getAnOperand() = access and
|
||||||
access.getTarget() = var and
|
access.getTarget() = var and
|
||||||
// Comparing to 0 is not an upper bound check
|
// Comparing to 0 is not an upper bound check
|
||||||
not oper.getRightOperand().getValue() = "0"
|
not oper.getAnOperand().getValue() = "0"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,6 +182,7 @@ private predicate nodeIsBarrierIn(DataFlow::Node node) {
|
|||||||
node = getNodeForSource(any(Expr e))
|
node = getNodeForSource(any(Expr e))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cached
|
||||||
private predicate instructionTaintStep(Instruction i1, Instruction i2) {
|
private predicate instructionTaintStep(Instruction i1, Instruction i2) {
|
||||||
// Expressions computed from tainted data are also tainted
|
// Expressions computed from tainted data are also tainted
|
||||||
exists(CallInstruction call, int argIndex | call = i2 |
|
exists(CallInstruction call, int argIndex | call = i2 |
|
||||||
@@ -191,9 +203,22 @@ private predicate instructionTaintStep(Instruction i1, Instruction i2) {
|
|||||||
or
|
or
|
||||||
i2.(UnaryInstruction).getUnary() = i1
|
i2.(UnaryInstruction).getUnary() = i1
|
||||||
or
|
or
|
||||||
i2.(ChiInstruction).getPartial() = i1 and
|
// Flow out of definition-by-reference
|
||||||
|
i2.(ChiInstruction).getPartial() = i1.(WriteSideEffectInstruction) and
|
||||||
not i2.isResultConflated()
|
not i2.isResultConflated()
|
||||||
or
|
or
|
||||||
|
// Flow from an element to an array or union that contains it.
|
||||||
|
i2.(ChiInstruction).getPartial() = i1 and
|
||||||
|
not i2.isResultConflated() and
|
||||||
|
exists(Type t | i2.getResultLanguageType().hasType(t, false) |
|
||||||
|
t instanceof Union
|
||||||
|
or
|
||||||
|
t instanceof ArrayType
|
||||||
|
or
|
||||||
|
// Buffers or unknown size
|
||||||
|
t instanceof UnknownType
|
||||||
|
)
|
||||||
|
or
|
||||||
exists(BinaryInstruction bin |
|
exists(BinaryInstruction bin |
|
||||||
bin = i2 and
|
bin = i2 and
|
||||||
predictableInstruction(i2.getAnOperand().getDef()) and
|
predictableInstruction(i2.getAnOperand().getDef()) and
|
||||||
@@ -350,6 +375,16 @@ private Element adjustedSink(DataFlow::Node sink) {
|
|||||||
result.(AssignOperation).getAnOperand() = sink.asExpr()
|
result.(AssignOperation).getAnOperand() = sink.asExpr()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `tainted` may contain taint from `source`.
|
||||||
|
*
|
||||||
|
* A tainted expression is either directly user input, or is
|
||||||
|
* computed from user input in a way that users can probably
|
||||||
|
* control the exact output of the computation.
|
||||||
|
*
|
||||||
|
* This doesn't include data flow through global variables.
|
||||||
|
* If you need that you must call `taintedIncludingGlobalVars`.
|
||||||
|
*/
|
||||||
cached
|
cached
|
||||||
predicate tainted(Expr source, Element tainted) {
|
predicate tainted(Expr source, Element tainted) {
|
||||||
exists(DefaultTaintTrackingCfg cfg, DataFlow::Node sink |
|
exists(DefaultTaintTrackingCfg cfg, DataFlow::Node sink |
|
||||||
@@ -358,16 +393,21 @@ predicate tainted(Expr source, Element tainted) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate tainted_instruction(
|
/**
|
||||||
Function sourceFunc, Instruction source, Function sinkFunc, Instruction sink
|
* Holds if `tainted` may contain taint from `source`, where the taint passed
|
||||||
) {
|
* through a global variable named `globalVar`.
|
||||||
sourceFunc = source.getEnclosingFunction() and
|
*
|
||||||
sinkFunc = sink.getEnclosingFunction() and
|
* A tainted expression is either directly user input, or is
|
||||||
exists(DefaultTaintTrackingCfg cfg |
|
* computed from user input in a way that users can probably
|
||||||
cfg.hasFlow(DataFlow::instructionNode(source), DataFlow::instructionNode(sink))
|
* control the exact output of the computation.
|
||||||
)
|
*
|
||||||
}
|
* This version gives the same results as tainted but also includes
|
||||||
|
* data flow through global variables.
|
||||||
|
*
|
||||||
|
* The parameter `globalVar` is the qualified name of the last global variable
|
||||||
|
* used to move the value from source to tainted. If the taint did not pass
|
||||||
|
* through a global variable, then `globalVar = ""`.
|
||||||
|
*/
|
||||||
cached
|
cached
|
||||||
predicate taintedIncludingGlobalVars(Expr source, Element tainted, string globalVar) {
|
predicate taintedIncludingGlobalVars(Expr source, Element tainted, string globalVar) {
|
||||||
tainted(source, tainted) and
|
tainted(source, tainted) and
|
||||||
@@ -385,11 +425,245 @@ predicate taintedIncludingGlobalVars(Expr source, Element tainted, string global
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the global variable whose qualified name is `id`. Use this predicate
|
||||||
|
* together with `taintedIncludingGlobalVars`. Example:
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* exists(string varName |
|
||||||
|
* taintedIncludingGlobalVars(source, tainted, varName) and
|
||||||
|
* var = globalVarFromId(varName)
|
||||||
|
* )
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
GlobalOrNamespaceVariable globalVarFromId(string id) { id = result.getQualifiedName() }
|
GlobalOrNamespaceVariable globalVarFromId(string id) { id = result.getQualifiedName() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve potential target function(s) for `call`.
|
||||||
|
*
|
||||||
|
* If `call` is a call through a function pointer (`ExprCall`) or
|
||||||
|
* targets a virtual method, simple data flow analysis is performed
|
||||||
|
* in order to identify target(s).
|
||||||
|
*/
|
||||||
Function resolveCall(Call call) {
|
Function resolveCall(Call call) {
|
||||||
exists(CallInstruction callInstruction |
|
exists(CallInstruction callInstruction |
|
||||||
callInstruction.getAST() = call and
|
callInstruction.getAST() = call and
|
||||||
result = Dispatch::viableCallable(callInstruction)
|
result = Dispatch::viableCallable(callInstruction)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides definitions for augmenting source/sink pairs with data-flow paths
|
||||||
|
* between them. From a `@kind path-problem` query, import this module in the
|
||||||
|
* global scope, extend `TaintTrackingConfiguration`, and use `taintedWithPath`
|
||||||
|
* in place of `tainted`.
|
||||||
|
*
|
||||||
|
* Importing this module will also import the query predicates that contain the
|
||||||
|
* taint paths.
|
||||||
|
*/
|
||||||
|
module TaintedWithPath {
|
||||||
|
private newtype TSingleton = MkSingleton()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A taint-tracking configuration that matches sources and sinks in the same
|
||||||
|
* way as the `tainted` predicate.
|
||||||
|
*
|
||||||
|
* Override `isSink` and `taintThroughGlobals` as needed, but do not provide
|
||||||
|
* a characteristic predicate.
|
||||||
|
*/
|
||||||
|
class TaintTrackingConfiguration extends TSingleton {
|
||||||
|
/** Override this to specify which elements are sinks in this configuration. */
|
||||||
|
abstract predicate isSink(Element e);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this predicate to `any()` to allow taint to flow through global
|
||||||
|
* variables.
|
||||||
|
*/
|
||||||
|
predicate taintThroughGlobals() { none() }
|
||||||
|
|
||||||
|
/** Gets a textual representation of this element. */
|
||||||
|
string toString() { result = "TaintTrackingConfiguration" }
|
||||||
|
}
|
||||||
|
|
||||||
|
private class AdjustedConfiguration extends DataFlow3::Configuration {
|
||||||
|
AdjustedConfiguration() { this = "AdjustedConfiguration" }
|
||||||
|
|
||||||
|
override predicate isSource(DataFlow::Node source) { source = getNodeForSource(_) }
|
||||||
|
|
||||||
|
override predicate isSink(DataFlow::Node sink) {
|
||||||
|
exists(TaintTrackingConfiguration cfg | cfg.isSink(adjustedSink(sink)))
|
||||||
|
}
|
||||||
|
|
||||||
|
override predicate isAdditionalFlowStep(DataFlow::Node n1, DataFlow::Node n2) {
|
||||||
|
instructionTaintStep(n1.asInstruction(), n2.asInstruction())
|
||||||
|
or
|
||||||
|
exists(TaintTrackingConfiguration cfg | cfg.taintThroughGlobals() |
|
||||||
|
writesVariable(n1.asInstruction(), n2.asVariable().(GlobalOrNamespaceVariable))
|
||||||
|
or
|
||||||
|
readsVariable(n2.asInstruction(), n1.asVariable().(GlobalOrNamespaceVariable))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override predicate isBarrier(DataFlow::Node node) { nodeIsBarrier(node) }
|
||||||
|
|
||||||
|
override predicate isBarrierIn(DataFlow::Node node) { nodeIsBarrierIn(node) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A sink `Element` may map to multiple `DataFlowX::PathNode`s via (the
|
||||||
|
* inverse of) `adjustedSink`. For example, an `Expr` maps to all its
|
||||||
|
* conversions, and a `Variable` maps to all loads and stores from it. Because
|
||||||
|
* the path node is part of the tuple that constitutes the alert, this leads
|
||||||
|
* to duplicate alerts.
|
||||||
|
*
|
||||||
|
* To avoid showing duplicates, we edit the graph to replace the final node
|
||||||
|
* coming from the data-flow library with a node that matches exactly the
|
||||||
|
* `Element` sink that's requested.
|
||||||
|
*
|
||||||
|
* The same is done for sources.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private newtype TPathNode =
|
||||||
|
TWrapPathNode(DataFlow3::PathNode n) or
|
||||||
|
// There's a single newtype constructor for both sources and sinks since
|
||||||
|
// that makes it easiest to deal with the case where source = sink.
|
||||||
|
TEndpointPathNode(Element e) {
|
||||||
|
exists(AdjustedConfiguration cfg, DataFlow3::Node sourceNode, DataFlow3::Node sinkNode |
|
||||||
|
cfg.hasFlow(sourceNode, sinkNode)
|
||||||
|
|
|
||||||
|
sourceNode = getNodeForSource(e)
|
||||||
|
or
|
||||||
|
e = adjustedSink(sinkNode) and
|
||||||
|
exists(TaintTrackingConfiguration ttCfg | ttCfg.isSink(e))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** An opaque type used for the nodes of a data-flow path. */
|
||||||
|
class PathNode extends TPathNode {
|
||||||
|
/** Gets a textual representation of this element. */
|
||||||
|
string toString() { none() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if this element is at the specified location.
|
||||||
|
* The location spans column `startcolumn` of line `startline` to
|
||||||
|
* column `endcolumn` of line `endline` in file `filepath`.
|
||||||
|
* For more information, see
|
||||||
|
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||||
|
*/
|
||||||
|
predicate hasLocationInfo(
|
||||||
|
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||||
|
) {
|
||||||
|
none()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class WrapPathNode extends PathNode, TWrapPathNode {
|
||||||
|
DataFlow3::PathNode inner() { this = TWrapPathNode(result) }
|
||||||
|
|
||||||
|
override string toString() { result = this.inner().toString() }
|
||||||
|
|
||||||
|
override predicate hasLocationInfo(
|
||||||
|
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||||
|
) {
|
||||||
|
this.inner().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class EndpointPathNode extends PathNode, TEndpointPathNode {
|
||||||
|
Expr inner() { this = TEndpointPathNode(result) }
|
||||||
|
|
||||||
|
override string toString() { result = this.inner().toString() }
|
||||||
|
|
||||||
|
override predicate hasLocationInfo(
|
||||||
|
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||||
|
) {
|
||||||
|
this
|
||||||
|
.inner()
|
||||||
|
.getLocation()
|
||||||
|
.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A PathNode whose `Element` is a source. It may also be a sink. */
|
||||||
|
private class InitialPathNode extends EndpointPathNode {
|
||||||
|
InitialPathNode() { exists(getNodeForSource(this.inner())) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A PathNode whose `Element` is a sink. It may also be a source. */
|
||||||
|
private class FinalPathNode extends EndpointPathNode {
|
||||||
|
FinalPathNode() { exists(TaintTrackingConfiguration cfg | cfg.isSink(this.inner())) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
|
||||||
|
query predicate edges(PathNode a, PathNode b) {
|
||||||
|
DataFlow3::PathGraph::edges(a.(WrapPathNode).inner(), b.(WrapPathNode).inner())
|
||||||
|
or
|
||||||
|
// To avoid showing trivial-looking steps, we _replace_ the last node instead
|
||||||
|
// of adding an edge out of it.
|
||||||
|
exists(WrapPathNode sinkNode |
|
||||||
|
DataFlow3::PathGraph::edges(a.(WrapPathNode).inner(), sinkNode.inner()) and
|
||||||
|
b.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode())
|
||||||
|
)
|
||||||
|
or
|
||||||
|
// Same for the first node
|
||||||
|
exists(WrapPathNode sourceNode |
|
||||||
|
DataFlow3::PathGraph::edges(sourceNode.inner(), b.(WrapPathNode).inner()) and
|
||||||
|
sourceNode.inner().getNode() = getNodeForSource(a.(InitialPathNode).inner())
|
||||||
|
)
|
||||||
|
or
|
||||||
|
// Finally, handle the case where the path goes directly from a source to a
|
||||||
|
// sink, meaning that they both need to be translated.
|
||||||
|
exists(WrapPathNode sinkNode, WrapPathNode sourceNode |
|
||||||
|
DataFlow3::PathGraph::edges(sourceNode.inner(), sinkNode.inner()) and
|
||||||
|
sourceNode.inner().getNode() = getNodeForSource(a.(InitialPathNode).inner()) and
|
||||||
|
b.(FinalPathNode).inner() = adjustedSink(sinkNode.inner().getNode())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Holds if `n` is a node in the graph of data flow path explanations. */
|
||||||
|
query predicate nodes(PathNode n, string key, string val) {
|
||||||
|
key = "semmle.label" and val = n.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `tainted` may contain taint from `source`, where `sourceNode` and
|
||||||
|
* `sinkNode` are the corresponding `PathNode`s that can be used in a query
|
||||||
|
* to provide path explanations. Extend `TaintTrackingConfiguration` to use
|
||||||
|
* this predicate.
|
||||||
|
*
|
||||||
|
* A tainted expression is either directly user input, or is computed from
|
||||||
|
* user input in a way that users can probably control the exact output of
|
||||||
|
* the computation.
|
||||||
|
*/
|
||||||
|
predicate taintedWithPath(Expr source, Element tainted, PathNode sourceNode, PathNode sinkNode) {
|
||||||
|
exists(AdjustedConfiguration cfg, DataFlow3::Node flowSource, DataFlow3::Node flowSink |
|
||||||
|
source = sourceNode.(InitialPathNode).inner() and
|
||||||
|
flowSource = getNodeForSource(source) and
|
||||||
|
cfg.hasFlow(flowSource, flowSink) and
|
||||||
|
tainted = adjustedSink(flowSink) and
|
||||||
|
tainted = sinkNode.(FinalPathNode).inner()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private predicate isGlobalVariablePathNode(WrapPathNode n) {
|
||||||
|
n.inner().getNode().asVariable() instanceof GlobalOrNamespaceVariable
|
||||||
|
}
|
||||||
|
|
||||||
|
private predicate edgesWithoutGlobals(PathNode a, PathNode b) {
|
||||||
|
edges(a, b) and
|
||||||
|
not isGlobalVariablePathNode(a) and
|
||||||
|
not isGlobalVariablePathNode(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `tainted` can be reached from a taint source without passing
|
||||||
|
* through a global variable.
|
||||||
|
*/
|
||||||
|
predicate taintedWithoutGlobals(Element tainted) {
|
||||||
|
exists(PathNode sourceNode, FinalPathNode sinkNode |
|
||||||
|
sourceNode.(WrapPathNode).inner().getNode() = getNodeForSource(_) and
|
||||||
|
edgesWithoutGlobals+(sourceNode, sinkNode) and
|
||||||
|
tainted = sinkNode.inner()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ Type getErasedRepr(Type t) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Gets a string representation of a type returned by `getErasedRepr`. */
|
/** Gets a string representation of a type returned by `getErasedRepr`. */
|
||||||
string ppReprType(Type t) { result = t.toString() }
|
string ppReprType(Type t) { none() } // stub implementation
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `t1` and `t2` are compatible, that is, whether data can flow from
|
* Holds if `t1` and `t2` are compatible, that is, whether data can flow from
|
||||||
|
|||||||
@@ -239,6 +239,17 @@ class DefinitionByReferenceNode extends InstructionNode {
|
|||||||
Parameter getParameter() {
|
Parameter getParameter() {
|
||||||
exists(CallInstruction ci | result = ci.getStaticCallTarget().getParameter(instr.getIndex()))
|
exists(CallInstruction ci | result = ci.getStaticCallTarget().getParameter(instr.getIndex()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override string toString() {
|
||||||
|
// This string should be unique enough to be helpful but common enough to
|
||||||
|
// avoid storing too many different strings.
|
||||||
|
result =
|
||||||
|
instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget().getName() +
|
||||||
|
" output argument"
|
||||||
|
or
|
||||||
|
not exists(instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget()) and
|
||||||
|
result = "output argument"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -289,7 +300,7 @@ ExprNode exprNode(Expr e) { result.getExpr() = e }
|
|||||||
* Gets the `Node` corresponding to `e`, if any. Here, `e` may be a
|
* Gets the `Node` corresponding to `e`, if any. Here, `e` may be a
|
||||||
* `Conversion`.
|
* `Conversion`.
|
||||||
*/
|
*/
|
||||||
ExprNode convertedExprNode(Expr e) { result.getExpr() = e }
|
ExprNode convertedExprNode(Expr e) { result.getConvertedExpr() = e }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the `Node` corresponding to the value of `p` at function entry.
|
* Gets the `Node` corresponding to the value of `p` at function entry.
|
||||||
@@ -323,6 +334,7 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
|
|||||||
simpleInstructionLocalFlowStep(nodeFrom.asInstruction(), nodeTo.asInstruction())
|
simpleInstructionLocalFlowStep(nodeFrom.asInstruction(), nodeTo.asInstruction())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cached
|
||||||
private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction iTo) {
|
private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction iTo) {
|
||||||
iTo.(CopyInstruction).getSourceValue() = iFrom
|
iTo.(CopyInstruction).getSourceValue() = iFrom
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
private import internal.ValueNumberingImports
|
||||||
|
private import ValueNumbering
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides additional information about value numbering in IR dumps.
|
||||||
|
*/
|
||||||
|
class ValueNumberPropertyProvider extends IRPropertyProvider {
|
||||||
|
override string getInstructionProperty(Instruction instr, string key) {
|
||||||
|
exists(ValueNumber vn |
|
||||||
|
vn = valueNumber(instr) and
|
||||||
|
key = "valnum" and
|
||||||
|
if strictcount(vn.getAnInstruction()) > 1
|
||||||
|
then result = vn.getDebugString()
|
||||||
|
else result = "unique"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,21 +1,6 @@
|
|||||||
private import internal.ValueNumberingInternal
|
private import internal.ValueNumberingInternal
|
||||||
private import internal.ValueNumberingImports
|
private import internal.ValueNumberingImports
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides additional information about value numbering in IR dumps.
|
|
||||||
*/
|
|
||||||
class ValueNumberPropertyProvider extends IRPropertyProvider {
|
|
||||||
override string getInstructionProperty(Instruction instr, string key) {
|
|
||||||
exists(ValueNumber vn |
|
|
||||||
vn = valueNumber(instr) and
|
|
||||||
key = "valnum" and
|
|
||||||
if strictcount(vn.getAnInstruction()) > 1
|
|
||||||
then result = vn.getDebugString()
|
|
||||||
else result = "unique"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value number assigned to a particular set of instructions that produce equivalent results.
|
* The value number assigned to a particular set of instructions that produce equivalent results.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
private import internal.ValueNumberingImports
|
||||||
|
private import ValueNumbering
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides additional information about value numbering in IR dumps.
|
||||||
|
*/
|
||||||
|
class ValueNumberPropertyProvider extends IRPropertyProvider {
|
||||||
|
override string getInstructionProperty(Instruction instr, string key) {
|
||||||
|
exists(ValueNumber vn |
|
||||||
|
vn = valueNumber(instr) and
|
||||||
|
key = "valnum" and
|
||||||
|
if strictcount(vn.getAnInstruction()) > 1
|
||||||
|
then result = vn.getDebugString()
|
||||||
|
else result = "unique"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,21 +1,6 @@
|
|||||||
private import internal.ValueNumberingInternal
|
private import internal.ValueNumberingInternal
|
||||||
private import internal.ValueNumberingImports
|
private import internal.ValueNumberingImports
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides additional information about value numbering in IR dumps.
|
|
||||||
*/
|
|
||||||
class ValueNumberPropertyProvider extends IRPropertyProvider {
|
|
||||||
override string getInstructionProperty(Instruction instr, string key) {
|
|
||||||
exists(ValueNumber vn |
|
|
||||||
vn = valueNumber(instr) and
|
|
||||||
key = "valnum" and
|
|
||||||
if strictcount(vn.getAnInstruction()) > 1
|
|
||||||
then result = vn.getDebugString()
|
|
||||||
else result = "unique"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value number assigned to a particular set of instructions that produce equivalent results.
|
* The value number assigned to a particular set of instructions that produce equivalent results.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
private import internal.ValueNumberingImports
|
||||||
|
private import ValueNumbering
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides additional information about value numbering in IR dumps.
|
||||||
|
*/
|
||||||
|
class ValueNumberPropertyProvider extends IRPropertyProvider {
|
||||||
|
override string getInstructionProperty(Instruction instr, string key) {
|
||||||
|
exists(ValueNumber vn |
|
||||||
|
vn = valueNumber(instr) and
|
||||||
|
key = "valnum" and
|
||||||
|
if strictcount(vn.getAnInstruction()) > 1
|
||||||
|
then result = vn.getDebugString()
|
||||||
|
else result = "unique"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,21 +1,6 @@
|
|||||||
private import internal.ValueNumberingInternal
|
private import internal.ValueNumberingInternal
|
||||||
private import internal.ValueNumberingImports
|
private import internal.ValueNumberingImports
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides additional information about value numbering in IR dumps.
|
|
||||||
*/
|
|
||||||
class ValueNumberPropertyProvider extends IRPropertyProvider {
|
|
||||||
override string getInstructionProperty(Instruction instr, string key) {
|
|
||||||
exists(ValueNumber vn |
|
|
||||||
vn = valueNumber(instr) and
|
|
||||||
key = "valnum" and
|
|
||||||
if strictcount(vn.getAnInstruction()) > 1
|
|
||||||
then result = vn.getDebugString()
|
|
||||||
else result = "unique"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value number assigned to a particular set of instructions that produce equivalent results.
|
* The value number assigned to a particular set of instructions that produce equivalent results.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -12,4 +12,5 @@ private import implementations.Strcat
|
|||||||
private import implementations.Strcpy
|
private import implementations.Strcpy
|
||||||
private import implementations.Strdup
|
private import implementations.Strdup
|
||||||
private import implementations.Strftime
|
private import implementations.Strftime
|
||||||
|
private import implementations.StdString
|
||||||
private import implementations.Swap
|
private import implementations.Swap
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* Provides implementation classes modelling various methods of allocation
|
||||||
|
* (`malloc`, `new` etc). See `semmle.code.cpp.models.interfaces.Allocation`
|
||||||
|
* for usage information.
|
||||||
|
*/
|
||||||
|
|
||||||
import semmle.code.cpp.models.interfaces.Allocation
|
import semmle.code.cpp.models.interfaces.Allocation
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
import semmle.code.cpp.models.interfaces.Allocation
|
/**
|
||||||
|
* Provides implementation classes modelling various methods of deallocation
|
||||||
|
* (`free`, `delete` etc). See `semmle.code.cpp.models.interfaces.Deallocation`
|
||||||
|
* for usage information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import semmle.code.cpp.models.interfaces.Deallocation
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A deallocation function such as `free`.
|
* A deallocation function such as `free`.
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import semmle.code.cpp.models.interfaces.Taint
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `std::basic_string` constructor(s).
|
||||||
|
*/
|
||||||
|
class StdStringConstructor extends TaintFunction {
|
||||||
|
StdStringConstructor() { this.hasQualifiedName("std", "basic_string", "basic_string") }
|
||||||
|
|
||||||
|
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||||
|
// flow from any constructor argument to return value
|
||||||
|
input.isParameter(_) and
|
||||||
|
output.isReturnValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The standard function `std::string.c_str`.
|
||||||
|
*/
|
||||||
|
class StdStringCStr extends TaintFunction {
|
||||||
|
StdStringCStr() { this.hasQualifiedName("std", "basic_string", "c_str") }
|
||||||
|
|
||||||
|
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||||
|
// flow from string itself (qualifier) to return value
|
||||||
|
input.isQualifierObject() and
|
||||||
|
output.isReturnValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -328,14 +328,24 @@ GlobalOrNamespaceVariable globalVarFromId(string id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A variable that has any kind of upper-bound check anywhere in the program
|
* A variable that has any kind of upper-bound check anywhere in the program. This is
|
||||||
|
* biased towards being inclusive because there are a lot of valid ways of doing an
|
||||||
|
* upper bounds checks if we don't consider where it occurs, for example:
|
||||||
|
* ```
|
||||||
|
* if (x < 10) { sink(x); }
|
||||||
|
*
|
||||||
|
* if (10 > y) { sink(y); }
|
||||||
|
*
|
||||||
|
* if (z > 10) { z = 10; }
|
||||||
|
* sink(z);
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
private predicate hasUpperBoundsCheck(Variable var) {
|
private predicate hasUpperBoundsCheck(Variable var) {
|
||||||
exists(RelationalOperation oper, VariableAccess access |
|
exists(RelationalOperation oper, VariableAccess access |
|
||||||
oper.getLeftOperand() = access and
|
oper.getAnOperand() = access and
|
||||||
access.getTarget() = var and
|
access.getTarget() = var and
|
||||||
// Comparing to 0 is not an upper bound check
|
// Comparing to 0 is not an upper bound check
|
||||||
not oper.getRightOperand().getValue() = "0"
|
not oper.getAnOperand().getValue() = "0"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -104,6 +104,7 @@
|
|||||||
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:9:11:9:20 | p#0 |
|
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:9:11:9:20 | p#0 |
|
||||||
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:91:42:91:44 | arg |
|
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:91:42:91:44 | arg |
|
||||||
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:92:12:92:14 | arg |
|
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:92:12:92:14 | arg |
|
||||||
|
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:96:11:96:12 | p2 |
|
||||||
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:97:27:97:32 | call to getenv |
|
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:97:27:97:32 | call to getenv |
|
||||||
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | (const char *)... |
|
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | (const char *)... |
|
||||||
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | p2 |
|
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | p2 |
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:91:31:91:33 | ret | AST only |
|
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:91:31:91:33 | ret | AST only |
|
||||||
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:92:5:92:8 | * ... | AST only |
|
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:92:5:92:8 | * ... | AST only |
|
||||||
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:92:6:92:8 | ret | AST only |
|
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:92:6:92:8 | ret | AST only |
|
||||||
|
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:96:11:96:12 | p2 | IR only |
|
||||||
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | (const char *)... | IR only |
|
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | (const char *)... | IR only |
|
||||||
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | p2 | IR only |
|
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | p2 | IR only |
|
||||||
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | test_diff.cpp:1:11:1:20 | p#0 | IR only |
|
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | test_diff.cpp:1:11:1:20 | p#0 | IR only |
|
||||||
|
|||||||
@@ -105,6 +105,63 @@
|
|||||||
| format.cpp:130:23:130:23 | 0 | format.cpp:130:21:130:24 | {...} | TAINT |
|
| format.cpp:130:23:130:23 | 0 | format.cpp:130:21:130:24 | {...} | TAINT |
|
||||||
| format.cpp:131:39:131:45 | ref arg & ... | format.cpp:132:8:132:13 | buffer | |
|
| format.cpp:131:39:131:45 | ref arg & ... | format.cpp:132:8:132:13 | buffer | |
|
||||||
| format.cpp:131:40:131:45 | buffer | format.cpp:131:39:131:45 | & ... | |
|
| format.cpp:131:40:131:45 | buffer | format.cpp:131:39:131:45 | & ... | |
|
||||||
|
| stl.cpp:67:12:67:17 | call to source | stl.cpp:71:7:71:7 | a | |
|
||||||
|
| stl.cpp:68:16:68:20 | 123 | stl.cpp:68:16:68:21 | call to basic_string | TAINT |
|
||||||
|
| stl.cpp:68:16:68:21 | call to basic_string | stl.cpp:72:7:72:7 | b | |
|
||||||
|
| stl.cpp:68:16:68:21 | call to basic_string | stl.cpp:74:7:74:7 | b | |
|
||||||
|
| stl.cpp:69:16:69:21 | call to source | stl.cpp:69:16:69:24 | call to basic_string | TAINT |
|
||||||
|
| stl.cpp:69:16:69:24 | call to basic_string | stl.cpp:73:7:73:7 | c | |
|
||||||
|
| stl.cpp:69:16:69:24 | call to basic_string | stl.cpp:75:7:75:7 | c | |
|
||||||
|
| stl.cpp:74:7:74:7 | b | stl.cpp:74:9:74:13 | call to c_str | TAINT |
|
||||||
|
| stl.cpp:75:7:75:7 | c | stl.cpp:75:9:75:13 | call to c_str | TAINT |
|
||||||
|
| stl.cpp:80:20:80:22 | call to basic_stringstream | stl.cpp:83:2:83:4 | ss1 | |
|
||||||
|
| stl.cpp:80:20:80:22 | call to basic_stringstream | stl.cpp:89:7:89:9 | ss1 | |
|
||||||
|
| stl.cpp:80:20:80:22 | call to basic_stringstream | stl.cpp:94:7:94:9 | ss1 | |
|
||||||
|
| stl.cpp:80:25:80:27 | call to basic_stringstream | stl.cpp:84:2:84:4 | ss2 | |
|
||||||
|
| stl.cpp:80:25:80:27 | call to basic_stringstream | stl.cpp:90:7:90:9 | ss2 | |
|
||||||
|
| stl.cpp:80:25:80:27 | call to basic_stringstream | stl.cpp:95:7:95:9 | ss2 | |
|
||||||
|
| stl.cpp:80:30:80:32 | call to basic_stringstream | stl.cpp:85:2:85:4 | ss3 | |
|
||||||
|
| stl.cpp:80:30:80:32 | call to basic_stringstream | stl.cpp:91:7:91:9 | ss3 | |
|
||||||
|
| stl.cpp:80:30:80:32 | call to basic_stringstream | stl.cpp:96:7:96:9 | ss3 | |
|
||||||
|
| stl.cpp:80:35:80:37 | call to basic_stringstream | stl.cpp:86:2:86:4 | ss4 | |
|
||||||
|
| stl.cpp:80:35:80:37 | call to basic_stringstream | stl.cpp:92:7:92:9 | ss4 | |
|
||||||
|
| stl.cpp:80:35:80:37 | call to basic_stringstream | stl.cpp:97:7:97:9 | ss4 | |
|
||||||
|
| stl.cpp:80:40:80:42 | call to basic_stringstream | stl.cpp:87:2:87:4 | ss5 | |
|
||||||
|
| stl.cpp:80:40:80:42 | call to basic_stringstream | stl.cpp:93:7:93:9 | ss5 | |
|
||||||
|
| stl.cpp:80:40:80:42 | call to basic_stringstream | stl.cpp:98:7:98:9 | ss5 | |
|
||||||
|
| stl.cpp:81:16:81:21 | call to source | stl.cpp:81:16:81:24 | call to basic_string | TAINT |
|
||||||
|
| stl.cpp:81:16:81:24 | call to basic_string | stl.cpp:87:9:87:9 | t | |
|
||||||
|
| stl.cpp:83:2:83:4 | ref arg ss1 | stl.cpp:89:7:89:9 | ss1 | |
|
||||||
|
| stl.cpp:83:2:83:4 | ref arg ss1 | stl.cpp:94:7:94:9 | ss1 | |
|
||||||
|
| stl.cpp:84:2:84:4 | ref arg ss2 | stl.cpp:90:7:90:9 | ss2 | |
|
||||||
|
| stl.cpp:84:2:84:4 | ref arg ss2 | stl.cpp:95:7:95:9 | ss2 | |
|
||||||
|
| stl.cpp:85:2:85:4 | ref arg ss3 | stl.cpp:91:7:91:9 | ss3 | |
|
||||||
|
| stl.cpp:85:2:85:4 | ref arg ss3 | stl.cpp:96:7:96:9 | ss3 | |
|
||||||
|
| stl.cpp:86:2:86:4 | ref arg ss4 | stl.cpp:92:7:92:9 | ss4 | |
|
||||||
|
| stl.cpp:86:2:86:4 | ref arg ss4 | stl.cpp:97:7:97:9 | ss4 | |
|
||||||
|
| stl.cpp:87:2:87:4 | ref arg ss5 | stl.cpp:93:7:93:9 | ss5 | |
|
||||||
|
| stl.cpp:87:2:87:4 | ref arg ss5 | stl.cpp:98:7:98:9 | ss5 | |
|
||||||
|
| stl.cpp:101:32:101:37 | source | stl.cpp:106:9:106:14 | source | |
|
||||||
|
| stl.cpp:103:20:103:22 | call to basic_stringstream | stl.cpp:105:2:105:4 | ss1 | |
|
||||||
|
| stl.cpp:103:20:103:22 | call to basic_stringstream | stl.cpp:108:7:108:9 | ss1 | |
|
||||||
|
| stl.cpp:103:20:103:22 | call to basic_stringstream | stl.cpp:110:7:110:9 | ss1 | |
|
||||||
|
| stl.cpp:103:25:103:27 | call to basic_stringstream | stl.cpp:106:2:106:4 | ss2 | |
|
||||||
|
| stl.cpp:103:25:103:27 | call to basic_stringstream | stl.cpp:109:7:109:9 | ss2 | |
|
||||||
|
| stl.cpp:103:25:103:27 | call to basic_stringstream | stl.cpp:111:7:111:9 | ss2 | |
|
||||||
|
| stl.cpp:105:2:105:4 | ss1 [post update] | stl.cpp:108:7:108:9 | ss1 | |
|
||||||
|
| stl.cpp:105:2:105:4 | ss1 [post update] | stl.cpp:110:7:110:9 | ss1 | |
|
||||||
|
| stl.cpp:106:2:106:4 | ss2 [post update] | stl.cpp:109:7:109:9 | ss2 | |
|
||||||
|
| stl.cpp:106:2:106:4 | ss2 [post update] | stl.cpp:111:7:111:9 | ss2 | |
|
||||||
|
| stl.cpp:124:16:124:28 | call to basic_string | stl.cpp:125:7:125:11 | path1 | |
|
||||||
|
| stl.cpp:124:17:124:26 | call to user_input | stl.cpp:124:16:124:28 | call to basic_string | TAINT |
|
||||||
|
| stl.cpp:125:7:125:11 | path1 | stl.cpp:125:13:125:17 | call to c_str | TAINT |
|
||||||
|
| stl.cpp:128:10:128:19 | call to user_input | stl.cpp:128:10:128:21 | call to basic_string | TAINT |
|
||||||
|
| stl.cpp:128:10:128:21 | call to basic_string | stl.cpp:128:2:128:21 | ... = ... | |
|
||||||
|
| stl.cpp:128:10:128:21 | call to basic_string | stl.cpp:129:7:129:11 | path2 | |
|
||||||
|
| stl.cpp:129:7:129:11 | path2 | stl.cpp:129:13:129:17 | call to c_str | TAINT |
|
||||||
|
| stl.cpp:131:15:131:24 | call to user_input | stl.cpp:131:15:131:27 | call to basic_string | TAINT |
|
||||||
|
| stl.cpp:131:15:131:27 | call to basic_string | stl.cpp:132:7:132:11 | path3 | |
|
||||||
|
| stl.cpp:132:7:132:11 | path3 | stl.cpp:132:13:132:17 | call to c_str | TAINT |
|
||||||
| taint.cpp:4:27:4:33 | source1 | taint.cpp:6:13:6:19 | source1 | |
|
| taint.cpp:4:27:4:33 | source1 | taint.cpp:6:13:6:19 | source1 | |
|
||||||
| taint.cpp:4:40:4:45 | clean1 | taint.cpp:5:8:5:13 | clean1 | |
|
| taint.cpp:4:40:4:45 | clean1 | taint.cpp:5:8:5:13 | clean1 | |
|
||||||
| taint.cpp:4:40:4:45 | clean1 | taint.cpp:6:3:6:8 | clean1 | |
|
| taint.cpp:4:40:4:45 | clean1 | taint.cpp:6:3:6:8 | clean1 | |
|
||||||
|
|||||||
133
cpp/ql/test/library-tests/dataflow/taint-tests/stl.cpp
Normal file
133
cpp/ql/test/library-tests/dataflow/taint-tests/stl.cpp
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
|
||||||
|
typedef unsigned long size_t;
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template<class charT> struct char_traits;
|
||||||
|
|
||||||
|
typedef size_t streamsize;
|
||||||
|
|
||||||
|
template <class T> class allocator {
|
||||||
|
public:
|
||||||
|
allocator() throw();
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
|
||||||
|
class basic_string {
|
||||||
|
public:
|
||||||
|
explicit basic_string(const Allocator& a = Allocator());
|
||||||
|
basic_string(const charT* s, const Allocator& a = Allocator());
|
||||||
|
|
||||||
|
const charT* c_str() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef basic_string<char> string;
|
||||||
|
|
||||||
|
template <class charT, class traits = char_traits<charT> >
|
||||||
|
class basic_istream /*: virtual public basic_ios<charT,traits> - not needed for this test */ {
|
||||||
|
public:
|
||||||
|
basic_istream<charT,traits>& operator>>(int& n);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class charT, class traits = char_traits<charT> >
|
||||||
|
class basic_ostream /*: virtual public basic_ios<charT,traits> - not needed for this test */ {
|
||||||
|
public:
|
||||||
|
typedef charT char_type;
|
||||||
|
basic_ostream<charT,traits>& write(const char_type* s, streamsize n);
|
||||||
|
|
||||||
|
basic_ostream<charT, traits>& operator<<(int n);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class charT, class traits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, const charT*);
|
||||||
|
template<class charT, class traits, class Allocator> basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>& os, const basic_string<charT, traits, Allocator>& str);
|
||||||
|
|
||||||
|
template<class charT, class traits = char_traits<charT>>
|
||||||
|
class basic_iostream : public basic_istream<charT, traits>, public basic_ostream<charT, traits> {
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>>
|
||||||
|
class basic_stringstream : public basic_iostream<charT, traits> {
|
||||||
|
public:
|
||||||
|
explicit basic_stringstream(/*ios_base::openmode which = ios_base::out|ios_base::in - not needed for this test*/);
|
||||||
|
|
||||||
|
basic_string<charT, traits, Allocator> str() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
using stringstream = basic_stringstream<char>;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *source();
|
||||||
|
void sink(const char *s) {};
|
||||||
|
void sink(const std::string &s) {};
|
||||||
|
void sink(const std::stringstream &s) {};
|
||||||
|
|
||||||
|
void test_string()
|
||||||
|
{
|
||||||
|
char *a = source();
|
||||||
|
std::string b("123");
|
||||||
|
std::string c(source());
|
||||||
|
|
||||||
|
sink(a); // tainted
|
||||||
|
sink(b);
|
||||||
|
sink(c); // tainted
|
||||||
|
sink(b.c_str());
|
||||||
|
sink(c.c_str()); // tainted
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_stringstream()
|
||||||
|
{
|
||||||
|
std::stringstream ss1, ss2, ss3, ss4, ss5;
|
||||||
|
std::string t(source());
|
||||||
|
|
||||||
|
ss1 << "1234";
|
||||||
|
ss2 << source();
|
||||||
|
ss3 << "123" << source();
|
||||||
|
ss4 << source() << "456";
|
||||||
|
ss5 << t;
|
||||||
|
|
||||||
|
sink(ss1);
|
||||||
|
sink(ss2); // tainted [NOT DETECTED]
|
||||||
|
sink(ss3); // tainted [NOT DETECTED]
|
||||||
|
sink(ss4); // tainted [NOT DETECTED]
|
||||||
|
sink(ss5); // tainted [NOT DETECTED]
|
||||||
|
sink(ss1.str());
|
||||||
|
sink(ss2.str()); // tainted [NOT DETECTED]
|
||||||
|
sink(ss3.str()); // tainted [NOT DETECTED]
|
||||||
|
sink(ss4.str()); // tainted [NOT DETECTED]
|
||||||
|
sink(ss5.str()); // tainted [NOT DETECTED]
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_stringstream_int(int source)
|
||||||
|
{
|
||||||
|
std::stringstream ss1, ss2;
|
||||||
|
|
||||||
|
ss1 << 1234;
|
||||||
|
ss2 << source;
|
||||||
|
|
||||||
|
sink(ss1);
|
||||||
|
sink(ss2); // tainted [NOT DETECTED]
|
||||||
|
sink(ss1.str());
|
||||||
|
sink(ss2.str()); // tainted [NOT DETECTED]
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
char *user_input() {
|
||||||
|
return source();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sink(const char *filename, const char *mode);
|
||||||
|
|
||||||
|
void test_strings2()
|
||||||
|
{
|
||||||
|
string path1 = user_input();
|
||||||
|
sink(path1.c_str(), "r"); // tainted
|
||||||
|
|
||||||
|
string path2;
|
||||||
|
path2 = user_input();
|
||||||
|
sink(path2.c_str(), "r"); // tainted
|
||||||
|
|
||||||
|
string path3(user_input());
|
||||||
|
sink(path3.c_str(), "r"); // tainted
|
||||||
|
}
|
||||||
@@ -8,6 +8,12 @@
|
|||||||
| format.cpp:96:8:96:13 | buffer | format.cpp:95:30:95:43 | call to source |
|
| format.cpp:96:8:96:13 | buffer | format.cpp:95:30:95:43 | call to source |
|
||||||
| format.cpp:101:8:101:13 | buffer | format.cpp:100:31:100:45 | call to source |
|
| format.cpp:101:8:101:13 | buffer | format.cpp:100:31:100:45 | call to source |
|
||||||
| format.cpp:106:8:106:14 | wbuffer | format.cpp:105:38:105:52 | call to source |
|
| format.cpp:106:8:106:14 | wbuffer | format.cpp:105:38:105:52 | call to source |
|
||||||
|
| stl.cpp:71:7:71:7 | a | stl.cpp:67:12:67:17 | call to source |
|
||||||
|
| stl.cpp:73:7:73:7 | c | stl.cpp:69:16:69:21 | call to source |
|
||||||
|
| stl.cpp:75:9:75:13 | call to c_str | stl.cpp:69:16:69:21 | call to source |
|
||||||
|
| stl.cpp:125:13:125:17 | call to c_str | stl.cpp:117:10:117:15 | call to source |
|
||||||
|
| stl.cpp:129:13:129:17 | call to c_str | stl.cpp:117:10:117:15 | call to source |
|
||||||
|
| stl.cpp:132:13:132:17 | call to c_str | stl.cpp:117:10:117:15 | call to source |
|
||||||
| taint.cpp:8:8:8:13 | clean1 | taint.cpp:4:27:4:33 | source1 |
|
| taint.cpp:8:8:8:13 | clean1 | taint.cpp:4:27:4:33 | source1 |
|
||||||
| 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 |
|
||||||
|
|||||||
@@ -8,6 +8,11 @@
|
|||||||
| format.cpp:96:8:96:13 | format.cpp:95:30:95:43 | AST only |
|
| format.cpp:96:8:96:13 | format.cpp:95:30:95:43 | AST only |
|
||||||
| format.cpp:101:8:101:13 | format.cpp:100:31:100:45 | AST only |
|
| format.cpp:101:8:101:13 | format.cpp:100:31:100:45 | AST only |
|
||||||
| format.cpp:106:8:106:14 | format.cpp:105:38:105:52 | AST only |
|
| format.cpp:106:8:106:14 | format.cpp:105:38:105:52 | AST only |
|
||||||
|
| stl.cpp:73:7:73:7 | stl.cpp:69:16:69:21 | AST only |
|
||||||
|
| stl.cpp:75:9:75:13 | stl.cpp:69:16:69:21 | AST only |
|
||||||
|
| stl.cpp:125:13:125:17 | stl.cpp:117:10:117:15 | AST only |
|
||||||
|
| stl.cpp:129:13:129:17 | stl.cpp:117:10:117:15 | AST only |
|
||||||
|
| stl.cpp:132:13:132:17 | stl.cpp:117:10:117:15 | AST only |
|
||||||
| taint.cpp:41:7:41:13 | taint.cpp:35:12:35:17 | AST only |
|
| taint.cpp:41:7:41:13 | taint.cpp:35:12:35:17 | AST only |
|
||||||
| taint.cpp:42:7:42:13 | taint.cpp:35:12:35:17 | AST only |
|
| taint.cpp:42:7:42:13 | taint.cpp:35:12:35:17 | AST only |
|
||||||
| taint.cpp:43:7:43:13 | taint.cpp:37:22:37:27 | AST only |
|
| taint.cpp:43:7:43:13 | taint.cpp:37:22:37:27 | AST only |
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
| stl.cpp:71:7:71:7 | (const char *)... | stl.cpp:67:12:67:17 | call to source |
|
||||||
|
| stl.cpp:71:7:71:7 | a | stl.cpp:67:12:67:17 | call to source |
|
||||||
| taint.cpp:8:8:8:13 | clean1 | taint.cpp:4:27:4:33 | source1 |
|
| taint.cpp:8:8:8:13 | clean1 | taint.cpp:4:27:4:33 | source1 |
|
||||||
| 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 |
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
missingOperand
|
missingOperand
|
||||||
unexpectedOperand
|
unexpectedOperand
|
||||||
duplicateOperand
|
duplicateOperand
|
||||||
| ssa.cpp:286:27:286:30 | ReturnIndirection: argv | Instruction has 2 operands with tag 'SideEffect' in function '$@'. | ssa.cpp:286:5:286:8 | IR: main | int main(int, char**) |
|
| ssa.cpp:301:27:301:30 | ReturnIndirection: argv | Instruction has 2 operands with tag 'SideEffect' in function '$@'. | ssa.cpp:301:5:301:8 | IR: main | int main(int, char**) |
|
||||||
missingPhiOperand
|
missingPhiOperand
|
||||||
missingOperandType
|
missingOperandType
|
||||||
duplicateChiOperand
|
duplicateChiOperand
|
||||||
@@ -20,7 +20,7 @@ switchInstructionWithoutDefaultEdge
|
|||||||
notMarkedAsConflated
|
notMarkedAsConflated
|
||||||
wronglyMarkedAsConflated
|
wronglyMarkedAsConflated
|
||||||
invalidOverlap
|
invalidOverlap
|
||||||
| ssa.cpp:286:27:286:30 | SideEffect | MemoryOperand 'SideEffect' has a `getDefinitionOverlap()` of 'MayPartiallyOverlap'. | ssa.cpp:286:5:286:8 | IR: main | int main(int, char**) |
|
| ssa.cpp:301:27:301:30 | SideEffect | MemoryOperand 'SideEffect' has a `getDefinitionOverlap()` of 'MayPartiallyOverlap'. | ssa.cpp:301:5:301:8 | IR: main | int main(int, char**) |
|
||||||
missingCanonicalLanguageType
|
missingCanonicalLanguageType
|
||||||
multipleCanonicalLanguageTypes
|
multipleCanonicalLanguageTypes
|
||||||
missingIRType
|
missingIRType
|
||||||
|
|||||||
@@ -5,3 +5,4 @@
|
|||||||
import semmle.code.cpp.ir.PrintIR
|
import semmle.code.cpp.ir.PrintIR
|
||||||
import semmle.code.cpp.ir.IR
|
import semmle.code.cpp.ir.IR
|
||||||
import semmle.code.cpp.ir.ValueNumbering
|
import semmle.code.cpp.ir.ValueNumbering
|
||||||
|
import semmle.code.cpp.ir.implementation.aliased_ssa.gvn.PrintValueNumbering
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
| test2.cpp:19:3:19:6 | call to free | There is a new/free mismatch between this free and the corresponding $@. | test2.cpp:18:12:18:18 | new | new |
|
| test2.cpp:19:3:19:6 | call to free | There is a new/free mismatch between this free and the corresponding $@. | test2.cpp:18:12:18:18 | new | new |
|
||||||
| test2.cpp:26:3:26:6 | call to free | There is a new/free mismatch between this free and the corresponding $@. | test2.cpp:25:7:25:13 | new | new |
|
| test2.cpp:26:3:26:6 | call to free | There is a new/free mismatch between this free and the corresponding $@. | test2.cpp:25:7:25:13 | new | new |
|
||||||
|
| test2.cpp:51:2:51:5 | call to free | There is a new/free mismatch between this free and the corresponding $@. | test2.cpp:45:18:45:24 | new | new |
|
||||||
|
| test2.cpp:55:2:55:5 | call to free | There is a new/free mismatch between this free and the corresponding $@. | test2.cpp:46:20:46:33 | call to operator new | new |
|
||||||
|
| test2.cpp:57:2:57:18 | delete | There is a malloc/delete mismatch between this delete and the corresponding $@. | test2.cpp:47:21:47:26 | call to malloc | malloc |
|
||||||
|
| test2.cpp:58:2:58:18 | call to operator delete | There is a malloc/delete mismatch between this delete and the corresponding $@. | test2.cpp:47:21:47:26 | call to malloc | malloc |
|
||||||
| test.cpp:36:2:36:17 | delete | There is a malloc/delete mismatch between this delete and the corresponding $@. | test.cpp:27:18:27:23 | call to malloc | malloc |
|
| test.cpp:36:2:36:17 | delete | There is a malloc/delete mismatch between this delete and the corresponding $@. | test.cpp:27:18:27:23 | call to malloc | malloc |
|
||||||
| test.cpp:41:2:41:5 | call to free | There is a new/free mismatch between this free and the corresponding $@. | test.cpp:26:7:26:17 | new | new |
|
| test.cpp:41:2:41:5 | call to free | There is a new/free mismatch between this free and the corresponding $@. | test.cpp:26:7:26:17 | new | new |
|
||||||
| test.cpp:68:3:68:11 | delete | There is a malloc/delete mismatch between this delete and the corresponding $@. | test.cpp:64:28:64:33 | call to malloc | malloc |
|
| test.cpp:68:3:68:11 | delete | There is a malloc/delete mismatch between this delete and the corresponding $@. | test.cpp:64:28:64:33 | call to malloc | malloc |
|
||||||
|
|||||||
@@ -34,3 +34,27 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
MyTest2Class<int> mt2c_i;
|
MyTest2Class<int> mt2c_i;
|
||||||
|
|
||||||
|
// ---
|
||||||
|
|
||||||
|
void* operator new(size_t);
|
||||||
|
void operator delete(void*);
|
||||||
|
|
||||||
|
void test_operator_new()
|
||||||
|
{
|
||||||
|
void *ptr_new = new int;
|
||||||
|
void *ptr_opnew = ::operator new(sizeof(int));
|
||||||
|
void *ptr_malloc = malloc(sizeof(int));
|
||||||
|
|
||||||
|
delete ptr_new; // GOOD
|
||||||
|
::operator delete(ptr_new); // GOOD
|
||||||
|
free(ptr_new); // BAD
|
||||||
|
|
||||||
|
delete ptr_opnew; // GOOD
|
||||||
|
::operator delete(ptr_opnew); // GOOD
|
||||||
|
free(ptr_opnew); // BAD
|
||||||
|
|
||||||
|
delete ptr_malloc; // BAD
|
||||||
|
::operator delete(ptr_malloc); // BAD
|
||||||
|
free(ptr_malloc); // GOOD
|
||||||
|
}
|
||||||
|
|||||||
@@ -1 +1,13 @@
|
|||||||
| test.c:17:11:17:18 | fileName | This argument to a file access function is derived from $@ and then passed to fopen(filename) | test.c:9:23:9:26 | argv | user input (argv) |
|
edges
|
||||||
|
| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | (const char *)... |
|
||||||
|
| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | (const char *)... |
|
||||||
|
| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName |
|
||||||
|
| test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName |
|
||||||
|
nodes
|
||||||
|
| test.c:9:23:9:26 | argv | semmle.label | argv |
|
||||||
|
| test.c:9:23:9:26 | argv | semmle.label | argv |
|
||||||
|
| test.c:17:11:17:18 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| test.c:17:11:17:18 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| test.c:17:11:17:18 | fileName | semmle.label | fileName |
|
||||||
|
#select
|
||||||
|
| test.c:17:11:17:18 | fileName | test.c:9:23:9:26 | argv | test.c:17:11:17:18 | fileName | This argument to a file access function is derived from $@ and then passed to fopen(filename) | test.c:9:23:9:26 | argv | user input (argv) |
|
||||||
|
|||||||
@@ -1,2 +1,30 @@
|
|||||||
| search.c:17:8:17:12 | query | Cross-site scripting vulnerability due to $@. | search.c:41:21:41:26 | call to getenv | this query data |
|
edges
|
||||||
| search.c:23:39:23:43 | query | Cross-site scripting vulnerability due to $@. | search.c:41:21:41:26 | call to getenv | this query data |
|
| search.c:14:24:14:28 | query | search.c:17:8:17:12 | (const char *)... |
|
||||||
|
| search.c:14:24:14:28 | query | search.c:17:8:17:12 | query |
|
||||||
|
| search.c:14:24:14:28 | query | search.c:17:8:17:12 | query |
|
||||||
|
| search.c:22:24:22:28 | query | search.c:23:39:23:43 | query |
|
||||||
|
| search.c:22:24:22:28 | query | search.c:23:39:23:43 | query |
|
||||||
|
| search.c:41:21:41:26 | call to getenv | search.c:45:17:45:25 | raw_query |
|
||||||
|
| search.c:41:21:41:26 | call to getenv | search.c:45:17:45:25 | raw_query |
|
||||||
|
| search.c:41:21:41:26 | call to getenv | search.c:47:17:47:25 | raw_query |
|
||||||
|
| search.c:41:21:41:26 | call to getenv | search.c:47:17:47:25 | raw_query |
|
||||||
|
| search.c:45:17:45:25 | raw_query | search.c:14:24:14:28 | query |
|
||||||
|
| search.c:47:17:47:25 | raw_query | search.c:22:24:22:28 | query |
|
||||||
|
nodes
|
||||||
|
| search.c:14:24:14:28 | query | semmle.label | query |
|
||||||
|
| search.c:17:8:17:12 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| search.c:17:8:17:12 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| search.c:17:8:17:12 | query | semmle.label | query |
|
||||||
|
| search.c:17:8:17:12 | query | semmle.label | query |
|
||||||
|
| search.c:17:8:17:12 | query | semmle.label | query |
|
||||||
|
| search.c:22:24:22:28 | query | semmle.label | query |
|
||||||
|
| search.c:23:39:23:43 | query | semmle.label | query |
|
||||||
|
| search.c:23:39:23:43 | query | semmle.label | query |
|
||||||
|
| search.c:23:39:23:43 | query | semmle.label | query |
|
||||||
|
| search.c:41:21:41:26 | call to getenv | semmle.label | call to getenv |
|
||||||
|
| search.c:41:21:41:26 | call to getenv | semmle.label | call to getenv |
|
||||||
|
| search.c:45:17:45:25 | raw_query | semmle.label | raw_query |
|
||||||
|
| search.c:47:17:47:25 | raw_query | semmle.label | raw_query |
|
||||||
|
#select
|
||||||
|
| search.c:17:8:17:12 | query | search.c:41:21:41:26 | call to getenv | search.c:17:8:17:12 | query | Cross-site scripting vulnerability due to $@. | search.c:41:21:41:26 | call to getenv | this query data |
|
||||||
|
| search.c:23:39:23:43 | query | search.c:41:21:41:26 | call to getenv | search.c:23:39:23:43 | query | Cross-site scripting vulnerability due to $@. | search.c:41:21:41:26 | call to getenv | this query data |
|
||||||
|
|||||||
@@ -1,2 +1,25 @@
|
|||||||
| test.cpp:26:10:26:16 | command | The value of this argument may come from $@ and is being passed to system | test.cpp:42:18:42:23 | call to getenv | call to getenv |
|
edges
|
||||||
| test.cpp:31:10:31:16 | command | The value of this argument may come from $@ and is being passed to system | test.cpp:43:18:43:23 | call to getenv | call to getenv |
|
| test.cpp:24:30:24:36 | command | test.cpp:26:10:26:16 | command |
|
||||||
|
| test.cpp:24:30:24:36 | command | test.cpp:26:10:26:16 | command |
|
||||||
|
| test.cpp:29:30:29:36 | command | test.cpp:31:10:31:16 | command |
|
||||||
|
| test.cpp:29:30:29:36 | command | test.cpp:31:10:31:16 | command |
|
||||||
|
| test.cpp:42:18:42:23 | call to getenv | test.cpp:24:30:24:36 | command |
|
||||||
|
| test.cpp:42:18:42:34 | (const char *)... | test.cpp:24:30:24:36 | command |
|
||||||
|
| test.cpp:43:18:43:23 | call to getenv | test.cpp:29:30:29:36 | command |
|
||||||
|
| test.cpp:43:18:43:34 | (const char *)... | test.cpp:29:30:29:36 | command |
|
||||||
|
nodes
|
||||||
|
| test.cpp:24:30:24:36 | command | semmle.label | command |
|
||||||
|
| test.cpp:26:10:26:16 | command | semmle.label | command |
|
||||||
|
| test.cpp:26:10:26:16 | command | semmle.label | command |
|
||||||
|
| test.cpp:26:10:26:16 | command | semmle.label | command |
|
||||||
|
| test.cpp:29:30:29:36 | command | semmle.label | command |
|
||||||
|
| test.cpp:31:10:31:16 | command | semmle.label | command |
|
||||||
|
| test.cpp:31:10:31:16 | command | semmle.label | command |
|
||||||
|
| test.cpp:31:10:31:16 | command | semmle.label | command |
|
||||||
|
| test.cpp:42:18:42:23 | call to getenv | semmle.label | call to getenv |
|
||||||
|
| test.cpp:42:18:42:34 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| test.cpp:43:18:43:23 | call to getenv | semmle.label | call to getenv |
|
||||||
|
| test.cpp:43:18:43:34 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
#select
|
||||||
|
| test.cpp:26:10:26:16 | command | test.cpp:42:18:42:23 | call to getenv | test.cpp:26:10:26:16 | command | The value of this argument may come from $@ and is being passed to system | test.cpp:42:18:42:23 | call to getenv | call to getenv |
|
||||||
|
| test.cpp:31:10:31:16 | command | test.cpp:43:18:43:23 | call to getenv | test.cpp:31:10:31:16 | command | The value of this argument may come from $@ and is being passed to system | test.cpp:43:18:43:23 | call to getenv | call to getenv |
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
edges
|
||||||
|
nodes
|
||||||
|
#select
|
||||||
|
|||||||
@@ -1,5 +1,53 @@
|
|||||||
| tests.c:28:3:28:9 | call to sprintf | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:28:22:28:25 | argv | argv |
|
edges
|
||||||
| tests.c:29:3:29:9 | call to sprintf | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:29:28:29:31 | argv | argv |
|
| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | (const char *)... |
|
||||||
| tests.c:31:15:31:23 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:31:15:31:23 | buffer100 | buffer100 |
|
| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | (const char *)... |
|
||||||
| tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:33:21:33:29 | buffer100 | buffer100 |
|
| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array |
|
||||||
| tests.c:34:25:34:33 | buffer100 | This 'sscanf string argument' with input from $@ may overflow the destination. | tests.c:34:10:34:13 | argv | argv |
|
| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array |
|
||||||
|
| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array |
|
||||||
|
| tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array |
|
||||||
|
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array |
|
||||||
|
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array |
|
||||||
|
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array |
|
||||||
|
| tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array |
|
||||||
|
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | (const char *)... |
|
||||||
|
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | (const char *)... |
|
||||||
|
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array |
|
||||||
|
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array |
|
||||||
|
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array |
|
||||||
|
| tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array |
|
||||||
|
nodes
|
||||||
|
| tests.c:28:22:28:25 | argv | semmle.label | argv |
|
||||||
|
| tests.c:28:22:28:25 | argv | semmle.label | argv |
|
||||||
|
| tests.c:28:22:28:28 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| tests.c:28:22:28:28 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| tests.c:28:22:28:28 | access to array | semmle.label | access to array |
|
||||||
|
| tests.c:28:22:28:28 | access to array | semmle.label | access to array |
|
||||||
|
| tests.c:28:22:28:28 | access to array | semmle.label | access to array |
|
||||||
|
| tests.c:29:28:29:31 | argv | semmle.label | argv |
|
||||||
|
| tests.c:29:28:29:31 | argv | semmle.label | argv |
|
||||||
|
| tests.c:29:28:29:34 | access to array | semmle.label | access to array |
|
||||||
|
| tests.c:29:28:29:34 | access to array | semmle.label | access to array |
|
||||||
|
| tests.c:29:28:29:34 | access to array | semmle.label | access to array |
|
||||||
|
| tests.c:31:15:31:23 | array to pointer conversion | semmle.label | array to pointer conversion |
|
||||||
|
| tests.c:31:15:31:23 | array to pointer conversion | semmle.label | array to pointer conversion |
|
||||||
|
| tests.c:31:15:31:23 | buffer100 | semmle.label | buffer100 |
|
||||||
|
| tests.c:31:15:31:23 | buffer100 | semmle.label | buffer100 |
|
||||||
|
| tests.c:31:15:31:23 | buffer100 | semmle.label | buffer100 |
|
||||||
|
| tests.c:33:21:33:29 | array to pointer conversion | semmle.label | array to pointer conversion |
|
||||||
|
| tests.c:33:21:33:29 | array to pointer conversion | semmle.label | array to pointer conversion |
|
||||||
|
| tests.c:33:21:33:29 | buffer100 | semmle.label | buffer100 |
|
||||||
|
| tests.c:33:21:33:29 | buffer100 | semmle.label | buffer100 |
|
||||||
|
| tests.c:33:21:33:29 | buffer100 | semmle.label | buffer100 |
|
||||||
|
| tests.c:34:10:34:13 | argv | semmle.label | argv |
|
||||||
|
| tests.c:34:10:34:13 | argv | semmle.label | argv |
|
||||||
|
| tests.c:34:10:34:16 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| tests.c:34:10:34:16 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| tests.c:34:10:34:16 | access to array | semmle.label | access to array |
|
||||||
|
| tests.c:34:10:34:16 | access to array | semmle.label | access to array |
|
||||||
|
| tests.c:34:10:34:16 | access to array | semmle.label | access to array |
|
||||||
|
#select
|
||||||
|
| tests.c:28:3:28:9 | call to sprintf | tests.c:28:22:28:25 | argv | tests.c:28:22:28:28 | access to array | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:28:22:28:25 | argv | argv |
|
||||||
|
| tests.c:29:3:29:9 | call to sprintf | tests.c:29:28:29:31 | argv | tests.c:29:28:29:34 | access to array | This 'call to sprintf' with input from $@ may overflow the destination. | tests.c:29:28:29:31 | argv | argv |
|
||||||
|
| tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 | tests.c:31:15:31:23 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:31:15:31:23 | buffer100 | buffer100 |
|
||||||
|
| tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 | tests.c:33:21:33:29 | buffer100 | This 'scanf string argument' with input from $@ may overflow the destination. | tests.c:33:21:33:29 | buffer100 | buffer100 |
|
||||||
|
| tests.c:34:25:34:33 | buffer100 | tests.c:34:10:34:13 | argv | tests.c:34:10:34:16 | access to array | This 'sscanf string argument' with input from $@ may overflow the destination. | tests.c:34:10:34:13 | argv | argv |
|
||||||
|
|||||||
@@ -1,28 +1,314 @@
|
|||||||
| argvLocal.c:95:9:95:15 | access to array | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:95:9:95:12 | argv | argv |
|
edges
|
||||||
| argvLocal.c:96:15:96:21 | access to array | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:96:15:96:18 | argv | argv |
|
| argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | (const char *)... |
|
||||||
| argvLocal.c:101:9:101:10 | i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:100:7:100:10 | argv | argv |
|
| argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | (const char *)... |
|
||||||
| argvLocal.c:102:15:102:16 | i1 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:100:7:100:10 | argv | argv |
|
| argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array |
|
||||||
| argvLocal.c:106:9:106:13 | access to array | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:105:14:105:17 | argv | argv |
|
| argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array |
|
||||||
| argvLocal.c:107:15:107:19 | access to array | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:105:14:105:17 | argv | argv |
|
| argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array |
|
||||||
| argvLocal.c:110:9:110:11 | * ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:105:14:105:17 | argv | argv |
|
| argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array |
|
||||||
| argvLocal.c:111:15:111:17 | * ... | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:105:14:105:17 | argv | argv |
|
| argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array |
|
||||||
| argvLocal.c:116:9:116:10 | i3 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:115:13:115:16 | argv | argv |
|
| argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array |
|
||||||
| argvLocal.c:117:15:117:16 | i3 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:115:13:115:16 | argv | argv |
|
| argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array |
|
||||||
| argvLocal.c:121:9:121:10 | i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:115:13:115:16 | argv | argv |
|
| argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array |
|
||||||
| argvLocal.c:122:15:122:16 | i4 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:115:13:115:16 | argv | argv |
|
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | (const char *)... |
|
||||||
| argvLocal.c:127:9:127:10 | i5 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:126:10:126:13 | argv | argv |
|
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | (const char *)... |
|
||||||
| argvLocal.c:128:15:128:16 | i5 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:126:10:126:13 | argv | argv |
|
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | i1 |
|
||||||
| argvLocal.c:131:9:131:14 | ... + ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:126:10:126:13 | argv | argv |
|
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | i1 |
|
||||||
| argvLocal.c:132:15:132:20 | ... + ... | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:126:10:126:13 | argv | argv |
|
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | i1 |
|
||||||
| argvLocal.c:135:9:135:12 | ... ++ | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:115:13:115:16 | argv | argv |
|
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | i1 |
|
||||||
| argvLocal.c:136:15:136:18 | -- ... | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:115:13:115:16 | argv | argv |
|
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:102:15:102:16 | i1 |
|
||||||
| argvLocal.c:144:9:144:10 | i7 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:100:7:100:10 | argv | argv |
|
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:102:15:102:16 | i1 |
|
||||||
| argvLocal.c:145:15:145:16 | i7 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:100:7:100:10 | argv | argv |
|
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:102:15:102:16 | i1 |
|
||||||
| argvLocal.c:150:9:150:10 | i8 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:149:11:149:14 | argv | argv |
|
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:102:15:102:16 | i1 |
|
||||||
| argvLocal.c:151:15:151:16 | i8 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:149:11:149:14 | argv | argv |
|
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | (const char *)... |
|
||||||
| argvLocal.c:157:9:157:10 | i9 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:156:23:156:26 | argv | argv |
|
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | (const char *)... |
|
||||||
| argvLocal.c:158:15:158:16 | i9 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:156:23:156:26 | argv | argv |
|
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | i7 |
|
||||||
| argvLocal.c:164:9:164:11 | i91 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:163:22:163:25 | argv | argv |
|
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | i7 |
|
||||||
| argvLocal.c:165:15:165:17 | i91 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:163:22:163:25 | argv | argv |
|
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | i7 |
|
||||||
| argvLocal.c:169:18:169:20 | i10 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:168:18:168:21 | argv | argv |
|
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | i7 |
|
||||||
| argvLocal.c:170:24:170:26 | i10 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:168:18:168:21 | argv | argv |
|
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:145:15:145:16 | i7 |
|
||||||
|
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:145:15:145:16 | i7 |
|
||||||
|
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:145:15:145:16 | i7 |
|
||||||
|
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:145:15:145:16 | i7 |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | (const char *)... |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | (const char *)... |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | (const char *)... |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | (const char *)... |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | (const char *)... |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | (const char *)... |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | array to pointer conversion |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | array to pointer conversion |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | array to pointer conversion |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | array to pointer conversion |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | (const char *)... |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | (const char *)... |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | (const char *)... |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | (const char *)... |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... |
|
||||||
|
| argvLocal.c:117:15:117:16 | array to pointer conversion | argvLocal.c:117:15:117:16 | printWrapper output argument |
|
||||||
|
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:121:9:121:10 | (const char *)... |
|
||||||
|
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:121:9:121:10 | i4 |
|
||||||
|
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | i4 |
|
||||||
|
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | i4 |
|
||||||
|
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | i4 |
|
||||||
|
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | (const char *)... |
|
||||||
|
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | ... ++ |
|
||||||
|
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... |
|
||||||
|
| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... |
|
||||||
|
| argvLocal.c:122:15:122:16 | i4 | argvLocal.c:122:15:122:16 | printWrapper output argument |
|
||||||
|
| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | (const char *)... |
|
||||||
|
| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | ... ++ |
|
||||||
|
| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... |
|
||||||
|
| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | -- ... |
|
||||||
|
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | (const char *)... |
|
||||||
|
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | (const char *)... |
|
||||||
|
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 |
|
||||||
|
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 |
|
||||||
|
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | array to pointer conversion |
|
||||||
|
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | array to pointer conversion |
|
||||||
|
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | array to pointer conversion |
|
||||||
|
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | array to pointer conversion |
|
||||||
|
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 |
|
||||||
|
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 |
|
||||||
|
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:131:9:131:14 | (const char *)... |
|
||||||
|
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:131:9:131:14 | (const char *)... |
|
||||||
|
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:131:9:131:14 | ... + ... |
|
||||||
|
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:131:9:131:14 | ... + ... |
|
||||||
|
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... |
|
||||||
|
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... |
|
||||||
|
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... |
|
||||||
|
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... |
|
||||||
|
| argvLocal.c:128:15:128:16 | array to pointer conversion | argvLocal.c:128:15:128:16 | printWrapper output argument |
|
||||||
|
| argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:131:9:131:14 | (const char *)... |
|
||||||
|
| argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:131:9:131:14 | ... + ... |
|
||||||
|
| argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:132:15:132:20 | ... + ... |
|
||||||
|
| argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:132:15:132:20 | ... + ... |
|
||||||
|
| argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | (const char *)... |
|
||||||
|
| argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | (const char *)... |
|
||||||
|
| argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | i8 |
|
||||||
|
| argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | i8 |
|
||||||
|
| argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | i8 |
|
||||||
|
| argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | i8 |
|
||||||
|
| argvLocal.c:149:11:149:14 | argv | argvLocal.c:151:15:151:16 | i8 |
|
||||||
|
| argvLocal.c:149:11:149:14 | argv | argvLocal.c:151:15:151:16 | i8 |
|
||||||
|
| argvLocal.c:149:11:149:14 | argv | argvLocal.c:151:15:151:16 | i8 |
|
||||||
|
| argvLocal.c:149:11:149:14 | argv | argvLocal.c:151:15:151:16 | i8 |
|
||||||
|
| argvLocal.c:156:23:156:26 | argv | argvLocal.c:157:9:157:10 | (const char *)... |
|
||||||
|
| argvLocal.c:156:23:156:26 | argv | argvLocal.c:157:9:157:10 | (const char *)... |
|
||||||
|
| argvLocal.c:156:23:156:26 | argv | argvLocal.c:157:9:157:10 | i9 |
|
||||||
|
| argvLocal.c:156:23:156:26 | argv | argvLocal.c:157:9:157:10 | i9 |
|
||||||
|
| argvLocal.c:156:23:156:26 | argv | argvLocal.c:158:15:158:16 | i9 |
|
||||||
|
| argvLocal.c:156:23:156:26 | argv | argvLocal.c:158:15:158:16 | i9 |
|
||||||
|
| argvLocal.c:156:23:156:26 | argv | argvLocal.c:158:15:158:16 | i9 |
|
||||||
|
| argvLocal.c:156:23:156:26 | argv | argvLocal.c:158:15:158:16 | i9 |
|
||||||
|
| argvLocal.c:163:22:163:25 | argv | argvLocal.c:164:9:164:11 | (const char *)... |
|
||||||
|
| argvLocal.c:163:22:163:25 | argv | argvLocal.c:164:9:164:11 | (const char *)... |
|
||||||
|
| argvLocal.c:163:22:163:25 | argv | argvLocal.c:164:9:164:11 | i91 |
|
||||||
|
| argvLocal.c:163:22:163:25 | argv | argvLocal.c:164:9:164:11 | i91 |
|
||||||
|
| argvLocal.c:163:22:163:25 | argv | argvLocal.c:165:15:165:17 | i91 |
|
||||||
|
| argvLocal.c:163:22:163:25 | argv | argvLocal.c:165:15:165:17 | i91 |
|
||||||
|
| argvLocal.c:163:22:163:25 | argv | argvLocal.c:165:15:165:17 | i91 |
|
||||||
|
| argvLocal.c:163:22:163:25 | argv | argvLocal.c:165:15:165:17 | i91 |
|
||||||
|
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:9:169:20 | (char *)... |
|
||||||
|
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:9:169:20 | (char *)... |
|
||||||
|
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:9:169:20 | (const char *)... |
|
||||||
|
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:9:169:20 | (const char *)... |
|
||||||
|
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:18:169:20 | i10 |
|
||||||
|
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:18:169:20 | i10 |
|
||||||
|
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:18:169:20 | i10 |
|
||||||
|
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:18:169:20 | i10 |
|
||||||
|
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:15:170:26 | (char *)... |
|
||||||
|
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:15:170:26 | (char *)... |
|
||||||
|
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:24:170:26 | i10 |
|
||||||
|
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:24:170:26 | i10 |
|
||||||
|
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:24:170:26 | i10 |
|
||||||
|
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:24:170:26 | i10 |
|
||||||
|
nodes
|
||||||
|
| argvLocal.c:9:25:9:31 | correct | semmle.label | correct |
|
||||||
|
| argvLocal.c:10:9:10:15 | Chi | semmle.label | Chi |
|
||||||
|
| argvLocal.c:95:9:95:12 | argv | semmle.label | argv |
|
||||||
|
| argvLocal.c:95:9:95:12 | argv | semmle.label | argv |
|
||||||
|
| argvLocal.c:95:9:95:15 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:95:9:95:15 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:95:9:95:15 | access to array | semmle.label | access to array |
|
||||||
|
| argvLocal.c:95:9:95:15 | access to array | semmle.label | access to array |
|
||||||
|
| argvLocal.c:95:9:95:15 | access to array | semmle.label | access to array |
|
||||||
|
| argvLocal.c:96:15:96:18 | argv | semmle.label | argv |
|
||||||
|
| argvLocal.c:96:15:96:18 | argv | semmle.label | argv |
|
||||||
|
| argvLocal.c:96:15:96:21 | access to array | semmle.label | access to array |
|
||||||
|
| argvLocal.c:96:15:96:21 | access to array | semmle.label | access to array |
|
||||||
|
| argvLocal.c:96:15:96:21 | access to array | semmle.label | access to array |
|
||||||
|
| argvLocal.c:100:7:100:10 | argv | semmle.label | argv |
|
||||||
|
| argvLocal.c:100:7:100:10 | argv | semmle.label | argv |
|
||||||
|
| argvLocal.c:101:9:101:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:101:9:101:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:101:9:101:10 | i1 | semmle.label | i1 |
|
||||||
|
| argvLocal.c:101:9:101:10 | i1 | semmle.label | i1 |
|
||||||
|
| argvLocal.c:101:9:101:10 | i1 | semmle.label | i1 |
|
||||||
|
| argvLocal.c:102:15:102:16 | i1 | semmle.label | i1 |
|
||||||
|
| argvLocal.c:102:15:102:16 | i1 | semmle.label | i1 |
|
||||||
|
| argvLocal.c:102:15:102:16 | i1 | semmle.label | i1 |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | semmle.label | argv |
|
||||||
|
| argvLocal.c:105:14:105:17 | argv | semmle.label | argv |
|
||||||
|
| argvLocal.c:106:9:106:13 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:106:9:106:13 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:106:9:106:13 | access to array | semmle.label | access to array |
|
||||||
|
| argvLocal.c:106:9:106:13 | access to array | semmle.label | access to array |
|
||||||
|
| argvLocal.c:106:9:106:13 | access to array | semmle.label | access to array |
|
||||||
|
| argvLocal.c:107:15:107:19 | access to array | semmle.label | access to array |
|
||||||
|
| argvLocal.c:107:15:107:19 | access to array | semmle.label | access to array |
|
||||||
|
| argvLocal.c:107:15:107:19 | access to array | semmle.label | access to array |
|
||||||
|
| argvLocal.c:110:9:110:11 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:110:9:110:11 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:110:9:110:11 | * ... | semmle.label | * ... |
|
||||||
|
| argvLocal.c:110:9:110:11 | * ... | semmle.label | * ... |
|
||||||
|
| argvLocal.c:110:9:110:11 | * ... | semmle.label | * ... |
|
||||||
|
| argvLocal.c:111:15:111:17 | * ... | semmle.label | * ... |
|
||||||
|
| argvLocal.c:111:15:111:17 | * ... | semmle.label | * ... |
|
||||||
|
| argvLocal.c:111:15:111:17 | * ... | semmle.label | * ... |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | semmle.label | argv |
|
||||||
|
| argvLocal.c:115:13:115:16 | argv | semmle.label | argv |
|
||||||
|
| argvLocal.c:116:9:116:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:116:9:116:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:116:9:116:10 | i3 | semmle.label | i3 |
|
||||||
|
| argvLocal.c:117:15:117:16 | array to pointer conversion | semmle.label | array to pointer conversion |
|
||||||
|
| argvLocal.c:117:15:117:16 | array to pointer conversion | semmle.label | array to pointer conversion |
|
||||||
|
| argvLocal.c:117:15:117:16 | i3 | semmle.label | i3 |
|
||||||
|
| argvLocal.c:117:15:117:16 | printWrapper output argument | semmle.label | printWrapper output argument |
|
||||||
|
| argvLocal.c:121:9:121:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:121:9:121:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:121:9:121:10 | i4 | semmle.label | i4 |
|
||||||
|
| argvLocal.c:122:15:122:16 | i4 | semmle.label | i4 |
|
||||||
|
| argvLocal.c:122:15:122:16 | i4 | semmle.label | i4 |
|
||||||
|
| argvLocal.c:122:15:122:16 | i4 | semmle.label | i4 |
|
||||||
|
| argvLocal.c:122:15:122:16 | printWrapper output argument | semmle.label | printWrapper output argument |
|
||||||
|
| argvLocal.c:126:10:126:13 | argv | semmle.label | argv |
|
||||||
|
| argvLocal.c:126:10:126:13 | argv | semmle.label | argv |
|
||||||
|
| argvLocal.c:127:9:127:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:127:9:127:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:127:9:127:10 | i5 | semmle.label | i5 |
|
||||||
|
| argvLocal.c:128:15:128:16 | array to pointer conversion | semmle.label | array to pointer conversion |
|
||||||
|
| argvLocal.c:128:15:128:16 | array to pointer conversion | semmle.label | array to pointer conversion |
|
||||||
|
| argvLocal.c:128:15:128:16 | i5 | semmle.label | i5 |
|
||||||
|
| argvLocal.c:128:15:128:16 | printWrapper output argument | semmle.label | printWrapper output argument |
|
||||||
|
| argvLocal.c:131:9:131:14 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:131:9:131:14 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:131:9:131:14 | ... + ... | semmle.label | ... + ... |
|
||||||
|
| argvLocal.c:132:15:132:20 | ... + ... | semmle.label | ... + ... |
|
||||||
|
| argvLocal.c:132:15:132:20 | ... + ... | semmle.label | ... + ... |
|
||||||
|
| argvLocal.c:132:15:132:20 | ... + ... | semmle.label | ... + ... |
|
||||||
|
| argvLocal.c:135:9:135:12 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:135:9:135:12 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:135:9:135:12 | ... ++ | semmle.label | ... ++ |
|
||||||
|
| argvLocal.c:136:15:136:18 | -- ... | semmle.label | -- ... |
|
||||||
|
| argvLocal.c:136:15:136:18 | -- ... | semmle.label | -- ... |
|
||||||
|
| argvLocal.c:136:15:136:18 | -- ... | semmle.label | -- ... |
|
||||||
|
| argvLocal.c:144:9:144:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:144:9:144:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:144:9:144:10 | i7 | semmle.label | i7 |
|
||||||
|
| argvLocal.c:144:9:144:10 | i7 | semmle.label | i7 |
|
||||||
|
| argvLocal.c:144:9:144:10 | i7 | semmle.label | i7 |
|
||||||
|
| argvLocal.c:145:15:145:16 | i7 | semmle.label | i7 |
|
||||||
|
| argvLocal.c:145:15:145:16 | i7 | semmle.label | i7 |
|
||||||
|
| argvLocal.c:145:15:145:16 | i7 | semmle.label | i7 |
|
||||||
|
| argvLocal.c:149:11:149:14 | argv | semmle.label | argv |
|
||||||
|
| argvLocal.c:149:11:149:14 | argv | semmle.label | argv |
|
||||||
|
| argvLocal.c:150:9:150:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:150:9:150:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:150:9:150:10 | i8 | semmle.label | i8 |
|
||||||
|
| argvLocal.c:150:9:150:10 | i8 | semmle.label | i8 |
|
||||||
|
| argvLocal.c:150:9:150:10 | i8 | semmle.label | i8 |
|
||||||
|
| argvLocal.c:151:15:151:16 | i8 | semmle.label | i8 |
|
||||||
|
| argvLocal.c:151:15:151:16 | i8 | semmle.label | i8 |
|
||||||
|
| argvLocal.c:151:15:151:16 | i8 | semmle.label | i8 |
|
||||||
|
| argvLocal.c:156:23:156:26 | argv | semmle.label | argv |
|
||||||
|
| argvLocal.c:156:23:156:26 | argv | semmle.label | argv |
|
||||||
|
| argvLocal.c:157:9:157:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:157:9:157:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:157:9:157:10 | i9 | semmle.label | i9 |
|
||||||
|
| argvLocal.c:158:15:158:16 | i9 | semmle.label | i9 |
|
||||||
|
| argvLocal.c:158:15:158:16 | i9 | semmle.label | i9 |
|
||||||
|
| argvLocal.c:158:15:158:16 | i9 | semmle.label | i9 |
|
||||||
|
| argvLocal.c:163:22:163:25 | argv | semmle.label | argv |
|
||||||
|
| argvLocal.c:163:22:163:25 | argv | semmle.label | argv |
|
||||||
|
| argvLocal.c:164:9:164:11 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:164:9:164:11 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:164:9:164:11 | i91 | semmle.label | i91 |
|
||||||
|
| argvLocal.c:165:15:165:17 | i91 | semmle.label | i91 |
|
||||||
|
| argvLocal.c:165:15:165:17 | i91 | semmle.label | i91 |
|
||||||
|
| argvLocal.c:165:15:165:17 | i91 | semmle.label | i91 |
|
||||||
|
| argvLocal.c:168:18:168:21 | argv | semmle.label | argv |
|
||||||
|
| argvLocal.c:168:18:168:21 | argv | semmle.label | argv |
|
||||||
|
| argvLocal.c:169:9:169:20 | (char *)... | semmle.label | (char *)... |
|
||||||
|
| argvLocal.c:169:9:169:20 | (char *)... | semmle.label | (char *)... |
|
||||||
|
| argvLocal.c:169:9:169:20 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:169:9:169:20 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| argvLocal.c:169:18:169:20 | i10 | semmle.label | i10 |
|
||||||
|
| argvLocal.c:169:18:169:20 | i10 | semmle.label | i10 |
|
||||||
|
| argvLocal.c:169:18:169:20 | i10 | semmle.label | i10 |
|
||||||
|
| argvLocal.c:170:15:170:26 | (char *)... | semmle.label | (char *)... |
|
||||||
|
| argvLocal.c:170:15:170:26 | (char *)... | semmle.label | (char *)... |
|
||||||
|
| argvLocal.c:170:24:170:26 | i10 | semmle.label | i10 |
|
||||||
|
| argvLocal.c:170:24:170:26 | i10 | semmle.label | i10 |
|
||||||
|
| argvLocal.c:170:24:170:26 | i10 | semmle.label | i10 |
|
||||||
|
#select
|
||||||
|
| argvLocal.c:95:9:95:15 | access to array | argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:95:9:95:12 | argv | argv |
|
||||||
|
| argvLocal.c:96:15:96:21 | access to array | argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:96:15:96:18 | argv | argv |
|
||||||
|
| argvLocal.c:101:9:101:10 | i1 | argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:100:7:100:10 | argv | argv |
|
||||||
|
| argvLocal.c:102:15:102:16 | i1 | argvLocal.c:100:7:100:10 | argv | argvLocal.c:102:15:102:16 | i1 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:100:7:100:10 | argv | argv |
|
||||||
|
| argvLocal.c:106:9:106:13 | access to array | argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:105:14:105:17 | argv | argv |
|
||||||
|
| argvLocal.c:107:15:107:19 | access to array | argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:105:14:105:17 | argv | argv |
|
||||||
|
| argvLocal.c:110:9:110:11 | * ... | argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:105:14:105:17 | argv | argv |
|
||||||
|
| argvLocal.c:111:15:111:17 | * ... | argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:105:14:105:17 | argv | argv |
|
||||||
|
| argvLocal.c:116:9:116:10 | i3 | argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:115:13:115:16 | argv | argv |
|
||||||
|
| argvLocal.c:117:15:117:16 | i3 | argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:115:13:115:16 | argv | argv |
|
||||||
|
| argvLocal.c:121:9:121:10 | i4 | argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:115:13:115:16 | argv | argv |
|
||||||
|
| argvLocal.c:122:15:122:16 | i4 | argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:115:13:115:16 | argv | argv |
|
||||||
|
| argvLocal.c:127:9:127:10 | i5 | argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:126:10:126:13 | argv | argv |
|
||||||
|
| argvLocal.c:128:15:128:16 | i5 | argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:126:10:126:13 | argv | argv |
|
||||||
|
| argvLocal.c:131:9:131:14 | ... + ... | argvLocal.c:126:10:126:13 | argv | argvLocal.c:131:9:131:14 | ... + ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:126:10:126:13 | argv | argv |
|
||||||
|
| argvLocal.c:132:15:132:20 | ... + ... | argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:126:10:126:13 | argv | argv |
|
||||||
|
| argvLocal.c:135:9:135:12 | ... ++ | argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:115:13:115:16 | argv | argv |
|
||||||
|
| argvLocal.c:136:15:136:18 | -- ... | argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:115:13:115:16 | argv | argv |
|
||||||
|
| argvLocal.c:144:9:144:10 | i7 | argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | i7 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:100:7:100:10 | argv | argv |
|
||||||
|
| argvLocal.c:145:15:145:16 | i7 | argvLocal.c:100:7:100:10 | argv | argvLocal.c:145:15:145:16 | i7 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:100:7:100:10 | argv | argv |
|
||||||
|
| argvLocal.c:150:9:150:10 | i8 | argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | i8 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:149:11:149:14 | argv | argv |
|
||||||
|
| argvLocal.c:151:15:151:16 | i8 | argvLocal.c:149:11:149:14 | argv | argvLocal.c:151:15:151:16 | i8 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:149:11:149:14 | argv | argv |
|
||||||
|
| argvLocal.c:157:9:157:10 | i9 | argvLocal.c:156:23:156:26 | argv | argvLocal.c:157:9:157:10 | i9 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:156:23:156:26 | argv | argv |
|
||||||
|
| argvLocal.c:158:15:158:16 | i9 | argvLocal.c:156:23:156:26 | argv | argvLocal.c:158:15:158:16 | i9 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:156:23:156:26 | argv | argv |
|
||||||
|
| argvLocal.c:164:9:164:11 | i91 | argvLocal.c:163:22:163:25 | argv | argvLocal.c:164:9:164:11 | i91 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:163:22:163:25 | argv | argv |
|
||||||
|
| argvLocal.c:165:15:165:17 | i91 | argvLocal.c:163:22:163:25 | argv | argvLocal.c:165:15:165:17 | i91 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:163:22:163:25 | argv | argv |
|
||||||
|
| argvLocal.c:169:18:169:20 | i10 | argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:18:169:20 | i10 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | argvLocal.c:168:18:168:21 | argv | argv |
|
||||||
|
| argvLocal.c:170:24:170:26 | i10 | argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:24:170:26 | i10 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format) | argvLocal.c:168:18:168:21 | argv | argv |
|
||||||
|
|||||||
@@ -1,8 +1,83 @@
|
|||||||
| funcsLocal.c:17:9:17:10 | i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:16:8:16:9 | i1 | fread |
|
edges
|
||||||
| funcsLocal.c:27:9:27:10 | i3 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:26:8:26:9 | i3 | fgets |
|
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | (const char *)... |
|
||||||
| funcsLocal.c:32:9:32:10 | i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:31:13:31:17 | call to fgets | fgets |
|
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | i1 |
|
||||||
| funcsLocal.c:32:9:32:10 | i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:31:19:31:21 | i41 | fgets |
|
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:58:9:58:10 | (const char *)... |
|
||||||
| funcsLocal.c:37:9:37:10 | i5 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:36:7:36:8 | i5 | gets |
|
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:58:9:58:10 | e1 |
|
||||||
| funcsLocal.c:42:9:42:10 | i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:41:13:41:16 | call to gets | gets |
|
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | (const char *)... |
|
||||||
| funcsLocal.c:42:9:42:10 | i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:41:18:41:20 | i61 | gets |
|
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 |
|
||||||
| funcsLocal.c:58:9:58:10 | e1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:16:8:16:9 | i1 | fread |
|
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | (const char *)... |
|
||||||
|
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | e1 |
|
||||||
|
| funcsLocal.c:26:8:26:9 | fgets output argument | funcsLocal.c:27:9:27:10 | (const char *)... |
|
||||||
|
| funcsLocal.c:26:8:26:9 | fgets output argument | funcsLocal.c:27:9:27:10 | i3 |
|
||||||
|
| funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | (const char *)... |
|
||||||
|
| funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | i3 |
|
||||||
|
| funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | (const char *)... |
|
||||||
|
| funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | (const char *)... |
|
||||||
|
| funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | i4 |
|
||||||
|
| funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | i4 |
|
||||||
|
| funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | i4 |
|
||||||
|
| funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | i4 |
|
||||||
|
| funcsLocal.c:31:19:31:21 | fgets output argument | funcsLocal.c:32:9:32:10 | (const char *)... |
|
||||||
|
| funcsLocal.c:31:19:31:21 | fgets output argument | funcsLocal.c:32:9:32:10 | i4 |
|
||||||
|
| funcsLocal.c:31:19:31:21 | i41 | funcsLocal.c:32:9:32:10 | (const char *)... |
|
||||||
|
| funcsLocal.c:31:19:31:21 | i41 | funcsLocal.c:32:9:32:10 | i4 |
|
||||||
|
| funcsLocal.c:36:7:36:8 | gets output argument | funcsLocal.c:37:9:37:10 | (const char *)... |
|
||||||
|
| funcsLocal.c:36:7:36:8 | gets output argument | funcsLocal.c:37:9:37:10 | i5 |
|
||||||
|
| funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | (const char *)... |
|
||||||
|
| funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | i5 |
|
||||||
|
| funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | (const char *)... |
|
||||||
|
| funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | (const char *)... |
|
||||||
|
| funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 |
|
||||||
|
| funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 |
|
||||||
|
| funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 |
|
||||||
|
| funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 |
|
||||||
|
| funcsLocal.c:41:18:41:20 | gets output argument | funcsLocal.c:42:9:42:10 | (const char *)... |
|
||||||
|
| funcsLocal.c:41:18:41:20 | gets output argument | funcsLocal.c:42:9:42:10 | i6 |
|
||||||
|
| funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | (const char *)... |
|
||||||
|
| funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | i6 |
|
||||||
|
nodes
|
||||||
|
| funcsLocal.c:16:8:16:9 | fread output argument | semmle.label | fread output argument |
|
||||||
|
| funcsLocal.c:16:8:16:9 | i1 | semmle.label | i1 |
|
||||||
|
| funcsLocal.c:17:9:17:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| funcsLocal.c:17:9:17:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| funcsLocal.c:17:9:17:10 | i1 | semmle.label | i1 |
|
||||||
|
| funcsLocal.c:26:8:26:9 | fgets output argument | semmle.label | fgets output argument |
|
||||||
|
| funcsLocal.c:26:8:26:9 | i3 | semmle.label | i3 |
|
||||||
|
| funcsLocal.c:27:9:27:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| funcsLocal.c:27:9:27:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| funcsLocal.c:27:9:27:10 | i3 | semmle.label | i3 |
|
||||||
|
| funcsLocal.c:31:13:31:17 | call to fgets | semmle.label | call to fgets |
|
||||||
|
| funcsLocal.c:31:13:31:17 | call to fgets | semmle.label | call to fgets |
|
||||||
|
| funcsLocal.c:31:19:31:21 | fgets output argument | semmle.label | fgets output argument |
|
||||||
|
| funcsLocal.c:31:19:31:21 | i41 | semmle.label | i41 |
|
||||||
|
| funcsLocal.c:32:9:32:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| funcsLocal.c:32:9:32:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| funcsLocal.c:32:9:32:10 | i4 | semmle.label | i4 |
|
||||||
|
| funcsLocal.c:32:9:32:10 | i4 | semmle.label | i4 |
|
||||||
|
| funcsLocal.c:32:9:32:10 | i4 | semmle.label | i4 |
|
||||||
|
| funcsLocal.c:36:7:36:8 | gets output argument | semmle.label | gets output argument |
|
||||||
|
| funcsLocal.c:36:7:36:8 | i5 | semmle.label | i5 |
|
||||||
|
| funcsLocal.c:37:9:37:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| funcsLocal.c:37:9:37:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| funcsLocal.c:37:9:37:10 | i5 | semmle.label | i5 |
|
||||||
|
| funcsLocal.c:41:13:41:16 | call to gets | semmle.label | call to gets |
|
||||||
|
| funcsLocal.c:41:13:41:16 | call to gets | semmle.label | call to gets |
|
||||||
|
| funcsLocal.c:41:18:41:20 | gets output argument | semmle.label | gets output argument |
|
||||||
|
| funcsLocal.c:41:18:41:20 | i61 | semmle.label | i61 |
|
||||||
|
| funcsLocal.c:42:9:42:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| funcsLocal.c:42:9:42:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| funcsLocal.c:42:9:42:10 | i6 | semmle.label | i6 |
|
||||||
|
| funcsLocal.c:42:9:42:10 | i6 | semmle.label | i6 |
|
||||||
|
| funcsLocal.c:42:9:42:10 | i6 | semmle.label | i6 |
|
||||||
|
| funcsLocal.c:58:9:58:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| funcsLocal.c:58:9:58:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| funcsLocal.c:58:9:58:10 | e1 | semmle.label | e1 |
|
||||||
|
#select
|
||||||
|
| funcsLocal.c:17:9:17:10 | i1 | funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:16:8:16:9 | i1 | fread |
|
||||||
|
| funcsLocal.c:27:9:27:10 | i3 | funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | i3 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:26:8:26:9 | i3 | fgets |
|
||||||
|
| funcsLocal.c:32:9:32:10 | i4 | funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:31:13:31:17 | call to fgets | fgets |
|
||||||
|
| funcsLocal.c:32:9:32:10 | i4 | funcsLocal.c:31:19:31:21 | i41 | funcsLocal.c:32:9:32:10 | i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:31:19:31:21 | i41 | fgets |
|
||||||
|
| funcsLocal.c:37:9:37:10 | i5 | funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | i5 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:36:7:36:8 | i5 | gets |
|
||||||
|
| funcsLocal.c:42:9:42:10 | i6 | funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:41:13:41:16 | call to gets | gets |
|
||||||
|
| funcsLocal.c:42:9:42:10 | i6 | funcsLocal.c:41:18:41:20 | i61 | funcsLocal.c:42:9:42:10 | i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:41:18:41:20 | i61 | gets |
|
||||||
|
| funcsLocal.c:58:9:58:10 | e1 | funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | e1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | funcsLocal.c:16:8:16:9 | i1 | fread |
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
edges
|
||||||
|
nodes
|
||||||
|
#select
|
||||||
|
|||||||
@@ -1,5 +1,65 @@
|
|||||||
| globalVars.c:27:9:27:12 | copy | This value may flow through $@, originating from $@, and is a formatting argument to printf(format). | globalVars.c:8:7:8:10 | copy | copy | globalVars.c:24:11:24:14 | argv | argv |
|
edges
|
||||||
| globalVars.c:30:15:30:18 | copy | This value may flow through $@, originating from $@, and is a formatting argument to printWrapper(str), which calls printf(format). | globalVars.c:8:7:8:10 | copy | copy | globalVars.c:24:11:24:14 | argv | argv |
|
| globalVars.c:8:7:8:10 | copy | globalVars.c:27:9:27:12 | copy |
|
||||||
| globalVars.c:38:9:38:13 | copy2 | This value may flow through $@, originating from $@, and is a formatting argument to printf(format). | globalVars.c:9:7:9:11 | copy2 | copy2 | globalVars.c:24:11:24:14 | argv | argv |
|
| globalVars.c:8:7:8:10 | copy | globalVars.c:27:9:27:12 | copy |
|
||||||
| globalVars.c:41:15:41:19 | copy2 | This value may flow through $@, originating from $@, and is a formatting argument to printWrapper(str), which calls printf(format). | globalVars.c:9:7:9:11 | copy2 | copy2 | globalVars.c:24:11:24:14 | argv | argv |
|
| globalVars.c:8:7:8:10 | copy | globalVars.c:27:9:27:12 | copy |
|
||||||
| globalVars.c:50:9:50:13 | copy2 | This value may flow through $@, originating from $@, and is a formatting argument to printf(format). | globalVars.c:9:7:9:11 | copy2 | copy2 | globalVars.c:24:11:24:14 | argv | argv |
|
| globalVars.c:8:7:8:10 | copy | globalVars.c:30:15:30:18 | copy |
|
||||||
|
| globalVars.c:8:7:8:10 | copy | globalVars.c:30:15:30:18 | copy |
|
||||||
|
| globalVars.c:8:7:8:10 | copy | globalVars.c:35:11:35:14 | copy |
|
||||||
|
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:38:9:38:13 | copy2 |
|
||||||
|
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:38:9:38:13 | copy2 |
|
||||||
|
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:38:9:38:13 | copy2 |
|
||||||
|
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:41:15:41:19 | copy2 |
|
||||||
|
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:41:15:41:19 | copy2 |
|
||||||
|
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:50:9:50:13 | copy2 |
|
||||||
|
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:50:9:50:13 | copy2 |
|
||||||
|
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:50:9:50:13 | copy2 |
|
||||||
|
| globalVars.c:11:22:11:25 | argv | globalVars.c:12:2:12:15 | Store |
|
||||||
|
| globalVars.c:12:2:12:15 | Store | globalVars.c:8:7:8:10 | copy |
|
||||||
|
| globalVars.c:15:21:15:23 | val | globalVars.c:16:2:16:12 | Store |
|
||||||
|
| globalVars.c:16:2:16:12 | Store | globalVars.c:9:7:9:11 | copy2 |
|
||||||
|
| globalVars.c:24:11:24:14 | argv | globalVars.c:11:22:11:25 | argv |
|
||||||
|
| globalVars.c:24:11:24:14 | argv | globalVars.c:11:22:11:25 | argv |
|
||||||
|
| globalVars.c:27:9:27:12 | copy | globalVars.c:27:9:27:12 | (const char *)... |
|
||||||
|
| globalVars.c:27:9:27:12 | copy | globalVars.c:27:9:27:12 | copy |
|
||||||
|
| globalVars.c:35:11:35:14 | copy | globalVars.c:15:21:15:23 | val |
|
||||||
|
| globalVars.c:38:9:38:13 | copy2 | globalVars.c:38:9:38:13 | (const char *)... |
|
||||||
|
| globalVars.c:38:9:38:13 | copy2 | globalVars.c:38:9:38:13 | copy2 |
|
||||||
|
| globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | (const char *)... |
|
||||||
|
| globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | copy2 |
|
||||||
|
nodes
|
||||||
|
| globalVars.c:8:7:8:10 | copy | semmle.label | copy |
|
||||||
|
| globalVars.c:9:7:9:11 | copy2 | semmle.label | copy2 |
|
||||||
|
| globalVars.c:11:22:11:25 | argv | semmle.label | argv |
|
||||||
|
| globalVars.c:12:2:12:15 | Store | semmle.label | Store |
|
||||||
|
| globalVars.c:15:21:15:23 | val | semmle.label | val |
|
||||||
|
| globalVars.c:16:2:16:12 | Store | semmle.label | Store |
|
||||||
|
| globalVars.c:24:11:24:14 | argv | semmle.label | argv |
|
||||||
|
| globalVars.c:24:11:24:14 | argv | semmle.label | argv |
|
||||||
|
| globalVars.c:27:9:27:12 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| globalVars.c:27:9:27:12 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| globalVars.c:27:9:27:12 | copy | semmle.label | copy |
|
||||||
|
| globalVars.c:27:9:27:12 | copy | semmle.label | copy |
|
||||||
|
| globalVars.c:27:9:27:12 | copy | semmle.label | copy |
|
||||||
|
| globalVars.c:30:15:30:18 | copy | semmle.label | copy |
|
||||||
|
| globalVars.c:30:15:30:18 | copy | semmle.label | copy |
|
||||||
|
| globalVars.c:30:15:30:18 | copy | semmle.label | copy |
|
||||||
|
| globalVars.c:35:11:35:14 | copy | semmle.label | copy |
|
||||||
|
| globalVars.c:38:9:38:13 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| globalVars.c:38:9:38:13 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| globalVars.c:38:9:38:13 | copy2 | semmle.label | copy2 |
|
||||||
|
| globalVars.c:38:9:38:13 | copy2 | semmle.label | copy2 |
|
||||||
|
| globalVars.c:38:9:38:13 | copy2 | semmle.label | copy2 |
|
||||||
|
| globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 |
|
||||||
|
| globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 |
|
||||||
|
| globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 |
|
||||||
|
| globalVars.c:50:9:50:13 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| globalVars.c:50:9:50:13 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 |
|
||||||
|
| globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 |
|
||||||
|
| globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 |
|
||||||
|
#select
|
||||||
|
| globalVars.c:27:9:27:12 | copy | globalVars.c:24:11:24:14 | argv | globalVars.c:27:9:27:12 | copy | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | globalVars.c:24:11:24:14 | argv | argv |
|
||||||
|
| globalVars.c:30:15:30:18 | copy | globalVars.c:24:11:24:14 | argv | globalVars.c:30:15:30:18 | copy | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(str), which calls printf(format) | globalVars.c:24:11:24:14 | argv | argv |
|
||||||
|
| globalVars.c:38:9:38:13 | copy2 | globalVars.c:24:11:24:14 | argv | globalVars.c:38:9:38:13 | copy2 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | globalVars.c:24:11:24:14 | argv | argv |
|
||||||
|
| globalVars.c:41:15:41:19 | copy2 | globalVars.c:24:11:24:14 | argv | globalVars.c:41:15:41:19 | copy2 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(str), which calls printf(format) | globalVars.c:24:11:24:14 | argv | argv |
|
||||||
|
| globalVars.c:50:9:50:13 | copy2 | globalVars.c:24:11:24:14 | argv | globalVars.c:50:9:50:13 | copy2 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | globalVars.c:24:11:24:14 | argv | argv |
|
||||||
|
|||||||
@@ -1,11 +1,157 @@
|
|||||||
| ifs.c:62:9:62:10 | c7 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:61:8:61:11 | argv | argv |
|
edges
|
||||||
| ifs.c:69:9:69:10 | c8 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:68:8:68:11 | argv | argv |
|
| ifs.c:61:8:61:11 | argv | ifs.c:62:9:62:10 | (const char *)... |
|
||||||
| ifs.c:75:9:75:10 | i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:74:8:74:11 | argv | argv |
|
| ifs.c:61:8:61:11 | argv | ifs.c:62:9:62:10 | (const char *)... |
|
||||||
| ifs.c:81:9:81:10 | i2 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:80:8:80:11 | argv | argv |
|
| ifs.c:61:8:61:11 | argv | ifs.c:62:9:62:10 | c7 |
|
||||||
| ifs.c:87:9:87:10 | i3 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:86:8:86:11 | argv | argv |
|
| ifs.c:61:8:61:11 | argv | ifs.c:62:9:62:10 | c7 |
|
||||||
| ifs.c:93:9:93:10 | i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:92:8:92:11 | argv | argv |
|
| ifs.c:61:8:61:11 | argv | ifs.c:62:9:62:10 | c7 |
|
||||||
| ifs.c:99:9:99:10 | i5 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:98:8:98:11 | argv | argv |
|
| ifs.c:61:8:61:11 | argv | ifs.c:62:9:62:10 | c7 |
|
||||||
| ifs.c:106:9:106:10 | i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:105:8:105:11 | argv | argv |
|
| ifs.c:68:8:68:11 | argv | ifs.c:69:9:69:10 | (const char *)... |
|
||||||
| ifs.c:112:9:112:10 | i7 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:111:8:111:11 | argv | argv |
|
| ifs.c:68:8:68:11 | argv | ifs.c:69:9:69:10 | (const char *)... |
|
||||||
| ifs.c:118:9:118:10 | i8 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:117:8:117:11 | argv | argv |
|
| ifs.c:68:8:68:11 | argv | ifs.c:69:9:69:10 | c8 |
|
||||||
| ifs.c:124:9:124:10 | i9 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:123:8:123:11 | argv | argv |
|
| ifs.c:68:8:68:11 | argv | ifs.c:69:9:69:10 | c8 |
|
||||||
|
| ifs.c:68:8:68:11 | argv | ifs.c:69:9:69:10 | c8 |
|
||||||
|
| ifs.c:68:8:68:11 | argv | ifs.c:69:9:69:10 | c8 |
|
||||||
|
| ifs.c:74:8:74:11 | argv | ifs.c:75:9:75:10 | (const char *)... |
|
||||||
|
| ifs.c:74:8:74:11 | argv | ifs.c:75:9:75:10 | (const char *)... |
|
||||||
|
| ifs.c:74:8:74:11 | argv | ifs.c:75:9:75:10 | i1 |
|
||||||
|
| ifs.c:74:8:74:11 | argv | ifs.c:75:9:75:10 | i1 |
|
||||||
|
| ifs.c:74:8:74:11 | argv | ifs.c:75:9:75:10 | i1 |
|
||||||
|
| ifs.c:74:8:74:11 | argv | ifs.c:75:9:75:10 | i1 |
|
||||||
|
| ifs.c:80:8:80:11 | argv | ifs.c:81:9:81:10 | (const char *)... |
|
||||||
|
| ifs.c:80:8:80:11 | argv | ifs.c:81:9:81:10 | (const char *)... |
|
||||||
|
| ifs.c:80:8:80:11 | argv | ifs.c:81:9:81:10 | i2 |
|
||||||
|
| ifs.c:80:8:80:11 | argv | ifs.c:81:9:81:10 | i2 |
|
||||||
|
| ifs.c:80:8:80:11 | argv | ifs.c:81:9:81:10 | i2 |
|
||||||
|
| ifs.c:80:8:80:11 | argv | ifs.c:81:9:81:10 | i2 |
|
||||||
|
| ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | (const char *)... |
|
||||||
|
| ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | (const char *)... |
|
||||||
|
| ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | i3 |
|
||||||
|
| ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | i3 |
|
||||||
|
| ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | i3 |
|
||||||
|
| ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | i3 |
|
||||||
|
| ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | (const char *)... |
|
||||||
|
| ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | (const char *)... |
|
||||||
|
| ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 |
|
||||||
|
| ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 |
|
||||||
|
| ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 |
|
||||||
|
| ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 |
|
||||||
|
| ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | (const char *)... |
|
||||||
|
| ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | (const char *)... |
|
||||||
|
| ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 |
|
||||||
|
| ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 |
|
||||||
|
| ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 |
|
||||||
|
| ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 |
|
||||||
|
| ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | (const char *)... |
|
||||||
|
| ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | (const char *)... |
|
||||||
|
| ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | i6 |
|
||||||
|
| ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | i6 |
|
||||||
|
| ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | i6 |
|
||||||
|
| ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | i6 |
|
||||||
|
| ifs.c:111:8:111:11 | argv | ifs.c:112:9:112:10 | (const char *)... |
|
||||||
|
| ifs.c:111:8:111:11 | argv | ifs.c:112:9:112:10 | (const char *)... |
|
||||||
|
| ifs.c:111:8:111:11 | argv | ifs.c:112:9:112:10 | i7 |
|
||||||
|
| ifs.c:111:8:111:11 | argv | ifs.c:112:9:112:10 | i7 |
|
||||||
|
| ifs.c:111:8:111:11 | argv | ifs.c:112:9:112:10 | i7 |
|
||||||
|
| ifs.c:111:8:111:11 | argv | ifs.c:112:9:112:10 | i7 |
|
||||||
|
| ifs.c:117:8:117:11 | argv | ifs.c:118:9:118:10 | (const char *)... |
|
||||||
|
| ifs.c:117:8:117:11 | argv | ifs.c:118:9:118:10 | (const char *)... |
|
||||||
|
| ifs.c:117:8:117:11 | argv | ifs.c:118:9:118:10 | i8 |
|
||||||
|
| ifs.c:117:8:117:11 | argv | ifs.c:118:9:118:10 | i8 |
|
||||||
|
| ifs.c:117:8:117:11 | argv | ifs.c:118:9:118:10 | i8 |
|
||||||
|
| ifs.c:117:8:117:11 | argv | ifs.c:118:9:118:10 | i8 |
|
||||||
|
| ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | (const char *)... |
|
||||||
|
| ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | (const char *)... |
|
||||||
|
| ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 |
|
||||||
|
| ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 |
|
||||||
|
| ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 |
|
||||||
|
| ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 |
|
||||||
|
nodes
|
||||||
|
| ifs.c:61:8:61:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:61:8:61:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:62:9:62:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:62:9:62:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:62:9:62:10 | c7 | semmle.label | c7 |
|
||||||
|
| ifs.c:62:9:62:10 | c7 | semmle.label | c7 |
|
||||||
|
| ifs.c:62:9:62:10 | c7 | semmle.label | c7 |
|
||||||
|
| ifs.c:68:8:68:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:68:8:68:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:69:9:69:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:69:9:69:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:69:9:69:10 | c8 | semmle.label | c8 |
|
||||||
|
| ifs.c:69:9:69:10 | c8 | semmle.label | c8 |
|
||||||
|
| ifs.c:69:9:69:10 | c8 | semmle.label | c8 |
|
||||||
|
| ifs.c:74:8:74:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:74:8:74:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:75:9:75:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:75:9:75:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:75:9:75:10 | i1 | semmle.label | i1 |
|
||||||
|
| ifs.c:75:9:75:10 | i1 | semmle.label | i1 |
|
||||||
|
| ifs.c:75:9:75:10 | i1 | semmle.label | i1 |
|
||||||
|
| ifs.c:80:8:80:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:80:8:80:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:81:9:81:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:81:9:81:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:81:9:81:10 | i2 | semmle.label | i2 |
|
||||||
|
| ifs.c:81:9:81:10 | i2 | semmle.label | i2 |
|
||||||
|
| ifs.c:81:9:81:10 | i2 | semmle.label | i2 |
|
||||||
|
| ifs.c:86:8:86:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:86:8:86:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:87:9:87:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:87:9:87:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:87:9:87:10 | i3 | semmle.label | i3 |
|
||||||
|
| ifs.c:87:9:87:10 | i3 | semmle.label | i3 |
|
||||||
|
| ifs.c:87:9:87:10 | i3 | semmle.label | i3 |
|
||||||
|
| ifs.c:92:8:92:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:92:8:92:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:93:9:93:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:93:9:93:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:93:9:93:10 | i4 | semmle.label | i4 |
|
||||||
|
| ifs.c:93:9:93:10 | i4 | semmle.label | i4 |
|
||||||
|
| ifs.c:93:9:93:10 | i4 | semmle.label | i4 |
|
||||||
|
| ifs.c:98:8:98:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:98:8:98:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:99:9:99:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:99:9:99:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:99:9:99:10 | i5 | semmle.label | i5 |
|
||||||
|
| ifs.c:99:9:99:10 | i5 | semmle.label | i5 |
|
||||||
|
| ifs.c:99:9:99:10 | i5 | semmle.label | i5 |
|
||||||
|
| ifs.c:105:8:105:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:105:8:105:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:106:9:106:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:106:9:106:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:106:9:106:10 | i6 | semmle.label | i6 |
|
||||||
|
| ifs.c:106:9:106:10 | i6 | semmle.label | i6 |
|
||||||
|
| ifs.c:106:9:106:10 | i6 | semmle.label | i6 |
|
||||||
|
| ifs.c:111:8:111:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:111:8:111:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:112:9:112:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:112:9:112:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:112:9:112:10 | i7 | semmle.label | i7 |
|
||||||
|
| ifs.c:112:9:112:10 | i7 | semmle.label | i7 |
|
||||||
|
| ifs.c:112:9:112:10 | i7 | semmle.label | i7 |
|
||||||
|
| ifs.c:117:8:117:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:117:8:117:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:118:9:118:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:118:9:118:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:118:9:118:10 | i8 | semmle.label | i8 |
|
||||||
|
| ifs.c:118:9:118:10 | i8 | semmle.label | i8 |
|
||||||
|
| ifs.c:118:9:118:10 | i8 | semmle.label | i8 |
|
||||||
|
| ifs.c:123:8:123:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:123:8:123:11 | argv | semmle.label | argv |
|
||||||
|
| ifs.c:124:9:124:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:124:9:124:10 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| ifs.c:124:9:124:10 | i9 | semmle.label | i9 |
|
||||||
|
| ifs.c:124:9:124:10 | i9 | semmle.label | i9 |
|
||||||
|
| ifs.c:124:9:124:10 | i9 | semmle.label | i9 |
|
||||||
|
#select
|
||||||
|
| ifs.c:62:9:62:10 | c7 | ifs.c:61:8:61:11 | argv | ifs.c:62:9:62:10 | c7 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:61:8:61:11 | argv | argv |
|
||||||
|
| ifs.c:69:9:69:10 | c8 | ifs.c:68:8:68:11 | argv | ifs.c:69:9:69:10 | c8 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:68:8:68:11 | argv | argv |
|
||||||
|
| ifs.c:75:9:75:10 | i1 | ifs.c:74:8:74:11 | argv | ifs.c:75:9:75:10 | i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:74:8:74:11 | argv | argv |
|
||||||
|
| ifs.c:81:9:81:10 | i2 | ifs.c:80:8:80:11 | argv | ifs.c:81:9:81:10 | i2 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:80:8:80:11 | argv | argv |
|
||||||
|
| ifs.c:87:9:87:10 | i3 | ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | i3 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:86:8:86:11 | argv | argv |
|
||||||
|
| ifs.c:93:9:93:10 | i4 | ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:92:8:92:11 | argv | argv |
|
||||||
|
| ifs.c:99:9:99:10 | i5 | ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:98:8:98:11 | argv | argv |
|
||||||
|
| ifs.c:106:9:106:10 | i6 | ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:105:8:105:11 | argv | argv |
|
||||||
|
| ifs.c:112:9:112:10 | i7 | ifs.c:111:8:111:11 | argv | ifs.c:112:9:112:10 | i7 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:111:8:111:11 | argv | argv |
|
||||||
|
| ifs.c:118:9:118:10 | i8 | ifs.c:117:8:117:11 | argv | ifs.c:118:9:118:10 | i8 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:117:8:117:11 | argv | argv |
|
||||||
|
| ifs.c:124:9:124:10 | i9 | ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format) | ifs.c:123:8:123:11 | argv | argv |
|
||||||
|
|||||||
@@ -1,9 +1,151 @@
|
|||||||
| test.cpp:42:31:42:36 | call to malloc | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
edges
|
||||||
| test.cpp:43:31:43:36 | call to malloc | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
| test.cpp:39:21:39:24 | argv | test.cpp:42:38:42:44 | (size_t)... |
|
||||||
| test.cpp:43:38:43:63 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
| test.cpp:39:21:39:24 | argv | test.cpp:42:38:42:44 | (size_t)... |
|
||||||
| test.cpp:45:31:45:36 | call to malloc | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
| test.cpp:39:21:39:24 | argv | test.cpp:42:38:42:44 | tainted |
|
||||||
| test.cpp:48:25:48:30 | call to malloc | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
| test.cpp:39:21:39:24 | argv | test.cpp:42:38:42:44 | tainted |
|
||||||
| test.cpp:49:17:49:30 | new[] | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
| test.cpp:39:21:39:24 | argv | test.cpp:42:38:42:44 | tainted |
|
||||||
| test.cpp:52:21:52:27 | call to realloc | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
| test.cpp:39:21:39:24 | argv | test.cpp:42:38:42:44 | tainted |
|
||||||
| test.cpp:52:35:52:60 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
| test.cpp:39:21:39:24 | argv | test.cpp:43:38:43:44 | (unsigned long)... |
|
||||||
| test.cpp:127:17:127:22 | call to malloc | This allocation size is derived from $@ and might overflow | test.cpp:123:25:123:30 | call to getenv | user input (getenv) |
|
| test.cpp:39:21:39:24 | argv | test.cpp:43:38:43:44 | (unsigned long)... |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:43:38:43:44 | tainted |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:43:38:43:44 | tainted |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:43:38:43:44 | tainted |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:43:38:43:44 | tainted |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:43:38:43:63 | ... * ... |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:43:38:43:63 | ... * ... |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:43:38:43:63 | ... * ... |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:43:38:43:63 | ... * ... |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:45:38:45:63 | ... + ... |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:45:38:45:63 | ... + ... |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:45:38:45:63 | ... + ... |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:45:38:45:63 | ... + ... |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:48:32:48:35 | (size_t)... |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:48:32:48:35 | (size_t)... |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:48:32:48:35 | size |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:48:32:48:35 | size |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:48:32:48:35 | size |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:48:32:48:35 | size |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:49:26:49:29 | size |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:49:26:49:29 | size |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:49:26:49:29 | size |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:49:26:49:29 | size |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:52:35:52:60 | ... * ... |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:52:35:52:60 | ... * ... |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:52:35:52:60 | ... * ... |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:52:35:52:60 | ... * ... |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:52:54:52:60 | (unsigned long)... |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:52:54:52:60 | (unsigned long)... |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:52:54:52:60 | tainted |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:52:54:52:60 | tainted |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:52:54:52:60 | tainted |
|
||||||
|
| test.cpp:39:21:39:24 | argv | test.cpp:52:54:52:60 | tainted |
|
||||||
|
| test.cpp:123:18:123:23 | call to getenv | test.cpp:127:24:127:27 | (unsigned long)... |
|
||||||
|
| test.cpp:123:18:123:23 | call to getenv | test.cpp:127:24:127:27 | size |
|
||||||
|
| test.cpp:123:18:123:23 | call to getenv | test.cpp:127:24:127:27 | size |
|
||||||
|
| test.cpp:123:18:123:23 | call to getenv | test.cpp:127:24:127:41 | ... * ... |
|
||||||
|
| test.cpp:123:18:123:23 | call to getenv | test.cpp:127:24:127:41 | ... * ... |
|
||||||
|
| test.cpp:123:18:123:31 | (const char *)... | test.cpp:127:24:127:27 | (unsigned long)... |
|
||||||
|
| test.cpp:123:18:123:31 | (const char *)... | test.cpp:127:24:127:27 | size |
|
||||||
|
| test.cpp:123:18:123:31 | (const char *)... | test.cpp:127:24:127:27 | size |
|
||||||
|
| test.cpp:123:18:123:31 | (const char *)... | test.cpp:127:24:127:41 | ... * ... |
|
||||||
|
| test.cpp:123:18:123:31 | (const char *)... | test.cpp:127:24:127:41 | ... * ... |
|
||||||
|
| test.cpp:132:19:132:24 | call to getenv | test.cpp:134:10:134:13 | (unsigned long)... |
|
||||||
|
| test.cpp:132:19:132:24 | call to getenv | test.cpp:134:10:134:13 | size |
|
||||||
|
| test.cpp:132:19:132:24 | call to getenv | test.cpp:134:10:134:13 | size |
|
||||||
|
| test.cpp:132:19:132:24 | call to getenv | test.cpp:134:10:134:27 | ... * ... |
|
||||||
|
| test.cpp:132:19:132:24 | call to getenv | test.cpp:134:10:134:27 | ... * ... |
|
||||||
|
| test.cpp:132:19:132:32 | (const char *)... | test.cpp:134:10:134:13 | (unsigned long)... |
|
||||||
|
| test.cpp:132:19:132:32 | (const char *)... | test.cpp:134:10:134:13 | size |
|
||||||
|
| test.cpp:132:19:132:32 | (const char *)... | test.cpp:134:10:134:13 | size |
|
||||||
|
| test.cpp:132:19:132:32 | (const char *)... | test.cpp:134:10:134:27 | ... * ... |
|
||||||
|
| test.cpp:132:19:132:32 | (const char *)... | test.cpp:134:10:134:27 | ... * ... |
|
||||||
|
| test.cpp:138:19:138:24 | call to getenv | test.cpp:142:11:142:14 | (unsigned long)... |
|
||||||
|
| test.cpp:138:19:138:24 | call to getenv | test.cpp:142:11:142:14 | size |
|
||||||
|
| test.cpp:138:19:138:24 | call to getenv | test.cpp:142:11:142:14 | size |
|
||||||
|
| test.cpp:138:19:138:24 | call to getenv | test.cpp:142:11:142:28 | ... * ... |
|
||||||
|
| test.cpp:138:19:138:24 | call to getenv | test.cpp:142:11:142:28 | ... * ... |
|
||||||
|
| test.cpp:138:19:138:32 | (const char *)... | test.cpp:142:11:142:14 | (unsigned long)... |
|
||||||
|
| test.cpp:138:19:138:32 | (const char *)... | test.cpp:142:11:142:14 | size |
|
||||||
|
| test.cpp:138:19:138:32 | (const char *)... | test.cpp:142:11:142:14 | size |
|
||||||
|
| test.cpp:138:19:138:32 | (const char *)... | test.cpp:142:11:142:28 | ... * ... |
|
||||||
|
| test.cpp:138:19:138:32 | (const char *)... | test.cpp:142:11:142:28 | ... * ... |
|
||||||
|
nodes
|
||||||
|
| test.cpp:39:21:39:24 | argv | semmle.label | argv |
|
||||||
|
| test.cpp:39:21:39:24 | argv | semmle.label | argv |
|
||||||
|
| test.cpp:42:38:42:44 | (size_t)... | semmle.label | (size_t)... |
|
||||||
|
| test.cpp:42:38:42:44 | (size_t)... | semmle.label | (size_t)... |
|
||||||
|
| test.cpp:42:38:42:44 | tainted | semmle.label | tainted |
|
||||||
|
| test.cpp:42:38:42:44 | tainted | semmle.label | tainted |
|
||||||
|
| test.cpp:42:38:42:44 | tainted | semmle.label | tainted |
|
||||||
|
| test.cpp:43:38:43:44 | (unsigned long)... | semmle.label | (unsigned long)... |
|
||||||
|
| test.cpp:43:38:43:44 | (unsigned long)... | semmle.label | (unsigned long)... |
|
||||||
|
| test.cpp:43:38:43:44 | tainted | semmle.label | tainted |
|
||||||
|
| test.cpp:43:38:43:44 | tainted | semmle.label | tainted |
|
||||||
|
| test.cpp:43:38:43:44 | tainted | semmle.label | tainted |
|
||||||
|
| test.cpp:43:38:43:63 | ... * ... | semmle.label | ... * ... |
|
||||||
|
| test.cpp:43:38:43:63 | ... * ... | semmle.label | ... * ... |
|
||||||
|
| test.cpp:43:38:43:63 | ... * ... | semmle.label | ... * ... |
|
||||||
|
| test.cpp:45:38:45:63 | ... + ... | semmle.label | ... + ... |
|
||||||
|
| test.cpp:45:38:45:63 | ... + ... | semmle.label | ... + ... |
|
||||||
|
| test.cpp:45:38:45:63 | ... + ... | semmle.label | ... + ... |
|
||||||
|
| test.cpp:48:32:48:35 | (size_t)... | semmle.label | (size_t)... |
|
||||||
|
| test.cpp:48:32:48:35 | (size_t)... | semmle.label | (size_t)... |
|
||||||
|
| test.cpp:48:32:48:35 | size | semmle.label | size |
|
||||||
|
| test.cpp:48:32:48:35 | size | semmle.label | size |
|
||||||
|
| test.cpp:48:32:48:35 | size | semmle.label | size |
|
||||||
|
| test.cpp:49:26:49:29 | size | semmle.label | size |
|
||||||
|
| test.cpp:49:26:49:29 | size | semmle.label | size |
|
||||||
|
| test.cpp:49:26:49:29 | size | semmle.label | size |
|
||||||
|
| test.cpp:52:35:52:60 | ... * ... | semmle.label | ... * ... |
|
||||||
|
| test.cpp:52:35:52:60 | ... * ... | semmle.label | ... * ... |
|
||||||
|
| test.cpp:52:35:52:60 | ... * ... | semmle.label | ... * ... |
|
||||||
|
| test.cpp:52:54:52:60 | (unsigned long)... | semmle.label | (unsigned long)... |
|
||||||
|
| test.cpp:52:54:52:60 | (unsigned long)... | semmle.label | (unsigned long)... |
|
||||||
|
| test.cpp:52:54:52:60 | tainted | semmle.label | tainted |
|
||||||
|
| test.cpp:52:54:52:60 | tainted | semmle.label | tainted |
|
||||||
|
| test.cpp:52:54:52:60 | tainted | semmle.label | tainted |
|
||||||
|
| test.cpp:123:18:123:23 | call to getenv | semmle.label | call to getenv |
|
||||||
|
| test.cpp:123:18:123:31 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| test.cpp:127:24:127:27 | (unsigned long)... | semmle.label | (unsigned long)... |
|
||||||
|
| test.cpp:127:24:127:27 | (unsigned long)... | semmle.label | (unsigned long)... |
|
||||||
|
| test.cpp:127:24:127:27 | size | semmle.label | size |
|
||||||
|
| test.cpp:127:24:127:27 | size | semmle.label | size |
|
||||||
|
| test.cpp:127:24:127:27 | size | semmle.label | size |
|
||||||
|
| test.cpp:127:24:127:41 | ... * ... | semmle.label | ... * ... |
|
||||||
|
| test.cpp:127:24:127:41 | ... * ... | semmle.label | ... * ... |
|
||||||
|
| test.cpp:127:24:127:41 | ... * ... | semmle.label | ... * ... |
|
||||||
|
| test.cpp:132:19:132:24 | call to getenv | semmle.label | call to getenv |
|
||||||
|
| test.cpp:132:19:132:32 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| test.cpp:134:10:134:13 | (unsigned long)... | semmle.label | (unsigned long)... |
|
||||||
|
| test.cpp:134:10:134:13 | (unsigned long)... | semmle.label | (unsigned long)... |
|
||||||
|
| test.cpp:134:10:134:13 | size | semmle.label | size |
|
||||||
|
| test.cpp:134:10:134:13 | size | semmle.label | size |
|
||||||
|
| test.cpp:134:10:134:13 | size | semmle.label | size |
|
||||||
|
| test.cpp:134:10:134:27 | ... * ... | semmle.label | ... * ... |
|
||||||
|
| test.cpp:134:10:134:27 | ... * ... | semmle.label | ... * ... |
|
||||||
|
| test.cpp:134:10:134:27 | ... * ... | semmle.label | ... * ... |
|
||||||
|
| test.cpp:138:19:138:24 | call to getenv | semmle.label | call to getenv |
|
||||||
|
| test.cpp:138:19:138:32 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| test.cpp:142:11:142:14 | (unsigned long)... | semmle.label | (unsigned long)... |
|
||||||
|
| test.cpp:142:11:142:14 | (unsigned long)... | semmle.label | (unsigned long)... |
|
||||||
|
| test.cpp:142:11:142:14 | size | semmle.label | size |
|
||||||
|
| test.cpp:142:11:142:14 | size | semmle.label | size |
|
||||||
|
| test.cpp:142:11:142:14 | size | semmle.label | size |
|
||||||
|
| test.cpp:142:11:142:28 | ... * ... | semmle.label | ... * ... |
|
||||||
|
| test.cpp:142:11:142:28 | ... * ... | semmle.label | ... * ... |
|
||||||
|
| test.cpp:142:11:142:28 | ... * ... | semmle.label | ... * ... |
|
||||||
|
#select
|
||||||
|
| test.cpp:42:31:42:36 | call to malloc | test.cpp:39:21:39:24 | argv | test.cpp:42:38:42:44 | tainted | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
||||||
|
| test.cpp:43:31:43:36 | call to malloc | test.cpp:39:21:39:24 | argv | test.cpp:43:38:43:63 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
||||||
|
| test.cpp:43:38:43:63 | ... * ... | test.cpp:39:21:39:24 | argv | test.cpp:43:38:43:44 | tainted | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
||||||
|
| test.cpp:45:31:45:36 | call to malloc | test.cpp:39:21:39:24 | argv | test.cpp:45:38:45:63 | ... + ... | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
||||||
|
| test.cpp:48:25:48:30 | call to malloc | test.cpp:39:21:39:24 | argv | test.cpp:48:32:48:35 | size | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
||||||
|
| test.cpp:49:17:49:30 | new[] | test.cpp:39:21:39:24 | argv | test.cpp:49:26:49:29 | size | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
||||||
|
| test.cpp:52:21:52:27 | call to realloc | test.cpp:39:21:39:24 | argv | test.cpp:52:35:52:60 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
||||||
|
| test.cpp:52:35:52:60 | ... * ... | test.cpp:39:21:39:24 | argv | test.cpp:52:54:52:60 | tainted | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
||||||
|
| test.cpp:127:17:127:22 | call to malloc | test.cpp:123:18:123:23 | call to getenv | test.cpp:127:24:127:41 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:123:18:123:23 | call to getenv | user input (getenv) |
|
||||||
|
| test.cpp:127:24:127:41 | ... * ... | test.cpp:123:18:123:23 | call to getenv | test.cpp:127:24:127:27 | size | This allocation size is derived from $@ and might overflow | test.cpp:123:18:123:23 | call to getenv | user input (getenv) |
|
||||||
|
| test.cpp:134:3:134:8 | call to malloc | test.cpp:132:19:132:24 | call to getenv | test.cpp:134:10:134:27 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:132:19:132:24 | call to getenv | user input (getenv) |
|
||||||
|
| test.cpp:134:10:134:27 | ... * ... | test.cpp:132:19:132:24 | call to getenv | test.cpp:134:10:134:13 | size | This allocation size is derived from $@ and might overflow | test.cpp:132:19:132:24 | call to getenv | user input (getenv) |
|
||||||
|
| test.cpp:142:4:142:9 | call to malloc | test.cpp:138:19:138:24 | call to getenv | test.cpp:142:11:142:28 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:138:19:138:24 | call to getenv | user input (getenv) |
|
||||||
|
| test.cpp:142:11:142:28 | ... * ... | test.cpp:138:19:138:24 | call to getenv | test.cpp:142:11:142:14 | size | This allocation size is derived from $@ and might overflow | test.cpp:138:19:138:24 | call to getenv | user input (getenv) |
|
||||||
|
|||||||
@@ -39,10 +39,10 @@ int main(int argc, char **argv) {
|
|||||||
int tainted = atoi(argv[1]);
|
int tainted = atoi(argv[1]);
|
||||||
|
|
||||||
MyStruct *arr1 = (MyStruct *)malloc(sizeof(MyStruct)); // GOOD
|
MyStruct *arr1 = (MyStruct *)malloc(sizeof(MyStruct)); // GOOD
|
||||||
MyStruct *arr2 = (MyStruct *)malloc(tainted); // BAD
|
MyStruct *arr2 = (MyStruct *)malloc(tainted); // DUBIOUS (not multiplied by anything)
|
||||||
MyStruct *arr3 = (MyStruct *)malloc(tainted * sizeof(MyStruct)); // BAD
|
MyStruct *arr3 = (MyStruct *)malloc(tainted * sizeof(MyStruct)); // BAD
|
||||||
MyStruct *arr4 = (MyStruct *)malloc(getTainted() * sizeof(MyStruct)); // BAD [NOT DETECTED]
|
MyStruct *arr4 = (MyStruct *)malloc(getTainted() * sizeof(MyStruct)); // BAD [NOT DETECTED]
|
||||||
MyStruct *arr5 = (MyStruct *)malloc(sizeof(MyStruct) + tainted); // BAD [NOT DETECTED]
|
MyStruct *arr5 = (MyStruct *)malloc(sizeof(MyStruct) + tainted); // DUBIOUS (not multiplied by anything)
|
||||||
|
|
||||||
int size = tainted * 8;
|
int size = tainted * 8;
|
||||||
char *chars1 = (char *)malloc(size); // BAD
|
char *chars1 = (char *)malloc(size); // BAD
|
||||||
@@ -52,7 +52,7 @@ int main(int argc, char **argv) {
|
|||||||
arr1 = (MyStruct *)realloc(arr1, sizeof(MyStruct) * tainted); // BAD
|
arr1 = (MyStruct *)realloc(arr1, sizeof(MyStruct) * tainted); // BAD
|
||||||
|
|
||||||
size = 8;
|
size = 8;
|
||||||
chars3 = new char[size]; // GOOD [FALSE POSITIVE]
|
chars3 = new char[size]; // GOOD
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -120,9 +120,73 @@ int bounded(int x, int limit) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void open_file_bounded () {
|
void open_file_bounded () {
|
||||||
int size = size = atoi(getenv("USER"));
|
int size = atoi(getenv("USER"));
|
||||||
int bounded_size = bounded(size, MAX_SIZE);
|
int bounded_size = bounded(size, MAX_SIZE);
|
||||||
|
|
||||||
int* a = (int*)malloc(bounded_size); // GOOD
|
int* a = (int*)malloc(bounded_size * sizeof(int)); // GOOD
|
||||||
int* b = (int*)malloc(size); // BAD
|
int* b = (int*)malloc(size * sizeof(int)); // BAD
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void more_bounded_tests() {
|
||||||
|
{
|
||||||
|
int size = atoi(getenv("USER"));
|
||||||
|
|
||||||
|
malloc(size * sizeof(int)); // BAD
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int size = atoi(getenv("USER"));
|
||||||
|
|
||||||
|
if (size > 0)
|
||||||
|
{
|
||||||
|
malloc(size * sizeof(int)); // BAD
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int size = atoi(getenv("USER"));
|
||||||
|
|
||||||
|
if (size < 100)
|
||||||
|
{
|
||||||
|
malloc(size * sizeof(int)); // BAD [NOT DETECTED]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int size = atoi(getenv("USER"));
|
||||||
|
|
||||||
|
if ((size > 0) && (size < 100))
|
||||||
|
{
|
||||||
|
malloc(size * sizeof(int)); // GOOD
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int size = atoi(getenv("USER"));
|
||||||
|
|
||||||
|
if ((100 > size) && (0 < size))
|
||||||
|
{
|
||||||
|
malloc(size * sizeof(int)); // GOOD
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int size = atoi(getenv("USER"));
|
||||||
|
|
||||||
|
malloc(size * sizeof(int)); // BAD [NOT DETECTED]
|
||||||
|
|
||||||
|
if ((size > 0) && (size < 100))
|
||||||
|
{
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int size = atoi(getenv("USER"));
|
||||||
|
|
||||||
|
if (size > 100)
|
||||||
|
{
|
||||||
|
malloc(size * sizeof(int)); // BAD [NOT DETECTED]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,11 +1,138 @@
|
|||||||
| test.c:21:17:21:17 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:18:13:18:16 | call to rand | Uncontrolled value |
|
edges
|
||||||
| test.c:35:5:35:5 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:34:13:34:18 | call to rand | Uncontrolled value |
|
| test.c:18:13:18:16 | call to rand | test.c:21:17:21:17 | r |
|
||||||
| test.c:40:5:40:5 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:39:13:39:21 | ... % ... | Uncontrolled value |
|
| test.c:18:13:18:16 | call to rand | test.c:21:17:21:17 | r |
|
||||||
| test.c:45:5:45:5 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:44:13:44:16 | call to rand | Uncontrolled value |
|
| test.c:18:13:18:16 | call to rand | test.c:21:17:21:17 | r |
|
||||||
| test.c:56:5:56:5 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:54:13:54:16 | call to rand | Uncontrolled value |
|
| test.c:18:13:18:16 | call to rand | test.c:21:17:21:17 | r |
|
||||||
| test.c:67:5:67:5 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:66:13:66:16 | call to rand | Uncontrolled value |
|
| test.c:34:13:34:18 | call to rand | test.c:35:5:35:5 | r |
|
||||||
| test.c:77:9:77:9 | r | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.c:75:13:75:19 | ... ^ ... | Uncontrolled value |
|
| test.c:34:13:34:18 | call to rand | test.c:35:5:35:5 | r |
|
||||||
| test.c:100:5:100:5 | r | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.c:99:14:99:19 | call to rand | Uncontrolled value |
|
| test.c:34:13:34:18 | call to rand | test.c:35:5:35:5 | r |
|
||||||
| test.cpp:25:7:25:7 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:8:9:8:12 | call to rand | Uncontrolled value |
|
| test.c:34:13:34:18 | call to rand | test.c:35:5:35:5 | r |
|
||||||
| test.cpp:31:7:31:7 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:13:10:13:13 | call to rand | Uncontrolled value |
|
| test.c:39:13:39:21 | ... % ... | test.c:40:5:40:5 | r |
|
||||||
| test.cpp:37:7:37:7 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:18:9:18:12 | call to rand | Uncontrolled value |
|
| test.c:39:13:39:21 | ... % ... | test.c:40:5:40:5 | r |
|
||||||
|
| test.c:39:13:39:21 | ... % ... | test.c:40:5:40:5 | r |
|
||||||
|
| test.c:39:13:39:21 | ... % ... | test.c:40:5:40:5 | r |
|
||||||
|
| test.c:44:13:44:16 | call to rand | test.c:45:5:45:5 | r |
|
||||||
|
| test.c:44:13:44:16 | call to rand | test.c:45:5:45:5 | r |
|
||||||
|
| test.c:44:13:44:16 | call to rand | test.c:45:5:45:5 | r |
|
||||||
|
| test.c:44:13:44:16 | call to rand | test.c:45:5:45:5 | r |
|
||||||
|
| test.c:54:13:54:16 | call to rand | test.c:56:5:56:5 | r |
|
||||||
|
| test.c:54:13:54:16 | call to rand | test.c:56:5:56:5 | r |
|
||||||
|
| test.c:54:13:54:16 | call to rand | test.c:56:5:56:5 | r |
|
||||||
|
| test.c:54:13:54:16 | call to rand | test.c:56:5:56:5 | r |
|
||||||
|
| test.c:60:13:60:16 | call to rand | test.c:61:5:61:5 | r |
|
||||||
|
| test.c:60:13:60:16 | call to rand | test.c:61:5:61:5 | r |
|
||||||
|
| test.c:60:13:60:16 | call to rand | test.c:61:5:61:5 | r |
|
||||||
|
| test.c:60:13:60:16 | call to rand | test.c:61:5:61:5 | r |
|
||||||
|
| test.c:60:13:60:16 | call to rand | test.c:62:5:62:5 | r |
|
||||||
|
| test.c:60:13:60:16 | call to rand | test.c:62:5:62:5 | r |
|
||||||
|
| test.c:60:13:60:16 | call to rand | test.c:62:5:62:5 | r |
|
||||||
|
| test.c:60:13:60:16 | call to rand | test.c:62:5:62:5 | r |
|
||||||
|
| test.c:66:13:66:16 | call to rand | test.c:67:5:67:5 | r |
|
||||||
|
| test.c:66:13:66:16 | call to rand | test.c:67:5:67:5 | r |
|
||||||
|
| test.c:66:13:66:16 | call to rand | test.c:67:5:67:5 | r |
|
||||||
|
| test.c:66:13:66:16 | call to rand | test.c:67:5:67:5 | r |
|
||||||
|
| test.c:75:13:75:19 | ... ^ ... | test.c:77:9:77:9 | r |
|
||||||
|
| test.c:75:13:75:19 | ... ^ ... | test.c:77:9:77:9 | r |
|
||||||
|
| test.c:75:13:75:19 | ... ^ ... | test.c:77:9:77:9 | r |
|
||||||
|
| test.c:75:13:75:19 | ... ^ ... | test.c:77:9:77:9 | r |
|
||||||
|
| test.c:99:14:99:19 | call to rand | test.c:100:5:100:5 | r |
|
||||||
|
| test.c:99:14:99:19 | call to rand | test.c:100:5:100:5 | r |
|
||||||
|
| test.c:99:14:99:19 | call to rand | test.c:100:5:100:5 | r |
|
||||||
|
| test.c:99:14:99:19 | call to rand | test.c:100:5:100:5 | r |
|
||||||
|
| test.cpp:8:9:8:12 | Store | test.cpp:24:11:24:18 | call to get_rand |
|
||||||
|
| test.cpp:8:9:8:12 | call to rand | test.cpp:8:9:8:12 | Store |
|
||||||
|
| test.cpp:8:9:8:12 | call to rand | test.cpp:8:9:8:12 | Store |
|
||||||
|
| test.cpp:13:2:13:15 | Chi | test.cpp:30:13:30:14 | get_rand2 output argument |
|
||||||
|
| test.cpp:13:10:13:13 | call to rand | test.cpp:13:2:13:15 | Chi |
|
||||||
|
| test.cpp:13:10:13:13 | call to rand | test.cpp:13:2:13:15 | Chi |
|
||||||
|
| test.cpp:18:2:18:14 | Chi | test.cpp:36:13:36:13 | get_rand3 output argument |
|
||||||
|
| test.cpp:18:9:18:12 | call to rand | test.cpp:18:2:18:14 | Chi |
|
||||||
|
| test.cpp:18:9:18:12 | call to rand | test.cpp:18:2:18:14 | Chi |
|
||||||
|
| test.cpp:24:11:24:18 | call to get_rand | test.cpp:25:7:25:7 | r |
|
||||||
|
| test.cpp:24:11:24:18 | call to get_rand | test.cpp:25:7:25:7 | r |
|
||||||
|
| test.cpp:30:13:30:14 | get_rand2 output argument | test.cpp:31:7:31:7 | r |
|
||||||
|
| test.cpp:30:13:30:14 | get_rand2 output argument | test.cpp:31:7:31:7 | r |
|
||||||
|
| test.cpp:36:13:36:13 | get_rand3 output argument | test.cpp:37:7:37:7 | r |
|
||||||
|
| test.cpp:36:13:36:13 | get_rand3 output argument | test.cpp:37:7:37:7 | r |
|
||||||
|
nodes
|
||||||
|
| test.c:18:13:18:16 | call to rand | semmle.label | call to rand |
|
||||||
|
| test.c:18:13:18:16 | call to rand | semmle.label | call to rand |
|
||||||
|
| test.c:21:17:21:17 | r | semmle.label | r |
|
||||||
|
| test.c:21:17:21:17 | r | semmle.label | r |
|
||||||
|
| test.c:21:17:21:17 | r | semmle.label | r |
|
||||||
|
| test.c:34:13:34:18 | call to rand | semmle.label | call to rand |
|
||||||
|
| test.c:34:13:34:18 | call to rand | semmle.label | call to rand |
|
||||||
|
| test.c:35:5:35:5 | r | semmle.label | r |
|
||||||
|
| test.c:35:5:35:5 | r | semmle.label | r |
|
||||||
|
| test.c:35:5:35:5 | r | semmle.label | r |
|
||||||
|
| test.c:39:13:39:21 | ... % ... | semmle.label | ... % ... |
|
||||||
|
| test.c:39:13:39:21 | ... % ... | semmle.label | ... % ... |
|
||||||
|
| test.c:40:5:40:5 | r | semmle.label | r |
|
||||||
|
| test.c:40:5:40:5 | r | semmle.label | r |
|
||||||
|
| test.c:40:5:40:5 | r | semmle.label | r |
|
||||||
|
| test.c:44:13:44:16 | call to rand | semmle.label | call to rand |
|
||||||
|
| test.c:44:13:44:16 | call to rand | semmle.label | call to rand |
|
||||||
|
| test.c:45:5:45:5 | r | semmle.label | r |
|
||||||
|
| test.c:45:5:45:5 | r | semmle.label | r |
|
||||||
|
| test.c:45:5:45:5 | r | semmle.label | r |
|
||||||
|
| test.c:54:13:54:16 | call to rand | semmle.label | call to rand |
|
||||||
|
| test.c:54:13:54:16 | call to rand | semmle.label | call to rand |
|
||||||
|
| test.c:56:5:56:5 | r | semmle.label | r |
|
||||||
|
| test.c:56:5:56:5 | r | semmle.label | r |
|
||||||
|
| test.c:56:5:56:5 | r | semmle.label | r |
|
||||||
|
| test.c:60:13:60:16 | call to rand | semmle.label | call to rand |
|
||||||
|
| test.c:60:13:60:16 | call to rand | semmle.label | call to rand |
|
||||||
|
| test.c:61:5:61:5 | r | semmle.label | r |
|
||||||
|
| test.c:61:5:61:5 | r | semmle.label | r |
|
||||||
|
| test.c:61:5:61:5 | r | semmle.label | r |
|
||||||
|
| test.c:62:5:62:5 | r | semmle.label | r |
|
||||||
|
| test.c:62:5:62:5 | r | semmle.label | r |
|
||||||
|
| test.c:62:5:62:5 | r | semmle.label | r |
|
||||||
|
| test.c:66:13:66:16 | call to rand | semmle.label | call to rand |
|
||||||
|
| test.c:66:13:66:16 | call to rand | semmle.label | call to rand |
|
||||||
|
| test.c:67:5:67:5 | r | semmle.label | r |
|
||||||
|
| test.c:67:5:67:5 | r | semmle.label | r |
|
||||||
|
| test.c:67:5:67:5 | r | semmle.label | r |
|
||||||
|
| test.c:75:13:75:19 | ... ^ ... | semmle.label | ... ^ ... |
|
||||||
|
| test.c:75:13:75:19 | ... ^ ... | semmle.label | ... ^ ... |
|
||||||
|
| test.c:77:9:77:9 | r | semmle.label | r |
|
||||||
|
| test.c:77:9:77:9 | r | semmle.label | r |
|
||||||
|
| test.c:77:9:77:9 | r | semmle.label | r |
|
||||||
|
| test.c:99:14:99:19 | call to rand | semmle.label | call to rand |
|
||||||
|
| test.c:99:14:99:19 | call to rand | semmle.label | call to rand |
|
||||||
|
| test.c:100:5:100:5 | r | semmle.label | r |
|
||||||
|
| test.c:100:5:100:5 | r | semmle.label | r |
|
||||||
|
| test.c:100:5:100:5 | r | semmle.label | r |
|
||||||
|
| test.cpp:8:9:8:12 | Store | semmle.label | Store |
|
||||||
|
| test.cpp:8:9:8:12 | call to rand | semmle.label | call to rand |
|
||||||
|
| test.cpp:8:9:8:12 | call to rand | semmle.label | call to rand |
|
||||||
|
| test.cpp:13:2:13:15 | Chi | semmle.label | Chi |
|
||||||
|
| test.cpp:13:10:13:13 | call to rand | semmle.label | call to rand |
|
||||||
|
| test.cpp:13:10:13:13 | call to rand | semmle.label | call to rand |
|
||||||
|
| test.cpp:18:2:18:14 | Chi | semmle.label | Chi |
|
||||||
|
| test.cpp:18:9:18:12 | call to rand | semmle.label | call to rand |
|
||||||
|
| test.cpp:18:9:18:12 | call to rand | semmle.label | call to rand |
|
||||||
|
| test.cpp:24:11:24:18 | call to get_rand | semmle.label | call to get_rand |
|
||||||
|
| test.cpp:25:7:25:7 | r | semmle.label | r |
|
||||||
|
| test.cpp:25:7:25:7 | r | semmle.label | r |
|
||||||
|
| test.cpp:25:7:25:7 | r | semmle.label | r |
|
||||||
|
| test.cpp:30:13:30:14 | get_rand2 output argument | semmle.label | get_rand2 output argument |
|
||||||
|
| test.cpp:31:7:31:7 | r | semmle.label | r |
|
||||||
|
| test.cpp:31:7:31:7 | r | semmle.label | r |
|
||||||
|
| test.cpp:31:7:31:7 | r | semmle.label | r |
|
||||||
|
| test.cpp:36:13:36:13 | get_rand3 output argument | semmle.label | get_rand3 output argument |
|
||||||
|
| test.cpp:37:7:37:7 | r | semmle.label | r |
|
||||||
|
| test.cpp:37:7:37:7 | r | semmle.label | r |
|
||||||
|
| test.cpp:37:7:37:7 | r | semmle.label | r |
|
||||||
|
#select
|
||||||
|
| test.c:21:17:21:17 | r | test.c:18:13:18:16 | call to rand | test.c:21:17:21:17 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:18:13:18:16 | call to rand | Uncontrolled value |
|
||||||
|
| test.c:35:5:35:5 | r | test.c:34:13:34:18 | call to rand | test.c:35:5:35:5 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:34:13:34:18 | call to rand | Uncontrolled value |
|
||||||
|
| test.c:40:5:40:5 | r | test.c:39:13:39:21 | ... % ... | test.c:40:5:40:5 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:39:13:39:21 | ... % ... | Uncontrolled value |
|
||||||
|
| test.c:45:5:45:5 | r | test.c:44:13:44:16 | call to rand | test.c:45:5:45:5 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:44:13:44:16 | call to rand | Uncontrolled value |
|
||||||
|
| test.c:56:5:56:5 | r | test.c:54:13:54:16 | call to rand | test.c:56:5:56:5 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:54:13:54:16 | call to rand | Uncontrolled value |
|
||||||
|
| test.c:67:5:67:5 | r | test.c:66:13:66:16 | call to rand | test.c:67:5:67:5 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:66:13:66:16 | call to rand | Uncontrolled value |
|
||||||
|
| test.c:77:9:77:9 | r | test.c:75:13:75:19 | ... ^ ... | test.c:77:9:77:9 | r | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.c:75:13:75:19 | ... ^ ... | Uncontrolled value |
|
||||||
|
| test.c:100:5:100:5 | r | test.c:99:14:99:19 | call to rand | test.c:100:5:100:5 | r | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.c:99:14:99:19 | call to rand | Uncontrolled value |
|
||||||
|
| test.cpp:25:7:25:7 | r | test.cpp:8:9:8:12 | call to rand | test.cpp:25:7:25:7 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:8:9:8:12 | call to rand | Uncontrolled value |
|
||||||
|
| test.cpp:31:7:31:7 | r | test.cpp:13:10:13:13 | call to rand | test.cpp:31:7:31:7 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:13:10:13:13 | call to rand | Uncontrolled value |
|
||||||
|
| test.cpp:37:7:37:7 | r | test.cpp:18:9:18:12 | call to rand | test.cpp:37:7:37:7 | r | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.cpp:18:9:18:12 | call to rand | Uncontrolled value |
|
||||||
|
|||||||
@@ -1,3 +1,33 @@
|
|||||||
| test.cpp:20:7:20:12 | call to strcmp | Untrusted input $@ might be vulnerable to a spoofing attack. | test.cpp:16:25:16:30 | call to getenv | call to getenv |
|
edges
|
||||||
| test.cpp:31:7:31:12 | call to strcmp | Untrusted input $@ might be vulnerable to a spoofing attack. | test.cpp:27:25:27:30 | call to getenv | call to getenv |
|
| test.cpp:16:25:16:30 | call to getenv | test.cpp:20:14:20:20 | address |
|
||||||
| test.cpp:42:7:42:12 | call to strcmp | Untrusted input $@ might be vulnerable to a spoofing attack. | test.cpp:38:25:38:30 | call to getenv | call to getenv |
|
| test.cpp:16:25:16:30 | call to getenv | test.cpp:20:14:20:20 | address |
|
||||||
|
| test.cpp:16:25:16:42 | (const char *)... | test.cpp:20:14:20:20 | address |
|
||||||
|
| test.cpp:16:25:16:42 | (const char *)... | test.cpp:20:14:20:20 | address |
|
||||||
|
| test.cpp:27:25:27:30 | call to getenv | test.cpp:31:14:31:20 | address |
|
||||||
|
| test.cpp:27:25:27:30 | call to getenv | test.cpp:31:14:31:20 | address |
|
||||||
|
| test.cpp:27:25:27:42 | (const char *)... | test.cpp:31:14:31:20 | address |
|
||||||
|
| test.cpp:27:25:27:42 | (const char *)... | test.cpp:31:14:31:20 | address |
|
||||||
|
| test.cpp:38:25:38:30 | call to getenv | test.cpp:42:14:42:20 | address |
|
||||||
|
| test.cpp:38:25:38:30 | call to getenv | test.cpp:42:14:42:20 | address |
|
||||||
|
| test.cpp:38:25:38:42 | (const char *)... | test.cpp:42:14:42:20 | address |
|
||||||
|
| test.cpp:38:25:38:42 | (const char *)... | test.cpp:42:14:42:20 | address |
|
||||||
|
nodes
|
||||||
|
| test.cpp:16:25:16:30 | call to getenv | semmle.label | call to getenv |
|
||||||
|
| test.cpp:16:25:16:42 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| test.cpp:20:14:20:20 | address | semmle.label | address |
|
||||||
|
| test.cpp:20:14:20:20 | address | semmle.label | address |
|
||||||
|
| test.cpp:20:14:20:20 | address | semmle.label | address |
|
||||||
|
| test.cpp:27:25:27:30 | call to getenv | semmle.label | call to getenv |
|
||||||
|
| test.cpp:27:25:27:42 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| test.cpp:31:14:31:20 | address | semmle.label | address |
|
||||||
|
| test.cpp:31:14:31:20 | address | semmle.label | address |
|
||||||
|
| test.cpp:31:14:31:20 | address | semmle.label | address |
|
||||||
|
| test.cpp:38:25:38:30 | call to getenv | semmle.label | call to getenv |
|
||||||
|
| test.cpp:38:25:38:42 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| test.cpp:42:14:42:20 | address | semmle.label | address |
|
||||||
|
| test.cpp:42:14:42:20 | address | semmle.label | address |
|
||||||
|
| test.cpp:42:14:42:20 | address | semmle.label | address |
|
||||||
|
#select
|
||||||
|
| test.cpp:20:7:20:12 | call to strcmp | test.cpp:16:25:16:30 | call to getenv | test.cpp:20:14:20:20 | address | Untrusted input $@ might be vulnerable to a spoofing attack. | test.cpp:16:25:16:30 | call to getenv | call to getenv |
|
||||||
|
| test.cpp:31:7:31:12 | call to strcmp | test.cpp:27:25:27:30 | call to getenv | test.cpp:31:14:31:20 | address | Untrusted input $@ might be vulnerable to a spoofing attack. | test.cpp:27:25:27:30 | call to getenv | call to getenv |
|
||||||
|
| test.cpp:42:7:42:12 | call to strcmp | test.cpp:38:25:38:30 | call to getenv | test.cpp:42:14:42:20 | address | Untrusted input $@ might be vulnerable to a spoofing attack. | test.cpp:38:25:38:30 | call to getenv | call to getenv |
|
||||||
|
|||||||
@@ -1 +1,13 @@
|
|||||||
| test.cpp:58:3:58:9 | call to sprintf | This write into buffer 'passwd' may contain unencrypted data from $@ | test.cpp:54:17:54:20 | argv | user input (argv) |
|
edges
|
||||||
|
| test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input |
|
||||||
|
| test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input |
|
||||||
|
| test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input |
|
||||||
|
| test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input |
|
||||||
|
nodes
|
||||||
|
| test.cpp:54:17:54:20 | argv | semmle.label | argv |
|
||||||
|
| test.cpp:54:17:54:20 | argv | semmle.label | argv |
|
||||||
|
| test.cpp:58:25:58:29 | input | semmle.label | input |
|
||||||
|
| test.cpp:58:25:58:29 | input | semmle.label | input |
|
||||||
|
| test.cpp:58:25:58:29 | input | semmle.label | input |
|
||||||
|
#select
|
||||||
|
| test.cpp:58:3:58:9 | call to sprintf | test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input | This write into buffer 'passwd' may contain unencrypted data from $@ | test.cpp:54:17:54:20 | argv | user input (argv) |
|
||||||
|
|||||||
@@ -1,2 +1,37 @@
|
|||||||
| test.cpp:24:10:24:35 | ! ... | Reliance on untrusted input $@ to raise privilege at $@ | test.cpp:20:29:20:34 | call to getenv | call to getenv | test.cpp:25:9:25:27 | ... = ... | ... = ... |
|
edges
|
||||||
| test.cpp:41:10:41:38 | ! ... | Reliance on untrusted input $@ to raise privilege at $@ | test.cpp:20:29:20:34 | call to getenv | call to getenv | test.cpp:42:8:42:26 | ... = ... | ... = ... |
|
| test.cpp:20:29:20:34 | call to getenv | test.cpp:24:10:24:35 | ! ... |
|
||||||
|
| test.cpp:20:29:20:34 | call to getenv | test.cpp:24:11:24:16 | call to strcmp |
|
||||||
|
| test.cpp:20:29:20:34 | call to getenv | test.cpp:24:11:24:16 | call to strcmp |
|
||||||
|
| test.cpp:20:29:20:34 | call to getenv | test.cpp:24:11:24:35 | (bool)... |
|
||||||
|
| test.cpp:20:29:20:34 | call to getenv | test.cpp:41:10:41:38 | ! ... |
|
||||||
|
| test.cpp:20:29:20:34 | call to getenv | test.cpp:41:11:41:16 | call to strcmp |
|
||||||
|
| test.cpp:20:29:20:34 | call to getenv | test.cpp:41:11:41:16 | call to strcmp |
|
||||||
|
| test.cpp:20:29:20:34 | call to getenv | test.cpp:41:11:41:38 | (bool)... |
|
||||||
|
| test.cpp:20:29:20:47 | (const char *)... | test.cpp:24:10:24:35 | ! ... |
|
||||||
|
| test.cpp:20:29:20:47 | (const char *)... | test.cpp:24:11:24:16 | call to strcmp |
|
||||||
|
| test.cpp:20:29:20:47 | (const char *)... | test.cpp:24:11:24:16 | call to strcmp |
|
||||||
|
| test.cpp:20:29:20:47 | (const char *)... | test.cpp:24:11:24:35 | (bool)... |
|
||||||
|
| test.cpp:20:29:20:47 | (const char *)... | test.cpp:41:10:41:38 | ! ... |
|
||||||
|
| test.cpp:20:29:20:47 | (const char *)... | test.cpp:41:11:41:16 | call to strcmp |
|
||||||
|
| test.cpp:20:29:20:47 | (const char *)... | test.cpp:41:11:41:16 | call to strcmp |
|
||||||
|
| test.cpp:20:29:20:47 | (const char *)... | test.cpp:41:11:41:38 | (bool)... |
|
||||||
|
| test.cpp:24:11:24:16 | call to strcmp | test.cpp:24:10:24:35 | ! ... |
|
||||||
|
| test.cpp:24:11:24:16 | call to strcmp | test.cpp:24:11:24:35 | (bool)... |
|
||||||
|
| test.cpp:41:11:41:16 | call to strcmp | test.cpp:41:10:41:38 | ! ... |
|
||||||
|
| test.cpp:41:11:41:16 | call to strcmp | test.cpp:41:11:41:38 | (bool)... |
|
||||||
|
nodes
|
||||||
|
| test.cpp:20:29:20:34 | call to getenv | semmle.label | call to getenv |
|
||||||
|
| test.cpp:20:29:20:47 | (const char *)... | semmle.label | (const char *)... |
|
||||||
|
| test.cpp:24:10:24:35 | ! ... | semmle.label | ! ... |
|
||||||
|
| test.cpp:24:11:24:16 | call to strcmp | semmle.label | call to strcmp |
|
||||||
|
| test.cpp:24:11:24:16 | call to strcmp | semmle.label | call to strcmp |
|
||||||
|
| test.cpp:24:11:24:35 | (bool)... | semmle.label | (bool)... |
|
||||||
|
| test.cpp:24:11:24:35 | (bool)... | semmle.label | (bool)... |
|
||||||
|
| test.cpp:41:10:41:38 | ! ... | semmle.label | ! ... |
|
||||||
|
| test.cpp:41:11:41:16 | call to strcmp | semmle.label | call to strcmp |
|
||||||
|
| test.cpp:41:11:41:16 | call to strcmp | semmle.label | call to strcmp |
|
||||||
|
| test.cpp:41:11:41:38 | (bool)... | semmle.label | (bool)... |
|
||||||
|
| test.cpp:41:11:41:38 | (bool)... | semmle.label | (bool)... |
|
||||||
|
#select
|
||||||
|
| test.cpp:24:10:24:35 | ! ... | test.cpp:20:29:20:34 | call to getenv | test.cpp:24:10:24:35 | ! ... | Reliance on untrusted input $@ to raise privilege at $@ | test.cpp:20:29:20:34 | call to getenv | call to getenv | test.cpp:25:9:25:27 | ... = ... | ... = ... |
|
||||||
|
| test.cpp:41:10:41:38 | ! ... | test.cpp:20:29:20:34 | call to getenv | test.cpp:41:10:41:38 | ! ... | Reliance on untrusted input $@ to raise privilege at $@ | test.cpp:20:29:20:34 | call to getenv | call to getenv | test.cpp:42:8:42:26 | ... = ... | ... = ... |
|
||||||
|
|||||||
@@ -341,6 +341,8 @@ namespace Semmle.Extraction.Tests
|
|||||||
string cwd = @"C:\Project")
|
string cwd = @"C:\Project")
|
||||||
{
|
{
|
||||||
Actions.GetEnvironmentVariable["CODEQL_AUTOBUILDER_CSHARP_NO_INDEXING"] = "false";
|
Actions.GetEnvironmentVariable["CODEQL_AUTOBUILDER_CSHARP_NO_INDEXING"] = "false";
|
||||||
|
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_TRAP_DIR"] = "";
|
||||||
|
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR"] = "";
|
||||||
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_ROOT"] = @"C:\codeql\csharp";
|
Actions.GetEnvironmentVariable["CODEQL_EXTRACTOR_CSHARP_ROOT"] = @"C:\codeql\csharp";
|
||||||
Actions.GetEnvironmentVariable["CODEQL_JAVA_HOME"] = @"C:\codeql\tools\java";
|
Actions.GetEnvironmentVariable["CODEQL_JAVA_HOME"] = @"C:\codeql\tools\java";
|
||||||
Actions.GetEnvironmentVariable["SEMMLE_DIST"] = @"C:\odasa";
|
Actions.GetEnvironmentVariable["SEMMLE_DIST"] = @"C:\odasa";
|
||||||
@@ -364,8 +366,7 @@ namespace Semmle.Extraction.Tests
|
|||||||
Actions.GetCurrentDirectory = cwd;
|
Actions.GetCurrentDirectory = cwd;
|
||||||
Actions.IsWindows = isWindows;
|
Actions.IsWindows = isWindows;
|
||||||
|
|
||||||
var options = new AutobuildOptions();
|
var options = new AutobuildOptions(Actions);
|
||||||
options.ReadEnvironment(Actions);
|
|
||||||
return new Autobuilder(Actions, options);
|
return new Autobuilder(Actions, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,10 +7,9 @@
|
|||||||
{
|
{
|
||||||
public BuildScript Analyse(Autobuilder builder, bool auto)
|
public BuildScript Analyse(Autobuilder builder, bool auto)
|
||||||
{
|
{
|
||||||
(var javaHome, var dist) =
|
var javaHome = builder.JavaHome;
|
||||||
builder.CodeQLJavaHome != null ?
|
var dist = builder.Distribution;
|
||||||
(builder.CodeQLJavaHome, builder.CodeQLExtractorCSharpRoot) :
|
|
||||||
(builder.SemmleJavaHome, builder.SemmleDist);
|
|
||||||
var command = new CommandBuilder(builder.Actions).
|
var command = new CommandBuilder(builder.Actions).
|
||||||
RunCommand(builder.Actions.PathCombine(javaHome, "bin", "java")).
|
RunCommand(builder.Actions.PathCombine(javaHome, "bin", "java")).
|
||||||
Argument("-jar").
|
Argument("-jar").
|
||||||
|
|||||||
@@ -10,40 +10,40 @@ namespace Semmle.Autobuild
|
|||||||
public class AutobuildOptions
|
public class AutobuildOptions
|
||||||
{
|
{
|
||||||
public readonly int SearchDepth = 3;
|
public readonly int SearchDepth = 3;
|
||||||
public string RootDirectory = null;
|
public readonly string RootDirectory;
|
||||||
static readonly string prefix = "LGTM_INDEX_";
|
private const string prefix = "LGTM_INDEX_";
|
||||||
|
|
||||||
public string VsToolsVersion;
|
public readonly string? VsToolsVersion;
|
||||||
public string MsBuildArguments;
|
public readonly string? MsBuildArguments;
|
||||||
public string MsBuildPlatform;
|
public readonly string? MsBuildPlatform;
|
||||||
public string MsBuildConfiguration;
|
public readonly string? MsBuildConfiguration;
|
||||||
public string MsBuildTarget;
|
public readonly string? MsBuildTarget;
|
||||||
public string DotNetArguments;
|
public readonly string? DotNetArguments;
|
||||||
public string DotNetVersion;
|
public readonly string? DotNetVersion;
|
||||||
public string BuildCommand;
|
public readonly string? BuildCommand;
|
||||||
public string[] Solution;
|
public readonly string[] Solution;
|
||||||
|
|
||||||
public bool IgnoreErrors;
|
public readonly bool IgnoreErrors;
|
||||||
public bool Buildless;
|
public readonly bool Buildless;
|
||||||
public bool AllSolutions;
|
public readonly bool AllSolutions;
|
||||||
public bool NugetRestore;
|
public readonly bool NugetRestore;
|
||||||
|
|
||||||
public Language Language;
|
public readonly Language Language;
|
||||||
public bool Indexing;
|
public readonly bool Indexing;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads options from environment variables.
|
/// Reads options from environment variables.
|
||||||
/// Throws ArgumentOutOfRangeException for invalid arguments.
|
/// Throws ArgumentOutOfRangeException for invalid arguments.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ReadEnvironment(IBuildActions actions)
|
public AutobuildOptions(IBuildActions actions)
|
||||||
{
|
{
|
||||||
RootDirectory = actions.GetCurrentDirectory();
|
RootDirectory = actions.GetCurrentDirectory();
|
||||||
VsToolsVersion = actions.GetEnvironmentVariable(prefix + "VSTOOLS_VERSION");
|
VsToolsVersion = actions.GetEnvironmentVariable(prefix + "VSTOOLS_VERSION");
|
||||||
MsBuildArguments = actions.GetEnvironmentVariable(prefix + "MSBUILD_ARGUMENTS").AsStringWithExpandedEnvVars(actions);
|
MsBuildArguments = actions.GetEnvironmentVariable(prefix + "MSBUILD_ARGUMENTS")?.AsStringWithExpandedEnvVars(actions);
|
||||||
MsBuildPlatform = actions.GetEnvironmentVariable(prefix + "MSBUILD_PLATFORM");
|
MsBuildPlatform = actions.GetEnvironmentVariable(prefix + "MSBUILD_PLATFORM");
|
||||||
MsBuildConfiguration = actions.GetEnvironmentVariable(prefix + "MSBUILD_CONFIGURATION");
|
MsBuildConfiguration = actions.GetEnvironmentVariable(prefix + "MSBUILD_CONFIGURATION");
|
||||||
MsBuildTarget = actions.GetEnvironmentVariable(prefix + "MSBUILD_TARGET");
|
MsBuildTarget = actions.GetEnvironmentVariable(prefix + "MSBUILD_TARGET");
|
||||||
DotNetArguments = actions.GetEnvironmentVariable(prefix + "DOTNET_ARGUMENTS").AsStringWithExpandedEnvVars(actions);
|
DotNetArguments = actions.GetEnvironmentVariable(prefix + "DOTNET_ARGUMENTS")?.AsStringWithExpandedEnvVars(actions);
|
||||||
DotNetVersion = actions.GetEnvironmentVariable(prefix + "DOTNET_VERSION");
|
DotNetVersion = actions.GetEnvironmentVariable(prefix + "DOTNET_VERSION");
|
||||||
BuildCommand = actions.GetEnvironmentVariable(prefix + "BUILD_COMMAND");
|
BuildCommand = actions.GetEnvironmentVariable(prefix + "BUILD_COMMAND");
|
||||||
Solution = actions.GetEnvironmentVariable(prefix + "SOLUTION").AsListWithExpandedEnvVars(actions, new string[0]);
|
Solution = actions.GetEnvironmentVariable(prefix + "SOLUTION").AsListWithExpandedEnvVars(actions, new string[0]);
|
||||||
@@ -60,7 +60,7 @@ namespace Semmle.Autobuild
|
|||||||
|
|
||||||
public static class OptionsExtensions
|
public static class OptionsExtensions
|
||||||
{
|
{
|
||||||
public static bool AsBool(this string value, string param, bool defaultValue)
|
public static bool AsBool(this string? value, string param, bool defaultValue)
|
||||||
{
|
{
|
||||||
if (value == null) return defaultValue;
|
if (value == null) return defaultValue;
|
||||||
switch (value.ToLower())
|
switch (value.ToLower())
|
||||||
@@ -80,7 +80,7 @@ namespace Semmle.Autobuild
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Language AsLanguage(this string key)
|
public static Language AsLanguage(this string? key)
|
||||||
{
|
{
|
||||||
switch (key)
|
switch (key)
|
||||||
{
|
{
|
||||||
@@ -95,7 +95,7 @@ namespace Semmle.Autobuild
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string[] AsListWithExpandedEnvVars(this string value, IBuildActions actions, string[] defaultValue)
|
public static string[] AsListWithExpandedEnvVars(this string? value, IBuildActions actions, string[] defaultValue)
|
||||||
{
|
{
|
||||||
if (value == null)
|
if (value == null)
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
|
|||||||
@@ -20,6 +20,14 @@ namespace Semmle.Autobuild
|
|||||||
BuildScript Analyse(Autobuilder builder, bool auto);
|
BuildScript Analyse(Autobuilder builder, bool auto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Exception indicating that environment variables are missing or invalid.
|
||||||
|
/// </summary>
|
||||||
|
class InvalidEnvironmentException : Exception
|
||||||
|
{
|
||||||
|
public InvalidEnvironmentException(string m) : base(m) { }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Main application logic, containing all data
|
/// Main application logic, containing all data
|
||||||
/// gathered from the project and filesystem.
|
/// gathered from the project and filesystem.
|
||||||
@@ -69,7 +77,7 @@ namespace Semmle.Autobuild
|
|||||||
/// List of project/solution files to build.
|
/// List of project/solution files to build.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IList<IProjectOrSolution> ProjectsOrSolutionsToBuild => projectsOrSolutionsToBuildLazy.Value;
|
public IList<IProjectOrSolution> ProjectsOrSolutionsToBuild => projectsOrSolutionsToBuildLazy.Value;
|
||||||
readonly Lazy<IList<IProjectOrSolution>> projectsOrSolutionsToBuildLazy;
|
private readonly Lazy<IList<IProjectOrSolution>> projectsOrSolutionsToBuildLazy;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Holds if a given path was found.
|
/// Holds if a given path was found.
|
||||||
@@ -129,7 +137,7 @@ namespace Semmle.Autobuild
|
|||||||
|
|
||||||
projectsOrSolutionsToBuildLazy = new Lazy<IList<IProjectOrSolution>>(() =>
|
projectsOrSolutionsToBuildLazy = new Lazy<IList<IProjectOrSolution>>(() =>
|
||||||
{
|
{
|
||||||
List<IProjectOrSolution> ret;
|
List<IProjectOrSolution>? ret;
|
||||||
if (options.Solution.Any())
|
if (options.Solution.Any())
|
||||||
{
|
{
|
||||||
ret = new List<IProjectOrSolution>();
|
ret = new List<IProjectOrSolution>();
|
||||||
@@ -143,7 +151,7 @@ namespace Semmle.Autobuild
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<IProjectOrSolution> FindFiles(string extension, Func<string, ProjectOrSolution> create)
|
IEnumerable<IProjectOrSolution>? FindFiles(string extension, Func<string, ProjectOrSolution> create)
|
||||||
{
|
{
|
||||||
var matchingFiles = GetExtensions(extension).
|
var matchingFiles = GetExtensions(extension).
|
||||||
Select(p => (ProjectOrSolution: create(p.Item1), DistanceFromRoot: p.Item2)).
|
Select(p => (ProjectOrSolution: create(p.Item1), DistanceFromRoot: p.Item2)).
|
||||||
@@ -177,19 +185,34 @@ namespace Semmle.Autobuild
|
|||||||
});
|
});
|
||||||
|
|
||||||
CodeQLExtractorCSharpRoot = Actions.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_ROOT");
|
CodeQLExtractorCSharpRoot = Actions.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_ROOT");
|
||||||
|
|
||||||
CodeQLJavaHome = Actions.GetEnvironmentVariable("CODEQL_JAVA_HOME");
|
|
||||||
|
|
||||||
SemmleDist = Actions.GetEnvironmentVariable("SEMMLE_DIST");
|
SemmleDist = Actions.GetEnvironmentVariable("SEMMLE_DIST");
|
||||||
|
|
||||||
SemmleJavaHome = Actions.GetEnvironmentVariable("SEMMLE_JAVA_HOME");
|
|
||||||
|
|
||||||
SemmlePlatformTools = Actions.GetEnvironmentVariable("SEMMLE_PLATFORM_TOOLS");
|
SemmlePlatformTools = Actions.GetEnvironmentVariable("SEMMLE_PLATFORM_TOOLS");
|
||||||
|
|
||||||
if (CodeQLExtractorCSharpRoot == null && SemmleDist == null)
|
JavaHome =
|
||||||
Log(Severity.Error, "The environment variables CODEQL_EXTRACTOR_CSHARP_ROOT and SEMMLE_DIST have not been set.");
|
Actions.GetEnvironmentVariable("CODEQL_JAVA_HOME") ??
|
||||||
|
Actions.GetEnvironmentVariable("SEMMLE_JAVA_HOME") ??
|
||||||
|
throw new InvalidEnvironmentException("The environment variable CODEQL_JAVA_HOME or SEMMLE_JAVA_HOME has not been set.");
|
||||||
|
|
||||||
|
Distribution =
|
||||||
|
CodeQLExtractorCSharpRoot ??
|
||||||
|
SemmleDist ??
|
||||||
|
throw new InvalidEnvironmentException("The environment variable CODEQL_EXTRACTOR_CSHARP_ROOT or SEMMLE_DIST has not been set.");
|
||||||
|
|
||||||
|
TrapDir =
|
||||||
|
Actions.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_TRAP_DIR") ??
|
||||||
|
Actions.GetEnvironmentVariable("TRAP_FOLDER") ??
|
||||||
|
throw new InvalidEnvironmentException("The environment variable CODEQL_EXTRACTOR_CSHARP_TRAP_DIR or TRAP_FOLDER has not been set.");
|
||||||
|
|
||||||
|
SourceArchiveDir =
|
||||||
|
Actions.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR") ??
|
||||||
|
Actions.GetEnvironmentVariable("SOURCE_ARCHIVE") ??
|
||||||
|
throw new InvalidEnvironmentException("The environment variable CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR or SOURCE_ARCHIVE has not been set.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string TrapDir { get; }
|
||||||
|
|
||||||
|
private string SourceArchiveDir { get; }
|
||||||
|
|
||||||
readonly ILogger logger = new ConsoleLogger(Verbosity.Info);
|
readonly ILogger logger = new ConsoleLogger(Verbosity.Info);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -271,9 +294,9 @@ namespace Semmle.Autobuild
|
|||||||
break;
|
break;
|
||||||
case CSharpBuildStrategy.Auto:
|
case CSharpBuildStrategy.Auto:
|
||||||
var cleanTrapFolder =
|
var cleanTrapFolder =
|
||||||
BuildScript.DeleteDirectory(Actions.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_TRAP_DIR") ?? Actions.GetEnvironmentVariable("TRAP_FOLDER"));
|
BuildScript.DeleteDirectory(TrapDir);
|
||||||
var cleanSourceArchive =
|
var cleanSourceArchive =
|
||||||
BuildScript.DeleteDirectory(Actions.GetEnvironmentVariable("CODEQL_EXTRACTOR_CSHARP_SOURCE_ARCHIVE_DIR") ?? Actions.GetEnvironmentVariable("SOURCE_ARCHIVE"));
|
BuildScript.DeleteDirectory(SourceArchiveDir);
|
||||||
var tryCleanExtractorArgsLogs =
|
var tryCleanExtractorArgsLogs =
|
||||||
BuildScript.Create(actions =>
|
BuildScript.Create(actions =>
|
||||||
{
|
{
|
||||||
@@ -376,38 +399,33 @@ namespace Semmle.Autobuild
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Value of CODEQL_EXTRACTOR_CSHARP_ROOT environment variable.
|
/// Value of CODEQL_EXTRACTOR_CSHARP_ROOT environment variable.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string CodeQLExtractorCSharpRoot { get; private set; }
|
private string? CodeQLExtractorCSharpRoot { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Value of CODEQL_JAVA_HOME environment variable.
|
|
||||||
/// </summary>
|
|
||||||
public string CodeQLJavaHome { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Value of SEMMLE_DIST environment variable.
|
/// Value of SEMMLE_DIST environment variable.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string SemmleDist { get; private set; }
|
private string? SemmleDist { get; }
|
||||||
|
|
||||||
/// <summary>
|
public string Distribution { get; }
|
||||||
/// Value of SEMMLE_JAVA_HOME environment variable.
|
|
||||||
/// </summary>
|
public string JavaHome { get; }
|
||||||
public string SemmleJavaHome { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Value of SEMMLE_PLATFORM_TOOLS environment variable.
|
/// Value of SEMMLE_PLATFORM_TOOLS environment variable.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string SemmlePlatformTools { get; private set; }
|
public string? SemmlePlatformTools { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The absolute path of the odasa executable.
|
/// The absolute path of the odasa executable.
|
||||||
|
/// null if we are running in CodeQL.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Odasa => SemmleDist == null ? null : Actions.PathCombine(SemmleDist, "tools", "odasa");
|
public string? Odasa => SemmleDist is null ? null : Actions.PathCombine(SemmleDist, "tools", "odasa");
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Construct a command that executed the given <paramref name="cmd"/> wrapped in
|
/// Construct a command that executed the given <paramref name="cmd"/> wrapped in
|
||||||
/// an <code>odasa --index</code>, unless indexing has been disabled, in which case
|
/// an <code>odasa --index</code>, unless indexing has been disabled, in which case
|
||||||
/// <paramref name="cmd"/> is run directly.
|
/// <paramref name="cmd"/> is run directly.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal CommandBuilder MaybeIndex(CommandBuilder builder, string cmd) => Options.Indexing ? builder.IndexCommand(Odasa, cmd) : builder.RunCommand(cmd);
|
internal CommandBuilder MaybeIndex(CommandBuilder builder, string cmd) => Options.Indexing && !(Odasa is null) ? builder.IndexCommand(Odasa, cmd) : builder.RunCommand(cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace Semmle.Autobuild
|
|||||||
/// <param name="env">Additional environment variables.</param>
|
/// <param name="env">Additional environment variables.</param>
|
||||||
/// <param name="stdOut">The lines of stdout.</param>
|
/// <param name="stdOut">The lines of stdout.</param>
|
||||||
/// <returns>The process exit code.</returns>
|
/// <returns>The process exit code.</returns>
|
||||||
int RunProcess(string exe, string args, string workingDirectory, IDictionary<string, string> env, out IList<string> stdOut);
|
int RunProcess(string exe, string args, string? workingDirectory, IDictionary<string, string>? env, out IList<string> stdOut);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Runs a process but does not capture its output.
|
/// Runs a process but does not capture its output.
|
||||||
@@ -31,7 +31,7 @@ namespace Semmle.Autobuild
|
|||||||
/// <param name="workingDirectory">The working directory (<code>null</code> for current directory).</param>
|
/// <param name="workingDirectory">The working directory (<code>null</code> for current directory).</param>
|
||||||
/// <param name="env">Additional environment variables.</param>
|
/// <param name="env">Additional environment variables.</param>
|
||||||
/// <returns>The process exit code.</returns>
|
/// <returns>The process exit code.</returns>
|
||||||
int RunProcess(string exe, string args, string workingDirectory, IDictionary<string, string> env);
|
int RunProcess(string exe, string args, string? workingDirectory, IDictionary<string, string>? env);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tests whether a file exists, File.Exists().
|
/// Tests whether a file exists, File.Exists().
|
||||||
@@ -63,7 +63,7 @@ namespace Semmle.Autobuild
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name of the variable.</param>
|
/// <param name="name">The name of the variable.</param>
|
||||||
/// <returns>The string value, or null if the variable is not defined.</returns>
|
/// <returns>The string value, or null if the variable is not defined.</returns>
|
||||||
string GetEnvironmentVariable(string name);
|
string? GetEnvironmentVariable(string name);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current directory, Directory.GetCurrentDirectory().
|
/// Gets the current directory, Directory.GetCurrentDirectory().
|
||||||
@@ -130,7 +130,7 @@ namespace Semmle.Autobuild
|
|||||||
|
|
||||||
bool IBuildActions.FileExists(string file) => File.Exists(file);
|
bool IBuildActions.FileExists(string file) => File.Exists(file);
|
||||||
|
|
||||||
ProcessStartInfo GetProcessStartInfo(string exe, string arguments, string workingDirectory, IDictionary<string, string> environment, bool redirectStandardOutput)
|
ProcessStartInfo GetProcessStartInfo(string exe, string arguments, string? workingDirectory, IDictionary<string, string>? environment, bool redirectStandardOutput)
|
||||||
{
|
{
|
||||||
var pi = new ProcessStartInfo(exe, arguments)
|
var pi = new ProcessStartInfo(exe, arguments)
|
||||||
{
|
{
|
||||||
@@ -146,7 +146,7 @@ namespace Semmle.Autobuild
|
|||||||
return pi;
|
return pi;
|
||||||
}
|
}
|
||||||
|
|
||||||
int IBuildActions.RunProcess(string cmd, string args, string workingDirectory, IDictionary<string, string> environment)
|
int IBuildActions.RunProcess(string cmd, string args, string? workingDirectory, IDictionary<string, string>? environment)
|
||||||
{
|
{
|
||||||
var pi = GetProcessStartInfo(cmd, args, workingDirectory, environment, false);
|
var pi = GetProcessStartInfo(cmd, args, workingDirectory, environment, false);
|
||||||
using (var p = Process.Start(pi))
|
using (var p = Process.Start(pi))
|
||||||
@@ -156,7 +156,7 @@ namespace Semmle.Autobuild
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int IBuildActions.RunProcess(string cmd, string args, string workingDirectory, IDictionary<string, string> environment, out IList<string> stdOut)
|
int IBuildActions.RunProcess(string cmd, string args, string? workingDirectory, IDictionary<string, string>? environment, out IList<string> stdOut)
|
||||||
{
|
{
|
||||||
var pi = GetProcessStartInfo(cmd, args, workingDirectory, environment, true);
|
var pi = GetProcessStartInfo(cmd, args, workingDirectory, environment, true);
|
||||||
return pi.ReadOutput(out stdOut);
|
return pi.ReadOutput(out stdOut);
|
||||||
@@ -166,7 +166,7 @@ namespace Semmle.Autobuild
|
|||||||
|
|
||||||
bool IBuildActions.DirectoryExists(string dir) => Directory.Exists(dir);
|
bool IBuildActions.DirectoryExists(string dir) => Directory.Exists(dir);
|
||||||
|
|
||||||
string IBuildActions.GetEnvironmentVariable(string name) => Environment.GetEnvironmentVariable(name);
|
string? IBuildActions.GetEnvironmentVariable(string name) => Environment.GetEnvironmentVariable(name);
|
||||||
|
|
||||||
string IBuildActions.GetCurrentDirectory() => Directory.GetCurrentDirectory();
|
string IBuildActions.GetCurrentDirectory() => Directory.GetCurrentDirectory();
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace Semmle.Autobuild
|
|||||||
chmod.RunCommand("/bin/chmod", $"u+x {scriptPath}");
|
chmod.RunCommand("/bin/chmod", $"u+x {scriptPath}");
|
||||||
var chmodScript = builder.Actions.IsWindows() ? BuildScript.Success : BuildScript.Try(chmod.Script);
|
var chmodScript = builder.Actions.IsWindows() ? BuildScript.Success : BuildScript.Try(chmod.Script);
|
||||||
|
|
||||||
var dir = Path.GetDirectoryName(scriptPath);
|
string? dir = Path.GetDirectoryName(scriptPath);
|
||||||
|
|
||||||
// A specific .NET Core version may be required
|
// A specific .NET Core version may be required
|
||||||
return chmodScript & DotNetRule.WithDotNet(builder, environment =>
|
return chmodScript & DotNetRule.WithDotNet(builder, environment =>
|
||||||
|
|||||||
@@ -48,8 +48,9 @@ namespace Semmle.Autobuild
|
|||||||
|
|
||||||
class BuildCommand : BuildScript
|
class BuildCommand : BuildScript
|
||||||
{
|
{
|
||||||
readonly string exe, arguments, workingDirectory;
|
readonly string exe, arguments;
|
||||||
readonly IDictionary<string, string> environment;
|
readonly string? workingDirectory;
|
||||||
|
readonly IDictionary<string, string>? environment;
|
||||||
readonly bool silent;
|
readonly bool silent;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -60,7 +61,7 @@ namespace Semmle.Autobuild
|
|||||||
/// <param name="silent">Whether this command should run silently.</param>
|
/// <param name="silent">Whether this command should run silently.</param>
|
||||||
/// <param name="workingDirectory">The working directory (<code>null</code> for current directory).</param>
|
/// <param name="workingDirectory">The working directory (<code>null</code> for current directory).</param>
|
||||||
/// <param name="environment">Additional environment variables.</param>
|
/// <param name="environment">Additional environment variables.</param>
|
||||||
public BuildCommand(string exe, string argumentsOpt, bool silent, string workingDirectory = null, IDictionary<string, string> environment = null)
|
public BuildCommand(string exe, string argumentsOpt, bool silent, string? workingDirectory = null, IDictionary<string, string>? environment = null)
|
||||||
{
|
{
|
||||||
this.exe = exe;
|
this.exe = exe;
|
||||||
this.arguments = argumentsOpt ?? "";
|
this.arguments = argumentsOpt ?? "";
|
||||||
@@ -131,8 +132,8 @@ namespace Semmle.Autobuild
|
|||||||
class BindBuildScript : BuildScript
|
class BindBuildScript : BuildScript
|
||||||
{
|
{
|
||||||
readonly BuildScript s1;
|
readonly BuildScript s1;
|
||||||
readonly Func<IList<string>, int, BuildScript> s2a;
|
readonly Func<IList<string>, int, BuildScript>? s2a;
|
||||||
readonly Func<int, BuildScript> s2b;
|
readonly Func<int, BuildScript>? s2b;
|
||||||
public BindBuildScript(BuildScript s1, Func<IList<string>, int, BuildScript> s2)
|
public BindBuildScript(BuildScript s1, Func<IList<string>, int, BuildScript> s2)
|
||||||
{
|
{
|
||||||
this.s1 = s1;
|
this.s1 = s1;
|
||||||
@@ -154,14 +155,19 @@ namespace Semmle.Autobuild
|
|||||||
return s2a(stdout1, ret1).Run(actions, startCallback, exitCallBack);
|
return s2a(stdout1, ret1).Run(actions, startCallback, exitCallBack);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret1 = s1.Run(actions, startCallback, exitCallBack);
|
if (s2b != null)
|
||||||
return s2b(ret1).Run(actions, startCallback, exitCallBack);
|
{
|
||||||
|
ret1 = s1.Run(actions, startCallback, exitCallBack);
|
||||||
|
return s2b(ret1).Run(actions, startCallback, exitCallBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InvalidOperationException("Unexpected error");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Run(IBuildActions actions, Action<string, bool> startCallback, Action<int, string, bool> exitCallBack, out IList<string> stdout)
|
public override int Run(IBuildActions actions, Action<string, bool> startCallback, Action<int, string, bool> exitCallBack, out IList<string> stdout)
|
||||||
{
|
{
|
||||||
var ret1 = s1.Run(actions, startCallback, exitCallBack, out var stdout1);
|
var ret1 = s1.Run(actions, startCallback, exitCallBack, out var stdout1);
|
||||||
var ret2 = (s2a != null ? s2a(stdout1, ret1) : s2b(ret1)).Run(actions, startCallback, exitCallBack, out var stdout2);
|
var ret2 = (s2a != null ? s2a(stdout1, ret1) : s2b!(ret1)).Run(actions, startCallback, exitCallBack, out var stdout2);
|
||||||
var @out = new List<string>();
|
var @out = new List<string>();
|
||||||
@out.AddRange(stdout1);
|
@out.AddRange(stdout1);
|
||||||
@out.AddRange(stdout2);
|
@out.AddRange(stdout2);
|
||||||
@@ -177,7 +183,7 @@ namespace Semmle.Autobuild
|
|||||||
/// <param name="silent">Whether the executable should run silently.</param>
|
/// <param name="silent">Whether the executable should run silently.</param>
|
||||||
/// <param name="workingDirectory">The working directory (<code>null</code> for current directory).</param>
|
/// <param name="workingDirectory">The working directory (<code>null</code> for current directory).</param>
|
||||||
/// <param name="environment">Additional environment variables.</param>
|
/// <param name="environment">Additional environment variables.</param>
|
||||||
public static BuildScript Create(string exe, string argumentsOpt, bool silent, string workingDirectory, IDictionary<string, string> environment) =>
|
public static BuildScript Create(string exe, string argumentsOpt, bool silent, string? workingDirectory, IDictionary<string, string>? environment) =>
|
||||||
new BuildCommand(exe, argumentsOpt, silent, workingDirectory, environment);
|
new BuildCommand(exe, argumentsOpt, silent, workingDirectory, environment);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ namespace Semmle.Autobuild
|
|||||||
|
|
||||||
readonly StringBuilder arguments;
|
readonly StringBuilder arguments;
|
||||||
bool firstCommand;
|
bool firstCommand;
|
||||||
string executable;
|
string? executable;
|
||||||
readonly EscapeMode escapingMode;
|
readonly EscapeMode escapingMode;
|
||||||
readonly string workingDirectory;
|
readonly string? workingDirectory;
|
||||||
readonly IDictionary<string, string> environment;
|
readonly IDictionary<string, string>? environment;
|
||||||
readonly bool silent;
|
readonly bool silent;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -25,7 +25,7 @@ namespace Semmle.Autobuild
|
|||||||
/// <param name="workingDirectory">The working directory (<code>null</code> for current directory).</param>
|
/// <param name="workingDirectory">The working directory (<code>null</code> for current directory).</param>
|
||||||
/// <param name="environment">Additional environment variables.</param>
|
/// <param name="environment">Additional environment variables.</param>
|
||||||
/// <param name="silent">Whether this command should be run silently.</param>
|
/// <param name="silent">Whether this command should be run silently.</param>
|
||||||
public CommandBuilder(IBuildActions actions, string workingDirectory = null, IDictionary<string, string> environment = null, bool silent = false)
|
public CommandBuilder(IBuildActions actions, string? workingDirectory = null, IDictionary<string, string>? environment = null, bool silent = false)
|
||||||
{
|
{
|
||||||
arguments = new StringBuilder();
|
arguments = new StringBuilder();
|
||||||
if (actions.IsWindows())
|
if (actions.IsWindows())
|
||||||
@@ -50,7 +50,7 @@ namespace Semmle.Autobuild
|
|||||||
RunCommand(odasa, "index --auto");
|
RunCommand(odasa, "index --auto");
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandBuilder CallBatFile(string batFile, string argumentsOpt = null)
|
public CommandBuilder CallBatFile(string batFile, string? argumentsOpt = null)
|
||||||
{
|
{
|
||||||
NextCommand();
|
NextCommand();
|
||||||
arguments.Append(" CALL");
|
arguments.Append(" CALL");
|
||||||
@@ -66,7 +66,7 @@ namespace Semmle.Autobuild
|
|||||||
/// <param name="command">The command to run.</param>
|
/// <param name="command">The command to run.</param>
|
||||||
/// <param name="argumentsOpt">Additional arguments.</param>
|
/// <param name="argumentsOpt">Additional arguments.</param>
|
||||||
/// <returns>this for chaining calls.</returns>
|
/// <returns>this for chaining calls.</returns>
|
||||||
public CommandBuilder IndexCommand(string odasa, string command, string argumentsOpt = null)
|
public CommandBuilder IndexCommand(string odasa, string command, string? argumentsOpt = null)
|
||||||
{
|
{
|
||||||
OdasaIndex(odasa);
|
OdasaIndex(odasa);
|
||||||
QuoteArgument(command);
|
QuoteArgument(command);
|
||||||
@@ -151,7 +151,7 @@ namespace Semmle.Autobuild
|
|||||||
arguments.Append(' ');
|
arguments.Append(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandBuilder Argument(string argumentsOpt)
|
public CommandBuilder Argument(string? argumentsOpt)
|
||||||
{
|
{
|
||||||
if (argumentsOpt != null)
|
if (argumentsOpt != null)
|
||||||
{
|
{
|
||||||
@@ -169,7 +169,7 @@ namespace Semmle.Autobuild
|
|||||||
arguments.Append(" &&");
|
arguments.Append(" &&");
|
||||||
}
|
}
|
||||||
|
|
||||||
public CommandBuilder RunCommand(string exe, string argumentsOpt = null)
|
public CommandBuilder RunCommand(string exe, string? argumentsOpt = null)
|
||||||
{
|
{
|
||||||
var (exe0, arg0) =
|
var (exe0, arg0) =
|
||||||
escapingMode == EscapeMode.Process && exe.EndsWith(".exe", System.StringComparison.Ordinal)
|
escapingMode == EscapeMode.Process && exe.EndsWith(".exe", System.StringComparison.Ordinal)
|
||||||
@@ -193,6 +193,14 @@ namespace Semmle.Autobuild
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a build script that contains just this command.
|
/// Returns a build script that contains just this command.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BuildScript Script => BuildScript.Create(executable, arguments.ToString(), silent, workingDirectory, environment);
|
public BuildScript Script
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (executable is null)
|
||||||
|
throw new System.InvalidOperationException("executable is null");
|
||||||
|
return BuildScript.Create(executable, arguments.ToString(), silent, workingDirectory, environment);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,13 +56,13 @@ namespace Semmle.Autobuild
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static BuildScript WithDotNet(Autobuilder builder, Func<string, IDictionary<string, string>, bool, BuildScript> f)
|
static BuildScript WithDotNet(Autobuilder builder, Func<string?, IDictionary<string, string>?, bool, BuildScript> f)
|
||||||
{
|
{
|
||||||
var installDir = builder.Actions.PathCombine(builder.Options.RootDirectory, ".dotnet");
|
string? installDir = builder.Actions.PathCombine(builder.Options.RootDirectory, ".dotnet");
|
||||||
var installScript = DownloadDotNet(builder, installDir);
|
var installScript = DownloadDotNet(builder, installDir);
|
||||||
return BuildScript.Bind(installScript, installed =>
|
return BuildScript.Bind(installScript, installed =>
|
||||||
{
|
{
|
||||||
Dictionary<string, string> env;
|
Dictionary<string, string>? env;
|
||||||
if (installed == 0)
|
if (installed == 0)
|
||||||
{
|
{
|
||||||
// The installation succeeded, so use the newly installed .NET Core
|
// The installation succeeded, so use the newly installed .NET Core
|
||||||
@@ -120,7 +120,7 @@ namespace Semmle.Autobuild
|
|||||||
/// variables needed by the installed .NET Core (<code>null</code> when no variables
|
/// variables needed by the installed .NET Core (<code>null</code> when no variables
|
||||||
/// are needed).
|
/// are needed).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static BuildScript WithDotNet(Autobuilder builder, Func<IDictionary<string, string>, BuildScript> f)
|
public static BuildScript WithDotNet(Autobuilder builder, Func<IDictionary<string, string>?, BuildScript> f)
|
||||||
=> WithDotNet(builder, (_1, env, _2) => f(env));
|
=> WithDotNet(builder, (_1, env, _2) => f(env));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -265,10 +265,10 @@ Invoke-Command -ScriptBlock $ScriptBlock";
|
|||||||
return listSdks.Script;
|
return listSdks.Script;
|
||||||
}
|
}
|
||||||
|
|
||||||
static string DotNetCommand(IBuildActions actions, string dotNetPath) =>
|
static string DotNetCommand(IBuildActions actions, string? dotNetPath) =>
|
||||||
dotNetPath != null ? actions.PathCombine(dotNetPath, "dotnet") : "dotnet";
|
dotNetPath != null ? actions.PathCombine(dotNetPath, "dotnet") : "dotnet";
|
||||||
|
|
||||||
BuildScript GetInfoCommand(IBuildActions actions, string dotNetPath, IDictionary<string, string> environment)
|
BuildScript GetInfoCommand(IBuildActions actions, string? dotNetPath, IDictionary<string, string>? environment)
|
||||||
{
|
{
|
||||||
var info = new CommandBuilder(actions, null, environment).
|
var info = new CommandBuilder(actions, null, environment).
|
||||||
RunCommand(DotNetCommand(actions, dotNetPath)).
|
RunCommand(DotNetCommand(actions, dotNetPath)).
|
||||||
@@ -276,7 +276,7 @@ Invoke-Command -ScriptBlock $ScriptBlock";
|
|||||||
return info.Script;
|
return info.Script;
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandBuilder GetCleanCommand(IBuildActions actions, string dotNetPath, IDictionary<string, string> environment)
|
CommandBuilder GetCleanCommand(IBuildActions actions, string? dotNetPath, IDictionary<string, string>? environment)
|
||||||
{
|
{
|
||||||
var clean = new CommandBuilder(actions, null, environment).
|
var clean = new CommandBuilder(actions, null, environment).
|
||||||
RunCommand(DotNetCommand(actions, dotNetPath)).
|
RunCommand(DotNetCommand(actions, dotNetPath)).
|
||||||
@@ -284,7 +284,7 @@ Invoke-Command -ScriptBlock $ScriptBlock";
|
|||||||
return clean;
|
return clean;
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandBuilder GetRestoreCommand(IBuildActions actions, string dotNetPath, IDictionary<string, string> environment)
|
CommandBuilder GetRestoreCommand(IBuildActions actions, string? dotNetPath, IDictionary<string, string>? environment)
|
||||||
{
|
{
|
||||||
var restore = new CommandBuilder(actions, null, environment).
|
var restore = new CommandBuilder(actions, null, environment).
|
||||||
RunCommand(DotNetCommand(actions, dotNetPath)).
|
RunCommand(DotNetCommand(actions, dotNetPath)).
|
||||||
@@ -292,7 +292,7 @@ Invoke-Command -ScriptBlock $ScriptBlock";
|
|||||||
return restore;
|
return restore;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BuildScript GetInstalledRuntimesScript(IBuildActions actions, string dotNetPath, IDictionary<string, string> environment)
|
static BuildScript GetInstalledRuntimesScript(IBuildActions actions, string? dotNetPath, IDictionary<string, string>? environment)
|
||||||
{
|
{
|
||||||
var listSdks = new CommandBuilder(actions, environment: environment, silent: true).
|
var listSdks = new CommandBuilder(actions, environment: environment, silent: true).
|
||||||
RunCommand(DotNetCommand(actions, dotNetPath)).
|
RunCommand(DotNetCommand(actions, dotNetPath)).
|
||||||
@@ -309,7 +309,7 @@ Invoke-Command -ScriptBlock $ScriptBlock";
|
|||||||
/// hence the need for CLR tracing), by adding a
|
/// hence the need for CLR tracing), by adding a
|
||||||
/// `/p:UseSharedCompilation=false` argument.
|
/// `/p:UseSharedCompilation=false` argument.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
BuildScript GetBuildScript(Autobuilder builder, string dotNetPath, IDictionary<string, string> environment, bool compatibleClr, string projOrSln)
|
BuildScript GetBuildScript(Autobuilder builder, string? dotNetPath, IDictionary<string, string>? environment, bool compatibleClr, string projOrSln)
|
||||||
{
|
{
|
||||||
var build = new CommandBuilder(builder.Actions, null, environment);
|
var build = new CommandBuilder(builder.Actions, null, environment);
|
||||||
var script = builder.MaybeIndex(build, DotNetCommand(builder.Actions, dotNetPath)).
|
var script = builder.MaybeIndex(build, DotNetCommand(builder.Actions, dotNetPath)).
|
||||||
|
|||||||
@@ -67,10 +67,10 @@ namespace Semmle.Autobuild
|
|||||||
string target = builder.Options.MsBuildTarget != null
|
string target = builder.Options.MsBuildTarget != null
|
||||||
? builder.Options.MsBuildTarget
|
? builder.Options.MsBuildTarget
|
||||||
: "rebuild";
|
: "rebuild";
|
||||||
string platform = builder.Options.MsBuildPlatform != null
|
string? platform = builder.Options.MsBuildPlatform != null
|
||||||
? builder.Options.MsBuildPlatform
|
? builder.Options.MsBuildPlatform
|
||||||
: projectOrSolution is ISolution s1 ? s1.DefaultPlatformName : null;
|
: projectOrSolution is ISolution s1 ? s1.DefaultPlatformName : null;
|
||||||
string configuration = builder.Options.MsBuildConfiguration != null
|
string? configuration = builder.Options.MsBuildConfiguration != null
|
||||||
? builder.Options.MsBuildConfiguration
|
? builder.Options.MsBuildConfiguration
|
||||||
: projectOrSolution is ISolution s2 ? s2.DefaultConfigurationName : null;
|
: projectOrSolution is ISolution s2 ? s2.DefaultConfigurationName : null;
|
||||||
|
|
||||||
@@ -96,9 +96,9 @@ namespace Semmle.Autobuild
|
|||||||
///
|
///
|
||||||
/// Returns <code>null</code> when no version is specified.
|
/// Returns <code>null</code> when no version is specified.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static VcVarsBatFile GetVcVarsBatFile(Autobuilder builder)
|
public static VcVarsBatFile? GetVcVarsBatFile(Autobuilder builder)
|
||||||
{
|
{
|
||||||
VcVarsBatFile vsTools = null;
|
VcVarsBatFile? vsTools = null;
|
||||||
|
|
||||||
if (builder.Options.VsToolsVersion != null)
|
if (builder.Options.VsToolsVersion != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,23 +6,27 @@ namespace Semmle.Autobuild
|
|||||||
{
|
{
|
||||||
static int Main()
|
static int Main()
|
||||||
{
|
{
|
||||||
var options = new AutobuildOptions();
|
|
||||||
var actions = SystemBuildActions.Instance;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
options.ReadEnvironment(actions);
|
var actions = SystemBuildActions.Instance;
|
||||||
|
var options = new AutobuildOptions(actions);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Console.WriteLine($"Semmle autobuilder for {options.Language}");
|
||||||
|
var builder = new Autobuilder(actions, options);
|
||||||
|
return builder.AttemptBuild();
|
||||||
|
}
|
||||||
|
catch(InvalidEnvironmentException ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine("The environment is invalid: {0}", ex.Message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (ArgumentOutOfRangeException ex)
|
catch (ArgumentOutOfRangeException ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine("The value \"{0}\" for parameter \"{1}\" is invalid", ex.ActualValue, ex.ParamName);
|
Console.WriteLine("The value \"{0}\" for parameter \"{1}\" is invalid", ex.ActualValue, ex.ParamName);
|
||||||
}
|
}
|
||||||
|
return 1;
|
||||||
var builder = new Autobuilder(actions, options);
|
|
||||||
|
|
||||||
Console.WriteLine($"Semmle autobuilder for {options.Language}");
|
|
||||||
|
|
||||||
return builder.AttemptBuild();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ namespace Semmle.Autobuild
|
|||||||
foreach (var include in projectFileIncludes.Concat(projectFilesIncludes))
|
foreach (var include in projectFileIncludes.Concat(projectFilesIncludes))
|
||||||
{
|
{
|
||||||
var includePath = builder.Actions.PathCombine(include.Value.Split('\\', StringSplitOptions.RemoveEmptyEntries));
|
var includePath = builder.Actions.PathCombine(include.Value.Split('\\', StringSplitOptions.RemoveEmptyEntries));
|
||||||
ret.Add(new Project(builder, builder.Actions.PathCombine(Path.GetDirectoryName(this.FullPath), includePath)));
|
ret.Add(new Project(builder, builder.Actions.PathCombine(DirectoryName, includePath)));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Semmle.Autobuild
|
namespace Semmle.Autobuild
|
||||||
@@ -24,6 +25,8 @@ namespace Semmle.Autobuild
|
|||||||
{
|
{
|
||||||
public string FullPath { get; private set; }
|
public string FullPath { get; private set; }
|
||||||
|
|
||||||
|
public string DirectoryName => Path.GetDirectoryName(FullPath) ?? "";
|
||||||
|
|
||||||
protected ProjectOrSolution(Autobuilder builder, string path)
|
protected ProjectOrSolution(Autobuilder builder, string path)
|
||||||
{
|
{
|
||||||
FullPath = builder.Actions.GetFullPath(path);
|
FullPath = builder.Actions.GetFullPath(path);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
<StartupObject />
|
<StartupObject />
|
||||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||||
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x64;linux-x64;osx-x64</RuntimeIdentifiers>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ namespace Semmle.Autobuild
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
class Solution : ProjectOrSolution, ISolution
|
class Solution : ProjectOrSolution, ISolution
|
||||||
{
|
{
|
||||||
readonly SolutionFile solution;
|
readonly SolutionFile? solution;
|
||||||
|
|
||||||
readonly IEnumerable<Project> includedProjects;
|
readonly IEnumerable<Project> includedProjects;
|
||||||
public override IEnumerable<IProjectOrSolution> IncludedProjects => includedProjects;
|
public override IEnumerable<IProjectOrSolution> IncludedProjects => includedProjects;
|
||||||
@@ -81,7 +81,7 @@ namespace Semmle.Autobuild
|
|||||||
includedProjects =
|
includedProjects =
|
||||||
solution.ProjectsInOrder.
|
solution.ProjectsInOrder.
|
||||||
Where(p => p.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat).
|
Where(p => p.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat).
|
||||||
Select(p => builder.Actions.PathCombine(Path.GetDirectoryName(path), builder.Actions.PathCombine(p.RelativePath.Split('\\', StringSplitOptions.RemoveEmptyEntries)))).
|
Select(p => builder.Actions.PathCombine(DirectoryName, builder.Actions.PathCombine(p.RelativePath.Split('\\', StringSplitOptions.RemoveEmptyEntries)))).
|
||||||
Select(p => new Project(builder, p)).
|
Select(p => new Project(builder, p)).
|
||||||
ToArray();
|
ToArray();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using System.IO;
|
namespace Semmle.Autobuild
|
||||||
|
|
||||||
namespace Semmle.Autobuild
|
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Build using standalone extraction.
|
/// Build using standalone extraction.
|
||||||
@@ -9,8 +7,11 @@ namespace Semmle.Autobuild
|
|||||||
{
|
{
|
||||||
public BuildScript Analyse(Autobuilder builder, bool auto)
|
public BuildScript Analyse(Autobuilder builder, bool auto)
|
||||||
{
|
{
|
||||||
BuildScript GetCommand(string solution)
|
BuildScript GetCommand(string? solution)
|
||||||
{
|
{
|
||||||
|
if (builder.SemmlePlatformTools is null)
|
||||||
|
return BuildScript.Failure;
|
||||||
|
|
||||||
var standalone = builder.Actions.PathCombine(builder.SemmlePlatformTools, "csharp", "Semmle.Extraction.CSharp.Standalone");
|
var standalone = builder.Actions.PathCombine(builder.SemmlePlatformTools, "csharp", "Semmle.Extraction.CSharp.Standalone");
|
||||||
var cmd = new CommandBuilder(builder.Actions);
|
var cmd = new CommandBuilder(builder.Actions);
|
||||||
cmd.RunCommand(standalone);
|
cmd.RunCommand(standalone);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
{
|
{
|
||||||
public BuildScript Analyse(Autobuilder builder, bool auto)
|
public BuildScript Analyse(Autobuilder builder, bool auto)
|
||||||
{
|
{
|
||||||
if (!builder.Options.Indexing)
|
if (!builder.Options.Indexing || builder.Odasa is null)
|
||||||
return BuildScript.Success;
|
return BuildScript.Success;
|
||||||
|
|
||||||
var command = new CommandBuilder(builder.Actions).
|
var command = new CommandBuilder(builder.Actions).
|
||||||
|
|||||||
@@ -163,7 +163,19 @@ namespace Semmle.BuildAnalyser
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="filepath">The filename to query.</param>
|
/// <param name="filepath">The filename to query.</param>
|
||||||
/// <returns>The assembly info.</returns>
|
/// <returns>The assembly info.</returns>
|
||||||
public AssemblyInfo GetAssemblyInfo(string filepath) => assemblyInfo[filepath];
|
public AssemblyInfo GetAssemblyInfo(string filepath)
|
||||||
|
{
|
||||||
|
if(assemblyInfo.TryGetValue(filepath, out var info))
|
||||||
|
{
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info = AssemblyInfo.ReadFromFile(filepath);
|
||||||
|
assemblyInfo.Add(filepath, info);
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// List of pending DLLs to index.
|
// List of pending DLLs to index.
|
||||||
readonly List<string> dlls = new List<string>();
|
readonly List<string> dlls = new List<string>();
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
using System;
|
using Semmle.Util;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using Semmle.Util;
|
|
||||||
using Semmle.Extraction.CSharp.Standalone;
|
using Semmle.Extraction.CSharp.Standalone;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Text;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
namespace Semmle.BuildAnalyser
|
namespace Semmle.BuildAnalyser
|
||||||
{
|
{
|
||||||
@@ -43,19 +46,18 @@ namespace Semmle.BuildAnalyser
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Main implementation of the build analysis.
|
/// Main implementation of the build analysis.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class BuildAnalysis : IBuildAnalysis
|
class BuildAnalysis : IBuildAnalysis, IDisposable
|
||||||
{
|
{
|
||||||
readonly AssemblyCache assemblyCache;
|
private readonly AssemblyCache assemblyCache;
|
||||||
readonly NugetPackages nuget;
|
private readonly NugetPackages nuget;
|
||||||
readonly IProgressMonitor progressMonitor;
|
private readonly IProgressMonitor progressMonitor;
|
||||||
HashSet<string> usedReferences = new HashSet<string>();
|
private readonly IDictionary<string, bool> usedReferences = new ConcurrentDictionary<string, bool>();
|
||||||
readonly HashSet<string> usedSources = new HashSet<string>();
|
private readonly IDictionary<string, bool> sources = new ConcurrentDictionary<string, bool>();
|
||||||
readonly HashSet<string> missingSources = new HashSet<string>();
|
private readonly IDictionary<string, string> unresolvedReferences = new ConcurrentDictionary<string, string>();
|
||||||
readonly Dictionary<string, string> unresolvedReferences = new Dictionary<string, string>();
|
private readonly DirectoryInfo sourceDir;
|
||||||
readonly DirectoryInfo sourceDir;
|
private int failedProjects, succeededProjects;
|
||||||
int failedProjects, succeededProjects;
|
private readonly string[] allSources;
|
||||||
readonly string[] allSources;
|
private int conflictedReferences = 0;
|
||||||
int conflictedReferences = 0;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs a C# build analysis.
|
/// Performs a C# build analysis.
|
||||||
@@ -64,6 +66,8 @@ namespace Semmle.BuildAnalyser
|
|||||||
/// <param name="progress">Display of analysis progress.</param>
|
/// <param name="progress">Display of analysis progress.</param>
|
||||||
public BuildAnalysis(Options options, IProgressMonitor progress)
|
public BuildAnalysis(Options options, IProgressMonitor progress)
|
||||||
{
|
{
|
||||||
|
var startTime = DateTime.Now;
|
||||||
|
|
||||||
progressMonitor = progress;
|
progressMonitor = progress;
|
||||||
sourceDir = new DirectoryInfo(options.SrcDir);
|
sourceDir = new DirectoryInfo(options.SrcDir);
|
||||||
|
|
||||||
@@ -74,36 +78,43 @@ namespace Semmle.BuildAnalyser
|
|||||||
Where(d => !options.ExcludesFile(d)).
|
Where(d => !options.ExcludesFile(d)).
|
||||||
ToArray();
|
ToArray();
|
||||||
|
|
||||||
var dllDirNames = options.DllDirs.Select(Path.GetFullPath);
|
var dllDirNames = options.DllDirs.Select(Path.GetFullPath).ToList();
|
||||||
|
PackageDirectory = new TemporaryDirectory(ComputeTempDirectory(sourceDir.FullName));
|
||||||
|
|
||||||
if (options.UseNuGet)
|
if (options.UseNuGet)
|
||||||
{
|
{
|
||||||
nuget = new NugetPackages(sourceDir.FullName);
|
try
|
||||||
ReadNugetFiles();
|
{
|
||||||
dllDirNames = dllDirNames.Concat(Enumerators.Singleton(nuget.PackageDirectory));
|
nuget = new NugetPackages(sourceDir.FullName, PackageDirectory);
|
||||||
|
ReadNugetFiles();
|
||||||
|
}
|
||||||
|
catch(FileNotFoundException)
|
||||||
|
{
|
||||||
|
progressMonitor.MissingNuGet();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find DLLs in the .Net Framework
|
// Find DLLs in the .Net Framework
|
||||||
if (options.ScanNetFrameworkDlls)
|
if (options.ScanNetFrameworkDlls)
|
||||||
{
|
{
|
||||||
dllDirNames = dllDirNames.Concat(Runtime.Runtimes.Take(1));
|
dllDirNames.Add(Runtime.Runtimes.First());
|
||||||
}
|
}
|
||||||
|
|
||||||
assemblyCache = new BuildAnalyser.AssemblyCache(dllDirNames, progress);
|
// These files can sometimes prevent `dotnet restore` from working correctly.
|
||||||
|
using (new FileRenamer(sourceDir.GetFiles("global.json", SearchOption.AllDirectories)))
|
||||||
|
using (new FileRenamer(sourceDir.GetFiles("Directory.Build.props", SearchOption.AllDirectories)))
|
||||||
|
{
|
||||||
|
var solutions = options.SolutionFile != null ?
|
||||||
|
new[] { options.SolutionFile } :
|
||||||
|
sourceDir.GetFiles("*.sln", SearchOption.AllDirectories).Select(d => d.FullName);
|
||||||
|
|
||||||
// Analyse all .csproj files in the source tree.
|
RestoreSolutions(solutions);
|
||||||
if (options.SolutionFile != null)
|
dllDirNames.Add(PackageDirectory.DirInfo.FullName);
|
||||||
{
|
assemblyCache = new BuildAnalyser.AssemblyCache(dllDirNames, progress);
|
||||||
AnalyseSolution(options.SolutionFile);
|
AnalyseSolutions(solutions);
|
||||||
}
|
|
||||||
else if (options.AnalyseCsProjFiles)
|
|
||||||
{
|
|
||||||
AnalyseProjectFiles();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!options.AnalyseCsProjFiles)
|
foreach (var filename in assemblyCache.AllAssemblies.Select(a => a.Filename))
|
||||||
{
|
UseReference(filename);
|
||||||
usedReferences = new HashSet<string>(assemblyCache.AllAssemblies.Select(a => a.Filename));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ResolveConflicts();
|
ResolveConflicts();
|
||||||
@@ -114,7 +125,7 @@ namespace Semmle.BuildAnalyser
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Output the findings
|
// Output the findings
|
||||||
foreach (var r in usedReferences)
|
foreach (var r in usedReferences.Keys)
|
||||||
{
|
{
|
||||||
progressMonitor.ResolvedReference(r);
|
progressMonitor.ResolvedReference(r);
|
||||||
}
|
}
|
||||||
@@ -132,7 +143,27 @@ namespace Semmle.BuildAnalyser
|
|||||||
UnresolvedReferences.Count(),
|
UnresolvedReferences.Count(),
|
||||||
conflictedReferences,
|
conflictedReferences,
|
||||||
succeededProjects + failedProjects,
|
succeededProjects + failedProjects,
|
||||||
failedProjects);
|
failedProjects,
|
||||||
|
DateTime.Now - startTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Computes a unique temp directory for the packages associated
|
||||||
|
/// with this source tree. Use a SHA1 of the directory name.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="srcDir"></param>
|
||||||
|
/// <returns>The full path of the temp directory.</returns>
|
||||||
|
private static string ComputeTempDirectory(string srcDir)
|
||||||
|
{
|
||||||
|
var bytes = Encoding.Unicode.GetBytes(srcDir);
|
||||||
|
|
||||||
|
using var sha1 = new SHA1CryptoServiceProvider();
|
||||||
|
var sha = sha1.ComputeHash(bytes);
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
foreach (var b in sha.Take(8))
|
||||||
|
sb.AppendFormat("{0:x2}", b);
|
||||||
|
|
||||||
|
return Path.Combine(Path.GetTempPath(), "GitHub", "packages", sb.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -143,7 +174,7 @@ namespace Semmle.BuildAnalyser
|
|||||||
void ResolveConflicts()
|
void ResolveConflicts()
|
||||||
{
|
{
|
||||||
var sortedReferences = usedReferences.
|
var sortedReferences = usedReferences.
|
||||||
Select(r => assemblyCache.GetAssemblyInfo(r)).
|
Select(r => assemblyCache.GetAssemblyInfo(r.Key)).
|
||||||
OrderBy(r => r.Version).
|
OrderBy(r => r.Version).
|
||||||
ToArray();
|
ToArray();
|
||||||
|
|
||||||
@@ -154,7 +185,9 @@ namespace Semmle.BuildAnalyser
|
|||||||
finalAssemblyList[r.Name] = r;
|
finalAssemblyList[r.Name] = r;
|
||||||
|
|
||||||
// Update the used references list
|
// Update the used references list
|
||||||
usedReferences = new HashSet<string>(finalAssemblyList.Select(r => r.Value.Filename));
|
usedReferences.Clear();
|
||||||
|
foreach (var r in finalAssemblyList.Select(r => r.Value.Filename))
|
||||||
|
UseReference(r);
|
||||||
|
|
||||||
// Report the results
|
// Report the results
|
||||||
foreach (var r in sortedReferences)
|
foreach (var r in sortedReferences)
|
||||||
@@ -183,7 +216,7 @@ namespace Semmle.BuildAnalyser
|
|||||||
/// <param name="reference">The filename of the reference.</param>
|
/// <param name="reference">The filename of the reference.</param>
|
||||||
void UseReference(string reference)
|
void UseReference(string reference)
|
||||||
{
|
{
|
||||||
usedReferences.Add(reference);
|
usedReferences[reference] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -192,25 +225,18 @@ namespace Semmle.BuildAnalyser
|
|||||||
/// <param name="sourceFile">The source file.</param>
|
/// <param name="sourceFile">The source file.</param>
|
||||||
void UseSource(FileInfo sourceFile)
|
void UseSource(FileInfo sourceFile)
|
||||||
{
|
{
|
||||||
if (sourceFile.Exists)
|
sources[sourceFile.FullName] = sourceFile.Exists;
|
||||||
{
|
|
||||||
usedSources.Add(sourceFile.FullName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
missingSources.Add(sourceFile.FullName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of resolved reference files.
|
/// The list of resolved reference files.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IEnumerable<string> ReferenceFiles => this.usedReferences;
|
public IEnumerable<string> ReferenceFiles => this.usedReferences.Keys;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of source files used in projects.
|
/// The list of source files used in projects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IEnumerable<string> ProjectSourceFiles => usedSources;
|
public IEnumerable<string> ProjectSourceFiles => sources.Where(s => s.Value).Select(s => s.Key);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// All of the source files in the source directory.
|
/// All of the source files in the source directory.
|
||||||
@@ -226,7 +252,7 @@ namespace Semmle.BuildAnalyser
|
|||||||
/// List of source files which were mentioned in project files but
|
/// List of source files which were mentioned in project files but
|
||||||
/// do not exist on the file system.
|
/// do not exist on the file system.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IEnumerable<string> MissingSourceFiles => missingSources;
|
public IEnumerable<string> MissingSourceFiles => sources.Where(s => !s.Value).Select(s => s.Key);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Record that a particular reference couldn't be resolved.
|
/// Record that a particular reference couldn't be resolved.
|
||||||
@@ -239,74 +265,101 @@ namespace Semmle.BuildAnalyser
|
|||||||
unresolvedReferences[id] = projectFile;
|
unresolvedReferences[id] = projectFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
readonly TemporaryDirectory PackageDirectory;
|
||||||
/// Performs an analysis of all .csproj files.
|
|
||||||
/// </summary>
|
|
||||||
void AnalyseProjectFiles()
|
|
||||||
{
|
|
||||||
AnalyseProjectFiles(sourceDir.GetFiles("*.csproj", SearchOption.AllDirectories));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads all the source files and references from the given list of projects.
|
/// Reads all the source files and references from the given list of projects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="projectFiles">The list of projects to analyse.</param>
|
/// <param name="projectFiles">The list of projects to analyse.</param>
|
||||||
void AnalyseProjectFiles(FileInfo[] projectFiles)
|
void AnalyseProjectFiles(IEnumerable<FileInfo> projectFiles)
|
||||||
{
|
{
|
||||||
progressMonitor.AnalysingProjectFiles(projectFiles.Count());
|
|
||||||
|
|
||||||
foreach (var proj in projectFiles)
|
foreach (var proj in projectFiles)
|
||||||
|
AnalyseProject(proj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalyseProject(FileInfo project)
|
||||||
|
{
|
||||||
|
if(!project.Exists)
|
||||||
{
|
{
|
||||||
try
|
progressMonitor.MissingProject(project.FullName);
|
||||||
{
|
return;
|
||||||
var csProj = new CsProjFile(proj);
|
}
|
||||||
|
|
||||||
foreach (var @ref in csProj.References)
|
try
|
||||||
{
|
{
|
||||||
AssemblyInfo resolved = assemblyCache.ResolveReference(@ref);
|
var csProj = new CsProjFile(project);
|
||||||
if (!resolved.Valid)
|
|
||||||
{
|
|
||||||
UnresolvedReference(@ref, proj.FullName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UseReference(resolved.Filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var src in csProj.Sources)
|
foreach (var @ref in csProj.References)
|
||||||
{
|
|
||||||
// Make a note of which source files the projects use.
|
|
||||||
// This information doesn't affect the build but is dumped
|
|
||||||
// as diagnostic output.
|
|
||||||
UseSource(new FileInfo(src));
|
|
||||||
}
|
|
||||||
++succeededProjects;
|
|
||||||
}
|
|
||||||
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
|
|
||||||
{
|
{
|
||||||
++failedProjects;
|
AssemblyInfo resolved = assemblyCache.ResolveReference(@ref);
|
||||||
progressMonitor.FailedProjectFile(proj.FullName, ex.Message);
|
if (!resolved.Valid)
|
||||||
|
{
|
||||||
|
UnresolvedReference(@ref, project.FullName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UseReference(resolved.Filename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var src in csProj.Sources)
|
||||||
|
{
|
||||||
|
// Make a note of which source files the projects use.
|
||||||
|
// This information doesn't affect the build but is dumped
|
||||||
|
// as diagnostic output.
|
||||||
|
UseSource(new FileInfo(src));
|
||||||
|
}
|
||||||
|
|
||||||
|
++succeededProjects;
|
||||||
|
}
|
||||||
|
catch (Exception ex) // lgtm[cs/catch-of-all-exceptions]
|
||||||
|
{
|
||||||
|
++failedProjects;
|
||||||
|
progressMonitor.FailedProjectFile(project.FullName, ex.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Restore(string projectOrSolution)
|
||||||
|
{
|
||||||
|
int exit = DotNet.RestoreToDirectory(projectOrSolution, PackageDirectory.DirInfo.FullName);
|
||||||
|
switch(exit)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
// No errors
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
progressMonitor.CommandFailed("dotnet", $"restore \"{projectOrSolution}\"", exit);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public void RestoreSolutions(IEnumerable<string> solutions)
|
||||||
/// Delete packages directory.
|
|
||||||
/// </summary>
|
|
||||||
public void Cleanup()
|
|
||||||
{
|
{
|
||||||
if (nuget != null) nuget.Cleanup(progressMonitor);
|
Parallel.ForEach(solutions, new ParallelOptions { MaxDegreeOfParallelism = 4 }, Restore);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public void AnalyseSolutions(IEnumerable<string> solutions)
|
||||||
/// Analyse all project files in a given solution only.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="solutionFile">The filename of the solution.</param>
|
|
||||||
public void AnalyseSolution(string solutionFile)
|
|
||||||
{
|
{
|
||||||
var sln = new SolutionFile(solutionFile);
|
Parallel.ForEach(solutions, new ParallelOptions { MaxDegreeOfParallelism = 4 } , solutionFile =>
|
||||||
AnalyseProjectFiles(sln.Projects.Select(p => new FileInfo(p)).ToArray());
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var sln = new SolutionFile(solutionFile);
|
||||||
|
progressMonitor.AnalysingSolution(solutionFile);
|
||||||
|
AnalyseProjectFiles(sln.Projects.Select(p => new FileInfo(p)).Where(p => p.Exists));
|
||||||
|
}
|
||||||
|
catch (Microsoft.Build.Exceptions.InvalidProjectFileException ex)
|
||||||
|
{
|
||||||
|
progressMonitor.FailedProjectFile(solutionFile, ex.BaseMessage);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
PackageDirectory?.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,12 +10,18 @@ namespace Semmle.BuildAnalyser
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
class CsProjFile
|
class CsProjFile
|
||||||
{
|
{
|
||||||
|
private string Filename { get; }
|
||||||
|
|
||||||
|
private string Directory => Path.GetDirectoryName(Filename);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads the .csproj file.
|
/// Reads the .csproj file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="filename">The .csproj file.</param>
|
/// <param name="filename">The .csproj file.</param>
|
||||||
public CsProjFile(FileInfo filename)
|
public CsProjFile(FileInfo filename)
|
||||||
{
|
{
|
||||||
|
Filename = filename.FullName;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// This can fail if the .csproj is invalid or has
|
// This can fail if the .csproj is invalid or has
|
||||||
@@ -39,7 +45,7 @@ namespace Semmle.BuildAnalyser
|
|||||||
/// and there seems to be no way to make it succeed. Fails on Linux.
|
/// and there seems to be no way to make it succeed. Fails on Linux.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="filename">The file to read.</param>
|
/// <param name="filename">The file to read.</param>
|
||||||
public void ReadMsBuildProject(FileInfo filename)
|
private void ReadMsBuildProject(FileInfo filename)
|
||||||
{
|
{
|
||||||
var msbuildProject = new Microsoft.Build.Execution.ProjectInstance(filename.FullName);
|
var msbuildProject = new Microsoft.Build.Execution.ProjectInstance(filename.FullName);
|
||||||
|
|
||||||
@@ -62,7 +68,7 @@ namespace Semmle.BuildAnalyser
|
|||||||
/// fallback if ReadMsBuildProject() fails.
|
/// fallback if ReadMsBuildProject() fails.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="filename">The .csproj file.</param>
|
/// <param name="filename">The .csproj file.</param>
|
||||||
public void ReadProjectFileAsXml(FileInfo filename)
|
private void ReadProjectFileAsXml(FileInfo filename)
|
||||||
{
|
{
|
||||||
var projFile = new XmlDocument();
|
var projFile = new XmlDocument();
|
||||||
var mgr = new XmlNamespaceManager(projFile.NameTable);
|
var mgr = new XmlNamespaceManager(projFile.NameTable);
|
||||||
@@ -71,22 +77,48 @@ namespace Semmle.BuildAnalyser
|
|||||||
var projDir = filename.Directory;
|
var projDir = filename.Directory;
|
||||||
var root = projFile.DocumentElement;
|
var root = projFile.DocumentElement;
|
||||||
|
|
||||||
references =
|
// Figure out if it's dotnet core
|
||||||
root.SelectNodes("/msbuild:Project/msbuild:ItemGroup/msbuild:Reference/@Include", mgr).
|
|
||||||
NodeList().
|
|
||||||
Select(node => node.Value).
|
|
||||||
ToArray();
|
|
||||||
|
|
||||||
var relativeCsIncludes =
|
bool netCoreProjectFile = root.GetAttribute("Sdk") == "Microsoft.NET.Sdk";
|
||||||
root.SelectNodes("/msbuild:Project/msbuild:ItemGroup/msbuild:Compile/@Include", mgr).
|
|
||||||
NodeList().
|
|
||||||
Select(node => node.Value).
|
|
||||||
ToArray();
|
|
||||||
|
|
||||||
csFiles = relativeCsIncludes.
|
if (netCoreProjectFile)
|
||||||
Select(cs => Path.DirectorySeparatorChar == '/' ? cs.Replace("\\", "/") : cs).
|
{
|
||||||
Select(f => Path.GetFullPath(Path.Combine(projDir.FullName, f))).
|
var relativeCsIncludes =
|
||||||
ToArray();
|
root.SelectNodes("/Project/ItemGroup/Compile/@Include", mgr).
|
||||||
|
NodeList().
|
||||||
|
Select(node => node.Value).
|
||||||
|
ToArray();
|
||||||
|
|
||||||
|
var explicitCsFiles = relativeCsIncludes.
|
||||||
|
Select(cs => Path.DirectorySeparatorChar == '/' ? cs.Replace("\\", "/") : cs).
|
||||||
|
Select(f => Path.GetFullPath(Path.Combine(projDir.FullName, f)));
|
||||||
|
|
||||||
|
var additionalCsFiles = System.IO.Directory.GetFiles(Directory, "*.cs", SearchOption.AllDirectories);
|
||||||
|
|
||||||
|
csFiles = explicitCsFiles.Concat(additionalCsFiles).ToArray();
|
||||||
|
|
||||||
|
references = new string[0];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
references =
|
||||||
|
root.SelectNodes("/msbuild:Project/msbuild:ItemGroup/msbuild:Reference/@Include", mgr).
|
||||||
|
NodeList().
|
||||||
|
Select(node => node.Value).
|
||||||
|
ToArray();
|
||||||
|
|
||||||
|
var relativeCsIncludes =
|
||||||
|
root.SelectNodes("/msbuild:Project/msbuild:ItemGroup/msbuild:Compile/@Include", mgr).
|
||||||
|
NodeList().
|
||||||
|
Select(node => node.Value).
|
||||||
|
ToArray();
|
||||||
|
|
||||||
|
csFiles = relativeCsIncludes.
|
||||||
|
Select(cs => Path.DirectorySeparatorChar == '/' ? cs.Replace("\\", "/") : cs).
|
||||||
|
Select(f => Path.GetFullPath(Path.Combine(projDir.FullName, f))).
|
||||||
|
ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string[] references;
|
string[] references;
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Semmle.BuildAnalyser
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Utilities to run the "dotnet" command.
|
||||||
|
/// </summary>
|
||||||
|
static class DotNet
|
||||||
|
{
|
||||||
|
public static int RestoreToDirectory(string projectOrSolutionFile, string packageDirectory)
|
||||||
|
{
|
||||||
|
using var proc = Process.Start("dotnet", $"restore --no-dependencies \"{projectOrSolutionFile}\" --packages \"{packageDirectory}\" /p:DisableImplicitNuGetFallbackFolder=true");
|
||||||
|
proc.WaitForExit();
|
||||||
|
return proc.ExitCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
using System;
|
using Semmle.Util;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Semmle.BuildAnalyser
|
namespace Semmle.BuildAnalyser
|
||||||
{
|
{
|
||||||
@@ -19,10 +18,10 @@ namespace Semmle.BuildAnalyser
|
|||||||
/// Create the package manager for a specified source tree.
|
/// Create the package manager for a specified source tree.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sourceDir">The source directory.</param>
|
/// <param name="sourceDir">The source directory.</param>
|
||||||
public NugetPackages(string sourceDir)
|
public NugetPackages(string sourceDir, TemporaryDirectory packageDirectory)
|
||||||
{
|
{
|
||||||
SourceDirectory = sourceDir;
|
SourceDirectory = sourceDir;
|
||||||
PackageDirectory = computeTempDirectory(sourceDir);
|
PackageDirectory = packageDirectory;
|
||||||
|
|
||||||
// Expect nuget.exe to be in a `nuget` directory under the directory containing this exe.
|
// Expect nuget.exe to be in a `nuget` directory under the directory containing this exe.
|
||||||
var currentAssembly = System.Reflection.Assembly.GetExecutingAssembly().Location;
|
var currentAssembly = System.Reflection.Assembly.GetExecutingAssembly().Location;
|
||||||
@@ -50,45 +49,12 @@ namespace Semmle.BuildAnalyser
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public IEnumerable<FileInfo> PackageFiles => packages;
|
public IEnumerable<FileInfo> PackageFiles => packages;
|
||||||
|
|
||||||
// Whether to delete the packages directory prior to each run.
|
|
||||||
// Makes each build more reproducible.
|
|
||||||
const bool cleanupPackages = true;
|
|
||||||
|
|
||||||
public void Cleanup(IProgressMonitor pm)
|
|
||||||
{
|
|
||||||
var packagesDirectory = new DirectoryInfo(PackageDirectory);
|
|
||||||
|
|
||||||
if (packagesDirectory.Exists)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
packagesDirectory.Delete(true);
|
|
||||||
}
|
|
||||||
catch (System.IO.IOException ex)
|
|
||||||
{
|
|
||||||
pm.Warning(string.Format("Couldn't delete package directory - it's probably held open by something else: {0}", ex.Message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Download the packages to the temp folder.
|
/// Download the packages to the temp folder.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pm">The progress monitor used for reporting errors etc.</param>
|
/// <param name="pm">The progress monitor used for reporting errors etc.</param>
|
||||||
public void InstallPackages(IProgressMonitor pm)
|
public void InstallPackages(IProgressMonitor pm)
|
||||||
{
|
{
|
||||||
if (cleanupPackages)
|
|
||||||
{
|
|
||||||
Cleanup(pm);
|
|
||||||
}
|
|
||||||
|
|
||||||
var packagesDirectory = new DirectoryInfo(PackageDirectory);
|
|
||||||
|
|
||||||
if (!Directory.Exists(PackageDirectory))
|
|
||||||
{
|
|
||||||
packagesDirectory.Create();
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var package in packages)
|
foreach (var package in packages)
|
||||||
{
|
{
|
||||||
RestoreNugetPackage(package.FullName, pm);
|
RestoreNugetPackage(package.FullName, pm);
|
||||||
@@ -109,31 +75,7 @@ namespace Semmle.BuildAnalyser
|
|||||||
/// This will be in the Temp location
|
/// This will be in the Temp location
|
||||||
/// so as to not trample the source tree.
|
/// so as to not trample the source tree.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string PackageDirectory
|
public TemporaryDirectory PackageDirectory { get; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Computes a unique temp directory for the packages associated
|
|
||||||
/// with this source tree. Use a SHA1 of the directory name.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="srcDir"></param>
|
|
||||||
/// <returns>The full path of the temp directory.</returns>
|
|
||||||
string computeTempDirectory(string srcDir)
|
|
||||||
{
|
|
||||||
var bytes = Encoding.Unicode.GetBytes(srcDir);
|
|
||||||
|
|
||||||
var sha = sha1.ComputeHash(bytes);
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
foreach (var b in sha.Take(8))
|
|
||||||
sb.AppendFormat("{0:x2}", b);
|
|
||||||
|
|
||||||
return Path.Combine(Path.GetTempPath(), "Semmle", "packages", sb.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Restore all files in a specified package.
|
/// Restore all files in a specified package.
|
||||||
@@ -171,16 +113,15 @@ namespace Semmle.BuildAnalyser
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (var p = Process.Start(pi))
|
using var p = Process.Start(pi);
|
||||||
{
|
|
||||||
string output = p.StandardOutput.ReadToEnd();
|
|
||||||
string error = p.StandardError.ReadToEnd();
|
|
||||||
|
|
||||||
p.WaitForExit();
|
string output = p.StandardOutput.ReadToEnd();
|
||||||
if (p.ExitCode != 0)
|
string error = p.StandardError.ReadToEnd();
|
||||||
{
|
|
||||||
pm.FailedNugetCommand(pi.FileName, pi.Arguments, output + error);
|
p.WaitForExit();
|
||||||
}
|
if (p.ExitCode != 0)
|
||||||
|
{
|
||||||
|
pm.FailedNugetCommand(pi.FileName, pi.Arguments, output + error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace Semmle.Extraction.CSharp.Standalone
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Searches for source/references and creates separate extractions.
|
/// Searches for source/references and creates separate extractions.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class Analysis
|
class Analysis : IDisposable
|
||||||
{
|
{
|
||||||
readonly ILogger logger;
|
readonly ILogger logger;
|
||||||
|
|
||||||
@@ -71,12 +71,9 @@ namespace Semmle.Extraction.CSharp.Standalone
|
|||||||
projectExtraction.Sources.AddRange(options.SolutionFile == null ? buildAnalysis.AllSourceFiles : buildAnalysis.ProjectSourceFiles);
|
projectExtraction.Sources.AddRange(options.SolutionFile == null ? buildAnalysis.AllSourceFiles : buildAnalysis.ProjectSourceFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public void Dispose()
|
||||||
/// Delete any Nuget assemblies.
|
|
||||||
/// </summary>
|
|
||||||
public void Cleanup()
|
|
||||||
{
|
{
|
||||||
buildAnalysis.Cleanup();
|
buildAnalysis.Dispose();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -85,8 +82,9 @@ namespace Semmle.Extraction.CSharp.Standalone
|
|||||||
static int Main(string[] args)
|
static int Main(string[] args)
|
||||||
{
|
{
|
||||||
var options = Options.Create(args);
|
var options = Options.Create(args);
|
||||||
|
// options.CIL = true; // To do: Enable this
|
||||||
var output = new ConsoleLogger(options.Verbosity);
|
var output = new ConsoleLogger(options.Verbosity);
|
||||||
var a = new Analysis(output);
|
using var a = new Analysis(output);
|
||||||
|
|
||||||
if (options.Help)
|
if (options.Help)
|
||||||
{
|
{
|
||||||
@@ -97,6 +95,8 @@ namespace Semmle.Extraction.CSharp.Standalone
|
|||||||
if (options.Errors)
|
if (options.Errors)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
var start = DateTime.Now;
|
||||||
|
|
||||||
output.Log(Severity.Info, "Running C# standalone extractor");
|
output.Log(Severity.Info, "Running C# standalone extractor");
|
||||||
a.AnalyseProjects(options);
|
a.AnalyseProjects(options);
|
||||||
int sourceFiles = a.Extraction.Sources.Count();
|
int sourceFiles = a.Extraction.Sources.Count();
|
||||||
@@ -117,10 +117,9 @@ namespace Semmle.Extraction.CSharp.Standalone
|
|||||||
new ExtractionProgress(output),
|
new ExtractionProgress(output),
|
||||||
new FileLogger(options.Verbosity, Extractor.GetCSharpLogPath()),
|
new FileLogger(options.Verbosity, Extractor.GetCSharpLogPath()),
|
||||||
options);
|
options);
|
||||||
output.Log(Severity.Info, "Extraction complete");
|
output.Log(Severity.Info, $"Extraction completed in {DateTime.Now-start}");
|
||||||
}
|
}
|
||||||
|
|
||||||
a.Cleanup();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,7 +150,7 @@ namespace Semmle.Extraction.CSharp.Standalone
|
|||||||
|
|
||||||
public void MissingSummary(int missingTypes, int missingNamespaces)
|
public void MissingSummary(int missingTypes, int missingNamespaces)
|
||||||
{
|
{
|
||||||
logger.Log(Severity.Info, "Failed to resolve {0} types and {1} namespaces", missingTypes, missingNamespaces);
|
logger.Log(Severity.Info, "Failed to resolve {0} types in {1} namespaces", missingTypes, missingNamespaces);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Semmle.Util.Logging;
|
using Semmle.Util.Logging;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Semmle.BuildAnalyser
|
namespace Semmle.BuildAnalyser
|
||||||
{
|
{
|
||||||
@@ -9,15 +10,17 @@ namespace Semmle.BuildAnalyser
|
|||||||
{
|
{
|
||||||
void FindingFiles(string dir);
|
void FindingFiles(string dir);
|
||||||
void UnresolvedReference(string id, string project);
|
void UnresolvedReference(string id, string project);
|
||||||
void AnalysingProjectFiles(int count);
|
void AnalysingSolution(string filename);
|
||||||
void FailedProjectFile(string filename, string reason);
|
void FailedProjectFile(string filename, string reason);
|
||||||
void FailedNugetCommand(string exe, string args, string message);
|
void FailedNugetCommand(string exe, string args, string message);
|
||||||
void NugetInstall(string package);
|
void NugetInstall(string package);
|
||||||
void ResolvedReference(string filename);
|
void ResolvedReference(string filename);
|
||||||
void Summary(int existingSources, int usedSources, int missingSources, int references, int unresolvedReferences, int resolvedConflicts, int totalProjects, int failedProjects);
|
void Summary(int existingSources, int usedSources, int missingSources, int references, int unresolvedReferences, int resolvedConflicts, int totalProjects, int failedProjects, TimeSpan analysisTime);
|
||||||
void Warning(string message);
|
void Warning(string message);
|
||||||
void ResolvedConflict(string asm1, string asm2);
|
void ResolvedConflict(string asm1, string asm2);
|
||||||
void MissingProject(string projectFile);
|
void MissingProject(string projectFile);
|
||||||
|
void CommandFailed(string exe, string arguments, int exitCode);
|
||||||
|
void MissingNuGet();
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProgressMonitor : IProgressMonitor
|
class ProgressMonitor : IProgressMonitor
|
||||||
@@ -46,9 +49,9 @@ namespace Semmle.BuildAnalyser
|
|||||||
logger.Log(Severity.Debug, "Unresolved {0} referenced by {1}", id, project);
|
logger.Log(Severity.Debug, "Unresolved {0} referenced by {1}", id, project);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AnalysingProjectFiles(int count)
|
public void AnalysingSolution(string filename)
|
||||||
{
|
{
|
||||||
logger.Log(Severity.Info, "Analyzing project files...");
|
logger.Log(Severity.Info, $"Analyzing {filename}...");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FailedProjectFile(string filename, string reason)
|
public void FailedProjectFile(string filename, string reason)
|
||||||
@@ -73,7 +76,9 @@ namespace Semmle.BuildAnalyser
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void Summary(int existingSources, int usedSources, int missingSources,
|
public void Summary(int existingSources, int usedSources, int missingSources,
|
||||||
int references, int unresolvedReferences, int resolvedConflicts, int totalProjects, int failedProjects)
|
int references, int unresolvedReferences,
|
||||||
|
int resolvedConflicts, int totalProjects, int failedProjects,
|
||||||
|
TimeSpan analysisTime)
|
||||||
{
|
{
|
||||||
logger.Log(Severity.Info, "");
|
logger.Log(Severity.Info, "");
|
||||||
logger.Log(Severity.Info, "Build analysis summary:");
|
logger.Log(Severity.Info, "Build analysis summary:");
|
||||||
@@ -85,6 +90,7 @@ namespace Semmle.BuildAnalyser
|
|||||||
logger.Log(Severity.Info, "{0, 6} resolved assembly conflicts", resolvedConflicts);
|
logger.Log(Severity.Info, "{0, 6} resolved assembly conflicts", resolvedConflicts);
|
||||||
logger.Log(Severity.Info, "{0, 6} projects", totalProjects);
|
logger.Log(Severity.Info, "{0, 6} projects", totalProjects);
|
||||||
logger.Log(Severity.Info, "{0, 6} missing/failed projects", failedProjects);
|
logger.Log(Severity.Info, "{0, 6} missing/failed projects", failedProjects);
|
||||||
|
logger.Log(Severity.Info, "Build analysis completed in {0}", analysisTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Warning(string message)
|
public void Warning(string message)
|
||||||
@@ -94,12 +100,22 @@ namespace Semmle.BuildAnalyser
|
|||||||
|
|
||||||
public void ResolvedConflict(string asm1, string asm2)
|
public void ResolvedConflict(string asm1, string asm2)
|
||||||
{
|
{
|
||||||
logger.Log(Severity.Info, "Resolved {0} as {1}", asm1, asm2);
|
logger.Log(Severity.Debug, "Resolved {0} as {1}", asm1, asm2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MissingProject(string projectFile)
|
public void MissingProject(string projectFile)
|
||||||
{
|
{
|
||||||
logger.Log(Severity.Info, "Solution is missing {0}", projectFile);
|
logger.Log(Severity.Info, "Solution is missing {0}", projectFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void CommandFailed(string exe, string arguments, int exitCode)
|
||||||
|
{
|
||||||
|
logger.Log(Severity.Error, $"Command {exe} {arguments} failed with exit code {exitCode}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MissingNuGet()
|
||||||
|
{
|
||||||
|
logger.Log(Severity.Error, "Missing nuget.exe");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Semmle.Extraction.CSharp\Semmle.Extraction.CSharp.csproj" />
|
<ProjectReference Include="..\Semmle.Extraction.CSharp\Semmle.Extraction.CSharp.csproj" />
|
||||||
|
<ProjectReference Include="..\Semmle.Util\Semmle.Util.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ namespace Semmle.BuildAnalyser
|
|||||||
{
|
{
|
||||||
readonly Microsoft.Build.Construction.SolutionFile solutionFile;
|
readonly Microsoft.Build.Construction.SolutionFile solutionFile;
|
||||||
|
|
||||||
|
private string FullPath { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read the file.
|
/// Read the file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -19,8 +21,8 @@ namespace Semmle.BuildAnalyser
|
|||||||
public SolutionFile(string filename)
|
public SolutionFile(string filename)
|
||||||
{
|
{
|
||||||
// SolutionFile.Parse() expects a rooted path.
|
// SolutionFile.Parse() expects a rooted path.
|
||||||
var fullPath = Path.GetFullPath(filename);
|
FullPath = Path.GetFullPath(filename);
|
||||||
solutionFile = Microsoft.Build.Construction.SolutionFile.Parse(fullPath);
|
solutionFile = Microsoft.Build.Construction.SolutionFile.Parse(FullPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -45,7 +45,10 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
|||||||
Access(ExpressionNodeInfo info, ISymbol symbol, bool implicitThis, IEntity target)
|
Access(ExpressionNodeInfo info, ISymbol symbol, bool implicitThis, IEntity target)
|
||||||
: base(info.SetKind(AccessKind(info.Context, symbol)))
|
: base(info.SetKind(AccessKind(info.Context, symbol)))
|
||||||
{
|
{
|
||||||
cx.TrapWriter.Writer.expr_access(this, target);
|
if (!(target is null))
|
||||||
|
{
|
||||||
|
cx.TrapWriter.Writer.expr_access(this, target);
|
||||||
|
}
|
||||||
|
|
||||||
if (implicitThis && !symbol.IsStatic)
|
if (implicitThis && !symbol.IsStatic)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -71,7 +71,9 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
|||||||
if (symbol == null)
|
if (symbol == null)
|
||||||
{
|
{
|
||||||
info.Context.ModelError(info.Node, "Failed to determine symbol for member access");
|
info.Context.ModelError(info.Node, "Failed to determine symbol for member access");
|
||||||
return new MemberAccess(info.SetKind(ExprKind.UNKNOWN), expression, symbol);
|
// Default to property access - this can still give useful results but
|
||||||
|
// the target of the expression should be checked in QL.
|
||||||
|
return new MemberAccess(info.SetKind(ExprKind.PROPERTY_ACCESS), expression, symbol);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprKind kind;
|
ExprKind kind;
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ namespace Semmle.Extraction.CSharp.Entities
|
|||||||
|
|
||||||
protected override void Populate(TextWriter trapFile)
|
protected override void Populate(TextWriter trapFile)
|
||||||
{
|
{
|
||||||
var ns = Namespace.Create(cx, (INamespaceSymbol)cx.GetModel(Node).GetSymbolInfo(Node.Name).Symbol);
|
var @namespace = (INamespaceSymbol) cx.GetModel(Node).GetSymbolInfo(Node.Name).Symbol;
|
||||||
|
var ns = Namespace.Create(cx, @namespace);
|
||||||
trapFile.namespace_declarations(this, ns);
|
trapFile.namespace_declarations(this, ns);
|
||||||
trapFile.namespace_declaration_location(this, cx.Create(Node.Name.GetLocation()));
|
trapFile.namespace_declaration_location(this, cx.Create(Node.Name.GetLocation()));
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
|||||||
{
|
{
|
||||||
if (symbol.TypeKind == TypeKind.Error)
|
if (symbol.TypeKind == TypeKind.Error)
|
||||||
{
|
{
|
||||||
Context.Extractor.MissingType(symbol.ToString());
|
Context.Extractor.MissingType(symbol.ToString(), Context.FromSource);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
|||||||
|
|
||||||
if (namespaceSymbol == null)
|
if (namespaceSymbol == null)
|
||||||
{
|
{
|
||||||
cx.Extractor.MissingNamespace(Node.Name.ToFullString());
|
cx.Extractor.MissingNamespace(Node.Name.ToFullString(), cx.FromSource);
|
||||||
cx.ModelError(Node, "Namespace not found");
|
cx.ModelError(Node, "Namespace not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -214,7 +214,6 @@ namespace Semmle.Extraction.CSharp
|
|||||||
static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter trapFile, Action<Context, TextWriter, ITypeSymbol> subTermAction)
|
static void BuildNamedTypeId(this INamedTypeSymbol named, Context cx, TextWriter trapFile, Action<Context, TextWriter, ITypeSymbol> subTermAction)
|
||||||
{
|
{
|
||||||
bool prefixAssembly = true;
|
bool prefixAssembly = true;
|
||||||
if (cx.Extractor.Standalone) prefixAssembly = false;
|
|
||||||
if (named.ContainingAssembly is null) prefixAssembly = false;
|
if (named.ContainingAssembly is null) prefixAssembly = false;
|
||||||
|
|
||||||
if (named.IsTupleType)
|
if (named.IsTupleType)
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ namespace Semmle.Extraction
|
|||||||
#if DEBUG_LABELS
|
#if DEBUG_LABELS
|
||||||
using (var id = new StringWriter())
|
using (var id = new StringWriter())
|
||||||
{
|
{
|
||||||
entity.WriteId(id);
|
entity.WriteQuotedId(id);
|
||||||
CheckEntityHasUniqueLabel(id.ToString(), entity);
|
CheckEntityHasUniqueLabel(id.ToString(), entity);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -270,6 +270,8 @@ namespace Semmle.Extraction
|
|||||||
TrapWriter = trapWriter;
|
TrapWriter = trapWriter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool FromSource => Scope.FromSource;
|
||||||
|
|
||||||
public bool IsGlobalContext => Scope.IsGlobalScope;
|
public bool IsGlobalContext => Scope.IsGlobalScope;
|
||||||
|
|
||||||
public readonly ICommentGenerator CommentGenerator = new CommentProcessor();
|
public readonly ICommentGenerator CommentGenerator = new CommentProcessor();
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user